绿满眶商城微信小程序-uniapp
zxl
2025-08-28 1ea0a9f92a01fa727a47e44b4fd58e5d1a03e0a0
领取记录,跳转
4个文件已修改
5个文件已添加
348 ■■■■■ 已修改文件
api/prize-activity.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/prize-record.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/mine/activity/applyActivityList.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/prizeRecord/prizeRecord.vue 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabbar/user/utils/tool.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/mine/prize-activity.png 补丁 | 查看 | 原始文档 | blame | 历史
static/mine/prize-record.png 补丁 | 查看 | 原始文档 | blame | 历史
store/index.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/prize-activity.js
New file
@@ -0,0 +1,17 @@
import { http, Method } from "@/utils/request.js";
import api from "@/config/api.js";
/**
 * 获得抽奖活动
 *
 * @param params
 */
 export function getONPrizeActivity() {
  return http.request({
    url: "/lmk/activity-prize/getONPrizeActivity",
    method: Method.GET,
    needToken: true,
  });
}
api/prize-record.js
New file
@@ -0,0 +1,15 @@
import {
    http,
    Method
} from "@/utils/request.js";
import api from "@/config/api.js";
export function getPage(param){
    return http.request({
      url: "/lmk/prizeRecord",
      method: Method.GET,
      needToken: true,
      params:param
    });
}
pages.json
@@ -35,6 +35,7 @@
          "navigationBarTitleText" : ""
        }
      }
        // {
        //     "path": "pages/tabbar/home/index",
        //     "style": {
@@ -402,6 +403,33 @@
        //     ]
        // },
        {
            "root" : "pages/prizeRecord",
            "pages": [
                {
                    "path":"prizeRecord",
                    "style" :
                    {
                        "navigationBarTitleText" : "",
                        "componentPlaceholder": {
                            "u-form": "view",
                            "u-form-item": "view",
                            "u-input": "view",
                            "u-icon": "view",
                            "u-action-sheet": "view",
                            "u-checkbox-group": "view",
                            "u-checkbox": "view",
                            "u-navbar": "view",
                            "u-button": "view",
                            "u-image": "view",
                            "u-empty": "view",
                            "u-loadmore":"view"
                        }
                    }
                }
            ]
        },
        {
            "root": "pages/mine",
            "pages": [
                // {
pages/mine/activity/applyActivityList.vue
@@ -65,8 +65,6 @@
        data() {
            return {
                scrollViewTop: uni.upx2px(50 + 80 + 40), // 50rpx空白 + 80rpx按钮 + 40rpx边距
                scrollViewBottom: uni.upx2px(120), // 底部预留
                query: {
                    pageNumber: 1,
                    pageSize: 5,
@@ -223,11 +221,6 @@
        height: auto;
    }
    /* 活动列表样式 */
    .activity-list {
        padding: 20rpx 24rpx;
    }
    .card {
        background: #fff;
pages/prizeRecord/prizeRecord.vue
New file
@@ -0,0 +1,254 @@
<template>
    <view class="container">
        <view style="height:50rpx"></view>
        <u-empty v-if="mockData.length === 0 && !loading" mode="data"
            icon="http://cdn.uviewui.com/uview/empty/data.png">
        </u-empty>
        <!-- 关键修复:确保scroll-view高度正确且事件绑定有效 -->
        <scroll-view
            scroll-y class="scroll-view-container" style="height: 40vh" @scrolltolower="loadMore" :lower-threshold="50"
        >
            <view v-for="(item, idx) in mockData" :key="idx" class="prize-record-item card">
                <view class="prize-record-info">
                    <view class="info-header">
                        <view class="prize-activity-name">{{ item.prizeActivityName }}</view>
                        <view class="prize-status-tag"
                            :class="item.prizeStatus === 'WIN' ? 'tag-winning' : 'tag-not-win'">
                            {{ item.prizeStatus === 'WIN' ? '已中奖' : '未中奖' }}
                        </view>
                    </view>
                    <view class="info-content">
                        <view class="content-label">奖品内容:</view>
                        <view class="prize-content">{{ item.prizeContent || '暂无奖品描述' }}</view>
                    </view>
                    <view class="prize-record-meta">
                        <view class="meta-item">
                            <u-icon name="clock-o" size="16" color="#999"></u-icon>
                            <text class="meta-text">{{ formatTime(item.createTime) }}</text>
                        </view>
                        <view class="meta-item" v-if="item.activitySource">
                            <u-icon name="map" size="16" color="#999"></u-icon>
                            <text class="meta-text">{{ item.activitySource }}</text>
                        </view>
                    </view>
                </view>
            </view>
            <view class="load-more">
                <u-loadmore v-if="mockData.length > 0" :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'"
                    :load-text="{
                        loadmore: '上拉加载更多',
                        loading: '正在加载',
                        nomore: '没有更多了'
                      }" />
            </view>
            <view style="height:150rpx"></view>
        </scroll-view>
    </view>
</template>
<script>
    import { getPage } from '@/api/prize-record.js'
    export default {
        data() {
            return {
                query: {
                    pageNumber: 1,
                    pageSize: 5,
                },
                loading: false,
                total: 0,
                mockData: [],
                noMore: false,
            }
        },
        onLoad() {
            this.getPage();
        },
        methods: {
            onPullDownRefresh() {
                this.mockData = [];
                this.query.pageNumber = 1;
                this.getPage()
                setTimeout(() => {
                    uni.stopPullDownRefresh();
                }, 1000);
            },
            formatTime(timeStr) {
                if (!timeStr || typeof timeStr !== 'string') return '未知时间';
                try {
                    // 手动解析格式,解决兼容性问题
                    const [datePart, timePart] = timeStr.split('T');
                    if (!datePart || !timePart) return '无效时间';
                    const [year, month, day] = datePart.split('-');
                    const hourMinute = timePart.split('.')[0].slice(0, 5);
                    const [hour, minute] = hourMinute.split(':');
                    return `${year}-${month}-${day} ${hour}:${minute}`;
                } catch (error) {
                    console.warn('日期解析失败:', error);
                    return '未知时间';
                }
            },
            async getPage() {
                try {
                    const res = await getPage(this.query);
                    if (res.statusCode === 200) {
                        const newData = res.data.data || [];
                        this.total = res.data.total || 0;
                        this.mockData = this.query.pageNumber === 1 ? newData : [...this.mockData, ...newData];
                        this.noMore = newData.length < this.query.pageSize || this.mockData.length >= this.total;
                    }
                } catch (error) {
                    console.error('加载失败:', error);
                    if (this.query.pageNumber > 1) {
                        this.query.pageNumber -= 1;
                    }
                } finally {
                    this.loading = false;
                    uni.hideLoading();
                    uni.stopPullDownRefresh();
                }
            },
            loadMore() {
                // 增加日志便于调试
                console.log('触发上拉加载', 'loading:', this.loading, 'noMore:', this.noMore);
                if (this.loading || this.noMore) return;
                this.loading = true;
                // 移除不必要的延迟,避免影响体验
                this.query.pageNumber += 1;
                this.getPage();
            },
        }
    }
</script>
<style>
    .container {
        height: 100vh;
        display: flex;
        flex-direction: column;
        background-color: #f7f8fa;
    }
    /* 关键修复:使用flex确保高度正确计算 */
    .scroll-view-container {
        flex: 1;
        overflow-y: auto; /* 明确设置垂直滚动 */
        padding: 0 20rpx;
        box-sizing: border-box;
        -webkit-overflow-scrolling: touch; /* 优化移动端滚动体验 */
    }
    .load-more {
        padding: 20rpx 0;
        text-align: center;
        color: #999;
        font-size: 26rpx;
        background-color: #f8f9fa;
    }
    .card {
        background: #fff;
        border-radius: 20rpx;
        margin: 0 0 24rpx;
        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03),
            0 6rpx 16rpx rgba(0, 0, 0, 0.04);
        transition: all 0.25s ease;
    }
    .prize-record-item {
        padding: 30rpx 28rpx;
    }
    .info-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 22rpx;
    }
    .prize-activity-name {
        font-size: 34rpx;
        font-weight: 600;
        color: #222;
        line-height: 1.4;
        max-width: 70%;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .prize-status-tag {
        padding: 6rpx 18rpx;
        border-radius: 20rpx;
        font-size: 24rpx;
        font-weight: 500;
        text-align: center;
    }
    .tag-winning {
        background-color: #fff1f0;
        color: #ff4d4f;
        border: 1px solid #ffccc7;
    }
    .tag-not-win {
        background-color: #f5f5f5;
        color: #888;
        border: 1px solid #e5e5e5;
    }
    .info-content {
        margin-bottom: 24rpx;
        padding-left: 4rpx;
    }
    .content-label {
        font-size: 24rpx;
        color: #999;
        margin-bottom: 8rpx;
    }
    .prize-content {
        font-size: 28rpx;
        color: #555;
        line-height: 1.6;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
    }
    .prize-record-meta {
        display: flex;
        justify-content: flex-start;
        gap: 24rpx;
        padding-top: 20rpx;
        border-top: 1px solid #f8f8f8;
    }
    .meta-item {
        display: flex;
        align-items: center;
        gap: 8rpx;
    }
    .meta-text {
        font-size: 22rpx;
        color: #888;
        white-space: nowrap;
        letter-spacing: 0.5rpx;
    }
</style>
pages/tabbar/user/utils/tool.vue
@@ -136,6 +136,15 @@
                        <image src="/static/mine/order.png" mode=""></image>
                        <view>商户订单管理</view>
                    </view>
                    <view class="interact-item" v-if="prizeActivityId !== null && prizeActivityId !==''" @click="gotoPrizeActivity()">
                        <image  src="/static/mine/prize-activity.png"></image>
                        <view>抽奖活动</view>
                    </view>
                    <view class="interact-item" @click="navigateTo('/pages/prizeRecord/prizeRecord')">
                        <image  src="/static/mine/prize-record.png"></image>
                        <view>抽奖记录</view>
                    </view>
                </view>
            </view>
@@ -145,6 +154,7 @@
<script>
    import { getUserInfo } from "@/api/members";
    import {getONPrizeActivity} from '@/api/prize-activity.js'
import {
        distribution
    } from "@/api/goods";
@@ -154,6 +164,7 @@
    export default {
        data() {
            return {
                prizeActivityId:'',
                isStoreManger:false,
                configs,
                storage
@@ -169,8 +180,23 @@
                    }
                }
            })
            this.getONPrizeActivity();
        },
        methods: {
            getONPrizeActivity(){
                getONPrizeActivity().then(res =>{
                    if(res.statusCode=== 200){
                        //后端没查到开启的抽奖活动 res.data.data.id值为null
                        this.prizeActivityId = res.data.data.id;
                    }
                })
            },
            gotoPrizeActivity(){
                uni.navigateTo({
                    url:'/pages/prize/PrizeDetail/PrizeDetail?id=' + this.prizeActivityId,
                });
            },
            
            handleNavigate(url) {
                uni.navigateTo({
static/mine/prize-activity.png
static/mine/prize-record.png
store/index.js
@@ -17,6 +17,7 @@
    token: "",
     // 活动弹窗状态
     activityPopup: {
         prizeActivityId:'',
          show: false,
          title: '',
          desc: '',