ProcessTraceList.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <template>
  2. <el-timeline>
  3. <el-timeline-item
  4. v-for="activity in props.trace.activities"
  5. :key="activity.activityId"
  6. :timestamp="displayTime(activity.completeTime)"
  7. :hide-timestamp="!displayTime(activity.completeTime)"
  8. >
  9. <div>
  10. <el-tag :effect="activity.nodeType === 'VIRTUAL' ? 'plain' : 'light'">
  11. <el-icon><component :is="getIcon(activity.nodeType)" /></el-icon>
  12. {{ activity.nodeName }}
  13. </el-tag>
  14. <div style="margin-top: 10px">
  15. <el-table :data="activity.assignments" border stripe row-key="assignId">
  16. <el-table-column prop="receiverName" label="审批人" :width="120">
  17. <template #default="scope">
  18. <span :title="scope.row.receiverFullPath">{{ scope.row.receiverName }}</span>
  19. </template>
  20. </el-table-column>
  21. <el-table-column prop="operateTime" label="审批时间" :width="120">
  22. <template #default="scope">{{ displayTime(scope.row.operateTime) }}</template>
  23. </el-table-column>
  24. <el-table-column prop="operateStatus" label="操作" :width="120">
  25. <template #default="scope">
  26. <el-tag v-if="scope.row.operateStatus && scope.row.operateStatus !== 'NONE'" :type="getNodeStatusType(scope.row.operateStatus)">
  27. {{ getNodeStatusName(scope.row.operateStatus) }}
  28. </el-tag>
  29. </template>
  30. </el-table-column>
  31. <el-table-column prop="comments" label="审批意见" show-overflow-tooltip :width="120"></el-table-column>
  32. <el-table-column prop="accessoryList" label="意见附件" :width="120">
  33. <template #default="scope">
  34. <accessory-uploader :modelValue="scope.row.accessoryList" category="workflow" readonly />
  35. </template>
  36. </el-table-column>
  37. <el-table-column :width="80">
  38. <template #default="scope">
  39. <el-button v-if="activity.nodeType === 'BRANCH'" @click="onTraceChild(scope.row.assignId)">
  40. <el-icon title="查看子流程"><ZoomIn /></el-icon>
  41. </el-button>
  42. </template>
  43. </el-table-column>
  44. </el-table>
  45. </div>
  46. </div>
  47. </el-timeline-item>
  48. </el-timeline>
  49. </template>
  50. <script setup lang="ts">
  51. import dayjs from 'dayjs'
  52. import type { TagProps } from 'element-plus'
  53. import type { TraceInfo, NodeDescriptorType, OperateStatus } from '@cacp/ui'
  54. import AccessoryUploader from '@/components/accessory/AccessoryUploader.vue'
  55. type TagType = TagProps['type']
  56. const props = defineProps<{
  57. trace?: TraceInfo
  58. }>()
  59. const emits = defineEmits<{
  60. (e: 'on-trace-child', assignId: string): void
  61. }>()
  62. function displayTime(dt: string) {
  63. return dt ? dayjs(dt).format('YYYY-MM-DD HH:mm') : ''
  64. }
  65. function getIcon(nodeType: NodeDescriptorType) {
  66. if (nodeType === 'START') {
  67. return 'VideoPlay'
  68. } else if (nodeType === 'END') {
  69. return 'CircleCheck'
  70. } else if (nodeType === 'BRANCH') {
  71. return 'FolderAdd'
  72. } else {
  73. return 'Memo'
  74. }
  75. }
  76. function getNodeStatusType(status: OperateStatus): TagType | undefined {
  77. if (status === 'AGREE') {
  78. return 'primary'
  79. } else if (status === 'BACK') {
  80. return 'warning'
  81. } else if (status === 'REJECT') {
  82. return 'danger'
  83. } else if (status === 'REVOKE') {
  84. return 'info'
  85. }
  86. }
  87. function getNodeStatusName(status: OperateStatus) {
  88. if (status === 'AGREE') {
  89. return '流转'
  90. } else if (status === 'BACK') {
  91. return '退回'
  92. } else if (status === 'REJECT') {
  93. return '驳回'
  94. } else if (status === 'REVOKE') {
  95. return '撤回'
  96. } else {
  97. return ''
  98. }
  99. }
  100. function onTraceChild(assignId: string) {
  101. emits('on-trace-child', assignId)
  102. }
  103. </script>