Commit 73fe85be authored by mqf_0707's avatar mqf_0707

新增组件

parent 7282c3f2
......@@ -26,7 +26,8 @@
"dev:rn": "npm run build:rn -- --watch",
"dev:qq": "npm run build:qq -- --watch",
"dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch"
"dev:quickapp": "npm run build:quickapp -- --watch",
"preview": "taobaodev build-preview --debug"
},
"browserslist": [
"last 3 versions",
......@@ -38,33 +39,33 @@
"@babel/helper-create-class-features-plugin": "^7.13.0",
"@babel/runtime": "^7.7.7",
"@pluve/taro-plugin-mars": "^1.1.1",
"@tarojs/cli": "v3.2.0-canary.9",
"@tarojs/components": "v3.2.0-canary.9",
"@tarojs/react": "v3.2.0-canary.9",
"@tarojs/runtime": "v3.2.0-canary.9",
"@tarojs/taro": "v3.2.0-canary.9",
"@tarojs/cli": "3.3.2",
"@tarojs/components": "3.3.2",
"@tarojs/react": "3.3.2",
"@tarojs/runtime": "3.3.2",
"@tarojs/taro": "3.3.2",
"@tbmp/mp-cloud-sdk": "^1.4.2",
"classnames": "^2.2.6",
"hox": "^1.1.2",
"lodash": "4.17.15",
"react": "^16.10.0",
"react-dom": "^16.10.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"taro-ui": "^3.0.0-alpha.3",
"tbcc-sdk-ts": "^1.0.6"
},
"devDependencies": {
"@babel/core": "^7.8.0",
"@tarojs/mini-runner": "v3.2.0-canary.9",
"@tarojs/webpack-runner": "v3.2.0-canary.9",
"@tarojs/mini-runner": "3.3.2",
"@tarojs/webpack-runner": "3.3.2",
"@types/react": "^16.0.0",
"@types/webpack-env": "^1.13.6",
"babel-eslint": "^10.1.0",
"babel-preset-taro": "v3.2.0-canary.9",
"babel-preset-taro": "3.3.2",
"eslint": "^7.12.1",
"eslint-config-standard": "^16.0.2",
"eslint-config-standard-jsx": "^10.0.0",
"eslint-config-standard-react": "^11.0.1",
"eslint-config-taro": "v3.2.0-canary.9",
"eslint-config-taro": "3.3.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
......@@ -73,4 +74,4 @@
"style-resources-loader": "^1.4.1",
"stylelint": "9.3.0"
}
}
}
\ No newline at end of file
......@@ -37,7 +37,8 @@ const apiList = {
getShareInfo: 'getShareInfo',
getVipInfo: 'getVipInfo',
getCollectGoodsList: 'getCollectGoodsList',
getItemListByItemIds: 'getItemListByItemIds'
getItemListByItemIds: 'getItemListByItemIds',
updateEnamePrizeReceived: 'updateEnamePrizeReceived', // 会员权益领取
}
// 生成API
......
export default {
pages: [
'pages/index/index'
'pages/index/index',
'pages/packageGood/browseGoods/browseGoods',
'pages/packageGood/collectGoods/collectGoods',
'pages/packageGood/orderGoods/orderGoods',
'pages/packageGood/cartGoods/cartGoods'
],
subPackages: [
{
......@@ -14,7 +18,8 @@ export default {
"pages": [
'browseGoods/browseGoods',
'collectGoods/collectGoods',
'orderGoods/orderGoods'
'orderGoods/orderGoods',
'cartGoods/cartGoods'
]
},
{
......
import React, { useState } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import classnames from 'classnames'
import tbccTs from 'tbcc-sdk-ts'
const { openDetail } = tbccTs.tb
import styles from './GoodsList.module.less'
function GoodsList(props) {
const {
goodsList = [],
task = {
itemId: '617724147979,617724563528,617300295119',
taskType: 'browseGoods',
image: {
collect: '//yun.dui88.com/taobaomini/clientCTest/goods_collection@2x.png',
no_collect: '//yun.dui88.com/taobaomini/clientCTest/collection_no_collect@2x.png',
img: '//yun.dui88.com/taobaomini/clientCTest/goods_img@2x.png'
},
color: '#181818'
},
onOpenDetail,
onCompleteTask
} = props
const goToGoodsDetail = async(item) => {
const { taskType } = task
const { itemId } = item
if (taskType === 'browseGoods') {
onOpenDetail && onOpenDetail(itemId)
}
await openDetail(String(itemId))
}
// 收藏商品
const goToCollectGoods = async(item) => {
const { itemId, collected } = item
onCompleteTask && onCompleteTask(itemId,collected)
}
// 收藏按钮
const getCollectStyle = (collected) => {
return classnames(styles['item__price-collect'],{
[`${styles['item__price-no-collect']}`]: collected
})
}
return (
<ScrollView scrollY className={styles['container__scroll']}>
<View className={styles['container__content-list']}>
{
goodsList.map((item, i) => {
return (
<View className={styles['content-item']} key={'goods_'+i}>
<View className={styles['item__img']} onClick={() => goToGoodsDetail(item)}>
<Image mode='scaleToFill' src={item.image} />
</View>
<View className={styles['item__name']} style={{ color: task.color }}>{item.name}</View>
<View className={styles['item__price']}>
<View className={styles['item__price-num']}><text>¥</text>{item.price}</View>
{
task.taskType === 'collectGoods' &&
<View
onClick={() => goToCollectGoods(item)}
className={() => getCollectStyle(item.collected)}
>
<Image mode='scaleToFill' src={item.collected ? task.image.collect : task.image.no_collect} />
</View>
}
</View>
</View>
)
})
}
</View>
</ScrollView>
)
}
export default GoodsList
\ No newline at end of file
.container__scroll {
height: 100%;
}
.container__content-list {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.content-item {
width: 340px;
height: 510px;
background: #fff;
margin-bottom: 20px;
}
.content-item:nth-child(even) {
margin-left: 20px;
}
.item__img {
width: 340px;
height: 340px;
background: #e1e1e1;
}
.item__img image {
width: 100%;
height: 100%;
}
.item__name {
margin: 25px 0 31px 21px;
width: 310px;
height: 60px;
font-size: 24px;
font-family: PingFang SC;
font-weight: 400;
color: rgba(24, 24, 24, 1);
line-height: 30px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.item__price {
padding: 0 31px 0 24px;
display: flex;
justify-content: space-between;
}
.item__price-num {
font-size: 32px;
font-family: PingFang SC;
font-weight: 600;
color: rgba(255, 42, 0, 1);
}
.item__price-num text {
font-size: 24px;
margin-right: 2px;
}
.item__price-collect {
width: 118px;
height: 31px;
background-size: 100% 100%;
}
.item__price-collect image {
width: 100%;
height: 100%;
}
.item__price-no-collect {
width: 30px;
height: 30px;
}
.item__price-no-collect image {
width: 100%;
height: 100%;
}
.goods-modal-timer {
width: 147px;
height: 223px;
position: absolute;
top: 502px;
right: 19px;
background: #eee;
}
\ No newline at end of file
import React, { useState } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import classnames from 'classnames'
import styles from './GoodsTitle.module.less'
function GoodsTitle(props) {
const { config } = props
return (
<View className={styles['goods-title']}>
<Image src={config.image} style={{width: config.width / 100 + 'rem', height: config.height / 100 + 'rem' }} />
</View>
)
}
export default GoodsTitle
\ No newline at end of file
.goods-title {
.wh(100%,100%);
.flex-row-center();
.flex-row-middle();
}
\ No newline at end of file
import React, { useState } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import classnames from 'classnames'
import styles from './Progress.module.less'
const PRO_ICON = {
icon: '//yun.duiba.com.cn/taobaomini/provideBeauty/total/progress_icon.png'
}
function Progress(props) {
const { allHotValue = 0, level1 = 0, level2 = 0, level3 = 0, width = 576 } = props
const getProItm = classnames(styles['progress-box-com'],{
[`${styles['progress-box-com-02']}`]: allHotValue === level3
})
const tranHotValue = (value) => {
const _num = parseInt(value / 10000)
if(_num) return _num + '万'
return value
}
return (
<View className={styles['progress-box']}>
<View className={getProItm} style={{width: allHotValue >= level3 ? '100%' : (allHotValue / level3) * 100 +'%'}}></View>
<View className={styles['progress-box__icon']}>
<Image className={styles['progress-box__icon-itm']} style={{left: (level1 / level3) * width / 100 + 'rem'}} src={PRO_ICON['icon']} />
<Image className={styles['progress-box__icon-itm']} style={{left: (level2 / level3) * width / 100 + 'rem'}} src={PRO_ICON['icon']} />
<Image className={styles['progress-box__icon-itm']} style={{right: -0.04 + 'rem'}} src={PRO_ICON['icon']} />
</View>
<View className={styles['progress-box__txt']}>
<View className={styles['progress-box__txt-item']} style={{left: (level1 / level3) * width / 100 + 'rem'}}>{tranHotValue(level1)}</View>
<View className={styles['progress-box__txt-item']} style={{left: (level2 / level3) * width / 100 + 'rem'}}>{tranHotValue(level2)}</View>
<View className={styles['progress-box__txt-item']} style={{left: width / 100 + 'rem'}}>{tranHotValue(level3)}</View>
</View>
</View>
)
}
export default Progress
\ No newline at end of file
.progress-box {
width: 576px;
height: 24px;
border: 1px solid #EF9028;
border-radius: 12px;
position: relative;
}
.progress-box-com {
height: 24px;
background: linear-gradient(0deg, #FF8A00, #FFFAF4);
border-radius: 12px;
position: absolute;
top: 0;
left: 0;
}
.progress-box__icon, .progress-box__txt {
.wh(100%,100%);
position: absolute;
top: 0;
left: 0;
}
.progress-box__icon-itm {
.wh(32px,32px);
position: absolute;
top: -4px;
transform: translate(-50%,0);
}
.progress-box__icon-itm:last-child {
transform: none;
}
.progress-box__txt-item {
font-size: 30px;
font-family: FZLTHProGlobal;
font-weight: 400;
color: #1C1C1C;
position: absolute;
top: -46px;
text-align: center;
transform: translate(-50%,0);
white-space: nowrap;
}
.progress-box__txt-item:last-child {
transform: translate(-100%,0);
}
\ No newline at end of file
import React, { useState } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import classnames from 'classnames'
import { RANK_LIST } from '@/mock'
import styles from './RankList.module.less'
const RANK_ICON = {
1: '',
2: '',
3: ''
}
function RankList(props) {
const { rankList = RANK_LIST } = props
return (
<ScrollView scrollY className={styles['scroll-container']}>
{
rankList.map((itm,i) => {
return(
<View className={`${styles['scroll-item']} ${styles['scroll-item'+(i+1)]}`}>
<View className={styles['scroll-item__rank']}>
{i <= 2 && <View className={styles['rank-icon']}>
<Image src={RANK_ICON[i+1]} />
</View>}
<View>{itm.rank}</View>
</View>
<View className={styles['scroll-item__user']}>{itm.userNick}</View>
<View className={styles['scroll-item__score']}>{itm.hotValue}</View>
</View>
)
})
}
</ScrollView>
)
}
export default RankList
\ No newline at end of file
.scroll-container {
.wh(100%,100%);
}
.scroll-item {
.flex-row-space();
.wh(100%,60px);
background-color: antiquewhite;
margin-bottom: 15px;
}
.scroll-item__rank {
width: 33%;
.flex-row-center();
}
.rank-icon {
.wh(30px,30px);
background-color: aqua;
border-radius: 100%;
}
.scroll-item__user {
width: 34%;
.flex-row-center();
}
.scroll-item__score {
width: 33%;
.flex-row-center();
}
\ No newline at end of file
import React, { useState } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import classnames from 'classnames'
import styles from './RankTitle.module.less'
function RankTitle(props) {
const { titleList = ['排名','用户名','人气值'], myRank = { rank: '11', userNick: '用户名', hotValue: '534443' } } = props
return (
<View className={styles['rank-box']}>
<View className={styles['rank-box__title']}>
{
titleList.map(val => {
return(
<View className={styles['box-itm']}>{val}</View>
)
})
}
</View>
<View className={styles['rank-box__info']}>
<View className={styles['box-itm']}>{myRank.rank}</View>
<View className={styles['box-itm']}>{myRank.userNick}</View>
<View className={styles['box-itm']}>{myRank.hotValue}</View>
</View>
</View>
)
}
export default RankTitle
\ No newline at end of file
.rank-box {
.wh(100%,100px);
}
.rank-box__title,.rank-box__info {
.wh(100%,40px);
.flex-row-space();
}
.box-itm {
height: 100%;
width: 33%;
.flex-row-center();
}
.box-itm:nth-child(2) {
width: 34%;
}
.rank-box__info {
background-color: #000;
color: #ffffff;
}
\ No newline at end of file
import React, { useState } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import Taro, { useShareAppMessage, useDidShow } from '@tarojs/taro'
import classnames from 'classnames'
import styles from './ScrollXView.module.less'
function ScrollXView(props) {
const { prizeList = [], marginRight = 26, width = 300, height = 300 } = props
const showPrize = classnames(styles['show-pize-box'],{
[`${styles['show-pize-box__two']}`]: prizeList.length === 1
})
return (
<>
<ScrollView scrollX className={styles['scroll-x-box']}>
{<View className={showPrize} style={prizeList.length > 1?{width: (prizeList.length * width + (prizeList.length) * marginRight + 100) / 100 + 'rem'}: { width: '100%'}}>
{
prizeList.map(itm => {
return(
<View style={{ width: width / 100 +'rem',height: height / 100 +'rem'}} className={styles['show-pirze__item']}>
<View className={styles['pirze__item-img']}>
<Image src={itm.image} className={styles['pirze__item-img-icon']} />
</View>
<View className={styles['pirze__item-name']}>{itm.name}</View>
</View>
)
})
}
</View>}
</ScrollView>
</>
)
}
export default ScrollXView
\ No newline at end of file
.scroll-x-box {
.wh(100%,100%);
display: flex;
justify-content: flex-start;
align-items: center;
}
.show-pize-box {
display: flex;
justify-content: flex-start;
align-items: center;
}
.show-pize-box__two {
display: flex;
justify-content: center;
align-items: center;
}
.show-pirze__item {
background: #E7E7EF;
border-radius: 25px;
margin-left: 26px;
}
.show-pirze__item:last-child {
margin-right: 26px;
}
.show-pirze__item:first-child {
margin-left: 10px;
}
.pirze__item-img {
width: 224px;
height: 224px;
background: #FFFFFF;
border-radius: 25px;
margin: 16px auto 20px;
}
.pirze__item-img-icon {
width: 224px;
height: 224px;
border-radius: 25px;
}
.pirze__item-name {
font-size: 25px;
font-family: FZLTHProGlobal;
font-weight: 400;
color: #1C1C1C;
text-align: center;
}
\ No newline at end of file
import { View, ScrollView, Image } from '@tarojs/components'
import React from 'react'
import tbccTs from 'tbcc-sdk-ts'
const { openDetail, collectGoods, checkGoodsCollectedStatus, commonToast } = tbccTs.tb
import './GoodsPage.less'
export default function GoodsPage(props) {
const {
isBackFlag = 0, goodsList = [],
task = {
itemId: '617724147979,617724563528,617300295119',
taskType: 'browseGoods',
type: '02', // 01 banner 02
bannerHeight: 430,
image: {
bg: '//yun.dui88.com/taobaomini/clientCTest/goods_bg@2x.png',
banner: '//yun.dui88.com/taobaomini/clientCTest/goods_banner@2x.png',
title: '//yun.dui88.com/taobaomini/clientCTest/goods_title@2x.png',
collect: '//yun.dui88.com/taobaomini/clientCTest/goods_collection@2x.png',
no_collect: '//yun.dui88.com/taobaomini/clientCTest/collection_no_collect@2x.png',
img: '//yun.dui88.com/taobaomini/clientCTest/goods_img@2x.png'
},
color: '#181818'
},
collectFlag = false,
onOpenDetail,
onCompleteTask
} = props
const goToGoodsDetail = async(item) => {
const { taskType } = task
const { itemId } = item
if (taskType === 'browseGoods') {
onOpenDetail && onOpenDetail(itemId)
}
await openDetail(String(itemId))
}
// 收藏商品
const goToCollectGoods = async(item) => {
const { itemId, collected } = item
const { taskType } = task
// 今日是否已收藏过
if(collectFlag) {
commonToast('任务已完成,请明日再来')
return;
}
if (collected) {
commonToast('您已收藏过该商品了')
return
}
// 判断是否活动外已收藏商品
const isCollected = await checkGoodsCollectedStatus(+itemId)
if (isCollected) {
onCompleteTask && onCompleteTask(taskType, itemId)
return
}
const result = await collectGoods(+itemId)
if (result) {
onCompleteTask && onCompleteTask(taskType, itemId)
}
}
return (
<View className='goods-modal-container' style={{ background: `url(${task.image.bg}) no-repeat`, backgroundSize: '750rpx 1624rpx' }}>
{task.type === '01'
? <View
style={{ background: `url(${task.image.title}) no-repeat`, backgroundSize: '100% 100%' }}
className='goods-modal-container__title'
/>
: <View className='goods-modal-container__banner' style={{ background: `url(${task.image.banner}) no-repeat`, backgroundSize: '100% 100%', height: task.bannerHeight + 'rpx' }} />}
<View className='goods-modal-container__content' style={{ top: task.type === '02' ? task.bannerHeight + 'rpx' : '209rpx' }}>
<ScrollView scrollY className='goods-modal-container__scroll'>
<View className='goods-modal-container__content-list'>
{
goodsList.map((item, i) => {
return (
<View className='goods-modal-container__content-item' key={'goods_'+i}>
<View className='goods-modal-container__content-item__img' onClick={() => goToGoodsDetail(item)}>
<Image mode='scaleToFill' src={item.image} />
</View>
<View className='goods-modal-container__content-item__name' style={{ color: task.color }}>{item.name}</View>
<View className='goods-modal-container__content-item__price'>
<View className='goods-modal-container__content-item__price-num'><text>¥</text>{item.price}</View>
{
task.taskType === 'collectGoods' &&
<View
onClick={() => goToCollectGoods(item)}
className={item.collected ? 'goods-modal-container__content-item__price-collect' : 'goods-modal-container__content-item__price-no-collect'}
>
<Image mode='scaleToFill' src={item.collected ? task.image.collect : task.image.no_collect} />
</View>
}
</View>
</View>
)
})
}
</View>
</ScrollView>
</View>
</View>
)
}
.goods-modal-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
min-height: 100vh;
/* background: url('//yun.dui88.com/taobaomini/clientCTestgoods_bg@2x.png') no-repeat; */
background-size: 750px 1624px;
overflow: hidden;
z-index: 20;
}
.goods-modal-container__title {
width: 750px;
height: 120px;
margin: 96px 0 11px;
}
.goods-modal-container__banner {
width: 750px;
height: 400px;
margin-bottom: 30px;
background: #e1e1e1;
}
.goods-modal-container__content {
position: absolute;
top: 190px;
left: 0;
bottom: 0;
padding-top: 41px;
padding: 41px 25px 0;
width: 750px;
/* height: inherit; */
}
.goods-modal-container__scroll {
height: 100%;
}
.goods-modal-container__content-list {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.goods-modal-container__content-item {
width: 340px;
height: 510px;
background: #fff;
margin-bottom: 20px;
}
.goods-modal-container__content-item:nth-child(even) {
margin-left: 20px;
}
.goods-modal-container__content-item__img {
width: 340px;
height: 340px;
background: #e1e1e1;
}
.goods-modal-container__content-item__img image {
width: 100%;
height: 100%;
}
.goods-modal-container__content-item__name {
margin: 25px 0 31px 21px;
width: 310px;
height: 60px;
font-size: 24px;
font-family: PingFang SC;
font-weight: 400;
color: rgba(24, 24, 24, 1);
line-height: 30px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.goods-modal-container__content-item__price {
padding: 0 31px 0 24px;
display: flex;
justify-content: space-between;
}
.goods-modal-container__content-item__price-num {
font-size: 32px;
font-family: PingFang SC;
font-weight: 600;
color: rgba(255, 42, 0, 1);
}
.goods-modal-container__content-item__price-num text {
font-size: 24px;
margin-right: 2px;
}
.goods-modal-container__content-item__price-collect {
width: 118px;
height: 31px;
background-size: 100% 100%;
}
.goods-modal-container__content-item__price-collect image {
width: 100%;
height: 100%;
}
.goods-modal-container__content-item__price-no-collect {
width: 30px;
height: 30px;
}
.goods-modal-container__content-item__price-no-collect image {
width: 100%;
height: 100%;
}
.goods-modal-timer {
width: 147px;
height: 223px;
position: absolute;
top: 502px;
right: 19px;
background: #eee;
}
import { View, Image, Text } from '@tarojs/components'
import React, { useState } from 'react'
import Modal from '@/components/_base/Modal/Modal'
import { useThrottle } from '@/hooks/useThrottle'
import styles from './PrizeModal.module.less'
import { BENEFIT_TYPE, PRIZE_TYPE } from '@/const'
import { checkIsMember } from 'tbcc-sdk-ts/lib/utils'
import { commonToast, navigateToOutside } from 'tbcc-sdk-ts/lib/core/tb'
import { receiveEnamePrize, receiveObjectPrize, applyActivity } from '@/utils/util'
import config from '@/config'
import API from '@/api'
export default function PrizeModal(props) {
const { prizeData = {}, onClose = () => {}, } = props
const app = getApp()
const { image = '', name = '', id = '', type = 1, benefitType = 1, ename = '' } = prizeData
const [ memberModalVisible, setMemberModalVisible ] = useState(false)
const onRecivePrize = useThrottle(async () => {
const { activityId } = app
if(type === PRIZE_TYPE.CREDITS || (type === PRIZE_TYPE.ENAME && benefitType === BENEFIT_TYPE.MEMBER)) {
const isVip = await checkIsMember()
if(!isVip) {
commonToast('加入会员才可领取哦')
setMemberModalVisible(true)
return;
}
}
if(type === PRIZE_TYPE.ENAME && benefitType === BENEFIT_TYPE.MEMBER) {
// receiveMemberEname()
navigateToOutside(ename)
onClose()
return;
}
const result = type === PRIZE_TYPE.OBJECT ? (await receiveObjectPrize({ activityId, id })) : (await receiveEnamePrize({ activityId, id }))
if(result.success && result.status == 1) {
commonToast('奖品发放成功,请前往我的奖品处进行使用')
onClose()
}else if(!result.success && result.status == 2) {
commonToast('奖品发放失败,请前往我的奖品处进行处理')
onClose()
}
},2000)
// 领取会员权益
const receiveMemberEname = async () => {
if(!ename) {
onClose()
return;
}
const result = await applyActivity(config.sellerId,ename)
if(result.businessSuccess) {
const { success, data } = await API.updateEnamePrizeReceived({ id })
if(success) {
commonToast('奖品发放成功,请前往我的奖品处进行使用')
onClose()
}else {
commonToast('奖品发放失败,请前往我的奖品处进行处理')
onClose()
}
}else {
commonToast('奖品发放失败,请前往我的奖品处进行处理')
onClose()
}
}
const onAuthSuccess = async() => {
setMemberModalVisible(false)
onRecivePrize()
}
const onAuthFail = () => {
setMemberModalVisible(false)
}
const closeMemberModal = () => {
setMemberModalVisible(false)
}
return (
<>
<Modal hideCloseButton={true} top={'50%'}>
<View className={styles['prize-container']}>
<Image className={styles['prize-title']} src={'//yun.duiba.com.cn/taobaomini/provideBeauty/prize/invite_title_01.png'} />
<View className={styles['prize-name']}>{'获得'+name+'奖品'}</View>
<View className={styles['prize-name_box']}>
<Image src={'//yun.duiba.com.cn/taobaomini/provideBeauty/prize/m_prize_bg_01.png'} className={styles['prize-name_box-top']} />
<View className={styles['prize-name_box-icon']}>
<Image src={image} className={styles['prize-name_box-icon-img']} />
</View>
<Image src={'//yun.duiba.com.cn/taobaomini/provideBeauty/prize/m_prize_bg_02.png'} className={styles['prize-name_box-bottom']} />
</View>
<Image className={styles['prize-fenwei']} src={'//yun.duiba.com.cn/taobaomini/provideBeauty/prize/fenwei.png'} />
<Image src={'//yun.duiba.com.cn/taobaomini/provideBeauty/prize/btn_02.png'} onClick={() => onRecivePrize()} className={styles['prize-btn']} />
<View className={styles['prize-desc']}>奖品可在我的奖品中查看</View>
</View>
</Modal>
{
memberModalVisible &&
<member-modal
onClose={() => closeMemberModal()}
onAuthFail={onAuthFail}
onAuthSuccess={onAuthSuccess}
/>
}
</>
)
}
\ No newline at end of file
.prize-container {
.wh(500px,488px);
position: relative;
}
.prize-fenwei {
.wh(500px,488px);
position: absolute;
top: 0;
left: 0;
}
.pos-row-center() {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%,0);
}
.prize-title {
.wh(132px,43px);
.pos-row-center();
}
.prize-name_box {
.wh(426px,370px);
.pos-row-center();
top: 100px;
}
.prize-name_box-top {
.wh(426px,142px);
.pos-row-center();
}
.prize-name_box-bottom {
.wh(296px,170px);
.pos-row-center();
top: 200px;
}
.prize-name {
font-size: 40px;
font-family: FZLTHProGlobal;
font-weight: 400;
color: #FFBC6E;
.pos-row-center();
top: 54px;
white-space: nowrap
}
.prize-name_box-icon {
.wh(140px,140px);
.pos-row-center();
top: 150rpx;
}
.prize-name_box-icon-img {
.wh(120px,120px);
}
.prize-btn {
.wh(218px,54px);
position: absolute;
left: 50%;
transform: translate(-50%,0);
bottom: 40rpx;
}
.prize-desc{
width: 500rpx;
position: absolute;
left: 50%;
transform: translate(-50%,0);
bottom: -40rpx;
font-size: 23px;
font-family: FZLTHProGlobal;
font-weight: 400;
// color: #8A3C00;
color: #FFBC6E;
text-align: center;
}
\ No newline at end of file
import { View, ScrollView, Image } from '@tarojs/components'
import React, { useState, useEffect } from 'react'
import Popup from '@/components/_base/Popup/Popup'
import React, { useState, useEffect, useRef } from 'react'
import { noopFn } from '@/utils/util'
import { useTasks } from '@/hooks/useTasks'
import tbccTs from 'tbcc-sdk-ts'
import API from '@/api'
import config from '@/config'
import { useThrottle } from '@/hooks/useThrottle'
import { TASK_STATUS, TASK_CONFIG } from '@/const'
import './TasksModal.less'
import Popup from '@/components/_base/Popup/Popup'
import { TASK_STATUS, TASK_CONFIG, SHOP_ID, BROSE_GOOD_TYPE } from '@/const'
import styles from './TasksModal.module.less'
import { useDidShow } from '@tarojs/taro'
import { TASK_DATA } from '@/mock'
import { checkIsMember } from 'tbcc-sdk-ts/lib/utils'
const { commonToast, favorShop, navigateTo, navigateToOutside, showSharePanel } = tbccTs.tb
const { commonToast, favorShop, navigateTo, navigateToOutside, showSharePanel, navigateToTaobaoPage } = tbccTs.tb
export default function TasksModal(props) {
const app = getApp()
const { onClose = noopFn, onUpdate, taskFlag } = props
const [ memberShopVisible, setMemberShopVisible ] = useState(false)
const [ currentTaskType, setCurrentTaskType ] = useState('')
const [ preBrowseTime, setPreBrowseTime ] = useState(null)
const preBrowseTime = useRef(null)
const { taskList, fetchTaskList } = useTasks()
const { taskIcon, commonTaskTxt, doTaskTxt, browseType, browseTime } = TASK_CONFIG
const [ taskList, setTaskList ] = useState(TASK_DATA)
const { taskIcon, commonTaskTxt, doTaskTxt, jumpLinkType, browseTime, showTaskType, browseGoodType, orderGoodType } = TASK_CONFIG
useDidShow(() => {
if (app.isFlashTask) {
app.isFlashTask = false
if (preBrowseTime && ((Date.now() - preBrowseTime) / 1000) >= browseTime) {
if (preBrowseTime.current && ((Date.now() - preBrowseTime.current) / 1000) >= browseTime && currentTaskType !== 'browseGoods') {
doCompleteTaskHandle(currentTaskType, true)
} else {
preBrowseTime.current = null
} else if(preBrowseTime.current && ((Date.now() - preBrowseTime.current) / 1000) < browseTime) {
commonToast(`未达到${browseTime}秒~`)
preBrowseTime.current = null
}else {
fetchTaskList()
}
}
})
useEffect(() => {
if(showTaskType === 2 && taskFlag) {
fetchTaskList()
}else {
fetchTaskList()
}
},[taskFlag])
const fetchTaskList = async () => {
const isVip = await checkIsMember()
const { success, data } = await API.getTaskList({ isVip })
if(success && data) {
const { list = [] } = data
setTaskList(list)
}
}
const handleTapItem = useThrottle(async(item) => {
const { status, taskType } = item
const tapFn = {
[TASK_STATUS.WAIT_RECEIVE]: async() => {
const { success, data } = await API.receiveTaskRewards({ taskType })
const { success, data } = await API.receiveTaskRewards({ taskType, rewardsKey: 'totalHotValue' })
if (success && data) {
const { rewards } = data
commonToast(`领取成功,次数+${rewards}`)
commonToast(`领取成功,奖励值+${rewards}`)
fetchTaskList()
onUpdate && onUpdate()
}
......@@ -68,34 +88,38 @@ export default function TasksModal(props) {
// 跳转任务 https://www.feizhu.com
jumpLink: async() => {
navigateToOutside(url)
if (browseType === 2) {
if (jumpLinkType === 2) {
doCompleteTaskHandle(taskType)
} else {
app.isFlashTask = true
setPreBrowseTime(Date.now())
preBrowseTime.current = Date.now()
}
// await API.addStat({ type: 'BROWSE_LIVE'})
},
browseGoods: async() => {
app.isFlashTask = true
if (url) {
navigateToOutside(url)
return
}
navigateTo(`/pages/browseGoods/browseGoods?itemIds=${itemIds}&keepTime=${keepTime}`)
if(browseGoodType === BROSE_GOOD_TYPE.PAGE) preBrowseTime.current = Date.now()
navigateTo(`/pages/packageGood/browseGoods/browseGoods?itemIds=${itemIds}&keepTime=${keepTime}`)
},
orderGoods: async() => {
app.isFlashTask = true
if (url) {
navigateToOutside(url)
return
if(orderGoodType === ORDER_GOOD_TYPE.PAGE) {
navigateTo(`/pages/packageGood/orderGoods/orderGoods?itemIds=${itemIds}`)
}else {
await navigateToTaobaoPage(SHOP_ID)
}
navigateTo(`/pages/orderGoods/orderGoods?itemIds=${itemIds}`)
},
collectGoods: async() => {
app.isFlashTask = true
navigateTo(`/pages/collectGoods/collectGoods?itemIds=${itemIds}`)
navigateTo(`/pages/packageGood/collectGoods/collectGoods?itemIds=${itemIds}`)
},
sign: () => doCompleteTaskHandle(taskType)
sign: () => doCompleteTaskHandle(taskType),
share: () => {
showSharePanel();
setTimeout(() => {
doCompleteTaskHandle(taskType)
}, 2000);
}
}
completeFn[taskType] && completeFn[taskType]()
}
......@@ -104,7 +128,6 @@ export default function TasksModal(props) {
const { success } = await API.doCompleteTask({ taskType })
if (success) {
await fetchTaskList()
flag && setPreBrowseTime(null)
}
}
......@@ -118,7 +141,6 @@ export default function TasksModal(props) {
const onAuthFail = () => {
setMemberShopVisible(false)
}
const onCloseModal = () => {
onClose && onClose()
}
......@@ -126,23 +148,23 @@ export default function TasksModal(props) {
return (
<>
<Popup onClose={onCloseModal} height='700rpx'>
<View className='task-modal-container'>
<View className='task-modal-content'>
<View className='task-modal-content__title'>任务模块</View>
<View className='task-modal-content__list'>
<ScrollView scroll-y='{{true}}' className='task-modal-content__scroll'>
<View className={styles['modal-container']}>
<View className={styles['modal-content']}>
<View className={styles['modal-content__title']}>任务模块</View>
<View className={styles['modal-content__list']}>
<ScrollView scroll-y='{{true}}' className={styles['modal-content__scroll']}>
{
taskList.map((item, i) => {
return (
<View className='task-modal-content-item' key={'task_I' + i}>
<View className='task-modal-content-item__left'>
<View className={styles['item']} key={'task_I' + i}>
<View className={styles['item__left']}>
<Image src={taskIcon[item.taskType]} mode='widthFix' />
</View>
<View className='task-modal-content-item__left-label'>
<View className='task-modal-content-item__left-title'>{item.title}</View>
<View className='task-modal-content-item__left-reward'>抽盒次数+{item.rewards}</View>
<View className={styles['item__left-label']}>
<View className={styles['item__left-title']}>{item.title}</View>
<View className={styles['item__left-reward']}>抽盒次数+{item.rewards}</View>
</View>
<View className={'task-modal-content__list-item__right' + ' ' + 'task-item__status-' + item.status} onClick={() => handleTapItem(item)}>
<View className={`${styles['list-item__right']} ${styles['item__status-' + item.status]}`} onClick={() => handleTapItem(item)}>
{
item.status === TASK_STATUS.WAIT_DO ? (doTaskTxt[item.taskType] || '去完成') : commonTaskTxt[item.status]
}
......
.task-modal-container {
.modal-container {
width: 100%;
height: 700rpx;
position: absolute;
......@@ -6,7 +6,7 @@
left: 0;
background-color: #ffffff;
}
.task-modal__close {
.modal__close {
position: absolute;
right: 20rpx;
top: -80rpx;
......@@ -15,20 +15,20 @@
background: url('//yun.dui88.com/taobaomini/clientCTest/modal_close_btn.png') center center no-repeat;
background-size: 48rpx 48rpx;
}
.task-modal-content__title {
.modal-content__title {
text-align: center;
margin: 30rpx 0;
}
.task-modal-content__list {
.modal-content__list {
width: 100%;
height: 600rpx;
padding: 0 16rpx;
}
.task-modal-content__scroll {
.modal-content__scroll {
width: 100%;
height: 100%;
}
.task-modal-content-item {
.item {
display: flex;
justify-content: space-between;
align-items: center;
......@@ -36,7 +36,7 @@
padding: 16rpx;
border: 1rpx solid #eee;
}
.task-modal-content-item__left {
.item__left {
width: 120rpx;
height: 120rpx;
display: flex;
......@@ -44,22 +44,22 @@
align-items: center;
background-color: #eee;
}
.task-modal-content-item__left image {
.item__left image {
width: 80rpx;
}
.task-modal-content-item__left-label {
.item__left-label {
flex: 1;
flex-direction: column;
align-items: center;
margin: 0 16rpx;
}
.task-modal-content-item__left-title {
.item__left-title {
}
.task-modal-content-item__left-reward {
.item__left-reward {
margin-top: 10rpx;
}
.task-modal-content__list-item__right {
.list-item__right {
display: flex;
justify-content: center;
align-items: center;
......@@ -68,13 +68,12 @@
background-color: #eee;
border-radius: 30rpx;
}
.task-item__status-1 {
.item__status-1 {
}
.task-item__status-2 {
.item__status-2 {
}
.task-item__status-3 {
.item__status-3 {
}
\ No newline at end of file
import { View, Image, Text } from '@tarojs/components'
import React from 'react'
import Modal from '@/components/_base/Modal/Modal'
import { useThrottle } from '@/hooks/useThrottle'
import styles from './PrizeNoModal.module.less'
export default function PrizeNoModal(props) {
const { onHandle = () => {}, type = 1 } = props
return (
<Modal hideCloseButton={true} top={'50%'}>
{type === 1 && <View className={styles['prize-container']}>
<Text className={styles['prize-info']}>{'很遗憾,未抽中奖品\n再接再厉'}</Text>
<View className={styles['prize-btn']} onClick={()=> onHandle(type)}>再抽一次</View>
<Image className={styles['prize-close']} onClick={()=> onHandle(2)} src={'//yun.duiba.com.cn/taobaomini/provideBeauty/close_btn.png'} />
</View>}
{type === 2 && <View className={styles['prize-container-02']}>
<Text className={styles['prize-info-02']}>{'很遗憾,感谢参与\n更多福利活动等着你'}</Text>
<View className={styles['prize-btn-02']} onClick={()=> onHandle(type)}>我知道了</View>
<View className={styles['prize-desc']}>奖品可在我的奖品中查看</View>
</View>}
</Modal>
)
}
\ No newline at end of file
.prize-container {
.wh(450px,305px);
position: relative;
.image('//yun.dui88.com/taobaomini/provideBeauty/prize/prize_bg_02.png');
}
.pos-row-center() {
position: absolute;
left: 50%;
transform: translate(-50%,0);
}
.prize-btn {
.wh(162px,37px);
.pos-row-center();
bottom: 38px;
background: linear-gradient(0deg, #FFBC6E, #FFDFB4);
border-radius: 18px;
.flex-row-center();
font-size: 31px;
font-family: FZLTHProGlobal;
font-weight: 400;
color: #1C1C1C;
}
.prize-info {
width: 300px;
.pos-row-center();
bottom: 30px;
top: 110px;
font-size: 25px;
font-family: FZLTHProGlobal;
font-weight: 400;
color: #1C1C1C;
text-align: center;
}
.prize-desc{
position: absolute;
left: 160px;
bottom: 55px;
font-size: 20px;
font-family: FZLTHProGlobal;
font-weight: 400;
color: #1C1C1C;
text-align: center;
}
.prize-container-02 {
.wh(570px,398px);
position: relative;
.image('//yun.dui88.com/taobaomini/provideBeauty/prize/prize_bg_01.png');
}
.prize-info-02 {
width: 442px;
position: absolute;
left: 41px;
bottom: 30px;
top: 87px;
font-size: 25px;
font-family: FZLTHProGlobal;
font-weight: 400;
line-height: 33px;
color: #1C1C1C;
text-align: center;
}
.prize-btn-02 {
width: 172px;
height: 36px;
background: #F6F6F6;
border-radius: 18px;
font-size: 25px;
font-family: FZLTHProGlobal;
font-weight: 400;
color: #F4B45E;
position: absolute;
left: 180px;
bottom: 94px;
.flex-row-center();
margin-right: 30px;
}
.prize-close {
.wh(38px,38px);
.pos-row-center();
bottom: -60px;
}
\ No newline at end of file
......@@ -95,7 +95,39 @@ export const TASK_CONFIG = {
orderGoods: '去完成',
collectGoods: '去完成'
},
browseType: 2, // 1 跳转浏览15s 才算完成 2 跳转即算完成
jumpLinkType: 1, // 1 跳转浏览15s 才算完成 2 跳转即算完成
browseTime: 15, // 浏览时间
jumpType: 1 // 1 浏览15s 才算完成 2 点击就算完成任务
browseGoodType: 3, // 1 浏览15s 才算完成 2 点击就算完成任务 3 浏览指定商品详情页 15s
showTaskType: 1,// 1 弹窗 2 列表
orderGoodType: 1, // 1 集合页下单 2 跳转店铺
}
// 权益类型
export const BENEFIT_TYPE = {
ENAME: 1,// 普通权益
MEMBER: 2 // 会员权益
}
// 浏览商品类型
export const BROSE_GOOD_TYPE = {
PAGE: 1, // 浏览集合页15s
CLICK: 2, // 点击就算完成任务
DETAIL: 3 // 浏览指定商品详情页15s
}
// 购买商品类型
export const ORDER_GOOD_TYPE = {
PAGE: 1, // 集合页下单
SHOP: 2, // 跳转店铺
}
// 店铺ID
export const SHOP_ID = '60014226'
// 助力弹窗类型
export const HELP_MODAL_TYPE = {
HELP: 1, // 邀请助力
FAIL: 2, // 助力失败
REWARDS: 3, // 助力信息展示
}
// 助力弹窗是否已弹
export const HELP_MODAL_SHOW = {
SHOW: 1, // 已弹
NOT_SHOW: 2, // 未弹
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import config from '../config'
import { useAuth } from './useAuth'
import { noopFn } from '@/utils/util'
import { checkShopFavoredStatus } from 'tbcc-sdk-ts/lib/core/tb'
import { checkIsMember } from 'tbcc-sdk-ts/lib/utils'
const { login } = API
......@@ -24,12 +25,14 @@ export function useLogin(callback = noopFn) {
const doLogin = async (authInfo) => {
const isFollow = await checkShopFavoredStatus(config.sellerId)
const isVip = await checkIsMember()
const { nickName: userNick, avatar } = authInfo
const { inviteId } = params
const res = await login({ userNick, avatar, isFollow, inviteId })
const res = await login({ userNick, avatar, isFollow, inviteId, isVip })
if (res?.success) {
const { newUser,firstLoginToday, openId } = res.data
const _loginInfo = {
...res.data,
newUser,firstLoginToday, openId,
userNick,
avatar,
inviteId
......
// 任务数据模拟
export const TASK_DATA = [
{
taskType: 'follow',
rewards: 100,
times: 1,
taskRateType: 1,
todayCompleteTimes: 0,
status: 1,
title: '关注店铺',
},
{
taskType: 'orderGoods',
rewards: 100,
times: 1,
taskRateType: 1,
todayCompleteTimes: 0,
status: 1,
title: '下单任意商品'
},
{
taskType: 'invites',
rewards: 100,
times: 1,
taskRateType: 3,
todayCompleteTimes: 0,
status: 1,
title: '邀请好友'
},
{
taskType: 'sign',
rewards: 100,
times: 1,
taskRateType: 1,
todayCompleteTimes: 0,
status: 1,
title: '每日签到'
},
{
taskType: 'browseGoods',
rewards: 50,
times: 1,
taskRateType: 1,
todayCompleteTimes: 0,
status: 1,
title: '每日浏览宝贝'
},
{
taskType: 'cart',
rewards: 50,
times: 1,
taskRateType: 1,
todayCompleteTimes: 0,
status: 1,
title: '加购商品'
},
{
taskType: 'member',
rewards: 200,
times: 1,
taskRateType: 1,
todayCompleteTimes: 0,
status: 1,
title: '加入会员 '
},
{
taskType: 'share',
rewards: 80,
times: 1,
taskRateType: 1,
todayCompleteTimes: 0,
status: 1,
title: '分享活动'
},
{
taskType: 'jumpLink',
rewards: 50,
times: 1,
taskRateType: 2,
todayCompleteTimes: 0,
status: 1,
title: '每日观看直播'
}
]
// 排行榜
export const RANK_LIST = [
{
rank: 1,
userNick: '用户昵称',
hotValue: 98882892
},
{
rank: 2,
userNick: '用户昵称',
hotValue: 98882892
},
{
rank: 3,
userNick: '用户昵称',
hotValue: 98882892
},
{
rank: 4,
userNick: '用户昵称',
hotValue: 98882892
},
{
rank: 5,
userNick: '用户昵称',
hotValue: 98882892
},
{
rank: 6,
userNick: '用户昵称',
hotValue: 98882892
},
{
rank: 7,
userNick: '用户昵称',
hotValue: 98882892
}
]
\ No newline at end of file
import React, { useState } from 'react'
import React, { useRef, useState } from 'react'
import { View, Image } from '@tarojs/components'
import Taro, { useShareAppMessage, useDidShow } from '@tarojs/taro'
import classnames from 'classnames'
import { SHARE_CONFIG } from '@/const.js'
import { SHARE_CONFIG, HELP_MODAL_TYPE, HELP_MODAL_SHOW } from '@/const.js'
import { useLogin, useLoginFromShare } from '@/hooks/useLogin'
import { useActivityInfoModel, useLoginInfoModel } from '@/store'
import API from '@/api'
......@@ -33,38 +33,77 @@ function Index() {
const [ ruleModalVisible, setRuleModalVisible ] = useState(false)
const [ tasksModalVisible, setTasksModalVisible ] = useState(false)
const [updateFlag, setUpdateFlag] = useState(1)
// 分享图
const SHARE_IMG = useRef('')
// 助力弹窗类型
const [helpType,setHelpType] = useState(HELP_MODAL_TYPE.HELP)
// 助力弹窗标识
const showHelp = useRef(false)
const fetchActivityInfo = async() => {
const { success, data } = await API.getActivityBaseInfoById()
success && setActivityInfoAndStatus(data)
if(success) {
const { startTime, endTime, rule } = data
setActivityInfoAndStatus({
startTime, endTime, rule
})
}
}
// 获取用户信息
const fetchUserInfo = async () => {
const { success, data } = await API.getUserInfo()
success && setUserInfo(data)
}
useEffect(() =>{
checkIsMember().then(isVip => {
console.warn(isVip)
fetchActivityInfo()
getImgShareUrl('cloud://CEFE74AE67921906B5AF842150646D35/share.png').then(url => {
SHARE_IMG.current = url
})
})
},[])
// 授权登录完成
useLogin(async () => {
fetchActivityInfo()
useLogin(async (info) => {
handleVisibleModal(info)
fetchUserInfo()
setUpdateFlag(1)
getShareInfo()
})
// 查看是否有助力信息
const getShareInfo = async () => {
const { success, data } = await API.getShareInfo()
if(success && data && data?.inviteCount) {
setHelpInfo(data)
setDoHelpModalVisible(true)
setHelpType(HELP_MODAL_TYPE.REWARDS)
}
}
// 分享链接进入活动
useLoginFromShare((inviteId) => {
console.log('inviteId :>> ', inviteId)
setDoHelpModalVisible(true)
app.inviteId = inviteId
})
useShareAppMessage(() => {
return {
...SHARE_CONFIG,
imageUrl: SHARE_IMG.current,
path: `pages/index/index?inviteId=${loginInfo.openId}`
}
})
// 助力弹窗 -> 其他弹窗
const handleVisibleModal = async (info) => {
const isVip = await checkIsMember()
// 是否为助力弹窗
if(app.inviteId && !showHelp.current) {
setDoHelpModalVisible(true)
setHelpType(isVip? HELP_MODAL_TYPE.FAIL: HELP_MODAL_TYPE.HELP)
showHelp.current = true
return;
}
// 其他弹窗
}
const onClose = () => {
setMemberVisible(false)
}
const onAuthSuccess = () => {
setMemberVisible(false)
}
......@@ -72,36 +111,46 @@ function Index() {
setMemberVisible(false)
}
const onShare = () => {
// console.warn(222)
showSharePanel()
// openDetail('652334795450')
}
const onGoMyPrizePage = () =>{
my.navigateTo({url: '/pages/packagePrize/myPrize/myPrize'})
}
const homeStyle = classnames(styles.container,{
[`${styles['content_fixed']}`]: ruleModalVisible
})
const onHandleModal = (type) => {
const Fn = {
'visible': () => setModalVisible(true),
'close': () => setModalVisible(false)
}
Fn[type]()
}
const onHandleClose = () => {
setDoHelpModalVisible(false)
if(loginInfo.newUser) {
handleVisibleModal(loginInfo)
}
if(helpType === HELP_MODAL_TYPE.REWARDS) {
setUpdateFlag(HELP_MODAL_TYPE.REWARDS)
fetchUserInfo()
}
}
const onHandleIndex = (type,updateActInfo) => {
const Fn = {
'updateUserInfo': () => {
fetchUserInfo()
updateActInfo && fetchActivityInfo()
},
'rule': () => setRuleModalVisible(true),
'prize': () => navigateTo('/pages/packagePrize/myPrize/myPrize'),
'game': () => navigateTo('/pages/packageGame/game/game')
}
Fn[type]()
}
return (
<View className={homeStyle} style={{ backgroundImage: `url(${INDEX_CONFIG.bg})`}}>
{/* <View className={styles['page-container__1206']}>
<View className={styles['page-container__1624']}>
<View className={styles['page-container__content']}>适配方案</View>
</View>
</View> */}
{/* <View className={styles['blank_content']}><text>{`弹窗后内容区禁止滑动方案{position: fixed}`}</text></View> */}
{/* <View className={styles.countTime}>
<CountDown endTime={(Date.now() + 3 * 60 * 60 * 1000)} fontSize={'20rpx'} color={'#1B5F7F'} onUpdate={() => updateFlash()} />
</View> */}
{/* <Image src={testImg}></Image> */}
<View className={styles.rule} style={{ backgroundImage: `url(${INDEX_CONFIG.ruleButton})` }} onTap={() => setRuleModalVisible(true)}>活动规则</View>
<View className={styles.my_prize} style={{ backgroundImage: `url(${INDEX_CONFIG.myPrizeButton})` }} onTap={onGoMyPrizePage}>我的奖品</View>
<View className={styles.share} style={{ backgroundImage: `url(${INDEX_CONFIG.shareButton})` }} onTap={onShare}>分享</View>
<View className={styles.tasks} style={{ backgroundImage: `url(${INDEX_CONFIG.taskButton})` }} onTap={() => setTasksModalVisible(true)}>任务</View>
<View className={styles.games} style={{ backgroundImage: `url(${INDEX_CONFIG.taskButton})` }} onTap={() => navigateTo('/pages/packageGame/game/game')}>游戏</View>
<View className={styles.rule} style={{ backgroundImage: `url(${INDEX_CONFIG.ruleButton})` }} onClick={() => setRuleModalVisible(true)}>活动规则</View>
<View className={styles.my_prize} style={{ backgroundImage: `url(${INDEX_CONFIG.myPrizeButton})` }} onClick={() => onHandleIndex('prize')}>我的奖品</View>
<View className={styles.tasks} style={{ backgroundImage: `url(${INDEX_CONFIG.taskButton})` }} onClick={() => setTasksModalVisible(true)}>任务</View>
<View className={styles.games} style={{ backgroundImage: `url(${INDEX_CONFIG.taskButton})` }} onClick={() =>onHandleIndex('game') }>游戏</View>
<View className={styles.bemember} onTap={() => setMemberVisible(true)}>入会</View>
{
......
......@@ -9,36 +9,6 @@
right: 0;
bottom: 0;
}
// 适配方案开始
.page-container__1206 {
width: 750px;
height: 1206px;
position: absolute;
left: 0;
top: 50%;
margin-top: calc(-1206px / 2);
}
.page-container__1624 {
width: 750px;
min-height: 1624px;
position: absolute;
left: 0;
top: 50%;
margin-top: calc(-1624px / 2);
}
.page-container__content {
width: 200px;
height: 60px;
position: absolute;
left: 0;
top: 208px;
color: #fff;
background-color: #000;
text-align: center;
line-height: 60px;
}
// 适配方案结束
.content_fixed {
position: fixed;
}
......@@ -86,4 +56,10 @@
width: 100%;
height: 2500px;
background: #eee;
}
.rankModal {
.wh(750px,600px);
padding: 25px;
box-sizing: border-box;
background-color: #eee;
}
\ No newline at end of file
import React, { useEffect, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { View } from '@tarojs/components'
import GoodsPage from '@/components/_tb_modal/GoodsPage/GoodsPage'
import GoodsTitle from '@/components/_tb_comps/GoodsTitle/GoodsTitle'
import GoodsList from '@/components/_tb_comps/GoodsList/GoodsList'
import { useDidShow, useRouter, useDidHide } from '@tarojs/taro'
import API from '@/api'
import { TASK_CONFIG } from '@/const'
import { useRequest } from '@/hooks/useRequest'
import { TASK_CONFIG, BROSE_GOOD_TYPE } from '@/const'
import { commonToast } from 'tbcc-sdk-ts/lib/core/tb'
import styles from './browseGoods.module.less'
const browseConfig = {
taskType: 'browseGoods',
type: '01',
bg: '//yun.dui88.com/taobaomini/clientCTest/goods_bg@2x.png',
head: {
image: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
width: 750,// 头部banner/title 宽度
height: 120,// 头部banner/title 高度
},
image: {
bg: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_bg@2x.png',
banner: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_banner@2x.png',
title: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
collect: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_collection@2x.png',
......@@ -22,66 +28,112 @@ const browseConfig = {
}
function BrowseGoodsPage() {
const [ percent, setPercent ] = useState(0)
const [ isJumpLink, setIsJumpLink ] = useState(false)
const { jumpType, browseTime } = TASK_CONFIG
let browserTimer = null
let usePercent = 0
const [ startTimer, setStartTimer ] = useState(false)
const preBrowseTime = useRef(null)
const currentItemId = useRef('')
const usePercent = useRef(0)
const browserTimer = useRef(null)
const [goodsList, setGoodsList] = useState([])
const { browseGoodType, browseTime = 15 } = TASK_CONFIG
const { params: { itemIds, keepTime } } = useRouter()
const { data: { list = [] }, success: listSuccess } = useRequest(API.getItemListByItemIds, { itemIds }, { isShowLoading: true })
useEffect(() => {
listSuccess && list.length && browseGoodsTimes()
return () => clearInterval(browserTimer)
}, [ list ])
getGoodsList()
}, [])
// 浏览集合页15s
useEffect(() => {
if(browseGoodType === BROSE_GOOD_TYPE.PAGE) {
!browserTimer.current && goodsList.length && browseGoodsTimes()
return () => browserTimer.current && clearInterval(browserTimer.current)
}
},[goodsList])
const getGoodsList = async () => {
const { data } = await API.getItemListByItemIds({ itemIds })
setGoodsList(data?.list || [])
}
useDidShow(() => {
// 重新回到页面开启倒计时
if (!browserTimer && jumpType === 1 && isJumpLink) {
usePercent = percent
if(browseGoodType === BROSE_GOOD_TYPE.PAGE && startTimer && usePercent.current < +browseTime) {
browseGoodsTimes()
}
console.warn('回到该页面了')
if (browseGoodType === BROSE_GOOD_TYPE.DETAIL && preBrowseTime.current && ((Date.now() - preBrowseTime.current) / 1000) >= browseTime) {
onCompleteTask()
currentItemId.current = ''
preBrowseTime.current = null
} else if(preBrowseTime.current) {
commonToast(`未达到${browseTime}秒~`)
currentItemId.current = ''
preBrowseTime.current = null
}
})
useDidHide(() => {
// 页面关闭清除定时器
clearInterval(browserTimer)
if(browserTimer.curren) {
clearInterval(browserTimer.current)
setStartTimer(true)
}
})
// 浏览记录
const onCompleteTask = async(itemId) => {
const { success } = await API.doCompleteTask({ taskType: browseConfig.taskType, itemId })
const { success } = await API.doCompleteTask({ taskType: browseConfig.taskType, itemId: currentItemId.current })
if (success) {
getGoodsList()
commonToast('浏览成功')
setIsJumpLink(false)
}
}
const onOpenDetail = (itemId) => {
if (jumpType === 1) {
setPercent(usePercent)
setIsJumpLink(true)
clearInterval(browserTimer)
return
// 点击商品 跳转时处理
const onOpenDetail = (itemId, collected) => {
const handleFn = {
[BROSE_GOOD_TYPE.PAGE]: () => {
setStartTimer(true)
clearInterval(browserTimer.current)
return;
},
[BROSE_GOOD_TYPE.CLICK]: () => {
currentItemId.current = itemId
onCompleteTask()
},
[BROSE_GOOD_TYPE.DETAIL]: () => {
if(collected) {
commonToast('该商品已经浏览过了')
return;
}
preBrowseTime.current = Date.now()
currentItemId.current = itemId
}
}
onCompleteTask(itemId)
handleFn[browseGoodType]()
}
// 浏览页面定时器
const browseGoodsTimes = () => {
browserTimer = setInterval(() => {
usePercent += 1
const keepTime_ = +keepTime || browseTime
if (usePercent >= keepTime_) {
browserTimer.current = setInterval(() => {
usePercent.current += 1
console.warn(usePercent.current)
const keepTime_ = browseTime
if (usePercent.current >= keepTime_) {
onCompleteTask()
clearInterval(browserTimer)
clearInterval(browserTimer.current)
usePercent.current = 0
}
}, 1000)
}
return (
<View>
<GoodsPage goodsList={list} task={browseConfig} onOpenDetail={() => onOpenDetail} />
<View className={styles['page-container']}>
<View className={styles['page-psd-container']} style={{ background: `url(${browseConfig.bg}) no-repeat`, backgroundSize: '750rpx 1624rpx' }}>
<View className={styles['page-content']}>
<View className={styles['page-content__title']}>
<GoodsTitle config={browseConfig.head}/>
</View>
<View className={styles['page-content__list']}>
<GoodsList goodsList={goodsList} task={browseConfig} onOpenDetail={(itemId,collected) => onOpenDetail(itemId,collected)} />
</View>
</View>
</View>
</View>
)
}
......
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
}
.page-content__list {
position: absolute;
top: 140px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
width: 750px;
}
\ No newline at end of file
export default {
navigationBarTitleText: '加购商品',
enableSkia: 'true',
allowsBounceVertical: 'NO',
enableShareAppMessage: true
}
import React, { useState, useEffect, useRef } from 'react'
import { View } from '@tarojs/components'
import GoodsTitle from '@/components/_tb_comps/GoodsTitle/GoodsTitle'
import GoodsList from '@/components/_tb_comps/GoodsList/GoodsList'
import { useRouter } from '@tarojs/taro'
import tbccTs from 'tbcc-sdk-ts'
import API from '@/api'
import { useThrottle } from '@/hooks/useThrottle'
import styles from './cartGoods.module.less'
const { commonToast, showSkuModal } = tbccTs.tb
const cartConfig = {
taskType: 'cartGoods',
type: '01',
bg: '//yun.dui88.com/taobaomini/clientCTest/goods_bg@2x.png',
head: {
image: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
width: 750,// 头部banner/title 宽度
height: 120,// 头部banner/title 高度
},
image: {
banner: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_banner@2x.png',
title: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
collect: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_collection@2x.png',
no_collect: '//yun.duiba.com.cn/taobaomini/clientCTest/collection_no_collect@2x.png',
img: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_img@2x.png'
},
color: '#181818'
}
function CartGoodsPage() {
const router = useRouter()
const [goodsList, setGoodsList] = useState([])
const { itemIds } = router?.params
// 收藏状态
const collectflag = useRef(false)
useEffect(() => {
getGoodsList()
}, [])
const getGoodsList = async () => {
const { data } = await API.getCollectGoodsList({ itemIds })
setGoodsList(data?.list || [])
}
// 加入购物车 // 对应itemId为 574141925233 skuId为4018047819826 数量为4
const onCompleteTask = useThrottle(async (itemId, collected) => {
console.log(itemId)
if (collected) {
commonToast('您已加购过该商品了')
return;
}
if(!collectflag.current){
const { status, quantity } = await showSkuModal(String(itemId))
if (status == "addCartSuccess") {
const { success } = await API.doCompleteTask({ taskType: cartConfig.taskType, itemId, count: quantity })
if (success) {
collectflag.current = true
getGoodsList()
commonToast('加购成功')
}
}
} else {
commonToast('该任务今天已完成,明天再来吧~')
}
}, 2000);
return (
<View className={styles['page-container']}>
<View className={styles['page-psd-container']} style={{ background: `url(${cartConfig.bg}) no-repeat`, backgroundSize: '750rpx 1624rpx' }}>
<View className={styles['page-content']}>
<View className={styles['page-content__title']}>
<GoodsTitle config={cartConfig.head}/>
</View>
<View className={styles['page-content__list']}>
<GoodsList goodsList={goodsList} task={cartConfig} onOpenDetail={(itemId,collected) => onCompleteTask(itemId,collected)} />
</View>
</View>
</View>
</View>
)
}
export default CartGoodsPage
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
}
.page-content__list {
position: absolute;
top: 140px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
width: 750px;
}
\ No newline at end of file
import React, { useState, useEffect } from 'react'
import React, { useState, useEffect, useRef } from 'react'
import { View } from '@tarojs/components'
import GoodsPage from '@/components/_tb_modal/GoodsPage/GoodsPage'
import GoodsTitle from '@/components/_tb_comps/GoodsTitle/GoodsTitle'
import GoodsList from '@/components/_tb_comps/GoodsList/GoodsList'
import { useRouter } from '@tarojs/taro'
import tbccTs from 'tbcc-sdk-ts'
import API from '@/api'
import { useThrottle } from '@/hooks/useThrottle'
const { commonToast } = tbccTs.tb
import styles from './collectGoods.module.less'
const browseConfig = {
const collectConfig = {
taskType: 'collectGoods',
type: '01',
bg: '//yun.dui88.com/taobaomini/clientCTest/goods_bg@2x.png',
head: {
image: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
width: 750,// 头部banner/title 宽度
height: 120,// 头部banner/title 高度
},
image: {
bg: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_bg@2x.png',
banner: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_banner@2x.png',
title: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
collect: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_collection@2x.png',
......@@ -27,7 +34,7 @@ function CollectGoodsPage() {
const [goodsList, setGoodsList] = useState([])
const { itemIds } = router?.params
// 收藏状态
const [collectflag, setCollectFlag ] = useState(false)
const collectFlag = useRef(false)
useEffect(() => {
getGoodsList()
......@@ -38,18 +45,49 @@ function CollectGoodsPage() {
setGoodsList(data?.list || [])
}
const onCompleteTask = useThrottle(async(taskType, itemId) => {
const { success } = await API.doCompleteTask({ taskType, itemId })
if (success) {
setCollectFlag(true)
getGoodsList()
commonToast('收藏成功')
const onCompleteTask = useThrottle(async(itemId,collected) => {
const collectFn = async () => {
const { success } = await API.doCompleteTask({ taskType, itemId })
if (success) {
collectFlag.current = true
getGoodsList()
commonToast('收藏成功')
}
}
// 今日是否已收藏过
if(collectFlag.current) {
commonToast('任务已完成,请明日再来')
return;
}
if (collected) {
commonToast('您已收藏过该商品了')
return;
}
// 判断是否活动外已收藏商品
const isCollected = await checkGoodsCollectedStatus(+itemId)
if (isCollected) {
collectFn()
return;
}
const result = await collectGoods(+itemId)
if (result) {
collectFn()
return;
}
})
return (
<View>
<GoodsPage goodsList={goodsList} collectFlag={collectflag} task={browseConfig} onCompleteTask={() => onCompleteTask} />
<View className={styles['page-container']}>
<View className={styles['page-psd-container']} style={{ background: `url(${collectConfig.bg}) no-repeat`, backgroundSize: '750rpx 1624rpx' }}>
<View className={styles['page-content']}>
<View className={styles['page-content__title']}>
<GoodsTitle config={collectConfig.head}/>
</View>
<View className={styles['page-content__list']}>
<GoodsList goodsList={goodsList} task={collectConfig} onOpenDetail={(itemId,collected) => onCompleteTask(itemId,collected)} />
</View>
</View>
</View>
</View>
)
}
......
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
}
.page-content__list {
position: absolute;
top: 140px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
width: 750px;
}
\ No newline at end of file
import React, { useEffect, useState } from 'react'
import { View } from '@tarojs/components'
import GoodsPage from '@/components/_tb_modal/GoodsPage/GoodsPage'
import GoodsTitle from '@/components/_tb_comps/GoodsTitle/GoodsTitle'
import GoodsList from '@/components/_tb_comps/GoodsList/GoodsList'
import { useRequest } from '@/hooks/useRequest'
import { useRouter } from '@tarojs/taro'
import API from '@/api'
import styles from './orderGoods.module.less'
const browseConfig = {
const orderConfig = {
taskType: 'orderGoods',
type: '01',
bg: '//yun.dui88.com/taobaomini/clientCTest/goods_bg@2x.png',
head: {
image: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
width: 750,// 头部banner/title 宽度
height: 120,// 头部banner/title 高度
},
image: {
bg: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_bg@2x.png',
banner: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_banner@2x.png',
title: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_title@2x.png',
collect: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_collection@2x.png',
......@@ -25,8 +32,17 @@ function OrderGoodsPage() {
const { data } = useRequest(API.getItemListByItemIds, { itemIds })
return (
<View>
<GoodsPage goodsList={data?.list || []} task={browseConfig} />
<View className={styles['page-container']}>
<View className={styles['page-psd-container']} style={{ background: `url(${orderConfig.bg}) no-repeat`, backgroundSize: '750rpx 1624rpx' }}>
<View className={styles['page-content']}>
<View className={styles['page-content__title']}>
<GoodsTitle config={orderConfig.head}/>
</View>
<View className={styles['page-content__list']}>
<GoodsList goodsList={data?.list || []} task={orderConfig} onOpenDetail={(itemId,isBrowsed) => onOpenDetail(itemId,isBrowsed)} />
</View>
</View>
</View>
</View>
)
}
......
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
}
.page-content__list {
position: absolute;
top: 140px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
width: 750px;
}
\ No newline at end of file
import React, { useState, useEffect } from 'react'
import { Image, ScrollView, View } from '@tarojs/components'
import API from '@/api'
import { DRAW_STATUS, PRIZE_TYPE } from '@/const'
import { DRAW_STATUS, PRIZE_TYPE, BENEFIT_TYPE } from '@/const'
import DeliveryModal from '@/components/_tb_modal/DeliveryModal/DeliveryModal'
import tbccTs from 'tbcc-sdk-ts'
import { useThrottle } from '@/hooks/useThrottle'
import { checkIsMember } from 'tbcc-sdk-ts/lib/utils'
import { dateFormatter } from '@/utils/date'
import './myPrize.less'
import styles from './myPrize.module.less'
import { getApp } from '@tarojs/taro'
import { applyActivity } from '@/utils/util'
const { commonToast, getUserAddress, navigateToOutside, setClipboard } = tbccTs.tb
const { getMyPrizeList } = API
......@@ -40,14 +41,14 @@ const prizeConfig = {
btnStyle: {
width: '150rpx'
},
contentTop: '210rpx',
contentTop: '140rpx',
blankTxt: '暂无奖品',
hasLogistic: true, // 是否展示物流信息
isShowPirzeId: true // 是否显示奖品编号
hasLogistic: false, // 是否展示物流信息
isShowPirzeId: false // 是否显示奖品编号
}
function Empty(blankTxt) {
return <View className='my-prize-item__empty'>{blankTxt}</View>
return <View className={styles['my-prize-item__empty']}>{blankTxt}</View>
}
function MyPrizeList() {
......@@ -61,7 +62,6 @@ function MyPrizeList() {
useEffect(() => {
fetchMyPriceList()
}, [])
async function fetchMyPriceList() {
const res = await getMyPrizeList()
if (res.success && res?.data?.list?.length) {
......@@ -71,13 +71,29 @@ function MyPrizeList() {
setExpiredTime(dateFormatter(res?.data?.expiredTime, 'yyyy/MM/dd hh:mm:ss'))
}
}
// 复制编码
const handleCopyId = async(text) => {
await setClipboard(text)
commonToast('复制成功')
}
// 领取会员权益
const receiveMemberEname = async (id,ename) => {
if(!ename) {
return;
}
const result = await applyActivity(config.sellerId,ename)
if(result.businessSuccess) {
const { success, data } = await API.updateEnamePrizeReceived({ id }).catch(res => {
commonToast(res.message)
})
if(success) {
commonToast('领取成功')
fetchMyPriceList()
}
}else {
commonToast(result.errorMsg)
}
}
// 优惠券
async function handleGetEquity(id) {
const { activityId } = app
......@@ -87,7 +103,6 @@ function MyPrizeList() {
}
fetchMyPriceList()
}
// 领取实物
async function handleReceiveObjectPrize(id) {
const { activityId } = app
......@@ -97,7 +112,6 @@ function MyPrizeList() {
}
fetchMyPriceList()
}
// 积分
async function handleGetCredits(id) {
// 判断是否为会员
......@@ -108,7 +122,6 @@ function MyPrizeList() {
}
handleGetEquity(id)
}
// 领取实物前询问
async function handleChooseAddress(id) {
const userAddress = await getUserAddress().catch(err => {
......@@ -143,9 +156,8 @@ function MyPrizeList() {
}
})
}
const handleClick = useThrottle(async(item) => {
const { type, drawStatus, useUrl = '', id, _id } = item
const { type, drawStatus, useUrl = '', id, _id, ename = '', benefitType } = item
if (drawStatus === DRAW_STATUS.SUCCESS) {
if (type === PRIZE_TYPE.OBJECT && prizeConfig.hasLogistic) {
setCurrentPrize(item)
......@@ -163,9 +175,11 @@ function MyPrizeList() {
// 领取权益
const prizeId = id || _id
if (type === PRIZE_TYPE.ENAME) return handleGetEquity(prizeId)
if (type === PRIZE_TYPE.ENAME && (benefitType === BENEFIT_TYPE.ENAME || !benefitType)) return handleGetEquity(prizeId)
// 领取会员
if (type === PRIZE_TYPE.ENAME && benefitType === BENEFIT_TYPE.MEMBER) return receiveMemberEname(prizeId,ename)
// 领取实物
if (type === PRIZE_TYPE.OBJECT) return handleReceiveObjectPrize(prizeId)
if (type === PRIZE_TYPE.OBJECT) return handleChooseAddress(prizeId)
// 领取积分
if (type === PRIZE_TYPE.CREDITS) return handleGetCredits(prizeId)
}, 2000)
......@@ -182,53 +196,54 @@ function MyPrizeList() {
}
return (
<View>
<View className='my-prize-container' style={{ background: `url(${prizeConfig.bg}) no-repeat center top/cover` }}>
<View className='my-prize-label' style={{ background: `url(${prizeConfig.title}) no-repeat`, backgroundSize: '100% 100%' }} />
<View className='my-prize-content' style={{ top: prizeConfig.contentTop }}>
<ScrollView scrollY className='my-prize-content__scroll'>
{myPrizeList.length > 0 &&
<View className='my-prize-list'>
{myPrizeList.map((item, i) => {
return (
<View className='my-prize-item' key={'prize_'+i}>
<Image className='my-prize-item__avatar' src={item.image} />
<View className='my-prize-item__content'>
<View className='my-prize-item__name'>{item.name}</View>
{
prizeConfig.isShowPirzeId &&
<View className='my-prize-item__subtitle'>
<View className='my-prize-item__code'>奖品编码:{item.id || item._id}</View>
{/* <!-- 复制按钮 --> */}
<Image className='my-prize-item__copy' onTap={() => handleCopyId(item.id || item._id)} src={prizeConfig.copyIcon} />
</View>
}
{item.drawStatus === DRAW_STATUS.FAIL && <View className='my-prize-item__tip'>{item.remark}</View>}
{(item.drawStatus === DRAW_STATUS.RETRY || item.drawStatus === DRAW_STATUS.WAITAWARD) && <View className='my-prize-item__tip'>请于{expiredTime}前领取</View>}
{item.drawStatus === DRAW_STATUS.EXPIRED && <View className='my-prize-item__tip'>奖品已过期失效</View>}
<View className={styles['page-container']}>
<View className={styles['my-prize-container']} style={{ background: `url(${prizeConfig.bg}) no-repeat center top/cover` }}>
<View className={styles['page-content']}>
<View className={styles['my-prize-label']} style={{ background: `url(${prizeConfig.title}) no-repeat`, backgroundSize: '100% 100%' }} />
<View className={styles['my-prize-content']} style={{ top: prizeConfig.contentTop }}>
<ScrollView scrollY className={styles['my-prize-content__scroll']}>
{myPrizeList.length > 0 &&
<View className={styles['my-prize-list']}>
{myPrizeList.map((item, i) => {
return (
<View className={styles['my-prize-item']} key={'prize_'+i}>
<Image className={styles['my-prize-item__avatar']} src={item.image} />
<View className={styles['my-prize-item__content']}>
<View className={styles['my-prize-item__name']}>{item.name}</View>
{
prizeConfig.isShowPirzeId &&
<View className={styles['my-prize-item__subtitle']}>
<View className={styles['my-prize-item__code']}>奖品编码:{item.id || item._id}</View>
{/* <!-- 复制按钮 --> */}
<Image className={styles['my-prize-item__copy']} onTap={() => handleCopyId(item.id || item._id)} src={prizeConfig.copyIcon} />
</View>
}
{item.drawStatus === DRAW_STATUS.FAIL && <View className={styles['my-prize-item__tip']}>{item.remark}</View>}
{(item.drawStatus === DRAW_STATUS.RETRY || item.drawStatus === DRAW_STATUS.WAITAWARD) && <View className={styles['my-prize-item__tip']}>请于{expiredTime}前领取</View>}
{item.drawStatus === DRAW_STATUS.EXPIRED && <View className={styles['my-prize-item__tip']}>奖品已过期失效</View>}
</View>
<View className={styles['prize-item__status']} style={prizeConfig.btnStyle}>
{item.type === PRIZE_TYPE.OBJECT
? <Image onTap={() => handleClick(item)} src={prizeConfig.objectStatus[item.drawStatus]} mode='widthFix' />
: <Image onTap={() => handleClick(item)} src={(item.drawStatus === 3 && !item.useUrl) ? prizeConfig.receiveBtn : prizeConfig.enameStatus[item.drawStatus]} mode='widthFix' />}
</View>
</View>
<View className='prize-item__status' style={prizeConfig.btnStyle}>
{item.type === PRIZE_TYPE.OBJECT
? <Image onTap={() => handleClick(item)} src={prizeConfig.objectStatus[item.drawStatus]} mode='widthFix' />
: <Image onTap={() => handleClick(item)} src={(item.drawStatus === 3 && !item.useUrl) ? prizeConfig.receiveBtn : prizeConfig.enameStatus[item.drawStatus]} mode='widthFix' />}
</View>
</View>
)
})}
</View>}
{
myPrizeList.length === 0 && Empty(prizeConfig.blankTxt)
}
</ScrollView>
)
})}
</View>}
{
myPrizeList.length === 0 && Empty(prizeConfig.blankTxt)
}
</ScrollView>
</View>
</View>
</View>
{deliveryModalVisible && <DeliveryModal prizeItem={currentPrize} task={prizeConfig.logisticsImage} onClose={() => setDeliveryModalVisible(false)} />}
......
.page-container {
.page-container();
}
.my-prize-container {
width: 100vw;
height: 100vh;
opacity: 1;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
/* background: url('') no-repeat center top/cover; */
.page-container__1624();
}
.page-content {
.page-content();
}
.my-prize-container .my-prize-label {
width: 208px;
height: 36px;
margin: 140px auto 40px;
margin: 70px auto 40px;
background: url("//yun.duiba.com.cn/duiba-components-c-myprizeprize_title.png")
no-repeat;
background-size: 100% 100%;
......
......@@ -38,15 +38,18 @@
align-items: stretch;
}
.flex-row-left() {
.flex-row-normal();
justify-content: flex-start;
}
.flex-row-center() {
.flex-row-normal();
justify-content: center;
}
.flex-row-right() {
justify-content: flex-end;
}
.flex-row-space() {
.flex-row-normal();
justify-content: space-between;
}
.flex-row-wrap() {
......@@ -95,6 +98,7 @@
align-items: flex-start;
}
.flex-col-center() {
.flex-col-normal();
align-items: center;
}
.flex-col-right() {
......
.page-container {
.page-container() {
position: relative;
top: 0;
right: 0;
......@@ -6,8 +6,9 @@
width: 100vw;
height: 100vh;
min-height: 100vh;
overflow: hidden;
}
.page-container__content {
.page-container__1624() {
position: absolute;
width: 100vw;
height: 1624px;
......@@ -15,4 +16,13 @@
right: 0;
top: 50%;
transform: translate(0,-50%);
}
.page-content() {
position: absolute;
width: 100vw;
height: 100vh;
left: 0;
right: 0;
top: 50%;
transform: translate(0,-50%);
}
\ No newline at end of file
import tbccTs from 'tbcc-sdk-ts'
import API from '@/api'
const { getUserAddress, commonToast } = tbccTs.tb
export const noopFn = () => { }
// 领取实物
const getUerAddressParam = async () => {
const userAddress = await getUserAddress().catch(err => {
commonToast(err.errorMessage);
});
if(!userAddress) return false
const { name, telNumber, provinceName, cityName, cityCode, countyName, detailInfo, streetName } = userAddress || {};
const params = {
name,
phone: telNumber,
addressDetail: detailInfo,
cityCode,
city: cityName,
province: provinceName,
area: countyName,
streetName,
}
return {
params,
duibaAddress: userAddress.duibaAddress.address
}
}
const confirmAddress = async (address) => {
return new Promise(async (resolve,reject) => {
my.confirm({
title: '提示',
content: '确认使用该收货地址:' + address,
success: (res) => {
if(res.confirm) {
resolve(true)
}
resolve(false)
},
});
})
}
export const receiveObjectPrize = async (_params) => {
return new Promise(async (resolve,reject) => {
const userInfo = await getUerAddressParam()
if(!userInfo) resolve({ success: false, status: 3, message: '未领取' })
const { params: _params, duibaAddress } = userInfo
const { name, phone } = _params
const address = name + phone + duibaAddress
const canPass = await confirmAddress(address)
if(!canPass) resolve({ success: false, status: 3, message: '未领取' })
const { success, data } = await API.receiveObjectPrize({ ...params, ..._params })
if (success) {
resolve({ success: true, status: 1, message: '领取成功'})
}else {
resolve({ success: false, status: 2, message: '领取失败' })
}
})
}
// 领取权益
export const receiveEnamePrize = async (params) => {
return new Promise(async (resolve,reject) => {
const { success, data } = await API.receiveEnamePrize(params).catch(res => {
resolve({ success: false, status: 2 })
});
if (success) {
resolve({ success: true, status: 1 })
}else {
resolve({ success: false, status: 2 })
}
})
}
//打点
export const addStat = async(activityId, type)=> {
return new Promise(async (resolve,reject) => {
const result = await API.addStat({ activityId, type }).catch(res => {
commonToast(res && res.message);
});
if (result && result.success) {
resolve(true)
}
resolve(false)
})
}
export const createCanvas = async (canvasId) => {
return new Promise((resolve,reject) => {
my.createCanvas({
......@@ -11,3 +91,61 @@ export const createCanvas = async (canvasId) => {
})
})
}
// 查询商家权益活动
export const getActivity = (sellerId) => {
const memberBenefitPlugin = requirePlugin("memberBenefit")
if(!memberBenefitPlugin) return []
return new Promise(async (resolve,reject) => {
memberBenefitPlugin.getActivity({
data: {
sellerId,
},
success: (result) => {
resolve(result)
},
fail: (error) => {
console.log('获取失败'+JSON.stringify(error))
resolve(error)
}
});
})
}
// 领取商家权益
export const applyActivity = (sellerId, activityId) => {
const memberBenefitPlugin = requirePlugin("memberBenefit")
if(!memberBenefitPlugin) return []
return new Promise(async (resolve,reject) => {
memberBenefitPlugin.applyActivity({
data: {
sellerId,
activityId,
},
success: (result) => {
resolve(result)
},
fail: (error) => {
console.warn('领取商家权益失败'+JSON.stringify(error.data))
resolve(error.data)
}
});
})
}
// 查询商家会员等级
export const getGrade = (sellerId) => {
const memberBenefitPlugin = requirePlugin("memberBenefit")
if(!memberBenefitPlugin) return []
return new Promise(async (resolve,reject) => {
memberBenefitPlugin.getGrade({
data: {
sellerId
},
success: (result) => {
resolve(result)
},
fail: (error) => {
console.log('查询商家会员等级失败'+JSON.stringify(error))
resolve(error)
}
});
})
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment