完成个人中心红包模块功能

This commit is contained in:
赵毅 2025-12-17 10:03:40 +08:00
parent f70843f3dd
commit 62cc81168f
6 changed files with 297 additions and 131 deletions

View File

@ -17,4 +17,8 @@ export const apiArr = {
couponList: '/api/v1/wechat/discuss/list', // 获取优惠券列表
getUserCommunity:"/api/v1/wechat/community/owner/mylist",//获取用户社区信息
createQrcode: '/api/v1/wechat/water/device/qr-code', //获取小程序码
redPackageCenter: '/api/v2/wechat/red-package/center', //红包中心分页
redPackageClaim: '/api/v2/wechat/red-package/claim', //领取红包
redPackageMyred: '/api/v2/wechat/red-package/my-red', //我的红包分页
};

View File

@ -10,14 +10,17 @@
<!-- 红包列表 -->
<view class="content">
<view v-for="(item, index) in redPacketList" :key="index">
<view class="item">
<view class="item_left">{{ item.yuan }}</view>
<view class="item" v-if="item.red_package_config">
<view class="item_left">{{ item.red_package_config.money }}</view>
<view class="item_center">
<view class="title">{{ item.name }}</view>
<view class="time">{{ item.time }}</view>
<view class="desc">{{ item.shiyong }}</view>
<view class="title">{{ item.red_package_config.red_package_name }}</view>
<view class="time">{{ item.red_package_config.start_time }} -
{{ item.red_package_config.end_time }}</view>
<view class="desc">{{ item.red_package_config.belong_role === 1 ? '限指定店铺使用' :
(item.red_package_config.belong_role === 2 ? '限指定地区使用' :
'全平台使用') }}</view>
</view>
<view class="status2" :data-status="item.status"></view>
<view class="status2" :data-status="currentTab == 1 ? '已过期' : '已使用'"></view>
</view>
</view>
</view>
@ -25,49 +28,37 @@
</template>
<script>
import { menuButtonInfo, NavgateTo, picUrl, request } from '../../../utils/index';
import { apiArr } from '../../../api/user';
export default {
data() {
return {
currentTab: 0, //
changeIndex: 1,
tabList: ['已使用', '已过期'],
redPacketList: [
{
name: '新用户注册红包',
time: '2085.07.77 00:27到期',
shiyong: '全平台使用',
status: '去使用',
yuan: 5.32
},
{
name: '满减红包',
time: '2085.07.77 00:27到期',
shiyong: '全平台使用',
status: '去使用',
yuan: 5,
manjian: '满0元可用'
},
{
name: '固定红包',
time: '2085.07.77 00:27到期',
shiyong: '限改店铺指定商品使用',
status: '去使用',
yuan: 5
},
{
name: '固定红包',
time: '2085.07.77 00:27到期',
shiyong: '限广州地区使用',
status: '去使用',
yuan: 5
}
]
redPacketList: []
}
},
methods: {
async getRedPacketHistory(changeIndex) {
console.log("🚀 ~ changeIndex:", changeIndex)
const params = {
user_id: uni.getStorageSync('userId'),
history: changeIndex,
}
const res = await request(apiArr.redPackageMyred, 'POST', params);
this.redPacketList = res.rows;
},
switchTab(index) {
this.currentTab = index;
this.changeIndex = index === 0 ? 1 : 3;
this.getRedPacketHistory(this.changeIndex);
console.log('选中的标签:', this.tabList[index]);
}
},
onLoad() {
this.getRedPacketHistory(1);
}
}
</script>

View File

@ -1,5 +1,6 @@
page {
background-color: #f6f7fb;
overflow-y: hidden;
}
.container {
@ -60,11 +61,25 @@ page {
/* 红包列表 */
.content {
padding: 0 20rpx;
height: 75vh;
overflow-y: auto;
}
.ad_name{
margin: 15rpx 0 30rpx 0;
display: flex;
align-items: center;
}
.ad_name image {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.item {
padding: 20rpx;
height: 130rpx;
padding: 0 20rpx;
height: 170rpx;
margin-bottom: 30rpx;
border-radius: 20rpx;
display: flex;

View File

@ -4,41 +4,108 @@
<view class="stats">
<view class="stat-item">
<view class="stat-label">红包数</view>
<view class="stat-value">1000,000</view>
<view class="stat-value">{{ redPacketNum }}</view>
</view>
<view class="stat-item">
<view class="stat-label">红包金额</view>
<view class="stat-value">1000,000</view>
<view class="stat-value">{{ redPacketMoney }}</view>
</view>
</view>
<!-- 分类标签 -->
<view class="tabs">
<view
v-for="(tab, index) in tabList"
:key="index"
:class="['tab', { active: currentTab === index }]"
@click="switchTab(index)"
>
<view v-for="(tab, index) in tabList" :key="index" :class="['tab', { active: currentTab === index }]"
@click="switchTab(index)">
{{ tab }}
</view>
</view>
<!-- 红包列表 -->
<view class="content">
<view v-for="(item, index) in redPacketList" :key="index">
<view class="item">
<view class="item_left">
<view class="price">{{ item.yuan }}</view>
<view v-if="item.manjian" class="manjian">{{ item.manjian }}</view>
<!-- 地区分组显示 -->
<view v-if="currentTab === 2">
<view v-for="(group, groupIndex) in redPacketList" :key="groupIndex">
<view class="ad_name">
<image src="https://static.hshuishang.com/Index_add.png" mode="widthFix" />
{{ group.ad_name }}地区使用
</view>
<view class="item_center">
<view class="title">{{ item.name }}</view>
<view class="time">{{ item.time }}</view>
<view class="desc">{{ item.shiyong }}</view>
<view v-for="(item, itemIndex) in group.packets" :key="itemIndex">
<view v-if="item.red_package_config">
<view class="item">
<view class="item_left">
<view class="price">{{ item.red_package_config.money }}</view>
<view v-if="item.red_package_config.manjian" class="manjian">
{{ item.red_package_config.manjian }}
</view>
</view>
<view class="item_center">
<view class="title">{{ item.red_package_config.red_package_name }}</view>
<view class="time">{{ item.red_package_config.end_time }}到期</view>
<view class="desc">{{ item.red_package_config.belong_role === 1 ? '限指定店铺使用' :
(item.red_package_config.belong_role === 2 ? '限指定地区使用' :
'全平台使用') }}</view>
</view>
<view class="item_right" v-if="item.status === 2">
<view class="status" @click="useRedPacket(item)">去使用</view>
</view>
</view>
</view>
</view>
<view class="item_right">
<view class="status" @click="useRedPacket(item)">{{ item.status }}</view>
</view>
</view>
<!-- 店铺分组显示 -->
<view v-else-if="currentTab === 3">
<view v-for="(group, groupIndex) in redPacketList" :key="groupIndex">
<view class="ad_name">
<image src="https://static.hshuishang.com/Index_add.png" mode="widthFix" />
{{ group.merchant_name }}
</view>
<view v-for="(item, itemIndex) in group.packets" :key="itemIndex">
<view v-if="item.red_package_config">
<view class="item">
<view class="item_left">
<view class="price">{{ item.red_package_config.money }}</view>
<view v-if="item.red_package_config.manjian" class="manjian">
{{ item.red_package_config.manjian }}
</view>
</view>
<view class="item_center">
<view class="title">{{ item.red_package_config.red_package_name }}</view>
<view class="time">{{ item.red_package_config.end_time }}到期</view>
<view class="desc">{{ item.red_package_config.belong_role === 1 ? '限指定店铺使用' :
(item.red_package_config.belong_role === 2 ? '限指定地区使用' :
'全平台使用') }}</view>
</view>
<view class="item_right" v-if="item.status === 2">
<view class="status" @click="useRedPacket(item)">去使用</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 普通显示 -->
<view v-else>
<view v-for="(item, index) in redPacketList" :key="index">
<view v-if="item.red_package_config">
<view class="item">
<view class="item_left">
<view class="price">{{ item.red_package_config.money }}</view>
<view v-if="item.red_package_config.manjian" class="manjian">
{{ item.red_package_config.manjian }}
</view>
</view>
<view class="item_center">
<view class="title">{{ item.red_package_config.red_package_name }}</view>
<view class="time">{{ item.red_package_config.end_time }}到期</view>
<view class="desc">{{ item.red_package_config.belong_role === 1 ? '限指定店铺使用' :
(item.red_package_config.belong_role === 2 ? '限指定地区使用' :
'全平台使用') }}</view>
</view>
<view class="item_right" v-if="item.status === 2">
<view class="status" @click="useRedPacket(item)">去使用</view>
</view>
</view>
</view>
</view>
</view>
@ -48,55 +115,108 @@
<script>
import { menuButtonInfo, NavgateTo, picUrl, request } from '../../../utils/index';
import { apiArr } from '../../../api/user';
export default {
data() {
return {
currentTab: 0, //
tabList: ['全部', '平台', '地区', '店铺', '历史记录'], //
redPacketList: [
{
name: '新用户注册红包',
time: '2085.07.77 00:27到期',
shiyong: '全平台使用',
status: '去使用',
yuan: 5.32
},
{
name: '满减红包',
time: '2085.07.77 00:27到期',
shiyong: '全平台使用',
status: '去使用',
yuan: 5,
manjian: '满0元可用'
},
{
name: '固定红包',
time: '2085.07.77 00:27到期',
shiyong: '限改店铺指定商品使用',
status: '去使用',
yuan: 5
},
{
name: '固定红包',
time: '2085.07.77 00:27到期',
shiyong: '限广州地区使用',
status: '去使用',
yuan: 5
}
]
redPacketList: [],
changeIndex: 0,
redPacketNum: 0,
redPacketMoney: 0.00,
}
},
methods: {
async getMyRedPacket(changeIndex) {
const params = {
user_id: uni.getStorageSync('userId'),
belong_role: changeIndex == 0 ? '' : changeIndex,
}
const res = await request(apiArr.redPackageMyred, 'POST', params);
let processedList = res.rows.map(item => {
const newItem = { ...item };
if (newItem?.agent_info?.ad?.ad_name) {
newItem.agent_info.ad.ad_name = newItem.agent_info.ad.ad_name.split(',').join('');
}
return newItem;
});
if (this.currentTab == 2) {
// ad_name
const grouped = {};
processedList.forEach(item => {
if (item?.agent_info?.ad?.ad_name) {
const adName = item.agent_info.ad.ad_name;
if (!grouped[adName]) {
grouped[adName] = {
ad_name: adName,
packets: []
};
}
grouped[adName].packets.push(item);
}
});
this.redPacketList = Object.values(grouped);
} else if (this.currentTab == 3) {
// merchant_name
const grouped = {};
processedList.forEach(item => {
if (item?.merchant_info?.merchant_name) {
const merchantName = item.merchant_info.merchant_name;
if (!grouped[merchantName]) {
grouped[merchantName] = {
merchant_name: merchantName,
packets: []
};
}
grouped[merchantName].packets.push(item);
}
});
this.redPacketList = Object.values(grouped);
} else {
this.redPacketList = processedList;
}
this.redPacketNum = res.rows.filter(item => item.red_package_config).length;
this.redPacketMoney = res.rows.reduce((total, item) =>
item.red_package_config ? total + item.red_package_config.money : total, 0.00
).toFixed(2);
},
useRedPacket(item) {
console.log('使用红包:', item);
if (item.belong_role == 1) {
uni.setStorageSync('merchantInfo', item.merchant_info);
NavgateTo('/packages/localLife/detail/index')
} else if (item.belong_role == 2) {
NavgateTo('/pages/index/index');
} else if (item.belong_role == 3) {
NavgateTo('/packages/shop/index/index');
}
},
switchTab(index) {
this.currentTab = index;
console.log('选中的标签:', this.tabList[index]);
if(this.tabList[index] == '历史记录'){
if (index == 0) {
this.changeIndex = 0;
} else if (index == 1) {
this.changeIndex = 3;
} else if (index == 2) {
this.changeIndex = 2;
} else if (index == 3) {
this.changeIndex = 1;
}
this.getMyRedPacket(this.changeIndex);
if (this.tabList[index] == '历史记录') {
NavgateTo('/packages/user/history/index');
}
}
},
onShow() {
this.switchTab(0);
this.getMyRedPacket(0);
}
}
</script>

View File

@ -3,8 +3,8 @@
}
.item {
padding: 20rpx;
height: 130rpx;
padding: 0 20rpx;
height: 170rpx;
margin-bottom: 30rpx;
border-radius: 20rpx;
display: flex;
@ -17,7 +17,7 @@
.item_left {
font-size: 40rpx;
font-weight: bold;
width: 170rpx;
width: 150rpx;
height: 170rpx;
line-height: 170rpx;
padding-left: 30rpx;
@ -52,6 +52,8 @@
.item_right {
margin-right: 20rpx;
position: relative; /* 添加相对定位 */
z-index: 10; /* 添加更高的z-index值 */
}
.status {
@ -63,6 +65,8 @@
color: #ff7557;
font-size: 24rpx;
font-weight: bold;
position: relative; /* 添加相对定位 */
z-index: 10; /* 添加更高的z-index值 */
}
.status2 {
@ -73,6 +77,7 @@
height: 120rpx;
overflow: hidden;
transform: rotate(0deg);
z-index: 1; /* 添加较低的z-index值 */
}
.status2::after {
@ -179,4 +184,13 @@
font-size: 32rpx;
font-weight: bold;
padding: 0;
}
.content {
height: calc(100vh - 100rpx);
}
.loading {
text-align: center;
padding: 20rpx;
color: #999;
}

View File

@ -1,25 +1,27 @@
<template>
<view class="container">
<view class="content">
<scroll-view class="content" scroll-y @scrolltolower="loadMore">
<view v-for="(item, index) in redPacketList" :key="index">
<view class="item">
<view class="item_left">{{ item.yuan }}</view>
<view class="item_left">{{ item.money }}</view>
<view class="item_center">
<view class="title">{{ item.name }}</view>
<view class="time">{{ item.time }}</view>
<view class="desc">{{ item.shiyong }}</view>
<view class="title">{{ item.red_package_name }}</view>
<view class="time">{{ item.end_time }}到期</view>
<view class="desc">{{ item.scope }}</view>
</view>
<view class="item_right">
<view class="status" @click="showPopup(item)">{{ item.status }}</view>
<view class="status" @click="showPopup(item)">{{ item.is_received ? '已领取' : '领取' }}</view>
</view>
<view class="status2" :data-status="item.status"></view>
<view class="status2" :data-status="item.is_received ? '' : '待领取'" v-if="!item.is_received"></view>
</view>
</view>
</view>
<!-- 加载状态 -->
<view v-if="loading" class="loading">加载中...</view>
</scroll-view>
<view class="bottom">
<view @click="goRedPacket()">我的权益</view>
</view>
<!-- 弹窗 -->
<view v-if="popupVisible" class="popup-overlay" @click="hidePopup">
<view class="popup-content" @click.stop>
@ -27,7 +29,7 @@
<view class="checkmark"></view>
</view>
<view class="popup-title">领取成功!</view>
<view class="popup-desc">已存入您的账户</view>
<view class="popup-desc">{{ currentItem.red_package_name }}{{ currentItem.money }}已存入您的账户</view>
<button class="popup-btn" @click="hidePopup">确定</button>
</view>
</view>
@ -35,40 +37,50 @@
</template>
<script>
import { menuButtonInfo, NavgateTo, picUrl, request } from '../../../utils/index';
import { apiArr } from '../../../api/user';
export default {
data() {
return {
redPacketList: [
{
name: '100元红包',
time: '2023-01-01 10:00:00',
shiyong: '用于购买商品',
status: '待领取',
yuan: 100
},
{
name: '50元红包',
time: '2023-01-02 12:00:00',
shiyong: '用于购买商品',
status: '待领取',
yuan: 50
},
{
name: '20元红包',
time: '2023-01-03 14:00:00',
shiyong: '用于购买商品',
status: '已使用',
yuan: 20
}
],
redPacketList: [],
popupVisible: false,
currentItem: null
currentItem: null,
page_num: 1,
page_size: 10,
loading: false,
noMore: false
}
},
methods: {
async getRedPacketCenter() {
const params = {
pageNum: this.page_num,
pageSize: this.page_size,
}
const res = await request(apiArr.redPackageCenter, 'POST', params);
//
if (this.page_num === 1) {
this.redPacketList = res.rows;
} else {
this.redPacketList = [...this.redPacketList, ...res.rows];
}
//
this.noMore = res.rows.length < this.page_size;
this.loading = false;
},
showPopup(item) {
this.currentItem = item;
this.popupVisible = true;
if (item.is_received) {
return
}
const params = {
user_id: uni.getStorageSync('userId'),
red_package_config_id: item.id,
}
request(apiArr.redPackageClaim, 'POST', params).then(res => {
this.currentItem = item;
this.popupVisible = true;
this.getRedPacketCenter()
})
},
hidePopup() {
this.popupVisible = false;
@ -76,7 +88,17 @@ export default {
},
goRedPacket() {
NavgateTo('/packages/user/myRedPacket/index');
},
//
loadMore() {
if (this.loading || this.noMore) return;
this.loading = true;
this.page_num++;
this.getRedPacketCenter();
}
},
onLoad() {
this.getRedPacketCenter();
}
}
</script>