Delay-audit-batch.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. <template>
  2. <el-dialog
  3. v-model="state.dialogVisible"
  4. draggable
  5. title="延期批量审批"
  6. ref="dialogRef"
  7. @mouseup="mouseup"
  8. :style="'transform: ' + state.transform + ';'"
  9. destroy-on-close
  10. :close-on-click-modal="false"
  11. @close="close"
  12. append-to-body
  13. >
  14. <el-form :model="state.ruleForm" label-width="110px" ref="ruleFormRef" v-loading="state.loading" :disabled="state.loading">
  15. <slot name="header"></slot>
  16. <el-row :gutter="10">
  17. <!-- 审批流程 -->
  18. <template v-if="canReject">
  19. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  20. <el-form-item label="审批结果" prop="isPass" :rules="[{ required: true, message: '请选择审批结果', trigger: 'change' }]">
  21. <el-radio-group v-model="state.ruleForm.isPass">
  22. <el-radio :value="true">同意</el-radio>
  23. <el-radio :value="false">不同意</el-radio>
  24. </el-radio-group>
  25. </el-form-item>
  26. </el-col>
  27. <!-- 审批通过 -->
  28. <template v-if="state.ruleForm.isPass">
  29. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  30. <el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
  31. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
  32. <el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
  33. </el-select>
  34. <!-- <p class="flex-center-align color-danger" v-if="showFastSendOrder">
  35. 当前推荐派单办理对象:{{ fastStepName }} <el-button type="primary" link class="ml4" @click="fastSendOrder">快捷派单</el-button>
  36. </p>-->
  37. </el-form-item>
  38. </el-col>
  39. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showHandlers">
  40. <el-form-item
  41. label="办理对象"
  42. prop="nextHandlers"
  43. :rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]"
  44. v-if="showHandlers"
  45. >
  46. <el-select-v2
  47. v-model="state.ruleForm.nextHandlers"
  48. :options="state.handlerOptions"
  49. placeholder="请选择办理对象"
  50. class="w100"
  51. multiple
  52. clearable
  53. collapse-tags
  54. collapse-tags-tooltip
  55. filterable
  56. value-key="key"
  57. @change="selectHandlers"
  58. :multiple-limit="multipleLimit"
  59. />
  60. </el-form-item>
  61. </el-col>
  62. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showMainHandler">
  63. <el-form-item label="主办" prop="nextMainHandler" :rules="[{ required: false, message: '请选择主办', trigger: 'change' }]">
  64. <el-select v-model="state.ruleForm.nextMainHandler" placeholder="请选择主办" class="w100" filterable>
  65. <el-option v-for="item in state.handlerMainOptions" :key="item.key" :label="item.value" :value="item.key" />
  66. </el-select>
  67. </el-form-item>
  68. </el-col>
  69. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="countersignAble">
  70. <el-form-item label="发起会签" prop="isStartCountersign" :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]">
  71. <el-switch
  72. v-model="state.ruleForm.isStartCountersign"
  73. inline-prompt
  74. active-text="是"
  75. inactive-text="否"
  76. @change="changeStartCountersign"
  77. :disabled="countersignDisabled"
  78. />
  79. </el-form-item>
  80. </el-col>
  81. </template>
  82. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  83. <el-form-item label="" prop="isSms">
  84. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" />
  85. </el-form-item>
  86. </el-col>
  87. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  88. <el-form-item
  89. :label="state.inputPlaceholder"
  90. prop="opinion"
  91. :rules="[{ required: true, message: `请填写${state.inputPlaceholder}`, trigger: 'blur' }]"
  92. >
  93. <common-advice
  94. @chooseAdvice="chooseAdvice"
  95. v-model="state.ruleForm.opinion"
  96. :placeholder="'请填写' + state.inputPlaceholder"
  97. :loading="state.loading"
  98. :commonEnum="commonEnum.Delay"
  99. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  100. />
  101. </el-form-item>
  102. </el-col>
  103. <!-- <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  104. <el-form-item label="附件" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
  105. <annex-list name="延期附件" :businessId="state.orderDetail.id" classify="延期上传" v-model:format="handleFiles" />
  106. </el-form-item>
  107. </el-col>-->
  108. </template>
  109. <!-- 办理流程 -->
  110. <template v-else>
  111. <el-col v-if="orderContent">
  112. <el-form-item label="受理内容">
  113. <text-ellipsis :content="orderContent" :rows="1"> </text-ellipsis>
  114. </el-form-item>
  115. </el-col>
  116. <!-- 非退回流程都需要选择 -->
  117. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  118. <el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
  119. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
  120. <el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
  121. </el-select>
  122. <!-- <p class="flex-center-align color-danger" v-if="showFastSendOrder">
  123. 当前推荐派单办理对象:{{ fastStepName }} <el-button type="primary" link class="ml4" @click="fastSendOrder">快捷派单</el-button>
  124. </p>-->
  125. </el-form-item>
  126. </el-col>
  127. <!-- 非退回流程都需要选择并且如果选择了结束节点就不需要选择办理对象 -->
  128. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showHandlers">
  129. <el-form-item
  130. label="办理对象"
  131. prop="nextHandlers"
  132. :rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]"
  133. >
  134. <el-select-v2
  135. v-model="state.ruleForm.nextHandlers"
  136. :options="state.handlerOptions"
  137. placeholder="请选择办理对象"
  138. class="w100"
  139. multiple
  140. clearable
  141. collapse-tags
  142. collapse-tags-tooltip
  143. filterable
  144. value-key="key"
  145. @change="selectHandlers"
  146. :multiple-limit="multipleLimit"
  147. />
  148. </el-form-item>
  149. </el-col>
  150. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showMainHandler">
  151. <el-form-item label="主办" prop="nextMainHandler" :rules="[{ required: false, message: '请选择主办', trigger: 'change' }]">
  152. <el-select v-model="state.ruleForm.nextMainHandler" placeholder="请选择主办" class="w100" filterable>
  153. <el-option v-for="item in state.handlerMainOptions" :key="item.key" :label="item.value" :value="item.key" />
  154. </el-select>
  155. </el-form-item>
  156. </el-col>
  157. <!-- 工单办理专有参数 -->
  158. <template v-if="flowDirection">
  159. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  160. <el-form-item label="办理时限" prop="timeLimit" :rules="[{ required: true, message: '请填写办理时限', trigger: 'blur' }]">
  161. <el-row :gutter="10">
  162. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  163. <el-input-number
  164. placeholder="办理时限"
  165. v-model="state.ruleForm.timeLimit"
  166. controls-position="right"
  167. class="w100"
  168. :min="1"
  169. :max="99"
  170. disabled
  171. ></el-input-number>
  172. </el-col>
  173. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-loading="state.loading">
  174. <el-form-item
  175. label=""
  176. label-width="0"
  177. prop="timeLimitUnit"
  178. :rules="[{ required: true, message: '请选择办理时限单位', trigger: 'change' }]"
  179. >
  180. <el-select v-model="state.ruleForm.timeLimitUnit" placeholder="办理时限单位" disabled style="width: 240px">
  181. <el-option v-for="item in timeTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
  182. </el-select>
  183. </el-form-item>
  184. </el-col>
  185. </el-row>
  186. </el-form-item>
  187. </el-col>
  188. </template>
  189. <!-- 话务部到一级部门 派单组到一级部门 -->
  190. <template v-if="seatToOrgOne || paidanToOrgOne">
  191. <el-col :span="24">
  192. <el-form-item label="派单类型" prop="orderAssignMode" :rules="[{ required: true, message: '请选择派单类型', trigger: 'change' }]">
  193. <el-radio-group v-model="state.ruleForm.orderAssignMode" @change="selectDispatchType">
  194. <el-radio :value="0">逐级派单</el-radio>
  195. <el-radio :value="1">跨级派单</el-radio>
  196. </el-radio-group>
  197. </el-form-item>
  198. </el-col>
  199. <el-col :span="12" v-if="state.ruleForm.orderAssignMode === 0">
  200. <el-form-item label="接办部门" prop="nextHandlers" :rules="[{ required: true, message: '请选择接办部门', trigger: 'change' }]">
  201. <!-- <el-select v-model="state.ruleForm.paidanObj" placeholder="请选择接办部门" class="w100" filterable multiple>
  202. <el-option v-for="item in state.paidanObjOptions" :key="item.key" :label="item.value" :value="item.key" />
  203. </el-select>-->
  204. <el-select-v2
  205. v-model="state.ruleForm.nextHandlers"
  206. :options="state.handlerOptions"
  207. placeholder="请选择接办部门"
  208. class="w100"
  209. multiple
  210. clearable
  211. collapse-tags
  212. collapse-tags-tooltip
  213. filterable
  214. value-key="key"
  215. @change="selectHandlers"
  216. :multiple-limit="multipleLimit"
  217. />
  218. </el-form-item>
  219. </el-col>
  220. <el-col :span="24" v-if="state.ruleForm.orderAssignMode === 1">
  221. <el-row class="w100" :gutter="10">
  222. <el-col>
  223. <el-form-item label="接办部门" prop="nextHandler" :rules="[{ required: true, message: '请选择接办部门', trigger: 'change' }]">
  224. <el-select-v2
  225. v-model="state.ruleForm.nextHandler"
  226. :options="state.handlerOptions"
  227. placeholder="请选择接办部门"
  228. class="w100"
  229. clearable
  230. filterable
  231. value-key="key"
  232. @change="selectHandlers"
  233. />
  234. </el-form-item>
  235. </el-col>
  236. <!-- 二级部门 -->
  237. <template v-if="showOrgLevelTwo">
  238. <el-col :span="12">
  239. <el-form-item label="下一环节" prop="levelTwoStep" :rules="[{ required: false, message: '请选择下一环节', trigger: 'change' }]">
  240. <el-select-v2
  241. v-model="state.ruleForm.levelTwoStep"
  242. :options="levelTwoStepOptions"
  243. placeholder="请选择下一环节"
  244. class="w100"
  245. filterable
  246. value-key="key"
  247. clearable
  248. @change="selectOrgLevelTwo"
  249. />
  250. </el-form-item>
  251. </el-col>
  252. <el-col :span="12">
  253. <el-form-item
  254. label="办理对象"
  255. prop="levelTwoHandlers"
  256. :rules="[{ required: false, message: '请选择办理对象', trigger: 'change' }]"
  257. >
  258. <el-select-v2
  259. v-model="state.ruleForm.levelTwoHandlers"
  260. :options="levelTwoHandleOptions"
  261. placeholder="请选择办理对象"
  262. class="w100"
  263. clearable
  264. filterable
  265. value-key="key"
  266. multiple
  267. collapse-tags
  268. collapse-tags-tooltip
  269. :max-collapse-tags="1"
  270. @change="selectOrgLevelTwoHandler"
  271. />
  272. </el-form-item>
  273. </el-col>
  274. </template>
  275. <!-- 三级部门 -->
  276. <template v-if="showOrgLevelThree">
  277. <el-col :span="12">
  278. <el-form-item label="下一环节" prop="levelThreeStep" :rules="[{ required: false, message: '请选择下一环节', trigger: 'change' }]">
  279. <el-select-v2
  280. v-model="state.ruleForm.levelThreeStep"
  281. :options="levelThreeStepOptions"
  282. placeholder="请选择下一环节"
  283. class="w100"
  284. filterable
  285. value-key="key"
  286. clearable
  287. @change="selectOrgLevelThree"
  288. />
  289. </el-form-item>
  290. </el-col>
  291. <el-col :span="12">
  292. <el-form-item
  293. label="办理对象"
  294. prop="levelTwoHandlers"
  295. :rules="[{ required: false, message: '请选择办理对象', trigger: 'change' }]"
  296. >
  297. <el-select-v2
  298. v-model="state.ruleForm.levelThreeHandlers"
  299. :options="levelThreeHandleOptions"
  300. placeholder="请选择办理对象"
  301. class="w100"
  302. clearable
  303. filterable
  304. value-key="key"
  305. multiple
  306. collapse-tags
  307. collapse-tags-tooltip
  308. :max-collapse-tags="1"
  309. @change="selectOrgLevelThreeHandler"
  310. />
  311. </el-form-item>
  312. </el-col>
  313. </template>
  314. </el-row>
  315. </el-col>
  316. </template>
  317. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="countersignAble">
  318. <el-form-item label="发起会签" prop="isStartCountersign" :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]">
  319. <el-switch
  320. v-model="state.ruleForm.isStartCountersign"
  321. inline-prompt
  322. active-text="是"
  323. inactive-text="否"
  324. @change="changeStartCountersign"
  325. :disabled="countersignDisabled"
  326. />
  327. </el-form-item>
  328. </el-col>
  329. <!-- 汇总节点需要填写 并且是工单办理 -->
  330. <template v-if="inputRealHandler">
  331. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  332. <el-form-item label="经办人" prop="realHandlerName" :rules="[{ required: false, message: '请填写经办人', trigger: 'blur' }]">
  333. <el-input v-model="state.ruleForm.realHandlerName" placeholder="请填写经办人" clearable> </el-input>
  334. </el-form-item>
  335. </el-col>
  336. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  337. <el-form-item label="经办人电话" prop="realHandlerPhone" :rules="[{ required: false, message: '请填写经办人电话', trigger: 'blur' }]">
  338. <el-input v-model="state.ruleForm.realHandlerPhone" placeholder="请填写办理人电话" 请填写经办人电话> </el-input>
  339. </el-form-item>
  340. </el-col>
  341. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  342. <el-form-item label="是否与市民沟通" prop="realIsContacted">
  343. <el-switch v-model="state.ruleForm.realIsContacted" inline-prompt active-text="是" inactive-text="否" />
  344. </el-form-item>
  345. </el-col>
  346. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  347. <el-form-item label="是否与市民现场沟通" prop="realContactLocale" label-width="150">
  348. <el-switch v-model="state.ruleForm.realContactLocale" inline-prompt active-text="是" inactive-text="否" />
  349. </el-form-item>
  350. </el-col>
  351. </template>
  352. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="isSmsSelectShow">
  353. <el-form-item label="" prop="isSms">
  354. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" />
  355. </el-form-item>
  356. </el-col>
  357. <!-- 选择结束节点时并且是工单办理并且不是中心,显示部门处理结果 -->
  358. <template v-if="showResult">
  359. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  360. <el-form-item label="处理结果" prop="isResolved" :rules="[{ required: true, message: '请选择处理结果', trigger: 'change' }]">
  361. <el-radio-group v-model="state.ruleForm.isResolved">
  362. <el-radio :value="true">已得到解决</el-radio>
  363. <el-radio :value="false">未得到解决</el-radio>
  364. </el-radio-group>
  365. </el-form-item>
  366. </el-col>
  367. </template>
  368. <!-- 选择结束节点时并且是工单办理并且工单来源是110时,显示警情退回 -->
  369. <template v-if="showPoliceReturn">
  370. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  371. <el-form-item label="" prop="isPoliceReturn">
  372. <el-checkbox v-model="state.ruleForm.isPoliceReturn" label="警情退回" />
  373. </el-form-item>
  374. </el-col>
  375. </template>
  376. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  377. <el-form-item
  378. :label="state.inputPlaceholder"
  379. prop="opinion"
  380. :rules="[{ required: true, message: `请填写${state.inputPlaceholder}`, trigger: 'blur' }]"
  381. >
  382. <common-advice
  383. @chooseAdvice="chooseAdvice"
  384. v-model="state.ruleForm.opinion"
  385. :placeholder="'请填写' + state.inputPlaceholder"
  386. :loading="state.loading"
  387. :commonEnum="commonEnum.Delay"
  388. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  389. />
  390. </el-form-item>
  391. </el-col>
  392. </template>
  393. </el-row>
  394. </el-form>
  395. <template #footer>
  396. <span class="dialog-footer">
  397. <el-button @click="closeDialog" class="default-button">取 消</el-button>
  398. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading">办理</el-button>
  399. </span>
  400. </template>
  401. </el-dialog>
  402. </template>
  403. <script setup lang="ts" name="processApproval">
  404. import { computed, defineAsyncComponent, nextTick, reactive, ref, watch } from 'vue';
  405. import { ElMessage, ElNotification, FormInstance } from 'element-plus';
  406. import other from '@/utils/other';
  407. import { useUserInfo } from '@/stores/userInfo';
  408. import { storeToRefs } from 'pinia';
  409. import { commonEnum } from '@/utils/constants';
  410. import { orderAssignParams, orderTimeConfig } from '@/api/business/order';
  411. import { delayApproveParams, delayBatchApprove } from '@/api/business/delay';
  412. import { useAppConfig } from '@/stores/appConfig';
  413. // 引入组件
  414. const CommonAdvice = defineAsyncComponent(() => import('@/components/CommonAdvice/index.vue')); // 常用意见
  415. const TextEllipsis = defineAsyncComponent(() => import('@/components/TextEllipsis/index.vue'));
  416. // 定义子组件向父组件传值/事件
  417. const emit = defineEmits(['updateList']);
  418. // 定义变量内容
  419. const state = reactive<any>({
  420. dialogVisible: false, // 弹窗显示隐藏
  421. ruleForm: {
  422. isPass: true, // 审批结果
  423. //流程表单
  424. opinion: '', // 意见
  425. nextStepCode: '', // 下一节点
  426. nextStepName: '', // 下一节点名称
  427. backToCountersignEnd: false, // 是否回到会签结束节点
  428. nextHandlers: [], // 下一节点办理对象
  429. nextMainHandler: '', // 主办人
  430. isSms: false, // 是否短信通知
  431. isStartCountersign: false, // 是否发起会签
  432. stepId: null, // 步骤id
  433. // isTransferHandle:false, // 是否转办
  434. orderAssignMode: 0, // 派单类型默认逐级派单
  435. },
  436. delayForm: {
  437. //延期申请表单
  438. timeLimitCount: null, // 延期申请数量
  439. content: '', // 延期申请理由
  440. timeLimitUnit: 2, // 延期申请单位 默认工作日
  441. },
  442. discernForm: {
  443. // 甄别表单
  444. content: '', // 甄别理由
  445. },
  446. redoForm: {
  447. // 重办表单
  448. content: '', // 重办理由
  449. },
  450. terminateForm: {
  451. //终止表单
  452. content: '', // 终止理由
  453. },
  454. nextStepOptions: [], // 下一节点
  455. handlerOptions: [], // 办理对象
  456. transform: 'translate(0px, 0px)', // 滚动条位置
  457. loading: false, // 提交按钮loading
  458. workflowId: '', // 流程id
  459. handlerClassifies: [], //撤回办理对象
  460. handlerMainOptions: [], // 主办人
  461. handleId: '', // 流程处理ID
  462. inputPlaceholder: '办理意见', // 意见提示
  463. orderDetail: {}, // 工单详情
  464. });
  465. const ruleFormRef = ref<RefType>(); //表单组件
  466. const storesUserInfo = useUserInfo();
  467. const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
  468. const appConfigStore = useAppConfig();
  469. const { AppConfigInfo } = storeToRefs(appConfigStore); // 系统配置信息
  470. // 打开弹窗
  471. const delayId = ref<EmptyArrayType>([]);
  472. const openDialog = async (val: any) => {
  473. console.log(val);
  474. selectNext.value = {};
  475. currentParams.value = {};
  476. state.ruleForm.nextHandlers = [];
  477. state.ruleForm.nextHandler = {};
  478. isSmsSelectShow.value = false;
  479. state.ruleForm.isSms = false;
  480. state.loading = true;
  481. state.dialogVisible = true;
  482. try {
  483. delayId.value = val.map((item: any) => item.id);
  484. state.ruleForm.workflowId = state.workflowId = val[0].workflowId ?? ''; // 流程id 默认取第一个
  485. state.orderDetail = val[0].order ?? {}; // 工单详情
  486. // 延期审批
  487. const [nextResponseDelayAudit] = await Promise.all([delayApproveParams(state.workflowId)]); //获取延期审批流程参数
  488. handleResult(nextResponseDelayAudit);
  489. await nextTick(() => {
  490. restForm(ruleFormRef.value);
  491. });
  492. } finally {
  493. state.loading = false;
  494. }
  495. };
  496. const canReject = ref<boolean>(false); // 是否可以驳回
  497. const timeTypeOptions = ref<EmptyArrayType>([]); // 办理时限单位
  498. const canStartCountersign = ref<boolean>(false); // 是否可以发起会签
  499. const isMainHandlerShow = ref<boolean>(false); // 是否展示主办人
  500. const currentParams = ref<EmptyObjectType>({}); // 当前获取到的参数(当前节点信息)
  501. const orderContent = ref<string>(''); // 受理内容
  502. const handleResult = (res: any) => {
  503. currentParams.value = res.result; // 当前获取到的参数(当前节点信息)
  504. state.nextStepOptions = res.result.steps; //办理对象选择内容
  505. canReject.value = res.result.canReject ?? false; // 是否可以驳回
  506. timeTypeOptions.value = res.result.timeTypeOptions ?? []; // 办理时限申请单位
  507. canStartCountersign.value = res.result.canStartCountersign ?? false; // 是否可以发起会签
  508. isMainHandlerShow.value = res.result.isMainHandlerShow ?? false; // 是否展示主办人
  509. orderContent.value = res.result.content ?? ''; // 受理内容
  510. if (state.nextStepOptions.length === 1) {
  511. // 下一节点是否只有一个 默认选中第一个
  512. setTimeout(() => {
  513. state.ruleForm.nextStepCode = state.nextStepOptions[0].key; // 下一节点code
  514. state.ruleForm.nextStepName = state.nextStepOptions[0].value; // 下一节点name
  515. state.ruleForm.backToCountersignEnd = state.nextStepOptions[0].backToCountersignEnd ?? false; // 是否回到会签结束节点
  516. }, 100);
  517. selectNextStep(state.nextStepOptions[0].key); // 查询流程下一节点参数
  518. } else {
  519. state.ruleForm.nextStepCode = '';
  520. state.ruleForm.nextStepName = '';
  521. }
  522. if (res.result.opinion) {
  523. // 如果有汇总意见没有临时保存 取汇总意见 临时保存会覆盖汇总意见
  524. setTimeout(() => {
  525. state.ruleForm.opinion = res.result.opinion;
  526. }, 100);
  527. }
  528. state.ruleForm.stepId = res.result.stepId;
  529. state.loading = false;
  530. };
  531. // 流程选择下一环节
  532. // 先确定当前环节是那一步
  533. /*
  534. * currentParams.value.currentStepBusinessType 表示当前节点到哪一步 0坐席 1派单 2部门节点 3部门领导节点
  535. * */
  536. /*selectNext.value.businessType 表示选择节点到哪一步 0 坐席 1派单 2部门节点 3部门领导节点
  537. * selectNext.value.orgLevel 表示部门等级 1 一级部门 2 二级部门 3 三级部门 4 四级部门
  538. * selectNext.value.stepType 0普通节点 3汇总节点
  539. * */
  540. // 话务部到派单组
  541. const seatTopaidan = computed(() => {
  542. return currentParams.value.currentStepBusinessType === 0 && selectNext.value.businessType === 1;
  543. });
  544. // 话务部到一级部门
  545. const seatToOrgOne = computed(() => {
  546. return currentParams.value.currentStepBusinessType === 0 && selectNext.value.businessType === 2 && selectNext.value.orgLevel === 1;
  547. });
  548. // 派单组到一级部门
  549. const paidanToOrgOne = computed(() => {
  550. return currentParams.value.currentStepBusinessType === 1 && selectNext.value.businessType === 2 && selectNext.value.orgLevel === 1;
  551. });
  552. // 是否展示短信通知选择
  553. const isSmsSelectShow = ref(false);
  554. // 办理对象是否必填 0-角色 1-部门类型 2-部门类型 3-指定用户 4-指定部门
  555. const nextHandlersRequired = ref<Boolean>(false);
  556. const selectNext = ref<EmptyObjectType>({}); // 选择的下一个节点
  557. const selectNextStep = (val: any) => {
  558. ruleFormRef.value?.resetFields('nextHandlers');
  559. ruleFormRef.value?.resetFields('nextMainHandler');
  560. state.ruleForm.nextHandlers = [];
  561. const next = state.nextStepOptions.find((item: any) => item.key === val);
  562. selectNext.value = next;
  563. const items = next.items; //获取下一节点
  564. state.ruleForm.nextStepName = next.value; // 下一节点name
  565. state.ruleForm.handlerType = next.handlerType;
  566. state.ruleForm.businessType = next.businessType;
  567. state.ruleForm.flowDirection = next.flowDirection;
  568. state.ruleForm.backToCountersignEnd = next.backToCountersignEnd ?? false; // 是否回到会签结束节点
  569. state.handlerOptions = items ?? [];
  570. state.handlerOptions = state.handlerOptions.map((item: any) => {
  571. return {
  572. value: {
  573. ...item,
  574. },
  575. label: item.value,
  576. };
  577. });
  578. if (items.length === 1) {
  579. // 如果办理对象只有一个默认选中
  580. state.ruleForm.nextHandlers = [items[0]];
  581. }
  582. // 办理对象是否必填
  583. nextHandlersRequired.value = ![0].includes(next.handlerType);
  584. // 以下是默认需要吧短信勾上的场景 话务部到一级部门 派单组到一级部门
  585. state.ruleForm.isSms = seatToOrgOne.value || paidanToOrgOne.value;
  586. // 是否展示短信通知 (取消坐席流转至“派单组”时的短信通知选项框 )
  587. isSmsSelectShow.value = !seatTopaidan.value;
  588. };
  589. // 会签是否可用 (配置可以会签 并且选择的是逐级派单,并且是普通节点 并且选择是部门)
  590. const countersignAble = computed(() => {
  591. return canStartCountersign.value && state.ruleForm.orderAssignMode === 0 && selectNext.value.stepType === 0 && selectNext.value.businessType === 2;
  592. });
  593. // 办理对象是否能够选择多个(可以发起会签可以选择多个,不能发起会签只能选择一个) 加个判断 选择的下一环节必须是部门(会签必须是选择的部门)
  594. const multipleLimit = computed(() => {
  595. return canStartCountersign.value && selectNext.value.businessType === 2 ? 0 : 1;
  596. });
  597. watch(
  598. () => state.ruleForm.nextHandlers, // 监听办理对象 多个办理对象自动发起会签
  599. (val) => {
  600. state.ruleForm.isStartCountersign = val.length > 1;
  601. }
  602. );
  603. const countersignDisabled = computed(() => {
  604. // (选中的办理对象如果是一个) 因为是disabled 所以这里取反
  605. return !(state.ruleForm.nextHandlers.length === 1);
  606. });
  607. // 是否发起会签
  608. const changeStartCountersign = () => {
  609. };
  610. // 是否展示办理对象 (结束节点不展示: next.stepType===2 表示为结束节点,下一环节为派单组时 next.businessType === 1,办理对象下拉框隐藏:AppConfigInfo.value.isAverageSendOrder= true 表示开启了平均派单 )
  611. const showHandlers = computed(() => {
  612. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  613. // const isAverageSendOrder = AppConfigInfo.value.isAverageSendOrder && next?.businessType === 1; // 开启平均派单并且下一个环节是派单组 !isAverageSendOrder
  614. if (!next) return true;
  615. // 话务部到派单 派单组到一级部门 也不需要展示办理对象 如果下一环节是汇总节点与不需要展示办理
  616. return next?.stepType !== 2 && !(seatToOrgOne.value || paidanToOrgOne.value) && selectNext.value.stepType !== 3;
  617. });
  618. // 是否展示部门处理结果 ( 选择结束节点时并且当前操作人不是中心时,显示部门处理结果 )
  619. const showResult = computed(() => {
  620. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  621. return next?.stepType === 2 && !userInfos.value.isCenter;
  622. });
  623. // 是否展示警情退回 (选择结束节点时并且工单来源是110时,显示警情退回)
  624. const showPoliceReturn = computed(() => {
  625. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  626. return next?.stepType === 2 && state.orderDetail?.source === 200;
  627. });
  628. // 是否是汇总节点(汇总需要填入其他参数)并且是工单办理
  629. const inputRealHandler = computed(() => {
  630. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  631. return next?.inputRealHandler;
  632. });
  633. // 是否展示办理时限 flowDirection 并且是工单办理
  634. const flowDirection = computed(() => {
  635. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  636. if (!next) return false;
  637. return [0, 1].includes(next.flowDirection);
  638. });
  639. // 计算期满时间
  640. watch(
  641. () => flowDirection.value,
  642. (val) => {
  643. if (val) {
  644. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  645. state.ruleForm.flowDirection = next.flowDirection;
  646. orderTimeConfig({ flowDirection: next.flowDirection, acceptTypeCode: state.orderDetail.acceptTypeCode }).then((res: any) => {
  647. state.ruleForm.timeLimit = res.result.count ?? null; // 办理时限
  648. state.ruleForm.timeLimitUnit = res.result.timeType ?? ''; // 办理时限单位
  649. });
  650. }
  651. }
  652. );
  653. // 是否展示主办
  654. const showMainHandler = computed(() => {
  655. return state.ruleForm.nextHandlers.length > 1 && isMainHandlerShow.value;
  656. });
  657. // 主办从办理对象中选择
  658. state.handlerMainOptions = computed(() => {
  659. return state.ruleForm.nextHandlers;
  660. });
  661. // 选择派单类型 需要清空选择的内容
  662. const selectDispatchType = () => {
  663. ruleFormRef.value.resetFields('nextHandlers');
  664. ruleFormRef.value.resetFields('nextHandler');
  665. state.ruleForm.nextHandlers = [];
  666. state.ruleForm.nextHandler = null;
  667. state.ruleForm.isStartCountersign = false;
  668. showOrgLevelTwo.value = false;
  669. state.ruleForm.levelTwoStep = null;
  670. levelTwoStepOptions.value = [];
  671. levelTwoHandleOptions.value = [];
  672. state.ruleForm.levelTwoHandlers = [];
  673. showOrgLevelThree.value = false;
  674. state.ruleForm.levelThreeStep = null;
  675. state.ruleForm.levelThreeHandlers = [];
  676. levelThreeStepOptions.value = [];
  677. levelThreeHandleOptions.value = [];
  678. };
  679. // 选择办理对象
  680. const showOrgLevelTwo = ref(false); // 是否展示二级部门选择
  681. const levelTwoStepOptions = ref<EmptyArrayType>([]); // 二级部门节点
  682. const levelTwoHandleOptions = ref<EmptyArrayType>([]); // 二级部门办理参数
  683. const selectHandlers = () => {
  684. if (state.ruleForm.nextHandlers && state.ruleForm.nextHandlers.length > 1) {
  685. // AppConfigInfo.value.noSignOrgCode 对应的办理对象不能参与会签
  686. const isProvince12345 = state.ruleForm.nextHandlers.find((item: any) => AppConfigInfo.value.noSignOrgCode.includes(item.key));
  687. if (isProvince12345) {
  688. // 如果选择了省12345平台或者省12345交办就提示不能参与会签 并且从选择中移除
  689. ElMessage({
  690. message: '省12345平台和省12345交办不能参与会签',
  691. grouping: true,
  692. });
  693. state.ruleForm.nextHandlers = state.ruleForm.nextHandlers.filter((item: any) => !AppConfigInfo.value.noSignOrgCode.includes(item.key));
  694. }
  695. }
  696. if (state.ruleForm.nextHandlers && state.ruleForm.nextHandlers.length <= 1) {
  697. // 如果只有一个办理对象就不需要发起会签
  698. state.ruleForm.isStartCountersign = false;
  699. }
  700. if ((seatToOrgOne.value || paidanToOrgOne.value) && state.ruleForm.orderAssignMode === 1) {
  701. showOrgLevelTwo.value = false;
  702. state.ruleForm.levelTwoStep = null;
  703. levelTwoStepOptions.value = [];
  704. levelTwoHandleOptions.value = [];
  705. state.ruleForm.levelTwoHandlers = [];
  706. showOrgLevelThree.value = false;
  707. state.ruleForm.levelThreeStep = null;
  708. state.ruleForm.levelThreeHandlers = [];
  709. levelThreeStepOptions.value = [];
  710. levelThreeHandleOptions.value = [];
  711. state.ruleForm.nextHandlers = [state.ruleForm.nextHandler];
  712. // 话务部到一级部门 派单组到一级部门 并且是跨级派单 需要查询下一级部门
  713. const request = {
  714. WorkflowId: state.ruleForm.workflowId,
  715. StepCode: selectNext.value.key,
  716. StepType: selectNext.value.stepType,
  717. BusinessType: selectNext.value.businessType,
  718. HandlerType: selectNext.value.handlerType,
  719. OrgIds: state.ruleForm.nextHandler ? [state.ruleForm.nextHandler.key] : [],
  720. };
  721. orderAssignParams(request).then((res: any) => {
  722. showOrgLevelTwo.value = true;
  723. levelTwoStepOptions.value = res.result.steps.map((item: any) => {
  724. return {
  725. value: {
  726. ...item,
  727. },
  728. label: item.value,
  729. };
  730. });
  731. if (res.result.steps.length === 1) {
  732. state.ruleForm.levelTwoStep = res.result.steps[0];
  733. levelTwoHandleOptions.value = state.ruleForm.levelTwoStep.items.map((item: any) => {
  734. return {
  735. value: {
  736. ...item,
  737. },
  738. label: item.value,
  739. };
  740. });
  741. }
  742. });
  743. } else {
  744. showOrgLevelTwo.value = false;
  745. }
  746. };
  747. // 选择二级部门节点
  748. const selectOrgLevelTwo = (val: any) => {
  749. if (val) {
  750. levelTwoHandleOptions.value = state.ruleForm.levelTwoStep.items.map((item: any) => {
  751. return {
  752. value: {
  753. ...item,
  754. },
  755. label: item.value,
  756. };
  757. });
  758. } else {
  759. levelTwoHandleOptions.value = [];
  760. state.ruleForm.levelTwoHandlers = [];
  761. state.ruleForm.levelThreeHandlers = [];
  762. levelThreeStepOptions.value = [];
  763. levelThreeHandleOptions.value = [];
  764. showOrgLevelThree.value = false;
  765. }
  766. };
  767. const showOrgLevelThree = ref(false);
  768. const levelThreeStepOptions = ref<EmptyArrayType>([]); // 三级部门节点
  769. const levelThreeHandleOptions = ref<EmptyArrayType>([]); // 三级部门办理参数
  770. // 选择二级部门办理对象 展示三级办理对象和节点
  771. const selectOrgLevelTwoHandler = (val: any) => {
  772. const ids = val.map((item: any) => item.key);
  773. if (val && val.length) {
  774. const request = {
  775. WorkflowId: state.ruleForm.workflowId,
  776. StepCode: state.ruleForm.levelTwoStep.key,
  777. StepType: state.ruleForm.levelTwoStep.stepType,
  778. BusinessType: state.ruleForm.levelTwoStep.businessType,
  779. HandlerType: state.ruleForm.levelTwoStep.handlerType,
  780. OrgIds: ids,
  781. };
  782. orderAssignParams(request).then((res: any) => {
  783. showOrgLevelThree.value = true;
  784. levelThreeStepOptions.value = res.result.steps.map((item: any) => {
  785. return {
  786. value: {
  787. ...item,
  788. },
  789. label: item.value,
  790. };
  791. });
  792. if (res.result.steps.length === 1) {
  793. state.ruleForm.levelThreeStep = res.result.steps[0];
  794. levelThreeHandleOptions.value = state.ruleForm.levelThreeStep.items.map((item: any) => {
  795. return {
  796. value: {
  797. ...item,
  798. },
  799. label: item.value,
  800. };
  801. });
  802. }
  803. });
  804. } else {
  805. state.ruleForm.levelThreeHandlers = [];
  806. levelThreeStepOptions.value = [];
  807. levelThreeHandleOptions.value = [];
  808. showOrgLevelThree.value = false;
  809. }
  810. };
  811. // 选择三级部门节点
  812. const selectOrgLevelThree = (val: any) => {
  813. if (val) {
  814. levelThreeHandleOptions.value = state.ruleForm.levelThreeStep.items.map((item: any) => {
  815. return {
  816. value: {
  817. ...item,
  818. },
  819. label: item.value,
  820. };
  821. });
  822. } else {
  823. state.ruleForm.levelThreeHandlers = [];
  824. levelThreeHandleOptions.value = [];
  825. }
  826. };
  827. const selectOrgLevelThreeHandler = () => {};
  828. // 设置抽屉
  829. const dialogRef = ref<RefType>();
  830. const mouseup = () => {
  831. state.transform = dialogRef.value.dialogContentRef.$el.style.transform;
  832. };
  833. // 关闭弹窗
  834. const closeDialog = () => {
  835. state.dialogVisible = false;
  836. };
  837. // 重置表单方法
  838. const restForm = (formEl: FormInstance | undefined) => {
  839. if (!formEl) return;
  840. state.ruleForm.opinion = '';
  841. state.delayForm.endTime = '';
  842. formEl.resetFields();
  843. formEl.clearValidate();
  844. };
  845. // 选择常用意见 填入填写框 办理
  846. const chooseAdvice = (item: any) => {
  847. state.ruleForm.opinion += item.content;
  848. };
  849. const close = () => {
  850. restForm(ruleFormRef.value);
  851. orderContent.value = '';
  852. };
  853. // 办理
  854. const onSubmit = (formEl: FormInstance | undefined) => {
  855. if (!formEl) return;
  856. formEl.validate((valid: boolean) => {
  857. if (!valid) return;
  858. state.loading = true;
  859. let submitObj = other.deepClone(state.ruleForm);
  860. if (submitObj.nextHandlers && submitObj.nextHandlers.length) {
  861. if (submitObj.nextHandlers.length === 1) {
  862. submitObj.nextMainHandler = submitObj.nextHandlers[0].key;
  863. }
  864. }
  865. const request = {
  866. nextWorkflow: submitObj,
  867. // files: handleFiles.value,
  868. delayId: delayId.value,
  869. isPass: state.ruleForm.isPass,
  870. };
  871. delayBatchApprove(request)
  872. .then((res: any) => {
  873. emit('updateList');
  874. state.loading = false;
  875. closeDialog();
  876. ElNotification({
  877. title: '提示',
  878. type: 'info',
  879. dangerouslyUseHTMLString: true, // 允许使用 HTML 内容
  880. message: res.result,
  881. });
  882. })
  883. .catch((err: any) => {
  884. console.log(err, 'err');
  885. emit('updateList');
  886. closeDialog();
  887. });
  888. });
  889. };
  890. // 暴露变量
  891. defineExpose({
  892. openDialog,
  893. closeDialog,
  894. });
  895. </script>
  896. <style lang="scss">
  897. .modal_class {
  898. pointer-events: none;
  899. height: 100%;
  900. }
  901. .dialog_class {
  902. pointer-events: auto;
  903. flex-direction: column;
  904. margin: 0 !important;
  905. position: absolute;
  906. top: 20%;
  907. left: 25%;
  908. }
  909. </style>