|
|
@@ -391,17 +391,35 @@
|
|
|
<div class="section-header-left">
|
|
|
<span class="section-icon">🧾</span>
|
|
|
<span class="section-title">扫货成功数据</span>
|
|
|
+ <div class="selection-search-bar">
|
|
|
+ <a-input
|
|
|
+ v-model:value="sweepSearchKeyword"
|
|
|
+ placeholder="按饰品ID或名称搜索"
|
|
|
+ class="selection-search-input"
|
|
|
+ allow-clear
|
|
|
+ />
|
|
|
+ <span v-if="sweepSearchKeyword && filteredSweepList.length !== sweepList.length" class="selection-search-hint">
|
|
|
+ 匹配 {{ filteredSweepList.length }} / {{ sweepList.length }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<div class="section-actions">
|
|
|
+ <a-button type="link" size="small" class="btn-export" @click="exportSweepTxt">
|
|
|
+ 导出TXT
|
|
|
+ </a-button>
|
|
|
+ <a-button type="link" size="small" class="btn-export" :loading="exportingSweepExcel" @click="exportSweepExcel">
|
|
|
+ 导出Excel
|
|
|
+ </a-button>
|
|
|
+ <a-divider type="vertical" class="btn-divider" />
|
|
|
<a-button type="link" size="small" class="btn-log" @click="openSweepLogModal">
|
|
|
- 扫货日志查看
|
|
|
+ 查看扫货日志
|
|
|
</a-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="section-body table-wrap">
|
|
|
<a-table
|
|
|
- :columns="sweepColumns"
|
|
|
- :data-source="sweepList"
|
|
|
+ :columns="filteredSweepColumns"
|
|
|
+ :data-source="paginatedSweepList"
|
|
|
:pagination="sweepPagination"
|
|
|
:loading="sweepTableLoading"
|
|
|
:row-key="sweepRowKey"
|
|
|
@@ -1063,6 +1081,107 @@ const switchingStatus = computed(() => buffSweepStore.switchingStatus)
|
|
|
const buffPrepareFor = ref<'selection' | 'sweep' | null>(null)
|
|
|
const sweepTableLoading = ref(false)
|
|
|
const sweepList = ref<any[]>([])
|
|
|
+const sweepSearchKeyword = ref('')
|
|
|
+const exportingSweepExcel = ref(false)
|
|
|
+
|
|
|
+const filteredSweepList = computed(() => {
|
|
|
+ if (!sweepSearchKeyword.value.trim()) {
|
|
|
+ return sweepList.value
|
|
|
+ }
|
|
|
+ const keyword = sweepSearchKeyword.value.trim().toLowerCase()
|
|
|
+ return sweepList.value.filter((item) => {
|
|
|
+ const idMatch = String(item.goods_id || item.id || '').toLowerCase().includes(keyword)
|
|
|
+ const nameMatch = (item.goods_name || item.name || '').toLowerCase().includes(keyword)
|
|
|
+ return idMatch || nameMatch
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+const paginatedSweepList = computed(() => {
|
|
|
+ const start = (sweepPagination.current - 1) * sweepPagination.pageSize
|
|
|
+ const end = start + sweepPagination.pageSize
|
|
|
+ return filteredSweepList.value.slice(start, end)
|
|
|
+})
|
|
|
+
|
|
|
+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 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} 条数据`)
|
|
|
+}
|
|
|
+
|
|
|
+const exportSweepExcel = async () => {
|
|
|
+ const data = sweepList.value
|
|
|
+ if (data.length === 0) {
|
|
|
+ message.warning('暂无数据可导出')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ exportingSweepExcel.value = true
|
|
|
+ try {
|
|
|
+ const XLSX = await import('xlsx')
|
|
|
+ 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 ws = XLSX.utils.json_to_sheet(exportData)
|
|
|
+ const wb = XLSX.utils.book_new()
|
|
|
+ XLSX.utils.book_append_sheet(wb, ws, '扫货成功数据')
|
|
|
+ XLSX.writeFile(wb, `扫货成功数据_${new Date().toISOString().slice(0, 10)}.xlsx`)
|
|
|
+ message.success(`已导出 ${data.length} 条数据`)
|
|
|
+ } catch (err) {
|
|
|
+ console.error('导出Excel失败:', err)
|
|
|
+ message.error('导出Excel失败')
|
|
|
+ } finally {
|
|
|
+ exportingSweepExcel.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
type BoundSteamApiAccount = {
|
|
|
id: number
|
|
|
steam_username: string
|
|
|
@@ -1385,9 +1504,11 @@ const tablePagination = reactive({
|
|
|
const sweepPagination = reactive({
|
|
|
current: 1,
|
|
|
pageSize: 10,
|
|
|
- total: 0,
|
|
|
+ total: computed(() => filteredSweepList.value.length),
|
|
|
showSizeChanger: true,
|
|
|
- showTotal: (total: number) => `共 ${total} 条`
|
|
|
+ showTotal: (total: number) => `共 ${total} 条`,
|
|
|
+ simple: false,
|
|
|
+ showQuickJumper: true
|
|
|
})
|
|
|
|
|
|
const columns = [
|
|
|
@@ -2779,7 +2900,6 @@ function startSweepPoll(showFinishMessage = false) {
|
|
|
function onSweepTableChange(pagination: any) {
|
|
|
sweepPagination.current = pagination?.current || 1
|
|
|
sweepPagination.pageSize = pagination?.pageSize || 10
|
|
|
- fetchSweepResult(true)
|
|
|
}
|
|
|
|
|
|
/** 判断是否为网络相关错误(需要重试) */
|