会员权益

This commit is contained in:
2026-04-29 15:33:58 +08:00
commit 54965243da
2787 changed files with 242809 additions and 0 deletions

View File

@@ -0,0 +1,195 @@
<!-- +----------------------------------------------------------------------
| 麦沃德科技赋能开发者助力商协会发展
+----------------------------------------------------------------------
| Copyright (c) 20172024 www.wdsxh.cn All rights reserved.
+----------------------------------------------------------------------
| 沃德商协会系统并不是自由软件不加密并不代表开源未经许可不可自由转售和商用
+----------------------------------------------------------------------
| Author: MY WORLD Team <bd@maiwd.cn> www.maiwd.cn
+----------------------------------------------------------------------
| 积分明细 开发者: 麦沃德科技-半夏
+---------------------------------------------------------------------- -->
<template>
<view class="container" v-if="loadEnd">
<!-- 标题栏 -->
<title-bar :showBack="true" title="积分明细"></title-bar>
<!-- 内容区 -->
<view class="container-main" :style="{'--theme-color': themeColor}">
<view class="main-screen" :style="{top: titleBarHeight + 'px'}">
<view class="screen-item" :class="{active: selectScreen == index}" @click="changeScreen(index)" v-for="(item, index) in screenList" :key="index">{{item.text}}</view>
</view>
<view class="main-list" v-if="dataList.length">
<view class="list-item" v-for="item in dataList" :key="item.id">
<view class="item-top flex align-items-center">
<view class="top-name flex-item text-ellipsis-more">{{item.memo}}</view>
<view class="top-amount" :style="{color: item.change == 2 ? '#5A5B6E' : themeColor}">
{{item.change == 2 ? "-" : "+"}}{{item.points}}
</view>
</view>
<view class="item-bottom">{{item.createtime}}</view>
</view>
</view>
<empty top="30%" title="暂无相关内容~" v-else></empty>
</view>
</view>
</template>
<script>
import { mapState } from "vuex"
export default {
data() {
return {
// 加载完成
loadEnd: false,
// 标题栏高度
titleBarHeight: 0,
// 分类列表
screenList: [{
text: "全部",
},
{
text: "收入",
type: 1
},
{
text: "支出",
type: 2
},
],
// 已选分类
selectScreen: 0,
// 分类查询参数
page: 1,
limit: 20,
hasMore: false,
// 明细列表
dataList: {},
}
},
computed: {
...mapState({
themeColor: state => state.app.themeColor,
})
},
mounted() {
// #ifdef MP-WEIXIN
let statusBarHeight = uni.getSystemInfoSync().statusBarHeight
let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.titleBarHeight = statusBarHeight + (menuButtonInfo.top - statusBarHeight) * 2 + menuButtonInfo.height
// #endif
},
onLoad() {
uni.showLoading({
title: "加载中"
})
this.getDataList(() => {
uni.hideLoading()
this.loadEnd = true
})
},
onPullDownRefresh() {
this.page = 1
this.getDataList(() => {
uni.stopPullDownRefresh()
})
},
onReachBottom() {
if (this.hasMore) {
this.page++
this.getDataList()
}
},
methods: {
// 更改分类
changeScreen(index) {
this.selectScreen = index
this.page = 1
this.getDataList()
},
// 获取积分明细列表
getDataList(fn) {
this.$util.request("points.record", {
page: this.page,
limit: this.limit,
...this.selectScreen ? { change: this.selectScreen } : {}
}).then(res => {
if (fn) fn()
if (res.code == 1) {
let list = res.data.data
this.hasMore = this.page < res.data.total / this.limit ? true : false
this.dataList = this.page == 1 ? list : [...this.dataList, ...list];
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
console.error('获取积分明细列表 ', error)
})
},
}
}
</script>
<style lang="scss">
.container {
.container-main {
.main-screen {
position: sticky;
top: 0;
z-index: 99;
background: #FFF;
display: flex;
.screen-item {
flex: 1;
padding: 44rpx 32rpx;
color: #8D929C;
font-size: 28rpx;
line-height: 40rpx;
text-align: center;
text-align: center;
&.active {
color: var(--theme-color);
}
}
}
.main-list {
padding: 32rpx;
.list-item {
border-radius: 16rpx;
background: #FFF;
padding: 32rpx;
.item-top {
.top-name {
color: #5A5B6E;
font-size: 28rpx;
font-weight: 600;
line-height: 40rpx;
}
.top-amount {
margin-left: 48rpx;
font-size: 28rpx;
font-weight: 600;
line-height: 40rpx;
}
}
.item-bottom {
margin-top: 8rpx;
color: #979797;
font-size: 24rpx;
line-height: 34rpx;
}
}
}
}
}
</style>

375
pagesPoints/index/index.vue Normal file
View File

@@ -0,0 +1,375 @@
<!-- +----------------------------------------------------------------------
| 麦沃德科技赋能开发者助力商协会发展
+----------------------------------------------------------------------
| Copyright (c) 20172024 www.wdsxh.cn All rights reserved.
+----------------------------------------------------------------------
| 沃德商协会系统并不是自由软件不加密并不代表开源未经许可不可自由转售和商用
+----------------------------------------------------------------------
| Author: MY WORLD Team <bd@maiwd.cn> www.maiwd.cn
+----------------------------------------------------------------------
| 积分商城 开发者: 麦沃德科技-半夏
+---------------------------------------------------------------------- -->
<template>
<view class="container" v-if="loadEnd">
<!-- 顶部区域 -->
<view class="container-header">
<view class="header-nav" :style="{height: titleBarHeight + 'px'}">
<title-bar positionMode="fixed" :frontColor="titleColor" :backgroundColor="titleBackground" title="积分商城"></title-bar>
</view>
<view class="header-info">
<view class="info-title">我的积分</view>
<view class="info-value">{{pointsInfo.my_points}}</view>
<view class="info-text">
<text>{{pointsInfo.points_description}}</text>
</view>
</view>
<image class="header-icon" src="/static/points.png" mode="widthFix"></image>
</view>
<!-- 内容区 -->
<view class="container-main">
<view class="main-menu">
<view class="menu-item" @click="toOrderList()">
<image class="item-icon" src="/static/mall/order.png" mode="aspectFit"></image>
<view class="item-box">
<view class="box-title">兑换订单</view>
<view class="box-subtitle">查看兑换订单列表</view>
</view>
</view>
<view class="menu-item" @click="toPointsDetails()">
<image class="item-icon" src="/static/mall/details.png" mode="aspectFit"></image>
<view class="item-box">
<view class="box-title">积分明细</view>
<view class="box-subtitle">查看积分收支明细</view>
</view>
</view>
</view>
<view class="main-column">
<view class="column-title">积分商品</view>
<view class="column-list">
<mall-goods ref="mallGoods" v-if="goodsList.length"></mall-goods>
<empty top="32rpx" title="分类下暂无相关商品~" v-else></empty>
</view>
</view>
</view>
<!-- 底部导航 -->
<tab-bar></tab-bar>
</view>
</template>
<script>
import { mapState } from "vuex"
import mallGoods from '@/pagesPoints/component/mall/goods.vue'
// #ifdef H5
import wx from 'weixin-js-sdk';
// #endif
export default {
components: {
mallGoods
},
data() {
return {
// 是否加载完成
loadEnd: false,
// 顶部导航栏背景色
titleBackground: "rgba(255, 255, 255, 0)",
// 顶部导航栏字体颜色
titleColor: "#000",
// 标题栏高度
titleBarHeight: 0,
// 积分信息
pointsInfo: {},
// 分类查询参数
page: 1,
limit: 20,
hasMore: false,
// 商品列表
goodsList: [],
};
},
computed: {
...mapState({
shareImage: state => state.app.shareImage,
shareTitle: state => state.app.shareTitle,
})
},
mounted() {
// #ifdef MP-WEIXIN
let statusBarHeight = uni.getSystemInfoSync().statusBarHeight
let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.titleBarHeight = (menuButtonInfo.top - statusBarHeight) * 2 + menuButtonInfo.height + statusBarHeight
// #endif
},
onLoad() {
uni.showLoading({
title: "加载中"
})
this.getPointsInfo()
this.getGoodsList(() => {
this.loadEnd = true
uni.hideLoading()
})
// #ifdef H5
this.initConfig()
// #endif
},
onPullDownRefresh() {
this.getPointsInfo()
this.page = 1
if (this.goodsList.length) this.$refs.mallGoods.clearList()
this.getGoodsList(() => {
uni.stopPullDownRefresh();
});
},
onReachBottom() {
if (this.hasMore) {
this.page++
this.getGoodsList();
}
},
onShareAppMessage() {
return {
title: this.shareTitle,
imageUrl: this.shareImage,
}
},
onShareTimeline() {
return {
title: this.shareTitle,
imageUrl: this.shareImage,
}
},
onPageScroll(e) {
const scrollTop = e.scrollTop
if (scrollTop > 100) {
this.titleBackground = "#fff"
this.titleColor = "black"
} else {
let opacity = parseFloat(scrollTop / 100).toFixed(4)
this.titleBackground = "rgba(255, 255, 255, " + opacity + ")"
if (scrollTop > 30) {
this.titleColor = "black"
uni.setNavigationBarColor({
frontColor: "#000000",
backgroundColor: "#ffffff"
})
} else {
this.titleColor = '#000000'
uni.setNavigationBarColor({
frontColor: this.titleColor,
backgroundColor: "transparent"
})
}
}
},
methods: {
// #ifdef H5
// 微信公众号初始化方法
initConfig() {
this.$util.request("main.WeChatConfig", {
url: location.href.split('#')[0]
}).then(res => {
if (res.code == 1) {
wx.config({
debug: false,
appId: res.data.appId,
timestamp: Number(res.data.timestamp),
nonceStr: res.data.nonceStr,
signature: res.data.signature,
jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"],
openTagList: ["updateAppMessageShareData", "updateTimelineShareData"],
})
wx.ready(() => {
wx.updateAppMessageShareData({
title: this.shareTitle,
desc: "",
link: window.location.href,
imgUrl: this.shareImage,
});
wx.updateTimelineShareData({
title: this.shareTitle,
link: window.location.href,
imgUrl: this.shareImage,
});
});
} else {
uni.hideLoading()
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('通过config接口注入权限验证配置 ', error)
})
},
// #endif
// 获取积分信息
getPointsInfo() {
this.$util.request("points.info").then(res => {
if (res.code == 1) {
this.pointsInfo = res.data;
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
console.error('获取积分信息', error)
})
},
// 获取分类筛选的商品
getGoodsList(fn) {
this.$util.request("points.goodsList", {
page: this.page,
limit: this.limit,
}).then(res => {
if (fn) fn()
if (res.code == 1) {
let list = res.data.data
this.hasMore = this.page < res.data.total / this.limit ? true : false
this.goodsList = this.page == 1 ? list : [...this.goodsList, ...list];
this.$nextTick(() => {
if (this.goodsList.length) this.$refs.mallGoods.getList(this.goodsList)
})
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
if (fn) fn()
console.error('获取商品列表', error)
})
},
// 瀑布流加载完成
waterfallLoadEnd() {
this.waterfallData.reset = false;
if (this.hasMore) this.waterfallData.status = 'await';
else this.waterfallData.status = "finish"
},
// 跳转订单列表
toOrderList() {
this.$util.toPage({
mode: 1,
path: "/pagesPoints/order/index"
})
},
// 跳转积分明细
toPointsDetails() {
this.$util.toPage({
mode: 1,
path: "/pagesPoints/index/details"
})
},
}
}
</script>
<style lang="scss">
.container {
.container-header {
position: relative;
z-index: 998;
background: linear-gradient(355deg, #FFEB74 4.39%, #FF5A00 121.55%);
.header-info {
position: relative;
z-index: 1;
padding: 64rpx 48rpx 48rpx;
.info-title {
color: #FFF;
font-size: 32rpx;
font-weight: 600;
line-height: 48rpx;
}
.info-value {
margin-top: 16rpx;
color: #FFF;
text-shadow: 0 4px 4px rgba(255, 77, 0, 0.25);
font-size: 72rpx;
font-weight: 700;
line-height: 88rpx;
}
.info-text {
margin-top: 16rpx;
color: #7C2C00;
font-size: 24rpx;
line-height: 40rpx;
}
}
.header-icon {
position: absolute;
right: 0;
bottom: 0;
width: 336rpx;
height: auto;
}
}
.container-main {
padding: 32rpx;
.main-menu {
display: flex;
justify-content: space-between;
.menu-item {
width: 48%;
padding: 18rpx 32rpx;
border-radius: 16rpx;
background: #FFF;
display: flex;
align-items: center;
.item-icon {
width: 64rpx;
height: 64rpx;
}
.item-box {
flex: 1;
margin-left: 16rpx;
.box-title {
color: #5A5B6E;
font-size: 28rpx;
font-weight: 600;
line-height: 40rpx;
}
.box-subtitle {
margin-top: 8rpx;
color: #979797;
font-size: 20rpx;
font-weight: 400;
line-height: 28rpx;
}
}
}
}
.main-column {
margin-top: 32rpx;
.column-title {
color: #333;
font-size: 32rpx;
font-weight: 600;
line-height: 48rpx;
}
.column-list {
margin-top: 32rpx;
}
}
}
}
</style>