218 lines
6.6 KiB
Vue
218 lines
6.6 KiB
Vue
<template>
|
||
<div class="order-rechange-page">
|
||
<!-- 搜索区域:按接口参数保留订单号、用户名称、状态、开始/结束时间 -->
|
||
<OrderRechangeSearch
|
||
:search-form="searchForm"
|
||
:search-options="searchOptions"
|
||
@search="handleSearch"
|
||
@reset="handleReset"
|
||
></OrderRechangeSearch>
|
||
|
||
<!-- 列表区域:改为真实接口数据,保留原有表格结构 -->
|
||
<OrderRechangeTable
|
||
:table-data="tableTree"
|
||
:columns="tableColumnsOptions"
|
||
:highlight-current-row="false"
|
||
>
|
||
<!-- 操作列插槽 -->
|
||
<template #operation="{ row }">
|
||
<el-button type="primary" :disabled="row.status !== '1'" @click="handleAudit(row, 3)"
|
||
>审核通过</el-button
|
||
>
|
||
<el-button type="danger" :disabled="row.status !== '1'" @click="handleAudit(row, 4)"
|
||
>审核驳回</el-button
|
||
>
|
||
</template>
|
||
</OrderRechangeTable>
|
||
|
||
<!-- 分页区域:使用接口返回的 total / current_page / per_page -->
|
||
<OrderRechangePagination
|
||
v-model="currentPage"
|
||
v-model:pageSizeValue="pageSize"
|
||
:total="total"
|
||
@pagination-change="handlePaginationChange"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { onMounted, ref } from 'vue'
|
||
import OrderRechangeSearch from '@/components/common/Search.vue'
|
||
import OrderRechangeTable from '@/components/common/Table.vue'
|
||
import OrderRechangePagination from '@/components/common/Pagination.vue'
|
||
import { getRechargeOrderListApi, reviewRechargeOrder } from '@/api/modules/order/rechange.ts'
|
||
import { search, tableColumns } from './options'
|
||
import { getRecentSevenDays } from '@/utils/handleTime.ts'
|
||
|
||
// 充值订单数据结构:只保留页面展示所需字段,接口原始字段在请求后统一映射。
|
||
interface RechangeOrderItem {
|
||
id: number
|
||
orderNo: string
|
||
userName: string
|
||
currency: string
|
||
amount: string
|
||
status: string
|
||
statusText: string
|
||
rechangeTime: string
|
||
rechangeAccount: string
|
||
}
|
||
|
||
const initTime = getRecentSevenDays('YYYY-MM-DD')
|
||
|
||
// 搜索表单结构:与接口查询参数一一对应,页面字段名保持可读性。
|
||
interface SearchFormData {
|
||
trade_id: string
|
||
user_name: string
|
||
status: string
|
||
start_time: string
|
||
end_time: string
|
||
}
|
||
|
||
// 搜索项配置。
|
||
const searchOptions = ref(search)
|
||
|
||
// 搜索表单:由公共 Search 组件双向绑定。
|
||
const createDefaultSearchForm = (): SearchFormData => ({
|
||
trade_id: '',
|
||
user_name: '',
|
||
status: '',
|
||
start_time: initTime.start,
|
||
end_time: initTime.end,
|
||
})
|
||
|
||
const searchForm = ref<SearchFormData>(createDefaultSearchForm())
|
||
|
||
// 表格数据与列配置。
|
||
const tableTree = ref<RechangeOrderItem[]>([])
|
||
const tableColumnsOptions = ref(tableColumns)
|
||
|
||
// 分页状态:由接口返回值驱动。
|
||
const currentPage = ref(1)
|
||
const pageSize = ref(10)
|
||
const total = ref(0)
|
||
|
||
// 充值状态映射:对齐接口文档中的 1/2/3/4 定义。
|
||
const getRechargeStatusText = (status: string | number | null | undefined) => {
|
||
const statusMap: Record<string, string> = {
|
||
'1': '未审核',
|
||
'2': '未付款',
|
||
'3': '已付款',
|
||
'4': '驳回',
|
||
}
|
||
|
||
return statusMap[String(status ?? '')] || '--'
|
||
}
|
||
|
||
// 获取充值订单列表:把接口返回字段统一映射成页面表格结构。
|
||
const getRechargeOrderList = async () => {
|
||
const params = {
|
||
page: currentPage.value,
|
||
page_size: pageSize.value,
|
||
trade_id: searchForm.value.trade_id || null,
|
||
start_time: searchForm.value.start_time
|
||
? `${searchForm.value.start_time} 00:00:00`
|
||
: initTime.start,
|
||
end_time: searchForm.value.end_time ? `${searchForm.value.end_time} 23:59:59` : initTime.end,
|
||
user_name: searchForm.value.user_name || null,
|
||
status: searchForm.value.status || null,
|
||
}
|
||
|
||
try {
|
||
const data: any = await getRechargeOrderListApi(params)
|
||
const list = Array.isArray(data?.data) ? data.data : []
|
||
|
||
tableTree.value = list.map((item: any, index: number) => ({
|
||
id: Number(item.id ?? index + 1),
|
||
// 订单号:接口返回字段为 trade_id
|
||
orderNo: String(item.trade_id ?? '--'),
|
||
// 用户名:用于后续可能的页面扩展,当前取 user.username
|
||
userName: item.user?.username ?? '--',
|
||
// 充值币种:根据返回结构取 recharge_currency.symbol
|
||
currency: item.recharge_currency?.symbol ?? '--',
|
||
// 金额:根据返回结构取 recharge_amount
|
||
amount: String(item.recharge_amount ?? '--'),
|
||
status: String(item.status ?? ''),
|
||
statusText: getRechargeStatusText(item.status),
|
||
// 充值时间:根据返回结构取 created_at
|
||
rechangeTime: item.created_at ?? '--',
|
||
// 充值账号:当前返回里最接近账号标识的是 user.username
|
||
rechangeAccount: item.user?.username ?? '--',
|
||
}))
|
||
|
||
total.value = Number(data?.total ?? list.length)
|
||
currentPage.value = Number(data?.current_page ?? currentPage.value)
|
||
pageSize.value = Number(data?.per_page ?? pageSize.value)
|
||
} catch (error) {
|
||
tableTree.value = []
|
||
total.value = 0
|
||
console.error('获取充值订单列表失败', error)
|
||
}
|
||
}
|
||
|
||
// 页面加载后拉取首屏数据。
|
||
onMounted(() => {
|
||
getRechargeOrderList()
|
||
})
|
||
|
||
// 搜索:切回第一页后重新请求列表。
|
||
const handleSearch = () => {
|
||
currentPage.value = 1
|
||
getRechargeOrderList()
|
||
}
|
||
|
||
// 重置:恢复默认搜索条件并重新请求列表。
|
||
const handleReset = () => {
|
||
searchForm.value = createDefaultSearchForm()
|
||
currentPage.value = 1
|
||
pageSize.value = 10
|
||
getRechargeOrderList()
|
||
}
|
||
|
||
// 分页切换:同步页码和每页条数后重新请求。
|
||
const handlePaginationChange = (page: { currentPage: number; pageSize: number }) => {
|
||
currentPage.value = page.currentPage
|
||
pageSize.value = page.pageSize
|
||
getRechargeOrderList()
|
||
}
|
||
|
||
// 审核通过:调用接口修改状态为 3 已付款。
|
||
const handleAudit = async (row: RechangeOrderItem, status: number) => {
|
||
try {
|
||
await reviewRechargeOrder({ id: row.id, status: status })
|
||
ElMessage.success('审核通过')
|
||
await getRechargeOrderList()
|
||
} catch (error) {
|
||
ElMessage.error('审核失败')
|
||
console.error('审核失败', error)
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.order-rechange-page {
|
||
min-height: 100%;
|
||
|
||
// 覆盖公共搜索组件的拉伸行为,让输入框尺寸更接近设计图。
|
||
:deep(.search-container .el-form) {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
}
|
||
|
||
:deep(.search-container .el-form-item) {
|
||
flex: 0 0 auto;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
:deep(.search-container .el-input),
|
||
:deep(.search-container .el-select),
|
||
:deep(.search-container .el-date-editor) {
|
||
width: 100%;
|
||
}
|
||
|
||
:deep(.table-container) {
|
||
height: calc(100vh - 220px);
|
||
}
|
||
}
|
||
</style>
|