todo-list.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <template>
  2. <view>
  3. <!-- 搜索组件 -->
  4. <TodoSearchForm
  5. :search-params="queryParams"
  6. @search="handleSearch"
  7. @reset="handleReset"
  8. />
  9. <view class="bpm-list">
  10. <view
  11. v-for="item in list"
  12. :key="item.id"
  13. class="bpm-card"
  14. @click="handleDetail(item)"
  15. >
  16. <view class="bpm-card-content">
  17. <view class="bpm-card-header">
  18. <view class="bpm-card-title">
  19. {{ item.processInstance?.name }}
  20. </view>
  21. <wd-tag type="primary" plain>
  22. 待审批
  23. </wd-tag>
  24. </view>
  25. <view v-if="item.processInstance?.summary?.length" class="bpm-summary">
  26. <view v-for="(s, idx) in item.processInstance.summary" :key="idx" class="bpm-summary-item">
  27. <text class="text-[#999]">{{ s.key }}:</text>
  28. <text>{{ s.value }}</text>
  29. </view>
  30. </view>
  31. <view class="bpm-card-info">
  32. <view class="bpm-user">
  33. <view class="bpm-avatar">
  34. {{ item.processInstance?.startUser?.nickname?.[0] || '?' }}
  35. </view>
  36. <text class="bpm-nickname">{{ item.processInstance?.startUser?.nickname }}</text>
  37. </view>
  38. <text class="bpm-time--warning">{{ formatPast(item.createTime) }}</text>
  39. </view>
  40. </view>
  41. <view class="bpm-actions">
  42. <view class="bpm-action-btn" @click.stop="handleReject(item)">
  43. <text>拒绝</text>
  44. </view>
  45. <view class="bpm-action-btn" @click.stop="handleApprove(item)">
  46. <text>同意</text>
  47. </view>
  48. </view>
  49. </view>
  50. <!-- 加载更多 -->
  51. <view v-if="loadMoreState !== 'loading' && list.length === 0" class="bpm-empty">
  52. <wd-status-tip image="content" tip="暂无待办任务" />
  53. </view>
  54. <wd-loadmore
  55. v-if="list.length > 0"
  56. :state="loadMoreState"
  57. @reload="loadMore"
  58. />
  59. </view>
  60. </view>
  61. </template>
  62. <script lang="ts" setup>
  63. import type { TodoSearchFormData } from './todo-search-form.vue'
  64. import type { Task } from '@/api/bpm/task'
  65. import type { LoadMoreState } from '@/http/types'
  66. import { onReachBottom } from '@dcloudio/uni-app'
  67. import { onMounted, reactive, ref, watch } from 'vue'
  68. import { getTaskTodoPage } from '@/api/bpm/task'
  69. import { formatDateRange, formatPast } from '@/utils/date'
  70. import TodoSearchForm from './todo-search-form.vue'
  71. import './index.scss'
  72. const props = defineProps<{
  73. active?: boolean
  74. }>()
  75. const total = ref(0)
  76. const list = ref<Task[]>([])
  77. const loadMoreState = ref<LoadMoreState>('loading')
  78. const isFirstLoad = ref(true)
  79. const queryParams = reactive({
  80. pageNo: 1,
  81. pageSize: 10,
  82. name: undefined as string | undefined,
  83. createTime: [undefined, undefined] as [number | undefined, number | undefined],
  84. })
  85. /** 查询列表 */
  86. async function getList() {
  87. loadMoreState.value = 'loading'
  88. try {
  89. const params: any = { ...queryParams }
  90. params.createTime = formatDateRange(queryParams.createTime)
  91. const data = await getTaskTodoPage(params)
  92. list.value = [...list.value, ...data.list]
  93. total.value = data.total
  94. loadMoreState.value = list.value.length >= total.value ? 'finished' : 'loading'
  95. } catch {
  96. queryParams.pageNo = queryParams.pageNo > 1 ? queryParams.pageNo - 1 : 1
  97. loadMoreState.value = 'error'
  98. }
  99. }
  100. /** 加载更多 */
  101. function loadMore() {
  102. if (loadMoreState.value === 'finished') {
  103. return
  104. }
  105. queryParams.pageNo++
  106. getList()
  107. }
  108. /** 搜索 */
  109. function handleSearch(data?: TodoSearchFormData) {
  110. queryParams.name = data?.name
  111. queryParams.createTime = data?.createTime ?? [undefined, undefined]
  112. queryParams.pageNo = 1
  113. list.value = []
  114. getList()
  115. }
  116. /** 重置 */
  117. function handleReset() {
  118. handleSearch()
  119. }
  120. /** 查看详情 */
  121. function handleDetail(item: Task) {
  122. uni.navigateTo({ url: `/pages-bpm/processInstance/detail/index?id=${item.processInstance.id}` })
  123. }
  124. /** 同意 */
  125. function handleApprove(item: Task) {
  126. uni.navigateTo({ url: `/pages-bpm/processInstance/detail/audit/index?id=${item.id}&pass=true` })
  127. }
  128. /** 拒绝 */
  129. function handleReject(item: Task) {
  130. uni.navigateTo({ url: `/pages-bpm/processInstance/detail/audit/index?id=${item.id}&pass=false` })
  131. }
  132. /** 触底加载更多 */
  133. onReachBottom(() => {
  134. loadMore()
  135. })
  136. /** 监听激活状态,刷新数据 */
  137. watch(() => props.active, (val) => {
  138. if (val && !isFirstLoad.value) {
  139. queryParams.pageNo = 1
  140. list.value = []
  141. getList()
  142. }
  143. })
  144. /** 初始化 */
  145. onMounted(() => {
  146. getList()
  147. isFirstLoad.value = false
  148. })
  149. </script>