index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <!--流程的流转记录-->
  2. <template>
  3. <div class="tels-restApply-precess-record">
  4. <el-dialog :title="state.dialogTitle" v-model="state.dialogVisible" width="90%" draggable destroy-on-close append-to-body>
  5. <slot name="header"></slot>
  6. <slot>
  7. <vxe-table
  8. border
  9. :scrollY="{ enabled: true, gt: 100 }"
  10. :column-config="{
  11. resizable: true,
  12. }"
  13. showOverflow
  14. :loading="gridOptions.loading"
  15. :data="gridOptions.data"
  16. :row-config="{
  17. isHover: true,
  18. height: 30,
  19. useKey: true,
  20. }"
  21. :expand-config="{
  22. padding: true,
  23. trigger: 'row',
  24. }"
  25. max-height="600px"
  26. align="center"
  27. >
  28. <vxe-column type="seq" width="50"></vxe-column>
  29. <vxe-column type="expand" width="50">
  30. <template #content="{ row }">
  31. <!--流程节点-->
  32. <template v-if="row.traceStyle === 0">
  33. <div class="mb10 formatted-text">
  34. <el-text tag="p" class="font-bold">{{ row.handleModeTypeText }}:</el-text>{{ row.opinion }}
  35. </div>
  36. <div class="mb10 formatted-text" v-if="row.remark"><el-text tag="p" class="font-bold">备注信息:</el-text>{{ row.remark }}</div>
  37. <template v-if="row.files.length">
  38. <annex-list name="附件" readonly businessId="" classify="查看附件" v-model="row.files" />
  39. </template>
  40. </template>
  41. <!--发布-->
  42. <template v-if="row.traceStyle === 1">
  43. <div class="mb5"><el-text tag="b">发布状态:</el-text>:{{ row.handleModeText }}</div>
  44. <div class="mb10 formatted-text"><el-text tag="p" class="font-bold">办理意见:</el-text>{{ row.arrangeOpinion }}</div>
  45. </template>
  46. <!--回访-->
  47. <template v-if="row.traceStyle === 2">
  48. <div class="mb5 formatted-text" v-if="row.voiceEvaluateText"><el-text tag="b">语音评价:</el-text>{{ row.voiceEvaluateText }}</div>
  49. <div class="mb5 formatted-text" v-if="row.seatEvaluateText"><el-text tag="b">话务员评价:</el-text>{{ row.seatEvaluateText }}</div>
  50. <div class="mb5 formatted-text" v-if="row.visitContent"><el-text tag="b">话务员回访内容:</el-text>{{ row.visitContent }}</div>
  51. <template v-if="row.orderFlowVisitDetails && row.orderFlowVisitDetails.length">
  52. <div class="mt10" v-for="(item, index) in row.orderFlowVisitDetails" :key="index">
  53. <el-row :gutter="10">
  54. <el-col>
  55. <el-text tag="p" type="primary" class="font-bold mb5" size="large">{{ item.visitOrgName }}</el-text>
  56. </el-col>
  57. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  58. <div class="mb5"><el-text tag="b">部门办件结果:</el-text>{{ item.orgProcessingResults }}</div>
  59. </el-col>
  60. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="item.orgNoSatisfiedReason && item.orgNoSatisfiedReason.length">
  61. <div class="mb5">
  62. <el-text tag="b">不满意原因:</el-text>{{ item.orgNoSatisfiedReason.map((item: any) => item).join(',') }}
  63. </div>
  64. </el-col>
  65. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="item.orgHandledAttitude">
  66. <div class="mb5"><el-text tag="b">部门办件态度:</el-text>{{ item.orgHandledAttitude }}</div>
  67. </el-col>
  68. <el-col>
  69. <div class="mb5 formatted-text"><el-text tag="p" class="font-bold">部门回访内容:</el-text>{{ item.visitContent }}</div>
  70. </el-col>
  71. </el-row>
  72. </div>
  73. </template>
  74. </template>
  75. <!--解释-->
  76. <template v-if="row.traceStyle === 9">
  77. <div class="mb10 formatted-text"><el-text tag="p" class="font-bold">办理意见:</el-text>{{ row.opinion }}</div>
  78. <div class="mb10 formatted-text" v-if="row.remark"><el-text tag="p" class="font-bold">备注信息:</el-text>{{ row.remark }}</div>
  79. <template v-if="row.files.length">
  80. <annex-list name="附件" readonly businessId="" classify="查看附件" v-model="row.files" />
  81. </template>
  82. </template>
  83. </template>
  84. </vxe-column>
  85. <vxe-column field="creationTime" title="建立时间" width="160">
  86. <template #default="{ row }">
  87. {{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
  88. </template>
  89. </vxe-column>
  90. <vxe-column field="name" title="当前节点"></vxe-column>
  91. <vxe-column field="assignerName" title="交办人"></vxe-column>
  92. <vxe-column field="assignOrgName" title="交办部门"></vxe-column>
  93. <vxe-column field="acceptorName" title="接办人"></vxe-column>
  94. <vxe-column field="acceptorOrgName" title="接办部门"></vxe-column>
  95. <vxe-column field="handlerName" title="办理人"></vxe-column>
  96. <vxe-column field="acceptTime" title="签收时间" width="160">
  97. <template #default="{ row }">
  98. {{ formatDate(row.acceptTime, 'YYYY-mm-dd HH:MM:SS') }}
  99. </template>
  100. </vxe-column>
  101. <vxe-column field="handleTime" title="办理时间" width="160">
  102. <template #default="{ row }">
  103. {{ formatDate(row.handleTime, 'YYYY-mm-dd HH:MM:SS') }}
  104. </template>
  105. </vxe-column>
  106. <vxe-column field="stepExpiredTime" title="期满时间" width="160">
  107. <template #default="{ row }">
  108. {{ formatDate(row.stepExpiredTime, 'YYYY-mm-dd HH:MM:SS') }}
  109. </template>
  110. </vxe-column>
  111. <vxe-column field="expiredStatusText" title="超期状态"></vxe-column>
  112. <vxe-column field="handleModeText" title="流转状态">
  113. <template #default="{ row }">
  114. <el-text :type="row.handleMode !== 0 ? 'danger' : ''">{{ row.handleModeText }}</el-text>
  115. </template>
  116. </vxe-column>
  117. <vxe-column title="是否会签" width="90">
  118. <template #default="{ row }">
  119. <template v-if="row.traces && row.traces.length">
  120. <el-button link type="primary" @click.stop="onCountersign(row)">查看会签</el-button>
  121. </template>
  122. <span v-else></span>
  123. </template>
  124. </vxe-column>
  125. </vxe-table>
  126. <!-- <vxe-grid v-bind="gridOptions">
  127. <template #expand_content="{ row }">
  128. &lt;!&ndash;流程节点&ndash;&gt;
  129. <template v-if="row.traceStyle === 0">
  130. <div class="mb10 formatted-text">
  131. <el-text tag="p" class="font-bold">{{ row.handleModeTypeText }}:</el-text>{{ row.opinion }}
  132. </div>
  133. <div class="mb10 formatted-text" v-if="row.remark"><el-text tag="p" class="font-bold">备注信息:</el-text>{{ row.remark }}</div>
  134. <template v-if="row.files.length">
  135. <annex-list name="附件" readonly businessId="" classify="查看附件" v-model="row.files" />
  136. </template>
  137. </template>
  138. &lt;!&ndash;发布&ndash;&gt;
  139. <template v-if="row.traceStyle === 1">
  140. <div class="mb5"><el-text tag="b">发布状态:</el-text>:{{ row.handleModeText }}</div>
  141. <div class="mb10 formatted-text"><el-text tag="p" class="font-bold">办理意见:</el-text>{{ row.arrangeOpinion }}</div>
  142. </template>
  143. &lt;!&ndash;回访&ndash;&gt;
  144. <template v-if="row.traceStyle === 2">
  145. <div class="mb5 formatted-text" v-if="row.voiceEvaluateText"><el-text tag="b">语音评价:</el-text>{{ row.voiceEvaluateText }}</div>
  146. <div class="mb5 formatted-text" v-if="row.seatEvaluateText"><el-text tag="b">话务员评价:</el-text>{{ row.seatEvaluateText }}</div>
  147. <div class="mb5 formatted-text" v-if="row.visitContent"><el-text tag="b">话务员回访内容:</el-text>{{ row.visitContent }}</div>
  148. <template v-if="row.orderFlowVisitDetails && row.orderFlowVisitDetails.length">
  149. <div class="mt10" v-for="(item, index) in row.orderFlowVisitDetails" :key="index">
  150. <el-row :gutter="10">
  151. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  152. <div class="mb5"><el-text tag="b">部门办件结果:</el-text>{{ item.orgProcessingResults }}</div>
  153. </el-col>
  154. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="item.orgNoSatisfiedReason">
  155. <div class="mb5"><el-text tag="b">不满意原因:</el-text>{{ item.orgNoSatisfiedReason }}</div>
  156. </el-col>
  157. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="item.orgHandledAttitude">
  158. <div class="mb5"><el-text tag="b">部门办件态度:</el-text>{{ item.orgHandledAttitude }}</div>
  159. </el-col>
  160. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  161. <div class="mb5"><el-text tag="b">部门回访内容:</el-text>{{ item.visitContent }}</div>
  162. </el-col>
  163. </el-row>
  164. </div>
  165. </template>
  166. </template>
  167. &lt;!&ndash;结束&ndash;&gt;
  168. <template v-if="row.traceStyle === 9">
  169. <div class="mb10 formatted-text"><el-text tag="p" class="font-bold">办理意见:</el-text>{{ row.opinion }}</div>
  170. <div class="mb10 formatted-text" v-if="row.remark"><el-text tag="p" class="font-bold">备注信息:</el-text>{{ row.remark }}</div>
  171. <template v-if="row.files.length">
  172. <annex-list name="附件" readonly businessId="" classify="查看附件" v-model="row.files" />
  173. </template>
  174. </template>
  175. </template>
  176. <template #action="{ row }">
  177. <template v-if="row.traces && row.traces.length">
  178. <el-button link type="primary" @click="onCountersign(row)">查看会签</el-button>
  179. </template>
  180. <span v-else></span>
  181. </template>
  182. <template #handleModeText="{ row }">
  183. <el-text :type="row.handleMode !== 0 ? 'danger' : ''">{{ row.handleModeText }}</el-text>
  184. </template>
  185. </vxe-grid>-->
  186. </slot>
  187. <slot name="footer"></slot>
  188. <template #footer>
  189. <el-button @click="closeDialog" class="default-button">关闭</el-button>
  190. </template>
  191. </el-dialog>
  192. <el-dialog title="查看会签" v-model="countersignDialog" append-to-body draggable destroy-on-close>
  193. <el-form class="show-info-form">
  194. <el-row class="w100">
  195. <!-- <p class="border-title">发起会签信息</p>
  196. <el-row class="pd15 w100">
  197. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  198. <el-form-item label="发起人:">{{ currentRow.createUserName }}</el-form-item>
  199. </el-col>
  200. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  201. <el-form-item label="发起部门:">{{ currentRow.createUserName }}</el-form-item>
  202. </el-col>
  203. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  204. <el-form-item label="发起时间:">{{ currentRow.createUserName }}</el-form-item>
  205. </el-col>
  206. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  207. <el-form-item label="会签状态:">{{ currentRow.createUserName }}</el-form-item>
  208. </el-col>
  209. <el-col>
  210. <el-form-item label="发起意见:">{{ currentRow.createUserName }}</el-form-item>
  211. </el-col>
  212. </el-row>
  213. 20241128000027
  214. <el-divider />-->
  215. <el-col>
  216. <p class="border-title mt10 mb20">会签部门信息</p>
  217. </el-col>
  218. <countersign-data :data="state.countersignData" />
  219. </el-row>
  220. </el-form>
  221. <template #footer>
  222. <el-button @click="closeDialogCountersign" class="default-button">关闭</el-button>
  223. </template>
  224. </el-dialog>
  225. </div>
  226. </template>
  227. <script setup lang="ts" name="auditRecord">
  228. import { reactive, defineAsyncComponent, ref } from 'vue';
  229. import { workflowDetail } from '@/api/system/workflow';
  230. import { transformFile } from '@/utils/tools';
  231. import { formatDate } from '@/utils/formatTime';
  232. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件列表
  233. const CountersignData = defineAsyncComponent(() => import('@/components/ProcessDetail/Countersign-data.vue'));
  234. // 定义变量内容
  235. const state = reactive<any>({
  236. dialogVisible: false,
  237. traces: [],
  238. loading: false,
  239. dialogTitle: '流程明细',
  240. countersignData: [], //会签信息
  241. });
  242. const currentRow = ref();
  243. const gridOptions = reactive<any>({
  244. border: true,
  245. loading: false,
  246. showOverflow: true,
  247. columnConfig: {
  248. resizable: true,
  249. },
  250. scrollY: {
  251. enabled: true,
  252. gt: 100,
  253. },
  254. rowConfig: { isHover: true, height: 30, useKey: true },
  255. expandConfig: { padding: true, trigger: true },
  256. align: 'center',
  257. maxHeight: '500px',
  258. columns: [
  259. { type: 'seq', width: 50 },
  260. { type: 'expand', width: 50, slots: { content: 'expand_content' } },
  261. { field: 'creationTime', title: '建立时间', width: 160, formatter: 'formatDate' },
  262. { field: 'name', title: '当前节点', width: 110 },
  263. { field: 'assignerName', title: '交办人', width: 120 },
  264. { field: 'assignOrgName', title: '交办部门', width: 140 },
  265. { field: 'acceptorName', title: '接办人', width: 120 },
  266. { field: 'acceptorOrgName', title: '接办部门', width: 140 },
  267. { field: 'handlerName', title: '办理人', width: 120 },
  268. { field: 'acceptTime', title: '签收时间', width: 160, formatter: 'formatDate' },
  269. { field: 'handleTime', title: '办理时间', width: 160, formatter: 'formatDate' },
  270. { field: 'stepExpiredTime', title: '期满时间', width: 160, formatter: 'formatDate' },
  271. { field: 'expiredStatusText', title: '超期状态', width: 100 },
  272. { field: 'handleModeText', title: '流转状态', width: 100, slots: { default: 'handleModeText' } },
  273. { title: '是否会签', width: 90, fixed: 'right', slots: { default: 'action' } },
  274. ],
  275. data: [],
  276. });
  277. // 打开弹窗
  278. const openDialog = async (row: any) => {
  279. gridOptions.loading = true;
  280. state.dialogVisible = true;
  281. await getTable(row);
  282. currentRow.value = row;
  283. };
  284. const getTable = async (row: any) => {
  285. try {
  286. // 查询审核记录
  287. const { result } = await workflowDetail(row.workflowId);
  288. state.traces = result ?? [];
  289. state.traces = formatTraces(state.traces);
  290. state.dialogTitle = row.dialogTitle ?? '流程明细';
  291. gridOptions.data = formatTraces(state.traces);
  292. gridOptions.loading = false;
  293. } catch (error) {
  294. console.log(error, '错误');
  295. gridOptions.loading = false;
  296. }
  297. };
  298. const formatTraces = (val: any) => {
  299. if (!val || !val.length) return [];
  300. val.forEach((item: any) => {
  301. item.files = transformFile(item.files);
  302. if (item.traceStyle === 1) {
  303. // 发布需要特殊处理
  304. item.handleModeText = item.publishState ? '公开' : '不公开';
  305. }
  306. if (item.traceStyle === 2) {
  307. // 回访需要特殊处理
  308. item.handleModeText = item.orderFlowVisitDetails
  309. .map((item: any) => {
  310. return item.orgProcessingResults;
  311. })
  312. .join(',');
  313. }
  314. // 需要给意见做一个映射关系 正常就是办理意见 其他状态就是其他意见 比如重办就是重办意见
  315. switch (item.handleMode) {
  316. case 0:
  317. item.handleModeTypeText = '办理意见';
  318. break;
  319. case 100:
  320. item.handleModeTypeText = '退回意见';
  321. break;
  322. case 200:
  323. item.handleModeTypeText = '特提意见';
  324. break;
  325. case 201:
  326. item.handleModeTypeText = '重办意见';
  327. break;
  328. default:
  329. break;
  330. }
  331. switch (item.expiredStatus) {
  332. case 0:
  333. item.type = 'success';
  334. break;
  335. case 1:
  336. item.type = 'primary';
  337. break;
  338. case 2:
  339. item.type = 'danger';
  340. break;
  341. default:
  342. break;
  343. }
  344. if (item.traces?.length) {
  345. formatTraces(item.traces);
  346. }
  347. });
  348. return val;
  349. };
  350. // 关闭流程弹窗
  351. const closeDialog = () => {
  352. state.dialogVisible = false;
  353. };
  354. // 会签弹窗
  355. const countersignDialog = ref(false);
  356. // 查看会签
  357. const onCountersign = (row: any) => {
  358. state.countersignData = row.traces;
  359. countersignDialog.value = true;
  360. };
  361. // 关闭会签弹窗
  362. const closeDialogCountersign = () => {
  363. state.countersignData = [];
  364. countersignDialog.value = false;
  365. };
  366. // 暴露变量
  367. defineExpose({
  368. openDialog,
  369. closeDialog,
  370. });
  371. </script>