Files
bdrp-app/src/pages/history-query.vue

170 lines
4.1 KiB
Vue
Raw Normal View History

2026-04-20 16:42:28 +08:00
<script setup>
import { onMounted, ref } from 'vue'
2026-04-27 14:48:54 +08:00
import { onReachBottom } from '@dcloudio/uni-app'
2026-04-20 16:42:28 +08:00
definePage({ layout: 'default', auth: true })
const page = ref(1)
const pageSize = ref(10)
const total = ref(0)
const reportList = ref([])
const loading = ref(false)
2026-04-27 14:48:54 +08:00
const hasMore = ref(true)
const loadMoreState = ref('loading')
2026-04-20 16:42:28 +08:00
// 初始加载数据
2026-04-27 14:48:54 +08:00
function mergeUniqueById(oldList, newList) {
const map = new Map()
const resolveKey = (item, index) => String(item?.id ?? item?.order_id ?? `${item?.create_time || ''}_${item?.query_state || ''}_${index}`)
oldList.forEach((item, index) => {
map.set(resolveKey(item, index), item)
})
newList.forEach((item, index) => {
map.set(resolveKey(item, oldList.length + index), item)
})
return Array.from(map.values())
}
async function fetchData(reset = false) {
if (loading.value)
return
if (!reset && !hasMore.value)
return
2026-04-20 16:42:28 +08:00
loading.value = true
2026-04-27 14:48:54 +08:00
if (reset) {
page.value = 1
hasMore.value = true
loadMoreState.value = 'loading'
reportList.value = []
}
2026-04-23 14:57:35 +08:00
const { data, error } = await useApiFetch(`query/list?page=${page.value}&page_size=${pageSize.value}`, { silent: true })
2026-04-20 16:42:28 +08:00
.get()
.json()
if (data.value && !error.value) {
if (data.value.code === 200) {
total.value = data.value.data.total
2026-04-27 14:48:54 +08:00
const incoming = data.value.data.list || []
reportList.value = reset ? incoming : mergeUniqueById(reportList.value, incoming)
const isLastPage = incoming.length < pageSize.value || reportList.value.length >= total.value
hasMore.value = !isLastPage
loadMoreState.value = isLastPage ? 'finished' : 'loading'
if (!isLastPage)
page.value += 1
}
else {
loadMoreState.value = 'error'
2026-04-20 16:42:28 +08:00
}
}
2026-04-27 14:48:54 +08:00
else {
loadMoreState.value = 'error'
}
2026-04-20 16:42:28 +08:00
loading.value = false
}
// 初始加载
onMounted(() => {
2026-04-27 14:48:54 +08:00
fetchData(true)
2026-04-20 16:42:28 +08:00
})
2026-04-27 14:48:54 +08:00
onReachBottom(() => {
2026-04-20 16:42:28 +08:00
fetchData()
2026-04-27 14:48:54 +08:00
})
2026-04-20 16:42:28 +08:00
function toDetail(item) {
if (item.query_state !== 'success')
return
uni.navigateTo({
url: `/pages/report-result-webview?order_id=${encodeURIComponent(String(item.order_id || ''))}`,
})
}
// 状态文字映射
function stateText(state) {
switch (state) {
case 'pending':
return '查询中'
case 'success':
return '查询成功'
case 'failed':
return '查询失败'
case 'refunded':
return '已退款'
default:
return '未知状态'
}
}
// 状态颜色映射
function statusClass(state) {
switch (state) {
case 'pending':
return 'status-pending'
case 'success':
return 'status-success'
case 'failed':
return 'status-failed'
case 'refunded':
return 'status-refunded'
default:
return ''
}
}
</script>
<template>
<view class="flex flex-col gap-4 p-4">
<view class="history-scroll">
<view
v-for="item in reportList" :key="item.id" class="relative mb-4 cursor-pointer rounded-lg bg-white p-4 shadow-sm"
@click="toDetail(item)"
>
<view class="flex flex-col">
<view class="mb-1 text-xl text-black">
{{ item.product_name }}
</view>
<view class="text-sm text-[#999999]">
{{ item.create_time }}
</view>
</view>
<view
class="absolute right-0 top-0 rounded-bl-lg rounded-tr-lg px-2 py-[1px] text-sm text-white font-medium"
:class="[statusClass(item.query_state)]"
>
{{ stateText(item.query_state) }}
</view>
</view>
<view v-if="loading" class="py-4 text-center text-sm text-gray-400">
加载中...
</view>
<view v-else-if="!reportList.length" class="py-4 text-center text-sm text-gray-400">
暂无记录
</view>
</view>
2026-04-27 14:48:54 +08:00
<wd-loadmore :state="loadMoreState" @reload="fetchData" />
2026-04-20 16:42:28 +08:00
</view>
</template>
<style scoped>
.history-scroll {
2026-04-27 14:48:54 +08:00
min-height: calc(100vh - 120px);
2026-04-20 16:42:28 +08:00
}
.status-pending {
background-color: #1976d2;
color: white;
}
.status-success {
background-color: #1FBE5D;
color: white;
}
.status-failed {
background-color: #EB3C3C;
color: white;
}
.status-refunded {
background-color: #999999;
color: white;
}
</style>