Files
uniapp_ycc/src/pages/historyQuery/index.vue
2026-02-09 15:13:40 +08:00

195 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
definePage({
layout: 'PageLayout',
style: {
navigationBarTitleText: '历史查询',
navigationStyle: 'default',
},
})
import { ref, onMounted, computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useUserStore } from '@/stores/userStore'
import useApiFetch from '@/composables/useApiFetch'
const userStore = useUserStore()
const { isLoggedIn, mobile } = storeToRefs(userStore)
const page = ref(1)
const pageSize = 10
const total = ref(0)
const reportList = ref([])
const loading = ref(false)
const finished = ref(false)
const queryRetentionDays = 30
const showBindNotice = computed(
() => isLoggedIn.value && !mobile.value && reportList.value.length > 0
)
const hasNoRecords = computed(() => reportList.value.length === 0)
async function fetchData() {
if (loading.value || finished.value) return
loading.value = true
try {
const { data, error } = await useApiFetch(
`query/list?page=${page.value}&page_size=${pageSize}`
)
.get()
.json()
if (data.value && !error.value) {
if (data.value.code === 200) {
total.value = data.value.data.total
if (data.value.data.list && data.value.data.list.length > 0) {
reportList.value.push(...data.value.data.list)
page.value += 1
}
if (reportList.value.length >= total.value) {
finished.value = true
}
} else {
finished.value = true
}
} else {
finished.value = true
}
} catch (err) {
finished.value = true
} finally {
loading.value = false
}
}
onMounted(() => {
fetchData()
})
function onLoadMore() {
if (!finished.value && !loading.value) fetchData()
}
function toDetail(item) {
if (item.query_state !== 'success') return
uni.navigateTo({
url: `/pages/report/index?orderId=${item.order_id || ''}`,
})
}
function toBindPhone() {
uni.navigateTo({ url: '/pages/me/index' })
}
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 p-4 min-h-screen">
<view
v-if="showBindNotice"
class="bg-yellow-50 border border-yellow-200 text-yellow-700 rounded-lg p-3 flex items-center justify-between mb-4"
>
<text class="text-sm flex-1">为防止报告丢失请绑定手机号</text>
<button
class="px-3 py-1 text-sm font-medium bg-blue-500 text-white rounded"
@click="toBindPhone"
>
绑定手机号
</button>
</view>
<view class="text-xs text-gray-500 mb-4">
为保障用户隐私及数据安全报告保留{{ queryRetentionDays }}过期自动清理
</view>
<view
v-if="hasNoRecords"
class="bg-white rounded-lg shadow-sm p-6 flex flex-col items-center justify-center gap-3"
>
<text class="text-gray-600 text-sm">暂无历史报告</text>
</view>
<scroll-view
v-else
scroll-y
class="flex-1"
style="height: 70vh"
:lower-threshold="80"
@scrolltolower="onLoadMore"
>
<view
v-for="item in reportList"
:key="item.id"
class="bg-white rounded-lg shadow-sm p-4 mb-4 relative"
@click="toDetail(item)"
>
<view class="flex flex-col">
<text class="text-xl text-black mb-1">{{ item.product_name }}</text>
<text class="text-sm text-[#999999]">{{ item.create_time }}</text>
</view>
<view
class="absolute top-0 right-0 rounded-bl-lg rounded-tr-lg px-2 py-0.5 text-white text-sm font-medium"
:class="[statusClass(item.query_state)]"
>
{{ stateText(item.query_state) }}
</view>
</view>
<view
v-if="reportList.length > 0"
class="py-4 text-center text-gray-400 text-sm"
>
<text v-if="loading">加载中...</text>
<text v-else-if="finished">没有更多了</text>
<text v-else>上拉加载更多</text>
</view>
</scroll-view>
</view>
</template>
<style scoped>
.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>