Commit d1e8a6d2 authored by wildfirecode13's avatar wildfirecode13

1111

parent 77492704
No preview for this file type
.DS_Store
node_modules/
\ No newline at end of file
const g = typeof global !== 'undefined' ? global : self;
g.appXAppJson = {
"app": {
"$homepage": "pages/index/index"
}
};
if(!self.Map || !self.Set || !self.Symbol) {
importScripts('https://gw.alipayobjects.com/as/g/appx_release/deps/1.0.3/es6-set-map-symbol.js');
}
\ No newline at end of file
require('@alipay/appx-compiler/lib/sjsEnvInit');
require('./config$');
require('../../components/ruleModal/ruleModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/commonModal/commonModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/endModal/endModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/logisticsModal/logisticsModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/prizeModal/prizeModal?hash=951cb6a7fcdd2a5332763295aa08b4f86b6fd2e1');
require('../../components/countDownModal/countDownModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/goodsModal/goodsModal?hash=96e16713cabf2568fcec05d01c8320620028d753');
require('../../pages/index/index?hash=75647a1ca05d716635459948f3761269d2180614');
require('../../pages/testPage/testPage?hash=32d7d2807ed4e666ef03b4b3fe8c38ecf2e34e68');
require('../../pages/tbccDemo/tbccDemo?hash=32d7d2807ed4e666ef03b4b3fe8c38ecf2e34e68');
require('../../pages/myprize/myprize?hash=74b7edb09b315961bb13059a83b72836912bfd2c');
require('../../pages/goodsPage/goodsPage?hash=c0b344ca1a847391fd4718c95c20dbe608f22e78');
if(!self.__appxInited) {
self.__appxInited = 1;
require('./config$');
var AFAppX = self.AFAppX.getAppContext
? self.AFAppX.getAppContext().AFAppX
: self.AFAppX;
self.getCurrentPages = AFAppX.getCurrentPages;
self.getApp = AFAppX.getApp;
self.Page = AFAppX.Page;
self.App = AFAppX.App;
self.my = AFAppX.bridge || AFAppX.abridge;
self.abridge = self.my;
self.Component = AFAppX.WorkerComponent || function(){};
self.$global = AFAppX.$global;
self.requirePlugin = AFAppX.requirePlugin;
if(AFAppX.registerApp) {
AFAppX.registerApp({
appJSON: appXAppJson,
});
}
function success() {
require('../../app');
require('../../components/ruleModal/ruleModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/commonModal/commonModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/endModal/endModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/logisticsModal/logisticsModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/prizeModal/prizeModal?hash=951cb6a7fcdd2a5332763295aa08b4f86b6fd2e1');
require('../../components/countDownModal/countDownModal?hash=05d2a9730dd6009bf9446182f9c985f40f8c0f43');
require('../../components/goodsModal/goodsModal?hash=96e16713cabf2568fcec05d01c8320620028d753');
require('../../pages/index/index?hash=75647a1ca05d716635459948f3761269d2180614');
require('../../pages/testPage/testPage?hash=32d7d2807ed4e666ef03b4b3fe8c38ecf2e34e68');
require('../../pages/tbccDemo/tbccDemo?hash=32d7d2807ed4e666ef03b4b3fe8c38ecf2e34e68');
require('../../pages/myprize/myprize?hash=74b7edb09b315961bb13059a83b72836912bfd2c');
require('../../pages/goodsPage/goodsPage?hash=c0b344ca1a847391fd4718c95c20dbe608f22e78');
}
self.bootstrapApp ? self.bootstrapApp({ success }) : success();
}
\ No newline at end of file
const app = getApp();
const { tbcc, cloudName, cloud, requestType } = app;
const { utils: { generateAPI }, request: tbccRequest, capi } = tbcc;
const request = tbccRequest({
cloud,
cloudName,
requestType
});
// api handle 列表
const apiList = {
...capi,
getIndex: {
handle: 'index',
isShowLoading: true
},
login: 'login'
};
// 生成API
const API = generateAPI(apiList, request);
export default API;
page {
background: #f7f7f7;
font-family: 'Helvetica Neue', Helvetica, Hiragino Sans GB, 'Microsoft Yahei', STHeiTi, Arial, sans-serif;
}
* {
box-sizing: border-box;
}
.d-flex {
display: flex
}
.d-flex__item {
flex: 1;
}
.d-flex--aligncenter {
align-items: center;
}
.modal-animate-fade-in {
opacity: 0;
animation: modalAnimateFadeIn .3s forwards;
}
.modal-animate-zoom-in {
transform: scale(0);
animation: modalAnimateZoomIn .3s forwards;
}
.modal-animate-fly-in {
transform: translateY(100%);
animation: modalAnimateFlyIn .3s forwards;
}
.btn-animate-pulse {
animation: btnAnimatePulse .8s infinite;
}
@keyframes modalAnimateFadeIn {
to {
opacity: 1;
}
}
@keyframes modalAnimateZoomIn {
to {
transform: scale(1);
}
}
@keyframes modalAnimateFlyIn {
to {
transform: translateY(0);
}
}
@keyframes btnAnimatePulse {
from {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
to {
transform: scale(1);
}
}
\ No newline at end of file
import cloud from '@tbmp/mp-cloud-sdk';
import tbcc from './tbcc-sdk';
cloud.init({
env: 'test' // 云函数环境 test 测试环境 online 线上环境
});
App({
requestType: 'cloud', // ams:ams接口,cloud: 云函数
cloudName: 'skechRun', // 主云函数项目名 base clientTemplate2C
cloud,
tbcc,
onLaunch(options) {
this.handleQuery(options.query || {});
},
onShow(options) {
// 从后台被 scheme 重新打开
console.log('执行了app onshow')
},
/**
* 处理链接参数
* @param {object} query 小程序链接上的参数
*/
handleQuery(query) {
const { activityId } = query;
this.activityId = activityId || '5f4605629897b44ce119d8f1';
}
});
{
"pages": [
"pages/index/index",
"pages/testPage/testPage",
"pages/tbccDemo/tbccDemo",
"pages/myprize/myprize",
"pages/goodsPage/goodsPage"
],
"window": {
"defaultTitle": "C端模板"
}
}
### 注意!
assets文件夹只做本地开发测试使用
因为淘宝打包有体积限制,最大不超过1M,所以打包提审请同步图片等资源到CDN上,然后删除assets文件夹再打包提审。
\ No newline at end of file
.common-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 20;
}
.common-modal__shade {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.75);
}
.common-modal__container {
position: absolute;
width: 500rpx;
height: 300rpx;
background: #4eafd7;
background-size: 100% 100%;
left: 50%;
top: 50%;
margin-left: -250rpx;
margin-top: -150rpx;
padding: 30rpx;
}
.common-modal__bd {
font-size: 28rpx;
text-align: center;
color: #fff;
padding: 50rpx 0;
}
.common-modal__close {
position: absolute;
right: -20rpx;
top: -80rpx;
height: 86rpx;
width: 86rpx;
background: url('../../assets/modal_close_btn.png') center center no-repeat;
background-size: 48rpx 48rpx;
z-index: 9;
}
.common-modal__confirm-btn {
margin: 0 auto;
text-align: center;
width: 341rpx;
height: 77rpx;
line-height: 77rpx;
background: #FFF;
background-size: 100% 100%;
font-size: 30rpx;
color: #0077a9;
font-weight: bold;
}
<view class="common-modal">
<view class="common-modal__shade modal-animate-fade-in" />
<view class="common-modal__container modal-animate-zoom-in">
<view class="common-modal__close" onTap="onModalClose" />
<view class="common-modal__bd">
<text>{{data.content}}</text>
</view>
<view class="common-modal__ft" a:if="{{data.btnText}}">
<view onTap="onModalConfirm" class="common-modal__confirm-btn">{{data.btnText}}</view>
</view>
</view>
</view>
Component({
methods: {
onModalClose() {
const { onModalClose } = this.props;
onModalClose && onModalClose();
},
onModalConfirm () {
const { onModalConfirm } = this.props;
onModalConfirm && onModalConfirm();
}
}
});
\ No newline at end of file
{
"component": true
}
\ No newline at end of file
.countdown {
position: fixed;
width: 144rpx;
height: 162rpx;
right: 0;
top: 600rpx;
}
.countdown-box-clock {
position: absolute;
top: 0;
left: 50%;
margin-left: -41rpx;
width: 82rpx;
height: 88rpx;
background-size: 100% 100%;
z-index: 10;
}
.countdown-box-clock__time {
position: absolute;
top: 5rpx;
left: 0;
width: 82rpx;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
}
.countdown-box-clock image {
width: 100%;
height: 100%;
}
.countdown-box {
position: absolute;
width: 130rpx;
height: 18rpx;
border-radius: 10rpx;
border: 1px solid #a6fffe;
background: #111192;
box-shadow: 0 0 4rpx 1rpx #7fd5ff;
top: 25rpx;
bottom: 20rpx;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
z-index: 11;
}
@keyframes countdownAnimation {
to {
transform: translateX(0);
}
}
.countdown-box .countdown-time {
height: 100%;
width: 100%;
background: linear-gradient(#3996f8, #19dffd);
}
.countdown-txt {
position: absolute;
width: 147rpx;
height: 91rpx;
bottom: 0rpx;
z-index: 1;
}
.countdown-txt image {
width: 100%;
height: 100%;
}
.countdown-txt__content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
line-height: 25rpx;
color: #2A2A2A;
text-align: center;
font-size: 20rpx;
}
.countdown-txt .txt:first-child{
margin-top: 25rpx;
}
.countdown-two {
position: absolute;
width: 554rpx;
height: 104rpx;
left: 50%;
margin-left: -277rpx;
bottom: 70rpx;
}
.countdown-two-clock {
position: absolute;
right: -10rpx;
bottom: 10rpx;
width: 104rpx;
height: 95rpx;
z-index: 15;
}
.countdown-two-clock image {
width: 100%;
height: 100%;
}
.countdown-two-clock .countdown-box-clock__time {
position: absolute;
top: 5rpx;
left: 0;
width: 104rpx;
height: 95rpx;
display: flex;
align-items: center;
justify-content: center;
}
.countdown-two-clock .countdown-box{
position: absolute;
left: 0;
bottom: -20rpx;
}
.countdown-two-txt {
position: absolute;
right: 90rpx;
top: 5rpx;
width: 323rpx;
height: 60rpx;
z-index: 14;
background: url('//yun.dui88.com/taobaomini/clientCTest/count_bg_02@2x.png');
background-size: 100% 100%;
color: #2A2A2A;
text-align: center;
font-size: 20rpx;
line-height: 60rpx;
}
.countdown-two-txt image {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 14;
}
.countdown-two__content {
position: absolute;
left: 0;
top: 0;
width: 323rpx;
height: 60rpx;
color: #2A2A2A;
text-align: center;
font-size: 20rpx;
}
\ No newline at end of file
<view class="countdown" a:if="{{styleType == '01'}}">
<view class="countdown-box-clock">
<image mode="scaleToFill" src="{{data.clock_bg}}"/>
<view class="countdown-box-clock__time" style="{{{'color':data.countTxtColor,'fontSize':data.countTxtSize+'rpx'}}}">{{countTime}}</view>
</view>
<view class="countdown-box" style="{{{'height':data.progressHeight+'rpx','width':data.progressWidth+'rpx'}}}">
<view class="countdown-time" style="transform: translateX({{percent*10 -100}}%);animation: countdownAnimation {{countTime-percent}}s forwards linear;"></view>
</view>
<view class="countdown-txt">
<image mode="scaleToFill" src="{{data.textBg}}"/>
<view class="countdown-txt__content">
<view class="txt">{{data.text.split('\n')[0]}}</view>
<view class="txt">{{data.text.split('\n')[1]}}</view>
</view>
</view>
</view>
<view class="countdown-two" a:else>
<view class="countdown-two-clock">
<image mode="scaleToFill" src="{{data.clock_bg}}"/>
<view class="countdown-box-clock__time" style="{{{'color':data.countTxtColor,'fontSize':42+'rpx'}}}">{{countTime}}</view>
</view>
<view class="countdown-box" style="{{{'height':55+'rpx','width':490+'rpx'}}}">
<view class="countdown-time" style="transform: translateX({{percent*10 -100}}%);animation: countdownAnimation {{countTime-percent}}s forwards linear;"></view>
</view>
<view class="countdown-two-txt" style="{{{'background':`url(${data.textBg}) no-repeat`,'backgroundSize': '100% 100%'}}}">
{{data.text}}
</view>
</view>
/**
* data: {
* text: //文案描述
* textBg: //文案背景
* progressWidth: //进度条宽
* progressHeight: //进度条高
* clock_bg: //时钟icon
* countTxt: //时钟文案
* countTxtColor: //时钟文字颜色
* countTxtSize: //时钟文字大小
* }
* usePercent: //已执行时长
* countTime: //倒计时长
* styleType: //样式(01——右对齐,02—底部)
*/
Component({
mixins: [],
data: {},
props: {
percent: 10,
usePercent:0,
countTime: 10,
styleType: '01',//browse_txt_bg count_bg_02
data: {
text: '浏览商品10s,获得任务奖励',
textBg: '//yun.dui88.com/taobaomini/clientCTest/count_bg_02@2x.png',
progressWidth:'130',
progressHeight:'18',
clock_bg: '//yun.dui88.com/taobaomini/clientCTest/clock@2x.png',
countTxt: '10',
countTxtColor: '#1CA4ED',
countTxtSize: '32'
}
},
didMount() { },
didUpdate() {},
didUnmount() { },
methods: {},
});
{
"component": true
}
\ No newline at end of file
.end-modal-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
min-height: 100vh;
/* background: url('//yun.dui88.com/taobaomini/clientCTest/end_bg@2x.png') no-repeat; */
background-size: 750rpx 1624rpx;
overflow: hidden;
z-index: 20;
}
.end-modal-container-content {
position: absolute;
width: 750rpx;
height: 480rpx;
top: 50%;
left: 0;
margin-top: -240rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.end-modal-container-content__icon {
width: 478rpx;
height: 340rpx;
}
.end-modal-container-content__icon image {
width: 100%;
height: 100%;
}
.end-modal-container-content__desc {
font-size: 36rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: #ADADAD;
}
\ No newline at end of file
<view class="end-modal-container" style="{{{'background':`url(${data.image.bg}) no-repeat`}}}">
<view class="end-modal-container-content">
<view class="end-modal-container-content__icon">
<image mode="scaleToFill" src="{{data.image.end_icon}}"/>
</view>
<view class="end-modal-container-content__desc">{{data.text}}</view>
</view>
</view>
\ No newline at end of file
Component({
mixins: [],
data: {},
props: {
data: {
image: {
bg: '//yun.dui88.com/taobaomini/clientCTest/end_bg@2x.png',
end_icon: '//yun.dui88.com/taobaomini/clientCTest/end_icon@2x.png',
},
text: '活动未开始'
}
},
didMount() {},
didUpdate() {},
didUnmount() {},
methods: {},
});
{
"component": true
}
\ No newline at end of file
.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: 750rpx 1624rpx;
overflow: hidden;
z-index: 20;
}
.goods-modal-container__title {
width: 750rpx;
height: 120rpx;
margin: 29rpx 0 11rpx;
}
.goods-modal-container__banner {
width: 750rpx;
height: 400rpx;
margin-bottom: 30rpx;
background: #E1E1E1;
}
.goods-modal-container__content {
position: absolute;
top: 190rpx;
left: 0;
bottom: 0;
padding-top: 41rpx;
padding: 41rpx 25rpx 0;
width: 750rpx;
/* 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: 340rpx;
height: 510rpx;
background: #fff;
margin-bottom: 20rpx;
}
.goods-modal-container__content-item:nth-child(even) {
margin-left: 20rpx;
}
.goods-modal-container__content-item__img {
width: 340rpx;
height: 340rpx;
background: #E1E1E1;
}
.goods-modal-container__content-item__img image {
width: 100%;
height: 100%;
}
.goods-modal-container__content-item__name {
margin: 25rpx 0 31rpx 21rpx;
width:310rpx;
height:60rpx;
font-size:24rpx;
font-family:PingFang SC;
font-weight:400;
color:rgba(24,24,24,1);
line-height:30rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.goods-modal-container__content-item__price {
padding: 0 31rpx 0 24rpx;
display: flex;
justify-content: space-between;
}
.goods-modal-container__content-item__price-num {
font-size:32rpx;
font-family:PingFang SC;
font-weight:600;
color:rgba(255,42,0,1);
}
.goods-modal-container__content-item__price-num text {
font-size: 24rpx;
margin-right: 2rpx;
}
.goods-modal-container__content-item__price-collect {
width: 118rpx;
height: 31rpx;
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: 30rpx;
height: 30rpx;
}
.goods-modal-container__content-item__price-no-collect image {
width: 100%;
height: 100%;
}
.goods-modal-timer {
width: 147rpx;
height: 223rpx;
position: absolute;
top: 502rpx;
right: 19rpx;
background: #eee;
}
.goods-modal-timer__clock {
}
\ No newline at end of file
<view class="goods-modal-container" style="{{{'background':`url(${task.image.bg}) no-repeat`}}}">
<view a:if="{{task.type == '01'}}"
style="{{{'background':`url(${task.image.title}) no-repeat`,'backgroundSize': '100% 100%'}}}" class="goods-modal-container__title"></view>
<view a:else class="goods-modal-container__banner" style="{{{'background':`url(${task.image.banner}) no-repeat`,'backgroundSize': '100% 100%','height':task.bannerHeight+'rpx'}}}"></view>
<view class="goods-modal-container__content" style="{{{'top':task.type == '02'?task.bannerHeight+'rpx':'149rpx'}}}">
<scroll-view scroll-y="{{true}}" class="goods-modal-container__scroll">
<view class="goods-modal-container__content-list">
<view class="goods-modal-container__content-item" a:for="{{goodsList}}" a:for-item="item">
<view class="goods-modal-container__content-item__img" data-item="{{item}}" onTap="goToGoodsDetail">
<image mode="scaleToFill" src="{{item.image}}"/>
</view>
<view class="goods-modal-container__content-item__name" style="{{{'color':task.color}}}">{{item.name}}</view>
<view class="goods-modal-container__content-item__price">
<view class="goods-modal-container__content-item__price-num"><text>¥</text>{{item.price}}</view>
<view a:if="{{task.taskType == 'collectGoods'}}"
data-item="{{item}}"
onTap="goToCollectGoods"
class="{{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>
</scroll-view>
</view>
<!-- 倒计时 -->
<count-down-modal a:if="{{isShowCountdown && task.taskType == 'browseGoods'}}" percent="{{percent}}" usePercent="{{usePercent}}" styleType="{{'01'}}" />
</view>
\ No newline at end of file
/**
* 任务类型(taskType):collectGoods、orderGoods、browseGoods、exchangeCredits
*/
const app = getApp();
const { tbcc } = app;
const { openDetail, collectGoods, checkGoodsCollectedStatus } = tbcc.tb;
Component({
mixins: [],
timer: null,
data: {
usePercent: 0, // 已进行的进度条
percent: 0,// 进度条
isShowCountdown: true, // 是否显示倒计时
isFlag: 1
},
props: {
isBackFlag: 0,
goodsList: [1,2,3],
task: {
itemId: '617724147979,617724563528,617300295119,614139753189',
taskType: 'browseGoods',
type: '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'
},
onCompleteTask: () => {}
},
didMount() {
const { taskType } = this.props.task
this.setData({ isFlag: this.props.isBackFlag })
console.log(this.props.goodsList)
if(taskType == 'browseGoods') {
this.browseGoodsTimes()
}
},
didUpdate(prevProps,prevData) {
if(prevData.isFlag && prevProps.isBackFlag != prevData.isFlag) {
console.log(3)
if(!this.timer) {
this.setData({ usePercent: this.data.percent })
this.browseGoodsTimes()
console.log(10 - this.usePercent)
}
}
},
didUnmount() {
clearTimeout(this.timer)
},
methods: {
/**
* 跳转商品详情页
*/
async goToGoodsDetail(e) {
clearInterval(this.timer)
this.setData({
percent: this.data.usePercent,
})
const { itemId } = e.target.dataset.item
await openDetail(String(itemId))
},
/**
* 收藏商品
*/
async goToCollectGoods(e) {
const { itemId, collected } = e.target.dataset.item
const { taskType } = this.props.task
if(collected) return;
let result = await collectGoods(itemId)
if(result) {
this.props.onCompleteTask(taskType, itemId)
}
},
/**
* 浏览商品倒计时
*/
browseGoodsTimes() {
const { taskType } = this.props.task
this.timer = setInterval(() => {
this.setData({
usePercent: this.data.usePercent + 1
}, () => {
if (this.data.usePercent >= 10) {
console.log(this.data.usePercent)
this.props.onCompleteTask(taskType)
clearInterval(this.timer)
}
})
},1000)
}
},
});
{
"component": true,
"usingComponents": {
"count-down-modal": "/components/countDownModal/countDownModal"
}
}
\ No newline at end of file
@keyframes modalAnimation {
to {
opacity: 1;
}
}
.logistics-modal-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.7);
z-index: 20;
opacity: 0;
animation: modalAnimation .3s forwards;
}
@keyframes containerAnimation {
to {
transform: scale(1)
}
}
.logistics-modal-container__content {
width: 646rpx;
height: 244rpx;
padding: 0 46rpx;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
display: flex;
align-items: center;
transform: scale(0);
animation: containerAnimation .3s forwards;
}
.logistics-modal-container__close {
position: absolute;
right: -10rpx;
top: -70rpx;
height: 48rpx;
width: 48rpx;
background: url("//yun.duiba.com.cn/taobaomini/aupresViva/tc_close.png") no-repeat;
background-size: 100% 100%;
}
.logistics-modal-container__content-item {
border-radius: 10rpx;
display: flex;
}
.logistics-modal-container__content-left {
width: 144rpx;
height: 144rpx;
background: rgba(244, 244, 244, 1);
}
.logistics-modal-container__content-left image {
width: 100%;
height: 100%;
}
.logistics-modal-container__content-right {
height: 144rpx;
margin-left: 24rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
font-size: 20rpx;
color: #959595;
flex: 1;
overflow: hidden;
white-space: nowrap;
}
.logistics-modal-container__content-name {
font-size: 28rpx;
color: rgba(51, 51, 51, 1);
}
.logistics-modal-container__content-desc {
font-size: 20rpx;
}
.logistics-modal-container__content-ids {
margin-bottom: 20rpx;
}
.logistics-modal-container__content-copy {
display: flex;
align-items: center;
height: 30rpx;
}
.logistics-modal-container__content-copy__code {
font-size: 20rpx;
}
.logistics-modal-container__content-copy__img {
width: 20rpx;
height: 20rpx;
background-size: 100% 100%;
margin-left: 20rpx;
}
\ No newline at end of file
<view class="logistics-modal-container">
<view class="logistics-modal-container__content"
style="{{prizeItem.shipStatus == 3 ?`background: url(${task.shipped}) no-repeat;background-size: 100% 100%;`
:`background: url(${task.notShipped}) no-repeat;background-size: 100% 100%;`}}">
<view class="logistics-modal-container__close" onTap="closeModal"></view>
<view class="logistics-modal-container__content-item">
<view class="logistics-modal-container__content-left">
<image mode="scaleToFill" src="{{prizeItem.image}}"/>
</view>
<view class="logistics-modal-container__content-right">
<view class="logistics-modal-container__content-name">{{prizeItem.name}}</view>
<view class="logistics-modal-container__content-copy">
<view class="logistics-modal-container__content-copy__code">奖品编码:{{prizeItem._id}}</view>
<view class="logistics-modal-container__content-copy__img" onTap="copyPrizeId"></view>
</view>
<view class="logistics-modal-container__content-desc">{{prizeItem.shipStatus== 3?'发货状态:已发货':'发货状态:未发货'}}</view>
<view class="logistics-modal-container__content-desc" a:if="{{prizeItem.shipStatus == 2}}">温馨提示:奖品将在活动结束7天内陆续发出</view>
<view class="logistics-modal-container__content-copy" a:else>
<view class="logistics-modal-container__content-copy__code">{{'物流单号:'+prizeItem.shipNum}}</view>
<view class="logistics-modal-container__content-copy__img" style="{{`background: url(${task.copyIcon}) no-repeat;background-size: 100% 100%;`}}" onTap="copyCode"></view>
</view>
</view>
</view>
</view>
</view>
\ No newline at end of file
const app = getApp();
const { tbcc } = app;
const { commonToast } = tbcc.tb;
Component({
mixins: [],
data: {},
props: {
prizeItem: {},
onCloseModal: () => { },
task: {
shipped: '',
notShipped: '',
}
},
didMount() { },
didUpdate() { },
didUnmount() { },
methods: {
closeModal() {
this.props.onCloseModal()
},
//复制运单号
copyCode() {
let { shipNum } = this.props.prizeItem
my.setClipboard({
text: shipNum + '',
success: () => {
commonToast('复制成功')
}
});
},
copyPrizeId() {
let { _id } = this.props.prizeItem
my.setClipboard({
text: _id + '',
success: () => {
commonToast('复制成功')
}
});
}
},
});
{
"component": true
}
\ No newline at end of file
.my-prize-page {
width: 100vw;
height: 100vh;
opacity: 1;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
/* background: url('') no-repeat center top/cover; */
}
.my-prize-page .my-prize-wrap {
width: 100%;
height: 100%;
overflow: auto;
}
.my-prize-page .my-prize-label {
width: 208rpx;
height: 36rpx;
margin: 140rpx auto 40rpx;
background: url('//yun.dui88.com/duiba-components-c-myprizeprize_title.png') no-repeat;
background-size: 100% 100%;
}
.my-prize-page .my-prize-list {
width: 100%;
height: auto;
}
.my-prize-page .my-prize-empty {
text-align: center;
color: #fff;
margin-top: 30rpx;
}
.my-prize-page .my-prize-item {
display: flex;
justify-content: center;
align-items: center;
padding: 0 28rpx 0 26rpx;
margin: 0 auto 24rpx;
position: relative;
box-sizing: border-box;
width: 700rpx;
height: 161rpx;
background-color: #ffffff;
box-shadow: 2rpx 3rpx 18rpx 0 rgba(230, 146, 255, 0.6);
border-radius: 10rpx;
box-sizing: border-box;
}
.my-prize-page .my-prize-item .my-prize-avatar {
width: 120rpx;
height: 120rpx;
}
.my-prize-page .my-prize-item .my-prize-content {
flex: 1;
min-width: 0;
padding: 0 20rpx;
display: flex;
flex-direction: column;
height: 130rpx;
}
.my-prize-page .my-prize-item .my-prize-subtitle {
display: flex;
justify-content: center;
align-items: center;
}
.my-prize-page .my-prize-item .my-prize-copy {
width: 20rpx;
height: 20rpx;
margin-left: 18rpx;
}
.my-prize-page .my-prize-item .prize-status {
width: 150rpx;
height: 41rpx;
}
.prize-status>image {
width: 100%;
height: 100%;
}
.my-prize-page .my-prize-item .my-prize-name {
width: 100%;
font-size: 28rpx;
color: #2d2d2d;
letter-spacing: -1rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.my-prize-page .my-prize-item .my-prize-tip {
margin-top: 8rpx;
font-size: 20rpx;
line-height: 20rpx;
letter-spacing: 0;
color: #8a8a8a;
}
.my-prize-page .my-prize-item .my-prize-code {
width: 290rpx;
font-family: PingFangSC-Regular;
font-size: 20rpx;
color: #8a8a8a;
letter-spacing: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
\ No newline at end of file
<view class="my-prize-page" style="{{{'background':`url(${task.image.bg}) no-repeat center top/cover`}}}">
<view class="my-prize-wrap">
<view class="my-prize-label"></view>
<view class="my-prize-list" a:if="{{myPrizeList && myPrizeList.length > 0}}">
<view class="my-prize-item" a:for="{{myPrizeList}}">
<image class="my-prize-avatar" src="{{item.image}}"/>
<view class="my-prize-content">
<label class="my-prize-name">{{item.name}}</label>
<view class="my-prize-subtitle">
<label class="my-prize-code">奖品编码:{{item._id}}</label>
<!-- 复制按钮 -->
<image class="my-prize-copy" data-text="{{item._id}}" onTap="handleCopyId" src="{{task.image.copyIcon}}" />
</view>
<view class="my-prize-tip" a:if="{{item.drawStatus === PRIZE_DRAW_STATUS_MAPPRIZE_DRAW_STATUS_MAP.FAILURE}}">{{item.remark}}</view>
<view class="my-prize-tip" a:if="{{item.drawStatus === PRIZE_DRAW_STATUS_MAP.REPEAT || (item.drawStatus === PRIZE_DRAW_STATUS_MAP.RECEIVE)}}">请于{{endTime}}前领取</view>
<view class="my-prize-tip" a:if="{{item.drawStatus === PRIZE_DRAW_STATUS_MAP.FINISHED }}">奖品已过期失效</view>
</view>
<view class="prize-status" style="{{task.btnStyle}}">
<!-- 未领取 -->
<block a:if="{{item.drawStatus===PRIZE_DRAW_STATUS_MAP.RECEIVE}}">
<!-- 实物填写地址 -->
<image a:if="{{item.type === PRIZE_TYPE_MAP.ENTITY}}" onTap="handleClick" data-item="{{item}}" src="{{task.image.addressBth}}" />
<!-- 优惠券立即领取 -->
<image a:else onTap="handleClick" data-item="{{item}}" src="{{task.image.getBth}}" />
</block>
<!-- 已领取 -->
<block a:if="{{item.drawStatus===PRIZE_DRAW_STATUS_MAP.SUCCESS}}">
<!-- 实物查看物流 -->
<image a:if="{{item.type === PRIZE_TYPE_MAP.ENTITY}}" onTap="handleView" data-item="{{item}}" src="{{task.image.logisticsBth}}" />
<!-- 优惠券去使用 -->
<image a:else onTap="handleTouse" data-item="{{item}}" src="{{task.image.useBtn}}" />
</block>
<!-- 重新领取 -->
<image a:if="{{item.drawStatus===PRIZE_DRAW_STATUS_MAP.REPEAT}}" onTap="handleClick" data-item="{{item}}" src="{{task.image.getAgainBtn}}" />
<!-- 已失效 -->
<image a:if="{{item.drawStatus===PRIZE_DRAW_STATUS_MAP.FINISHED}}" src="{{task.image.invalidBtn}}" />
<!-- 领取失败 -->
<image a:if="{{item.drawStatus===PRIZE_DRAW_STATUS_MAP.FAILURE}}" src="{{task.image.failBth}}" />
</view>
</view>
</view>
<view a:if="{{myPrizeList && myPrizeList.length === 0}}" class="my-prize-empty">暂无奖品</view>
</view>
<logistics-modal a:if="{{isLogistic}}" prizeItem="{{currentPrize}}" onCloseModal="closeLogisticModal" task="{{task.logisticsImage}}"/>
</view>
\ No newline at end of file
const app = getApp();
const { tbcc } = app;
const { commonToast, navigateToOutside, getUserAddress, setClipboard } = tbcc.tb;
const { PRIZE_TYPE_MAP, PRIZE_DRAW_STATUS_MAP } = tbcc.constants;
Component({
mixins: [],
data: {
PRIZE_TYPE_MAP,
PRIZE_DRAW_STATUS_MAP,
currentPrize: {},
isLogistic: false,
},
props: {
myPrizeList: null, //我的奖品
endTime: null,//到期时间
task: {
image: {},
logisticsImage: {},
btnStyle: {}
}
},
didMount() { },
didUpdate() { },
didUnmount() { },
methods: {
//领取奖品
handleClick(e) {
this.props.onHandleClick(e)
},
// 复制编码
handleCopyId(e) {
const { text } = e.target.dataset || {}
setClipboard({ text })
console.log(text)
commonToast('复制成功')
},
// 去使用
handleTouse(e) {
const { item } = e.target.dataset;
navigateToOutside(item.useUrl)
},
//查看物流
handleView(e) {
let { item } = e.target.dataset
this.setData({ currentPrize: item, isLogistic: true })
},
/**
* 关闭物流弹窗
*/
closeLogisticModal() {
this.setData({ isLogistic: false })
},
},
});
{
"component": true,
"usingComponents": {
"logistics-modal": "/components/logisticsModal/logisticsModal"
}
}
\ No newline at end of file
.rule-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 20;
}
.rule-modal__shade {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.75);
}
.rule-modal__container {
position: absolute;
width: 500rpx;
height: 600rpx;
background: #4eafd7;
background-size: 100% 100%;
left: 50%;
top: 50%;
margin-left: -250rpx;
margin-top: -300rpx;
}
.rule-modal__bd {
position: absolute;
top: 40rpx;
left: 40rpx;
right: 40rpx;
bottom: 40rpx;
overflow-x: hidden;
font-size: 24rpx;
color: #fff;
line-height: 1.5;
}
.rule-modal__close {
position: absolute;
right: -20rpx;
top: -80rpx;
height: 86rpx;
width: 86rpx;
background: url('../../assets/modal_close_btn.png') center center no-repeat;
background-size: 48rpx 48rpx;
z-index: 9;
}
<view class="rule-modal">
<view class="rule-modal__shade modal-animate-fade-in" />
<view class="rule-modal__container modal-animate-zoom-in">
<view class="rule-modal__close" onTap="onModalClose" />
<view class="rule-modal__bd">
<slot />
</view>
</view>
</view>
Component({
methods: {
onModalClose() {
const { onModalClose } = this.props;
onModalClose && onModalClose();
}
}
});
\ No newline at end of file
{
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@tbmp/mp-cloud-sdk": {
"version": "1.3.4",
"resolved": "https://registry.npm.taobao.org/@tbmp/mp-cloud-sdk/download/@tbmp/mp-cloud-sdk-1.3.4.tgz",
"integrity": "sha1-+1HCYryYfVc0kze0SOWv1oL6xgk="
}
}
}
{
"name": "",
"version": "1.0.0",
"main": "",
"license": "MIT",
"dependencies": {
"@tbmp/mp-cloud-sdk": "*"
}
}
<view class="goodsPage">
<goods-modal
isBackFlag="{{isBackFlag}}"
goodsList="{{goodsList}}"
task="{{task}}"
onCompleteTask="onCompleteTask" />
</view>
\ No newline at end of file
/**
* 任务类型(taskType):collectGoods、orderGoods、browseGoods、exchangeCredits
* task: {
* itemId: //商品ID
* taskType: //任务类型
* type: //头部样式(02——banner,01——标题)
* image: {//图片
* bg: //集合页背景
* banner: //头部banner
* title: //头部title
* collect: //商品以收藏
* no_collect: //商品未收藏
* }
* color: //商品名称:文字颜色
* }
*/
const app = getApp();
const { tbcc } = app;
const { openDetail, collectGoods, checkGoodsCollectedStatus, commonToast } = tbcc.tb;
import API from '../../api';
Page({
data: {
query: {},
task: {},
isBackFlag: 1,
goodsList: []
},
onLoad(query) {
this.query = query || {}
this.init()
},
onShow() {
//重新回到页面开启倒计时
this.setData({ isBackFlag: Math.floor((Math.random() * 100)) == this.data.isBackFlag ? 101 : Math.floor((Math.random() * 100)) })
},
init() {
const { itemId, taskType } = this.query
this.setData({
task: {
itemId,
taskType: 'browseGoods',
type: '01',
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'
}
})
this.initPage()
},
async initPage() {
const { activityId } = app
const { taskType, itemIds } = this.query
let goodsList = [
{
image: '',
name: '商品名商品名商品名商品名商品名商品名商品名商品商品',
price: '388',
itemId: 617724147979,
collected: false
},
{
image: '',
name: '商品名商品名商品名商品名商品名商品名商品名商品商品',
price: '388',
collected: true,
itemId: 617724563528,
},
{
image: '',
name: '商品名商品名商品名商品名商品名商品名商品名商品商品',
price: '388',
collected: false,
itemId: 617300295119,
},
{
image: '',
name: '商品名商品名商品名商品名商品名商品名商品名商品商品',
price: '388',
collected: true,
itemId: 614139753189,
},
{
image: '',
name: '商品名商品名商品名商品名商品名商品名商品名商品商品',
price: '388',
itemId: 617724147979,
},
]
this.setData({ goodsList })
let handel = taskType == 'collectGoods' ? 'getCollectItemList' : 'getItemListByItemIds'
const { success, data } = await API[handel]({ activityId, itemIds }).catch(res => {
res && commonToast(res)
}) || {}
if(success) {
this.setData({ goodsList: data || [] })
}
},
//任务完成
async onCompleteTask(taskType,itemId) {
console.log(taskType,itemId)
const { activityId } = app
switch(taskType) {
case 'collectGoods':
let { success, data } = await API.doCollectGoodsTask({ activityId, taskType, itemId }).catch(res => {
res && commonToast(res)
}) || {}
if(success) {
this.initPage()
}
break;
case 'browseGoods':
let browsResult = await API.doCollectGoodsTask({ activityId, taskType, itemId }).catch(res => {
res && commonToast(res)
}) || {}
console.log(browsResult)
if(browsResult.success) {
commonToast('任务完成,请到任务中心查看奖励')
}
break;
}
}
});
{
"usingComponents": {
"goods-modal": "/components/goodsModal/goodsModal"
}
}
\ No newline at end of file
.index-page {
min-height: 100vh;
}
.index-rule-btn, .index-myprize-btn {
position: absolute;
top: 30rpx;
width: 126rpx;
height: 48rpx;
line-height: 48rpx;
font-size: 22rpx;
background: rgba(0, 0, 0, 0.8);
color: #FFF;
text-align: center;
z-index: 5;
}
.index-rule-btn {
left: 0;
border-radius: 0 48rpx 48rpx 0;
}
.index-myprize-btn {
right: 0;
border-radius: 48rpx 0 0 48rpx;
}
.index-page__title {
font-size: 50rpx;
text-align: center;
padding: 100rpx 0 50rpx 0;
}
.index-page__content {
text-align: center;
font-size: 30rpx;
}
.index-page__tips {
padding-top: 40rpx;
text-align: center;
font-size: 22rpx;
}
.index-start-btn {
background: #0077a9;
color: #FFF;
width: 300rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
border-radius: 10rpx;
margin: 100rpx auto 50rpx auto;
font-size: 30rpx;
}
.index-tbcc-btn {
background: #0077a9;
color: #FFF;
width: 300rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
border-radius: 10rpx;
margin: 0 auto;
font-size: 30rpx;
}
.index-link-btn {
text-align: center;
color: #333;
font-size: 26rpx;
}
\ No newline at end of file
<view class="index-page">
<view class="index-rule-btn" onTap="showRuleModal">活动规则</view>
<navigator open-type="navigate" url="/pages/myprize/myprize" class="index-myprize-btn">我的奖品</navigator>
<view class="index-page__title">{{title}}</view>
<view class="index-page__content">{{content}}</view>
<view class="index-page__tips">AM接口只支持PC端预览,手机淘宝预览需要使用云函数模式</view>
<view class="index-start-btn" onTap="doStart">开始</view>
<navigator open-type="navigate" url="/pages/tbccDemo/tbccDemo" class="index-tbcc-btn">tbcc demo</navigator>
</view>
<rule-modal a:if="{{ruleModalVisible}}" onModalClose="closeRuleModal"><text>{{rule}}</text></rule-modal>
<common-modal a:if="{{commonModalVisible}}" data="{{commonModalData}}" onModalClose="closeCommonModal" onModalConfirm="confirmCommonModal" />
<end-modal a:if="{{false}}" />
\ No newline at end of file
const app = getApp();
const { tbcc } = app;
const { SHARE_CONFIG, REDIRECT_URL } = tbcc.constants;
import API from '../../api';
const { commonToast, getAuthUserInfo, navigateToOutside } = tbcc.tb;
Page({
data: {
title: '',
content: '',
rule: '',
commonModalData: {
content: '',
btnText: ''
},
commonModalConfirm: null,
commonModalVisible: false,
ruleModalVisible: false
},
onLoad(query) {
// 页面加载
this.getAuth();
console.info(`Page onLoad with query: ${JSON.stringify(query)}`);
},
init() {
this.getIndex();
},
onReady() {
// 页面加载完成
},
onShow() {
// 页面显示
},
onHide() {
// 页面隐藏
},
onUnload() {
// 页面被关闭
},
onTitleClick() {
// 标题被点击
},
onPullDownRefresh() {
// 页面被下拉
},
onReachBottom() {
// 页面被拉到底部
},
/**
* 获取用户授权信息
*/
async getAuth() {
const userInfo = await getAuthUserInfo().catch(err => {
console.log('未授权成功', err);
});
if (userInfo) {
console.log('userInfo', userInfo);
const { nickName, avatar } = userInfo;
app.nickName = nickName;
app.avatar = avatar;
this.login();
}
},
/**
* 获取主接口
*/
async getIndex() {
const { success, data } = await API.getIndex().catch(res => {
commonToast(res && res.message);
}) || {};
if (success && data) {
const { title, content, rule } = data;
this.setData({ title, content, rule });
}
},
/**
* 登录接口
*/
async login() {
const { nickName, avatar } = app;
const { success } = await API.login({ userNick:nickName, avatar }).catch(res => {
commonToast(res && res.message);
}) || {};
if (success) {
this.init();
}
},
/**
* 显示规则弹层
*/
showRuleModal() {
this.setData({
ruleModalVisible: true
});
},
/**
* 通用弹出确认按钮回调
*/
confirmCommonModal() {
const { commonModalConfirm } = this.data;
commonModalConfirm && commonModalConfirm();
},
/**
* 执行开始
*/
doStart() {
this.showCommonModal({
content: '活动还未开始\n请稍后',
btnText: '我知道了',
commonModalVisible: true,
confirmCallback: () => {
this.closeCommonModal();
}
});
},
/**
* 显示通用弹层
* @param {object} options content: 通用弹层内容 btnText:按钮文案 confirmCallback: 按钮确认回调
*/
showCommonModal({ content, btnText, confirmCallback }) {
this.setData({
commonModalConfirm: confirmCallback || null,
commonModalVisible: true,
commonModalData: { content, btnText }
});
},
/**
* 跳转到天猫页面
*/
goTmallPage() {
navigateToOutside(REDIRECT_URL['tmall']);
},
/**
* 关闭通用弹层
*/
closeCommonModal() {
this.setData({
commonModalVisible: false
});
},
/**
* 关闭活动规则弹层
*/
closeRuleModal() {
this.setData({
ruleModalVisible: false
});
},
onShareAppMessage() {
// 返回自定义分享信息
return SHARE_CONFIG;
},
});
{
"usingComponents": {
"rule-modal": "/components/ruleModal/ruleModal",
"common-modal": "/components/commonModal/commonModal",
"end-modal": "/components/endModal/endModal"
}
}
\ No newline at end of file
<view class="my-prize">
<prize-modal
myPrizeList="{{myPrizeList}}"
task="{{task}}"
endTime="{{endTime}}"
onHandleClick="handleClick"/>
</view>
\ No newline at end of file
'use strict';
import API from "/api";
const app = getApp();
const { tbcc } = app;
const { commonToast, navigateToOutside, getUserAddress, setClipboard } = tbcc.tb;
const { PRIZE_TYPE_MAP, PRIZE_DRAW_STATUS_MAP } = tbcc.constants;
let flag = false;
Page({
data: {
PRIZE_TYPE_MAP,
PRIZE_DRAW_STATUS_MAP,
myPrizeList: null, //我的奖品
endTime: null,//到期时间
task: {
image: {
bg: '//yun.duiba.com.cn/aurora/assets/e13fab3165d3a6bb4cbe8827e8f0fd41084b0091.png', //背景图
copyIcon: '//yun.dui88.com/duiba-components-c-myprizemyprize_copy_code.png', //复制
addressBth: '//yun.dui88.com/duiba-components-c-myprizeto_address.png', //填写地址(实物奖品)
getBth: '//yun.dui88.com/duiba-components-c-myprizeget_now.png', //立即领取(除实物奖品外)
logisticsBth: '//yun.dui88.com/duiba-components-c-myprizelogistics.png', //查看物流
useBth: '//yun.dui88.com/duiba-components-c-myprizeto_use.png', //去使用(除实物奖品外)
getAgainBtn: '//yun.dui88.com/duiba-components-c-myprizeget_again.png', //重新领取
invalidBtn: '//yun.duiba.com.cn/spark/assets/914ba8643c8abb8d710a3126ec312aecf6c4daf0.png', //已失效
failBth: '//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', // 待发货物流弹窗
copyIcon: '//yun.dui88.com/duiba-components-c-myprizemyprize_copy_code.png', //复制
},
btnStyle: { // 按钮自定义样式
width: '150rpx',
height: '41rpx',
}
}
},
onShow() {
flag = false
this.getMyPrize();
},
// 到期时间
getEndTime(prizeList = []) {
if (!prizeList || !prizeList.length) return null
const endTime = prizeList[0].expiredTime
if (!endTime) return null
const t1 = new Date(endTime).toLocaleDateString() + '';//获取年月日
const t2 = new Date(endTime).getHours() + '';//获取时
const t3 = new Date(endTime).getMinutes() + '';//获取分
const t4 = new Date(endTime).getMilliseconds() + '';//获取秒
console.log(endTime, new Date(endTime + 48 * 60 * 60 * 1000).toLocaleString(), 'endTime');
this.setData({
endTime: t1 + " " + t2.padStart(2, '0') + ":" + t3.padStart(2, '0') + ":" + t4.padStart(2, '0')
})
},
/**
* 获取奖品列表
* @param {string} type 是否展示loading
*/
async getMyPrize(type) {
const { activityId } = app;
if (type != 'noLoading') {
my.showLoading();
}
const { success, data, message } = await API.getMyPrizeList({ activityId }).catch(res => {
this.setData({
myPrizeList: []
})
}) || {};
if (success && data) {
this.setData({
myPrizeList: data.list
})
this.getEndTime(data.list)
}
if (type != 'noLoading') {
my.hideLoading();
}
},
//领取奖品
async handleClick(e) {
const { item } = e.target.dataset;
// 领取权益
if (item.type === PRIZE_TYPE_MAP.EQUITY) return this.handleGetEquity(e)
// 领取实物
if (item.type === PRIZE_TYPE_MAP.ENTITY) return this.handleGetEntity(e)
// 领取积分
if (item.type === PRIZE_TYPE_MAP.INTEGRATION) return this.handleGetIntergation(e)
},
// 优惠券
async handleGetEquity(e) {
if (flag) {
return
}
flag = true;
const { activityId } = app;
const { item } = e.target.dataset;
console.log(item, '领取权益')
const { success, data, message } = await API.receiveEnamePrize({ activityId, _id: item._id }).catch(res => {
this.getMyPrize('noLoading')
commonToast(res && res.message)
}) || {};
if (success && data) {
commonToast('领取成功')
this.getMyPrize()
}
setTimeout(() => {
flag = false
}, 500)
},
// 领取实物前询问
async handleGetEntity(e) {
if (flag) {
return
}
my.showLoading();
flag = true;
const { activityId } = app;
const { item } = e.target.dataset;
const userAddress = await getUserAddress({ joinTag: " " })
my.hideLoading();
if (!userAddress) return
const { name, telNumber, provinceName, cityName, cityCode, countyName, detailInfo, streetName } = userAddress || {};
const params = {
activityId,
name,
phone: telNumber,
detailInfo,
cityCode,
cityName,
provinceName,
countyName,
streetName,
_id: item._id
}
my.confirm({
title: '提示',
content: '确认使用该收货地址:' + name + telNumber + userAddress.duibaAddress.address,
confirmButtonText: '确定',
cancelButtonText: '取消',
success: (result) => {
console.log(result)
const { confirm } = result;
if (confirm) {
this.receiveObjectPrize(params);
}
},
});
flag = false
},
// 领取实物
async receiveObjectPrize(params) {
const { success, data, message } = await API.receiveObjectPrize(params) || {}
if (success && data) {
commonToast('领取成功')
} else {
commonToast(message)
}
this.getMyPrize()
},
// 积分
async handleGetIntergation(e) {
if (flag) {
return
}
flag = true;
// 判断是否为会员
await this.getUserInfo()
const { isVip, vipLink } = app;
if (!isVip) {
commonToast('立即加入会员,即可领取奖品', 2000);
setTimeout(() => {
navigateToOutside(vipLink)
}, 1000)
flag = false
return
}
const { activityId } = app;
const { item } = e.target.dataset;
console.log(item, '领取积分')
const { success, data, message } = await API.receiveEnamePrize({ activityId, _id: item._id }) || {};
if (success && data) {
commonToast('领取成功')
} else {
commonToast(message)
}
flag = false
this.getMyPrize()
},
//获取用户vip信息
async getUserInfo() {
const { activityId } = app;
const { success, data, message } = await API.getVipInfo({ activityId }) || {};
console.log(data, '用户vip信息');
if (success && data) {
app.isVip = (data && data.isVip) || false;
app.vipLink = (data && data.url) || '';
} else {
commonToast(message)
}
},
});
\ No newline at end of file
{
"usingComponents": {
"prize-modal": "/components/prizeModal/prizeModal"
}
}
\ No newline at end of file
.tbcc-demo-page {
text-align: center;
padding: 60rpx 20rpx 20rpx;
}
.tbcc-demo-page button {
margin-bottom: 10rpx;
}
.tbcc-demo-page .upload-image {
width: 200rpx;
height: 200rpx;
}
.tbcc-demo-page .input-item {
width: 684rpx;
height: 80rpx;
}
.text-risk-item {
margin: 30rpx auto;
}
.tbcc-demo__title {
padding: 20rpx;
font-weight: bold;
font-size: 36rpx;
}
\ No newline at end of file
<view class="tbcc-demo-page">
<view class="tbcc-demo__title">常用tb方法</view>
<button onTap="showCommomToast">弱提示</button>
<button onTap="showCommomConfirm">通用确认弹层</button>
<button onTap="getAuth">获取用户授权</button>
<button onTap="getSystemInfo">获取系统信息</button>
<button onTap="getServerTime">获取系统时间</button>
<button onTap="favorShop">关注店铺(百草味为例需预览)</button>
<button onTap="checkShopFavoredStatus">店铺关注状态(百草味为例需预览)</button>
<button onTap="getUserAddress">获取收货地址(需预览)</button>
<button onTap="collectGoods">收藏商品(iPad Pro为例)</button>
<button onTap="checkGoodsCollectedStatus">商品收藏状态(iPad Pro为例)</button>
<button onTap="openDetail">跳转淘宝商品页(iPad Pro为例)</button>
<button onTap="navigateToOutside">跳转外部链接(需预览)</button>
<button onTap="navigateTo">跳转内部链接(新开窗口)</button>
<button onTap="redirectTo">跳转内部链接(不新开窗口)</button>
<button onTap="uploadImage">选择上传图片</button>
<view a:if="{{uploadImgUrl}}">
<image mode="aspectFit" src="{{uploadImgUrl}}" class="upload-image"></image>
</view>
<button onTap="chattingSendCard">分享到群聊卡片(需预览)</button>
<view class="text-risk-item">
<input type="text" onInput="bindKeyInput" data-name="riskInput" placeholder="请输入校验文本" class="input-item" />
<button onTap="textRiskIdentification">文本风险检测(需预览)</button>
</view>
<view class="tbcc-demo__title">通用API方法</view>
<button onTap="receiveObjectPrize">领取实物奖励</button>
<button onTap="receiveEnamePrize">领取权益奖励</button>
</view>
import API from '../../api';
const app = getApp();
const { tbcc } = app;
const {
commonToast,
simpleAlert,
commonConfirm,
getAuthUserInfo,
getSystemInfo,
getServerTime,
favorShop,
checkShopFavoredStatus,
getUserAddress,
collectGoods,
checkGoodsCollectedStatus,
openDetail,
navigateToOutside,
navigateTo,
redirectTo,
uploadImage,
chattingSendCard,
textRiskIdentification
} = tbcc.tb;
const { dateFormatter, versionCompare } = tbcc.utils;
Page({
data: {
uploadImgUrl: '',
riskInput: ''
},
onLoad() {},
bindKeyInput(e) {
const { value } = e.detail;
const { name } = e.target.dataset;
this.setData({
[name]: value,
});
},
/**
* toast提示
*/
showCommomToast() {
commonToast('tbcc', 3000, () => {
console.log('tbcc toast loaded');
});
},
/**
* confirm弹窗
*/
showCommomConfirm() {
commonConfirm('提示', '内容', () => {
commonToast('保存成功');
});
},
/**
* 获取用户授权信息
*/
async getAuth() {
const userInfo = await getAuthUserInfo().catch(err => {
console.log('未授权成功', err);
});
if (userInfo) {
console.log('userInfo', userInfo);
const { nickName, avatar } = userInfo;
app.nickName = nickName;
app.avatar = avatar;
simpleAlert(nickName);
}
},
/**
* 获取系统信息
*/
async getSystemInfo() {
const systemInfo = await getSystemInfo().catch(err => {
console.log('获取系统信息失败', err);
});
if (systemInfo) {
console.log('systemInfo', systemInfo);
const { version } = systemInfo;
const compareVersion = '9.8.0';
const isNewVersion = versionCompare(version, compareVersion);
simpleAlert('当前版本:' + version + `${isNewVersion ? '为新版本': '为老版本'}`);
}
},
/**
* 获取系统时间
*/
async getServerTime() {
const severTime = await getServerTime().catch(err => {
console.log('获取系统时间失败', err);
});
simpleAlert('系统时间:' + dateFormatter(severTime, 'yyyy/MM/dd hh:mm:ss'));
},
/**
* 关注店铺
*/
async favorShop() {
const sellerId = 628189716; // 百草味sellerId
const favorStatus = await favorShop(sellerId).catch(err => {
console.log('关注店铺失败', err);
});
commonToast(favorStatus ? '关注成功' : '关注失败');
},
/**
* 查询店铺关注状态
*/
async checkShopFavoredStatus() {
const sellerId = 628189716; // 百草味sellerId
const favoredStatus = await checkShopFavoredStatus(sellerId).catch(err => {
console.log('查询关注店铺状态失败', err);
});
simpleAlert(favoredStatus ? '已关注店铺' : '未关注店铺');
},
/**
* 获取用户收货地址
*/
async getUserAddress() {
const userAddress = await getUserAddress().catch(err => {
commonToast(err.errorMessage);
});
if (userAddress) {
console.log('userAddress', userAddress);
const { name, phone, address } = userAddress.duibaAddress;
commonConfirm('提示', '确认使用该收货地址:' + name + phone + address, () => {
// TODO 保存接口
commonToast('保存成功');
});
}
},
/**
* 收藏商品
*/
async collectGoods() {
const itemId = 622499363381; // iPad Pro 为例
const collectGoodsStatus = await collectGoods(itemId).catch(err => {
console.log('收藏商品失败', err);
});
commonToast(collectGoodsStatus ? '收藏商品成功' : '收藏商品失败');
},
/**
* 收藏商品
*/
async checkGoodsCollectedStatus() {
const itemId = 622499363381; // iPad Pro 为例
const goodscollectedStatus = await checkGoodsCollectedStatus(itemId).catch(err => {
console.log('查询商品收场状态失败', err);
});
simpleAlert(goodscollectedStatus ? '商品已收藏' : '商品未收藏');
},
/**
* 跳转到淘宝商品页
*/
async openDetail() {
const itemId = '622499363381'; // iPad Pro 为例
await openDetail(itemId).catch(err => {
console.log('打开淘宝商品页失败', err);
});
},
/**
* 跳转到外部链接
*/
navigateToOutside() {
const url = 'https://www.tmall.com';
navigateToOutside(url);
},
/**
* 跳转到小程序内部链接(新开窗口)
*/
navigateTo() {
const url = '/pages/index/index';
navigateTo(url);
},
/**
* 跳转到小程序内部链接(不新开窗口)
*/
redirectTo() {
const url = '/pages/index/index';
redirectTo(url);
},
/**
* 选择上传图片
*/
async uploadImage() {
const uploadImageResultUrl = await uploadImage().catch(err => {
commonToast(err && (err.errorMessage || '上传图片失败'));
});
if (uploadImageResultUrl) {
this.setData({
uploadImgUrl: uploadImageResultUrl
});
}
},
/**
* 分享到群聊卡片
*/
async chattingSendCard() {
// 测试请求参数(格式示例)
const requestInfo = {
"biz_ext_map": "{\"activityId\":\"028fe748-9413-4df1-ad15-7d21d9ca16c9\",\"shareId\":\"AAGrFC1BALWl0Axwb3svqUyd\"}",
"card_template_id": 1588754547060,
"group_id": "0_G_2207623078795_1591670473134",
"weex_data_json": "{\"url\":\"https://m.duanqu.com?_ariver_appid=3000000005188064&nbsv=0.1.2007151634.12&nbsource=debug&nbsn=DEBUG&_mp_code=tb&query=activityId%3D028fe748-9413-4df1-ad15-7d21d9ca16c9%26groupId%3D0_G_2207623078795_1591670473134%26shareId%3DAAGrFC1BALWl0Axwb3svqUyd\",\"act_title\":\"一起出道赢大奖\",\"share\":\"@pilee0827 多度\",\"picture3\":\"https://yun.duiba.com.cn/upload/ltuwhbf39x.jpg\"}",
"message_id": "5f0fcdfeef507182be6c2247",
"app_secret": "appSecret",
"app_code": "30123678"
};
const messageResult = await chattingSendCard(requestInfo).catch(err => {
commonToast(err && err.errorMessage);
});
if (messageResult) {
const { result: { value, success } } = messageResult;
commonToast(value && success ? '分享到群聊成功' : '分享到群聊失败');
}
},
/**
* 文本风险校验
*/
async textRiskIdentification() {
const { riskInput } = this.data;
const success = await textRiskIdentification(riskInput).catch(err => {
console.log(err);
});
simpleAlert(`检测文本"${riskInput}",校验结果${success ? '通过' : '不通过'}`);
},
/**
* 领取实物奖励
*/
async receiveObjectPrize() {
const _id = '123'; // 测试奖品ID
const success = await API.fn.receiveObjectPrize({ _id });
if (success) {
commonToast('保存成功');
}
},
/**
* 领取权益奖励
*/
async receiveEnamePrize() {
const _id = '123'; // 测试奖品ID
const success = await API.fn.receiveEnamePrize({ _id });
if (success) {
commonToast('领取成功');
}
}
});
{}
\ No newline at end of file
.test-page {
text-align: center;
padding: 100rpx 0;
}
\ No newline at end of file
<view class="test-page">
测试跳转页面
</view>
\ No newline at end of file
Page({
data: {},
onLoad() {}
});
{}
\ No newline at end of file
import * as tb from './lib/tb';
import * as tbMock from './lib/tbMock';
import * as utils from './lib/utils';
import * as constants from './lib/constants';
import capi from './lib/capi';
import request from './lib/request';
const isH5 = 'undefined' !== typeof window;
// 如果为h5环境走mock数据
let _tb = {};
Object.entries(tb).forEach(([key, value]) => {
_tb[key] = isH5 ? tbMock[key] : value;
});
export default {
capi,
tb: _tb,
utils,
request,
constants
};
\ No newline at end of file
const capi = {
getMyPrizeList:'getMyPrizeList',
receiveObjectPrize: 'receiveObjectPrize',
receiveEnamePrize: 'receiveEnamePrize',
getItemListByItemIds: 'getItemListByItemIds',
getCollectItemList: 'getCollectItemList',
doCollectGoodsTask: 'doCollectGoodsTask',
getVipInfo:'getVipInfo'
};
export default capi;
import { getUserAddress, commonToast } from './tb';
import { getRequestParams } from './utils';
// 通用API封装方法
const capiFn = (apiList, request) => {
return {
async receiveObjectPrize(params) {
const { handle, method, ext } = getRequestParams(apiList['receiveObjectPrize']);
const userAddress = await getUserAddress().catch(err => {
commonToast(err.errorMessage);
});
if (userAddress) {
const { name, phone, address } = userAddress.duibaAddress;
commonConfirm('提示', '确认使用该收货地址:' + name + phone + address, async () => {
params = {
name,
phone,
address,
...params
}
const result = await request(handle, method, params, ext).catch(res => {
commonToast(res && res.message);
});
if (result && result.success) {
return true;
}
});
}
return false;
},
async receiveEnamePrize(params) {
const { handle, method, ext } = getRequestParams(apiList['receiveEnamePrize']);
const result = await request(handle, method, params, ext).catch(res => {
commonToast(res && res.message);
});
if (result && result.success) {
return true;
}
return false;
}
}
};
export default capiFn;
// 分享配置
export const SHARE_CONFIG = {
title: '分享测试标题',
desc: '分享测试描述',
imageUrl: '', // 分享图片URL
path: 'pages/index/index'
};
// 链接配置
export const REDIRECT_URL = {
'testpage': '/pages/testPage/testPage',
'tmall': 'https://www.tmall.com'
};
// 我的奖品状态
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 // 谢谢参与
}
const AMS_URL = 'https://ams.dui88.com/server/index.php?g=Web&c=Mock&o=simple&projectID=218&uri=';
const request = ({ cloud, cloudName, requestType = 'cloud' }) => {
if (!cloud) {
console.error('请传入cloud');
return false;
}
if (!cloudName) {
console.error('请传入云函数名称');
return false;
}
return async (handle, method, params, ext = {}) => {
const { activityId } = getApp();
// 默认注入activityId
params = { activityId, ...params };
if (!params.activityId) {
console.error(`${handle}:请传入activityId`);
return false;
}
const _cloudName = ext.cloudName || cloudName;
const { isShowLoading } = ext;
const hideMyLoading = () => {
if (isShowLoading) {
my.hideLoading();
}
};
if (isShowLoading) {
my.showLoading();
}
const requestAms = () => {
return new Promise((resolve, reject) => {
my.request({
url: AMS_URL + _cloudName + '.' + handle,
method,
data: params,
dataType: 'json'
}).then(({ data: res }) => {
hideMyLoading();
if (res && res.success) {
resolve(res);
} else {
reject(res);
}
}).catch(() => {
hideMyLoading();
reject();
});
})
};
const requestCloud = () => {
return new Promise((resolve, reject) => {
cloud.function.invoke(_cloudName, params, handle).then(res => {
console.log(handle, params, res);
hideMyLoading();
if (res && res.success) {
resolve(res);
} else {
reject(res);
}
return res;
}).catch(() => {
hideMyLoading();
reject();
});
});
};
return requestType === 'ams' ? requestAms() : requestCloud();
};
};
export default request;
\ No newline at end of file
/**
* 通用toast
* @param {string} content toast内容
* @param {number} duration 显示时长
* @param {function} successCb 成功回调
*/
export const commonToast = (content, duration = 3000, successCb) => {
my.showToast({
content: content || '换个姿势再试一次~',
duration,
success: successCb
});
};
/**
* 简易alert
* @param {string} content toast内容
*/
export const simpleAlert = content => {
my.alert({
content
});
};
/**
* 通用确认弹窗
* @param {string} title 标题
* @param {string} content 内容
* @param {function} successCb 成功回调
*/
export const commonConfirm = (title = '提示', content, successCb) => {
my.confirm({
title,
content,
confirmButtonText: '确定',
cancelButtonText: '取消',
success: result => {
const { confirm } = result;
if (confirm) {
successCb && successCb();
}
}
});
};
/**
* 获取授权用户信息
* @returns {object} 用户登录信息
*/
export const getAuthUserInfo = async () => {
return new Promise((resolve, reject) => {
my.authorize({
scopes: 'scope.userInfo',
success: () => {
my.getAuthUserInfo({
success: userInfo => {
resolve(userInfo);
},
fail: err => {
reject(err);
}
});
},
fail: err => {
reject(err);
}
});
});
};
/**
* 获取系统信息
* @returns {object} 小程序系统信息
*/
export const getSystemInfo = async () => {
return new Promise((resolve, reject) => {
my.getSystemInfo({
success: res => {
resolve(res);
},
fail: err => {
reject(err);
}
});
});
};
/**
* 执行关注店铺
* @param {number} sellerId 店铺归属的卖家Id
* @returns {boolean} 关注状态
*/
export const favorShop = async sellerId => {
if (!sellerId) {
console.error('favorShop: 请传入卖家Id');
return false;
}
return new Promise((resolve, reject) => {
my.tb.favorShop({
id: +sellerId,
success: res => {
resolve(res);
},
fail: err => {
if (err.error === 11) {
// error code 11 为用户取消操作不认作失败场景
resolve(false);
}
reject(err);
}
});
});
};
/**
* 判断是否关注店铺
* @param {number} sellerId 店铺归属的卖家Id
* @returns {boolean} 关注状态
*/
export const checkShopFavoredStatus = async sellerId => {
if (!sellerId) {
console.error('checkShopFavoredStatus: 请传入卖家Id');
return false;
}
return new Promise((resolve, reject) => {
my.tb.checkShopFavoredStatus({
id: +sellerId,
success: res => {
resolve(res.isFavor);
},
fail: err => {
reject(err);
}
});
});
};
/**
* 跳转到外部链接
* @param {string} url 跳转链接
*/
export const navigateToOutside = url => {
if (!url) {
console.error('navigateToOutside: 请传入url');
return false;
}
my.call('navigateToOutside', { url });
};
/**
* 跳转到内部链接(新开窗口)
* @param {string} url 跳转链接
*/
export const navigateTo = url => {
if (!url) {
console.error('navigateTo: 请传入url');
return false;
}
my.navigateTo({ url });
};
/**
* 跳转到内部链接(不新开窗口)
* @param {string} url 跳转链接
*/
export const redirectTo = url => {
if (!url) {
console.error('redirectTo: 请传入url');
return false;
}
my.redirectTo({ url });
};
/**
* 获取服务器时间
* @returns {number} 服务器时间戳
*/
export const getServerTime = async () => {
return new Promise((resolve, reject) => {
my.getServerTime({
success: res => {
resolve(res.time);
},
fail: err => {
reject(err);
}
});
});
};
/**
* 收藏商品
* @param {number} 商品id
* @returns {object} 收藏结果
*/
export const collectGoods = async id => {
if (!id) {
console.error('collectGoods: 请传入商品id');
return false;
}
return new Promise((resolve, reject) => {
my.tb.collectGoods({
id: +id,
success: res => {
resolve(res);
},
fail: err => {
if (err.error === 11) {
// error code 11 为用户取消操作不认作失败场景
resolve(false);
}
reject(err);
}
});
});
};
/**
* 查询商品收藏状态
* @param {number} 商品id
* @returns {boolean} 商品收场状态
*/
export const checkGoodsCollectedStatus = async id => {
if (!id) {
console.error('checkGoodsCollectedStatus: 请传入商品id');
return false;
}
return new Promise(resolve => {
my.tb.checkGoodsCollectedStatus({
id: +id,
success: res => {
resolve(res.isCollect);
}
});
});
};
/**
* 跳转到淘宝商品页
* @param {string} itemId 商品ID
*/
export const openDetail = async itemId => {
if (!itemId) {
console.error('openDetail: 请传入商品id');
return false;
}
return new Promise((resolve, reject) => {
my.tb.openDetail({
itemId: itemId + '',
success: res => {
resolve(res);
},
fail: res => {
reject(res);
}
});
});
};
/**
* 创建音频类
*/
class AudioModel {
constructor(opts = {}) {
const { src } = opts;
if (!src) {
console.error('请输入音频链接');
return false;
}
try {
const innerAudioContext = my.createInnerAudioContext();
Object.keys(opts).forEach(item => {
innerAudioContext[item] = opts[item];
});
return innerAudioContext;
} catch (e) {
console.error('当前版本不支持音频');
}
}
}
/**
* 创建音频实例
* @param {object} opts 配置对象 例 { src: '音频链接', autoplay: false }
*/
export const createAudio = opts => {
const audioInstance = new AudioModel(opts);
return audioInstance;
};
/**
* 获取淘宝用户收货地址
*/
export const getUserAddress = async (opts = {}) => {
let defaults = {
addAddress: 'show',
searchAddress: 'hide',
locateAddress: 'hide',
joinTag: '' // 分割收货地址符号(淘宝商家有特定发货需求)
};
let _opts = Object.assign({}, defaults, opts);
return new Promise((resolve, reject) => {
my.authorize({
scopes: 'scope.addressList',
success: () => {
const { addAddress, searchAddress, locateAddress, joinTag } = _opts;
if (!my.tb.chooseAddress) {
reject({
noSupport: true,
errorMessage: '当前版本不支持选择收货地址,请升级到最新版本'
});
return false;
}
my.tb.chooseAddress(
{
addAddress,
searchAddress,
locateAddress
},
res => {
const { error, provinceName, countyName, cityName, streetName, detailInfo, name, telNumber } = res;
// 如果有error为用户取消操作不做操作
if (error) {
resolve(false);
} else {
resolve({
...res,
duibaAddress: {
name,
phone: telNumber,
address: [provinceName, cityName, countyName, streetName, detailInfo].join(joinTag)
}
});
}
},
res => {
reject(res);
}
);
}
});
});
};
/**
* 选择图片
*/
export const chooseImage = async (opts = {}) => {
let defaults = {
count: 1,
sourceType: ['camera', 'album'],
compressLevel: 1
};
let _opts = Object.assign({}, defaults, opts);
const { count, sourceType, compressLevel } = _opts;
return new Promise((resolve, reject) => {
if (!my.chooseImage) {
reject({
noSupport: true,
errorMessage: '当前版本不支持选择收货地址,请升级到最新版本'
});
return false;
}
my.chooseImage({
count,
sourceType,
success: res => {
my.compressImage({
apFilePaths: res.apFilePaths,
level: compressLevel,
success: data => {
resolve(data);
},
fail: err => {
resolve(err);
}
});
},
fail: err => {
// error code 2001 为摄像头授权取消、ios 11为用户取消操作不认作失败场景 、安卓 为1
if (err.error !== 2001 && err.error !== 11 && err.error !== 1) {
reject(err);
} else {
resolve(false);
}
}
});
});
};
/**
* 获取图片信息
* @param {string} src 图片地址
*/
export const getImageInfo = async src => {
return new Promise((resolve, reject) => {
my.getImageInfo({
src,
success: res => {
resolve(res);
},
fail: err => {
reject(err);
}
});
});
};
/**
* 获取图片信息
* @param {*} opts chooseImage配置参数
*/
export const uploadImage = async (opts = {}) => {
const { cloud } = getApp();
if (!cloud) {
console.error('chattingSendCard: 请传入app.cloud');
return false;
}
const chooseImageResult = await chooseImage(opts).catch(err => {
commonToast(err && (err.errorMessage || '选择图片失败'));
});
if (chooseImageResult) {
const { apFilePaths } = chooseImageResult;
const filePath = apFilePaths[0];
const imageInfo = await getImageInfo(filePath).catch(err => {
commonToast(err && err.errorMessage);
});
// 找不到图片信息
if (!imageInfo) {
return false;
}
const { path: imagePath } = imageInfo;
const { url } = await cloud.file.uploadFile({
filePath,
fileType: 'image',
fileName: imagePath.split('/').pop()
});
return url;
}
return false;
}
/**
* 分享到群聊卡片
* @param {object} requestInfo 分享到群聊卡片所需请求参数
*/
export const chattingSendCard = async (requestInfo) => {
const { cloud } = getApp();
if (!cloud) {
console.error('chattingSendCard: 请传入app.cloud');
return false;
}
if (!requestInfo) {
console.error('chattingSendCard: 请传入卡片请求参数');
return false;
}
return new Promise((resolve, reject) => {
my.authorize({
scopes: 'scope.groupChat',
success: async () => {
const result = await cloud.topApi
.invoke({
api: 'taobao.chatting.platform.message.sendcard',
data: { request_info: JSON.stringify(requestInfo) }
})
.catch(err => {
reject(err);
});
if (result) {
const { error } = result;
if (error) {
resolve(false);
} else {
resolve(result);
}
}
},
fail: err => {
if (err.error === 11) {
// error code 11 为用户取消操作不认作失败场景
resolve(false);
}
reject(err);
}
});
});
};
/**
* 分享到群聊卡片
* @param {*} cloud 小程序云
* @param {object} requestInfo 分享到群聊卡片所需请求参数
*/
export const textRiskIdentification = async (text) => {
return new Promise((resolve, reject) => {
if (!my.tb.textRiskIdentification) {
reject({
noSupport: true,
errorMessage: '不支持文本校验'
});
}
my.tb.textRiskIdentification({
data:{
text
},
success: res => {
if (res.data && res.data.result) {
const { suggestion }= res.data.result;
if (suggestion === 'pass') {
resolve(true);
}
}
resolve(false);
},
fail: err => {
reject(err)
},
})
})
}
// 剪切板
export function setClipboard(params) {
return promisifyMyApi('setClipboard', params)
};
function promisifyMyApi(methodName, params = {}) {
return new Promise((resolve, reject) => {
my[methodName]({
...params,
success: res => {
resolve(res)
},
fail: err => {
reject(err)
}
})
})
}
/**
* 通用toast
* @param {string} content toast内容
* @param {number} duration 显示时长
* @param {function} successCb 成功回调
*/
export const commonToast = (content, duration = 3000, successCb) => {
return '暂不支持toast';
};
/**
* 简易alert
* @param {string} content toast内容
*/
export const simpleAlert = content => {
alert(content);
};
/**
* 通用确认弹窗
* @param {string} title 标题
* @param {string} content 内容
* @param {function} successCb 成功回调
*/
export const commonConfirm = (title = '提示', content, successCb) => {
my.confirm({
title,
content,
confirmButtonText: '确定',
cancelButtonText: '取消',
success: result => {
const { confirm } = result;
if (confirm) {
successCb && successCb();
}
}
});
};
/**
* 获取授权用户信息
* @returns {object} 用户登录信息
*/
export const getAuthUserInfo = async () => {
return {
nickName: 'nickName',
avatar: '123',
mixNick: '1234'
};
};
/**
* 获取系统信息
* @returns {object} 小程序系统信息
*/
export const getSystemInfo = async () => {
return {
version: '9.5.0'
};
};
/**
* 执行关注店铺
* @param {number} sellerId 店铺归属的卖家Id
* @returns {boolean} 关注状态
*/
export const favorShop = async sellerId => {
if (!sellerId) {
console.error('favorShop: 请传入卖家Id');
return false;
}
return {};
};
/**
* 判断是否关注店铺
* @param {number} sellerId 店铺归属的卖家Id
* @returns {boolean} 关注状态
*/
export const checkShopFavoredStatus = async sellerId => {
if (!sellerId) {
console.error('checkShopFavoredStatus: 请传入卖家Id');
return false;
}
return true;
};
/**
* 跳转到外部链接
* @param {string} url 跳转链接
*/
export const navigateToOutside = url => {
if (!url) {
console.error('navigateToOutside: 请传入url');
return false;
}
window.location = url;
};
/**
* 跳转到内部链接(新开窗口)
* @param {string} url 跳转链接
*/
export const navigateTo = url => {
if (!url) {
console.error('navigateTo: 请传入url');
return false;
}
window.location = url;
};
/**
* 跳转到内部链接(不新开窗口)
* @param {string} url 跳转链接
*/
export const redirectTo = url => {
if (!url) {
console.error('redirectTo: 请传入url');
return false;
}
window.replace(url);
};
/**
* 获取服务器时间
* @returns {number} 服务器时间戳
*/
export const getServerTime = async () => {
return +new Date();
};
/**
* 收藏商品
* @param {number} 商品id
* @returns {object} 收藏结果
*/
export const collectGoods = async id => {
if (!id) {
console.error('collectGoods: 请传入商品id');
return false;
}
return new Promise((resolve, reject) => {
my.tb.collectGoods({
id,
success: res => {
resolve(res);
},
fail: err => {
if (err.errorMessage === '该商品已收藏') {
// 已收藏没有给到errorCode,只能通过message判断
// 返回收藏成功,并且给到标记代表是已收藏的
resolve({ success: true, hasCollected: true, errorMessage: err.errorMessage });
} else if (err.error !== 11) {
// error code 11 为用户取消操作不认作失败场景
reject(err);
}
}
});
});
};
/**
* 查询商品收藏状态
* @param {number} 商品id
* @returns {boolean} 商品收场状态
*/
export const checkGoodsCollectedStatus = async id => {
if (!id) {
console.error('checkGoodsCollectedStatus: 请传入商品id');
return false;
}
return new Promise((resolve) => {
my.tb.checkGoodsCollectedStatus({
id,
success: res => {
resolve(res.isCollect);
}
});
});
};
/**
* 跳转到淘宝商品页
* @param {string} itemId 商品ID
*/
export const openDetail = async itemId => {
if (!itemId) {
console.error('openDetail: 请传入商品id');
return false;
}
window.location = 'https://item.taobao.com/item.htm?id=' + itemId;
};
/**
* 获取淘宝用户收货地址
*/
export const getUserAddress = async (opts = {}) => {
return {
name: 1,
phone: 1,
address: 123
}
};
/**
* 选择图片
*/
export const chooseImage = async (opts = {}) => {
let defaults = {
count: 1,
sourceType: ['camera', 'album'],
compressLevel: 1
};
let _opts = Object.assign({}, defaults, opts);
const { count, sourceType, compressLevel } = _opts;
return new Promise((resolve, reject) => {
if (!my.chooseImage) {
reject({
noSupport: true,
errorMessage: '当前版本不支持选择收货地址,请升级到最新版本'
});
return false;
}
my.chooseImage({
count,
sourceType,
success: res => {
my.compressImage({
apFilePaths: res.apFilePaths,
level: compressLevel,
success: data => {
resolve(data);
},
fail: err => {
resolve(err);
}
});
},
fail: err => {
// error code 2001 为摄像头授权取消、ios 11为用户取消操作不认作失败场景 、安卓 为1
if (err.error !== 2001 && err.error !== 11 && err.error !== 1) {
reject(err);
} else {
resolve(false);
}
}
});
});
};
/**
* 获取图片信息
* @param {string} src 图片地址
*/
export const getImageInfo = async src => {
return new Promise((resolve, reject) => {
my.getImageInfo({
src,
success: res => {
resolve(res);
},
fail: err => {
reject(err);
}
});
});
};
/**
* 获取图片信息
* @param {*} opts chooseImage配置参数
*/
export const uploadImage = async (opts = {}) => {
const { cloud } = getApp();
if (!cloud) {
console.error('chattingSendCard: 请传入app.cloud');
return false;
}
const chooseImageResult = await chooseImage(opts).catch(err => {
commonToast(err && (err.errorMessage || '选择图片失败'));
});
if (chooseImageResult) {
const { apFilePaths } = chooseImageResult;
const filePath = apFilePaths[0];
const imageInfo = await getImageInfo(filePath).catch(err => {
commonToast(err && err.errorMessage);
});
// 找不到图片信息
if (!imageInfo) {
return false;
}
const { path: imagePath } = imageInfo;
const { url } = await cloud.file.uploadFile({
filePath,
fileType: 'image',
fileName: imagePath.split('/').pop()
});
return url;
}
return false;
}
/**
* 分享到群聊卡片
* @param {object} requestInfo 分享到群聊卡片所需请求参数
*/
export const chattingSendCard = async (requestInfo) => {
alert('无法模拟');
return false;
};
/**
* 分享到群聊卡片
* @param {*} cloud 小程序云
* @param {object} requestInfo 分享到群聊卡片所需请求参数
*/
export const textRiskIdentification = async (text) => {
return true;
}
\ No newline at end of file
import capiFn from './capiFn';
/**
* 时间格式化
* @param date 接收可以被new Date()方法转换的内容
* @param format 字符串,需要的格式例如:'yyyy/MM/dd hh:mm:ss'
* @returns {String}
*/
export const dateFormatter = (date, format = 'yyyy/MM/dd') => {
if (!date) return '-';
date = new Date(
typeof date === 'string' && isNaN(date) ? date.replace(/-/g, '/') : date
);
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds(),
'q+': Math.floor((date.getMonth() + 3) / 3),
S: date.getMilliseconds()
};
if (/(y+)/.test(format)) {
format = format.replace(
RegExp.$1,
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
);
}
for (let k in o) {
if (new RegExp('(' + k + ')').test(format)) {
format = format.replace(
RegExp.$1,
RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
);
}
}
return format;
};
/**
* 版本比较
* @param {string} cur 当前版本
* @param {string} compare 比较版本
*/
export const versionCompare = (cur, compare) => {
const _cur = cur.split('.');
const _compare = compare.split('.');
if (+_cur[0] < +_compare[0]) {
return false;
} else if ( +_cur[0] === +_compare[0] && +_cur[1] < +_compare[1] ) {
return false;
} else if (+_cur[0] === +_compare[0] && +_cur[1] === +_compare[1] && +_cur[2] < +_compare[2]) {
return false;
}
return true;
};
/**
* 获取request请求所需参数
* @param {object/string} value API项配置
*/
export const getRequestParams = value => {
if (typeof value === 'string') {
return {
handle: value,
method: 'POST',
ext: {}
}
} else if (typeof value === 'object') {
const { handle, method = 'POST', ...ext } = value;
return {
handle,
method,
ext: { ...ext }
}
} else {
console.error('getRequestParams: 传参有误');
}
};
/**
* 生成API
* @param {array} apiList API数据数组
* @param {function} request 请求
*/
export const generateAPI = (apiList, request) => {
const api = {};
Object.entries(apiList).forEach(([key, value]) => {
const { handle, method, ext } = getRequestParams(value);
api[key] = params => request(handle, method, params, ext);
});
api.fn = capiFn(apiList, request);
return api;
};
\ No newline at end of file
import cloud from './node_modules/@tbmp/mp-cloud-sdk/types/platforms/mp';
import tbcc from './tbcc-sdk';
cloud.init({
env: 'test' // 云函数环境 test 测试环境 online 线上环境
});
App({
requestType: 'cloud', // ams:ams接口,cloud: 云函数
cloudName: 'skechRun', // 主云函数项目名 base clientTemplate2C
cloud,
tbcc,
onLaunch(options) {
this.handleQuery(options.query || {});
},
onShow(options) {
// 从后台被 scheme 重新打开
console.log('执行了app onshow')
},
/**
* 处理链接参数
* @param {object} query 小程序链接上的参数
*/
handleQuery(query) {
const { activityId } = query;
this.activityId = activityId || '5f4605629897b44ce119d8f1';
}
});
import { Db } from "./node_modules/@tbmp/mp-cloud-sdk/types/core/db/dbp/mp-cloud-sdk/types/core/db/db";
export default Db;
import {ICloudService} from "./node_modules/@tbmp/mp-cloud-sdk/types/core/interface/cloudServicee/interface/cloudService";
export default class Process extends ICloudService {
invoke(options: { api: string, data?: any, headers?: any }): Promise<any>;
private topRequest;
}
import {ICloudService} from "./node_modules/@tbmp/mp-cloud-sdk/types/core/interface/cloudServicee/interface/cloudService";
export default class Qimen extends ICloudService {
invoke(options: { api: string, data?: any, targetAppKey?: any, headers?: any }): Promise<any>;
private topRequest;
}
import {ICloudService} from "./node_modules/@tbmp/mp-cloud-sdk/types/core/interface/cloudServicee/interface/cloudService";
export default class Top extends ICloudService {
invoke(options: { api: string, data?: any, headers?: any, authScope?: string }): Promise<any>;
private topRequest;
}
import {IProxy} from '@tbmp/mp-cloud-sdk/types/shared/request';
import {ICloudOptions} from '@tbmp/mp-cloud-sdk/types/shared/types';
import CloudFunction from '@tbmp/mp-cloud-sdk/types/core/functions';
import CloudStorage from '@tbmp/mp-cloud-sdk/types/core/storage';
import Db from '../../core/db';
import Top from '../../core/openApi/client/top';
import Qimen from '../../core/openApi/client/qimen';
import Process from '../../core/openApi/client/process';
import Application from './node_modules/@tbmp/mp-cloud-sdk/types/core/openApi/client/application';
export declare class Cloud {
function: CloudFunction;
file: CloudStorage;
db: Db;
topApi: Top;
qimenApi: Qimen;
processApi: Process;
application: Application;
init(options: ICloudOptions, proxy?: IProxy): Promise<boolean>;
}
declare const _default: Cloud;
export default _default;
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