66 lines
2.3 KiB
Vue
66 lines
2.3 KiB
Vue
<template>
|
|
<view class="orders">
|
|
<view class="hint" v-if="!isLoggedIn">请先登录后查看VIP支付记录</view>
|
|
<view v-else>
|
|
<view class="item" v-for="it in list" :key="it.id">
|
|
<view class="row1">
|
|
<text class="price">¥ {{ toMoney(it.price) }}</text>
|
|
<text class="channel">{{ it.channel || '支付' }}</text>
|
|
</view>
|
|
<view class="row2">
|
|
<text class="date">{{ fmt(it.createdAt) }}</text>
|
|
<text class="duration">{{ it.durationDays }} 天</text>
|
|
</view>
|
|
<view class="row3" v-if="it.expireTo">
|
|
<text class="expire">有效期至 {{ fmt(it.expireTo) }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="empty" v-if="list.length===0">暂无支付记录</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { get } from '../../common/http.js'
|
|
|
|
export default {
|
|
data(){
|
|
return { list: [], page: 1, size: 20, loading: false }
|
|
},
|
|
onShow(){ this.fetch(true) },
|
|
computed: {
|
|
isLoggedIn(){ try { return !!uni.getStorageSync('TOKEN') } catch(e){ return false } }
|
|
},
|
|
methods: {
|
|
async fetch(reset=false){
|
|
if (!this.isLoggedIn) return
|
|
if (this.loading) return
|
|
this.loading = true
|
|
try {
|
|
const p = reset ? 1 : this.page
|
|
const data = await get('/api/vip/recharges', { page: p, size: this.size })
|
|
const arr = Array.isArray(data?.list) ? data.list : []
|
|
this.list = reset ? arr : (this.list || []).concat(arr)
|
|
this.page = p + 1
|
|
} finally { this.loading = false }
|
|
},
|
|
fmt(v){ if (!v) return ''; const s = String(v); const m = s.match(/^(\d{4}-\d{2}-\d{2})([ T](\d{2}:\d{2}))/); return m ? `${m[1]} ${m[3]}` : s },
|
|
toMoney(v){ try { return Number(v).toFixed(2) } catch(_) { return v } }
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.orders { padding: 16rpx 16rpx calc(env(safe-area-inset-bottom) + 16rpx); }
|
|
.hint { color: $uni-text-color-grey; padding: 24rpx; text-align: center; }
|
|
.item { background:#fff; border:1rpx solid $uni-border-color; border-radius: 16rpx; padding: 18rpx; margin: 12rpx 0; }
|
|
.row1 { display:flex; justify-content: space-between; align-items:center; margin-bottom: 6rpx; }
|
|
.price { color:#111; font-weight: 800; font-size: 34rpx; }
|
|
.channel { color:#666; font-size: 24rpx; }
|
|
.row2 { display:flex; justify-content: space-between; color:#666; font-size: 24rpx; }
|
|
.row3 { margin-top: 6rpx; color:#4C8DFF; font-size: 24rpx; }
|
|
.empty { text-align:center; color:#999; padding: 40rpx 0; }
|
|
</style>
|
|
|
|
|