index.vue 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848
  1. <template>
  2. <el-dialog
  3. v-model="state.dialogVisible"
  4. draggable
  5. :title="state.dialogTitle"
  6. ref="dialogRef"
  7. @mouseup="mouseup"
  8. :style="'transform: ' + state.transform + ';'"
  9. destroy-on-close
  10. :close-on-click-modal="false"
  11. @close="close"
  12. :modal-class="isOrderAccept ? 'modal_class' : ''"
  13. :class="isOrderAccept ? 'dialog_class' : ''"
  14. :append-to-body="!isOrderAccept"
  15. :modal="!isOrderAccept"
  16. >
  17. <el-steps :active="activeStep" align-center finish-status="success" class="mb20" v-if="showStepsArr.includes(state.processType)">
  18. <el-step title="业务表单" />
  19. <el-step title="流程表单" />
  20. </el-steps>
  21. <!-- {{ seatTopaidan ? '话务部到派单组' : '' }}
  22. {{ seatToOrgOne ? '话务部到一级部门' : '' }}
  23. {{ paidanToOrgOne ? '派单组到一级部门' : '' }}-->
  24. <div v-show="activeStep === 0" v-loading="state.loading">
  25. <el-form :model="state.delayForm" label-width="110px" ref="delayFormRef" v-if="state.processType === '延期申请'">
  26. <el-row :gutter="10">
  27. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  28. <el-form-item label="工单编码"> {{ state.orderDetail.no }} </el-form-item>
  29. </el-col>
  30. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  31. <el-form-item label="工单标题"> {{ state.orderDetail.title }} </el-form-item>
  32. </el-col>
  33. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  34. <el-form-item label="申请人"> {{ userInfos.name }} </el-form-item>
  35. </el-col>
  36. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  37. <el-form-item label="申请部门"> {{ userInfos.orgName }} </el-form-item>
  38. </el-col>
  39. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  40. <el-form-item label="申请时间"> {{ formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
  41. </el-col>
  42. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  43. <el-form-item label="当前期满时间"> {{ formatDate(state.orderDetail.expiredTime, 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
  44. </el-col>
  45. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="12" v-loading="state.loading">
  46. <el-form-item prop="timeLimitCount" :rules="[{ required: true, message: '请填写延期申请数量', trigger: 'blur' }]" label-width="130px">
  47. <template #label>
  48. <div style="height: 34px; display: flex; align-items: center">
  49. 延期申请数量
  50. <el-tooltip placement="top-start">
  51. <SvgIcon name="ele-QuestionFilled" size="18px" class="ml3" />
  52. <template #content> 延期申请数量为1-{{ AppConfigInfo.applyDelayTime }} </template>
  53. </el-tooltip>
  54. </div>
  55. </template>
  56. <el-row :gutter="10" class="w100">
  57. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  58. <el-input-number
  59. placeholder="延期申请数量"
  60. v-model="state.delayForm.timeLimitCount"
  61. controls-position="right"
  62. :min="1"
  63. :max="AppConfigInfo.applyDelayTime"
  64. class="w100"
  65. ></el-input-number>
  66. </el-col>
  67. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-loading="state.loading">
  68. <el-form-item
  69. label=""
  70. label-width="0"
  71. prop="timeLimitUnit"
  72. :rules="[{ required: true, message: '请选择延期申请单位', trigger: 'change' }]"
  73. >
  74. <el-select disabled v-model="state.delayForm.timeLimitUnit" placeholder="延期申请单位">
  75. <el-option v-for="item in timeType" :value="item.key" :key="item.key" :label="item.value" />
  76. </el-select>
  77. </el-form-item>
  78. </el-col>
  79. </el-row>
  80. </el-form-item>
  81. </el-col>
  82. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  83. <el-form-item label="申请理由" prop="content" :rules="[{ required: true, message: '请填写延期申请理由', trigger: 'blur' }]">
  84. <common-advice
  85. @chooseAdvice="chooseAdviceDelay"
  86. v-model="state.delayForm.content"
  87. placeholder="请填写延期申请理由"
  88. :loading="state.loading"
  89. :commonEnum="commonOpinionType"
  90. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  91. />
  92. </el-form-item>
  93. </el-col>
  94. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  95. <el-form-item label="附件">
  96. <annex-list name="延期附件" v-model:format="handleFilesDelay" :businessId="state.orderDetail.id" classify="延期上传" />
  97. </el-form-item>
  98. </el-col>
  99. </el-row>
  100. </el-form>
  101. <el-form :model="state.discernForm" label-width="110px" ref="discernFormRef" v-if="state.processType === '甄别申请'">
  102. <el-row :gutter="10">
  103. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  104. <el-form-item label="工单编码"> {{ state.orderDetail.no }} </el-form-item>
  105. </el-col>
  106. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  107. <el-form-item label="工单标题"> {{ state.orderDetail.title }} </el-form-item>
  108. </el-col>
  109. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  110. <el-form-item label="申请人"> {{ userInfos.name }} </el-form-item>
  111. </el-col>
  112. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  113. <el-form-item label="申请部门"> {{ userInfos.orgName }} </el-form-item>
  114. </el-col>
  115. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  116. <el-form-item label="申请时间"> {{ formatDate(Date(), 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
  117. </el-col>
  118. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  119. <el-form-item label="申请类型" prop="type" :rules="[{ required: true, message: '请选择申请类型', trigger: 'change' }]">
  120. <el-select v-model="state.discernForm.type" placeholder="请选择申请类型" class="w100" value-key="dicDataValue">
  121. <el-option v-for="item in screenTypeOptions" :value="item" :key="item.dicDataValue" :label="item.dicDataName" />
  122. </el-select>
  123. </el-form-item>
  124. </el-col>
  125. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  126. <el-form-item label="申请理由" prop="content" :rules="[{ required: true, message: '请填写甄别申请理由', trigger: 'blur' }]">
  127. <common-advice
  128. @chooseAdvice="chooseAdviceDiscern"
  129. v-model="state.discernForm.content"
  130. placeholder="请填写甄别申请理由"
  131. :loading="state.loading"
  132. :commonEnum="commonOpinionType"
  133. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  134. />
  135. </el-form-item>
  136. </el-col>
  137. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  138. <el-form-item label="附件">
  139. <annex-list
  140. name="甄别附件"
  141. ref="discernAnnexListRef"
  142. v-model:format="handleFilesDiscern"
  143. :businessId="state.orderDetail.id"
  144. classify="甄别上传"
  145. />
  146. </el-form-item>
  147. </el-col>
  148. </el-row>
  149. </el-form>
  150. <el-form :model="state.terminateForm" label-width="110px" ref="terminateFormRef" v-if="state.processType === '终止申请'">
  151. <el-row :gutter="10">
  152. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  153. <el-form-item label="工单编码"> {{ state.orderDetail.no }} </el-form-item>
  154. </el-col>
  155. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  156. <el-form-item label="工单标题"> {{ state.orderDetail.title }} </el-form-item>
  157. </el-col>
  158. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  159. <el-form-item label="终止理由" prop="content" :rules="[{ required: true, message: '请填写终止申请理由', trigger: 'blur' }]">
  160. <common-advice
  161. @chooseAdvice="chooseAdviceTerminate"
  162. v-model="state.terminateForm.content"
  163. placeholder="请填写终止申请理由"
  164. :loading="state.loading"
  165. :commonEnum="commonOpinionType"
  166. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  167. />
  168. </el-form-item>
  169. </el-col>
  170. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  171. <el-form-item label="附件">
  172. <annex-list
  173. name="终止附件"
  174. ref="terminateAnnexListRef"
  175. v-model:format="handleFilesTerminate"
  176. :businessId="state.orderDetail.id"
  177. classify="终止上传"
  178. />
  179. </el-form-item>
  180. </el-col>
  181. </el-row>
  182. </el-form>
  183. </div>
  184. <el-form
  185. :model="state.ruleForm"
  186. label-width="110px"
  187. ref="ruleFormRef"
  188. v-show="activeStep === 1"
  189. v-loading="state.loading"
  190. :disabled="state.loading"
  191. >
  192. <slot name="header"></slot>
  193. <el-row :gutter="10">
  194. <!-- 审批流程 -->
  195. <template v-if="auditArr.includes(state.processType) && canReject">
  196. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType)">
  197. <el-form-item label="审批结果" prop="isPass" :rules="[{ required: true, message: '请选择审批结果', trigger: 'change' }]">
  198. <el-radio-group v-model="state.ruleForm.isPass">
  199. <el-radio :value="true">同意</el-radio>
  200. <el-radio :value="false">不同意</el-radio>
  201. </el-radio-group>
  202. </el-form-item>
  203. </el-col>
  204. <!-- 审批通过 -->
  205. <template v-if="state.ruleForm.isPass">
  206. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  207. <el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
  208. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
  209. <el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
  210. </el-select>
  211. <!-- <p class="flex-center-align color-danger" v-if="showFastSendOrder">
  212. 当前推荐派单办理对象:{{ fastStepName }} <el-button type="primary" link class="ml4" @click="fastSendOrder">快捷派单</el-button>
  213. </p>-->
  214. </el-form-item>
  215. </el-col>
  216. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType) && showHandlers">
  217. <el-form-item
  218. label="办理对象"
  219. prop="nextHandlers"
  220. :rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]"
  221. v-if="!returnArr.includes(state.processType) && showHandlers"
  222. >
  223. <el-select-v2
  224. v-model="state.ruleForm.nextHandlers"
  225. :options="state.handlerOptions"
  226. placeholder="请选择办理对象"
  227. class="w100"
  228. multiple
  229. clearable
  230. collapse-tags
  231. collapse-tags-tooltip
  232. filterable
  233. value-key="key"
  234. @change="selectHandlers"
  235. :multiple-limit="multipleLimit"
  236. />
  237. </el-form-item>
  238. </el-col>
  239. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showMainHandler">
  240. <el-form-item label="主办" prop="nextMainHandler" :rules="[{ required: false, message: '请选择主办', trigger: 'change' }]">
  241. <el-select v-model="state.ruleForm.nextMainHandler" placeholder="请选择主办" class="w100" filterable>
  242. <el-option v-for="item in state.handlerMainOptions" :key="item.key" :label="item.value" :value="item.key" />
  243. </el-select>
  244. </el-form-item>
  245. </el-col>
  246. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="countersignAble">
  247. <el-form-item label="发起会签" prop="isStartCountersign" :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]">
  248. <el-switch
  249. v-model="state.ruleForm.isStartCountersign"
  250. inline-prompt
  251. active-text="是"
  252. inactive-text="否"
  253. @change="changeStartCountersign"
  254. :disabled="countersignDisabled"
  255. />
  256. </el-form-item>
  257. </el-col>
  258. </template>
  259. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  260. <el-form-item label="" prop="isSms">
  261. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" />
  262. </el-form-item>
  263. </el-col>
  264. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  265. <el-form-item
  266. :label="state.inputPlaceholder"
  267. prop="opinion"
  268. :rules="[{ required: true, message: `请填写${state.inputPlaceholder}`, trigger: 'blur' }]"
  269. >
  270. <common-advice
  271. @chooseAdvice="chooseAdvice"
  272. v-model="state.ruleForm.opinion"
  273. :placeholder="'请填写' + state.inputPlaceholder"
  274. :loading="state.loading"
  275. :commonEnum="commonOpinionType"
  276. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  277. />
  278. </el-form-item>
  279. </el-col>
  280. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  281. <el-form-item label="附件" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
  282. <annex-list :name="state.annexName" :businessId="state.orderDetail.id" :classify="state.classify" v-model:format="handleFiles" />
  283. </el-form-item>
  284. </el-col>
  285. </template>
  286. <!-- 办理流程 -->
  287. <template v-else>
  288. <el-col v-if="orderContent">
  289. <el-form-item label="受理内容">
  290. <text-ellipsis :content="orderContent" :rows="1"> </text-ellipsis>
  291. </el-form-item>
  292. </el-col>
  293. <!-- 非退回流程都需要选择 -->
  294. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType)">
  295. <el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
  296. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
  297. <el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
  298. </el-select>
  299. <!-- <p class="flex-center-align color-danger" v-if="showFastSendOrder">
  300. 当前推荐派单办理对象:{{ fastStepName }} <el-button type="primary" link class="ml4" @click="fastSendOrder">快捷派单</el-button>
  301. </p>-->
  302. </el-form-item>
  303. </el-col>
  304. <!-- 非退回流程都需要选择并且如果选择了结束节点就不需要选择办理对象 -->
  305. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="!returnArr.includes(state.processType) && showHandlers">
  306. <el-form-item
  307. label="办理对象"
  308. prop="nextHandlers"
  309. :rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]"
  310. >
  311. <el-select-v2
  312. v-model="state.ruleForm.nextHandlers"
  313. :options="state.handlerOptions"
  314. placeholder="请选择办理对象"
  315. class="w100"
  316. multiple
  317. clearable
  318. collapse-tags
  319. collapse-tags-tooltip
  320. filterable
  321. value-key="key"
  322. @change="selectHandlers"
  323. :multiple-limit="multipleLimit"
  324. />
  325. </el-form-item>
  326. </el-col>
  327. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showMainHandler">
  328. <el-form-item label="主办" prop="nextMainHandler" :rules="[{ required: false, message: '请选择主办', trigger: 'change' }]">
  329. <el-select v-model="state.ruleForm.nextMainHandler" placeholder="请选择主办" class="w100" filterable>
  330. <el-option v-for="item in state.handlerMainOptions" :key="item.key" :label="item.value" :value="item.key" />
  331. </el-select>
  332. </el-form-item>
  333. </el-col>
  334. <!-- 工单办理专有参数 -->
  335. <template v-if="flowDirection">
  336. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  337. <el-form-item label="办理时限" prop="timeLimit" :rules="[{ required: true, message: '请填写办理时限', trigger: 'blur' }]">
  338. <el-row :gutter="10">
  339. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  340. <el-input-number
  341. placeholder="办理时限"
  342. v-model="state.ruleForm.timeLimit"
  343. controls-position="right"
  344. class="w100"
  345. :min="1"
  346. :max="99"
  347. disabled
  348. ></el-input-number>
  349. </el-col>
  350. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-loading="state.loading">
  351. <el-form-item
  352. label=""
  353. label-width="0"
  354. prop="timeLimitUnit"
  355. :rules="[{ required: true, message: '请选择办理时限单位', trigger: 'change' }]"
  356. >
  357. <el-select v-model="state.ruleForm.timeLimitUnit" placeholder="办理时限单位" disabled style="width: 240px">
  358. <el-option v-for="item in timeTypeOptions" :value="item.key" :key="item.key" :label="item.value" />
  359. </el-select>
  360. </el-form-item>
  361. </el-col>
  362. </el-row>
  363. </el-form-item>
  364. </el-col>
  365. </template>
  366. <!-- 话务部到一级部门 派单组到一级部门 -->
  367. <template v-if="seatToOrgOne || paidanToOrgOne">
  368. <el-col :span="24">
  369. <el-form-item label="派单类型" prop="orderAssignMode" :rules="[{ required: true, message: '请选择派单类型', trigger: 'change' }]">
  370. <el-radio-group v-model="state.ruleForm.orderAssignMode" @change="selectDispatchType">
  371. <el-radio :value="0">逐级派单</el-radio>
  372. <el-radio :value="1">跨级派单</el-radio>
  373. </el-radio-group>
  374. </el-form-item>
  375. </el-col>
  376. <el-col :span="12" v-if="state.ruleForm.orderAssignMode === 0">
  377. <el-form-item label="接办部门" prop="nextHandlers" :rules="[{ required: true, message: '请选择接办部门', trigger: 'change' }]">
  378. <!-- <el-select v-model="state.ruleForm.paidanObj" placeholder="请选择接办部门" class="w100" filterable multiple>
  379. <el-option v-for="item in state.paidanObjOptions" :key="item.key" :label="item.value" :value="item.key" />
  380. </el-select>-->
  381. <el-select-v2
  382. v-model="state.ruleForm.nextHandlers"
  383. :options="state.handlerOptions"
  384. placeholder="请选择接办部门"
  385. class="w100"
  386. multiple
  387. clearable
  388. collapse-tags
  389. collapse-tags-tooltip
  390. filterable
  391. value-key="key"
  392. @change="selectHandlers"
  393. :multiple-limit="multipleLimit"
  394. />
  395. </el-form-item>
  396. </el-col>
  397. <el-col :span="24" v-if="state.ruleForm.orderAssignMode === 1">
  398. <el-row class="w100" :gutter="10">
  399. <el-col>
  400. <el-form-item label="接办部门" prop="nextHandler" :rules="[{ required: true, message: '请选择接办部门', trigger: 'change' }]">
  401. <el-select-v2
  402. v-model="state.ruleForm.nextHandler"
  403. :options="state.handlerOptions"
  404. placeholder="请选择接办部门"
  405. class="w100"
  406. clearable
  407. filterable
  408. value-key="key"
  409. @change="selectHandlers"
  410. />
  411. </el-form-item>
  412. </el-col>
  413. <!-- 二级部门 -->
  414. <template v-if="showOrgLevelTwo">
  415. <el-col :span="12">
  416. <el-form-item label="下一环节" prop="levelTwoStep" :rules="[{ required: false, message: '请选择下一环节', trigger: 'change' }]">
  417. <el-select-v2
  418. v-model="state.ruleForm.levelTwoStep"
  419. :options="levelTwoStepOptions"
  420. placeholder="请选择下一环节"
  421. class="w100"
  422. filterable
  423. value-key="key"
  424. clearable
  425. @change="selectOrgLevelTwo"
  426. />
  427. </el-form-item>
  428. </el-col>
  429. <el-col :span="12">
  430. <el-form-item
  431. label="办理对象"
  432. prop="levelTwoHandlers"
  433. :rules="[{ required: false, message: '请选择办理对象', trigger: 'change' }]"
  434. >
  435. <el-select-v2
  436. v-model="state.ruleForm.levelTwoHandlers"
  437. :options="levelTwoHandleOptions"
  438. placeholder="请选择办理对象"
  439. class="w100"
  440. clearable
  441. filterable
  442. value-key="key"
  443. multiple
  444. collapse-tags
  445. collapse-tags-tooltip
  446. :max-collapse-tags="1"
  447. @change="selectOrgLevelTwoHandler"
  448. />
  449. </el-form-item>
  450. </el-col>
  451. </template>
  452. <!-- 三级部门 -->
  453. <template v-if="showOrgLevelThree">
  454. <el-col :span="12">
  455. <el-form-item label="下一环节" prop="levelThreeStep" :rules="[{ required: false, message: '请选择下一环节', trigger: 'change' }]">
  456. <el-select-v2
  457. v-model="state.ruleForm.levelThreeStep"
  458. :options="levelThreeStepOptions"
  459. placeholder="请选择下一环节"
  460. class="w100"
  461. filterable
  462. value-key="key"
  463. clearable
  464. @change="selectOrgLevelThree"
  465. />
  466. </el-form-item>
  467. </el-col>
  468. <el-col :span="12">
  469. <el-form-item
  470. label="办理对象"
  471. prop="levelTwoHandlers"
  472. :rules="[{ required: false, message: '请选择办理对象', trigger: 'change' }]"
  473. >
  474. <el-select-v2
  475. v-model="state.ruleForm.levelThreeHandlers"
  476. :options="levelThreeHandleOptions"
  477. placeholder="请选择办理对象"
  478. class="w100"
  479. clearable
  480. filterable
  481. value-key="key"
  482. multiple
  483. collapse-tags
  484. collapse-tags-tooltip
  485. :max-collapse-tags="1"
  486. @change="selectOrgLevelThreeHandler"
  487. />
  488. </el-form-item>
  489. </el-col>
  490. </template>
  491. </el-row>
  492. </el-col>
  493. </template>
  494. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="countersignAble">
  495. <el-form-item label="发起会签" prop="isStartCountersign" :rules="[{ required: false, message: '请选择发起会签', trigger: 'change' }]">
  496. <el-switch
  497. v-model="state.ruleForm.isStartCountersign"
  498. inline-prompt
  499. active-text="是"
  500. inactive-text="否"
  501. @change="changeStartCountersign"
  502. :disabled="countersignDisabled"
  503. />
  504. </el-form-item>
  505. </el-col>
  506. <!-- 汇总节点需要填写 并且是工单办理 -->
  507. <template v-if="inputRealHandler">
  508. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  509. <el-form-item label="经办人" prop="realHandlerName" :rules="[{ required: false, message: '请填写经办人', trigger: 'blur' }]">
  510. <el-input v-model="state.ruleForm.realHandlerName" placeholder="请填写经办人" clearable> </el-input>
  511. </el-form-item>
  512. </el-col>
  513. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  514. <el-form-item label="经办人电话" prop="realHandlerPhone" :rules="[{ required: false, message: '请填写经办人电话', trigger: 'blur' }]">
  515. <el-input v-model="state.ruleForm.realHandlerPhone" placeholder="请填写办理人电话" 请填写经办人电话> </el-input>
  516. </el-form-item>
  517. </el-col>
  518. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  519. <el-form-item label="是否与市民沟通" prop="realIsContacted">
  520. <el-switch v-model="state.ruleForm.realIsContacted" inline-prompt active-text="是" inactive-text="否" />
  521. </el-form-item>
  522. </el-col>
  523. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  524. <el-form-item label="是否与市民现场沟通" prop="realContactLocale" label-width="150">
  525. <el-switch v-model="state.ruleForm.realContactLocale" inline-prompt active-text="是" inactive-text="否" />
  526. </el-form-item>
  527. </el-col>
  528. </template>
  529. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="isSmsSelectShow">
  530. <el-form-item label="" prop="isSms">
  531. <el-checkbox v-model="state.ruleForm.isSms" label="短信通知" />
  532. </el-form-item>
  533. </el-col>
  534. <!-- 选择结束节点时并且是工单办理并且不是中心,显示部门处理结果 -->
  535. <template v-if="showResult">
  536. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  537. <el-form-item label="处理结果" prop="isResolved" :rules="[{ required: true, message: '请选择处理结果', trigger: 'change' }]">
  538. <el-radio-group v-model="state.ruleForm.isResolved">
  539. <el-radio :value="true">已得到解决</el-radio>
  540. <el-radio :value="false">未得到解决</el-radio>
  541. </el-radio-group>
  542. </el-form-item>
  543. </el-col>
  544. </template>
  545. <!-- 选择结束节点时并且是工单办理并且工单来源是110时,显示警情退回 -->
  546. <template v-if="showPoliceReturn">
  547. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  548. <el-form-item label="" prop="isPoliceReturn">
  549. <el-checkbox v-model="state.ruleForm.isPoliceReturn" label="警情退回" />
  550. </el-form-item>
  551. </el-col>
  552. </template>
  553. <template v-if="!['延期申请', '甄别申请', '终止申请'].includes(state.processType)">
  554. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  555. <el-form-item
  556. :label="state.inputPlaceholder"
  557. prop="opinion"
  558. :rules="[{ required: true, message: `请填写${state.inputPlaceholder}`, trigger: 'blur' }]"
  559. >
  560. <common-advice
  561. @chooseAdvice="chooseAdvice"
  562. v-model="state.ruleForm.opinion"
  563. :placeholder="'请填写' + state.inputPlaceholder"
  564. :loading="state.loading"
  565. :commonEnum="commonOpinionType"
  566. :maxlength="AppConfigInfo.handleOpinionWordLimit"
  567. />
  568. </el-form-item>
  569. </el-col>
  570. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" v-if="showRemarkTextarea">
  571. <el-form-item label="备注信息" prop="remark" :rules="[{ required: false, message: `请填写备注信息`, trigger: 'blur' }]">
  572. <el-input v-model="state.ruleForm.remark" :rows="2" type="textarea" placeholder="请填写备注信息" />
  573. </el-form-item>
  574. </el-col>
  575. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  576. <el-form-item label="附件" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
  577. <annex-list :name="state.annexName" :businessId="state.orderDetail.id" :classify="state.classify" v-model:format="handleFiles" />
  578. </el-form-item>
  579. </el-col>
  580. </template>
  581. </template>
  582. <!-- 在派单组并且是开启了预警管理并且是有预警信息 -->
  583. <template v-if="AppConfigInfo.isEarly && isPaidan && earlyResponseData?.orderEarlyInfo?.length">
  584. <el-col>
  585. <p class="border-title mb10">预警信息</p>
  586. </el-col>
  587. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  588. <el-form-item label="预警词语">
  589. <template #label>
  590. <p class="flex-center-align">
  591. 预警词语
  592. <el-tooltip content="次数是指工单内含有预警词语的工单数量" placement="top-start" trigger="hover">
  593. <SvgIcon name="ele-QuestionFilled" class="ml3"></SvgIcon>
  594. </el-tooltip>
  595. </p>
  596. </template>
  597. <div v-for="item in earlyResponseData?.orderEarlyInfo">
  598. <p>
  599. {{ item.keyWord }} (<span>近一周:{{ item.weekNum }}次</span> <span>近一个月:{{ item.monthNum }}次</span>)
  600. </p>
  601. </div>
  602. </el-form-item>
  603. </el-col>
  604. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="earlyResponseData?.orderEarly?.seatEarlyWarningTypeName">
  605. <el-form-item label="坐席预警判断">
  606. {{ earlyResponseData.orderEarly?.seatEarlyWarningTypeName }} ,{{ earlyResponseData.orderEarly?.seatEarlyWarningLevelName }}
  607. </el-form-item>
  608. </el-col>
  609. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-else> </el-col>
  610. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  611. <el-form-item label="预警选择" prop="dispatchEarlyWarning" :rules="[{ required: false, message: '请选择预警选择', trigger: 'change' }]">
  612. <el-select
  613. v-model="state.ruleForm.dispatchEarlyWarning"
  614. placeholder="请选择预警选择"
  615. filterable
  616. value-key="id"
  617. multiple
  618. collapse-tags
  619. clearable
  620. collapse-tags-tooltip
  621. >
  622. <el-option
  623. v-for="item in earlyResponseData?.orderEarly?.canChooseEarlyWarning"
  624. :key="item.id"
  625. :label="item.earlyWarningName"
  626. :value="item"
  627. />
  628. </el-select>
  629. </el-form-item>
  630. </el-col>
  631. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="earlyResponseData?.orderEarly?.canChooseEarlyWarning?.length">
  632. <el-form-item label-width="10px">
  633. <el-text type="danger" tag="b">已启动自动预警,选择预警名称</el-text>
  634. </el-form-item>
  635. </el-col>
  636. </template>
  637. </el-row>
  638. </el-form>
  639. <template #footer>
  640. <span class="dialog-footer">
  641. <el-text type="danger" class="mr15" tag="b" v-if="showTempSave">温馨提示:临时保存只保存{{ state.inputPlaceholder }}</el-text>
  642. <el-button @click="closeDialog" class="default-button">取 消</el-button>
  643. <el-button type="primary" @click="handleTempSave" :loading="state.loading" v-if="showTempSave">临时保存</el-button>
  644. <el-button
  645. class="default-button"
  646. @click="onPrevious"
  647. :loading="state.loading"
  648. v-if="activeStep === 1 && showStepsArr.includes(state.processType)"
  649. >上一步</el-button
  650. >
  651. <el-button class="default-button" @click="onNext" :loading="state.loading" v-if="activeStep === 0 && showStepsArr.includes(state.processType)"
  652. >下一步</el-button
  653. >
  654. <el-popconfirm
  655. title="该工单属于超期状态,若符合延期要求,请延期通过后办结,是否继续办理?"
  656. v-if="isOverdueTips"
  657. @confirm="onSubmit(ruleFormRef)"
  658. width="300"
  659. >
  660. <template #reference>
  661. <el-button type="primary" :loading="state.loading">办理</el-button>
  662. </template>
  663. </el-popconfirm>
  664. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading" v-else-if="!isOverdueTips && activeStep === 1"
  665. >办理</el-button
  666. >
  667. </span>
  668. </template>
  669. </el-dialog>
  670. </template>
  671. <script setup lang="ts" name="processApproval">
  672. import { computed, defineAsyncComponent, nextTick, reactive, ref, watch, watchEffect } from 'vue';
  673. import { ElMessage, FormInstance } from 'element-plus';
  674. import other from '@/utils/other';
  675. import { useUserInfo } from '@/stores/userInfo';
  676. import { storeToRefs } from 'pinia';
  677. import { commonEnum } from '@/utils/constants';
  678. import { orderAssignParams, orderFlowParams, orderHandle, orderProcessTempSave, orderStartFlow, orderTimeConfig } from '@/api/business/order';
  679. import {
  680. orderPrevious,
  681. workflowNext,
  682. workflowNextSteps,
  683. workflowNextStepsByOrder,
  684. workflowNextStepsByOrderInstead,
  685. workflowPrevious,
  686. workflowRecall,
  687. workflowRecallParams,
  688. workflowReject,
  689. } from '@/api/system/workflow';
  690. import { delayApply, delayApproveParams, delayBaseData, workflowDelayParams } from '@/api/business/delay';
  691. import { discernApply, discernApproveParams, screenBaseData, workflowDiscernParams } from '@/api/business/discern';
  692. import {
  693. KnowledgeAdd,
  694. KnowledgeAddStartFlowParams,
  695. KnowledgeDel,
  696. KnowledgeDeleteStartFlowParams,
  697. KnowledgeOffShelf,
  698. KnowledgeOffShelfStartFlowParams,
  699. KnowledgeUpdate,
  700. KnowledgeUpdateStartFlowParams,
  701. } from '@/api/knowledge';
  702. import { formatDate } from '@/utils/formatTime';
  703. import { useAppConfig } from '@/stores/appConfig';
  704. import { terminateNextFlowParams, terminateStartFlow, terminateStartFlowParams } from '@/api/business/terminate';
  705. // 引入组件
  706. const CommonAdvice = defineAsyncComponent(() => import('@/components/CommonAdvice/index.vue')); // 常用意见
  707. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件列表
  708. const TextEllipsis = defineAsyncComponent(() => import('@/components/TextEllipsis/index.vue'));
  709. // 定义子组件向父组件传值/事件
  710. const emit = defineEmits(['orderProcessSuccess', 'orderProcessFailed']);
  711. // 定义变量内容
  712. const state = reactive<any>({
  713. dialogVisible: false, // 弹窗显示隐藏
  714. ruleForm: {
  715. isPass: true, // 审批结果
  716. //流程表单
  717. opinion: '', // 意见
  718. nextStepCode: '', // 下一节点
  719. nextStepName: '', // 下一节点名称
  720. backToCountersignEnd: false, // 是否回到会签结束节点
  721. nextHandlers: [], // 下一节点办理对象
  722. nextMainHandler: '', // 主办人
  723. isSms: false, // 是否短信通知
  724. isStartCountersign: false, // 是否发起会签
  725. stepId: null, // 步骤id
  726. // isTransferHandle:false, // 是否转办
  727. orderAssignMode: 0, // 派单类型默认逐级派单
  728. dispatchEarlyWarning: [], // 预警信息
  729. },
  730. delayForm: {
  731. //延期申请表单
  732. timeLimitCount: null, // 延期申请数量
  733. content: '', // 延期申请理由
  734. timeLimitUnit: 2, // 延期申请单位 默认工作日
  735. },
  736. discernForm: {
  737. // 甄别表单
  738. content: '', // 甄别理由
  739. },
  740. redoForm: {
  741. // 重办表单
  742. content: '', // 重办理由
  743. },
  744. terminateForm: {
  745. //终止表单
  746. content: '', // 终止理由
  747. },
  748. nextStepOptions: [], // 下一节点
  749. handlerOptions: [], // 办理对象
  750. transform: 'translate(0px, 0px)', // 滚动条位置
  751. loading: false, // 提交按钮loading
  752. processType: 'next', // 流程状态
  753. workflowId: '', // 流程id
  754. handlerClassifies: [], //撤回办理对象
  755. handlerMainOptions: [], // 主办人
  756. handleId: '', // 流程处理ID
  757. dialogTitle: '', // 弹窗标题
  758. annexName: '', // 附件标题
  759. inputPlaceholder: '办理意见', // 意见提示
  760. orderDetail: {}, // 工单详情
  761. });
  762. const ruleFormRef = ref<RefType>(); //表单组件
  763. const storesUserInfo = useUserInfo();
  764. const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
  765. const showStepsArr = ['延期申请', '甄别申请', '终止申请']; // 显示步骤条的流程
  766. const handelArr = ['工单办理']; // 处于办理状态的流程 (如果是汇总节点 需要填写办理对象等 办理流程才有期满时间)
  767. const returnArr = ['工单退回', '甄别退回', '延期退回', '终止退回']; // 退回流程 (退回流程不需要展示其他 只需要填写意见和附件即可)
  768. const auditArr = ['甄别审批', '延期审批', '知识审批', '终止审批']; // 审批流程 (审批流程需要选择是否通过和下一环节)
  769. const appConfigStore = useAppConfig();
  770. const { AppConfigInfo } = storeToRefs(appConfigStore); // 系统配置信息
  771. const showTempSave = computed(() => {
  772. // 是否显示临时办理
  773. return ['工单办理', '工单代办', '工单受理'].includes(state.processType);
  774. });
  775. const timeType = ref<EmptyArrayType>([]); // 延期申请单位
  776. const screenTypeOptions = ref<EmptyArrayType>([]); // 甄别类型
  777. const screenType = ref(null); // 甄别类型 自贡甄别特殊需求
  778. const earlyResponseData = ref<EmptyObjectType>({
  779. }); // 预警信息
  780. // 打开弹窗
  781. const openDialog = async (val: any) => {
  782. console.log(val);
  783. selectNext.value = {};
  784. currentParams.value = {};
  785. state.ruleForm.nextHandlers = [];
  786. state.ruleForm.nextHandler = {};
  787. isSmsSelectShow.value = false;
  788. state.ruleForm.isSms = false;
  789. state.loading = true;
  790. state.dialogVisible = true;
  791. try {
  792. const { id, processType, extra, orderDetail } = val;
  793. state.ruleForm.workflowId = state.workflowId = id ?? ''; // 流程id
  794. state.processType = processType ?? '办理流程'; // 业务类型
  795. state.orderDetail = orderDetail ?? {}; // 工单详情
  796. const { dialogTitle, inputPlaceholder, annexName, classify, earlyResponse } = extra ?? {};
  797. state.dialogTitle = dialogTitle ?? '提交流程'; // 流程标题
  798. state.annexName = annexName ?? '办理附件'; // 附件标题
  799. state.classify = classify ?? '办理上传'; // 附件分类
  800. state.inputPlaceholder = inputPlaceholder ?? '办理意见'; // 意见提示
  801. screenType.value = extra.screenType;
  802. if (earlyResponse) {
  803. earlyResponseData.value = earlyResponse;
  804. }
  805. switch (state.processType) {
  806. case '工单受理': //开始流程
  807. const [orderStartWorkflowResponse] = await Promise.all([orderFlowParams(orderDetail.id)]); //获取开启流程参数
  808. handleResult(orderStartWorkflowResponse);
  809. break;
  810. case '工单撤回': // 撤回流程
  811. const [workflowRecallResponse] = await Promise.all([workflowRecallParams(state.workflowId)]); //获取开启流程参数
  812. handleResult(workflowRecallResponse);
  813. break;
  814. case '延期申请': // 延期申请
  815. const [workflowDelayResponse, responseDelay] = await Promise.all([workflowDelayParams(), delayBaseData()]); //获取开启流程参数
  816. timeType.value = responseDelay.result?.timeType ?? []; // 延期时间单位
  817. handleResult(workflowDelayResponse);
  818. break;
  819. case '延期审批': // 延期审批
  820. const [nextResponseDelayAudit] = await Promise.all([delayApproveParams(state.workflowId)]); //获取延期审批流程参数
  821. handleResult(nextResponseDelayAudit);
  822. break;
  823. case '甄别申请': // 甄别申请
  824. const [workflowDiscernResponse, responseDiscern] = await Promise.all([workflowDiscernParams(), screenBaseData()]); //获取开启流程参数
  825. screenTypeOptions.value = responseDiscern.result?.screenType ?? []; // 甄别理由
  826. handleResult(workflowDiscernResponse);
  827. break;
  828. case '终止申请': // 终止申请
  829. const [workflowTerminateResponse] = await Promise.all([terminateStartFlowParams()]); //获取开启流程参数
  830. handleResult(workflowTerminateResponse);
  831. break;
  832. case '工单退回': // 退回流程
  833. break;
  834. case '甄别退回': // 退回流程
  835. break;
  836. case '甄别审批': // 甄别审批
  837. const [nextResponseDiscernAudit] = await Promise.all([discernApproveParams(state.workflowId)]); //获取甄别审批流程参数
  838. handleResult(nextResponseDiscernAudit);
  839. break;
  840. case '终止审批': // 终止审批
  841. const [nextResponseTerminateAudit] = await Promise.all([terminateNextFlowParams(state.workflowId)]); //获取终止审批流程参数
  842. handleResult(nextResponseTerminateAudit);
  843. break;
  844. case '延期退回': // 退回流程
  845. break;
  846. case '工单办理': // 工单办理
  847. const [workflowNextStepsResponse] = await Promise.all([workflowNextStepsByOrder(state.orderDetail.id)]); // 获取下一节点和下一节点参数
  848. handleResult(workflowNextStepsResponse);
  849. break;
  850. case '工单代办':
  851. const [orderHandleInstanceResponse] = await Promise.all([workflowNextStepsByOrderInstead(state.orderDetail.id)]); // 工单代办参数获取
  852. handleResult(orderHandleInstanceResponse);
  853. break;
  854. case '新增知识':
  855. const [KnowledgeAddStartFlowResponse] = await Promise.all([KnowledgeAddStartFlowParams()]); // 知识库新增参数
  856. handleResult(KnowledgeAddStartFlowResponse);
  857. break;
  858. case '更新知识':
  859. const [KnowledgeUpdateResponse] = await Promise.all([KnowledgeUpdateStartFlowParams()]); // 知识库更新参数
  860. handleResult(KnowledgeUpdateResponse);
  861. break;
  862. case '更新新增知识':
  863. const [KnowledgeAddUpdateResponse] = await Promise.all([KnowledgeAddStartFlowParams()]); // 知识库更新参数
  864. handleResult(KnowledgeAddUpdateResponse);
  865. break;
  866. case '删除知识':
  867. const [KnowledgeDeleteResponse] = await Promise.all([KnowledgeDeleteStartFlowParams()]); // 知识库删除参数
  868. handleResult(KnowledgeDeleteResponse);
  869. break;
  870. case '知识下架':
  871. const [KnowledgeOffShelfResponse] = await Promise.all([KnowledgeOffShelfStartFlowParams()]); // 知识库下架参数
  872. handleResult(KnowledgeOffShelfResponse);
  873. break;
  874. default: // 默认下一流程 工单办理
  875. // 获取下一节点和下一节点参数
  876. const [nextResponse] = await Promise.all([workflowNextSteps(state.workflowId)]);
  877. handleResult(nextResponse);
  878. break;
  879. }
  880. } finally {
  881. state.loading = false;
  882. }
  883. };
  884. const isOrderAccept = computed(() => {
  885. return state.processType === '工单受理';
  886. });
  887. // 常用意见类型
  888. const commonOpinionType = computed(() => {
  889. switch (state.processType) {
  890. case '工单受理':
  891. return commonEnum.Seat;
  892. case '工单退回':
  893. return commonEnum.Return;
  894. case '工单办理':
  895. return commonEnum.OrderCirculation;
  896. case '甄别审批':
  897. case '甄别申请':
  898. return commonEnum.Discriminate;
  899. case '延期审批':
  900. case '延期申请':
  901. return commonEnum.Delay;
  902. case '终止审批':
  903. case '终止申请':
  904. return commonEnum.OrderCirculation;
  905. case '知识审批':
  906. return commonEnum.KnowledgeL;
  907. default:
  908. return commonEnum.OrderCirculation;
  909. }
  910. });
  911. const canReject = ref<boolean>(false); // 是否可以驳回
  912. const timeTypeOptions = ref<EmptyArrayType>([]); // 办理时限单位
  913. const canStartCountersign = ref<boolean>(false); // 是否可以发起会签
  914. const isMainHandlerShow = ref<boolean>(false); // 是否展示主办人
  915. const currentParams = ref<EmptyObjectType>({}); // 当前获取到的参数(当前节点信息)
  916. const orderContent = ref<string>(''); // 受理内容
  917. const handleResult = (res: any) => {
  918. currentParams.value = res.result; // 当前获取到的参数(当前节点信息)
  919. state.nextStepOptions = res.result.steps; //办理对象选择内容
  920. canReject.value = res.result.canReject ?? false; // 是否可以驳回
  921. timeTypeOptions.value = res.result.timeTypeOptions ?? []; // 办理时限申请单位
  922. canStartCountersign.value = res.result.canStartCountersign ?? false; // 是否可以发起会签
  923. isMainHandlerShow.value = res.result.isMainHandlerShow ?? false; // 是否展示主办人
  924. orderContent.value = res.result.content ?? ''; // 受理内容
  925. if (handelArr.includes(state.processType)) {
  926. // 办理才有期满时间
  927. state.ruleForm.expiredTime = res.result.expiredTime ?? null; // 期满时间
  928. }
  929. if (state.nextStepOptions.length === 1) {
  930. // 下一节点是否只有一个 默认选中第一个
  931. setTimeout(() => {
  932. state.ruleForm.nextStepCode = state.nextStepOptions[0].key; // 下一节点code
  933. state.ruleForm.nextStepName = state.nextStepOptions[0].value; // 下一节点name
  934. state.ruleForm.backToCountersignEnd = state.nextStepOptions[0].backToCountersignEnd ?? false; // 是否回到会签结束节点
  935. }, 100);
  936. selectNextStep(state.nextStepOptions[0].key); // 查询流程下一节点参数
  937. } else {
  938. state.ruleForm.nextStepCode = '';
  939. state.ruleForm.nextStepName = '';
  940. }
  941. if (res.result.opinion) {
  942. // 如果有汇总意见没有临时保存 取汇总意见 临时保存会覆盖汇总意见
  943. setTimeout(() => {
  944. state.ruleForm.opinion = res.result.opinion;
  945. }, 100);
  946. }
  947. state.ruleForm.stepId = res.result.stepId;
  948. state.loading = false;
  949. };
  950. // 上一部
  951. const onPrevious = () => {
  952. activeStep.value = 0;
  953. };
  954. const delayFormRef = ref<RefType>(); //延期申请表单组件
  955. const discernFormRef = ref<RefType>(); //甄别申请表单组件
  956. const terminateFormRef = ref<RefType>(); // 终止申请表单组件
  957. const redoFormRef = ref<RefType>(); //重办表单组件
  958. // 下一步
  959. const onNext = () => {
  960. switch (state.processType) {
  961. case '延期申请':
  962. delayFormRef.value?.validate((valid: boolean) => {
  963. if (!valid) return;
  964. activeStep.value = 1;
  965. });
  966. break;
  967. case '甄别申请': // 甄别申请
  968. discernFormRef.value?.validate((valid: boolean) => {
  969. if (!valid) return;
  970. activeStep.value = 1;
  971. });
  972. break;
  973. case '终止申请': // 终止申请
  974. terminateFormRef.value?.validate((valid: boolean) => {
  975. if (!valid) return;
  976. activeStep.value = 1;
  977. });
  978. break;
  979. default: // 默认下一流程
  980. activeStep.value = 1;
  981. break;
  982. }
  983. };
  984. const activeStep = ref(0); //步骤条
  985. watchEffect(() => {
  986. if (state.dialogVisible) {
  987. activeStep.value = showStepsArr.includes(state.processType) ? 0 : 1;
  988. }
  989. });
  990. // 流程选择下一环节
  991. const fastStepCode = ref(''); // 推荐派单处理对象code
  992. const fastStepName = ref(''); // 推荐派单处理对象
  993. // expiredStatus 超期状态(0正常 1即将超期 2已超期) 工单流转选择“结束”节点,点击“办理”时需验证该工单是否处于已超期状态
  994. const isOverdueTips = computed(() => {
  995. return state.orderDetail.expiredStatus === 2 && state.ruleForm.nextStepCode === 'end';
  996. });
  997. // 先确定当前环节是那一步
  998. /*
  999. * currentParams.value.currentStepBusinessType 表示当前节点到哪一步 0坐席 1派单 2部门节点 3部门领导节点
  1000. * */
  1001. /*selectNext.value.businessType 表示选择节点到哪一步 0 坐席 1派单 2部门节点 3部门领导节点
  1002. * selectNext.value.orgLevel 表示部门等级 1 一级部门 2 二级部门 3 三级部门 4 四级部门
  1003. * selectNext.value.stepType 0普通节点 3汇总节点
  1004. * */
  1005. // 话务部到派单组
  1006. const seatTopaidan = computed(() => {
  1007. return currentParams.value.currentStepBusinessType === 0 && selectNext.value.businessType === 1;
  1008. });
  1009. // 话务部到一级部门
  1010. const seatToOrgOne = computed(() => {
  1011. return currentParams.value.currentStepBusinessType === 0 && selectNext.value.businessType === 2 && selectNext.value.orgLevel === 1;
  1012. });
  1013. // 派单组到一级部门
  1014. const paidanToOrgOne = computed(() => {
  1015. return currentParams.value.currentStepBusinessType === 1 && selectNext.value.businessType === 2 && selectNext.value.orgLevel === 1;
  1016. });
  1017. // 当前是否是派单组
  1018. const isPaidan = computed(() => {
  1019. return currentParams.value.currentStepBusinessType === 1;
  1020. });
  1021. // 是否展示短信通知选择
  1022. const isSmsSelectShow = ref(false);
  1023. // 办理对象是否必填 0-角色 1-部门类型 2-部门类型 3-指定用户 4-指定部门
  1024. // 2024/10/28 新增甄别申请 延期申请 终止申请选择办理对象非必填 !showStepsArr.includes(state.processType)
  1025. const nextHandlersRequired = ref<Boolean>(false);
  1026. const selectNext = ref<EmptyObjectType>({}); // 选择的下一个节点
  1027. const selectNextStep = (val: any) => {
  1028. ruleFormRef.value?.resetFields('nextHandlers');
  1029. ruleFormRef.value?.resetFields('nextMainHandler');
  1030. state.ruleForm.nextHandlers = [];
  1031. const next = state.nextStepOptions.find((item: any) => item.key === val);
  1032. selectNext.value = next;
  1033. const items = next.items; //获取下一节点
  1034. state.ruleForm.nextStepName = next.value; // 下一节点name
  1035. state.ruleForm.handlerType = next.handlerType;
  1036. state.ruleForm.businessType = next.businessType;
  1037. state.ruleForm.flowDirection = next.flowDirection;
  1038. state.ruleForm.backToCountersignEnd = next.backToCountersignEnd ?? false; // 是否回到会签结束节点
  1039. state.handlerOptions = items ?? [];
  1040. state.handlerOptions = state.handlerOptions.map((item: any) => {
  1041. return {
  1042. value: {
  1043. ...item,
  1044. },
  1045. label: item.value,
  1046. };
  1047. });
  1048. fastStepName.value = next.recommendOrgName; // 推荐派单处理对象
  1049. fastStepCode.value = next.recommendOrgId; // 推荐派单处理对象code
  1050. if (items.length === 1) {
  1051. // 如果办理对象只有一个默认选中
  1052. state.ruleForm.nextHandlers = [items[0]];
  1053. }
  1054. // 办理对象是否必填
  1055. // nextHandlersRequired.value = ![0].includes(next.handlerType) && !showStepsArr.includes(state.processType);
  1056. nextHandlersRequired.value = ![0].includes(next.handlerType);
  1057. // 以下是默认需要吧短信勾上的场景 话务部到一级部门 派单组到一级部门
  1058. state.ruleForm.isSms = seatToOrgOne.value || paidanToOrgOne.value;
  1059. // 是否展示短信通知 (取消坐席流转至“派单组”时的短信通知选项框 )
  1060. isSmsSelectShow.value = !seatTopaidan.value;
  1061. };
  1062. // 会签是否可用 (配置可以会签 并且选择的是逐级派单,并且是普通节点 并且选择是部门)
  1063. const countersignAble = computed(() => {
  1064. return canStartCountersign.value && state.ruleForm.orderAssignMode === 0 && selectNext.value.stepType === 0 && selectNext.value.businessType === 2;
  1065. });
  1066. // 办理对象是否能够选择多个(可以发起会签可以选择多个,不能发起会签只能选择一个) 加个判断 选择的下一环节必须是部门(会签必须是选择的部门)
  1067. const multipleLimit = computed(() => {
  1068. return canStartCountersign.value && selectNext.value.businessType === 2 ? 0 : 1;
  1069. });
  1070. watch(
  1071. () => state.ruleForm.nextHandlers, // 监听办理对象 多个办理对象自动发起会签
  1072. (val) => {
  1073. state.ruleForm.isStartCountersign = val.length > 1;
  1074. }
  1075. );
  1076. const countersignDisabled = computed(() => {
  1077. // (选中的办理对象如果是一个) 因为是disabled 所以这里取反
  1078. return !(state.ruleForm.nextHandlers.length === 1);
  1079. });
  1080. // 是否发起会签
  1081. const changeStartCountersign = (val: boolean) => {
  1082. /* if (!val) {
  1083. // 如果不能会签清空办理对象
  1084. state.ruleForm.nextHandlers = [];
  1085. ruleFormRef.value?.resetFields('nextHandlers');
  1086. }*/
  1087. };
  1088. // 是否展示办理对象 (结束节点不展示: next.stepType===2 表示为结束节点,下一环节为派单组时 next.businessType === 1,办理对象下拉框隐藏:AppConfigInfo.value.isAverageSendOrder= true 表示开启了平均派单 )
  1089. const showHandlers = computed(() => {
  1090. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  1091. const isAverageSendOrder = AppConfigInfo.value.isAverageSendOrder && next?.businessType === 1; // 开启平均派单并且下一个环节是派单组 !isAverageSendOrder
  1092. if (!next) return true;
  1093. // 话务部到派单 派单组到一级部门 也不需要展示办理对象 如果下一环节是汇总节点与不需要展示办理
  1094. return next?.stepType !== 2 && !(seatToOrgOne.value || paidanToOrgOne.value) && selectNext.value.stepType !== 3;
  1095. });
  1096. // 是否展示部门处理结果 ( 选择结束节点时并且当前操作人不是中心时,显示部门处理结果 )
  1097. const showResult = computed(() => {
  1098. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  1099. return next?.stepType === 2 && !userInfos.value.isCenter;
  1100. });
  1101. // 是否展示警情退回 (选择结束节点时并且工单来源是110时,显示警情退回)
  1102. const showPoliceReturn = computed(() => {
  1103. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  1104. return next?.stepType === 2 && state.orderDetail?.source === 200;
  1105. });
  1106. // 是否是汇总节点(汇总需要填入其他参数)并且是工单办理
  1107. const inputRealHandler = computed(() => {
  1108. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  1109. return next?.inputRealHandler && handelArr.includes(state.processType);
  1110. });
  1111. // 是否显示快捷派单
  1112. const showFastSendOrder = computed(() => {
  1113. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  1114. if (!next) return false;
  1115. return next?.recommendOrgName && next?.recommendOrgId;
  1116. });
  1117. // 快速派单
  1118. const fastSendOrder = () => {
  1119. if (!fastStepCode.value) return;
  1120. // 如果办理对象中没有推荐派单的对象就添加
  1121. if (!state.ruleForm.nextHandlers.find((item: any) => item.key === fastStepCode.value)) {
  1122. const next = state.handlerOptions.find((item: any) => item.value.key === fastStepCode.value);
  1123. if (next) state.ruleForm.nextHandlers = [...state.ruleForm.nextHandlers, next.value];
  1124. }
  1125. };
  1126. // 是否展示办理时限 flowDirection 并且是工单办理
  1127. const flowDirection = computed(() => {
  1128. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  1129. if (!next) return false;
  1130. return [0, 1].includes(next.flowDirection) && handelArr.includes(state.processType);
  1131. });
  1132. // 是否展示备注输入框
  1133. const showRemarkTextarea = computed(() => {
  1134. return ['工单受理', '工单办理'].includes(state.processType);
  1135. });
  1136. // 计算期满时间
  1137. watch(
  1138. () => flowDirection.value,
  1139. (val) => {
  1140. if (val) {
  1141. const next = state.nextStepOptions.find((item: any) => item.key === state.ruleForm.nextStepCode);
  1142. state.ruleForm.flowDirection = next.flowDirection;
  1143. orderTimeConfig({ flowDirection: next.flowDirection, acceptTypeCode: state.orderDetail.acceptTypeCode }).then((res: any) => {
  1144. state.ruleForm.timeLimit = res.result.count ?? null; // 办理时限
  1145. state.ruleForm.timeLimitUnit = res.result.timeType ?? ''; // 办理时限单位
  1146. });
  1147. }
  1148. }
  1149. );
  1150. // 是否展示主办
  1151. const showMainHandler = computed(() => {
  1152. return state.ruleForm.nextHandlers.length > 1 && isMainHandlerShow.value;
  1153. });
  1154. // 主办从办理对象中选择
  1155. state.handlerMainOptions = computed(() => {
  1156. return state.ruleForm.nextHandlers;
  1157. });
  1158. // 选择派单类型 需要清空选择的内容
  1159. const selectDispatchType = () => {
  1160. ruleFormRef.value.resetFields('nextHandlers');
  1161. ruleFormRef.value.resetFields('nextHandler');
  1162. state.ruleForm.nextHandlers = [];
  1163. state.ruleForm.nextHandler = null;
  1164. state.ruleForm.isStartCountersign = false;
  1165. showOrgLevelTwo.value = false;
  1166. state.ruleForm.levelTwoStep = null;
  1167. levelTwoStepOptions.value = [];
  1168. levelTwoHandleOptions.value = [];
  1169. state.ruleForm.levelTwoHandlers = [];
  1170. showOrgLevelThree.value = false;
  1171. state.ruleForm.levelThreeStep = null;
  1172. state.ruleForm.levelThreeHandlers = [];
  1173. levelThreeStepOptions.value = [];
  1174. levelThreeHandleOptions.value = [];
  1175. };
  1176. // 选择办理对象
  1177. const showOrgLevelTwo = ref(false); // 是否展示二级部门选择
  1178. const levelTwoStepOptions = ref<EmptyArrayType>([]); // 二级部门节点
  1179. const levelTwoHandleOptions = ref<EmptyArrayType>([]); // 二级部门办理参数
  1180. const selectHandlers = () => {
  1181. if (state.ruleForm.nextHandlers && state.ruleForm.nextHandlers.length > 1) {
  1182. // AppConfigInfo.value.noSignOrgCode 对应的办理对象不能参与会签
  1183. const isProvince12345 = state.ruleForm.nextHandlers.find((item: any) => AppConfigInfo.value.noSignOrgCode.includes(item.key));
  1184. if (isProvince12345) {
  1185. // 如果选择了省12345平台或者省12345交办就提示不能参与会签 并且从选择中移除
  1186. ElMessage({
  1187. message: '省12345平台和省12345交办不能参与会签',
  1188. grouping: true,
  1189. });
  1190. state.ruleForm.nextHandlers = state.ruleForm.nextHandlers.filter((item: any) => !AppConfigInfo.value.noSignOrgCode.includes(item.key));
  1191. }
  1192. }
  1193. if (state.ruleForm.nextHandlers && state.ruleForm.nextHandlers.length <= 1) {
  1194. // 如果只有一个办理对象就不需要发起会签
  1195. state.ruleForm.isStartCountersign = false;
  1196. }
  1197. if ((seatToOrgOne.value || paidanToOrgOne.value) && state.ruleForm.orderAssignMode === 1) {
  1198. showOrgLevelTwo.value = false;
  1199. state.ruleForm.levelTwoStep = null;
  1200. levelTwoStepOptions.value = [];
  1201. levelTwoHandleOptions.value = [];
  1202. state.ruleForm.levelTwoHandlers = [];
  1203. showOrgLevelThree.value = false;
  1204. state.ruleForm.levelThreeStep = null;
  1205. state.ruleForm.levelThreeHandlers = [];
  1206. levelThreeStepOptions.value = [];
  1207. levelThreeHandleOptions.value = [];
  1208. state.ruleForm.nextHandlers = [state.ruleForm.nextHandler];
  1209. // 话务部到一级部门 派单组到一级部门 并且是跨级派单 需要查询下一级部门
  1210. const request = {
  1211. WorkflowId: state.ruleForm.workflowId,
  1212. StepCode: selectNext.value.key,
  1213. StepType: selectNext.value.stepType,
  1214. BusinessType: selectNext.value.businessType,
  1215. HandlerType: selectNext.value.handlerType,
  1216. OrgIds: state.ruleForm.nextHandler ? [state.ruleForm.nextHandler.key] : [],
  1217. };
  1218. orderAssignParams(request).then((res: any) => {
  1219. showOrgLevelTwo.value = true;
  1220. levelTwoStepOptions.value = res.result.steps.map((item: any) => {
  1221. return {
  1222. value: {
  1223. ...item,
  1224. },
  1225. label: item.value,
  1226. };
  1227. });
  1228. if (res.result.steps.length === 1) {
  1229. state.ruleForm.levelTwoStep = res.result.steps[0];
  1230. levelTwoHandleOptions.value = state.ruleForm.levelTwoStep.items.map((item: any) => {
  1231. return {
  1232. value: {
  1233. ...item,
  1234. },
  1235. label: item.value,
  1236. };
  1237. });
  1238. }
  1239. });
  1240. } else {
  1241. showOrgLevelTwo.value = false;
  1242. }
  1243. };
  1244. // 选择二级部门节点
  1245. const selectOrgLevelTwo = (val: any) => {
  1246. if (val) {
  1247. levelTwoHandleOptions.value = state.ruleForm.levelTwoStep.items.map((item: any) => {
  1248. return {
  1249. value: {
  1250. ...item,
  1251. },
  1252. label: item.value,
  1253. };
  1254. });
  1255. } else {
  1256. levelTwoHandleOptions.value = [];
  1257. state.ruleForm.levelTwoHandlers = [];
  1258. state.ruleForm.levelThreeHandlers = [];
  1259. levelThreeStepOptions.value = [];
  1260. levelThreeHandleOptions.value = [];
  1261. showOrgLevelThree.value = false;
  1262. }
  1263. };
  1264. const showOrgLevelThree = ref(false);
  1265. const levelThreeStepOptions = ref<EmptyArrayType>([]); // 三级部门节点
  1266. const levelThreeHandleOptions = ref<EmptyArrayType>([]); // 三级部门办理参数
  1267. // 选择二级部门办理对象 展示三级办理对象和节点
  1268. const selectOrgLevelTwoHandler = (val: any) => {
  1269. const ids = val.map((item: any) => item.key);
  1270. if (val && val.length) {
  1271. const request = {
  1272. WorkflowId: state.ruleForm.workflowId,
  1273. StepCode: state.ruleForm.levelTwoStep.key,
  1274. StepType: state.ruleForm.levelTwoStep.stepType,
  1275. BusinessType: state.ruleForm.levelTwoStep.businessType,
  1276. HandlerType: state.ruleForm.levelTwoStep.handlerType,
  1277. OrgIds: ids,
  1278. };
  1279. orderAssignParams(request).then((res: any) => {
  1280. showOrgLevelThree.value = true;
  1281. levelThreeStepOptions.value = res.result.steps.map((item: any) => {
  1282. return {
  1283. value: {
  1284. ...item,
  1285. },
  1286. label: item.value,
  1287. };
  1288. });
  1289. if (res.result.steps.length === 1) {
  1290. state.ruleForm.levelThreeStep = res.result.steps[0];
  1291. levelThreeHandleOptions.value = state.ruleForm.levelThreeStep.items.map((item: any) => {
  1292. return {
  1293. value: {
  1294. ...item,
  1295. },
  1296. label: item.value,
  1297. };
  1298. });
  1299. }
  1300. });
  1301. } else {
  1302. state.ruleForm.levelThreeHandlers = [];
  1303. levelThreeStepOptions.value = [];
  1304. levelThreeHandleOptions.value = [];
  1305. showOrgLevelThree.value = false;
  1306. }
  1307. /*const request = {
  1308. WorkflowId: state.ruleForm.workflowId,
  1309. StepCode: val.key,
  1310. StepType: val.stepType,
  1311. BusinessType: val.businessType,
  1312. HandlerType: val.handlerType,
  1313. OrgIds: state.ruleForm.nextHandler ? [state.ruleForm.nextHandler.key] : [],
  1314. };
  1315. console.log(request, selectNext.value);
  1316. orderAssignParams(request).then((res: any) => {
  1317. console.log(res);
  1318. showOrgLevelTwo.value = true;
  1319. levelTwoStepOptions.value = res.result.steps.map((item: any) => {
  1320. return {
  1321. value: {
  1322. ...item,
  1323. },
  1324. label: item.value,
  1325. };
  1326. });
  1327. if(res.result.steps.length === 1){
  1328. state.ruleForm.levelTwoSteps = [res.result.steps[0]];
  1329. }
  1330. });*/
  1331. };
  1332. // 选择三级部门节点
  1333. const selectOrgLevelThree = (val: any) => {
  1334. if (val) {
  1335. levelThreeHandleOptions.value = state.ruleForm.levelThreeStep.items.map((item: any) => {
  1336. return {
  1337. value: {
  1338. ...item,
  1339. },
  1340. label: item.value,
  1341. };
  1342. });
  1343. } else {
  1344. state.ruleForm.levelThreeHandlers = [];
  1345. levelThreeHandleOptions.value = [];
  1346. }
  1347. };
  1348. const selectOrgLevelThreeHandler = () => {};
  1349. // 设置抽屉
  1350. const dialogRef = ref<RefType>();
  1351. const mouseup = () => {
  1352. state.transform = dialogRef.value.dialogContentRef.$el.style.transform;
  1353. };
  1354. // 关闭弹窗
  1355. const closeDialog = () => {
  1356. state.dialogVisible = false;
  1357. };
  1358. // 重置表单方法
  1359. const restForm = (formEl: FormInstance | undefined) => {
  1360. if (!formEl) return;
  1361. state.ruleForm.opinion = '';
  1362. state.delayForm.endTime = '';
  1363. formEl.resetFields();
  1364. formEl.clearValidate();
  1365. };
  1366. // 选择常用意见 填入填写框 办理
  1367. const chooseAdvice = (item: any) => {
  1368. state.ruleForm.opinion += item.content;
  1369. };
  1370. // 选择常用意见 填入填写框 延期
  1371. const chooseAdviceDelay = (item: any) => {
  1372. state.delayForm.content += item.content;
  1373. };
  1374. // 选择常用意见 填入填写框 甄别
  1375. const chooseAdviceDiscern = (item: any) => {
  1376. state.discernForm.content += item.content;
  1377. };
  1378. // 选择常用意见 填入填写框 终止
  1379. const chooseAdviceTerminate = (item: any) => {
  1380. state.terminateForm.content += item.content;
  1381. };
  1382. const afterSubmit = (emitType?: 'orderProcessSuccess' | 'orderProcessFailed', showMessage?: boolean, message?: string) => {
  1383. state.loading = false;
  1384. closeDialog();
  1385. const msg = message ?? '操作成功';
  1386. if (showMessage) ElMessage.success(msg);
  1387. if (emitType) emit(emitType);
  1388. };
  1389. const close = () => {
  1390. restForm(ruleFormRef.value);
  1391. restForm(delayFormRef.value);
  1392. restForm(discernFormRef.value);
  1393. restForm(terminateFormRef.value);
  1394. restForm(redoFormRef.value);
  1395. orderContent.value = '';
  1396. };
  1397. // 办理
  1398. const handleFiles = ref<EmptyArrayType>([]); // 流程附件
  1399. const handleFilesDelay = ref<EmptyArrayType>([]); // 延期附件
  1400. const handleFilesDiscern = ref<EmptyArrayType>([]); // 甄别附件
  1401. const handleFilesTerminate = ref<EmptyArrayType>([]); // 终止附件
  1402. const onSubmit = (formEl: FormInstance | undefined) => {
  1403. if (!formEl) return;
  1404. formEl.validate((valid: boolean) => {
  1405. if (!valid) return;
  1406. state.loading = true;
  1407. let submitObj = other.deepClone(state.ruleForm);
  1408. if (submitObj.nextHandlers && submitObj.nextHandlers.length) {
  1409. if (submitObj.nextHandlers.length === 1) {
  1410. submitObj.nextMainHandler = submitObj.nextHandlers[0].key;
  1411. }
  1412. }
  1413. if (!flowDirection.value) {
  1414. // 需要填写办理时限
  1415. Reflect.deleteProperty(submitObj, 'timeLimit');
  1416. Reflect.deleteProperty(submitObj, 'timeLimitUnit');
  1417. } else {
  1418. submitObj.external = {
  1419. timeLimit: state.ruleForm.timeLimit,
  1420. timeLimitUnit: state.ruleForm.timeLimitUnit,
  1421. };
  1422. }
  1423. Reflect.deleteProperty(submitObj, 'isPoliceReturn');
  1424. Reflect.deleteProperty(submitObj, 'isResolved');
  1425. submitObj.external = {
  1426. isPoliceReturn: state.ruleForm.isPoliceReturn,
  1427. isResolved: state.ruleForm.isResolved,
  1428. };
  1429. let crossSteps: EmptyArrayType = [];
  1430. if (state.ruleForm.orderAssignMode === 1) {
  1431. // 如果选中了跨级派单
  1432. const levelOneParams = {
  1433. // 一级部门
  1434. nextStepCode: state.ruleForm.nextStepCode,
  1435. nextStepName: state.ruleForm.nextStepName,
  1436. flowDirection: state.ruleForm.flowDirection,
  1437. handlerType: state.ruleForm.handlerType,
  1438. stepType: state.ruleForm.stepType,
  1439. businessType: state.ruleForm.businessType,
  1440. nextHandlers: state.ruleForm.nextHandlers,
  1441. sort: 1,
  1442. };
  1443. crossSteps.push(levelOneParams);
  1444. if (state.ruleForm.levelTwoHandlers && state.ruleForm.levelTwoHandlers.length) {
  1445. // 二级部门
  1446. const levelTwoParams = {
  1447. nextStepCode: state.ruleForm.levelTwoStep.key,
  1448. nextStepName: state.ruleForm.levelTwoStep.value,
  1449. flowDirection: state.ruleForm.levelTwoStep.flowDirection,
  1450. handlerType: state.ruleForm.levelTwoStep.handlerType,
  1451. stepType: state.ruleForm.levelTwoStep.stepType,
  1452. businessType: state.ruleForm.levelTwoStep.businessType,
  1453. nextHandlers: state.ruleForm.levelTwoHandlers,
  1454. sort: 2,
  1455. };
  1456. crossSteps.push(levelTwoParams);
  1457. }
  1458. if (state.ruleForm.levelThreeHandlers && state.ruleForm.levelThreeHandlers.length) {
  1459. // 三级部门
  1460. const levelThreeParams = {
  1461. nextStepCode: state.ruleForm.levelThreeStep.key,
  1462. nextStepName: state.ruleForm.levelThreeStep.value,
  1463. flowDirection: state.ruleForm.levelThreeStep.flowDirection,
  1464. handlerType: state.ruleForm.levelThreeStep.handlerType,
  1465. stepType: state.ruleForm.levelThreeStep.stepType,
  1466. businessType: state.ruleForm.levelThreeStep.businessType,
  1467. nextHandlers: state.ruleForm.levelThreeHandlers,
  1468. sort: 3,
  1469. };
  1470. crossSteps.push(levelThreeParams);
  1471. }
  1472. }
  1473. // submitObj.stepExpiredTime = submitObj.expiredTime; //节点过期时间
  1474. switch (state.processType) {
  1475. case '工单受理':
  1476. const request = {
  1477. data: { orderId: state.orderDetail.id, ...submitObj, crossSteps },
  1478. workflow: { ...submitObj, files: handleFiles.value, currentTag: currentParams.value.currentTag },
  1479. };
  1480. orderStartFlow(request)
  1481. .then(() => {
  1482. afterSubmit('orderProcessSuccess', true);
  1483. })
  1484. .catch(() => {
  1485. afterSubmit('orderProcessFailed');
  1486. });
  1487. break;
  1488. case '工单撤回':
  1489. workflowRecall({ ...submitObj, files: handleFiles.value })
  1490. .then(() => {
  1491. afterSubmit('orderProcessSuccess', true);
  1492. })
  1493. .catch(() => {
  1494. afterSubmit('orderProcessFailed');
  1495. });
  1496. break;
  1497. case '延期申请':
  1498. const requestDelay = {
  1499. data: {
  1500. orderId: state.orderDetail.id,
  1501. delayNum: state.delayForm.timeLimitCount,
  1502. delayUnit: state.delayForm.timeLimitUnit,
  1503. delayReason: state.delayForm.content,
  1504. files: handleFilesDelay.value,
  1505. },
  1506. workflow: {
  1507. ...submitObj,
  1508. opinion: state.delayForm.content,
  1509. files: handleFilesDelay.value,
  1510. },
  1511. };
  1512. delayApply(requestDelay)
  1513. .then(() => {
  1514. afterSubmit('orderProcessSuccess', true, '延期申请成功');
  1515. })
  1516. .catch(() => {
  1517. afterSubmit('orderProcessFailed');
  1518. });
  1519. break;
  1520. case '延期退回':
  1521. workflowPrevious({ ...submitObj, files: handleFiles.value })
  1522. .then(() => {
  1523. afterSubmit('orderProcessSuccess', true);
  1524. })
  1525. .catch(() => {
  1526. afterSubmit('orderProcessFailed');
  1527. });
  1528. break;
  1529. case '延期审批':
  1530. if (state.ruleForm.isPass) {
  1531. // 审批通过 下一步
  1532. workflowNext({ ...submitObj, reviewResult: 1, files: handleFiles.value })
  1533. .then(() => {
  1534. afterSubmit('orderProcessSuccess', true);
  1535. })
  1536. .catch(() => {
  1537. afterSubmit('orderProcessFailed');
  1538. });
  1539. } else {
  1540. // 审批拒绝
  1541. const requestDelayAudit = {
  1542. opinion: state.ruleForm.opinion,
  1543. workflowId: state.workflowId,
  1544. files: handleFiles.value,
  1545. stepId: state.ruleForm.stepId,
  1546. };
  1547. workflowReject(requestDelayAudit)
  1548. .then(() => {
  1549. afterSubmit('orderProcessSuccess', true);
  1550. })
  1551. .catch(() => {
  1552. afterSubmit('orderProcessFailed');
  1553. });
  1554. }
  1555. break;
  1556. case '甄别申请':
  1557. const requestDiscern = {
  1558. data: {
  1559. no: state.orderDetail.no,
  1560. visitId: state.orderDetail.visitId,
  1561. visitDetailId: state.orderDetail.visitDetailId,
  1562. orderId: state.orderDetail.id,
  1563. typeDicId: state.discernForm.type.dicDataValue,
  1564. typeDicName: state.discernForm.type.dicDataName,
  1565. content: state.discernForm.content,
  1566. screenType: screenType.value,
  1567. files: handleFilesDiscern.value,
  1568. },
  1569. workflow: { ...submitObj, files: handleFilesDiscern.value, opinion: state.discernForm.content },
  1570. };
  1571. discernApply(requestDiscern)
  1572. .then(() => {
  1573. afterSubmit('orderProcessSuccess', true, '甄别申请成功');
  1574. })
  1575. .catch(() => {
  1576. afterSubmit('orderProcessFailed');
  1577. });
  1578. break;
  1579. case '甄别退回':
  1580. workflowPrevious({ ...submitObj, files: handleFiles.value })
  1581. .then(() => {
  1582. afterSubmit('orderProcessSuccess', true);
  1583. })
  1584. .catch(() => {
  1585. afterSubmit('orderProcessFailed');
  1586. });
  1587. break;
  1588. case '甄别审批':
  1589. if (state.ruleForm.isPass) {
  1590. // 审批通过 下一步
  1591. workflowNext({ ...submitObj, reviewResult: 1, files: handleFiles.value })
  1592. .then(() => {
  1593. afterSubmit('orderProcessSuccess', true);
  1594. })
  1595. .catch(() => {
  1596. afterSubmit('orderProcessFailed');
  1597. });
  1598. } else {
  1599. // 审批拒绝
  1600. const requestDiscernAudit = {
  1601. opinion: state.ruleForm.opinion,
  1602. workflowId: state.workflowId,
  1603. files: handleFiles.value,
  1604. stepId: state.ruleForm.stepId,
  1605. };
  1606. workflowReject(requestDiscernAudit)
  1607. .then(() => {
  1608. afterSubmit('orderProcessSuccess', true);
  1609. })
  1610. .catch(() => {
  1611. afterSubmit('orderProcessFailed');
  1612. });
  1613. }
  1614. break;
  1615. case '终止申请':
  1616. const requestTerminate = {
  1617. data: {
  1618. no: state.orderDetail.no,
  1619. orderId: state.orderDetail.id,
  1620. content: state.terminateForm.content,
  1621. files: handleFilesTerminate.value,
  1622. },
  1623. workflow: { ...submitObj, files: handleFilesTerminate.value, opinion: state.terminateForm.content },
  1624. };
  1625. terminateStartFlow(requestTerminate)
  1626. .then(() => {
  1627. afterSubmit('orderProcessSuccess', true, '终止申请成功');
  1628. })
  1629. .catch(() => {
  1630. afterSubmit('orderProcessFailed');
  1631. });
  1632. break;
  1633. case '终止审批':
  1634. if (state.ruleForm.isPass) {
  1635. // 审批通过 下一步
  1636. workflowNext({ ...submitObj, reviewResult: 1, files: handleFiles.value })
  1637. .then(() => {
  1638. afterSubmit('orderProcessSuccess', true);
  1639. })
  1640. .catch(() => {
  1641. afterSubmit('orderProcessFailed');
  1642. });
  1643. } else {
  1644. // 审批拒绝
  1645. const requestTerminateAudit = {
  1646. opinion: state.ruleForm.opinion,
  1647. workflowId: state.workflowId,
  1648. files: handleFiles.value,
  1649. stepId: state.ruleForm.stepId,
  1650. };
  1651. workflowReject(requestTerminateAudit)
  1652. .then(() => {
  1653. afterSubmit('orderProcessSuccess', true);
  1654. })
  1655. .catch(() => {
  1656. afterSubmit('orderProcessFailed');
  1657. });
  1658. }
  1659. break;
  1660. case '终止退回':
  1661. workflowPrevious({ ...submitObj, files: handleFiles.value })
  1662. .then(() => {
  1663. afterSubmit('orderProcessSuccess', true);
  1664. })
  1665. .catch(() => {
  1666. afterSubmit('orderProcessFailed');
  1667. });
  1668. break;
  1669. case '工单退回':
  1670. orderPrevious({ ...submitObj, files: handleFiles.value, orderId: state.orderDetail.id })
  1671. .then(() => {
  1672. afterSubmit('orderProcessSuccess', true, '退回申请成功');
  1673. })
  1674. .catch(() => {
  1675. afterSubmit('orderProcessFailed');
  1676. });
  1677. break;
  1678. case '工单办理': // 工单办理流程
  1679. case '工单代办': // 工单代办流程
  1680. const requestHandle = {
  1681. data: { orderId: state.orderDetail.id, ...submitObj, crossSteps },
  1682. workflow: { ...submitObj, files: handleFiles.value, currentTag: currentParams.value.currentTag },
  1683. };
  1684. orderHandle(requestHandle)
  1685. .then(() => {
  1686. afterSubmit('orderProcessSuccess', true);
  1687. })
  1688. .catch(() => {
  1689. afterSubmit('orderProcessFailed');
  1690. });
  1691. break;
  1692. case '新增知识':
  1693. const KnowledgeAddRequest = {
  1694. data: { ...state.orderDetail },
  1695. workflow: { ...submitObj, files: handleFiles.value },
  1696. };
  1697. KnowledgeAdd(KnowledgeAddRequest)
  1698. .then(() => {
  1699. afterSubmit('orderProcessSuccess', true, '新增知识成功');
  1700. })
  1701. .catch(() => {
  1702. afterSubmit('orderProcessFailed');
  1703. });
  1704. break;
  1705. case '知识审批':
  1706. if (state.ruleForm.isPass) {
  1707. // 审批通过 下一步
  1708. workflowNext({ ...submitObj, reviewResult: 1, files: handleFiles.value })
  1709. .then(() => {
  1710. afterSubmit('orderProcessSuccess', true);
  1711. })
  1712. .catch(() => {
  1713. afterSubmit('orderProcessFailed');
  1714. });
  1715. } else {
  1716. // 审批拒绝
  1717. const requestDiscernAudit = {
  1718. opinion: state.ruleForm.opinion,
  1719. workflowId: state.workflowId,
  1720. files: handleFiles.value,
  1721. stepId: state.ruleForm.stepId,
  1722. };
  1723. workflowReject(requestDiscernAudit)
  1724. .then(() => {
  1725. afterSubmit('orderProcessSuccess', true);
  1726. })
  1727. .catch(() => {
  1728. afterSubmit('orderProcessFailed');
  1729. });
  1730. }
  1731. break;
  1732. case '更新新增知识':
  1733. const KnowledgeAddUpdateRequest = {
  1734. data: { ...state.orderDetail },
  1735. workflow: { ...submitObj, files: handleFiles.value },
  1736. };
  1737. KnowledgeUpdate(KnowledgeAddUpdateRequest)
  1738. .then(() => {
  1739. afterSubmit('orderProcessSuccess', true);
  1740. })
  1741. .catch(() => {
  1742. afterSubmit('orderProcessFailed');
  1743. });
  1744. break;
  1745. case '更新知识':
  1746. const KnowledgeUpdateRequest = {
  1747. data: { ...state.orderDetail },
  1748. workflow: { ...submitObj, files: handleFiles.value },
  1749. };
  1750. KnowledgeUpdate(KnowledgeUpdateRequest)
  1751. .then(() => {
  1752. afterSubmit('orderProcessSuccess', true);
  1753. })
  1754. .catch(() => {
  1755. afterSubmit('orderProcessFailed');
  1756. });
  1757. break;
  1758. case '删除知识':
  1759. const KnowledgeRemoveRequest = {
  1760. data: { ...state.orderDetail },
  1761. workflow: { ...submitObj, files: handleFiles.value },
  1762. };
  1763. KnowledgeDel(KnowledgeRemoveRequest)
  1764. .then(() => {
  1765. afterSubmit('orderProcessSuccess', true, '删除知识申请成功');
  1766. })
  1767. .catch(() => {
  1768. afterSubmit('orderProcessFailed');
  1769. });
  1770. break;
  1771. case '知识下架':
  1772. const KnowledgeOffShelfRequest = {
  1773. data: { ...state.orderDetail },
  1774. workflow: { ...submitObj, files: handleFiles.value },
  1775. };
  1776. KnowledgeOffShelf(KnowledgeOffShelfRequest)
  1777. .then(() => {
  1778. afterSubmit('orderProcessSuccess', true, '下架知识申请成功');
  1779. })
  1780. .catch(() => {
  1781. afterSubmit('orderProcessFailed');
  1782. });
  1783. break;
  1784. default: // 默认工单办理
  1785. const requestDefault = {
  1786. data: { orderId: state.orderDetail.id, ...submitObj, crossSteps },
  1787. workflow: { ...submitObj, files: handleFiles.value, currentTag: currentParams.value.currentTag },
  1788. };
  1789. orderHandle(requestDefault)
  1790. .then(() => {
  1791. afterSubmit('orderProcessSuccess', true);
  1792. })
  1793. .catch(() => {
  1794. afterSubmit('orderProcessFailed');
  1795. });
  1796. break;
  1797. }
  1798. });
  1799. };
  1800. // 临时保存
  1801. const handleTempSave = () => {
  1802. ruleFormRef.value
  1803. .validateField('opinion')
  1804. .then(() => {
  1805. state.loading = true;
  1806. orderProcessTempSave({ orderId: state.orderDetail.id, opinion: state.ruleForm.opinion })
  1807. .then(() => {
  1808. state.loading = false;
  1809. ElMessage.success('临时保存成功');
  1810. })
  1811. .catch((err) => {
  1812. state.loading = false;
  1813. console.log(err);
  1814. });
  1815. })
  1816. .catch(() => {});
  1817. };
  1818. // 暴露变量
  1819. defineExpose({
  1820. openDialog,
  1821. closeDialog,
  1822. });
  1823. </script>
  1824. <style lang="scss">
  1825. .modal_class {
  1826. pointer-events: none;
  1827. height: 100%;
  1828. }
  1829. .dialog_class {
  1830. pointer-events: auto;
  1831. flex-direction: column;
  1832. margin: 0 !important;
  1833. position: absolute;
  1834. top: 20%;
  1835. left: 25%;
  1836. }
  1837. </style>