Commit 4864b784 authored by wanghuan's avatar wanghuan

Merge branch 'c_client_taro-pack' of...

Merge branch 'c_client_taro-pack' of http://gitlab2.dui88.com/qinhaitao/taobao-mini-template into c_client_taro-pack
parents 9343cf13 4a775d5e
No preview for this file type
export default {
hasCanvas: false, // 是否开启游戏模块自动注入dist
hasCanvas: true, // 是否开启游戏模块自动注入dist
defaultPlugins: [
[
'@pluve/taro-plugin-mars', // taro暂时未支持阿里小程序自定义插件 需要引用插件的页面需配置
......
import cloud from '@tbmp/mp-cloud-sdk'
import tbccTs from 'tbcc-sdk-ts'
import conifg from './config/index'
import conifg from './config/config'
const { utils: { generateAPI }, request: tbccRequest, capi, capiFn } = tbccTs
const { cloudName, requestType } = conifg
......@@ -38,6 +38,19 @@ const apiList = {
getCollectGoodsList: 'getCollectGoodsList',
getItemListByItemIds: 'getItemListByItemIds',
updateEnamePrizeReceived: 'updateEnamePrizeReceived', // 会员权益领取
getMyPrizeList: 'getMyAwardsList',
receiveObjectPrize: {
handle: 'recieveObjectPrize',
method: 'GET',
isShowLoading: false,
toastError: false
},
receiveEnamePrize: {
handle: 'recieveEnamePrize',
method: 'GET',
isShowLoading: false,
toastError: false
},
getRotatePrizeListInfo:'getRotatePrizeListInfo',//获取奖品列表接口,暂未实现
drawRotatePrize:'drawRotatePrize',//大转盘抽奖接口,暂未实现
......
......@@ -33,7 +33,7 @@ export default {
enableSkia: 'true',
allowsBounceVertical: 'NO',
navigationBarTitleText: '活动名称',
navigationBarForceEnable: true
navigationBarForceEnable: false
},
plugins: {
cemMember: {
......
......@@ -4,7 +4,7 @@ import './app.less'
// 使用taro-ui 按需引入的组件样式
import './taro-ui.scss'
import config from './config/index'
import config from './config/config'
import './utils/mdProxy'
const { env, tornadoAPI, defaultActivityId } = config
......
import { View } from '@tarojs/components'
import React from 'react'
import styles from './ContainerFit.module.less'
export default function ContainerFit(props) {
const { bg = ''} = props
return (
<View className={styles['page-container']}>
<View className={styles['page-psd-container']} style={{ background: `url(${bg}) no-repeat`, backgroundSize: '7.5rem 16.24rem' }}>
<View className={styles['page-content']}>
{props.children}
</View>
</View>
</View>
)
}
\ No newline at end of file
.page-container {
position: relative;
top: 0;
right: 0;
left: 0;
width: 100vw;
height: 100vh;
min-height: 100vh;
overflow: hidden;
}
.page-psd-container {
position: absolute;
width: 100vw;
height: 1624px;
left: 0;
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
......@@ -5,28 +5,26 @@ import { Main } from './output';
const app = getApp()
Component({
isUpdateFlag: true,
data: {
needDataInCanvas: {}
},
didMount(query) {
data: {},
props: {
data: {}
},
didMount(query) {},
didUpdate(preProps,preData) {
// 实时监听数据更新
const { updateFlag, netName, updateData } = this.props
const { updateFlag, data } = this.props
if(updateFlag !== 1 && updateFlag !== preProps.updateFlag) {
// this.postMessage(netName, updateData)
console.warn('数据更新了')
this.postMessage(data.type, data)
}
},
didUnMount() {
// 页面被关闭
this.main && this.main.destroy();
},
methods: {
onCanvasReady() {
console.log("进canvas了")
// 创建Main,授权登录完后才创建
this.createMain();
},
//创建引入的Main
createMain() {
const self = this;
my.createCanvas({
id: 'canvas',
......@@ -41,12 +39,10 @@ Component({
if (!this.main) {
try {
this.main = new Main(ccc)
//添加事件,为了和main里的通信
this.main.addGlobalEvent("onMessage", self.onMessage, self)
} catch (err) {
console.error(err)
}
}
}
......@@ -58,145 +54,28 @@ Component({
let netName = e.data.netName;
//接口参数
let parameter = e.data.parameter;
//暂时发现3个需要用户操作的接口
//定制的授权
if (netName == "mine.authorize") {
this.getAuth()
}
//获取地址
else if (netName == "mine.getUserAddress") {
this.getUserAddress(parameter.prizeId)
}
//关注店铺的操作
else if (netName == "mine.favorShop") {
this.doFavorShop()
}
//领养名字,有弹框的
else if (netName == "mine.getAdoptName") {
this.setData({ "adoptModalVisible": true, type: parameter.type })
}
//打开详情页,还有成功失败
else if (netName == "mine.openDetail") {
openDetail(parameter.itemId).then(
() => {
this.postMessage(netName, { success: true })
if(netName.indexOf("mine") == 0) {
// 和游戏页面通信
this.props.onMessage({
type: 'message',
target: {
id: this.props.id
},
() => {
this.postMessage(netName, { success: false })
data: {
netName,
parameter
}
)
})
}else {
this.postMessage(netName, { success: false })
}
//前端同步接口
else if (netName.indexOf("mine") == 0) {
var data = { success: true }
switch (netName) {
case "mine.getAppData"://获取信息
data = {
success: true,
data: {
activityId: app.activityId,//|| "5e7c40e98564b57d7fb95812",
nickName: app.nickName,
avatar: app.avatar,
openId: app.openId,
inviteId: this.inviteId,//判断是否要发助力用
isFollow: app.isFollow,
needDataInCanvas:app.needDataInCanvas,
activityInfo:this.activityInfo,
userInfo:this.userInfo,
newUser: this.newUser,
remainTimes: this.remainTimes,
firstLoginToday: this.firstLoginToday,
}
}
break;
case "mine.navigateToOutside"://跳转小程序外的页面
my.call("navigateToOutside", {
url: parameter.url
}, (res) => {
// my.alert({ content: "success - " + JSON.stringify(res)})
})
console.log(parameter.url)
break;
case "mine.navigateTo"://跳转小程序内的页面
my.navigateTo({
url: parameter.url
})
break;
case "mine.navigateBack"://返回页面
my.navigateBack({
delta: parameter.delta || 1
})
break;
case "mine.showSharePanel"://分享
//多一个参数
this.openId = parameter.openId;
my.showSharePanel()
break;
case "mine.reportAnalytics": ////淘宝自定义埋点
reportAnalytics(parameter.logkey);
break;
case "mine.openMusic": //音频
playBgMusic(parameter.isOn, this.musicUrl);
break;
case "mine.openTask": //打开任务
this.setData({ taskModalVisible: true });
break;
case "mine.openMember": //打开入会
this.setData({ expend: true, });
break;
}
this.postMessage(netName, data)
} else {
//获取后端接口
const { function: fc } = app.cloud;
//处理下带上activityId
if (!parameter) parameter = {};
parameter.activityId = app.activityId;
//netName得分割下
fc.invoke(netName.split(".")[0], parameter, netName.split(".")[1])
.then(res => {
// console.log("返回数据" + JSON.stringify(res));
//发送消息
this.postMessage(netName, res || { success: false })
}, (err) => {
//网络异常,返回失败
this.postMessage(netName, { success: false })
})
}
},
//和main通信的方法,接收main的信息
onMessage2(e) {
// this.props.onPostMessage({
// type: 'postMessage',
// target: {
// id: this.props.id
// },
// data: e.data
// })
},
postMessage(netName, data) {
// this.main.dispatchGlobalEvent(netName, data)
this.main && this.main.dispatchGlobalEvent({ type: netName }, data)//以防复用事件event串了,就用这种方式
},
//鼠标事件
onMouseEvent(e) {
if (this.main) this.main.stage.onMouseEvent(e)
},
// 发送数据
onPostMessage() {
this.props.onPostMessage({
type: 'postMessage',
target: {
id: this.props.id
},
data: {
a: 222,
b: 33
}
})
}
}
});
<member-shop-center expend="{{true}}" onClose="onMemberModalClose" onAuthFail="onAuthFail" onAuthSuccess="onAuthSuccess"/>
<member-shop-center expend="{{expend}}" sellerId="{{sellerId}}" onClose="onMemberModalClose" onAuthFail="onAuthFail" onAuthSuccess="onAuthSuccess"/>
Component({
data: {
visible: true
},
data: {},
props: { expend: false, sellerId: '' },
didMount(){},
methods: {
onMemberModalClose() {
// console.log('this.props :>> ', this.props);
......
......@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { View, Image, Text } from "@tarojs/components";
import LoadingBar,{LOAD_TYPE} from "../LoadingBar/LoadingBar";
import styles from './BrowserLoading.module.less'
import {BROWSE_COUNTDOWN_OBJ} from '@/const'
import {BROWSE_COUNTDOWN_OBJ} from '@/config/browse.config'
const BrowserLoading = (props) => {
const {loadFlag,count} = props;
return (
......
......@@ -4,8 +4,6 @@ import classnames from 'classnames'
import tbccTs from 'tbcc-sdk-ts'
const { openDetail } = tbccTs.tb
import styles from './GoodsList.module.less'
import BrowserLoading from '../BrowserLoading/BrowserLoading'
import {BROWSE_COUNTDOWN_OBJ} from '@/const'
function GoodsList(props) {
const {
......@@ -18,12 +16,10 @@ function GoodsList(props) {
no_collect: '//yun.dui88.com/taobaomini/clientCTest/collection_no_collect@2x.png',
img: '//yun.dui88.com/taobaomini/clientCTest/goods_img@2x.png'
},
color: '#181818',
loadFlag:BROWSE_COUNTDOWN_OBJ.DEFAULT
color: '#181818'
},
onOpenDetail,
onCompleteTask,
count
onCompleteTask
} = props
const goToGoodsDetail = async(item) => {
......@@ -73,10 +69,6 @@ function GoodsList(props) {
)
})
}
{
task.loadFlag &&
<BrowserLoading loadFlag={task.loadFlag} count={count} />
}
</View>
</ScrollView>
)
......
.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;
}
.browse_loading{
width: 200px;
height: 200px;
position: fixed;
right: 20px;
top: 400px;
border: 1px solid cyan;
box-sizing: border-box;
}
.count_img{
width: 100%;
height: 100%;
border: 1px solid rgb(47, 131, 99);
box-sizing: border-box;
background-image: url('//yun.dui88.com/7f705da9-5f16-4cf1-a239-3903c5c23995.png');
.image-property(contain, center center);
}
.count_time{
width: 100px;
height: 60px;
line-height: 60px;
margin: 40px auto 0;
border: 1px solid cyan;
box-sizing: border-box;
font-size: 40px;
font-weight: 600;
color: #000;
text-align: center;
}
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
.goods-title {
.wh(100%,100%);
.flex-row-center();
.flex-row-middle();
}
\ No newline at end of file
# 排行榜组件
---
## 何时使用
- 当某个页面需要展示累计邀请、分等级奖励进度条、累计签到等。
## 目录结构
`RankTitle` 排行榜头部
`RankList` 排行榜列表
## RankTitle API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --------- | ------------ | ----------- | ------------------------------------------------------- | ---- |
| titleList | 表头 | ArrayString | - | |
| myRank | 个人排名信息 | Object | { rank: '11', userNick: '用户名', rankValue: '534443' } | |
## RankList API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| -------- | ----------- | ----------- | -------- | ---- |
| rankList | 排名信息 | ArrayObject | 见示例一 | |
| rankIcon | 前三名 Icon | Object | 见示例二 | |
## 示例一
```
[{
rank: 1,
userNick: '用户昵称',
hotValue: 98882892
}]
```
## 示例二
```
{
1: '//yun.duiba.com.cn/taobaomini/pike_call/icon_06.png',
2: '//yun.duiba.com.cn/taobaomini/pike_call/icon_07.png',
3: '//yun.duiba.com.cn/taobaomini/pike_call/icon_08.png'
}
```
import React ,{ memo } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import { RANK_LIST } from '@/mock'
import styles from './RankList.module.less'
const RANK_ICON = {
1: '//yun.duiba.com.cn/taobaomini/pike_call/icon_06.png',
2: '//yun.duiba.com.cn/taobaomini/pike_call/icon_07.png',
3: '//yun.duiba.com.cn/taobaomini/pike_call/icon_08.png'
}
const RankList = memo((props) => {
const { rankList = RANK_LIST, rankIcon = RANK_ICON } = 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 && (
<Image className={styles['rank-icon']} src={rankIcon[i + 1]} />
)}
<View className={styles['rank-num']}>{itm.rank}</View>
</View>
<View className={styles['scroll-item__user']}>{itm.userNick}</View>
<View className={styles['scroll-item__score']}>
{itm.rankValue}
</View>
</View>
)
})}
</ScrollView>
)
})
export default RankList
import React, { memo } from 'react'
import { View } from '@tarojs/components'
import styles from './RankTitle.module.less'
const RankTitle = memo((props) => {
const {
titleList = ['排名', '用户名', '人气值'],
myRank = { rank: '11', userNick: '用户名', rankValue: '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.rankValue}</View>
</View>
</View>
)
})
export default RankTitle
.rank-box {
.wh(100%,168px);
}
.rank-box__title {
.wh(100%,102px);
.flex-row-space();
.image('//yun.duiba.com.cn/taobaomini/pike_call/rank_title_bg.png');
}
.rank-box__info {
.wh(100%,66px);
.flex-row-space();
background: linear-gradient(-90deg, #FFDE8B 0%, #FFEAB5 100%);
}
.box-itm {
height: 66px;
width: 33%;
.flex-row-center();
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.box-itm:first-child {
font-size: 30px;
font-family: YouSheBiaoTiHei;
font-weight: 600;
color: #2D2B28;
}
.box-itm:nth-child(2) {
width: 34%;
font-size: 26px;
font-family: SourceHanSansCN;
font-weight: 400;
color: #666666;
}
.box-itm:last-child {
font-size: 28px;
font-family: WorkSans;
font-weight: 600;
color: #2D2B28;
}
\ No newline at end of file
import { RankList, RankTitle } from '..'
const Demo = () => {
return (
<>
<RankTitle />
<RankList />
</>
)
}
export default Demo
export { default as RankList } from './RankList/RankList'
export { default as RankTitle } from './RankTitle/RankTitle'
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: '//yun.duiba.com.cn/taobaomini/pike_call/icon_06.png',
2: '//yun.duiba.com.cn/taobaomini/pike_call/icon_07.png',
3: '//yun.duiba.com.cn/taobaomini/pike_call/icon_08.png'
}
function RankList(props) {
const { rankList = RANK_LIST, minNum = 2 } = 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 <= minNum && <Image className={styles['rank-icon']} src={RANK_ICON[i+1]} />}
<View className={styles['rank-num']}>{itm.rank}</View>
</View>
<View className={styles['scroll-item__user']}>{itm.userNick}</View>
<View className={styles['scroll-item__score']}>{itm.rankValue}</View>
</View>
)
})
}
</ScrollView>
)
}
export default RankList
\ 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
......@@ -3,7 +3,7 @@ import {View,Image,Text} from '@tarojs/components'
import styles from './RotateWheel.module.less'
import {useThrottle} from '@/hooks/useThrottle'
import API from '@/api'
import { prizeList } from '@/const'
import { prizeList } from '@/mock'
import Taro,{showToast,redirectTo,navigateTo} from '@tarojs/taro'
const oneTurn = 360;
......
import React, { useState } from 'react'
import { View, Image, ScrollView } from '@tarojs/components'
import classnames from 'classnames'
import styles from './GoodsTitle.module.less'
import styles from './TitleImg.module.less'
function GoodsTitle(props) {
function TitleImg(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 className={styles['title-box']}>
<Image src={config.image} mode="widthFix" style={{width: config.width / 100 + 'rem', height: config.height / 100 + 'rem' }} />
</View>
)
}
export default GoodsTitle
\ No newline at end of file
export default TitleImg
\ No newline at end of file
.title-box {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
\ No newline at end of file
/**
* 全局配置
*/
import React from 'react'
export const BtnTexts = {
UNREACH: '',
REACH_UNRECEIVED: '',
REACH_RECEIVED: ''
}
export const ProgressGlobalConfig = {
type: 1,
maxLevel: 15,
width: 500,
BtnTexts
}
export const ProgressContext = React.createContext()
import { View, Image } from '@tarojs/components'
import { memo, useContext, useMemo } from 'react'
import classnames from 'classnames'
import { ProgressContext } from '../ProgressContext'
// css
import styles from './index.module.less'
const ProgressNode = memo(props => {
const {
descInfo,
iconInfo,
isReceived = false,
isReach,
levelValue,
levelPos,
id
} = props
const {
BtnTexts,
maxLevel,
nodeClassName,
iconImgClassName,
iconTxtClassName,
iconClassName,
descClassName,
btnClassName,
activeBtnClassName,
disableBtnClassName,
onReceviceClick
} = useMemo(() => useContext(ProgressContext), ProgressContext)
// 节点按钮点击
const btnClick = () => {
return isReach && !isReceived ? onReceviceClick(id) : null
}
// 判断方法
const checkFunc = fn => {
return typeof fn === 'function'
}
// 判断对象是否为空
const checkObject = obj => {
return obj instanceof Object && JSON.stringify(obj) !== '{}'
}
const getNodeStyle = classnames(styles['defualt-progress-node'], {
[nodeClassName]: nodeClassName
})
const getDescStyle = classnames(styles['defualt-progress-node-desc'], {
[descInfo?.className]: descInfo?.className,
[descClassName]: descClassName
})
const getIconStyle = classnames(styles['defualt-progress-node-icon'], {
[iconInfo?.className]: iconInfo?.className,
[iconClassName]: iconClassName
})
const getIconImgStyle = classnames(
styles['defualt-progress-node-icon-iconImg'],
{
[iconImgClassName]: iconImgClassName
}
)
const getIconTxtStyle = classnames(styles['defualt-progress-node-icon-txt'], {
[iconTxtClassName]: iconTxtClassName
})
const getBtnStyle = classnames(styles['defualt-progress-node-btn-txt'], {
[btnClassName]: !isReach && btnClassName,
[activeBtnClassName]: isReach && !isReceived && activeBtnClassName,
[disableBtnClassName]: isReach && isReceived && disableBtnClassName
})
return (
<View
className={getNodeStyle}
style={{
left: levelPos ? levelPos : (levelValue / maxLevel) * 100 + '%'
}}
>
{/* 描述 */}
{checkObject(descInfo) && (
<View className={getDescStyle}>{descInfo.descTxt}</View>
)}
{/* icon */}
{checkObject(iconInfo) && (
<View className={getIconStyle}>
{iconInfo?.iconUrl && (
<Image className={getIconImgStyle} src={iconInfo.iconUrl} />
)}
{iconInfo?.iconTxt && (
<View className={getIconTxtStyle}>{iconInfo.iconTxt}</View>
)}
</View>
)}
{/* 节点按钮 */}
{checkFunc(onReceviceClick) && (
<View className={getBtnStyle} onTap={btnClick}>
{isReach
? isReceived
? BtnTexts.REACH_RECEIVED
: BtnTexts.REACH_UNRECEIVED
: BtnTexts.UNREACH}
</View>
)}
</View>
)
})
export default ProgressNode
.defualt-progress-node {
display: flex;
flex-direction: column;
position: absolute;
z-index: 10;
font-size: 20px;
transform: translate(-100%, -100%);
white-space: nowrap;
}
// 描述
.defualt-progress-node-desc {
position: absolute;
right: -110px;
top: -54px;
z-index: 11;
}
// Icon
.defualt-progress-node-icon {
.wh(32px, 32px);
}
// Icon贴图
.defualt-progress-node-icon-iconImg {
.wh(155px, 151px);
position: absolute;
top: -54px;
}
// Icon文本
.defualt-progress-node-icon-txt {
font-size: 22px;
}
// 按钮
.defualt-progress-node-btn-txt {
position: absolute;
top: 80px;
left: 6px;
}
# 进度条组件
---
## 何时使用
- 当某个页面需要展示累计邀请、分等级奖励进度条、累计签到等。
## 目录结构
`ProgressContext` 进度条全局默认配置
`ProgressNode` 进度条节点
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| levelList | 节点数据 | ArrayObject | 见下面示例一 | |
| currentValue | 当前进度值 | Numbver | 0 | |
| className | 进度条节点组样式 | Object | - | |
| maxLevel | 最大值 | Number | 15 | |
| width | 进度条长度 | Number | 500 | |
| BtnTexts | 进度按钮状态文本 | Object | {UNREACH: '待解锁',REACH_UNRECEIVED: '已解锁',REACH_RECEIVED: '已领取'} | |
| onReceviceClick | 点击进度按钮回调 | Function | (id)=>{} | |
| nodeClassName | 节点样式 | Object | - | |
| iconImgClassName | icon图片样式 | Object | - | |
| iconTxtClassName | icon文本样式 | Object | - | |
| descClassName | 描述样式 | Object | - | |
| btnClassName | 进度按钮样式 | Object | - | |
| activeBtnClassName | 进度按钮可点样式 | Object | - | |
| disableBtnClassName | 进度按钮不可用样式 | Object | - | |
## 示例一
```
[
{
id: 0, //节点id
levelValue: 0, //节点值
isReceived: true, //是否已领取
iconInfo: {
iconUrl: '//yun.dui88.com/tebuXinYuan/main-circle-tip.png',
iconTxt: ''
},
descInfo: {
descTxt: '等级1'
}
},
{
id: 1,
levelValue: 5,
isReceived: false,
iconInfo: {
iconUrl: '//yun.dui88.com/tebuXinYuan/main-circle-tip.png',
iconTxt: ''
},
descInfo: {
descTxt: '等级2'
}
}
]
```
import React, { useState } from 'react'
import { View } from '@tarojs/components'
import Progress from '../index'
import styles from './index.module.less'
const initLevelList = [
{
id: 0,
levelValue: 0,
isReceived: true,
iconInfo: {
iconUrl: '//yun.dui88.com/tebuXinYuan/main-circle-tip.png',
iconTxt: ''
},
descInfo: {
descTxt: '等级1'
}
},
{
id: 1,
levelValue: 5,
isReceived: false,
iconInfo: {
iconUrl: '//yun.dui88.com/tebuXinYuan/main-circle-tip.png',
iconTxt: ''
},
descInfo: {
descTxt: '等级2'
}
},
{
id: 2,
levelValue: 10,
isReceived: false,
iconInfo: {
iconUrl: '//yun.dui88.com/tebuXinYuan/main-circle-tip.png',
iconTxt: ''
},
descInfo: {
descTxt: '等级3'
}
},
{
id: 3,
levelValue: 15,
isReceived: false,
iconInfo: {
iconUrl: '//yun.dui88.com/tebuXinYuan/main-circle-tip.png',
iconTxt: ''
},
descInfo: {
descTxt: '等级4'
}
}
]
const Demo = props => {
const [levelList, setLevelList] = useState(initLevelList)
const [currentValue, setCurrentValue] = useState(10)
const onReceviceClick = id => {
console.log('点击:', id)
}
return (
<View className={styles['progress']}>
<Progress
levelList={levelList}
currentValue={currentValue}
btnClassName={styles['btnClassName']}
activeBtnClassName={styles['activeBtn']}
disableBtnClassName={styles['disableBtn']}
onReceviceClick={onReceviceClick}
/>
</View>
)
}
export default Demo
.progress {
margin-top: 100px;
display: flex;
justify-content: center;
}
.disableBtn {
.wh(108px, 42px);
.image('//yun.dui88.com/tebuXinYuan/main-received-btn.png');
}
.activeBtn {
.wh(108px, 42px);
.image('//yun.dui88.com/tebuXinYuan/main-waitReceive-btn.png');
}
.btnClassName {
.wh(108px, 42px);
.image('//yun.dui88.com/tebuXinYuan/main-waitUnlock-btn.png');
}
import { View } from '@tarojs/components'
import { memo, useMemo, useCallback } from 'react'
import classnames from 'classnames'
import ProgressNode from './ProgressNode'
import styles from './index.module.less'
import {
ProgressContext,
ProgressGlobalConfig
} from './ProgressContext'
const Progress = memo(props => {
const {
levelList = [],
currentValue = 0,
className,
maxLevel = ProgressGlobalConfig.maxLevel,
width = ProgressGlobalConfig.width
} = props
const LevelList = useMemo(() => {
return levelList
}, levelList)
// 合并全局配置
const mergeConfigToDefault = useCallback(config => {
return { ...ProgressGlobalConfig, ...config }
}, [])
/**
* 过滤props
* @param {*} props 过滤对象
* @param {*} filterPropArr 需要过滤掉的属性名称
* @returns
*/
const filterProps = (props, filterPropArr) => {
if (typeof props !== 'object' || !Array.isArray(filterPropArr)) {
throw new Error('参数格式不正确')
}
let obj = {}
Object.keys(props)
.filter(key => !filterPropArr.includes(key))
.map(key => {
obj[key] = props[key]
})
return obj
}
const getProgressStyle = classnames(styles['defualt-progress'], {
[className]: className
})
const getProItm = classnames(styles['progress-box-com'], {
[`${styles['progress-box-com-02']}`]: currentValue === maxLevel
})
return (
// 全局配置注入
<ProgressContext.Provider
value={mergeConfigToDefault(
filterProps(props, ['levelList', 'currentValue'])
)}
>
{/* 进度条-all */}
<View
className={styles['progress-box']}
style={{ width: width / 100 + 'rem' }}
>
{/* 进度条-current */}
<View
className={getProItm}
style={{
width:
currentValue >= maxLevel
? '100%'
: (currentValue / maxLevel) * 100 + '%'
}}
/>
{/* 进度条节点 */}
<View className={getProgressStyle}>
{LevelList.map((item, index) => {
return (
<ProgressNode
key={index}
{...item}
isReach={item.levelValue <= currentValue}
/>
)
})}
</View>
</View>
</ProgressContext.Provider>
)
})
export default Progress
.progress-box {
width: 692px;
height: 20px;
background: #371b15;
// border: 1px solid #371B15;
// box-shadow: 0px 0px 3px 0px #4D3328;
border-radius: 4px;
position: relative;
}
.defualt-progress {
}
.progress-box-com {
height: 20px;
background: linear-gradient(270deg, #ffde8b 0%, #ffce38 100%);
border-radius: 4px;
position: absolute;
top: 0;
left: 0;
transition: all 0.5s cubic-bezier(0, 0.64, 0.36, 1);
}
......@@ -3,7 +3,7 @@ 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 { BENEFIT_TYPE, PRIZE_TYPE } from '@/config/myPrize.config'
import { checkIsMember } from 'tbcc-sdk-ts/lib/utils'
import { commonToast, navigateToOutside } from 'tbcc-sdk-ts/lib/core/tb'
import { receiveEnamePrize, receiveObjectPrize, receiveMemberEname } from '@/utils/util'
......
......@@ -3,14 +3,15 @@ import React, { useState, useEffect, useRef } from 'react'
import { noopFn } from '@/utils/util'
import tbccTs from 'tbcc-sdk-ts'
import API from '@/api'
import config from '@/config/index'
import config from '@/config/config'
import { useThrottle } from '@/hooks/useThrottle'
import Popup from '@/components/_base/Popup/Popup'
import { TASK_STATUS, TASK_CONFIG, SHOP_ID, BROSE_GOOD_TYPE, ORDER_GOOD_TYPE } from '@/const'
import { SHOP_ID } 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'
import { TASK_CONFIG, ORDER_GOOD_TYPE, BROSE_GOOD_TYPE, TASK_STATUS } from '@/config/task.config'
const { commonToast, favorShop, navigateTo, navigateToOutside, showSharePanel, navigateToTaobaoPage } = tbccTs.tb
......@@ -22,7 +23,7 @@ export default function TasksModal(props) {
const preBrowseTime = useRef(null)
const [ taskList, setTaskList ] = useState(TASK_DATA)
const { taskIcon, commonTaskTxt, doTaskTxt, jumpLinkType, browseTime, showTaskType, browseGoodType, orderGoodType } = TASK_CONFIG
const { icons, commonTxt, doTxt, jumpType, browseTime, showTaskType, browseType, orderType } = TASK_CONFIG
useDidShow(() => {
if (app.isFlashTask) {
......@@ -41,7 +42,7 @@ export default function TasksModal(props) {
useEffect(() => {
if(showTaskType === 2 && taskFlag) {
fetchTaskList()
}else {
}else if(showTaskType === 1){
fetchTaskList()
}
},[taskFlag])
......@@ -51,7 +52,7 @@ export default function TasksModal(props) {
const { success, data } = await API.getTaskList({ isVip })
if(success && data) {
const { list = [] } = data
setTaskList(list)
// setTaskList(list)
}
}
......@@ -88,7 +89,7 @@ export default function TasksModal(props) {
// 跳转任务 https://www.feizhu.com
jumpLink: async() => {
navigateToOutside(url)
if (jumpLinkType === 2) {
if (jumpType === 2) {
doCompleteTaskHandle(taskType)
} else {
app.isFlashTask = true
......@@ -98,12 +99,12 @@ export default function TasksModal(props) {
},
browseGoods: async() => {
app.isFlashTask = true
if(browseGoodType === BROSE_GOOD_TYPE.PAGE) preBrowseTime.current = Date.now()
if(browseType === BROSE_GOOD_TYPE.PAGE) preBrowseTime.current = Date.now()
navigateTo(`/pages/packageGood/browseGoods/browseGoods?itemIds=${itemIds}&keepTime=${keepTime}`)
},
orderGoods: async() => {
app.isFlashTask = true
if(orderGoodType === ORDER_GOOD_TYPE.PAGE) {
if(orderType === ORDER_GOOD_TYPE.PAGE) {
navigateTo(`/pages/packageGood/orderGoods/orderGoods?itemIds=${itemIds}`)
}else {
await navigateToTaobaoPage(SHOP_ID)
......@@ -158,7 +159,7 @@ export default function TasksModal(props) {
return (
<View className={styles['item']} key={'task_I' + i}>
<View className={styles['item__left']}>
<Image src={taskIcon[item.taskType]} mode='widthFix' />
<Image src={icons[item.taskType]} mode='widthFix' />
</View>
<View className={styles['item__left-label']}>
<View className={styles['item__left-title']}>{item.title}</View>
......@@ -166,7 +167,7 @@ export default function TasksModal(props) {
</View>
<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]
item.status === TASK_STATUS.WAIT_DO ? (doTxt[item.taskType] || '去完成') : commonTxt[item.status]
}
</View>
</View>
......
export const BROWSE_CONFIG = {
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: {
img: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_img@2x.png'
},
color: '#181818',
countDown: ''
}
/*
浏览页倒计时标识
DEFAULT: 默认为空,不展示
PICTURE: loading进度条显示倒计时
NUMBER: 数字倒计时(15s)
*/
export const BROWSE_COUNTDOWN_OBJ = {
PICTURE:'PICTURE',
NUMBER:"NUMBER",
DEFAULT:""
}
\ No newline at end of file
export const CART_CONFIG = {
taskType: 'cartGoods',
type: 1, // 1 单个商品可重复完成 2 单个商品只可完成一次
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: {
collect: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_collection@2x.png',
no_collect: '//yun.duiba.com.cn/taobaomini/clientCTest/collection_no_collect@2x.png',
},
color: '#181818'
}
// 任务完成类型
export const CART_TYPE = {
ONE: 1, // 单个商品可重复完成
MORE: 2 // 单个商品只可完成一次
}
\ No newline at end of file
export default {
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: {
collect: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_collection@2x.png',
no_collect: '//yun.duiba.com.cn/taobaomini/clientCTest/collection_no_collect@2x.png'
},
color: '#181818'
}
\ No newline at end of file
export default {
env: 'test', // 云函数环境 test 测试环境 online 线上环境
requestType: 'cloud', // cloud: 云函数, yapi: yapi 接口, ams: ams接口,tornadoAPI: 风驰台接口
cloudName: 'pkrqdb', // 主云函数项目名 CommonToC
sellerId: '2207644377875',
tornadoAPI: 'https://tornado.duibadev.com.cn/tbServer/api?db=db3000000038851072&proxyIp=172.16.130.158', // 新增:当requestType: 'tornadoAPI'时,找服务端提供地址
defaultActivityId: '611cd5f78e6a08bf202eeb7e' // 默认活动id
}
\ No newline at end of file
export default {
env: 'test', // 云函数环境 test 测试环境 online 线上环境
requestType: 'yapi', // cloud: 云函数, yapi: yapi 接口, ams: ams接口,tornadoAPI: 风驰台接口
cloudName: 'CommonToC', // 主云函数项目名 CommonToC
sellerId: '2207644377875',
tornadoAPI: 'https://tornado.duibadev.com.cn/tbServer/api?db=db3000000038851072&proxyIp=172.16.130.158', // 新增:当requestType: 'tornadoAPI'时,找服务端提供地址
defaultActivityId: '60642aafc752d118247c2a2d' // 默认活动id
}
\ No newline at end of file
// 领取奖品状态
export const DRAW_STATUS = {
// 待领取
WAITAWARD: 1,
// 处理中
PROCESSING: 2,
// 领取成功
SUCCESS: 3,
// 领取失败
FAIL: 4,
// 已过期
EXPIRED: 5,
// 重新领取
RETRY: 6
}
// 奖品类型
export const PRIZE_TYPE = {
ENAME: 1,
CREDITS: 2,
OBJECT: 3,
THANKS: 5
}
// 权益类型
export const BENEFIT_TYPE = {
ENAME: 1,// 普通权益
MEMBER: 2 // 会员权益
}
// 我的奖品配置
export const PRIZE_CONFIG = {
bg: '//yun.duiba.com.cn/aurora/assets/e13fab3165d3a6bb4cbe8827e8f0fd41084b0091.png', // 背景图
head: {
image: '//yun.dui88.com/duiba-components-c-myprizeprize_title.png',// 标题
width: 208,// 头部banner/title 宽度
height: 36,// 头部banner/title 高度
},
copyIcon: '//yun.dui88.com/duiba-components-c-myprizemyprize_copy_code.png', // 复制
receiveBtn: '//yun.duiba.com.cn/bestoreBox/prize_received.png', // 已领取 权益类奖品未配置 uesUrl使用
objectStatus: {
1: '//yun.dui88.com/duiba-components-c-myprizeto_address.png', // 填写地址(实物奖品)
3: '//yun.dui88.com/duiba-components-c-myprizelogistics.png', // 查看物流
},
enameStatus: {
1: '//yun.dui88.com/duiba-components-c-myprizeget_now.png', // 立即领取(除实物奖品外)
3: '//yun.duiba.com.cn/bestoreBox/prize_received.png', // 去使用(除实物奖品外)
},
orderStatus: {
1: '//yun.dui88.com/duiba-components-c-myprizeget_now.png', // 去支付(除实物奖品外)
3: '//yun.duiba.com.cn/bestoreBox/prize_received.png', // 已领取
},
commonStatus: {
6: '//yun.dui88.com/duiba-components-c-myprizeget_again.png', // 重新领取
5: '//yun.duiba.com.cn/spark/assets/914ba8643c8abb8d710a3126ec312aecf6c4daf0.png', // 已失效
4: '//yun.duiba.com.cn/spark/assets/8267375232058a6d0140270b1594427fb08d6ae3.png' // 领取失败
},
logisticsImage: {
shipped: '//yun.dui88.com/duiba-components-c-myprizeprize_shipped.png', // 已发货物理弹窗
notShipped: '//yun.dui88.com/duiba-components-c-myprizenotshipped.png' // 待发货物流弹窗
},
btnStyle: {
width: '150rpx'
},
contentTop: '208rpx',
blankTxt: '暂无奖品',
hasLogistic: false, // 是否展示物流信息
isShowPirzeId: false // 是否显示奖品编号
}
\ No newline at end of file
export default {
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: {
img: '//yun.duiba.com.cn/taobaomini/clientCTest/goods_img@2x.png'
},
color: '#181818'
}
\ No newline at end of file
// 任务状态
export const TASK_STATUS = {
WAIT_DO: 1, // 未完成
WAIT_RECEIVE: 2, // 待领取
DONE: 3 // 已完成
}
// 任务频率类型常量
export const TASK_RATE_TYPE = {
FOREVER: 1,
EVERYDAY: 2,
NOLIMIT: 3
}
// 浏览商品类型
export const BROSE_GOOD_TYPE = {
PAGE: 1, // 浏览集合页15s
CLICK: 2, // 点击就算完成任务
DETAIL: 3 // 浏览指定商品详情页15s
}
// 购买商品类型
export const ORDER_GOOD_TYPE = {
PAGE: 1, // 集合页下单
SHOP: 2, // 跳转店铺
}
export const TASK_CONFIG = {
icons: { // 任务图标
follow: '//yun.duiba.com.cn/baicaoweiFarmer/follow.png',
member: '//yun.duiba.com.cn/baicaoweiFarmer/memberStar1.png',
invites: '//yun.duiba.com.cn/baicaoweiFarmer/invites.png',
jumpLink: '//yun.duiba.com.cn/baicaoweiFarmer/browseGoodsLink.png',
browseGoods: '//yun.duiba.com.cn/baicaoweiFarmer/browseGoods.png',
orderGoods: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png',
collectGoods: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png',
sign: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png',
exchangeCredits: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png'
},
commonTxt: {
1: '去完成',
2: '待领取',
3: '已完成'
},
doTxt: {
follow: '立即关注',
invites: '去邀请',
member: '1秒入会',
sign: '立即签到',
jumpLink: '去完成',
browseGoods: '去完成',
orderGoods: '去完成',
collectGoods: '去完成'
},
jumpType: 1, // 1 跳转浏览15s 才算完成 2 跳转即算完成
browseTime: 15, // 浏览时间
browseType: 1, // 1 浏览15s 才算完成 2 点击就算完成任务 3 浏览指定商品详情页 15s
showTaskType: 1,// 1 弹窗 2 列表
orderType: 1, // 1 集合页下单 2 跳转店铺
}
\ No newline at end of file
......@@ -4,48 +4,6 @@ export const SHARE_CONFIG = {
desc: '分享测试描述',
imageUrl: '' // 分享图片URL
}
// 领取奖品状态
export const DRAW_STATUS = {
// 待领取
WAITAWARD: 1,
// 处理中
PROCESSING: 2,
// 领取成功
SUCCESS: 3,
// 领取失败
FAIL: 4,
// 已过期
EXPIRED: 5,
// 重新领取
RETRY: 6
}
// 奖品类型
export const PRIZE_TYPE = {
ENAME: 1,
CREDITS: 2,
OBJECT: 3,
THANKS: 5
}
// 我的奖品状态
export const PRIZE_DRAW_STATUS_MAP = {
RECEIVE: 1, // 待领取
DEALING: 2, // 处理中
SUCCESS: 3, // 领取成功
FAILURE: 4, // 领取失败
FINISHED: 5, // 已过期
REPEAT: 6 // 重新领取
}
// 奖品类型
export const PRIZE_TYPE_MAP = {
EQUITY: 1, // 权益
INTEGRATION: 2, // 积分
ENTITY: 3, // 实物
THANKS: 5 // 谢谢参与
}
// 活动状态
export const ACTIVITY_STATUS = {
NO_EXIST: 0, // 不存在
......@@ -53,70 +11,6 @@ export const ACTIVITY_STATUS = {
NO_START: 2, // 未开始
END: 3 // 已经结束
}
// 任务频率类型常量
export const TASK_RATE_TYPE = {
FOREVER: 1,
EVERYDAY: 2,
NOLIMIT: 3
}
// 任务状态
export const TASK_STATUS = {
WAIT_DO: 1, // 未完成
WAIT_RECEIVE: 2, // 待领取
DONE: 3 // 已完成
}
export const TASK_CONFIG = {
taskIcon: { // 任务图标
follow: '//yun.duiba.com.cn/baicaoweiFarmer/follow.png',
member: '//yun.duiba.com.cn/baicaoweiFarmer/memberStar1.png',
invites: '//yun.duiba.com.cn/baicaoweiFarmer/invites.png',
jumpLink: '//yun.duiba.com.cn/baicaoweiFarmer/browseGoodsLink.png',
browseGoods: '//yun.duiba.com.cn/baicaoweiFarmer/browseGoods.png',
orderGoods: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png',
collectGoods: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png',
sign: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png',
exchangeCredits: '//yun.duiba.com.cn/baicaoweiFarmer/orderGoods.png'
},
commonTaskTxt: {
1: '去完成',
2: '待领取',
3: '已完成'
},
doTaskTxt: {
follow: '立即关注',
invites: '去邀请',
member: '1秒入会',
sign: '立即签到',
jumpLink: '去完成',
browseGoods: '去完成',
orderGoods: '去完成',
collectGoods: '去完成'
},
jumpLinkType: 1, // 1 跳转浏览15s 才算完成 2 跳转即算完成
browseTime: 15, // 浏览时间
browseGoodType: 1, // 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'
......
......@@ -4,7 +4,6 @@
import React, { useState, useEffect } from "react";
import { playBgMusic1 } from "@/utils/audio";
const app = getApp();
/**
* @description 一个页面不能同时create两个音频文件
* @param {*} url cloud文件链接
......@@ -52,5 +51,3 @@
musicUrl
};
};
......@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
import { useRouter } from '@tarojs/taro'
import { useLoginInfoModel } from '../store/loginInfo'
import API from '../api'
import config from '@/config/index'
import config from '@/config/config'
import { useAuth } from './useAuth'
import { noopFn } from '@/utils/util'
import { checkShopFavoredStatus } from 'tbcc-sdk-ts/lib/core/tb'
......
This diff is collapsed.
import React, { useRef, useState } from 'react'
import { View, Image } from '@tarojs/components'
import Taro, { useShareAppMessage, useDidShow } from '@tarojs/taro'
import Taro, { useShareAppMessage, useDidShow, getApp } from '@tarojs/taro'
import classnames from 'classnames'
import { SHARE_CONFIG, HELP_MODAL_TYPE, HELP_MODAL_SHOW } from '@/const.js'
import { useLogin, useLoginFromShare } from '@/hooks/useLogin'
......@@ -17,7 +17,7 @@ const { navigateTo, openDetail, showSharePanel } = tbcc.tb
const { getImgShareUrl, checkIsMember, validateActivityStatus } = tbcc.utils
import {useAudio} from '@/hooks/useAudio'
import {CLOUD_OBJ, BGMUSIC_URL, prizeList} from '@/const'
import {CLOUD_OBJ, BGMUSIC_URL} from '@/const'
import ScrollXView from '@/components/_tb_comps/ScrollXView/ScrollXView'
......@@ -78,10 +78,8 @@ const swiper_config = {
textContent:{width:300,height:60}
}
function Index() {
const app = getApp()
const { activityInfo, setActivityInfoAndStatus } = useActivityInfoModel()
const { loginInfo } = useLoginInfoModel()
......@@ -128,12 +126,10 @@ function Index() {
// })
},[])
// 授权登录完成
// useLogin(async (info) => {
// handleVisibleModal(info)
// fetchUserInfo()
// setUpdateFlag(1)
// getShareInfo()
// })
useLogin(async (info) => {
handleVisibleModal(info)
// setUpdateFlag(1)
})
// 查看是否有助力信息
const getShareInfo = async () => {
const { success, data } = await API.getShareInfo()
......@@ -178,16 +174,6 @@ function Index() {
setMemberVisible(false)
}
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) {
......@@ -213,7 +199,7 @@ function Index() {
}
return (
<View className={homeStyle}>
<View className={styles.container} style={{ backgroundImage: `url(${INDEX_CONFIG.bg})`}}>
<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>
......@@ -273,7 +259,7 @@ function Index() {
onClose={() => setDoHelpModalVisible(false)}
/>
}
{memberVisible && <member-modal onClose={onClose} onAuthFail={onAuthFail} onAuthSuccess={onAuthSuccess} />}
{<member-modal expend={memberVisible} sellerId={98563612} onClose={onClose} onAuthFail={onAuthFail} onAuthSuccess={onAuthSuccess} />}
</View>
)
}
......
......@@ -10,9 +10,6 @@
bottom: 0;
background-image: linear-gradient(45deg,#fbc2eb 10%, #a6c1ee);
}
.content_fixed {
position: fixed;
}
.index_button() {
.wh(150px, 46px);
.border(#000);
......
import React, { useEffect, useState, useRef } from 'react'
import { View, Canvas } from '@tarojs/components'
import { useDidShow, useRouter, useDidHide } from '@tarojs/taro'
import { View } from '@tarojs/components'
import { useDidShow, useRouter, useDidHide, getApp } from '@tarojs/taro'
import API from '@/api'
import { TASK_CONFIG } from '@/const'
import { useLogin, useLoginFromShare } from '@/hooks/useLogin'
import { useActivityInfoModel, useLoginInfoModel } from '@/store'
import {
......@@ -18,10 +17,12 @@ import { versionCompare, getImgShareUrl } from 'tbcc-sdk-ts/lib/utils'
import styles from './game.module.less'
function GamePage(props) {
const app = getApp()
const { activityInfo, setActivityInfoAndStatus } = useActivityInfoModel()
const { loginInfo } = useLoginInfoModel()
const [canvasData,setCanvasData] = useState({})
const [ taskModalVisible, setTaskModalVisible] = useState(false)
const [ canvasVisible, setCanvasVisible] = useState(false)
const [ memberVisible,setMemberVisible] = useState(false)
const [updateFlag, setUpdateFlag] = useState(1)
const compRef = useRef(null)
......@@ -31,31 +32,24 @@ function GamePage(props) {
// console.log(res)
// })
},[])
useDidShow(() =>{
// canvasMain.run();
})
useDidHide(() =>{
// canvasMain.pause();
})
useDidShow(() =>{})
useDidHide(() =>{})
//检查版本号
const checkSystem = async () => {
const { version } = await getSystemInfo();
console.log('version', version);
return versionCompare(version, '9.10.0');
}
const getAuth = () => {
console.log('getAuth')
}
const getUserAddress = () => {
}
const doFavorShop = () => {
console.log('doFavorShop')
}
// 授权后登录
useLogin(res => {
// 登录完成渲染cavans
setCanvasVisible(true)
})
//和main通信的方法,接收main的信息
const onMessage = (e)=> {
// 接口名字 参数
const { netName, parameter } = e.mpEvent.data
console.warn('netName:'+netName,parameter)
//定制的授权
if (netName == "mine.authorize") {
this.getAuth()
......@@ -78,27 +72,29 @@ function GamePage(props) {
}
//前端同步接口
else if (netName.indexOf("mine") == 0) {
var data = { success: true }
let data = { success: true, type: netName }
switch (netName) {
case "mine.getAppData"://获取信息
const { userNick, avatar, openId, newUser, remainTimes, firstLoginToday } = loginInfo
data = {
success: true,
type: netName,
data: {
activityId: app.activityId,//|| "5e7c40e98564b57d7fb95812",
nickName: app.nickName,
avatar: app.avatar,
openId: app.openId,
inviteId: this.inviteId,//判断是否要发助力用
nickName: userNick,
avatar,
openId,
inviteId: app.inviteId,//判断是否要发助力用
isFollow: app.isFollow,
needDataInCanvas:app.needDataInCanvas,
activityInfo:this.activityInfo,
userInfo:this.userInfo,
newUser: this.newUser,
remainTimes: this.remainTimes,
firstLoginToday: this.firstLoginToday,
needDataInCanvas: {},
activityInfo: activityInfo,
userInfo: {},
newUser: newUser,
remainTimes: remainTimes,
firstLoginToday: firstLoginToday
}
}
console.warn(data)
break;
case "mine.navigateToOutside"://跳转小程序外的页面
navigateToOutside(parameter.url)
......@@ -128,6 +124,9 @@ function GamePage(props) {
setMemberVisible(true)
break;
}
// commonToast(JSON.stringify(data))
setUpdateFlag(Math.floor(Math.random() * 1000))
setCanvasData(data)
} else {
//获取后端接口
const { function: fc } = app.cloud;
......@@ -146,16 +145,9 @@ function GamePage(props) {
})
}
}
const postMessageEvent = () => {
console.log('222222')
}
const onClose = () => {
console.warn(1111)
setMemberVisible(false)
}
const onAuthSuccess = () => {
setMemberVisible(false)
}
......@@ -164,10 +156,11 @@ function GamePage(props) {
}
const onTestHandle = () => {
setMemberVisible(true)
// onMessage({mpEvent: { data: { netName: 'mine.getAppData' }}})
}
return(
<View>
{ true && <canvas-comp canvasData={canvasData} onPostMessage={onMessage} updateFlag={updateFlag} />}
{ canvasVisible && <canvas-comp data={canvasData} onMessage={onMessage} updateFlag={updateFlag} />}
<View className={styles['test-box']} onClick={(e) => onTestHandle(e)}>入会按钮</View>
{memberVisible && <member-modal onClose={onClose} onAuthFail={onAuthFail} onAuthSuccess={onAuthSuccess} />}
</View>
......
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
.wh(750px,208px);
}
.page-content__list {
position: absolute;
top: 140px;
top: 208px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
......
import React, { useState, useEffect, useRef } from 'react'
import { View } from '@tarojs/components'
import GoodsTitle from '@/components/_tb_comps/GoodsTitle/GoodsTitle'
import ContainerFit from '@/components/_base/ContainerFit/ContainerFit'
import TitleImg from '@/components/_tb_comps/TitleImg/TitleImg'
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'
import { CART_CONFIG, CART_TYPE } from '@/config/cart.config'
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([])
......@@ -47,38 +30,33 @@ function CartGoodsPage() {
// 加入购物车 // 对应itemId为 574141925233 skuId为4018047819826 数量为4
const onCompleteTask = useThrottle(async (itemId, collected) => {
console.log(itemId)
if (collected) {
if (collected && CART_CONFIG.type === CART_TYPE.ONE) {
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 {
if(collectflag.current && CART_CONFIG.type === CART_TYPE.ONE) {
commonToast('该任务今天已完成,明天再来吧~')
}
const { status, quantity } = await showSkuModal(String(itemId))
if (status == "addCartSuccess") {
const { success } = await API.doCompleteTask({ taskType: CART_CONFIG.taskType, itemId, count: quantity })
if (success) {
collectflag.current = true
getGoodsList()
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>
<ContainerFit bg={CART_CONFIG.bg}>
<View className={styles['page-content__title']}>
<TitleImg config={CART_CONFIG.head}/>
</View>
<View className={styles['page-content__list']}>
<GoodsList goodsList={goodsList} task={CART_CONFIG} onOpenDetail={(itemId,collected) => onCompleteTask(itemId,collected)} />
</View>
</View>
</ContainerFit>
)
}
......
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
.wh(750px,208px);
}
.page-content__list {
position: absolute;
top: 140px;
top: 208px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
......
import React, { useState, useEffect, useRef } from 'react'
import { View } from '@tarojs/components'
import GoodsTitle from '@/components/_tb_comps/GoodsTitle/GoodsTitle'
import ContainerFit from '@/components/_base/ContainerFit/ContainerFit'
import TitleImg from '@/components/_tb_comps/TitleImg/TitleImg'
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 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: {
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'
}
import COLLECT_CONFIG from '@/config/collect.config'
function CollectGoodsPage() {
const router = useRouter()
......@@ -77,18 +59,14 @@ function CollectGoodsPage() {
})
return (
<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>
<ContainerFit bg={COLLECT_CONFIG.bg}>
<View className={styles['page-content__title']}>
<TitleImg config={COLLECT_CONFIG.head}/>
</View>
<View className={styles['page-content__list']}>
<GoodsList goodsList={goodsList} task={COLLECT_CONFIG} onOpenDetail={(itemId,collected) => onCompleteTask(itemId,collected)} />
</View>
</View>
</ContainerFit>
)
}
......
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
.wh(750px,208px);
}
.page-content__list {
position: absolute;
top: 140px;
top: 208px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
......
import React, { useEffect, useState } from 'react'
import { View } from '@tarojs/components'
import GoodsTitle from '@/components/_tb_comps/GoodsTitle/GoodsTitle'
import ContainerFit from '@/components/_base/ContainerFit/ContainerFit'
import TitleImg from '@/components/_tb_comps/TitleImg/TitleImg'
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 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: {
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'
}
import ORDER_CONFIG from '@/config/order.config'
function OrderGoodsPage() {
const router = useRouter()
......@@ -32,18 +15,15 @@ function OrderGoodsPage() {
const { data } = useRequest(API.getItemListByItemIds, { itemIds })
return (
<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>
<ContainerFit bg={ORDER_CONFIG.bg}>
<View className={styles['page-content__title']}>
<TitleImg config={ORDER_CONFIG.head}/>
</View>
</View>
<View className={styles['page-content__list']}>
<GoodsList goodsList={data?.list || []} task={ORDER_CONFIG} onOpenDetail={(itemId,isBrowsed) => onOpenDetail(itemId,isBrowsed)} />
</View>
</ContainerFit>
)
}
......
.page-container {
.page-container();
}
.page-psd-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.page-content__title {
.wh(750px,140px);
.wh(750px,208px);
}
.page-content__list {
position: absolute;
top: 140px;
top: 208px;
left: 0;
bottom: 0;
padding: 41px 25px 0;
......
.page-container {
.page-container();
}
.my-prize-container {
.page-container__1624();
}
.page-content {
.page-content();
}
.my-prize-container .my-prize-label {
width: 208px;
height: 36px;
margin: 70px auto 40px;
background: url("//yun.duiba.com.cn/duiba-components-c-myprizeprize_title.png")
no-repeat;
background-size: 100% 100%;
.my-prize-label {
width: 100%;
height: 208px;
}
.my-prize-content {
position: absolute;
left: 0;
......@@ -29,19 +14,16 @@
height: 100%;
padding-top: 30px;
}
.my-prize-container .my-prize-list {
.my-prize-list {
width: 100%;
height: auto;
}
.my-prize-container .my-prize-item__empty {
.my-prize-item__empty {
text-align: center;
color: #fff;
margin-top: 30px;
}
.my-prize-list .my-prize-item {
.my-prize-item {
display: flex;
justify-content: center;
align-items: center;
......@@ -56,13 +38,11 @@
border-radius: 10px;
box-sizing: border-box;
}
.my-prize-list .my-prize-item .my-prize-item__avatar {
.my-prize-item__avatar {
width: 120px;
height: 120px;
}
.my-prize-list .my-prize-item .my-prize-item__content {
.my-prize-item__content {
flex: 1;
min-width: 0;
padding: 0 20px;
......@@ -72,28 +52,23 @@
align-items: flex-start;
justify-content: center;
}
.my-prize-list .my-prize-item .my-prize-item__subtitle {
.my-prize-item__subtitle {
display: flex;
justify-content: center;
align-items: center;
}
.my-prize-list .my-prize-item .my-prize-item__copy {
.my-prize-item__copy {
width: 20px;
height: 20px;
margin-left: 18px;
}
.my-prize-list .my-prize-item .prize-item__status {
.prize-item__status {
width: 150px;
}
.prize-item__status > image {
width: 100%;
}
.my-prize-list .my-prize-item .my-prize-item__name {
.my-prize-item__name {
width: 100%;
font-size: 28px;
color: #2d2d2d;
......@@ -102,16 +77,14 @@
text-overflow: ellipsis;
white-space: nowrap;
}
.my-prize-list .my-prize-item .my-prize-item__tip {
.my-prize-item__tip {
margin-top: 8px;
font-size: 20px;
line-height: 20px;
letter-spacing: 0;
color: #8a8a8a;
}
.my-prize-list .my-prize-item .my-prize-item__code {
.my-prize-item__code {
width: 290px;
font-family: PingFangSC-Regular;
font-size: 20px;
......
import React, { useEffect, useState, useRef } from 'react'
import { View } from '@tarojs/components'
import { useDidShow, useRouter, useDidHide, getApp } from '@tarojs/taro'
import API from '@/api'
import { useLogin, useLoginFromShare } from '@/hooks/useLogin'
import { useActivityInfoModel, useLoginInfoModel } from '@/store'
import {useAudio} from '@/hooks/useAudio'
import {CLOUD_OBJ, BGMUSIC_URL} from '@/const'
import ScrollXView from '@/components/_tb_comps/ScrollXView/ScrollXView'
import SwiperView from '@/components/_tb_comps/SwiperView/SwiperView'
import RotateWheel from '@/components/_tb_comps/RotateWheel/RotateWheel'
export default function PreComp(props) {
return(
<View>
</View>
)
}
\ No newline at end of file
import { useState } from 'react'
import { createModel } from 'hox'
function useUserInfo() {
const [ activityInfo, setUserInfo ] = useState({
success: false,
gameTimes: 0
})
return {
activityInfo,
setUserInfo
}
}
export const useUserInfoModel = createModel(useUserInfo)
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