index.vue 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
  1. <template>
  2. <el-dialog
  3. v-model="state.dialogVisible"
  4. draggable
  5. :title="state.dialogTitle"
  6. ref="dialogRef"
  7. @mouseup="mouseup"
  8. :style="'transform: ' + state.transform + ';'"
  9. append-to-body
  10. destroy-on-close
  11. :close-on-click-modal="false"
  12. @close="close"
  13. >
  14. <el-steps :active="activeStep" align-center finish-status="success" class="mb20" v-if="showStepsArr.includes(state.processType)">
  15. <el-step title="业务表单" />
  16. <el-step title="流程表单" />
  17. </el-steps>
  18. <div v-show="activeStep === 0" v-loading="state.loading">
  19. <el-form :model="state.delayForm" label-width="110px" ref="delayFormRef" v-if="state.processType === '延期申请'">
  20. <el-row :gutter="10">
  21. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  22. <el-form-item label="工单编码"> {{ state.orderDetail.no }} </el-form-item>
  23. </el-col>
  24. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  25. <el-form-item label="工单标题"> {{ state.orderDetail.title }} </el-form-item>
  26. </el-col>
  27. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  28. <el-form-item label="申请人"> {{ userInfos.name }} </el-form-item>
  29. </el-col>
  30. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  31. <el-form-item label="申请部门"> {{ userInfos.orgName }} </el-form-item>
  32. </el-col>
  33. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  34. <el-form-item label="申请时间"> {{ formatDate(Date(), 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
  35. </el-col>
  36. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  37. <el-form-item label="当前期满时间"> {{ formatDate(state.orderDetail.expiredTime, 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
  38. </el-col>
  39. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="12" v-loading="state.loading">
  40. <el-form-item label="延期申请数量" prop="timeLimitCount" :rules="[{ required: true, message: '请输入延期申请数量', trigger: 'blur' }]">
  41. <el-row :gutter="10">
  42. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  43. <el-input-number
  44. placeholder="延期申请数量"
  45. v-model="state.delayForm.timeLimitCount"
  46. controls-position="right"
  47. class="w100"
  48. @input="computeTime"
  49. :min="1"
  50. :max="99"
  51. ></el-input-number>
  52. </el-col>
  53. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-loading="state.loading">
  54. <el-form-item
  55. label=""
  56. label-width="0"
  57. prop="timeLimitUnit"
  58. :rules="[{ required: true, message: '请选择延期申请单位', trigger: 'change' }]"
  59. >
  60. <el-select v-model="state.delayForm.timeLimitUnit" placeholder="延期申请单位" @change="computeTime">
  61. <el-option v-for="item in timeType" :value="item.key" :key="item.key" :label="item.value" />
  62. </el-select>
  63. </el-form-item>
  64. </el-col>
  65. </el-row>
  66. </el-form-item>
  67. </el-col>
  68. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  69. <el-form-item label="延期后期满时间"> {{ state.delayForm.endTime }} </el-form-item>
  70. </el-col>
  71. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  72. <el-form-item label="申请理由" prop="content" :rules="[{ required: true, message: '请填写延期申请理由', trigger: 'blur' }]">
  73. <common-advice
  74. @chooseAdvice="chooseAdviceDelay"
  75. v-model="state.delayForm.content"
  76. placeholder="请填写延期申请理由"
  77. :loading="state.loading"
  78. :commonEnum="commonEnum.Delay"
  79. />
  80. </el-form-item>
  81. </el-col>
  82. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  83. <el-form-item label="附件">
  84. <annex-list name="延期附件" v-model:format="handleFilesDelay" :businessId="state.orderDetail.id" classify="延期上传" />
  85. </el-form-item>
  86. </el-col>
  87. </el-row>
  88. </el-form>
  89. <el-form :model="state.discernForm" label-width="110px" ref="discernFormRef" v-if="state.processType === '甄别申请'">
  90. <el-row :gutter="10">
  91. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  92. <el-form-item label="工单编码"> {{ state.orderDetail.no }} </el-form-item>
  93. </el-col>
  94. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  95. <el-form-item label="工单标题"> {{ state.orderDetail.title }} </el-form-item>
  96. </el-col>
  97. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  98. <el-form-item label="申请人"> {{ userInfos.name }} </el-form-item>
  99. </el-col>
  100. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  101. <el-form-item label="申请部门"> {{ userInfos.orgName }} </el-form-item>
  102. </el-col>
  103. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  104. <el-form-item label="申请时间"> {{ dayjs(Date()).format('YYYY-MM-DD HH:mm:ss') }} </el-form-item>
  105. </el-col>
  106. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  107. <el-form-item label="申请类型" prop="type" :rules="[{ required: true, message: '请选择申请类型', trigger: 'change' }]">
  108. <el-select v-model="state.discernForm.type" placeholder="请选择申请类型" class="w100" value-key="dicDataValue">
  109. <el-option v-for="item in screenTypeOptions" :value="item" :key="item.dicDataValue" :label="item.dicDataName" />
  110. </el-select>
  111. </el-form-item>
  112. </el-col>
  113. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  114. <el-form-item label="申请理由" prop="content" :rules="[{ required: true, message: '请填写甄别申请理由', trigger: 'blur' }]">
  115. <common-advice
  116. @chooseAdvice="chooseAdviceDiscern"
  117. v-model="state.discernForm.content"
  118. placeholder="请填写甄别申请理由"
  119. :loading="state.loading"
  120. :commonEnum="commonEnum.Discriminate"
  121. />
  122. </el-form-item>
  123. </el-col>
  124. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  125. <el-form-item label="附件">
  126. <annex-list
  127. name="甄别附件"
  128. ref="discernAnnexListRef"
  129. v-model:format="handleFilesDiscern"
  130. :businessId="state.orderDetail.id"
  131. classify="甄别上传"
  132. />
  133. </el-form-item>
  134. </el-col>
  135. </el-row>
  136. </el-form>
  137. <el-form :model="state.redoForm" label-width="110px" ref="redoFormRef" v-if="state.processType === '工单重办'">
  138. <el-row :gutter="10">
  139. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  140. <el-form-item label="工单编码"> {{ state.orderDetail.no }} </el-form-item>
  141. </el-col>
  142. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  143. <el-form-item label="工单标题"> {{ state.orderDetail.title }} </el-form-item>
  144. </el-col>
  145. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  146. <el-form-item label="申请人"> {{ userInfos.name }} </el-form-item>
  147. </el-col>
  148. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  149. <el-form-item label="申请部门"> {{ userInfos.orgName }} </el-form-item>
  150. </el-col>
  151. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  152. <el-form-item label="申请时间"> {{ dayjs(Date()).format('YYYY-MM-DD HH:mm:ss') }} </el-form-item>
  153. </el-col>
  154. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  155. <el-form-item label="重办理由" prop="orderRedoReason" :rules="[{ required: true, message: '请选择重办理由', trigger: 'change' }]">
  156. <el-select v-model="state.redoForm.orderRedoReason" placeholder="请选择重办理由" clearable class="w100">
  157. <el-option v-for="item in orderRedoReasonOptions" :value="item.key" :key="item.key" :label="item.value" />
  158. </el-select>
  159. </el-form-item>
  160. </el-col>
  161. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  162. <el-form-item label="重办意见" prop="redoOpinion" :rules="[{ required: true, message: '请填写重办意见', trigger: 'blur' }]">
  163. <common-advice
  164. @chooseAdvice="chooseAdviceRedo"
  165. v-model="state.redoForm.redoOpinion"
  166. placeholder="请填写重办意见"
  167. :loading="state.loading"
  168. :commonEnum="commonEnum.OrderCirculation"
  169. />
  170. </el-form-item>
  171. </el-col>
  172. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  173. <el-form-item label="附件">
  174. <annex-list name="重办附件" v-model:format="handleFilesDiscern" :businessId="state.orderDetail.id" classify="重办上传" />
  175. </el-form-item>
  176. </el-col>
  177. </el-row>
  178. </el-form>
  179. </div>
  180. <el-form :model="state.ruleForm" label-width="110px" ref="ruleFormRef" v-show="activeStep === 1" v-loading="state.loading">
  181. <slot name="header"></slot>
  182. <el-row :gutter="10">
  183. <!-- 审批流程 -->
  184. <template v-if="auditArr.includes(state.processType) && canReject">
  185. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType)">
  186. <el-form-item label="审批结果" prop="isPass" :rules="[{ required: true, message: '请选择审批结果', trigger: 'change' }]">
  187. <el-radio-group v-model="state.ruleForm.isPass">
  188. <el-radio :label="true">同意</el-radio>
  189. <el-radio :label="false">不同意</el-radio>
  190. </el-radio-group>
  191. </el-form-item>
  192. </el-col>
  193. <!-- 审批通过 -->
  194. <template v-if="state.ruleForm.isPass">
  195. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  196. <el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
  197. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
  198. <el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
  199. </el-select>
  200. <p class="flex-center-align color-danger" v-if="showFastSendOrder">
  201. 当前推荐派单办理对象:{{ fastStepName }} <el-button type="primary" link class="ml4" @click="fastSendOrder">快捷派单</el-button>
  202. </p>
  203. </el-form-item>
  204. </el-col>
  205. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType) && showHandlers">
  206. <el-form-item label="办理对象" prop="nextHandlers" :rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]">
  207. <el-select-v2
  208. v-model="state.ruleForm.nextHandlers"
  209. :options="state.handlerOptions"
  210. placeholder="请选择办理对象"
  211. class="w100"
  212. multiple
  213. clearable
  214. collapse-tags
  215. collapse-tags-tooltip
  216. filterable
  217. value-key="key"
  218. @change="selectHandlers"
  219. :multiple-limit="multipleLimit"
  220. />
  221. </el-form-item>
  222. </el-col>
  223. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showMainHandler">
  224. <el-form-item label="主办" prop="nextMainHandler" :rules="[{ required: false, message: '请选择主办', trigger: 'change' }]">
  225. <el-select v-model="state.ruleForm.nextMainHandler" placeholder="请选择主办" class="w100" filterable>
  226. <el-option v-for="item in state.handlerMainOptions" :key="item.key" :label="item.value" :value="item.key" />
  227. </el-select>
  228. </el-form-item>
  229. </el-col>
  230. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="countersignAble">
  231. <el-form-item label="发起会签" prop="isStartCountersign" :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]">
  232. <el-switch
  233. v-model="state.ruleForm.isStartCountersign"
  234. inline-prompt
  235. active-text="是"
  236. inactive-text="否"
  237. @change="changeStartCountersign"
  238. :disabled="countersignDisabled"
  239. />
  240. </el-form-item>
  241. </el-col>
  242. </template>
  243. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  244. <el-form-item label="" prop="isSms">
  245. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" />
  246. </el-form-item>
  247. </el-col>
  248. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  249. <el-form-item
  250. :label="state.inputPlaceholder"
  251. prop="opinion"
  252. :rules="[{ required: true, message: `请填写${state.inputPlaceholder}`, trigger: 'blur' }]"
  253. >
  254. <common-advice
  255. @chooseAdvice="chooseAdvice"
  256. v-model="state.ruleForm.opinion"
  257. :placeholder="'请填写' + state.inputPlaceholder"
  258. :loading="state.loading"
  259. :commonEnum="commonEnum.OrderCirculation"
  260. />
  261. </el-form-item>
  262. </el-col>
  263. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  264. <el-form-item label="附件" prop="additions" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
  265. <annex-list :name="state.annexName" :businessId="state.orderDetail.id" :classify="state.classify" v-model:format="handleFiles" />
  266. </el-form-item>
  267. </el-col>
  268. </template>
  269. <!-- 办理流程 -->
  270. <template v-else>
  271. <!-- 非退回流程都需要选择 -->
  272. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType)">
  273. <el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
  274. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
  275. <el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
  276. </el-select>
  277. <p class="flex-center-align color-danger" v-if="showFastSendOrder">
  278. 当前推荐派单办理对象:{{ fastStepName }} <el-button type="primary" link class="ml4" @click="fastSendOrder">快捷派单</el-button>
  279. </p>
  280. </el-form-item>
  281. </el-col>
  282. <!-- 非退回流程都需要选择并且如果选择了结束节点就不需要选择办理对象 -->
  283. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType) && showHandlers">
  284. <el-form-item label="办理对象" prop="nextHandlers" :rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]">
  285. <el-select-v2
  286. v-model="state.ruleForm.nextHandlers"
  287. :options="state.handlerOptions"
  288. placeholder="请选择办理对象"
  289. class="w100"
  290. multiple
  291. clearable
  292. collapse-tags
  293. collapse-tags-tooltip
  294. filterable
  295. value-key="key"
  296. @change="selectHandlers"
  297. :multiple-limit="multipleLimit"
  298. />
  299. </el-form-item>
  300. </el-col>
  301. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showMainHandler">
  302. <el-form-item label="主办" prop="nextMainHandler" :rules="[{ required: false, message: '请选择主办', trigger: 'change' }]">
  303. <el-select v-model="state.ruleForm.nextMainHandler" placeholder="请选择主办" class="w100" filterable>
  304. <el-option v-for="item in state.handlerMainOptions" :key="item.key" :label="item.value" :value="item.key" />
  305. </el-select>
  306. </el-form-item>
  307. </el-col>
  308. <!-- 工单办理专有参数 -->
  309. <template v-if="flowDirection">
  310. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  311. <el-form-item label="办理时限" prop="timeLimit" :rules="[{ required: true, message: '请输入办理时限', trigger: 'blur' }]">
  312. <el-row :gutter="10">
  313. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  314. <el-input-number
  315. placeholder="办理时限"
  316. v-model="state.ruleForm.timeLimit"
  317. controls-position="right"
  318. class="w100"
  319. @input="computeTimeNext"
  320. :min="1"
  321. :max="99"
  322. ></el-input-number>
  323. </el-col>
  324. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-loading="state.loading">
  325. <el-form-item
  326. label=""
  327. label-width="0"
  328. prop="timeLimitUnit"
  329. :rules="[{ required: true, message: '请选择办理时限单位', trigger: 'change' }]"
  330. >
  331. <el-select v-model="state.ruleForm.timeLimitUnit" placeholder="办理时限单位" @change="computeTimeNext" disabled>
  332. <el-option v-for="item in timeTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
  333. </el-select>
  334. </el-form-item>
  335. </el-col>
  336. </el-row>
  337. </el-form-item>
  338. </el-col>
  339. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  340. <el-form-item label="工单期满时间">
  341. {{ state.ruleForm.endTime }}
  342. </el-form-item>
  343. </el-col>
  344. <!-- <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="handelArr.includes(state.processType)">
  345. <el-form-item label="节点期满时间" prop="expiredTime" :rules="[{ required: true, message: '请选择节点期满时间', trigger: 'change' }]">
  346. <el-date-picker
  347. v-model="state.ruleForm.expiredTime"
  348. type="datetime"
  349. placeholder="请选择节点期满时间"
  350. value-format="YYYY-MM-DD[T]HH:mm:ss"
  351. class="w100"
  352. />
  353. </el-form-item>
  354. </el-col>-->
  355. </template>
  356. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="countersignAble">
  357. <el-form-item label="发起会签" prop="isStartCountersign" :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]">
  358. <el-switch
  359. v-model="state.ruleForm.isStartCountersign"
  360. inline-prompt
  361. active-text="是"
  362. inactive-text="否"
  363. @change="changeStartCountersign"
  364. :disabled="countersignDisabled"
  365. />
  366. </el-form-item>
  367. </el-col>
  368. <!-- 汇总节点需要输入 并且是工单办理 -->
  369. <template v-if="inputRealHandler">
  370. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  371. <el-form-item label="经办人" prop="realHandlerName" :rules="[{ required: false, message: '请填写经办人', trigger: 'blur' }]">
  372. <el-input v-model="state.ruleForm.realHandlerName" placeholder="请填写经办人" clearable> </el-input>
  373. </el-form-item>
  374. </el-col>
  375. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  376. <el-form-item label="经办人电话" prop="realHandlerPhone" :rules="[{ required: false, message: '请填写经办人电话', trigger: 'blur' }]">
  377. <el-input v-model="state.ruleForm.realHandlerPhone" placeholder="请填写办理人电话" 请填写经办人电话> </el-input>
  378. </el-form-item>
  379. </el-col>
  380. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  381. <el-form-item label="是否与市民沟通" prop="realIsContacted">
  382. <el-switch v-model="state.ruleForm.realIsContacted" inline-prompt active-text="是" inactive-text="否" />
  383. </el-form-item>
  384. </el-col>
  385. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  386. <el-form-item label="是否与市民现场沟通" prop="realContactLocale" label-width="150">
  387. <el-switch v-model="state.ruleForm.realContactLocale" inline-prompt active-text="是" inactive-text="否" />
  388. </el-form-item>
  389. </el-col>
  390. </template>
  391. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  392. <el-form-item label="" prop="isSms">
  393. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" />
  394. </el-form-item>
  395. </el-col>
  396. <template v-if="!['延期申请', '甄别申请'].includes(state.processType)">
  397. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  398. <el-form-item
  399. :label="state.inputPlaceholder"
  400. prop="opinion"
  401. :rules="[{ required: true, message: `请填写${state.inputPlaceholder}`, trigger: 'blur' }]"
  402. >
  403. <common-advice
  404. @chooseAdvice="chooseAdvice"
  405. v-model="state.ruleForm.opinion"
  406. :placeholder="'请填写' + state.inputPlaceholder"
  407. :loading="state.loading"
  408. :commonEnum="commonEnum.OrderCirculation"
  409. />
  410. </el-form-item>
  411. </el-col>
  412. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  413. <el-form-item label="附件" prop="additions" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
  414. <annex-list :name="state.annexName" :businessId="state.orderDetail.id" :classify="state.classify" v-model:format="handleFiles" />
  415. </el-form-item>
  416. </el-col>
  417. </template>
  418. </template>
  419. </el-row>
  420. </el-form>
  421. <template #footer>
  422. <span class="dialog-footer">
  423. <el-button @click="closeDialog" class="default-button">取 消</el-button>
  424. <el-button
  425. class="default-button"
  426. @click="onPrevious"
  427. :loading="state.loading"
  428. v-if="activeStep === 1 && showStepsArr.includes(state.processType)"
  429. >上一步</el-button
  430. >
  431. <el-button class="default-button" @click="onNext" :loading="state.loading" v-if="activeStep === 0 && showStepsArr.includes(state.processType)"
  432. >下一步</el-button
  433. >
  434. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading" v-if="activeStep === 1">办理</el-button>
  435. </span>
  436. </template>
  437. </el-dialog>
  438. </template>
  439. <script setup lang="ts" name="processApproval">
  440. import { computed, defineAsyncComponent, nextTick, reactive, ref, watch, watchEffect } from 'vue';
  441. import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
  442. import other from '@/utils/other';
  443. import { useUserInfo } from '@/stores/userInfo';
  444. import { storeToRefs } from 'pinia';
  445. import { commonEnum } from '@/utils/constants';
  446. import { orderFlowParams, orderHandle, orderStartFlow, orderTimeConfig } from "@/api/business/order";
  447. import {
  448. orderPrevious,
  449. workflowNext,
  450. workflowNextSteps,
  451. workflowNextStepsByOrder,
  452. workflowPrevious,
  453. workflowRecall,
  454. workflowRecallParams,
  455. workflowRedoParams,
  456. workflowReject,
  457. } from '@/api/system/workflow';
  458. import { redoApply, redoBaseData } from '@/api/business/redo';
  459. import { delayApply, delayBaseData, delayCalcEndTime, workflowDelayParams } from '@/api/business/delay';
  460. import { discernApply, screenBaseData, workflowDiscernParams } from '@/api/business/discern';
  461. import { debounce } from '@/utils/tools';
  462. import {
  463. KnowledgeAdd,
  464. KnowledgeAddStartFlowParams,
  465. KnowledgeDel,
  466. KnowledgeDeleteStartFlowParams,
  467. KnowledgeUpdate,
  468. KnowledgeUpdateStartFlowParams,
  469. } from '@/api/knowledge';
  470. import dayjs from 'dayjs';
  471. import { formatDate } from '@/utils/formatTime';
  472. // 引入组件
  473. const CommonAdvice = defineAsyncComponent(() => import('@/components/CommonAdvice/index.vue')); // 常用意见
  474. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件列表
  475. // 定义子组件向父组件传值/事件
  476. const emit = defineEmits(['orderProcessSuccess', 'orderProcessFailed']);
  477. // 定义变量内容
  478. const state = reactive<any>({
  479. dialogVisible: false, // 弹窗显示隐藏
  480. ruleForm: {
  481. isPass: true, // 审批结果
  482. //流程表单
  483. opinion: '', // 意见
  484. nextStepCode: '', // 下一节点
  485. nextStepName: '', // 下一节点名称
  486. backToCountersignEnd: false, // 是否回到会签结束节点
  487. nextHandlers: [], // 下一节点办理对象
  488. nextMainHandler: '', // 主办人
  489. isSms: false, // 是否短信通知
  490. isStartCountersign: false, // 是否发起会签
  491. },
  492. delayForm: {
  493. //延期申请表单
  494. timeLimitCount: null, // 延期申请数量
  495. content: '', // 延期申请理由
  496. timeLimitUnit: 2, // 延期申请单位 默认工作日
  497. },
  498. discernForm: {
  499. // 甄别表单
  500. content: '', // 甄别理由
  501. },
  502. redoForm: {
  503. // 重办表单
  504. content: '', // 重办理由
  505. },
  506. nextStepOptions: [], // 下一节点
  507. handlerOptions: [], // 办理对象
  508. transform: 'translate(0px, 0px)', // 滚动条位置
  509. loading: false, // 提交按钮loading
  510. processType: 'next', // 流程状态
  511. workflowId: '', // 流程id
  512. handlerClassifies: [], //撤回办理对象
  513. handlerMainOptions: [], // 主办人
  514. handleId: '', // 流程处理ID
  515. dialogTitle: '', // 弹窗标题
  516. annexName: '', // 附件标题
  517. inputPlaceholder: '', // 意见提示
  518. orderDetail: {}, // 工单详情
  519. });
  520. const ruleFormRef = ref<RefType>(); //表单组件
  521. const storesUserInfo = useUserInfo();
  522. const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
  523. const showStepsArr = ['延期申请', '甄别申请', '工单重办']; // 显示步骤条的流程
  524. const handelArr = ['工单办理']; // 处于办理状态的流程 (如果是汇总节点 需要填写办理对象等 办理流程才有期满时间)
  525. const returnArr = ['工单退回', '甄别退回', '延期退回']; // 退回流程 (退回流程不需要展示其他 只需要填写意见和附件即可)
  526. const auditArr = ['甄别审批', '延期审批']; // 审批流程
  527. const timeType = ref<EmptyArrayType>([]); // 延期申请单位
  528. const orderRedoReasonOptions = ref<EmptyArrayType>([]); // 重办理由
  529. const screenTypeOptions = ref<EmptyArrayType>([]); // 甄别类型
  530. // 打开弹窗
  531. const openDialog = async (val: any) => {
  532. console.log(val);
  533. state.loading = true;
  534. state.dialogVisible = true;
  535. try {
  536. const { id, processType, extra, orderDetail } = val;
  537. state.ruleForm.workflowId = state.workflowId = id ?? ''; // 流程id
  538. state.processType = processType ?? '办理流程'; // 业务类型
  539. state.orderDetail = orderDetail ?? {}; // 工单详情
  540. const { dialogTitle, inputPlaceholder, annexName, classify } = extra ?? {};
  541. state.dialogTitle = dialogTitle ?? '提交流程'; // 流程标题
  542. state.annexName = annexName ?? '办理附件'; // 附件标题
  543. state.classify = classify ?? '办理上传'; // 附件分类
  544. state.inputPlaceholder = inputPlaceholder ?? '办理意见'; // 意见提示
  545. switch (state.processType) {
  546. case '工单受理': //开始流程
  547. const [orderStartWorkflowResponse] = await Promise.all([orderFlowParams()]); //获取开启流程参数
  548. handleResult(orderStartWorkflowResponse);
  549. break;
  550. case '工单撤回': // 撤回流程
  551. const [workflowRecallResponse] = await Promise.all([workflowRecallParams(state.workflowId)]); //获取开启流程参数
  552. handleResult(workflowRecallResponse);
  553. break;
  554. case '延期申请': // 延期申请
  555. const [workflowDelayResponse, responseDelay] = await Promise.all([workflowDelayParams(), delayBaseData()]); //获取开启流程参数
  556. timeType.value = responseDelay.result?.timeType ?? []; // 延期时间单位
  557. handleResult(workflowDelayResponse);
  558. break;
  559. case '甄别申请': // 甄别申请
  560. const [workflowDiscernResponse, responseDiscern] = await Promise.all([workflowDiscernParams(), screenBaseData()]); //获取开启流程参数
  561. screenTypeOptions.value = responseDiscern.result?.screenType ?? []; // 甄别理由
  562. handleResult(workflowDiscernResponse);
  563. break;
  564. case '工单重办': // 工单重办
  565. const [workflowRedoResponse, responseRedo] = await Promise.all([workflowRedoParams(state.workflowId), redoBaseData()]); //获取开启流程参数
  566. orderRedoReasonOptions.value = responseRedo.result?.orderRedoReasonOptions ?? []; // 重办理由
  567. handleResult(workflowRedoResponse);
  568. break;
  569. case '工单退回': // 退回流程
  570. break;
  571. case '甄别退回': // 退回流程
  572. break;
  573. case '延期退回': // 退回流程
  574. break;
  575. case '工单办理': // 工单办理
  576. const [workflowNextStepsResponse] = await Promise.all([workflowNextStepsByOrder(state.orderDetail.id)]); // 获取下一节点和下一节点参数
  577. handleResult(workflowNextStepsResponse);
  578. break;
  579. case '新增知识':
  580. const [KnowledgeAddStartFlowResponse] = await Promise.all([KnowledgeAddStartFlowParams()]); // 知识库新增参数
  581. handleResult(KnowledgeAddStartFlowResponse);
  582. break;
  583. case '更新知识':
  584. const [KnowledgeUpdateResponse] = await Promise.all([KnowledgeUpdateStartFlowParams()]); // 知识库更新参数
  585. handleResult(KnowledgeUpdateResponse);
  586. break;
  587. case '更新新增知识':
  588. const [KnowledgeAddUpdateResponse] = await Promise.all([KnowledgeAddStartFlowParams()]); // 知识库更新参数
  589. handleResult(KnowledgeAddUpdateResponse);
  590. break;
  591. case '删除知识':
  592. const [KnowledgeDeleteResponse] = await Promise.all([KnowledgeDeleteStartFlowParams()]); // 知识库删除参数
  593. handleResult(KnowledgeDeleteResponse);
  594. break;
  595. default: // 默认下一流程 工单办理
  596. // 获取下一节点和下一节点参数
  597. const [nextResponse] = await Promise.all([workflowNextSteps(state.workflowId)]);
  598. handleResult(nextResponse);
  599. break;
  600. }
  601. await nextTick(() => {
  602. restForm(ruleFormRef.value);
  603. });
  604. } finally {
  605. state.loading = false;
  606. }
  607. };
  608. const canReject = ref<boolean>(false); // 是否可以驳回
  609. const timeTypeOptions = ref<EmptyArrayType>([]); // 办理时限单位
  610. const canStartCountersign = ref<boolean>(false); // 是否可以发起会签
  611. const isMainHandlerShow = ref<boolean>(false); // 是否展示主办人
  612. const handleResult = (res: any) => {
  613. state.nextStepOptions = res.result.steps; //办理对象选择内容
  614. canReject.value = res.result.canReject ?? false; // 是否可以驳回
  615. timeTypeOptions.value = res.result.timeTypeOptions ?? []; // 办理时限申请单位
  616. canStartCountersign.value = res.result.canStartCountersign ?? false; // 是否可以发起会签
  617. isMainHandlerShow.value = res.result.isMainHandlerShow ?? false; // 是否展示主办人
  618. if (handelArr.includes(state.processType)) {
  619. // 办理才有期满时间
  620. state.ruleForm.expiredTime = res.result.expiredTime ?? null; // 期满时间
  621. }
  622. if (state.nextStepOptions.length === 1) {
  623. // 下一节点是否只有一个 默认选中第一个
  624. setTimeout(() => {
  625. state.ruleForm.nextStepCode = state.nextStepOptions[0].key; // 下一节点code
  626. state.ruleForm.nextStepName = state.nextStepOptions[0].value; // 下一节点name
  627. state.ruleForm.backToCountersignEnd = state.nextStepOptions[0].backToCountersignEnd ?? false; // 是否回到会签结束节点
  628. }, 0);
  629. selectNextStep(state.nextStepOptions[0].key); // 查询流程下一节点参数
  630. } else {
  631. state.ruleForm.nextStepCode = '';
  632. state.ruleForm.nextStepName = '';
  633. }
  634. state.loading = false;
  635. };
  636. // 上一部
  637. const onPrevious = () => {
  638. activeStep.value = 0;
  639. };
  640. const delayFormRef = ref<RefType>(); //延期申请表单组件
  641. const discernFormRef = ref<RefType>(); //甄别申请表单组件
  642. const redoFormRef = ref<RefType>(); //重办表单组件
  643. // 下一步
  644. const onNext = () => {
  645. switch (state.processType) {
  646. case '延期申请':
  647. delayFormRef.value?.validate((valid: boolean) => {
  648. if (!valid) return;
  649. activeStep.value = 1;
  650. });
  651. break;
  652. case '甄别申请': // 甄别申请
  653. discernFormRef.value?.validate((valid: boolean) => {
  654. if (!valid) return;
  655. activeStep.value = 1;
  656. });
  657. break;
  658. case '工单重办':
  659. redoFormRef.value?.validate((valid: boolean) => {
  660. if (!valid) return;
  661. activeStep.value = 1;
  662. });
  663. break;
  664. default: // 默认下一流程
  665. activeStep.value = 1;
  666. break;
  667. }
  668. };
  669. const activeStep = ref(0); //步骤条
  670. watchEffect(() => {
  671. if (state.dialogVisible) {
  672. activeStep.value = showStepsArr.includes(state.processType) ? 0 : 1;
  673. }
  674. });
  675. // 流程选择下一环节
  676. const fastStepCode = ref(''); // 推荐派单处理对象code
  677. const fastStepName = ref(''); // 推荐派单处理对象
  678. const selectNextStep = (val: any) => {
  679. ruleFormRef.value?.resetFields('nextHandlers');
  680. ruleFormRef.value?.resetFields('nextMainHandler');
  681. const next = state.nextStepOptions.find((item: any) => item.key === val);
  682. const items = next.items; //获取下一节点
  683. state.ruleForm.nextStepName = next.value; // 下一节点name
  684. state.ruleForm.backToCountersignEnd = next.backToCountersignEnd ?? false; // 是否回到会签结束节点
  685. state.handlerOptions = items ?? [];
  686. state.handlerOptions = state.handlerOptions.map((item: any) => {
  687. return {
  688. value: {
  689. ...item,
  690. },
  691. label: item.value,
  692. };
  693. });
  694. fastStepName.value = next.recommendOrgName; // 推荐派单处理对象
  695. fastStepCode.value = next.recommendOrgId; // 推荐派单处理对象code
  696. if(items.length === 1){ // 如果办理对象只有一个默认选中
  697. state.ruleForm.nextHandlers = [items[0]];
  698. }
  699. };
  700. // 会签是否可用 (多个办理对象,并且配置可以会签)
  701. const countersignAble = computed(() => {
  702. return canStartCountersign.value;
  703. });
  704. // 办理对象是否能够选择多个(可以发起会签可以选择多个,不能发起会签只能选择一个)
  705. const multipleLimit = computed(() => {
  706. return canStartCountersign.value ? 0 : 1;
  707. });
  708. watch(
  709. () => state.ruleForm.nextHandlers, // 监听办理对象 多个办理对象自动发起会签
  710. (val) => {
  711. state.ruleForm.isStartCountersign = val.length > 1;
  712. }
  713. );
  714. const countersignDisabled = computed(() => {
  715. // 是否可以发起会签
  716. return state.ruleForm.nextHandlers.length <= 1;
  717. });
  718. // 是否发起会签
  719. const changeStartCountersign = (val: boolean) => {
  720. if (!val) {
  721. // 如果不能会签清空办理对象
  722. state.ruleForm.nextHandlers = [];
  723. ruleFormRef.value?.resetFields('nextHandlers');
  724. }
  725. };
  726. // 是否展示办理对象 (只有结束节点不展示 next.stepType===2 表示为结束节点)
  727. const showHandlers = computed(() => {
  728. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  729. if (!next) return true;
  730. return next.stepType !== 2;
  731. });
  732. // 是否是汇总节点(汇总需要填入其他参数)并且是工单办理
  733. const inputRealHandler = computed(() => {
  734. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  735. return next?.inputRealHandler && handelArr.includes(state.processType);
  736. });
  737. // 是否显示快捷派单
  738. const showFastSendOrder = computed(() => {
  739. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  740. if (!next) return false;
  741. return next?.recommendOrgName && next?.recommendOrgId;
  742. });
  743. // 快速派单
  744. const fastSendOrder = () => {
  745. if (!fastStepCode.value) return;
  746. // 如果办理对象中没有推荐派单的对象就添加
  747. if (!state.ruleForm.nextHandlers.find((item: any) => item.key === fastStepCode.value)) {
  748. state.ruleForm.nextHandlers = [...state.ruleForm.nextHandlers, { key: fastStepCode.value, value: fastStepName.value }];
  749. }
  750. };
  751. // 是否展示办理时限 flowDirection 并且是工单办理
  752. const flowDirection = computed(() => {
  753. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  754. if (!next) return false;
  755. return [0, 1].includes(next.flowDirection) && handelArr.includes(state.processType);
  756. });
  757. // 计算工单期满时间
  758. watch(
  759. () => flowDirection.value,
  760. (val) => {
  761. if (val) {
  762. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  763. state.ruleForm.flowDirection = next.flowDirection;
  764. orderTimeConfig({ flowDirection: next.flowDirection, acceptTypeCode: state.orderDetail.acceptTypeCode }).then((res: any) => {
  765. state.ruleForm.timeLimit = res.result.count ?? null; // 办理时限
  766. state.ruleForm.timeLimitUnit = res.result.timeType ?? ''; // 办理时限单位
  767. computeTimeNext();
  768. });
  769. }
  770. }
  771. );
  772. // 办理计算工单期满时间
  773. const computeTimeNext = debounce(() => {
  774. if (!state.ruleForm.timeLimit || !state.ruleForm.timeLimitUnit) return;
  775. let request = {
  776. delayNum: state.ruleForm.timeLimit,
  777. delayUnit: state.ruleForm.timeLimitUnit,
  778. beginTime: state.ruleForm.expiredTime,
  779. };
  780. state.loading = true;
  781. delayCalcEndTime(request)
  782. .then((res: any) => {
  783. state.ruleForm.endTime = dayjs(res.result.endTime).format('YYYY-MM-DD HH:mm:ss');
  784. state.loading = false;
  785. })
  786. .catch(() => {
  787. state.delayForm.endTime = '';
  788. state.loading = false;
  789. });
  790. }, 300);
  791. // 选择办理对象
  792. const selectHandlers = () => {
  793. ruleFormRef.value?.resetFields('nextMainHandler');
  794. if (state.ruleForm.nextHandlers.length > 1) {
  795. // 多个办理对象 主办
  796. state.ruleForm.nextMainHandler = state.ruleForm.nextHandlers[0].key;
  797. }
  798. if (state.ruleForm.nextHandlers.length <= 1) {
  799. // 如果只有一个办理对象就不需要发起会签
  800. state.ruleForm.isStartCountersign = false;
  801. }
  802. };
  803. // 办理对象是否必填
  804. const nextHandlersRequired = ref<Boolean>(false);
  805. watch(() => state.ruleForm.nextStepCode,(val)=>{
  806. const next = state.nextStepOptions.find((item: any) => item.key === val);
  807. if (!next) return true;
  808. nextHandlersRequired.value = ![0].includes(next.handlerType);
  809. })
  810. // 是否展示主办
  811. const showMainHandler = computed(() => {
  812. return state.ruleForm.nextHandlers.length > 1 && isMainHandlerShow.value;
  813. });
  814. // 主办从办理对象中选择
  815. state.handlerMainOptions = computed(() => {
  816. return state.ruleForm.nextHandlers;
  817. });
  818. // 设置抽屉
  819. const dialogRef = ref<RefType>();
  820. const mouseup = () => {
  821. state.transform = dialogRef.value.dialogContentRef.$el.style.transform;
  822. };
  823. // 关闭弹窗
  824. const closeDialog = () => {
  825. state.dialogVisible = false;
  826. };
  827. // 重置表单方法
  828. const restForm = (formEl: FormInstance | undefined) => {
  829. if (!formEl) return;
  830. state.ruleForm.opinion = '';
  831. state.delayForm.endTime = '';
  832. formEl.resetFields();
  833. formEl.clearValidate();
  834. };
  835. // 选择常用意见 填入填写框 办理
  836. const chooseAdvice = (item: any) => {
  837. state.ruleForm.opinion += item.content;
  838. };
  839. // 选择常用意见 填入填写框 延期
  840. const chooseAdviceDelay = (item: any) => {
  841. state.delayForm.content += item.content;
  842. };
  843. // 计算期满时间
  844. const computeTime = debounce(() => {
  845. if (!state.delayForm.timeLimitCount || !state.delayForm.timeLimitUnit) return;
  846. let request = {
  847. delayNum: state.delayForm.timeLimitCount,
  848. delayUnit: state.delayForm.timeLimitUnit,
  849. beginTime: state.orderDetail.expiredTime,
  850. };
  851. state.loading = true;
  852. delayCalcEndTime(request)
  853. .then((res: any) => {
  854. state.delayForm.endTime = dayjs(res.result.endTime).format('YYYY-MM-DD HH:mm:ss');
  855. state.loading = false;
  856. })
  857. .catch(() => {
  858. state.delayForm.endTime = '';
  859. state.loading = false;
  860. });
  861. }, 300);
  862. // 选择常用意见 填入填写框 甄别
  863. const chooseAdviceDiscern = (item: any) => {
  864. state.discernForm.content += item.content;
  865. };
  866. // 选择常用意见 填入填写框 重办
  867. const chooseAdviceRedo = (item: any) => {
  868. state.redoForm.redoOpinion += item.content;
  869. };
  870. const afterSubmit = (emitType?: 'orderProcessSuccess' | 'orderProcessFailed', showMessage?: boolean) => {
  871. state.loading = false;
  872. closeDialog();
  873. if (showMessage) ElMessage.success('操作成功');
  874. if (emitType) emit(emitType);
  875. };
  876. const close = () => {
  877. restForm(ruleFormRef.value);
  878. restForm(delayFormRef.value);
  879. restForm(discernFormRef.value);
  880. restForm(redoFormRef.value);
  881. };
  882. // 提交
  883. const handleFiles = ref<EmptyArrayType>([]); // 流程附件
  884. const handleFilesDelay = ref<EmptyArrayType>([]); // 延期附件
  885. const handleFilesDiscern = ref<EmptyArrayType>([]); // 甄别附件
  886. const onSubmit = (formEl: FormInstance | undefined) => {
  887. if (!formEl) return;
  888. formEl.validate((valid: boolean) => {
  889. if (!valid) return;
  890. const isAuditText = '办理';
  891. ElMessageBox.confirm(`确认${isAuditText}?`, '提示', {
  892. confirmButtonText: '确认',
  893. cancelButtonText: '取消',
  894. type: 'warning',
  895. draggable: true,
  896. cancelButtonClass: 'default-button',
  897. autofocus: false,
  898. })
  899. .then(() => {
  900. state.loading = true;
  901. let submitObj = other.deepClone(state.ruleForm);
  902. if (submitObj.nextHandlers && submitObj.nextHandlers.length) {
  903. if (submitObj.nextHandlers.length === 1) {
  904. submitObj.nextMainHandler = submitObj.nextHandlers[0].key;
  905. }
  906. }
  907. if (!flowDirection.value) {
  908. // 需要填写办理时限
  909. Reflect.deleteProperty(submitObj, 'timeLimit');
  910. Reflect.deleteProperty(submitObj, 'timeLimitUnit');
  911. Reflect.deleteProperty(submitObj, 'flowDirection');
  912. } else {
  913. submitObj.external = {
  914. timeLimit: state.ruleForm.timeLimit,
  915. timeLimitUnit: state.ruleForm.timeLimitUnit,
  916. };
  917. }
  918. submitObj.stepExpiredTime = submitObj.expiredTime; //节点过期时间
  919. switch (state.processType) {
  920. case '工单受理':
  921. const request = {
  922. data: { ...state.orderDetail },
  923. workflow: { ...submitObj, files: handleFiles.value },
  924. };
  925. orderStartFlow(request)
  926. .then(() => {
  927. afterSubmit('orderProcessSuccess', true);
  928. })
  929. .catch(() => {
  930. afterSubmit('orderProcessFailed');
  931. });
  932. break;
  933. case '工单撤回':
  934. workflowRecall({ ...submitObj, files: handleFiles.value })
  935. .then(() => {
  936. afterSubmit('orderProcessSuccess', true);
  937. })
  938. .catch(() => {
  939. afterSubmit('orderProcessFailed');
  940. });
  941. break;
  942. case '延期申请':
  943. const requestDelay = {
  944. data: {
  945. orderId: state.orderDetail.id,
  946. delayNum: state.delayForm.timeLimitCount,
  947. delayUnit: state.delayForm.timeLimitUnit,
  948. delayReason: state.delayForm.content,
  949. files: handleFilesDelay.value,
  950. },
  951. workflow: {
  952. ...submitObj,
  953. opinion: state.delayForm.content,
  954. files: handleFilesDelay.value,
  955. },
  956. };
  957. delayApply(requestDelay)
  958. .then(() => {
  959. afterSubmit('orderProcessSuccess', true);
  960. })
  961. .catch(() => {
  962. afterSubmit('orderProcessFailed');
  963. });
  964. break;
  965. case '延期退回':
  966. workflowPrevious({ ...submitObj, files: handleFiles.value })
  967. .then(() => {
  968. afterSubmit('orderProcessSuccess', true);
  969. })
  970. .catch(() => {
  971. afterSubmit('orderProcessFailed');
  972. });
  973. break;
  974. case '延期审批':
  975. if (state.ruleForm.isPass) {
  976. // 审批通过 下一步
  977. workflowNext({ ...submitObj, files: handleFiles.value })
  978. .then(() => {
  979. afterSubmit('orderProcessSuccess', true);
  980. })
  981. .catch(() => {
  982. afterSubmit('orderProcessFailed');
  983. });
  984. } else {
  985. // 审批拒绝
  986. const requestDelayAudit = {
  987. opinion: state.ruleForm.opinion,
  988. workflowId: state.workflowId,
  989. files: handleFiles.value,
  990. };
  991. workflowReject(requestDelayAudit)
  992. .then(() => {
  993. afterSubmit('orderProcessSuccess', true);
  994. })
  995. .catch(() => {
  996. afterSubmit('orderProcessFailed');
  997. });
  998. }
  999. break;
  1000. case '甄别申请':
  1001. const requestDiscern = {
  1002. data: {
  1003. no: state.orderDetail.no,
  1004. visitId: state.orderDetail.visitId,
  1005. visitDetailId: state.orderDetail.visitDetailId,
  1006. orderId: state.orderDetail.id,
  1007. typeDicId: state.discernForm.type.dicDataValue,
  1008. typeDicName: state.discernForm.type.dicDataName,
  1009. content: state.discernForm.content,
  1010. files: handleFilesDiscern.value,
  1011. },
  1012. workflow: { ...submitObj, files: handleFilesDiscern.value, opinion: state.discernForm.content },
  1013. };
  1014. discernApply(requestDiscern)
  1015. .then(() => {
  1016. afterSubmit('orderProcessSuccess', true);
  1017. })
  1018. .catch(() => {
  1019. afterSubmit('orderProcessFailed');
  1020. });
  1021. break;
  1022. case '甄别退回':
  1023. workflowPrevious({ ...submitObj, files: handleFiles.value })
  1024. .then(() => {
  1025. afterSubmit('orderProcessSuccess', true);
  1026. })
  1027. .catch(() => {
  1028. afterSubmit('orderProcessFailed');
  1029. });
  1030. break;
  1031. case '甄别审批':
  1032. if (state.ruleForm.isPass) {
  1033. // 审批通过 下一步
  1034. workflowNext({ ...submitObj, files: handleFiles.value })
  1035. .then(() => {
  1036. afterSubmit('orderProcessSuccess', true);
  1037. })
  1038. .catch(() => {
  1039. afterSubmit('orderProcessFailed');
  1040. });
  1041. } else {
  1042. // 审批拒绝
  1043. const requestDiscernAudit = {
  1044. opinion: state.ruleForm.opinion,
  1045. workflowId: state.workflowId,
  1046. files: handleFiles.value,
  1047. };
  1048. workflowReject(requestDiscernAudit)
  1049. .then(() => {
  1050. afterSubmit('orderProcessSuccess', true);
  1051. })
  1052. .catch(() => {
  1053. afterSubmit('orderProcessFailed');
  1054. });
  1055. }
  1056. break;
  1057. case '工单重办':
  1058. const requestRedo = {
  1059. data: {
  1060. orderId: state.orderDetail.id,
  1061. orderRedoReason: state.redoForm.orderRedoReason,
  1062. redoOpinion: state.redoForm.redoOpinion,
  1063. },
  1064. workflow: { ...submitObj, files: handleFiles.value },
  1065. };
  1066. redoApply(requestRedo)
  1067. .then(() => {
  1068. afterSubmit('orderProcessSuccess', true);
  1069. })
  1070. .catch(() => {
  1071. afterSubmit('orderProcessFailed');
  1072. });
  1073. break;
  1074. case '工单退回':
  1075. orderPrevious({ ...submitObj, files: handleFiles.value })
  1076. .then(() => {
  1077. afterSubmit('orderProcessSuccess', true);
  1078. })
  1079. .catch(() => {
  1080. afterSubmit('orderProcessFailed');
  1081. });
  1082. break;
  1083. case '工单办理': // 工单办理流程
  1084. orderHandle({ ...submitObj, files: handleFiles.value })
  1085. .then(() => {
  1086. afterSubmit('orderProcessSuccess', true);
  1087. })
  1088. .catch(() => {
  1089. afterSubmit('orderProcessFailed');
  1090. });
  1091. break;
  1092. case '新增知识':
  1093. const KnowledgeAddRequest = {
  1094. data: { ...state.orderDetail },
  1095. workflow: { ...submitObj, files: handleFiles.value },
  1096. };
  1097. KnowledgeAdd(KnowledgeAddRequest)
  1098. .then(() => {
  1099. afterSubmit('orderProcessSuccess', true);
  1100. })
  1101. .catch(() => {
  1102. afterSubmit('orderProcessFailed');
  1103. });
  1104. break;
  1105. case '更新新增知识':
  1106. const KnowledgeAddUpdateRequest = {
  1107. data: { ...state.orderDetail },
  1108. workflow: { ...submitObj, files: handleFiles.value },
  1109. };
  1110. KnowledgeUpdate(KnowledgeAddUpdateRequest)
  1111. .then(() => {
  1112. afterSubmit('orderProcessSuccess', true);
  1113. })
  1114. .catch(() => {
  1115. afterSubmit('orderProcessFailed');
  1116. });
  1117. break;
  1118. case '更新知识':
  1119. const KnowledgeUpdateRequest = {
  1120. data: { ...state.orderDetail },
  1121. workflow: { ...submitObj, files: handleFiles.value },
  1122. };
  1123. KnowledgeUpdate(KnowledgeUpdateRequest)
  1124. .then(() => {
  1125. afterSubmit('orderProcessSuccess', true);
  1126. })
  1127. .catch(() => {
  1128. afterSubmit('orderProcessFailed');
  1129. });
  1130. break;
  1131. case '删除知识':
  1132. const KnowledgeRemoveRequest = {
  1133. data: { ...state.orderDetail },
  1134. workflow: { ...submitObj, files: handleFiles.value },
  1135. };
  1136. KnowledgeDel(KnowledgeRemoveRequest)
  1137. .then(() => {
  1138. afterSubmit('orderProcessSuccess', true);
  1139. })
  1140. .catch(() => {
  1141. afterSubmit('orderProcessFailed');
  1142. });
  1143. break;
  1144. default: // 默认工单办理
  1145. orderHandle({ ...submitObj, files: handleFiles.value })
  1146. .then(() => {
  1147. afterSubmit('orderProcessSuccess', true);
  1148. })
  1149. .catch(() => {
  1150. afterSubmit('orderProcessFailed');
  1151. });
  1152. break;
  1153. }
  1154. })
  1155. .catch(() => {});
  1156. });
  1157. };
  1158. // 否决
  1159. const onReject = (formEl: FormInstance | undefined) => {
  1160. if (!formEl) return;
  1161. formEl.validate((valid: boolean) => {
  1162. if (!valid) return;
  1163. ElMessageBox.confirm(`确认审批不通过?`, '提示', {
  1164. confirmButtonText: '确认',
  1165. cancelButtonText: '取消',
  1166. type: 'warning',
  1167. draggable: true,
  1168. cancelButtonClass: 'default-button',
  1169. autofocus: false,
  1170. })
  1171. .then(() => {})
  1172. .catch(() => {});
  1173. });
  1174. };
  1175. // 暴露变量
  1176. defineExpose({
  1177. openDialog,
  1178. closeDialog,
  1179. });
  1180. </script>