582 lines
14 KiB
Vue
582 lines
14 KiB
Vue
<template>
|
||
<view class="sign-page">
|
||
<view class="header">
|
||
<view class="label">我的积分</view>
|
||
<view class="value">{{infoDetail.points||0}}</view>
|
||
</view>
|
||
<view class="sign" v-if="list.length > 0">
|
||
<view class="title">累计签到 {{total.length}} 天</view>
|
||
<scroll-view scroll-x="true" class="sign-scroll">
|
||
<view class="item" v-for="(item,index) in list" :key="index" >
|
||
<view class="item-main":class="{'item-active':item.sign}">
|
||
<image src="@/static/an/point.gif" mode="" class="point-icon"></image>
|
||
<image src="@/static/new/sign/g.png" mode="" class="g-icon" v-if="item.sign"></image>
|
||
<view class="point" v-else>+{{item.rewardVoList[0].num}}</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
<!-- <view class="sign-list">
|
||
|
||
</view> -->
|
||
<view class="step">
|
||
<view class="dian-frist" :class="{'dian-frist-active':list[0].sign}"></view>
|
||
<template v-for="(item,index) in list">
|
||
<view :key="index" class="step-item" v-if="index != 0" :class="{'step-active':item.sign}">
|
||
<view class="dian" :class="{'dian-active':item.sign}"></view>
|
||
</view>
|
||
</template>
|
||
</view>
|
||
<view class="sign-btn" @click="sign" :class="{'dis-btn':isSign}">{{isSign ? '已签到' : '签到领积分'}}</view>
|
||
</view>
|
||
<template v-for="(item,key) in taskList">
|
||
<view class="main" :key="key" v-if="key === 'DAY'">
|
||
<view class="headers">
|
||
<view class="label">{{typeObj[key]}}</view>
|
||
<view class="value">
|
||
</view>
|
||
</view>
|
||
<view class="item" v-for="(childItem,childIndex) in item" :key="childIndex">
|
||
<view class="label">
|
||
<view class="title">{{childItem.name}}</view>
|
||
<view class="sub">{{childItem.summary}}</view>
|
||
</view>
|
||
<view class="get-value" v-if="childItem.status === 1" @click="taskReceiveCk(childItem)">{{statusObj[childItem.status]}}</view>
|
||
<view class="value"v-else @click="goPath(childItem)">
|
||
{{statusObj[childItem.status]}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<template v-for="(item,key) in taskList">
|
||
<view class="main" :key="key" v-if="key === 'WEEK'">
|
||
<view class="headers">
|
||
<view class="label">{{typeObj[key]}}</view>
|
||
<view class="value">
|
||
</view>
|
||
</view>
|
||
<view class="item" v-for="(childItem,childIndex) in item" :key="childIndex">
|
||
<view class="label">
|
||
<view class="title">{{childItem.name}}</view>
|
||
<view class="sub">{{childItem.summary}}</view>
|
||
</view>
|
||
<view class="get-value" v-if="childItem.status === 1" @click="taskReceiveCk(childItem)">{{statusObj[childItem.status]}}</view>
|
||
<view class="value"v-else @click="goPath(childItem)">
|
||
{{statusObj[childItem.status]}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<template v-for="(item,key) in taskList">
|
||
<view class="main" :key="key" v-if="key === 'MONTH'">
|
||
<view class="headers">
|
||
<view class="label">{{typeObj[key]}}</view>
|
||
<view class="value">
|
||
</view>
|
||
</view>
|
||
<view class="item" v-for="(childItem,childIndex) in item" :key="childIndex">
|
||
<view class="label">
|
||
<view class="title">{{childItem.name}}</view>
|
||
<view class="sub">{{childItem.summary}}</view>
|
||
</view>
|
||
<view class="get-value" v-if="childItem.status === 1" @click="taskReceiveCk(childItem)">{{statusObj[childItem.status]}}</view>
|
||
<view class="value"v-else @click="goPath(childItem)">
|
||
{{statusObj[childItem.status]}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<template v-for="(item,key) in taskList">
|
||
<view class="main" :key="key" v-if="key === 'CUSTOM'">
|
||
<view class="headers">
|
||
<view class="label">{{typeObj[key]}}</view>
|
||
<view class="value">
|
||
</view>
|
||
</view>
|
||
<view class="item" v-for="(childItem,childIndex) in item" :key="childIndex">
|
||
<view class="label">
|
||
<view class="title">{{childItem.name}}</view>
|
||
<view class="sub">{{childItem.summary}}</view>
|
||
</view>
|
||
<view class="get-value" v-if="childItem.status === 1" @click="taskReceiveCk(childItem)">{{statusObj[childItem.status]}}</view>
|
||
<view class="value"v-else @click="goPath(childItem)">
|
||
{{statusObj[childItem.status]}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<!-- 是否有未开完的奖品 -->
|
||
<NoOpenCom></NoOpenCom>
|
||
<!-- 所有页面的弹框 -->
|
||
<page-popup page="/pages/mine/sign" v-if="visible"></page-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { myMixins } from "@/mixins/mixins.js";
|
||
import { signInInfo,signIn,taskListApi,taskReceive } from '@/API/sign.js'
|
||
|
||
import { userInfo } from '@/API/user.js'
|
||
import NoOpenCom from '@/pages/index/components/noOpen.vue'
|
||
import reportClickFn from '@/utils/report.js'
|
||
export default{
|
||
mixins: [myMixins],
|
||
data(){
|
||
return{
|
||
list:[],
|
||
taskList:[],
|
||
infoDetail:{
|
||
phone:"",
|
||
avatarResource:{}
|
||
},
|
||
statusObj:{
|
||
0:'未完成',
|
||
1:'领取奖励',
|
||
'-1':'已领取',
|
||
},
|
||
total:[],
|
||
time:'',
|
||
signObj:{},
|
||
isSign:false,
|
||
typeObj:{
|
||
CUSTOM:"自定义任务",
|
||
DAY:"每日任务",
|
||
WEEK:"每周任务",
|
||
MONTH:'每月任务',
|
||
},
|
||
rewardTypeObj:{
|
||
FORMULA:'组合奖励',
|
||
POINTS:"积分",
|
||
COUPON:'优惠券',
|
||
PROMPT:'提示卡',
|
||
COIN:'代币'
|
||
},
|
||
visible:false
|
||
}
|
||
},
|
||
components:{NoOpenCom},
|
||
onShow() {
|
||
uni.$on('updateTabData', (data) => {
|
||
this.visible = false
|
||
setTimeout(() => {
|
||
this.visible = true
|
||
},500)
|
||
});
|
||
if(uni.getStorageSync('box-token')){
|
||
this.getUserInfo()
|
||
this.getSignInInfo()
|
||
this.getTaskList()
|
||
this.getTime()
|
||
}else{
|
||
uni.redirectTo({
|
||
url:`/pages/login/login`
|
||
})
|
||
}
|
||
},
|
||
mounted() {
|
||
this.visible = true
|
||
// this.getSignInInfo()
|
||
// console.log()
|
||
},
|
||
methods:{
|
||
getTime(){
|
||
let now = new Date();
|
||
let year = now.getFullYear();
|
||
let month = now.getMonth() + 1; // 月份从0开始,所以要加1
|
||
let day = now.getDate();
|
||
let hour = now.getHours();
|
||
let minute = now.getMinutes();
|
||
let second = now.getSeconds();
|
||
month = month < 10 ? `0${month}` : month
|
||
day = day < 10 ? `0${day}` : day
|
||
this.time = `${year}-${month}-${day}`
|
||
},
|
||
taskReceiveCk(item){
|
||
console.log(item)
|
||
uni.showLoading()
|
||
taskReceive(item.id).then(res => {
|
||
|
||
if(res.code === 200){
|
||
|
||
// this.$api.msg(res.message)
|
||
// 创建一个对象来存储每个类型的总数
|
||
const typeSums = {};
|
||
|
||
// 遍历数组,将相同类型的 num 相加
|
||
res.data.forEach(obj => {
|
||
if (typeSums[obj.type]) {
|
||
typeSums[obj.type] += obj.num;
|
||
} else {
|
||
typeSums[obj.type] = obj.num;
|
||
}
|
||
});
|
||
|
||
// 构造输出字符串
|
||
let resultStr = '';
|
||
|
||
// 将相同类型的 num 乘以其总数,构造输出字符串
|
||
for (const type in typeSums) {
|
||
resultStr += `${this.rewardTypeObj[type]}*${typeSums[type]}、`;
|
||
}
|
||
|
||
// 去除末尾多余的 '、'
|
||
resultStr = resultStr.slice(0, -1);
|
||
|
||
this.$api.msg(`${resultStr}领取成功`)
|
||
setTimeout(() => {
|
||
uni.hideLoading()
|
||
},1000)
|
||
this.getTaskList()
|
||
this.getUserInfo()
|
||
}
|
||
}).catch(err => {
|
||
uni.hideLoading()
|
||
})
|
||
},
|
||
getTaskList(){
|
||
taskListApi().then(res => {
|
||
console.log(res)
|
||
if(res.code === 200){
|
||
this.taskList = res.data
|
||
}else{
|
||
this.$api.msg(res.message)
|
||
}
|
||
})
|
||
},
|
||
// 获取用户信息
|
||
getUserInfo(){
|
||
userInfo().then(res => {
|
||
if(res.code === 200){
|
||
this.infoDetail = res.data
|
||
}else if(res.code == 400){
|
||
uni.removeStorageSync('userInfo')
|
||
uni.removeStorageSync('info')
|
||
this.$api.msg(res.message)
|
||
}else{
|
||
this.$api.msg(res.message)
|
||
}
|
||
})
|
||
},
|
||
getSignInInfo(){
|
||
uni.showLoading()
|
||
signInInfo().then(res => {
|
||
uni.hideLoading()
|
||
if(res.code === 200){
|
||
console.log(res)
|
||
this.list = res.data.details
|
||
this.total = []
|
||
this.signObj = {}
|
||
this.list.forEach(item => {
|
||
this.signObj[item.dt] = item.sign
|
||
if(item.sign){
|
||
this.total.push(item)
|
||
}
|
||
})
|
||
if(this.signObj[this.time]){
|
||
console.log('aaa')
|
||
this.isSign = true
|
||
}
|
||
}else{
|
||
this.$api.msg(res.message)
|
||
}
|
||
}).catch(err => {
|
||
uni.hideLoading()
|
||
})
|
||
},
|
||
sign(){
|
||
// 签到次数点击埋点
|
||
reportClickFn('sign_clk')
|
||
if(this.isSign){
|
||
return
|
||
}
|
||
uni.showLoading()
|
||
signIn().then(res => {
|
||
|
||
console.log(res)
|
||
if(res.code === 200){
|
||
if(res.data){
|
||
// 创建一个对象来存储每个类型的总数
|
||
const typeSums = {};
|
||
|
||
// 遍历数组,将相同类型的 num 相加
|
||
res.data.forEach(obj => {
|
||
if (typeSums[obj.type]) {
|
||
typeSums[obj.type] += obj.num;
|
||
} else {
|
||
typeSums[obj.type] = obj.num;
|
||
}
|
||
});
|
||
|
||
// 构造输出字符串
|
||
let resultStr = '';
|
||
|
||
// 将相同类型的 num 乘以其总数,构造输出字符串
|
||
for (const type in typeSums) {
|
||
resultStr += `${this.rewardTypeObj[type]}*${typeSums[type]}、`;
|
||
}
|
||
|
||
// 去除末尾多余的 '、'
|
||
resultStr = resultStr.slice(0, -1);
|
||
console.log("resultStr:",resultStr)
|
||
this.$api.msg(`${resultStr}领取成功`)
|
||
|
||
}
|
||
setTimeout(() => {
|
||
uni.hideLoading()
|
||
this.isSign = true
|
||
this.getSignInInfo()
|
||
this.getUserInfo()
|
||
},1000)
|
||
|
||
|
||
}else{
|
||
this.$api.msg(res.message)
|
||
}
|
||
}).catch(err => {
|
||
uni.hideLoading()
|
||
})
|
||
},
|
||
goPath(item){
|
||
if(item.path && item.status === 0){
|
||
if (item.path.indexOf('/pages/index/new-index') !== -1 || item.path.indexOf('/pages/shop/index') !== -1 || item.path.indexOf('/pages/mine/mine') !== -1) {
|
||
uni.switchTab({
|
||
url:`${item.path}`
|
||
})
|
||
} else {
|
||
uni.navigateTo({
|
||
url:`${item.path}`
|
||
})
|
||
}
|
||
}
|
||
}
|
||
},
|
||
onTabItemTap(item){
|
||
console.log("我点击了签到的bar")
|
||
// 签到tabbar点击次数
|
||
reportClickFn('sign_tabbar');
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
page{
|
||
background-color: #F5F5F5;
|
||
}
|
||
.sign-page{
|
||
padding: 0 32rpx;
|
||
background-image: url('@/static/new/sign/bg.png');
|
||
background-repeat: no-repeat;
|
||
background-size: 100%;
|
||
.header{
|
||
padding: 72rpx 32rpx;
|
||
|
||
.label{
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #000000;
|
||
}
|
||
.value{
|
||
margin-top: 8rpx;
|
||
font-size: 64rpx;
|
||
color: #000000;
|
||
}
|
||
}
|
||
.sign{
|
||
width: 686rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 24rpx;
|
||
padding: 24rpx;
|
||
.title{
|
||
font-weight: bold;
|
||
font-size: 28rpx;
|
||
color: #000000;
|
||
}
|
||
.sign-scroll{
|
||
white-space: nowrap;
|
||
.item{
|
||
display: inline-block;
|
||
margin-top: 22rpx;
|
||
.item-main{
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-direction: column;
|
||
width: 78rpx;
|
||
height: 108rpx;
|
||
background-color: #F5F5F5;
|
||
border-radius: 8rpx;
|
||
border: 2rpx solid #E6E6E6;
|
||
margin-right: 16rpx;
|
||
.point-icon{
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
}
|
||
.g-icon{
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
margin-top: 4rpx;
|
||
}
|
||
.point{
|
||
margin-top: 4rpx;
|
||
font-size: 20rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
.item-active{
|
||
background-image: url('@/static/new/sign/sign.png');
|
||
background-repeat: no-repeat;
|
||
background-size: 100%;
|
||
background-color: none;
|
||
border: none;
|
||
}
|
||
}
|
||
.sign-list{
|
||
// margin-top: 22rpx;
|
||
// display: flex;
|
||
// align-items: center;
|
||
|
||
|
||
}
|
||
}
|
||
|
||
.step{
|
||
margin-top: 16rpx;
|
||
padding: 0 32rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
.dian-frist{
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
border-radius: 50%;
|
||
background-color: #E6E6E6;
|
||
position: absolute;
|
||
top: -4rpx;
|
||
left: 32rpx;
|
||
z-index: 2;
|
||
}
|
||
.dian-frist-active{
|
||
background-color: #007FFF;
|
||
}
|
||
.step-item{
|
||
width: 94rpx;
|
||
border-top: 2px solid #E6E6E6;
|
||
position: relative;
|
||
.dian{
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
border-radius: 50%;
|
||
background-color: #E6E6E6;
|
||
position: absolute;
|
||
top: -8rpx;
|
||
right: -6rpx;
|
||
z-index: 2;
|
||
}
|
||
.dian-active{
|
||
background-color: #007FFF;
|
||
}
|
||
}
|
||
.step-active{
|
||
border-top: 2px solid #007FFF;
|
||
}
|
||
|
||
}
|
||
.sign-btn{
|
||
width: 638rpx;
|
||
height: 96rpx;
|
||
background: linear-gradient( 90deg, #39B2FF 0%, #3354FF 100%), #D9D9D9;
|
||
border-radius: 16rpx;
|
||
margin-top: 32rpx;
|
||
font-weight: bold;
|
||
font-size: 32rpx;
|
||
color: #FFFFFF;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.dis-btn{
|
||
background: #D9D9D9;
|
||
}
|
||
}
|
||
.main{
|
||
width: 686rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 24rpx;
|
||
padding: 0 24rpx;
|
||
margin-top: 24rpx;
|
||
.headers{
|
||
height: 96rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
border-bottom: 1px solid #F2F2F2;
|
||
|
||
.label{
|
||
font-weight: 800;
|
||
font-size: 32rpx;
|
||
color: #000000;
|
||
}
|
||
.value{
|
||
display: flex;
|
||
align-items: center;
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #999999;
|
||
.back-icon{
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
}
|
||
}
|
||
}
|
||
.item{
|
||
// width: 686rpx;
|
||
height: 128rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
.label{
|
||
.title{
|
||
font-weight: bold;
|
||
font-size: 28rpx;
|
||
color: #000000;
|
||
}
|
||
.sub{
|
||
font-weight: 500;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
margin-top: 8rpx;
|
||
}
|
||
}
|
||
.get-value{
|
||
width: 144rpx;
|
||
height: 64rpx;
|
||
background: linear-gradient( 90deg, #39B2FF 0%, #3354FF 100%), #D9D9D9;
|
||
border-radius: 8rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-weight: bold;
|
||
font-size: 28rpx;
|
||
color: #FFFFFF;
|
||
}
|
||
.value{
|
||
width: 144rpx;
|
||
height: 64rpx;
|
||
background: #F5F5F5;
|
||
border: 2rpx solid #E6E6E6;
|
||
border-radius: 8rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
|
||
.point-value{
|
||
margin-right: 8rpx;
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |