StuckInstanceTable.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <template>
  2. <el-card shadow="hover" class="detail-card" v-loading="loading">
  3. <template #header>
  4. <div class="detail-header">
  5. <span>流程明细</span>
  6. <div class="detail-actions">
  7. <el-select v-model="localQuery.processDefinitionId" placeholder="流程名称" clearable style="width: 160px;" @change="onProcessChange">
  8. <el-option v-for="def in definitionList" :key="def.id" :label="def.name" :value="def.id" />
  9. </el-select>
  10. <el-input v-model="localQuery.applicantName" placeholder="归属用户" clearable style="width: 140px; margin-left: 8px;" @change="onSearch" />
  11. <el-select v-model="localQuery.currentNodeId" placeholder="当前节点" clearable style="width: 140px; margin-left: 8px;" @change="onSearch">
  12. <el-option v-for="node in currentNodeOptions" :key="node.id" :label="node.name" :value="node.id" />
  13. </el-select>
  14. <el-button type="primary" @click="onSearch" style="margin-left: 8px;">查询</el-button>
  15. </div>
  16. </div>
  17. </template>
  18. <el-table :data="instanceList" stripe>
  19. <el-table-column prop="definitionName" label="流程名称" min-width="140" show-overflow-tooltip />
  20. <el-table-column label="业务编号" min-width="140">
  21. <template #default="{ row }">
  22. {{ row.bizValue || row.instanceNo || '-' }}
  23. </template>
  24. </el-table-column>
  25. <el-table-column prop="applicantName" label="发起人" min-width="100" />
  26. <el-table-column prop="status" label="状态" min-width="90">
  27. <template #default="{ row }">
  28. <el-tag :type="instanceStatusTagType(row.status)">{{ instanceStatusText(row.status) }}</el-tag>
  29. </template>
  30. </el-table-column>
  31. <el-table-column prop="currentNodeName" label="当前节点" min-width="120">
  32. <template #default="{ row }">
  33. {{ row.currentNodeName || row.currentNode || '-' }}
  34. </template>
  35. </el-table-column>
  36. <el-table-column prop="startTime" label="发起时间" min-width="160" />
  37. <el-table-column label="操作" min-width="80" fixed="right">
  38. <template #default="{ row }">
  39. <el-button link type="primary" size="small" @click="emit('detail', row.id)">详情</el-button>
  40. </template>
  41. </el-table-column>
  42. </el-table>
  43. <el-pagination
  44. v-model:current-page="localQuery.pageNum"
  45. v-model:page-size="localQuery.pageSize"
  46. :total="instanceTotal"
  47. :page-sizes="[10, 20, 50]"
  48. layout="total, sizes, prev, pager, next, jumper"
  49. class="pagination"
  50. @size-change="onPageChange"
  51. @current-change="onPageChange"
  52. />
  53. </el-card>
  54. </template>
  55. <script setup lang="ts">
  56. import { reactive, watch } from 'vue'
  57. import { instanceStatusText, instanceStatusTagType } from '@/utils/flow'
  58. import type { FlowInstance, FlowDefinition } from '@/types/flow'
  59. const props = defineProps<{
  60. instanceList: FlowInstance[]
  61. instanceTotal: number
  62. loading: boolean
  63. query: {
  64. pageNum: number
  65. pageSize: number
  66. processDefinitionId?: number
  67. processName: string
  68. applicantName: string
  69. currentNodeId: string
  70. }
  71. definitionList: FlowDefinition[]
  72. currentNodeOptions: { id: string; name: string }[]
  73. }>()
  74. const emit = defineEmits<{
  75. 'update:query': [typeof props.query]
  76. 'process-change': []
  77. 'search': []
  78. 'detail': [number]
  79. }>()
  80. const localQuery = reactive({ ...props.query })
  81. watch(
  82. () => props.query,
  83. (val) => {
  84. Object.assign(localQuery, val)
  85. },
  86. { deep: true, immediate: true }
  87. )
  88. function updateQuery() {
  89. emit('update:query', { ...localQuery })
  90. }
  91. function onProcessChange() {
  92. const def = props.definitionList.find((d) => d.id === localQuery.processDefinitionId)
  93. localQuery.processName = def?.name || ''
  94. localQuery.pageNum = 1
  95. updateQuery()
  96. emit('process-change')
  97. }
  98. function onSearch() {
  99. localQuery.pageNum = 1
  100. updateQuery()
  101. emit('search')
  102. }
  103. function onPageChange() {
  104. updateQuery()
  105. emit('search')
  106. }
  107. </script>
  108. <style scoped>
  109. .detail-card {
  110. margin-bottom: 16px;
  111. }
  112. .detail-header {
  113. display: flex;
  114. justify-content: space-between;
  115. align-items: center;
  116. }
  117. .detail-actions {
  118. display: flex;
  119. align-items: center;
  120. gap: 8px;
  121. }
  122. .el-pagination {
  123. margin-top: 16px;
  124. justify-content: flex-end;
  125. }
  126. </style>