|
|
@@ -419,7 +419,7 @@
|
|
|
<div class="section-body table-wrap">
|
|
|
<a-table
|
|
|
:columns="filteredSweepColumns"
|
|
|
- :data-source="paginatedSweepList"
|
|
|
+ :data-source="sweepList"
|
|
|
:pagination="sweepPagination"
|
|
|
:loading="sweepTableLoading"
|
|
|
:row-key="sweepRowKey"
|
|
|
@@ -1117,59 +1117,87 @@ const filteredSweepColumns = computed(() => {
|
|
|
return sweepColumns.filter(col => col.key !== 'listing_id')
|
|
|
})
|
|
|
|
|
|
-const formatSweepTime = (timestamp: number) => {
|
|
|
- if (!timestamp) return '—'
|
|
|
- const date = new Date(timestamp * 1000)
|
|
|
- return date.toLocaleString('zh-CN', {
|
|
|
- year: 'numeric',
|
|
|
- month: '2-digit',
|
|
|
- day: '2-digit',
|
|
|
- hour: '2-digit',
|
|
|
- minute: '2-digit',
|
|
|
- second: '2-digit',
|
|
|
- hour12: false
|
|
|
- })
|
|
|
+const formatSweepTime = (val: unknown) => {
|
|
|
+ if (val == null || val === '') return '—'
|
|
|
+ // 如果是 Unix 时间戳(数字,值较大如 1745000000)
|
|
|
+ if (typeof val === 'number' && val > 1000000000) {
|
|
|
+ const date = new Date(val * 1000)
|
|
|
+ return date.toLocaleString('zh-CN', {
|
|
|
+ year: 'numeric',
|
|
|
+ month: '2-digit',
|
|
|
+ day: '2-digit',
|
|
|
+ hour: '2-digit',
|
|
|
+ minute: '2-digit',
|
|
|
+ second: '2-digit',
|
|
|
+ hour12: false
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // 如果是字符串格式(如 "2026-04-24 10:30:00"),使用 dayjs 解析
|
|
|
+ const d = dayjs(val as string)
|
|
|
+ return d.isValid() ? d.format('YYYY-MM-DD HH:mm:ss') : '—'
|
|
|
}
|
|
|
|
|
|
const exportSweepTxt = () => {
|
|
|
- const data = sweepList.value
|
|
|
- if (data.length === 0) {
|
|
|
- message.warning('暂无数据可导出')
|
|
|
- return
|
|
|
- }
|
|
|
- const exportData = data.map((item, index) => ({
|
|
|
- '序号': index + 1,
|
|
|
- '饰品ID': item.goods_id || '',
|
|
|
- '饰品名称': item.goods_name || '',
|
|
|
- '区间': item.wear_range || '',
|
|
|
- '已购磨损值': item.purchase_wear || '',
|
|
|
- '目标价格(美元)': item.target_price_usd || '',
|
|
|
- '成交价格(美元)': item.purchase_price_usd || '',
|
|
|
- '成交价格(人民币)': item.purchase_price_cny || '',
|
|
|
- '购买账号': item.steam_account || '',
|
|
|
- '扫货时间': formatSweepTime(item.created_at)
|
|
|
- }))
|
|
|
- const txtContent = JSON.stringify(exportData, null, 2)
|
|
|
- const blob = new Blob(['\ufeff' + txtContent], { type: 'text/plain;charset=utf-8' })
|
|
|
- const url = URL.createObjectURL(blob)
|
|
|
- const link = document.createElement('a')
|
|
|
- link.href = url
|
|
|
- link.download = `扫货成功数据_${new Date().toISOString().slice(0, 10)}.txt`
|
|
|
- link.click()
|
|
|
- URL.revokeObjectURL(url)
|
|
|
- message.success(`已导出 ${data.length} 条数据`)
|
|
|
+ exportingSweepExcel.value = true
|
|
|
+ // 一次性加载所有数据,不受检索条件影响
|
|
|
+ secureApiClient.getAllBuffSweepResultLocal().then(res => {
|
|
|
+ exportingSweepExcel.value = false
|
|
|
+ if (res.code !== 200 || !res.data) {
|
|
|
+ message.error('加载数据失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const data = Array.isArray(res.data.items) ? res.data.items : []
|
|
|
+ if (data.length === 0) {
|
|
|
+ message.warning('暂无数据可导出')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 按时间倒序
|
|
|
+ data.sort((a: any, b: any) => parseLogTimestamp(b?.created_at) - parseLogTimestamp(a?.created_at))
|
|
|
+ const exportData = data.map((item: any, index: number) => ({
|
|
|
+ '序号': index + 1,
|
|
|
+ '饰品ID': item.goods_id || '',
|
|
|
+ '饰品名称': item.goods_name || '',
|
|
|
+ '区间': item.wear_range || '',
|
|
|
+ '已购磨损值': item.purchase_wear || '',
|
|
|
+ '目标价格(美元)': item.target_price_usd || '',
|
|
|
+ '成交价格(美元)': item.purchase_price_usd || '',
|
|
|
+ '成交价格(人民币)': item.purchase_price_cny || '',
|
|
|
+ '购买账号': item.steam_account || '',
|
|
|
+ '扫货时间': formatSweepTime(item.created_at)
|
|
|
+ }))
|
|
|
+ const txtContent = JSON.stringify(exportData, null, 2)
|
|
|
+ const blob = new Blob(['\ufeff' + txtContent], { type: 'text/plain;charset=utf-8' })
|
|
|
+ const url = URL.createObjectURL(blob)
|
|
|
+ const link = document.createElement('a')
|
|
|
+ link.href = url
|
|
|
+ link.download = `扫货成功数据_${new Date().toISOString().slice(0, 10)}.txt`
|
|
|
+ link.click()
|
|
|
+ URL.revokeObjectURL(url)
|
|
|
+ message.success(`已导出 ${data.length} 条数据`)
|
|
|
+ }).catch(() => {
|
|
|
+ exportingSweepExcel.value = false
|
|
|
+ message.error('导出失败')
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
const exportSweepExcel = async () => {
|
|
|
- const data = sweepList.value
|
|
|
- if (data.length === 0) {
|
|
|
- message.warning('暂无数据可导出')
|
|
|
- return
|
|
|
- }
|
|
|
exportingSweepExcel.value = true
|
|
|
try {
|
|
|
+ // 一次性加载所有数据,不受检索条件影响
|
|
|
+ const res = await secureApiClient.getAllBuffSweepResultLocal()
|
|
|
+ if (res.code !== 200 || !res.data) {
|
|
|
+ message.error('加载数据失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let data = Array.isArray(res.data.items) ? res.data.items : []
|
|
|
+ if (data.length === 0) {
|
|
|
+ message.warning('暂无数据可导出')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 按时间倒序
|
|
|
+ data.sort((a: any, b: any) => parseLogTimestamp(b?.created_at) - parseLogTimestamp(a?.created_at))
|
|
|
const XLSX = await import('xlsx')
|
|
|
- const exportData = data.map((item, index) => ({
|
|
|
+ const exportData = data.map((item: any, index: number) => ({
|
|
|
'序号': index + 1,
|
|
|
'饰品ID': item.goods_id || '',
|
|
|
'饰品名称': item.goods_name || '',
|
|
|
@@ -1518,7 +1546,7 @@ const tablePagination = reactive({
|
|
|
const sweepPagination = reactive({
|
|
|
current: 1,
|
|
|
pageSize: 10,
|
|
|
- total: computed(() => filteredSweepList.value.length),
|
|
|
+ total: 0,
|
|
|
showSizeChanger: true,
|
|
|
showTotal: (total: number) => `共 ${total} 条`,
|
|
|
simple: false,
|
|
|
@@ -2812,27 +2840,14 @@ async function fetchSweepResult(showLoading = false): Promise<string | null> {
|
|
|
sweepTableLoading.value = true
|
|
|
}
|
|
|
try {
|
|
|
+ // 后端分页加载
|
|
|
const res = await secureApiClient.getBuffSweepResultLocal(
|
|
|
sweepPagination.current,
|
|
|
sweepPagination.pageSize
|
|
|
)
|
|
|
if (res.code === 200 && res.data) {
|
|
|
- const nextItemsRaw = Array.isArray(res.data.items) ? res.data.items : []
|
|
|
- const nextItems = [...nextItemsRaw].sort((a: any, b: any) => {
|
|
|
- // 主要排序:按 created_at 时间倒序(最新在前)
|
|
|
- const byTime = parseLogTimestamp(b?.created_at) - parseLogTimestamp(a?.created_at)
|
|
|
- if (byTime !== 0) return byTime
|
|
|
- // 次要排序:按 listing_id 倒序(字符串比较,保持顺序一致性)
|
|
|
- const idA = a?.listing_id ?? ''
|
|
|
- const idB = b?.listing_id ?? ''
|
|
|
- return idB.localeCompare(idA)
|
|
|
- })
|
|
|
- // 与选品列表一致:每次拉取后整体替换,轮询时 showLoading=false,表格无整表 loading 闪烁。
|
|
|
- // 限制数组大小,防止内存泄漏
|
|
|
- const MAX_SWEEP_ITEMS = 2000
|
|
|
- sweepList.value = nextItems.length > MAX_SWEEP_ITEMS
|
|
|
- ? nextItems.slice(-MAX_SWEEP_ITEMS)
|
|
|
- : nextItems
|
|
|
+ const items = Array.isArray(res.data.items) ? res.data.items : []
|
|
|
+ sweepList.value = items
|
|
|
sweepPagination.total = res.data.total || 0
|
|
|
// 本地数据没有 status,返回 null 让轮询继续
|
|
|
return null
|
|
|
@@ -2906,8 +2921,12 @@ function startSweepPoll(showFinishMessage = false) {
|
|
|
}
|
|
|
|
|
|
function onSweepTableChange(pagination: any) {
|
|
|
- sweepPagination.current = pagination?.current || 1
|
|
|
- sweepPagination.pageSize = pagination?.pageSize || 10
|
|
|
+ const newPage = pagination?.current || 1
|
|
|
+ const newPageSize = pagination?.pageSize || 10
|
|
|
+ sweepPagination.current = newPage
|
|
|
+ sweepPagination.pageSize = newPageSize
|
|
|
+ // 翻页时重新请求后端数据
|
|
|
+ fetchSweepResult(false)
|
|
|
}
|
|
|
|
|
|
/** 判断是否为网络相关错误(需要重试) */
|