LZProcess.vue 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  1. <template>
  2. <!-- 本组件暂时只包含自贡的受理和办理流程 其他的流程后面提了看需求是单独写还是放在组件内 -->
  3. <el-dialog
  4. v-model="state.dialogVisible"
  5. draggable
  6. :title="state.dialogTitle"
  7. ref="dialogRef"
  8. @mouseup="mouseup"
  9. :style="'transform: ' + state.transform + ';'"
  10. destroy-on-close
  11. :close-on-click-modal="false"
  12. @close="close"
  13. :modal-class="isOrderAccept ? 'modal_class' : ''"
  14. :class="isOrderAccept ? 'dialog_class' : ''"
  15. :append-to-body="!isOrderAccept"
  16. :modal="!isOrderAccept"
  17. >
  18. <el-form :model="state.ruleForm" label-width="110px" ref="ruleFormRef" v-loading="state.loading">
  19. <slot name="header"></slot>
  20. <el-row :gutter="10">
  21. <!-- <el-col>
  22. <el-form-item label="当前选择的流程">
  23. {{ seatTopaidan ? '话务部到派单组' : '' }}
  24. {{ seatToOrgOne ? '话务部到一级部门' : '' }}
  25. {{ paidanToOrgOne ? '派单组到一级部门' : '' }}
  26. {{ paidanToEnd ? '派单组到归档' : '' }}
  27. {{ orgOneToEnd ? '一级部门到归档' : '' }}
  28. {{ orgToOrg ? '部门到部门' : '' }}
  29. {{ orgToOrgSummary ? '部门到汇总节点' : '' }}
  30. {{ orgSummaryToOrgSummary ? '部门汇总到部门汇总' : '' }}
  31. {{ orgSummaryToEnd ? '部门汇总到归档' : '' }}
  32. {{ orgToOrgLeader ? '部门到部门领导' : '' }}
  33. </el-form-item>
  34. </el-col>-->
  35. <!-- 退回流程 -->
  36. <template v-if="returnArr.includes(state.processType)">
  37. <el-col v-if="isShowReturnSms">
  38. <el-form-item prop="isSms">
  39. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" />
  40. </el-form-item>
  41. </el-col>
  42. </template>
  43. <!-- 办理流程 -->
  44. <template v-else>
  45. <el-col v-if="orderContent">
  46. <el-form-item label="受理内容">
  47. <text-ellipsis :content="orderContent" :rows="1"> </text-ellipsis>
  48. </el-form-item>
  49. </el-col>
  50. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  51. <el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
  52. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
  53. <el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
  54. </el-select>
  55. </el-form-item>
  56. </el-col>
  57. <!-- 工单办理专有参数 办理时限 -->
  58. <template v-if="flowDirection">
  59. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  60. <el-form-item label="办理时限" prop="timeLimit" :rules="[{ required: true, message: '请填写办理时限', trigger: 'blur' }]">
  61. <el-row :gutter="10">
  62. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  63. <el-input-number
  64. placeholder="办理时限"
  65. v-model="state.ruleForm.timeLimit"
  66. controls-position="right"
  67. class="w100"
  68. :min="1"
  69. :max="99"
  70. ></el-input-number>
  71. </el-col>
  72. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-loading="state.loading">
  73. <el-form-item
  74. label-width="0"
  75. prop="timeLimitUnit"
  76. :rules="[{ required: true, message: '请选择办理时限单位', trigger: 'change' }]"
  77. >
  78. <el-select v-model="state.ruleForm.timeLimitUnit" placeholder="办理时限单位" disabled style="width: 240px">
  79. <el-option v-for="item in timeTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
  80. </el-select>
  81. </el-form-item>
  82. </el-col>
  83. </el-row>
  84. </el-form-item>
  85. </el-col>
  86. </template>
  87. <!-- 非退回流程都需要选择并且如果选择了结束节点就不需要选择办理对象 -->
  88. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showHandlers">
  89. <el-form-item
  90. label="办理对象"
  91. prop="nextHandlers"
  92. :rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]"
  93. >
  94. <el-select-v2
  95. v-model="state.ruleForm.nextHandlers"
  96. :options="state.handlerOptions"
  97. placeholder="请选择办理对象"
  98. class="w100"
  99. multiple
  100. clearable
  101. collapse-tags
  102. collapse-tags-tooltip
  103. filterable
  104. value-key="key"
  105. @change="selectHandlers"
  106. :multiple-limit="multipleLimit"
  107. />
  108. </el-form-item>
  109. </el-col>
  110. <!-- 复选框参数 -->
  111. <el-col :span="24" v-if="isSmsSelectShow || seatTopaidan || seatToOrgOne || paidanToOrgOne || paidanToEnd">
  112. <el-form-item prop="isSms">
  113. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" v-if="isSmsSelectShow" :key="Math.random()" />
  114. <el-checkbox v-model="state.ruleForm.isForwarded" label="是否转办" v-if="seatTopaidan || seatToOrgOne" :key="Math.random()" />
  115. <template v-if="paidanToOrgOne || paidanToEnd">
  116. <el-checkbox v-model="state.ruleForm.isStepUrgent" label="紧急" :key="Math.random()" />
  117. <el-checkbox v-model="state.ruleForm.isEvasive" label="推诿" :key="Math.random()" />
  118. <el-checkbox v-model="state.ruleForm.isInactively" label="不积极" :key="Math.random()" />
  119. </template>
  120. </el-form-item>
  121. </el-col>
  122. <!-- 话务部到一级部门 派单组到一级部门 -->
  123. <template v-if="seatToOrgOne || paidanToOrgOne">
  124. <el-col :span="24">
  125. <el-form-item label="派单类型" prop="orderAssignMode" :rules="[{ required: true, message: '请选择派单类型', trigger: 'change' }]">
  126. <el-radio-group v-model="state.ruleForm.orderAssignMode" @change="selectDispatchType">
  127. <el-radio :value="0">逐级派单</el-radio>
  128. <el-radio :value="1">跨级派单</el-radio>
  129. <!-- <el-radio :value="2">主协办</el-radio>-->
  130. </el-radio-group>
  131. </el-form-item>
  132. </el-col>
  133. <el-col :span="24" v-if="state.ruleForm.orderAssignMode === 0">
  134. <el-row class="w100">
  135. <el-col :span="12">
  136. <el-form-item label="接办部门" prop="nextHandlers" :rules="[{ required: true, message: '请选择接办部门', trigger: 'change' }]">
  137. <!-- <el-select v-model="state.ruleForm.paidanObj" placeholder="请选择接办部门" class="w100" filterable multiple>
  138. <el-option v-for="item in state.paidanObjOptions" :key="item.key" :label="item.value" :value="item.key" />
  139. </el-select>-->
  140. <el-select-v2
  141. v-model="state.ruleForm.nextHandlers"
  142. :options="state.handlerOptions"
  143. placeholder="请选择接办部门"
  144. class="w100"
  145. multiple
  146. clearable
  147. collapse-tags
  148. collapse-tags-tooltip
  149. filterable
  150. value-key="key"
  151. @change="selectHandlers"
  152. :multiple-limit="multipleLimit"
  153. />
  154. </el-form-item>
  155. </el-col>
  156. <el-col :span="12" v-if="countersignAble">
  157. <el-form-item
  158. label="发起会签"
  159. prop="isStartCountersign"
  160. :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]"
  161. >
  162. <el-switch
  163. v-model="state.ruleForm.isStartCountersign"
  164. inline-prompt
  165. active-text="是"
  166. inactive-text="否"
  167. @change="changeStartCountersign"
  168. :disabled="countersignDisabled"
  169. />
  170. </el-form-item>
  171. </el-col>
  172. </el-row>
  173. </el-col>
  174. <el-col :span="24" v-if="state.ruleForm.orderAssignMode === 1">
  175. <el-row class="w100" :gutter="10">
  176. <el-col>
  177. <el-form-item label="接办部门" prop="nextHandler" :rules="[{ required: true, message: '请选择接办部门', trigger: 'change' }]">
  178. <el-select-v2
  179. v-model="state.ruleForm.nextHandler"
  180. :options="state.handlerOptions"
  181. placeholder="请选择接办部门"
  182. class="w100"
  183. clearable
  184. filterable
  185. value-key="key"
  186. @change="selectHandlers"
  187. />
  188. </el-form-item>
  189. </el-col>
  190. <!-- 二级部门 -->
  191. <template v-if="showOrgLevelTwo">
  192. <el-col :span="12">
  193. <el-form-item label="下一环节" prop="levelTwoStep" :rules="[{ required: false, message: '请选择下一环节', trigger: 'change' }]">
  194. <el-select-v2
  195. v-model="state.ruleForm.levelTwoStep"
  196. :options="levelTwoStepOptions"
  197. placeholder="请选择下一环节"
  198. class="w100"
  199. filterable
  200. value-key="key"
  201. clearable
  202. @change="selectOrgLevelTwo"
  203. />
  204. </el-form-item>
  205. </el-col>
  206. <el-col :span="12">
  207. <el-form-item
  208. label="办理对象"
  209. prop="levelTwoHandlers"
  210. :rules="[{ required: false, message: '请选择办理对象', trigger: 'change' }]"
  211. >
  212. <el-select-v2
  213. v-model="state.ruleForm.levelTwoHandlers"
  214. :options="levelTwoHandleOptions"
  215. placeholder="请选择办理对象"
  216. class="w100"
  217. clearable
  218. filterable
  219. value-key="key"
  220. multiple
  221. collapse-tags
  222. collapse-tags-tooltip
  223. :max-collapse-tags="1"
  224. @change="selectOrgLevelTwoHandler"
  225. />
  226. </el-form-item>
  227. </el-col>
  228. </template>
  229. <!-- 三级部门 -->
  230. <template v-if="showOrgLevelThree">
  231. <el-col :span="12">
  232. <el-form-item label="下一环节" prop="levelThreeStep" :rules="[{ required: false, message: '请选择下一环节', trigger: 'change' }]">
  233. <el-select-v2
  234. v-model="state.ruleForm.levelThreeStep"
  235. :options="levelThreeStepOptions"
  236. placeholder="请选择下一环节"
  237. class="w100"
  238. filterable
  239. value-key="key"
  240. clearable
  241. @change="selectOrgLevelThree"
  242. />
  243. </el-form-item>
  244. </el-col>
  245. <el-col :span="12">
  246. <el-form-item
  247. label="办理对象"
  248. prop="levelTwoHandlers"
  249. :rules="[{ required: false, message: '请选择办理对象', trigger: 'change' }]"
  250. >
  251. <el-select-v2
  252. v-model="state.ruleForm.levelThreeHandlers"
  253. :options="levelThreeHandleOptions"
  254. placeholder="请选择办理对象"
  255. class="w100"
  256. clearable
  257. filterable
  258. value-key="key"
  259. multiple
  260. collapse-tags
  261. collapse-tags-tooltip
  262. :max-collapse-tags="1"
  263. @change="selectOrgLevelThreeHandler"
  264. />
  265. </el-form-item>
  266. </el-col>
  267. </template>
  268. </el-row>
  269. </el-col>
  270. <el-col :span="24" v-if="state.ruleForm.orderAssignMode === 2">
  271. <el-form-item label="主办部门" prop="paidanObj" :rules="[{ required: true, message: '请选择主办部门', trigger: 'change' }]">
  272. <el-row class="w100" :gutter="20">
  273. <el-col :span="18">
  274. <el-select v-model="state.ruleForm.paidanObj" placeholder="请选择主办部门" class="w100" filterable>
  275. <el-option v-for="item in state.paidanObjOptions" :key="item.key" :label="item.value" :value="item.key" />
  276. </el-select>
  277. </el-col>
  278. <el-col :span="6">
  279. <el-checkbox v-model="state.ruleForm.zhipai">是否直派 </el-checkbox>
  280. </el-col>
  281. </el-row>
  282. </el-form-item>
  283. <el-row class="w100">
  284. <el-col :span="12">
  285. <el-form-item label="协办部门" prop="paidanObj" :rules="[{ required: false, message: '请选择协办部门', trigger: 'change' }]">
  286. <el-select v-model="state.ruleForm.paidanObj" placeholder="请选择协办部门" class="w100" filterable multiple>
  287. <el-option v-for="item in state.paidanObjOptions" :key="item.key" :label="item.value" :value="item.key" />
  288. </el-select>
  289. </el-form-item>
  290. </el-col>
  291. <el-col :span="12">
  292. <el-form-item label="抄送部门" prop="paidanObj" :rules="[{ required: false, message: '请选择抄送部门', trigger: 'change' }]">
  293. <el-select v-model="state.ruleForm.paidanObj" placeholder="请选择抄送部门" class="w100" filterable multiple>
  294. <el-option v-for="item in state.paidanObjOptions" :key="item.key" :label="item.value" :value="item.key" />
  295. </el-select>
  296. </el-form-item>
  297. </el-col>
  298. </el-row>
  299. </el-col>
  300. </template>
  301. <!-- 部门到部门 -->
  302. <template v-if="orgToOrg">
  303. <el-col>
  304. <el-row class="w100">
  305. <el-col :span="12">
  306. <el-form-item label="接办部门" prop="nextHandlers" :rules="[{ required: true, message: '请选择接办部门', trigger: 'change' }]">
  307. <el-select-v2
  308. v-model="state.ruleForm.nextHandlers"
  309. :options="state.handlerOptions"
  310. placeholder="请选择接办部门"
  311. class="w100"
  312. multiple
  313. clearable
  314. collapse-tags
  315. collapse-tags-tooltip
  316. filterable
  317. value-key="key"
  318. @change="selectHandlers"
  319. :multiple-limit="multipleLimit"
  320. />
  321. </el-form-item>
  322. </el-col>
  323. <el-col :span="12" v-if="countersignAble">
  324. <el-form-item
  325. label="发起会签"
  326. prop="isStartCountersign"
  327. :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]"
  328. >
  329. <el-switch
  330. v-model="state.ruleForm.isStartCountersign"
  331. inline-prompt
  332. active-text="是"
  333. inactive-text="否"
  334. @change="changeStartCountersign"
  335. :disabled="countersignDisabled"
  336. />
  337. </el-form-item>
  338. </el-col>
  339. </el-row>
  340. </el-col>
  341. </template>
  342. <!-- 派单组流转到归档 派单组到一级部门 -->
  343. <template v-if="paidanToOrgOne || paidanToEnd">
  344. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
  345. <el-form-item label="市州转办" prop="transpond" :rules="[{ required: false, message: '请选择市州转办', trigger: 'change' }]">
  346. <el-select v-model="state.ruleForm.transpond" placeholder="请选择市州转办" class="w100" @change="changeTransPond">
  347. <el-option :key="true" label="是" :value="true" />
  348. <el-option :key="false" label="否" :value="false" />
  349. </el-select>
  350. </el-form-item>
  351. </el-col>
  352. <!-- 必填,若“是否市州互转”为“是”,则展示选择市州选择框 -->
  353. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="state.ruleForm.transpond">
  354. <el-form-item prop="transpondCityObj" label-width="10px" :rules="[{ required: true, message: '请选择转办市州', trigger: 'change' }]">
  355. <el-select
  356. v-model="state.ruleForm.transpondCityObj"
  357. placeholder="请选择转办市州"
  358. class="w100"
  359. value-key="dicDataValue"
  360. @change="changeTranspondCity"
  361. clearable
  362. >
  363. <el-option v-for="item in transpondCity" :key="item.dicDataValue" :label="item.dicDataName" :value="item" />
  364. </el-select>
  365. </el-form-item>
  366. </el-col>
  367. </template>
  368. <!-- 派单组到一级部门 -->
  369. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12" v-if="paidanToOrgOne">
  370. <el-form-item label="领导短信" prop="leaderSMSKey" :rules="[{ required: false, message: '请选择领导短信', trigger: 'change' }]">
  371. <el-select v-model="state.ruleForm.leaderSMSKey" placeholder="请选择领导短信" class="w100" filterable clearable>
  372. <el-option v-for="item in leaderSMS" :key="item.key" :label="item.value" :value="item.key" />
  373. </el-select>
  374. </el-form-item>
  375. </el-col>
  376. <!-- 一级部门流转到归档 或者 部门流转至部门汇总 并且不能是会签-->
  377. <template v-if="(orgOneToEnd || orgToOrgSummary) && !isCountersign && ['ZiGong'].includes(themeConfig.appScope)">
  378. <el-col :span="24">
  379. <el-form-item prop="checkedCities" :rules="[{ required: true, message: '至少选择一项', trigger: 'change' }]">
  380. <el-checkbox-group v-model="state.ruleForm.checkedCities" @change="changeCheckBox">
  381. <el-checkbox value="0" label="已与市民电话联系,确认办理结果" />
  382. <el-checkbox value="1" label="已赴现场处置,将处理结果告知市民" />
  383. <el-checkbox value="2" label="其他" />
  384. </el-checkbox-group>
  385. </el-form-item>
  386. </el-col>
  387. <el-col :span="24">
  388. <el-form-item label="其他原因" prop="otherRemark" :rules="[{ required: false, message: '请填写其他原因', trigger: 'blur' }]">
  389. <el-input v-model="state.ruleForm.otherRemark" placeholder="请填写其他原因"> </el-input>
  390. </el-form-item>
  391. </el-col>
  392. <el-col :xs="24" :sm="8" :md="8" :lg="8">
  393. <el-form-item prop="realHandlerName" :rules="[{ required: true, message: '请填写经办人姓名', trigger: 'blur' }]">
  394. <el-input v-model="state.ruleForm.realHandlerName" placeholder="经办人姓名" autocomplete="on"> </el-input>
  395. </el-form-item>
  396. </el-col>
  397. <el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
  398. <el-form-item prop="realHandlerPhone" label-width="0" :rules="[{ required: true, message: '请填写经办人电话', trigger: 'blur' }]">
  399. <el-input v-model="state.ruleForm.realHandlerPhone" placeholder="经办人电话" autocomplete="on"> </el-input>
  400. </el-form-item>
  401. </el-col>
  402. <el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
  403. <el-form-item
  404. prop="realCommunicationTime"
  405. :xl="8"
  406. label-width="0"
  407. :rules="[{ required: true, message: '请选择沟通时间', trigger: 'change' }]"
  408. >
  409. <el-date-picker
  410. v-model="state.ruleForm.realCommunicationTime"
  411. type="datetime"
  412. placeholder="沟通时间"
  413. class="w100"
  414. clearable
  415. value-format="YYYY-MM-DD[T]HH:mm:ss"
  416. />
  417. </el-form-item>
  418. </el-col>
  419. <el-col :span="24">
  420. <el-form-item
  421. label="沟通地点"
  422. prop="realCommunicationAddress"
  423. :rules="[{ required: true, message: '请填写沟通地点', trigger: 'blur' }]"
  424. >
  425. <el-input v-model="state.ruleForm.realCommunicationAddress" placeholder="请填写沟通地点"> </el-input>
  426. </el-form-item>
  427. </el-col>
  428. </template>
  429. <!-- 选择结束节点时并且是工单办理并且工单来源是110时,显示警情退回 -->
  430. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showPoliceReturn">
  431. <el-form-item label="" prop="isPoliceReturn">
  432. <el-checkbox v-model="state.ruleForm.isPoliceReturn" label="警情退回" />
  433. </el-form-item>
  434. </el-col>
  435. </template>
  436. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  437. <el-form-item
  438. :label="state.inputPlaceholder"
  439. prop="opinion"
  440. :rules="[
  441. { required: true, message: `请填写${state.inputPlaceholder}`, trigger: 'blur' },
  442. { required: true, pattern: '[^ \x20]+', trigger: 'blur', message: `${state.inputPlaceholder}不能为空` },
  443. ]"
  444. >
  445. <common-advice
  446. @chooseAdvice="chooseAdvice"
  447. v-model="state.ruleForm.opinion"
  448. :placeholder="'请填写' + state.inputPlaceholder"
  449. :loading="state.loading"
  450. :commonEnum="commonOpinionType"
  451. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  452. />
  453. </el-form-item>
  454. </el-col>
  455. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" v-if="showRemarkTextarea">
  456. <el-form-item label="备注信息" prop="remark" :rules="[{ required: false, message: `请填写备注信息`, trigger: 'blur' }]">
  457. <el-input v-model="state.ruleForm.remark" :rows="2" type="textarea" placeholder="请填写备注信息" />
  458. </el-form-item>
  459. </el-col>
  460. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  461. <el-form-item label="附件" :rules="[{ required: false, message: '请选择附件', trigger: 'change' }]">
  462. <annex-list :name="state.annexName" :businessId="state.orderDetail.id" :classify="state.classify" v-model:format="handleFiles" />
  463. </el-form-item>
  464. </el-col>
  465. <!-- <el-col v-if="isOverdueTips" :span="24">
  466. <el-alert type="warning" show-icon title="注意"> 该工单属于超期状态,若符合延期要求,请延期通过后办结,是否继续办理 </el-alert>
  467. </el-col>-->
  468. </el-row>
  469. </el-form>
  470. <template #footer>
  471. <span class="dialog-footer">
  472. <el-text type="danger" class="mr15" tag="b" v-if="showTempSave">温馨提示:临时保存只保存{{ state.inputPlaceholder }}</el-text>
  473. <el-button @click="closeDialog" class="default-button">取消</el-button>
  474. <el-button type="primary" @click="handleTempSave" :loading="state.loading" v-if="showTempSave">临时保存</el-button>
  475. <template v-if="seatTopaidan || seatToOrgOne">
  476. <el-popconfirm title="确定当前工单为中心直办件?" v-if="!state.ruleForm.isForwarded" @confirm="onSubmit(ruleFormRef)" width="230">
  477. <template #reference>
  478. <el-button type="primary" :loading="state.loading">办理</el-button>
  479. </template>
  480. </el-popconfirm>
  481. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading" v-else>办理</el-button>
  482. </template>
  483. <template v-else>
  484. <el-popconfirm
  485. title="该工单属于超期状态,若符合延期要求,请延期通过后办结,是否继续办理?"
  486. v-if="isOverdueTips"
  487. @confirm="onSubmit(ruleFormRef)"
  488. width="300"
  489. >
  490. <template #reference>
  491. <el-button type="primary" :loading="state.loading">办理</el-button>
  492. </template>
  493. </el-popconfirm>
  494. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading" v-else>办理</el-button>
  495. </template>
  496. </span>
  497. </template>
  498. </el-dialog>
  499. </template>
  500. <script setup lang="ts" name="processApproval">
  501. import { computed, defineAsyncComponent, nextTick, reactive, ref, watch } from 'vue';
  502. import { ElMessage, FormInstance } from 'element-plus';
  503. import other from '@/utils/other';
  504. import { storeToRefs } from 'pinia';
  505. import { commonEnum } from '@/utils/constants';
  506. import {
  507. getDepartmentList,
  508. orderAssignParams,
  509. orderFlowParams,
  510. orderHandle,
  511. orderProcessTempSave,
  512. orderReturnParams,
  513. orderStartFlow,
  514. orderTimeConfig,
  515. } from '@/api/business/order';
  516. import { orderPrevious, workflowNextSteps, workflowNextStepsByOrder, workflowNextStepsByOrderInstead } from '@/api/system/workflow';
  517. import { useAppConfig } from '@/stores/appConfig';
  518. import { useThemeConfig } from '@/stores/themeConfig';
  519. // 引入组件
  520. const CommonAdvice = defineAsyncComponent(() => import('@/components/CommonAdvice/index.vue')); // 常用意见
  521. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件列表
  522. const TextEllipsis = defineAsyncComponent(() => import('@/components/TextEllipsis/index.vue'));
  523. // 定义子组件向父组件传值/事件
  524. const emit = defineEmits(['orderProcessSuccess', 'orderProcessFailed']);
  525. // 定义变量内容
  526. const state = reactive<any>({
  527. dialogVisible: false, // 弹窗显示隐藏
  528. ruleForm: {
  529. opinion: '', // 意见
  530. nextStepCode: '', // 下一节点
  531. nextStepName: '', // 下一节点名称
  532. backToCountersignEnd: false, // 是否回到会签结束节点
  533. nextHandlers: [], // 下一节点办理对象
  534. nextHandler: null, // 单选对象
  535. isSms: false, // 是否短信通知
  536. isStartCountersign: false, // 是否发起会签
  537. stepId: null, // 步骤id
  538. isForwarded: false, // 是否转办
  539. isStepUrgent: null, // 是否紧急
  540. isEvasive: null, // 是否推诿
  541. isInactively: null, // 是否不积极
  542. leaderSMSKey: null, // 领导短信key
  543. realHandlerName: null, // 办理人姓名
  544. realHandlerPhone: null, // 办理人电话
  545. realCommunicationTime: null, // 沟通时间
  546. realCommunicationAddress: null, //沟通地点
  547. realIsContacted: null, //已与市民沟通 已与市民电话联系,确认办理结果
  548. realContactLocale: null, // 已与市民现场沟通 已赴现场处置,将处理结果告知市民
  549. isOther: null, // 其它
  550. otherRemark: null, // 其它原因
  551. transpond: false, // 市州转办
  552. transpondCityName: null, // 市州转办信息
  553. transpondCityId: null, // 市州转办信息id
  554. transpondCityValue: null, // 市州转办信息
  555. orderAssignMode: 0, // 派单类型默认逐级派单
  556. copyToHandlers: [], // 抄送对象
  557. },
  558. nextStepOptions: [], // 下一节点
  559. handlerOptions: [], // 办理对象
  560. transform: 'translate(0px, 0px)', // 滚动条位置
  561. loading: false, // 提交按钮loading
  562. processType: 'next', // 流程状态
  563. workflowId: '', // 流程id
  564. handleId: '', // 流程处理ID
  565. dialogTitle: '', // 弹窗标题
  566. annexName: '', // 附件标题
  567. inputPlaceholder: '办理意见', // 意见提示
  568. orderDetail: {}, // 工单详情
  569. });
  570. const ruleFormRef = ref<RefType>(); //表单组件
  571. const handelArr = ['工单办理', '工单代办', '工单受理']; // 处于办理状态的流程
  572. const returnArr = ['工单退回']; // 退回流程 (退回流程不需要展示其他 只需要填写意见和附件即可)
  573. const appConfigStore = useAppConfig();
  574. const { AppConfigInfo } = storeToRefs(appConfigStore); // 系统配置信息
  575. const showTempSave = computed(() => {
  576. // 是否显示临时办理
  577. return ['工单办理', '工单代办', '工单受理'].includes(state.processType);
  578. });
  579. const storesThemeConfig = useThemeConfig();
  580. const { themeConfig } = storeToRefs(storesThemeConfig);
  581. // 打开弹窗
  582. const openDialog = async (val: any) => {
  583. console.log(val);
  584. selectNext.value = {};
  585. currentParams.value = {};
  586. state.ruleForm.nextHandlers = [];
  587. state.ruleForm.nextHandler = {};
  588. isSmsSelectShow.value = false;
  589. isNotShowNextHandlers.value = false;
  590. state.ruleForm.isSms = false;
  591. state.loading = true;
  592. state.dialogVisible = true;
  593. try {
  594. const { id, processType, extra, orderDetail } = val;
  595. state.ruleForm.workflowId = state.workflowId = id ?? ''; // 流程id
  596. state.processType = processType ?? '办理流程'; // 业务类型
  597. state.orderDetail = orderDetail ?? {}; // 工单详情
  598. state.ruleForm.isStepUrgent = orderDetail.isStepUrgent; // 是否紧急
  599. state.ruleForm.isEvasive = orderDetail.isEvasive; // 是否推诿
  600. state.ruleForm.isInactively = orderDetail.isInactively; // 是否不积极
  601. const { dialogTitle, inputPlaceholder, annexName, classify } = extra ?? {};
  602. state.dialogTitle = dialogTitle ?? '提交流程'; // 流程标题
  603. state.annexName = annexName ?? '办理附件'; // 附件标题
  604. state.classify = classify ?? '办理上传'; // 附件分类
  605. state.inputPlaceholder = inputPlaceholder ?? '办理意见'; // 意见提示
  606. switch (state.processType) {
  607. case '工单受理': //开始流程
  608. const [orderStartWorkflowResponse] = await Promise.all([orderFlowParams(orderDetail.id)]); //获取开启流程参数
  609. handleResult(orderStartWorkflowResponse);
  610. break;
  611. case '工单退回': // 退回流程
  612. const workflowReturnResponse = await orderReturnParams(state.orderDetail.id);
  613. handleResultReturn(workflowReturnResponse);
  614. break;
  615. case '工单办理': // 工单办理
  616. const [workflowNextStepsResponse] = await Promise.all([workflowNextStepsByOrder(state.orderDetail.id)]); // 获取下一节点和下一节点参数
  617. handleResult(workflowNextStepsResponse);
  618. break;
  619. case '工单代办':
  620. const [orderHandleInstanceResponse] = await Promise.all([workflowNextStepsByOrderInstead(state.orderDetail.id)]); // 工单代办参数获取
  621. handleResult(orderHandleInstanceResponse);
  622. break;
  623. default: // 默认下一流程 工单办理
  624. // 获取下一节点和下一节点参数
  625. const [nextResponse] = await Promise.all([workflowNextSteps(state.workflowId)]);
  626. handleResult(nextResponse);
  627. break;
  628. }
  629. await nextTick(() => {
  630. restForm(ruleFormRef.value);
  631. });
  632. } finally {
  633. state.loading = false;
  634. }
  635. };
  636. // 处理退回 currentBusinessType 表示选择节点到哪一步 0 坐席 1派单 2部门节点 3部门领导节点
  637. // targetBusinessType 0 坐席 1派单 2部门节点 3部门领导节点
  638. const isShowReturnSms = ref(false);
  639. const handleResultReturn = (res: any) => {
  640. // 部门退部门需要默认选中短信
  641. if (res.result.currentBusinessType === 2 && res.result.targetBusinessType === 2) {
  642. isShowReturnSms.value = true;
  643. state.ruleForm.isSms = true;
  644. } else {
  645. isShowReturnSms.value = false;
  646. state.ruleForm.isSms = false;
  647. }
  648. };
  649. const isOrderAccept = computed(() => {
  650. return state.processType === '工单受理';
  651. });
  652. // 常用意见类型
  653. const commonOpinionType = computed(() => {
  654. switch (state.processType) {
  655. case '工单受理':
  656. return commonEnum.Seat;
  657. case '工单退回':
  658. return commonEnum.Return;
  659. case '工单办理':
  660. return commonEnum.OrderCirculation;
  661. default:
  662. return commonEnum.OrderCirculation;
  663. }
  664. });
  665. const timeTypeOptions = ref<EmptyArrayType>([]); // 办理时限单位
  666. const canStartCountersign = ref<boolean>(false); // 是否可以发起会签
  667. const isMainHandlerShow = ref<boolean>(false); // 是否展示主办人
  668. const currentParams = ref<EmptyObjectType>({}); // 当前获取到的参数(当前节点信息)
  669. const leaderSMS = ref<EmptyArrayType>([]); // 领导短信选择
  670. const transpondCity = ref<EmptyArrayType>([]); // 市州互转选择
  671. const orderContent = ref<string>(''); // 受理内容
  672. const handleResult = (res: any) => {
  673. currentParams.value = res.result;
  674. state.nextStepOptions = res.result.steps; //办理对象选择内容
  675. timeTypeOptions.value = res.result.timeTypeOptions ?? []; // 办理时限申请单位
  676. canStartCountersign.value = res.result.canStartCountersign ?? false; // 是否可以发起会签
  677. isMainHandlerShow.value = res.result.isMainHandlerShow ?? false; // 是否展示主办人
  678. leaderSMS.value = res.result.leaderSMS ?? []; // 领导短信选择
  679. transpondCity.value = res.result.transpondCity ?? []; // 市州互转
  680. orderContent.value = res.result.content ?? ''; // 受理内容
  681. if (handelArr.includes(state.processType)) {
  682. // 办理才有期满时间
  683. state.ruleForm.expiredTime = res.result.expiredTime ?? null; // 期满时间
  684. }
  685. if (state.nextStepOptions.length === 1) {
  686. // 下一节点是否只有一个 默认选中第一个
  687. setTimeout(() => {
  688. state.ruleForm.nextStepCode = state.nextStepOptions[0].key; // 下一节点code
  689. state.ruleForm.nextStepName = state.nextStepOptions[0].value; // 下一节点name
  690. state.ruleForm.backToCountersignEnd = state.nextStepOptions[0].backToCountersignEnd ?? false; // 是否回到会签结束节点
  691. }, 100);
  692. selectNextStep(state.nextStepOptions[0].key); // 查询流程下一节点参数
  693. } else {
  694. state.ruleForm.nextStepCode = '';
  695. state.ruleForm.nextStepName = '';
  696. }
  697. if (res.result.opinion) {
  698. // 如果有汇总意见没有临时保存 取汇总意见 临时保存会覆盖汇总意见
  699. setTimeout(() => {
  700. state.ruleForm.opinion = res.result.opinion;
  701. }, 100);
  702. }
  703. state.ruleForm.stepId = res.result.stepId;
  704. };
  705. // 先确定当前环节是那一步
  706. /*
  707. * currentParams.value.currentStepBusinessType 表示当前节点到哪一步 0坐席 1派单 2部门节点 3部门领导节点
  708. * */
  709. /*selectNext.value.businessType 表示选择节点到哪一步 0 坐席 1派单 2部门节点 3部门领导节点
  710. * selectNext.value.orgLevel 表示部门等级 1 一级部门 2 二级部门 3 三级部门 4 四级部门
  711. * selectNext.value.stepType 0普通节点 3汇总节点
  712. * */
  713. // 话务部到派单组
  714. const seatTopaidan = computed(() => {
  715. return currentParams.value.currentStepBusinessType === 0 && selectNext.value.businessType === 1;
  716. });
  717. // 话务部到一级部门
  718. const seatToOrgOne = computed(() => {
  719. return currentParams.value.currentStepBusinessType === 0 && selectNext.value.businessType === 2 && selectNext.value.orgLevel === 1;
  720. });
  721. // 派单组到一级部门
  722. const paidanToOrgOne = computed(() => {
  723. return currentParams.value.currentStepBusinessType === 1 && selectNext.value.businessType === 2 && selectNext.value.orgLevel === 1;
  724. });
  725. // 派单组到归档
  726. const paidanToEnd = computed(() => {
  727. return currentParams.value.currentStepBusinessType === 1 && selectNext.value.key === 'end';
  728. });
  729. // 一级部门到归档
  730. const orgOneToEnd = computed(() => {
  731. return (
  732. currentParams.value.currentStepBusinessType === 2 &&
  733. currentParams.value.currentStepType !== 3 &&
  734. currentParams.value.currentOrgLevel === 1 &&
  735. selectNext.value.key === 'end'
  736. );
  737. });
  738. // 部门流转到部门
  739. const orgToOrg = computed(() => {
  740. return currentParams.value.currentStepBusinessType === 2 && selectNext.value.businessType === 2 && selectNext.value.stepType !== 3;
  741. });
  742. // 部门到部门汇总
  743. const orgToOrgSummary = computed(() => {
  744. return (
  745. currentParams.value.currentStepBusinessType === 2 &&
  746. currentParams.value.currentStepType !== 3 &&
  747. selectNext.value.businessType === 2 &&
  748. selectNext.value.stepType === 3
  749. );
  750. });
  751. // 部门流转到部门领导
  752. const orgToOrgLeader = computed(() => {
  753. return currentParams.value.currentStepBusinessType === 2 && selectNext.value.businessType === 3 && selectNext.value.key !== 'end';
  754. });
  755. // 部门退回部门 当前节点是部门 并且 部门等级大于1 需要展示短信并且默认勾选
  756. const orgReturnOrg = computed(() => {
  757. return currentParams.value.currentStepBusinessType === 2 && selectNext.value.orgLevel > 1;
  758. });
  759. // 部门汇总到部门汇总
  760. const orgSummaryToOrgSummary = computed(() => {
  761. return (
  762. currentParams.value.currentStepBusinessType === 2 &&
  763. currentParams.value.currentStepType === 3 &&
  764. selectNext.value.businessType === 2 &&
  765. selectNext.value.stepType === 3
  766. );
  767. });
  768. // 部门汇总到归档
  769. const orgSummaryToEnd = computed(() => {
  770. return (
  771. currentParams.value.currentStepBusinessType === 2 &&
  772. currentParams.value.currentStepType === 3 &&
  773. currentParams.value.currentOrgLevel === 1 &&
  774. selectNext.value.key === 'end'
  775. );
  776. });
  777. // 判断当前节点是否在会签中 0中心会签 1部门会签
  778. const isCountersign = computed(() => {
  779. return currentParams.value.counterSignType !== null;
  780. });
  781. // expiredStatus 超期状态(0正常 1即将超期 2已超期) 工单流转选择“结束”节点,点击“办理”时需验证该工单是否处于已超期状态
  782. const isOverdueTips = computed(() => {
  783. return state.orderDetail.expiredStatus === 2 && state.ruleForm.nextStepCode === 'end';
  784. });
  785. // 是否展示短信通知选择
  786. const isSmsSelectShow = ref(false);
  787. // 是否不展示办理对象
  788. const isNotShowNextHandlers = ref(false);
  789. // 重置表单内容
  790. const restFormData = () => {
  791. state.ruleForm.nextHandlers = [];
  792. state.ruleForm.nextHandler = {};
  793. /* state.ruleForm.isStepUrgent = null;
  794. state.ruleForm.isEvasive = null;
  795. state.ruleForm.isInactively = null;*/
  796. state.ruleForm.leaderSMSKey = null;
  797. state.ruleForm.realHandlerName = null;
  798. state.ruleForm.realHandlerPhone = null;
  799. state.ruleForm.realCommunicationTime = null;
  800. state.ruleForm.realCommunicationAddress = null;
  801. state.ruleForm.realIsContacted = null;
  802. state.ruleForm.realContactLocale = null;
  803. state.ruleForm.isOther = null;
  804. state.ruleForm.otherRemark = null;
  805. state.ruleForm.transpond = false;
  806. state.ruleForm.transpondCityName = null;
  807. state.ruleForm.transpondCityId = null;
  808. state.ruleForm.orderAssignMode = 0;
  809. state.ruleForm.copyToHandlers = [];
  810. showOrgLevelTwo.value = false;
  811. state.ruleForm.levelTwoStep = null;
  812. levelTwoStepOptions.value = [];
  813. levelTwoHandleOptions.value = [];
  814. state.ruleForm.levelTwoHandlers = [];
  815. showOrgLevelThree.value = false;
  816. state.ruleForm.levelThreeStep = null;
  817. state.ruleForm.levelThreeHandlers = [];
  818. levelThreeStepOptions.value = [];
  819. levelThreeHandleOptions.value = [];
  820. };
  821. // 办理对象是否必填
  822. const nextHandlersRequired = ref<Boolean>(false);
  823. // 流程选择下一环节
  824. const selectNext = ref<EmptyObjectType>({}); // 选择的下一个节点
  825. const selectNextStep = (val: any) => {
  826. ruleFormRef.value?.resetFields('nextHandlers');
  827. ruleFormRef.value?.resetFields('nextHandler');
  828. restFormData();
  829. const next = state.nextStepOptions.find((item: any) => item.key === val);
  830. selectNext.value = next;
  831. const items = next.items; //获取下一节点
  832. state.ruleForm.nextStepName = next.value; // 下一节点name
  833. state.ruleForm.handlerType = next.handlerType;
  834. state.ruleForm.businessType = next.businessType;
  835. state.ruleForm.stepType = next.stepType;
  836. state.ruleForm.flowDirection = next.flowDirection;
  837. state.ruleForm.backToCountersignEnd = next.backToCountersignEnd ?? false; // 是否回到会签结束节点
  838. state.handlerOptions = items ?? [];
  839. state.handlerOptions = state.handlerOptions.map((item: any) => {
  840. return {
  841. value: {
  842. ...item,
  843. },
  844. label: item.value,
  845. };
  846. });
  847. if (items.length === 1) {
  848. // 如果办理对象只有一个默认选中
  849. state.ruleForm.nextHandlers = [items[0]];
  850. }
  851. // 如果是泸州所有流转到派单组节点的都需要必填办理对象
  852. nextHandlersRequired.value = selectNext.value.businessType === 1;
  853. // 以下是默认需要吧短信勾上的场景 话务到部门、派单到一级部门、部门到部门、部门到汇总、部门到部门领导 部门退回到部门
  854. state.ruleForm.isSms =
  855. seatToOrgOne.value || paidanToOrgOne.value || orgToOrg.value || orgToOrgSummary.value || orgToOrgLeader.value || orgReturnOrg.value;
  856. // 是否展示短信通知 (话务部到一级部门 派单组到一级部门 部门流转到部门 部门到汇总 部门流转到部门领导 部门退回到部门)
  857. isSmsSelectShow.value =
  858. seatToOrgOne.value || paidanToOrgOne.value || orgToOrg.value || orgToOrgSummary.value || orgToOrgLeader.value || orgReturnOrg.value;
  859. // 是否不展示办理对象 (话务部到一级部门 派单组到一级部门 派单到归档 一级部门到归档 部门到部门 部门到汇总)
  860. isNotShowNextHandlers.value =
  861. seatToOrgOne.value ||
  862. paidanToOrgOne.value ||
  863. paidanToEnd.value ||
  864. orgOneToEnd.value ||
  865. orgToOrg.value ||
  866. orgToOrgSummary.value ||
  867. orgSummaryToEnd.value;
  868. };
  869. // 会签是否可用 (配置可以会签 并且选择的是逐级派单,并且是普通节点 并且选择是部门)
  870. const countersignAble = computed(() => {
  871. return canStartCountersign.value && state.ruleForm.orderAssignMode === 0 && selectNext.value.stepType === 0 && selectNext.value.businessType === 2;
  872. });
  873. // 办理对象是否能够选择多个(可以发起会签可以选择多个,不能发起会签只能选择一个) 加个判断 选择的下一环节必须是部门(会签必须是选择的部门)
  874. const multipleLimit = computed(() => {
  875. return canStartCountersign.value && selectNext.value.businessType === 2 ? 0 : 1;
  876. });
  877. watch(
  878. () => state.ruleForm.nextHandlers, // 监听办理对象 多个办理对象自动发起会签
  879. (val) => {
  880. if (val) {
  881. state.ruleForm.isStartCountersign = val.length > 1;
  882. }
  883. }
  884. );
  885. const countersignDisabled = computed(() => {
  886. // (选中的办理对象如果是一个) 因为是disabled 所以这里取反
  887. return !(state.ruleForm.nextHandlers.length === 1);
  888. });
  889. // 是否发起会签
  890. const changeStartCountersign = (val: boolean) => {
  891. /* if (!val) {
  892. // 如果不能会签清空办理对象
  893. state.ruleForm.nextHandlers = [];
  894. ruleFormRef.value?.resetFields('nextHandlers');
  895. }*/
  896. };
  897. // 选择派单类型 需要清空选择的内容
  898. const selectDispatchType = () => {
  899. ruleFormRef.value.resetFields('nextHandlers');
  900. ruleFormRef.value.resetFields('nextHandler');
  901. state.ruleForm.nextHandlers = [];
  902. state.ruleForm.nextHandler = null;
  903. state.ruleForm.isStartCountersign = false;
  904. showOrgLevelTwo.value = false;
  905. state.ruleForm.levelTwoStep = null;
  906. levelTwoStepOptions.value = [];
  907. levelTwoHandleOptions.value = [];
  908. state.ruleForm.levelTwoHandlers = [];
  909. showOrgLevelThree.value = false;
  910. state.ruleForm.levelThreeStep = null;
  911. state.ruleForm.levelThreeHandlers = [];
  912. levelThreeStepOptions.value = [];
  913. levelThreeHandleOptions.value = [];
  914. };
  915. // 是否展示办理对象 (办理对象下拉框隐藏:AppConfigInfo.value.isAverageSendOrder= true 表示开启了平均派单 )
  916. // 话务部到一级部门部不展示办理对象 派单组到一级部门不展示办理对象 派单组流转到归档不展示办理对象 一级部门流转到归档不展示办理对象 xx部门流转到xx部门 不展示办理对象 xx部门流转至xx部门汇总;不展示办理对象
  917. const showHandlers = computed(() => {
  918. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  919. const isAverageSendOrder = AppConfigInfo.value.isAverageSendOrder && next?.businessType === 1; // 开启平均派单
  920. if (!next) return true;
  921. // !isAverageSendOrder && 自贡的需求是如果选择了办理对象,则平均派单无效
  922. return !isNotShowNextHandlers.value;
  923. });
  924. // 是否展示警情退回 (选择结束节点时并且工单来源是110时,显示警情退回)
  925. const showPoliceReturn = computed(() => {
  926. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  927. return next?.stepType === 2 && state.orderDetail?.source === 200;
  928. });
  929. // 是否展示办理时限 flowDirection 并且是工单办理
  930. const flowDirection = computed(() => {
  931. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  932. if (!next) return false;
  933. return [0, 1].includes(next.flowDirection) && handelArr.includes(state.processType);
  934. });
  935. // 是否展示备注输入框
  936. const showRemarkTextarea = computed(() => {
  937. return ['工单受理', '工单办理'].includes(state.processType);
  938. });
  939. // 计算工单期满时间
  940. watch(
  941. () => flowDirection.value,
  942. (val) => {
  943. if (val) {
  944. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  945. state.ruleForm.flowDirection = next.flowDirection;
  946. orderTimeConfig({ flowDirection: next.flowDirection, acceptTypeCode: state.orderDetail.acceptTypeCode }).then((res: any) => {
  947. state.ruleForm.timeLimit = res.result.count ?? null; // 办理时限
  948. state.ruleForm.timeLimitUnit = res.result.timeType ?? ''; // 办理时限单位
  949. });
  950. }
  951. }
  952. );
  953. // 查询一级部门的下级部门 不传默认查所有
  954. const secondaryHandlers = ref<EmptyArrayType>([]);
  955. const getNextOrgList = async (orgCode?: string | any) => {
  956. try {
  957. const { result } = await getDepartmentList(orgCode);
  958. secondaryHandlers.value = result;
  959. } catch (e) {
  960. console.log(e);
  961. }
  962. };
  963. // 选择办理对象
  964. const showOrgLevelTwo = ref(false); // 是否展示二级部门选择
  965. const levelTwoStepOptions = ref<EmptyArrayType>([]); // 二级部门节点
  966. const levelTwoHandleOptions = ref<EmptyArrayType>([]); // 二级部门办理参数
  967. const selectHandlers = () => {
  968. if (state.ruleForm.nextHandlers && state.ruleForm.nextHandlers.length > 1) {
  969. // AppConfigInfo.value.noSignOrgCode 对应的办理对象不能参与会签
  970. const isProvince12345 = state.ruleForm.nextHandlers.find((item: any) => AppConfigInfo.value.noSignOrgCode.includes(item.key));
  971. if (isProvince12345) {
  972. // 如果选择了省12345平台或者省12345交办就提示不能参与会签 并且从选择中移除
  973. ElMessage({
  974. message: '省12345平台和省12345交办不能参与会签',
  975. grouping: true,
  976. });
  977. state.ruleForm.nextHandlers = state.ruleForm.nextHandlers.filter((item: any) => !AppConfigInfo.value.noSignOrgCode.includes(item.key));
  978. }
  979. }
  980. if (state.ruleForm.nextHandlers && state.ruleForm.nextHandlers.length <= 1) {
  981. // 如果只有一个办理对象就不需要发起会签
  982. state.ruleForm.isStartCountersign = false;
  983. }
  984. if ((seatToOrgOne.value || paidanToOrgOne.value) && state.ruleForm.orderAssignMode === 1) {
  985. showOrgLevelTwo.value = false;
  986. state.ruleForm.levelTwoStep = null;
  987. levelTwoStepOptions.value = [];
  988. levelTwoHandleOptions.value = [];
  989. state.ruleForm.levelTwoHandlers = [];
  990. showOrgLevelThree.value = false;
  991. state.ruleForm.levelThreeStep = null;
  992. state.ruleForm.levelThreeHandlers = [];
  993. levelThreeStepOptions.value = [];
  994. levelThreeHandleOptions.value = [];
  995. state.ruleForm.nextHandlers = [state.ruleForm.nextHandler];
  996. // 话务部到一级部门 派单组到一级部门 并且是跨级派单 需要查询下一级部门
  997. const request = {
  998. WorkflowId: state.ruleForm.workflowId,
  999. StepCode: selectNext.value.key,
  1000. StepType: selectNext.value.stepType,
  1001. BusinessType: selectNext.value.businessType,
  1002. HandlerType: selectNext.value.handlerType,
  1003. OrgIds: state.ruleForm.nextHandler ? [state.ruleForm.nextHandler.key] : [],
  1004. };
  1005. orderAssignParams(request).then((res: any) => {
  1006. showOrgLevelTwo.value = true;
  1007. levelTwoStepOptions.value = res.result.steps.map((item: any) => {
  1008. return {
  1009. value: {
  1010. ...item,
  1011. },
  1012. label: item.value,
  1013. };
  1014. });
  1015. if (res.result.steps.length === 1) {
  1016. state.ruleForm.levelTwoStep = res.result.steps[0];
  1017. levelTwoHandleOptions.value = state.ruleForm.levelTwoStep.items.map((item: any) => {
  1018. return {
  1019. value: {
  1020. ...item,
  1021. },
  1022. label: item.value,
  1023. };
  1024. });
  1025. }
  1026. });
  1027. } else {
  1028. showOrgLevelTwo.value = false;
  1029. }
  1030. };
  1031. // 选择二级部门节点
  1032. const selectOrgLevelTwo = (val: any) => {
  1033. if (val) {
  1034. levelTwoHandleOptions.value = state.ruleForm.levelTwoStep.items.map((item: any) => {
  1035. return {
  1036. value: {
  1037. ...item,
  1038. },
  1039. label: item.value,
  1040. };
  1041. });
  1042. } else {
  1043. levelTwoHandleOptions.value = [];
  1044. state.ruleForm.levelTwoHandlers = [];
  1045. state.ruleForm.levelThreeHandlers = [];
  1046. levelThreeStepOptions.value = [];
  1047. levelThreeHandleOptions.value = [];
  1048. showOrgLevelThree.value = false;
  1049. }
  1050. };
  1051. const showOrgLevelThree = ref(false);
  1052. const levelThreeStepOptions = ref<EmptyArrayType>([]); // 三级部门节点
  1053. const levelThreeHandleOptions = ref<EmptyArrayType>([]); // 三级部门办理参数
  1054. // 选择二级部门办理对象 展示三级办理对象和节点
  1055. const selectOrgLevelTwoHandler = (val: any) => {
  1056. const ids = val.map((item: any) => item.key);
  1057. if (val && val.length) {
  1058. const request = {
  1059. WorkflowId: state.ruleForm.workflowId,
  1060. StepCode: state.ruleForm.levelTwoStep.key,
  1061. StepType: state.ruleForm.levelTwoStep.stepType,
  1062. BusinessType: state.ruleForm.levelTwoStep.businessType,
  1063. HandlerType: state.ruleForm.levelTwoStep.handlerType,
  1064. OrgIds: ids,
  1065. };
  1066. orderAssignParams(request).then((res: any) => {
  1067. showOrgLevelThree.value = true;
  1068. levelThreeStepOptions.value = res.result.steps.map((item: any) => {
  1069. return {
  1070. value: {
  1071. ...item,
  1072. },
  1073. label: item.value,
  1074. };
  1075. });
  1076. if (res.result.steps.length === 1) {
  1077. state.ruleForm.levelThreeStep = res.result.steps[0];
  1078. levelThreeHandleOptions.value = state.ruleForm.levelThreeStep.items.map((item: any) => {
  1079. return {
  1080. value: {
  1081. ...item,
  1082. },
  1083. label: item.value,
  1084. };
  1085. });
  1086. }
  1087. });
  1088. } else {
  1089. state.ruleForm.levelThreeHandlers = [];
  1090. levelThreeStepOptions.value = [];
  1091. levelThreeHandleOptions.value = [];
  1092. showOrgLevelThree.value = false;
  1093. }
  1094. /*const request = {
  1095. WorkflowId: state.ruleForm.workflowId,
  1096. StepCode: val.key,
  1097. StepType: val.stepType,
  1098. BusinessType: val.businessType,
  1099. HandlerType: val.handlerType,
  1100. OrgIds: state.ruleForm.nextHandler ? [state.ruleForm.nextHandler.key] : [],
  1101. };
  1102. console.log(request, selectNext.value);
  1103. orderAssignParams(request).then((res: any) => {
  1104. console.log(res);
  1105. showOrgLevelTwo.value = true;
  1106. levelTwoStepOptions.value = res.result.steps.map((item: any) => {
  1107. return {
  1108. value: {
  1109. ...item,
  1110. },
  1111. label: item.value,
  1112. };
  1113. });
  1114. if(res.result.steps.length === 1){
  1115. state.ruleForm.levelTwoSteps = [res.result.steps[0]];
  1116. }
  1117. });*/
  1118. };
  1119. // 选择三级部门节点
  1120. const selectOrgLevelThree = (val: any) => {
  1121. if (val) {
  1122. levelThreeHandleOptions.value = state.ruleForm.levelThreeStep.items.map((item: any) => {
  1123. return {
  1124. value: {
  1125. ...item,
  1126. },
  1127. label: item.value,
  1128. };
  1129. });
  1130. } else {
  1131. state.ruleForm.levelThreeHandlers = [];
  1132. levelThreeHandleOptions.value = [];
  1133. }
  1134. };
  1135. const selectOrgLevelThreeHandler = () => {};
  1136. /*watch(
  1137. () => state.ruleForm.nextStepCode,
  1138. (val) => {
  1139. const next = state.nextStepOptions.find((item: any) => item.key === val);
  1140. if (!next) return true;
  1141. nextHandlersRequired.value = ![0].includes(next.handlerType);
  1142. }
  1143. );*/
  1144. // 选择多选框
  1145. /* <el-checkbox v-model="state.ruleForm.realIsContacted" label="已与市民电话联系,确认办理结果" />
  1146. <el-checkbox v-model="state.ruleForm.realContactLocale" label="已赴现场处置,将处理结果告知市民" />
  1147. <el-checkbox v-model="state.ruleForm.isOther" label="其他" />*/
  1148. const changeCheckBox = (val: any) => {
  1149. state.ruleForm.realIsContacted = val.includes('0');
  1150. state.ruleForm.realContactLocale = val.includes('1');
  1151. state.ruleForm.isOther = val.includes('2');
  1152. console.log(
  1153. `是否已与市民电话联系,确认办理结果:${val.includes('0')},是否已赴现场处置,将处理结果告知市民${val.includes('1')},是否其他${val.includes('2')}`
  1154. );
  1155. };
  1156. // 设置抽屉
  1157. const dialogRef = ref<RefType>();
  1158. const mouseup = () => {
  1159. state.transform = dialogRef.value.dialogContentRef.$el.style.transform;
  1160. };
  1161. // 关闭弹窗
  1162. const closeDialog = () => {
  1163. state.dialogVisible = false;
  1164. };
  1165. // 重置表单方法
  1166. const restForm = (formEl: FormInstance | undefined) => {
  1167. if (!formEl) return;
  1168. state.ruleForm.opinion = '';
  1169. formEl.resetFields();
  1170. formEl.clearValidate();
  1171. };
  1172. // 选择常用意见 填入填写框 办理
  1173. const chooseAdvice = (item: any) => {
  1174. state.ruleForm.opinion += item.content;
  1175. };
  1176. const afterSubmit = (emitType?: 'orderProcessSuccess' | 'orderProcessFailed', showMessage?: boolean, message?: string) => {
  1177. state.loading = false;
  1178. closeDialog();
  1179. const msg = message ?? '操作成功';
  1180. if (showMessage) ElMessage.success(msg);
  1181. if (emitType) emit(emitType);
  1182. };
  1183. const close = () => {
  1184. restForm(ruleFormRef.value);
  1185. orderContent.value = '';
  1186. };
  1187. // 选择是否市州互转
  1188. const changeTransPond = (val: any) => {
  1189. if (!val) {
  1190. state.ruleForm.transpondCityValue = null;
  1191. state.ruleForm.transpondCityName = null;
  1192. state.ruleForm.transpondCityId = null;
  1193. state.ruleForm.transpondCityObj = null;
  1194. }
  1195. };
  1196. // 选择市州互转
  1197. const changeTranspondCity = (val: any) => {
  1198. state.ruleForm.transpondCityId = val?.id ?? null;
  1199. state.ruleForm.transpondCityValue = val?.dicDataValue ?? null;
  1200. state.ruleForm.transpondCityName = val?.dicDataName ?? null;
  1201. };
  1202. // 办理
  1203. const handleFiles = ref<EmptyArrayType>([]); // 流程附件
  1204. const onSubmit = (formEl: FormInstance | undefined) => {
  1205. if (!formEl) return;
  1206. formEl.validate((valid: boolean) => {
  1207. if (!valid) return;
  1208. state.loading = true;
  1209. let submitObj = other.deepClone(state.ruleForm);
  1210. if (!flowDirection.value) {
  1211. // 需要填写办理时限
  1212. Reflect.deleteProperty(submitObj, 'timeLimit');
  1213. Reflect.deleteProperty(submitObj, 'timeLimitUnit');
  1214. } else {
  1215. submitObj.external = {
  1216. timeLimit: state.ruleForm.timeLimit,
  1217. timeLimitUnit: state.ruleForm.timeLimitUnit,
  1218. };
  1219. }
  1220. Reflect.deleteProperty(submitObj, 'isPoliceReturn');
  1221. Reflect.deleteProperty(submitObj, 'isResolved');
  1222. submitObj.external = {
  1223. isPoliceReturn: state.ruleForm.isPoliceReturn,
  1224. isResolved: state.ruleForm.isResolved,
  1225. };
  1226. let crossSteps: EmptyArrayType = [];
  1227. if (state.ruleForm.orderAssignMode === 1) {
  1228. // 如果选中了跨级派单
  1229. const levelOneParams = {
  1230. // 一级部门
  1231. nextStepCode: state.ruleForm.nextStepCode,
  1232. nextStepName: state.ruleForm.nextStepName,
  1233. flowDirection: state.ruleForm.flowDirection,
  1234. handlerType: state.ruleForm.handlerType,
  1235. stepType: state.ruleForm.stepType,
  1236. businessType: state.ruleForm.businessType,
  1237. nextHandlers: state.ruleForm.nextHandlers,
  1238. sort: 1,
  1239. };
  1240. crossSteps.push(levelOneParams);
  1241. if (state.ruleForm.levelTwoHandlers && state.ruleForm.levelTwoHandlers.length) {
  1242. // 二级部门
  1243. const levelTwoParams = {
  1244. nextStepCode: state.ruleForm.levelTwoStep.key,
  1245. nextStepName: state.ruleForm.levelTwoStep.value,
  1246. flowDirection: state.ruleForm.levelTwoStep.flowDirection,
  1247. handlerType: state.ruleForm.levelTwoStep.handlerType,
  1248. stepType: state.ruleForm.levelTwoStep.stepType,
  1249. businessType: state.ruleForm.levelTwoStep.businessType,
  1250. nextHandlers: state.ruleForm.levelTwoHandlers,
  1251. sort: 2,
  1252. };
  1253. crossSteps.push(levelTwoParams);
  1254. }
  1255. if (state.ruleForm.levelThreeHandlers && state.ruleForm.levelThreeHandlers.length) {
  1256. // 三级部门
  1257. const levelThreeParams = {
  1258. nextStepCode: state.ruleForm.levelThreeStep.key,
  1259. nextStepName: state.ruleForm.levelThreeStep.value,
  1260. flowDirection: state.ruleForm.levelThreeStep.flowDirection,
  1261. handlerType: state.ruleForm.levelThreeStep.handlerType,
  1262. stepType: state.ruleForm.levelThreeStep.stepType,
  1263. businessType: state.ruleForm.levelThreeStep.businessType,
  1264. nextHandlers: state.ruleForm.levelThreeHandlers,
  1265. sort: 3,
  1266. };
  1267. crossSteps.push(levelThreeParams);
  1268. }
  1269. }
  1270. switch (state.processType) {
  1271. case '工单受理':
  1272. const request = {
  1273. data: { orderId: state.orderDetail.id, ...submitObj, crossSteps },
  1274. workflow: { ...submitObj, files: handleFiles.value,currentTag:currentParams.value.currentTag },
  1275. };
  1276. orderStartFlow(request)
  1277. .then(() => {
  1278. afterSubmit('orderProcessSuccess', true);
  1279. })
  1280. .catch(() => {
  1281. afterSubmit('orderProcessFailed');
  1282. });
  1283. break;
  1284. case '工单办理': // 工单办理流程
  1285. case '工单代办': // 工单代办流程
  1286. const requestHandle = {
  1287. data: { orderId: state.orderDetail.id, ...submitObj, crossSteps },
  1288. workflow: { ...submitObj, files: handleFiles.value,currentTag:currentParams.value.currentTag },
  1289. };
  1290. orderHandle(requestHandle)
  1291. .then(() => {
  1292. afterSubmit('orderProcessSuccess', true);
  1293. })
  1294. .catch(() => {
  1295. afterSubmit('orderProcessFailed');
  1296. });
  1297. break;
  1298. case '工单退回':
  1299. const requestReturn = { ...submitObj, files: handleFiles.value, orderId: state.orderDetail.id };
  1300. orderPrevious(requestReturn)
  1301. .then(() => {
  1302. afterSubmit('orderProcessSuccess', true, '退回申请成功');
  1303. })
  1304. .catch(() => {
  1305. afterSubmit('orderProcessFailed');
  1306. });
  1307. break;
  1308. default: // 默认工单办理
  1309. const requestDefault = {
  1310. data: { orderId: state.orderDetail.id, ...submitObj, crossSteps },
  1311. workflow: { ...submitObj, files: handleFiles.value,currentTag:currentParams.value.currentTag },
  1312. };
  1313. orderHandle(requestDefault)
  1314. .then(() => {
  1315. afterSubmit('orderProcessSuccess', true);
  1316. })
  1317. .catch(() => {
  1318. afterSubmit('orderProcessFailed');
  1319. });
  1320. break;
  1321. }
  1322. });
  1323. };
  1324. // 临时保存
  1325. const handleTempSave = () => {
  1326. ruleFormRef.value
  1327. .validateField('opinion')
  1328. .then(() => {
  1329. state.loading = true;
  1330. orderProcessTempSave({ orderId: state.orderDetail.id, opinion: state.ruleForm.opinion })
  1331. .then(() => {
  1332. state.loading = false;
  1333. ElMessage.success('临时保存成功');
  1334. })
  1335. .catch((err) => {
  1336. state.loading = false;
  1337. console.log(err);
  1338. });
  1339. })
  1340. .catch(() => {});
  1341. };
  1342. // 暴露变量
  1343. defineExpose({
  1344. openDialog,
  1345. closeDialog,
  1346. });
  1347. </script>
  1348. <style lang="scss">
  1349. .modal_class {
  1350. pointer-events: none;
  1351. height: 100%;
  1352. }
  1353. .dialog_class {
  1354. pointer-events: auto;
  1355. flex-direction: column;
  1356. margin: 0 !important;
  1357. position: absolute;
  1358. top: 20%;
  1359. left: 25%;
  1360. }
  1361. </style>