index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <template>
  2. <div class="handlecenter_box">
  3. <van-tabs v-model:active="searchData['status']" :sticky="true" @click-tab="tabClickHandle">
  4. <div class="search_box">
  5. <div class="search_input">
  6. <van-search
  7. v-model="searchData['searchVal']"
  8. background="transparent"
  9. placeholder="搜索标题、申请编号、申请内容"
  10. @search="searchHandler"
  11. />
  12. </div>
  13. <div class="search_icon">
  14. <van-button type="primary" icon="replay" size="small" @click="resetHandler"></van-button>
  15. <van-icon name="filter-o" size="24" color="#51555A" @click="modelShow = true" style="margin-left: 6px;"/>
  16. </div>
  17. </div>
  18. <van-tab :title="'待办('+handlerCaseStatis['normal']+')'" name="1">
  19. <div class="handlecenter_card_box">
  20. <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
  21. <van-list
  22. v-model:loading="loading"
  23. :finished="finished"
  24. finished-text="没有更多了"
  25. @load="onLoad"
  26. >
  27. <div class="handlecenter_card" v-for="(item,index) in handleLists" :key="index">
  28. <div class="header">
  29. <p class="title">
  30. <span>业务编号:</span>
  31. <span>{{item['CODE']}}</span>
  32. </p>
  33. <p class="status">
  34. <span v-html="item['statusVal']"></span>
  35. </p>
  36. </div>
  37. <div class="content" @click="clickHandler(item, false)">
  38. <div class="titleBox">
  39. <p class="title">{{item['NAME']}}</p>
  40. <p class="desc">办理环节:<span>{{item['ACTIVITYNAME']}}</span></p>
  41. </div>
  42. <div class="desc">{{item['DESCRIBTION']??'暂无流程描述'}}</div>
  43. </div>
  44. <div class="tip">
  45. <div class="one">
  46. <van-icon name="clock-o" />
  47. <span>{{formatDateTime(new Date(item['STARTTIME']))}}</span>
  48. </div>
  49. <div class="two" @click="processLogHandle(item)">
  50. <van-button type="primary" icon="todo-list-o" size="mini">流程日志</van-button>
  51. </div>
  52. </div>
  53. </div>
  54. </van-list>
  55. </van-pull-refresh>
  56. </div>
  57. </van-tab>
  58. <van-tab :title="'已完成('+handlerCaseStatis['finish']+')'" name="90">
  59. <div class="handlecenter_card_box">
  60. <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
  61. <van-list
  62. v-model:loading="loading"
  63. :finished="finished"
  64. finished-text="没有更多了"
  65. @load="onLoad"
  66. >
  67. <div class="handlecenter_card" v-for="(item,index) in handleLists" :key="index">
  68. <div class="header">
  69. <p class="title">
  70. <span>业务编号:</span>
  71. <span>{{item['CODE']}}</span>
  72. </p>
  73. <p class="status">
  74. <!-- <span>{{ item['IS_END'] === 1 ? '归档' : '完成' }}</span> -->
  75. <span v-html="item['statusVal']"></span>
  76. </p>
  77. </div>
  78. <div class="content" @click="clickHandler(item, true)">
  79. <div class="titleBox">
  80. <p class="title">{{item['NAME']}}</p>
  81. <p class="desc">完成环节:<span>{{item['ACTIVITYNAME']}}</span></p>
  82. </div>
  83. <div class="desc">{{item['DESCRIBTION']??'暂无流程描述'}}</div>
  84. </div>
  85. <div class="tip">
  86. <div class="one">
  87. <van-icon name="clock-o" />
  88. <span>{{formatDateTime(new Date(item['STARTTIME']))}}</span>
  89. </div>
  90. <div class="two" @click="processLogHandle(item)">
  91. <van-button type="primary" icon="todo-list-o" size="mini">流程日志</van-button>
  92. </div>
  93. </div>
  94. </div>
  95. </van-list>
  96. </van-pull-refresh>
  97. </div>
  98. </van-tab>
  99. <van-tab :title="'已归档('+handlerCaseStatis['archive']+')'" name="99">
  100. <div class="handlecenter_card_box">
  101. <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
  102. <van-list
  103. v-model:loading="loading"
  104. :finished="finished"
  105. finished-text="没有更多了"
  106. @load="onLoad"
  107. >
  108. <div class="handlecenter_card" v-for="(item,index) in handleLists" :key="index">
  109. <div class="header">
  110. <p class="title">
  111. <span>业务编号:</span>
  112. <span>{{item['CODE']}}</span>
  113. </p>
  114. <p class="status">
  115. <span v-html="item['statusVal']"></span>
  116. </p>
  117. </div>
  118. <div class="content" @click="clickHandler(item, true)">
  119. <div class="titleBox">
  120. <p class="title">{{item['NAME']}}</p>
  121. </div>
  122. <div class="desc">{{item['DESCRIBTION']??'暂无流程描述'}}</div>
  123. </div>
  124. <div class="tip">
  125. <div class="one">
  126. <van-icon name="clock-o" />
  127. <span>{{formatDateTime(new Date(item['STARTTIME']))}}</span>
  128. </div>
  129. <div class="two" @click="processLogHandle(item)">
  130. <van-button type="primary" icon="todo-list-o" size="mini">流程日志</van-button>
  131. </div>
  132. </div>
  133. </div>
  134. </van-list>
  135. </van-pull-refresh>
  136. </div>
  137. </van-tab>
  138. </van-tabs>
  139. <van-dialog :show-cancel-button="true" v-model:show="modelShow" title="流程目录" @confirm="confirmHandle">
  140. <van-tree-select
  141. v-model:active-id="activeIds"
  142. v-model:main-active-index="activeIndex"
  143. :items="items"
  144. />
  145. </van-dialog>
  146. <van-dialog v-model:show="processLogShow" title="流程日志" confirmButtonText="关闭">
  147. <div class="processLogBox">
  148. <ul>
  149. <li v-for="(item,index) in processLogs" :key="index">
  150. <p :class="'status color'+item['handleMethod']">{{ filterStatus(item['handleMethod']) }}</p>
  151. <p class="header">{{ item['activityName'] }}</p>
  152. <p>{{ item['handleMethod'] === 0 ? '退回人' : '办理人' }}:{{ item['handler'] }}</p>
  153. <p>转件时间:{{item['receiveTime']}}</p>
  154. <p>办理时限:{{ item['shouldFinishTime'] ? item['shouldFinishTime'] : '无时限' }}</p>
  155. <p v-if="item['transferActivityName']">转至》{{ item['transferActivityName'] ? `[${item['transferActivityName']}]` : ''}}<span style="display: inline-block;margin-left: 5px;"></span></p>
  156. <p v-if="item['transferActivityName']">可办理人:{{ item['canHandler'] }}</p>
  157. </li>
  158. </ul>
  159. </div>
  160. </van-dialog>
  161. </div>
  162. </template>
  163. <script setup lang="ts">
  164. import { showToast } from "vant";
  165. import { getHandlerCaseCenterList, getHandlerCaseCenterCount,getRecordList, getFlowTemplateTreeDataByUser, saveAndGetMobileUrl } from '@/service/flow';
  166. import { listToTree } from '@/utils/tree';
  167. import PubsubService from "@/utils/PubsubService";
  168. import { formatDateTime, getQueryParamsByUrl } from '@/utils/common';
  169. import { useCommonStoreWithOut } from '@/stores/modules/common';
  170. defineOptions({
  171. name: 'HandleCenter'
  172. })
  173. const items = ref([]);
  174. const loading = ref(false);
  175. const finished = ref(false);
  176. const modelShow = ref(false);
  177. const refreshing = ref(false);
  178. const activeIds = ref<string[]>([]);
  179. const activeIndex = ref<number>(0);
  180. const onRefresh = () => {
  181. queryHandlerCaseCenterCount();
  182. queryHandlerCaseCenterList(true);
  183. };
  184. const onLoad = () => {
  185. loading.value = true;
  186. pageData.value.page = pageData.value.page + 1
  187. queryHandlerCaseCenterList();
  188. };
  189. const searchHandler = () => {
  190. queryHandlerCaseCenterCount();
  191. queryHandlerCaseCenterList(true);
  192. }
  193. const pageData = ref<{
  194. page: number
  195. rows: number
  196. records?: number
  197. }>({
  198. page: 0,
  199. rows: 10,
  200. records: 0
  201. })
  202. const searchData = ref<{
  203. status: string
  204. searchVal: string
  205. }>({
  206. status: '1',
  207. searchVal: ''
  208. })
  209. const handlerCaseStatis = ref<{
  210. normal: number
  211. finish: number
  212. archive: number
  213. }>({
  214. normal: 0,
  215. finish: 0,
  216. archive: 0
  217. })
  218. const queryHandlerCaseCenterCount = () => {
  219. const sendData = {
  220. isMobile: true,
  221. toSystemId: '',
  222. flowTemIds: JSON.stringify(activeIds.value),
  223. ...searchData.value
  224. }
  225. getHandlerCaseCenterCount(sendData).then((result:any) => {
  226. if (result) {
  227. handlerCaseStatis.value.normal = result.NORMAL
  228. handlerCaseStatis.value.finish = result.FINISH
  229. handlerCaseStatis.value.archive = result.ARCHIVE
  230. }
  231. })
  232. }
  233. queryHandlerCaseCenterCount()
  234. const handleLists = ref<any[]>([]);
  235. const queryHandlerCaseCenterList = (isPull = false) => {
  236. if (isPull) {
  237. pageData.value.page = 1
  238. refreshing.value = true;
  239. finished.value = false;
  240. }
  241. const sendData = {
  242. IEnd: 0,
  243. isMobile: true,
  244. toSystemId: '',
  245. flowTemIds: JSON.stringify(activeIds.value),
  246. ...pageData.value,
  247. ...searchData.value
  248. }
  249. getHandlerCaseCenterList(sendData).then((result: any) => {
  250. if (result.error_code) {
  251. finished.value = true;
  252. return;
  253. }
  254. if (result && result.rows) {
  255. isPull ? handleLists.value = result.rows : handleLists.value?.push(...result.rows)
  256. }
  257. if (isPull) {
  258. refreshing.value = false
  259. }
  260. /** 用来解决tab切换时,容器高度发生变化自动触发loading事件 */
  261. const time = setTimeout(() => {
  262. loading.value = false;
  263. clearTimeout(time);
  264. }, 800);
  265. if (result.records === handleLists.value.length) {
  266. finished.value = true;
  267. }
  268. });
  269. }
  270. const tabClickHandle = () => {
  271. loading.value = true;
  272. queryHandlerCaseCenterList(true);
  273. }
  274. const sendData = {
  275. isRight: 0,
  276. officeStatus: 1,
  277. excludedSystemId: '',
  278. toSystemId: '',
  279. };
  280. getFlowTemplateTreeDataByUser(sendData).then((result: any) => {
  281. result.forEach((item: any) => {
  282. item['text'] = item['name']
  283. })
  284. if (result && result.length > 0) {
  285. items.value = listToTree(result)[0]['children'];
  286. }
  287. });
  288. const resetHandler = () => {
  289. loading.value = true;
  290. searchData.value.searchVal = ''
  291. activeIds.value = []
  292. queryHandlerCaseCenterCount();
  293. queryHandlerCaseCenterList(true);
  294. }
  295. const confirmHandle = () => {
  296. loading.value = true;
  297. queryHandlerCaseCenterCount();
  298. queryHandlerCaseCenterList(true);
  299. }
  300. /**
  301. * 流程办理或查看
  302. */
  303. const CommonStore = useCommonStoreWithOut();
  304. const router = useRouter();
  305. const toPageHandle = (path: string, params: any) => {
  306. if (path) {
  307. //@ts-ignore
  308. const arr = path.split(window?.locationBaseUrl)
  309. if (arr.length > 1) {
  310. const {url, query} = getQueryParamsByUrl(arr[1])
  311. Object.assign(query, params);
  312. router.push({
  313. path: url,
  314. query
  315. })
  316. }
  317. }
  318. };
  319. const clickHandler = (item: any, isView: boolean) => {
  320. let btnArrJson: any[] = []
  321. if (item && item['btnArrJson']) {
  322. btnArrJson = JSON.parse(item['btnArrJson'])
  323. }
  324. const sendData = {
  325. "activityInsId": item['ACTIVITYINSID'],
  326. "flowInsId": item['FLOWINSID'],
  327. "participantId": item['PARTICIPANTID'],
  328. "isView": isView,
  329. "status": ''
  330. }
  331. CommonStore.setCFlowItemData({
  332. FLOWINSID: item['FLOWINSID'],
  333. CODE: item['CODE'],
  334. DESCRIBTION: item['DESCRIBTION'],
  335. ACTIVITYNAME: item['ACTIVITYINSID']
  336. })
  337. const operationMap = filterToCalBackBtn(btnArrJson);
  338. saveAndGetMobileUrl(sendData).then((result) => {
  339. if (typeof (result) === 'string') {
  340. toPageHandle(result, {
  341. '_isCalBack': operationMap['isCalback'],
  342. '_isObsolete': operationMap['isObsolete']
  343. })
  344. }
  345. });
  346. }
  347. type OperationType = {
  348. isCalback: string
  349. isObsolete: string
  350. }
  351. const filterToCalBackBtn = (lists: any[]): OperationType => {
  352. const map: OperationType = {
  353. isCalback: '0',
  354. isObsolete: '0'
  355. }
  356. for (let i: number = 0; i < lists.length; i++){
  357. if (lists[i]['name'] === "calBackBtn") {
  358. map['isCalback'] = lists[i]['iEnable'] ? '1' : '0'
  359. continue;
  360. }
  361. if (lists[i]['name'] === "obsoleteBtn") {
  362. map['isObsolete'] = lists[i]['iEnable'] ? '1' : '0'
  363. continue;
  364. }
  365. }
  366. return map;
  367. }
  368. /**
  369. * 流程日志
  370. */
  371. const filterStatus = (status: number) => {
  372. let msg = '';
  373. switch (status) {
  374. case 0:
  375. msg = '退件'
  376. break
  377. case 1:
  378. msg = '转件'
  379. break
  380. default:
  381. msg = '办理'
  382. break
  383. }
  384. return msg;
  385. }
  386. const processLogShow = ref<boolean>(false)
  387. const processLogs = ref<any[]>([])
  388. const processLogHandle = (item) => {
  389. getRecordList({
  390. flowInstanceId: item['FLOWINSID'],
  391. _search: false,
  392. sord: 'asc'
  393. }).then((result: any) => {
  394. if (result && result.length > 0) {
  395. processLogs.value = result
  396. processLogShow.value = true;
  397. }else{
  398. showToast({
  399. message: "暂无流程日志!",
  400. position: "top",
  401. });
  402. }
  403. })
  404. }
  405. PubsubService.subscribe('HandleCenterEvent', () => {
  406. searchHandler();
  407. })
  408. </script>
  409. <style lang="scss" scoped>
  410. @import "./index.scss";
  411. </style>