|
|
@@ -1,4 +1,5 @@
|
|
|
<script lang="ts" setup>
|
|
|
+import { onReachBottom } from '@dcloudio/uni-app'
|
|
|
import { usePagination, useRequest } from 'alova/client'
|
|
|
import { storeToRefs } from 'pinia'
|
|
|
import { computed, ref, watch } from 'vue'
|
|
|
@@ -6,6 +7,7 @@ import { getAccountCount } from '@/api/home'
|
|
|
import { getCouponIssuerAccountByPageMap } from '@/api/income'
|
|
|
import IncomeItem from '@/components/IncomeItem.vue'
|
|
|
import MescrollUni from '@/components/mescroll.vue'
|
|
|
+import MescrollBody from '@/custom-components/custom-mescroll/mescroll-body.vue'
|
|
|
import { useShare } from '@/hooks/useShare'
|
|
|
import { useUserStore } from '@/store'
|
|
|
import { useTokenStore } from '@/store/token'
|
|
|
@@ -16,6 +18,7 @@ definePage({
|
|
|
style: {
|
|
|
navigationBarTitleText: '收益',
|
|
|
navigationStyle: 'custom',
|
|
|
+ onReachBottomDistance: 157,
|
|
|
},
|
|
|
})
|
|
|
|
|
|
@@ -37,6 +40,7 @@ const showLoading = ref(false)
|
|
|
const pickerDate = ref(Date.now())
|
|
|
const pickerShow = ref(false)
|
|
|
const totalAmount = ref(0)
|
|
|
+const mescrollHeight = ref(0)
|
|
|
let mescroll = null
|
|
|
|
|
|
// 新增:滚动距离和透明度
|
|
|
@@ -81,12 +85,21 @@ watch(() => incomeData.value, (newVal) => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+watch(() => headerOverlayOpacity.value, (newVal) => {
|
|
|
+ if (newVal > 0) {
|
|
|
+ mescroll.lockDownScroll(true)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ mescroll.lockDownScroll(false)
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
// ============ mescroll 配置 ============
|
|
|
const downOption = reactive({
|
|
|
use: true,
|
|
|
auto: false,
|
|
|
- bgColor: '#ffffff',
|
|
|
- textColor: '#666',
|
|
|
+ bgColor: '#ed6b66',
|
|
|
+ textColor: '#fff',
|
|
|
textInOffset: '下拉刷新',
|
|
|
textOutOffset: '释放刷新',
|
|
|
textLoading: '刷新中...',
|
|
|
@@ -108,8 +121,6 @@ const upOption = reactive({
|
|
|
btnText: '刷新试试',
|
|
|
icon: '/static/images/mescroll-empty.png',
|
|
|
fixed: false,
|
|
|
- top: '200rpx',
|
|
|
- zIndex: 1,
|
|
|
},
|
|
|
textNoMore: '--- 已经到底了 ---',
|
|
|
toTop: {
|
|
|
@@ -117,6 +128,7 @@ const upOption = reactive({
|
|
|
offset: 1000,
|
|
|
bottom: 120,
|
|
|
},
|
|
|
+ isBoth: false,
|
|
|
// 开启虚拟列表优化(大数据量时)
|
|
|
virtual: {
|
|
|
use: false,
|
|
|
@@ -156,6 +168,17 @@ async function upCallback() {
|
|
|
page.value++
|
|
|
}
|
|
|
|
|
|
+onReachBottom(() => {
|
|
|
+ console.log('上拉加载触发')
|
|
|
+ if (isLastPage.value) {
|
|
|
+ // console.log(mescroll)
|
|
|
+ // mescroll.endSuccess(0, false)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ mescroll.showUpScroll()
|
|
|
+ page.value++
|
|
|
+})
|
|
|
+
|
|
|
onSuccess((response) => {
|
|
|
let isNextPage = isLastPage.value
|
|
|
// 此处处理alova isLastPage默认值为true,首次请求出现的无法加载下一页问题
|
|
|
@@ -202,6 +225,14 @@ onShow(async () => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+onLoad(() => {
|
|
|
+ // 计算mescroll最小高度
|
|
|
+ const systemInfo = uni.getSystemInfoSync()
|
|
|
+ const vh100 = systemInfo.screenHeight - systemInfo.safeAreaInsets.bottom
|
|
|
+ const tabbarHeight = (systemInfo.screenWidth / 750) * 100
|
|
|
+ mescrollHeight.value = vh100 - tabbarHeight
|
|
|
+})
|
|
|
+
|
|
|
// 创建分享hook实例
|
|
|
const { getShareConfig, getTimelineShareConfig } = useShare()
|
|
|
|
|
|
@@ -227,69 +258,71 @@ function goPage(page: string) {
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <view class="profile-container" :style="{ minHeight: `calc(100vh - 100rpx)` }">
|
|
|
- <!-- <up-pull-refresh :refreshing="refreshing" :threshold="60" @refresh="onRefresh"> -->
|
|
|
- <!-- 顶部区域 -->
|
|
|
- <view class="income-header"
|
|
|
- :style="{ background: `url(${getImageUrl('@img/income/income-bg.png')})`, backgroundSize: '100% 110%', backgroundPosition: 'left bottom', backgroundRepeat: 'no-repeat' }">
|
|
|
- <view class="income-header-avatar-info"
|
|
|
- :style="{ paddingTop: `calc(${safeAreaInsets.top}px + ${menuButtonInfo.height}px)` }">
|
|
|
- <view class="income-header-balance">
|
|
|
- 当前账户余额(元)
|
|
|
- </view>
|
|
|
- <view class="income-header-balance-num">
|
|
|
- <view class="income-header-balance-num-amount">
|
|
|
- {{ accountCountData?.balance || 0 }}
|
|
|
+ <view class="profile-container">
|
|
|
+ <view class="income-header-overlay"
|
|
|
+ :style="{ opacity: headerOverlayOpacity, height: `calc(${menuButtonInfo.bottom + 4}px + 50rpx)` }" />
|
|
|
+ <mescroll-body id="mescrollContainer" :height="`${mescrollHeight}px`" :sticky="true" :down="downOption"
|
|
|
+ :up="upOption" :fixed="false" :is-show-empty="true" @init="mescrollInit" @down="downCallback"
|
|
|
+ @up="upCallback" @emptyclick="reload">
|
|
|
+ <!-- 顶部区域 -->
|
|
|
+ <view class="income-header"
|
|
|
+ :style="{ background: `url(${getImageUrl('@img/income/income-bg.png')})`, backgroundSize: '100% 110%', backgroundPosition: 'left bottom', backgroundRepeat: 'no-repeat' }">
|
|
|
+ <view class="income-header-avatar-info"
|
|
|
+ :style="{ paddingTop: `calc(${safeAreaInsets.top}px + ${menuButtonInfo.height}px)` }">
|
|
|
+ <view class="income-header-balance">
|
|
|
+ 当前账户余额(元)
|
|
|
</view>
|
|
|
- <view class="income-header-balance-num-btns">
|
|
|
- <view v-if="isUnlock" class="income-header-balance-num-btn js" @click="goPage('unlockRewards')">
|
|
|
- 解锁
|
|
|
+ <view class="income-header-balance-num">
|
|
|
+ <view class="income-header-balance-num-amount">
|
|
|
+ {{ accountCountData?.balance || 0 }}
|
|
|
+ </view>
|
|
|
+ <view class="income-header-balance-num-btns">
|
|
|
+ <view v-if="isUnlock" class="income-header-balance-num-btn js"
|
|
|
+ @click="goPage('unlockRewards')">
|
|
|
+ 解锁
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <view class="income-header-tips">
|
|
|
- <view class="income-header-tips-item">
|
|
|
- <view class="income-header-tips-item-num">
|
|
|
- {{ accountCountData?.withdrawableAmount || 0 }}
|
|
|
- </view>
|
|
|
- <view class="income-header-tips-item-des">
|
|
|
- 可提现金额
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view class="income-header-tips-item">
|
|
|
- <view class="income-header-tips-item-num">
|
|
|
- {{ accountCountData?.unsettledAmount || 0 }}
|
|
|
- </view>
|
|
|
- <view class="income-header-tips-item-des">
|
|
|
- 未结算金额
|
|
|
+ <view class="income-header-tips">
|
|
|
+ <view class="income-header-tips-item">
|
|
|
+ <view class="income-header-tips-item-num">
|
|
|
+ {{ accountCountData?.withdrawableAmount || 0 }}
|
|
|
+ </view>
|
|
|
+ <view class="income-header-tips-item-des">
|
|
|
+ 可提现金额
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <view class="income-header-tips-item">
|
|
|
- <view class="income-header-tips-item-num">
|
|
|
- {{ accountCountData?.totalCommission || 0 }}
|
|
|
+ <view class="income-header-tips-item">
|
|
|
+ <view class="income-header-tips-item-num">
|
|
|
+ {{ accountCountData?.unsettledAmount || 0 }}
|
|
|
+ </view>
|
|
|
+ <view class="income-header-tips-item-des">
|
|
|
+ 未结算金额
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- <view class="income-header-tips-item-des">
|
|
|
- 累计收益
|
|
|
+ <view class="income-header-tips-item">
|
|
|
+ <view class="income-header-tips-item-num">
|
|
|
+ {{ accountCountData?.totalCommission || 0 }}
|
|
|
+ </view>
|
|
|
+ <view class="income-header-tips-item-des">
|
|
|
+ 累计收益
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <!-- 公告 -->
|
|
|
- <view v-if="isUnlock" class="income-header-notice">
|
|
|
- <view class="income-header-notice-icon">
|
|
|
- <image :src="getImageUrl('@img/income/notice.png')" mode="aspectFit" />
|
|
|
- </view>
|
|
|
- <view class="income-header-notice-content">
|
|
|
- 在考核周期内未达标已锁定收益,<text>前往查看~</text>
|
|
|
+ <!-- 公告 -->
|
|
|
+ <view v-if="isUnlock" class="income-header-notice">
|
|
|
+ <view class="income-header-notice-icon">
|
|
|
+ <image :src="getImageUrl('@img/income/notice.png')" mode="aspectFit" />
|
|
|
+ </view>
|
|
|
+ <view class="income-header-notice-content">
|
|
|
+ 在考核周期内未达标已锁定收益,<text>前往查看~</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <!-- 菜单 -->
|
|
|
- <view class="income-header-menu" :style="{ marginTop: isUnlock ? '24rpx' : '-50rpx' }">
|
|
|
- <view class="income-header-overlay"
|
|
|
- :style="{ opacity: headerOverlayOpacity, height: `calc(${menuButtonInfo.bottom + 4}px + 50rpx)` }" />
|
|
|
<!-- 结算筛选 -->
|
|
|
- <view class="income-header-menu-filter" :style="{ top: `${menuButtonInfo.bottom + 4}px` }">
|
|
|
+ <view class="income-header-menu-filter"
|
|
|
+ :style="{ marginTop: isUnlock ? '24rpx' : '-50rpx', top: `${menuButtonInfo.bottom + 4}px` }">
|
|
|
<view class="income-header-menu-filter-item" :class="[activeIndex === 0 ? 'active' : '']"
|
|
|
@click="tabChange(0)">
|
|
|
待结算
|
|
|
@@ -312,21 +345,15 @@ function goPage(page: string) {
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="income-menu-list">
|
|
|
- <mescroll-uni id="mescrollContainer" :down="downOption" :up="upOption" :fixed="false"
|
|
|
- :is-show-empty="true" @init="mescrollInit" @down="downCallback" @up="upCallback"
|
|
|
- @emptyclick="reload">
|
|
|
- <view v-for="item in incomeData" :key="item.userId" class="income-content-item">
|
|
|
- <income-item :data="item" :type="activeIndex" />
|
|
|
- </view>
|
|
|
- <!-- 滚动区域内的loading遮罩 -->
|
|
|
- <view v-if="showLoading && loading" class="loading-mask">
|
|
|
- <view class="loading-spinner" />
|
|
|
- <text class="loading-text">加载中...</text>
|
|
|
- </view>
|
|
|
- </mescroll-uni>
|
|
|
+ <view v-for="item in incomeData" :key="item.userId" class="income-content-item">
|
|
|
+ <income-item :data="item" :type="activeIndex" />
|
|
|
+ </view>
|
|
|
+ <!-- 滚动区域内的loading遮罩 -->
|
|
|
+ <view v-if="showLoading && loading" class="loading-mask">
|
|
|
+ <up-loading-icon color="#ed6b66" text="加载中" />
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <!-- </up-pull-refresh> -->
|
|
|
+ </mescroll-body>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
@@ -463,145 +490,150 @@ function goPage(page: string) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .income-header-menu {
|
|
|
- // background: #ffffff;
|
|
|
+ // 新增:吸顶区域上方的覆盖元素
|
|
|
+ .income-header-overlay {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ background-color: #ed6b66;
|
|
|
border-radius: 10rpx 10rpx 0rpx 0rpx;
|
|
|
- margin-left: 24rpx;
|
|
|
- margin-right: 23rpx;
|
|
|
- margin-bottom: 20rpx;
|
|
|
- flex: 1;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- min-height: 0;
|
|
|
+ z-index: 99;
|
|
|
+ pointer-events: none; // 确保不影响点击事件
|
|
|
+ }
|
|
|
|
|
|
- // 新增:吸顶区域上方的覆盖元素
|
|
|
- .income-header-overlay {
|
|
|
- position: fixed;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- background-color: #ed6b66;
|
|
|
- border-radius: 10rpx 10rpx 0rpx 0rpx;
|
|
|
- z-index: 99;
|
|
|
- pointer-events: none; // 确保不影响点击事件
|
|
|
- }
|
|
|
+ .income-header-menu-filter {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #333333;
|
|
|
+ height: 90rpx;
|
|
|
+ background: #ffffff;
|
|
|
+ box-shadow: 0rpx 3rpx 7rpx 0rpx rgba(213, 213, 213, 0.29);
|
|
|
+ border-radius: 10rpx 10rpx 0rpx 0rpx;
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ z-index: 100;
|
|
|
|
|
|
- .income-header-menu-filter {
|
|
|
+ .income-header-menu-filter-item {
|
|
|
+ flex: 1;
|
|
|
display: flex;
|
|
|
- justify-content: space-between;
|
|
|
+ justify-content: center;
|
|
|
align-items: center;
|
|
|
- font-weight: 500;
|
|
|
- font-size: 32rpx;
|
|
|
- color: #333333;
|
|
|
- height: 90rpx;
|
|
|
- background: #ffffff;
|
|
|
- box-shadow: 0rpx 3rpx 7rpx 0rpx rgba(213, 213, 213, 0.29);
|
|
|
- border-radius: 10rpx 10rpx 0rpx 0rpx;
|
|
|
- position: sticky;
|
|
|
- top: 0;
|
|
|
- z-index: 100;
|
|
|
+ position: relative;
|
|
|
+ height: 100%;
|
|
|
|
|
|
- .income-header-menu-filter-item {
|
|
|
- flex: 1;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- position: relative;
|
|
|
- height: 100%;
|
|
|
+ &.active {
|
|
|
+ color: #ed6b66;
|
|
|
|
|
|
- &.active {
|
|
|
- color: #ed6b66;
|
|
|
-
|
|
|
- &:after {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%);
|
|
|
- width: 67rpx;
|
|
|
- height: 6rpx;
|
|
|
- background: #ed6b66;
|
|
|
- border-radius: 3rpx;
|
|
|
- }
|
|
|
+ &:after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: 67rpx;
|
|
|
+ height: 6rpx;
|
|
|
+ background: #ed6b66;
|
|
|
+ border-radius: 3rpx;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ .income-menu-time-filter {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #333333;
|
|
|
+ padding: 30rpx 20rpx 14rpx;
|
|
|
+ background: #ffffff;
|
|
|
+ margin-top: 4rpx;
|
|
|
+ position: sticky;
|
|
|
+ z-index: 100;
|
|
|
|
|
|
- .income-menu-time-filter {
|
|
|
+ .income-menu-time-filter-text {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #000000;
|
|
|
display: flex;
|
|
|
- justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- font-weight: 400;
|
|
|
- font-size: 24rpx;
|
|
|
- color: #333333;
|
|
|
- padding: 30rpx 20rpx 14rpx;
|
|
|
- background: #ffffff;
|
|
|
- margin-top: 4rpx;
|
|
|
- position: sticky;
|
|
|
- z-index: 100;
|
|
|
-
|
|
|
- .income-menu-time-filter-text {
|
|
|
- font-weight: 400;
|
|
|
- font-size: 26rpx;
|
|
|
- color: #000000;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 12rpx;
|
|
|
- }
|
|
|
+ gap: 12rpx;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- .income-menu-list {
|
|
|
- background: #ffffff;
|
|
|
- // flex: 1;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- position: relative;
|
|
|
+ .income-menu-list {
|
|
|
+ background: #ffffff;
|
|
|
+ // flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ position: relative;
|
|
|
|
|
|
- #mescrollContainer {
|
|
|
- height: 100%;
|
|
|
- flex: 1;
|
|
|
- }
|
|
|
+ #mescrollContainer {
|
|
|
+ height: 100%;
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
|
|
|
- .income-content-item {
|
|
|
- margin-top: 20rpx;
|
|
|
- }
|
|
|
+ .income-content-item {
|
|
|
+ margin-top: 20rpx;
|
|
|
+ }
|
|
|
|
|
|
- // loading遮罩样式
|
|
|
- .loading-mask {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- background-color: rgba(255, 255, 255, 0.8);
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- z-index: 999;
|
|
|
- }
|
|
|
+ // loading遮罩样式
|
|
|
+ .loading-mask {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ background-color: rgba(255, 255, 255, 0.8);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: end;
|
|
|
+ z-index: 999;
|
|
|
+ }
|
|
|
|
|
|
- .loading-spinner {
|
|
|
- width: 40rpx;
|
|
|
- height: 40rpx;
|
|
|
- border: 4rpx solid #e0e0e0;
|
|
|
- border-top-color: #ed6b66;
|
|
|
- border-radius: 50%;
|
|
|
- animation: spin 1s linear infinite;
|
|
|
- }
|
|
|
+ .loading-spinner {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ border: 4rpx solid #e0e0e0;
|
|
|
+ border-top-color: #ed6b66;
|
|
|
+ border-radius: 50%;
|
|
|
+ animation: spin 1s linear infinite;
|
|
|
+ }
|
|
|
|
|
|
- .loading-text {
|
|
|
- margin-top: 16rpx;
|
|
|
- font-size: 24rpx;
|
|
|
- color: #666;
|
|
|
- }
|
|
|
+ .loading-text {
|
|
|
+ margin-left: 16rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
|
|
|
- @keyframes spin {
|
|
|
- to {
|
|
|
- transform: rotate(360deg);
|
|
|
- }
|
|
|
+ @keyframes spin {
|
|
|
+ to {
|
|
|
+ transform: rotate(360deg);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .income-header-menu-filter,
|
|
|
+ .income-menu-time-filter,
|
|
|
+ .income-menu-list {
|
|
|
+ margin-left: 24rpx;
|
|
|
+ margin-right: 23rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.mescroll-empty) {
|
|
|
+ width: auto;
|
|
|
+ margin-left: 23rpx;
|
|
|
+ margin-left: 24rpx;
|
|
|
+ background-color: #fff;
|
|
|
+ border-bottom-left-radius: 10rpx;
|
|
|
+ border-bottom-right-radius: 10rpx;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|