|
|
- <template>
- <view class="container">
- <!-- 顶部导航栏 -->
- <view class="nav-bar" :style="{ height: (statusBarHeight + 88) + 'rpx', paddingTop: statusBarHeight + 'px' }">
- <view class="back" @tap="goBack">
- <uni-icons type="left" size="25" color="#fff"></uni-icons>
- </view>
- <text class="title">钱包流水</text>
- </view>
- <!-- banner -->
- <view class="banner"
- :style="{ marginTop: (statusBarHeight + 88) + 'rpx', height: (bannerBaseHeight + statusBarHeight + 88) + 'rpx' }">
- <image class="banner-bg" :src="image" mode="aspectFill"></image>
- <!-- <view class="banner-content">
- <image class="wallet-icon" src="/static/wallet/wallet-3d.png" mode="aspectFit"></image>
- </view> -->
- </view>
-
- <!-- 账户余额 -->
- <view class="balance-card">
- <view class="balance-info">
- <text class="label">账户</text>
- <view class="amount">
- <text class="symbol">¥</text>
- <text class="value">{{ userInfo.money || '0.00' }}</text>
- </view>
- </view>
- <button class="withdraw-btn" @tap="withdraw">提现</button>
- </view>
-
- <!-- 记录切换标签 -->
- <view class="record-tabs">
- <view class="tab-item" :class="{ active: currentTab === 'settlement' }" @tap="switchTab('settlement')">
- 结算日志
- </view>
- <view class="tab-item" :class="{ active: currentTab === 'withdrawal' }" @tap="switchTab('withdrawal')">
- 提现记录
- </view>
- </view>
-
- <!-- 记录列表 -->
- <view class="record-item" v-for="(item, index) in recordList" :key="index">
- <view class="record-info">
- <view class="record-left">
- <text class="type">{{ item.title || (currentTab === 'settlement' ? '结算记录' : '提现记录') }}</text>
- <!-- 结算记录显示状态 -->
- <view class="status" v-if="currentTab === 'settlement' && item.state === 0">
- <text class="status-text">24小时后结算</text>
- </view>
- <!-- 提现记录显示时间 -->
- <text v-if="currentTab === 'withdrawal'" class="date">{{ formatDate(item.createTime) }}</text>
- </view>
- <view class="record-right">
- <text class="amount">¥{{ item.money || '0.00' }}</text>
- <!-- 结算记录显示时间 -->
- <text v-if="currentTab === 'settlement'" class="date">{{ formatDate(item.createTime) }}</text>
- <!-- 提现记录显示操作按钮 -->
- <template v-if="currentTab === 'withdrawal'">
- <button v-if="item.state === 0" class="withdraw-btn" @tap="receiveWithdrawal(item, index)">
- 提现
- </button>
- <text v-else class="received-text">已到账</text>
- </template>
- </view>
- </view>
- </view>
-
- <!-- 初始加载状态 -->
- <view v-if="loading && !isInitialized" class="loading-more">
- <text>数据加载中...</text>
- </view>
-
- <!-- 空状态 -->
- <view v-if="recordList.length === 0 && !loading && isInitialized" class="empty-state">
- <text>{{ currentTab === 'settlement' ? '暂无结算记录' : '暂无提现记录' }}</text>
- </view>
-
- <!-- 调试信息(临时启用查看状态) -->
- <!-- <view class="debug-info" style="padding: 20rpx; background: #f0f0f0; margin: 20rpx; font-size: 24rpx; border-radius: 10rpx;">
- <text>recordList.length: {{ recordList.length }}</text><br/>
- <text>loading: {{ loading }}</text><br/>
- <text>isInitialized: {{ isInitialized }}</text><br/>
- <text>currentTab: {{ currentTab }}</text><br/>
- <text>loadingMore: {{ loadingMore }}</text><br/>
- <text>noMore: {{ noMore }}</text>
- </view> -->
-
- <!-- 加载更多状态 -->
- <view v-if="loadingMore" class="loading-more">
- <text>加载更多中...</text>
- </view>
-
- <!-- 没有更多 -->
- <view v-if="noMore && recordList.length > 0" class="no-more">
- <text>没有更多了</text>
- </view>
- </view>
- </template>
-
- <script>
- import pullRefreshMixin from '@/pages/mixins/pullRefreshMixin.js'
- import api from '@/api/api.js'
-
- export default {
- mixins: [pullRefreshMixin],
- data() {
- return {
- statusBarHeight: 0,
- bannerBaseHeight: 300,
- currentTab: 'settlement',
- userInfo: {
- money: '0.00'
- },
- recordList: [],
- pageNum: 1,
- pageSize: 20,
- loading: false,
- loadingMore: false,
- noMore: false,
- refreshing: false,
- isInitialized: false
- }
- },
- computed: {
- image() {
- // console.log(getApp().globalData.bannerList,'getApp().globalData.bannerList')
- const item = getApp().globalData.bannerList.find(i => i.title === '我的-轮播图')
- return item ? item.image : ''
- },
- },
- onLoad() {
- this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight
- this.initData()
- },
- onPullDownRefresh() {
- this.onRefresh()
- },
- onReachBottom(){
- this.loadMore()
- },
- methods: {
- async initData() {
- await this.getUserInfo()
- await this.loadRecords()
- },
-
- async getUserInfo() {
- try {
- const res = await api('getUserByToken')
- if (res.code === 200 && res.data) {
- this.userInfo = res.data
- }
- } catch (error) {
- console.error('获取用户信息失败:', error)
- }
- },
-
- async loadRecords(isRefresh = false) {
- if (this.loading) return
- this.loading = true
-
- // 如果是刷新,重置分页状态
- if (isRefresh) {
- this.pageNum = 1
- this.noMore = false
- this.recordList = []
- }
-
- try {
- // 获取记录
- const res = await api('getMyMoneyLogPage', {
- status: this.currentTab === 'settlement' ? 0 : 1,
- pageNum: this.pageNum,
- pageSize: this.pageSize
- })
-
- if (res.code === 200 && res.data) {
- const records = res.data.records || []
-
- if (isRefresh) {
- this.recordList = records
- } else {
- this.recordList = [...this.recordList, ...records]
- }
-
- if (records.length < this.pageSize) {
- this.noMore = true
- }
- } else {
- this.recordList = []
- }
- } catch (error) {
- console.error('获取流水记录失败:', error)
- uni.showToast({
- title: '获取数据失败',
- icon: 'none'
- })
- } finally {
- this.loading = false
- this.isInitialized = true
- }
- },
-
- formatDate(timestamp) {
- if (!timestamp) return ''
- const date = new Date(timestamp)
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- return `${month}-${day}`
- },
-
- async onRefresh() {
- this.refreshing = true
- try {
- await this.getUserInfo()
- await this.loadRecords(true)
- } finally {
- this.refreshing = false
- uni.stopPullRefresh()
- }
- },
-
- goBack() {
- uni.navigateBack()
- },
-
- async switchTab(tab) {
- this.currentTab = tab
- // 切换标签时重新加载数据
- this.pageNum = 1
- this.noMore = false
- this.recordList = []
- this.isInitialized = false
- await this.loadRecords()
- },
-
- withdraw() {
- uni.navigateTo({
- url: '/pages/subcomponent/withdraw'
- })
- },
-
- async receiveWithdrawal(item, index) {
- try {
- // 验证提现金额
- if (!item.money || parseFloat(item.money) <= 0) {
- uni.showToast({
- title: '提现金额无效',
- icon: 'none'
- })
- return
- }
-
- // 获取用户名
- const userName = this.userInfo.name || this.userInfo.nickName || this.userInfo.userName
- if (!userName) {
- uni.showToast({
- title: '请先完善个人信息',
- icon: 'none'
- })
- return
- }
-
- // 显示确认弹窗
- const [error, res] = await uni.showModal({
- title: '确认提现',
- content: `确认提现金额 ¥${item.money} 到您的账户?`,
- confirmText: '确认提现',
- cancelText: '取消'
- })
-
- if (error || !res.confirm) {
- return
- }
-
- // 显示加载状态
- uni.showLoading({
- title: '正在提现...'
- })
-
- // 调用提现接口
- const result = await api('withdraw', {
- userName: userName,
- money: parseFloat(item.money)
- })
-
- if (result.code === 200) {
- // 更新本地状态
- this.recordList[index].state = 1
-
- uni.hideLoading()
- uni.showToast({
- title: '提现成功',
- icon: 'success'
- })
-
- // 重新获取用户信息更新余额
- await this.getUserInfo()
- } else {
- throw new Error(result.message || result.msg || '提现失败')
- }
-
- } catch (error) {
- uni.hideLoading()
- console.error('提现失败:', error)
- uni.showToast({
- title: error.message || '提现失败,请重试',
- icon: 'none'
- })
- }
- },
-
- async loadMore() {
- if (this.noMore || this.loadingMore) return
- this.loadingMore = true
- this.pageNum++
- try {
- const res = await api('getMyMoneyLogPage', {
- status: this.currentTab === 'settlement' ? 0 : 1,
- pageNum: this.pageNum,
- pageSize: this.pageSize
- })
-
- if (res.code === 200 && res.data) {
- const records = res.data.records || []
-
- this.recordList = [...this.recordList, ...records]
- if (records.length < this.pageSize) {
- this.noMore = true
- }
- }
- } catch (error) {
- console.error('加载更多记录失败:', error)
- this.pageNum-- // 失败时回退页码
- uni.showToast({
- title: '加载更多数据失败',
- icon: 'none'
- })
- } finally {
- this.loadingMore = false
- }
- }
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .container {
- min-height: 100vh;
- background: #fff;
- }
-
- .nav-bar {
- display: flex;
- align-items: center;
- background: linear-gradient(to right, #f68240 0%, #fc8940 10%);
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- z-index: 999;
- }
-
- .back {
- padding: 20rpx;
- margin-left: -20rpx;
- }
-
- .title {
- flex: 1;
- text-align: center;
- font-size: 34rpx;
- font-weight: 500;
- color: #fff;
- }
-
- .banner {
- position: relative;
- background: linear-gradient(to right, #f78b49, #fc8940);
- overflow: hidden;
- border-radius: 0 0 30rpx 30rpx;
- margin-top: 0;
- }
-
- .banner-bg {
- position: absolute;
- width: 100%;
- height: 100%;
- // opacity: 0.8;
- }
-
- .banner-content {
- position: relative;
- z-index: 1;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
-
- .wallet-icon {
- width: 240rpx;
- height: 240rpx;
- }
- }
-
- .balance-card {
- margin: -60rpx 30rpx 0;
- padding: 30rpx;
- background: #fff;
- border-radius: 20rpx;
- box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
- display: flex;
- justify-content: space-between;
- align-items: center;
- position: relative;
- z-index: 2;
-
- .balance-info {
- .label {
- font-size: 28rpx;
- color: #666;
- }
-
- .amount {
- margin-top: 8rpx;
- display: flex;
- align-items: baseline;
-
- .symbol {
- font-size: 32rpx;
- color: #333;
- }
-
- .value {
- font-size: 48rpx;
- font-weight: bold;
- color: #333;
- margin-left: 4rpx;
- }
- }
- }
-
- .withdraw-btn {
- width: 160rpx;
- height: 70rpx;
- background: #FFB74D;
- color: #fff;
- font-size: 28rpx;
- border-radius: 35rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- border: none;
-
- &::after {
- border: none;
- }
- }
- }
-
- .record-tabs {
- display: flex;
- padding: 20rpx 0;
- border-bottom: 1rpx solid #f5f5f5;
-
- .tab-item {
- position: relative;
- padding: 16rpx 0;
- font-size: 28rpx;
- color: #666;
- flex: 1;
- text-align: center;
-
- &.active {
- color: #333;
- font-weight: 500;
-
- &::after {
- content: '';
- position: absolute;
- left: 50%;
- transform: translateX(-50%);
- bottom: -21rpx;
- width: 48rpx;
- height: 2rpx;
- background: #FFB74D;
- }
- }
- }
- }
-
-
- .record-item {
- padding: 30rpx;
- border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
-
- .record-info {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
-
- .record-left {
- flex: 1;
-
- .type {
- font-size: 28rpx;
- color: #333;
- margin-bottom: 8rpx;
- }
-
- .status {
- display: inline-block;
- padding: 4rpx 8rpx;
- background: #FFB74D;
- border-radius: 8rpx;
- margin-top: 8rpx;
-
- .status-text {
- font-size: 22rpx;
- color: #fff;
- }
- }
-
- .date {
- font-size: 24rpx;
- color: #999;
- margin-top: 8rpx;
- }
- }
-
- .record-right {
- display: flex;
- flex-direction: column;
- align-items: flex-end;
-
- .amount {
- font-size: 28rpx;
- color: #333;
- font-weight: 500;
- margin-bottom: 8rpx;
- }
-
- .date {
- font-size: 24rpx;
- color: #999;
- }
-
- .withdraw-btn {
- width: 100rpx;
- height: 50rpx;
- background: #FFB74D;
- color: #fff;
- font-size: 24rpx;
- border-radius: 25rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- border: none;
- margin-top: 8rpx;
-
- &::after {
- border: none;
- }
- }
-
- .received-text {
- font-size: 22rpx;
- color: #52C41A;
- margin-top: 8rpx;
- }
- }
- }
- }
-
- .empty-state {
- width: 100%;
- text-align: center;
- padding: 100rpx 0;
- color: #999;
- font-size: 28rpx;
- }
-
- .loading-more {
- text-align: center;
- padding: 20rpx 0;
- color: #999;
- font-size: 28rpx;
- }
-
- .no-more {
- text-align: center;
- padding: 20rpx 0;
- color: #999;
- font-size: 28rpx;
- }
- </style>
|