Authored by 邱骏

限购码

{
"extends": "stylelint-config-yoho",
"rules": {
"string-quotes": "double",
"string-quotes": null,
"no-empty-source": null,
"unit-no-unknown": [
true,
... ...
... ... @@ -5,7 +5,8 @@
"pages/account/chooseArea",
"pages/account/bindMobile",
"pages/product/detail/detail",
"pages/share/share"
"pages/share/share",
"pages/webview/webview"
],
"window": {
"backgroundTextStyle": "dark",
... ... @@ -13,7 +14,7 @@
"navigationBarTitleText": "限定发售",
"navigationBarTextStyle": "white",
"backgroundColor": "#fff",
"onReachBottomDistance": 250
"onReachBottomDistance": 300
},
"debug": true
}
... ...
... ... @@ -107,6 +107,7 @@ function wechatUserIsBind(unionID, nickName) {
userInfo.ssouid = data.data.ssouid;
userInfo.uid = data.data.uid;
userInfo.sessionKey = data.data.session_key;
userInfo.wechat = app.globalData.userInfo.wechat || '';
app._removeSync('disableAutoLogin');
app.setUserInfo(userInfo);
... ... @@ -283,6 +284,7 @@ function getPhoneNumber(e) {
userInfo.mobile = res.data.profile;
userInfo.ssouid = res.data.ssouid;
userInfo.sessionKey = res.data.session_key;
userInfo.wechat = app.globalData.userInfo.wechat || '';
app._removeSync('disableAutoLogin');
app.setUserInfo(userInfo);
... ... @@ -327,9 +329,14 @@ function getUserInfo(e) {
code: 500,
message: 'getUserInfo authorize fail'
});
} else {
console.log(e.detail);
let userInfo = Object.assign(app.globalData.userInfo, { wechat: e.detail.userInfo});
app.setUserInfo(userInfo);
}
console.log(e.detail);
wx.showLoading();
event.emit('enable-tap-login');
... ... @@ -380,11 +387,11 @@ function getUserInfo(e) {
function getLoginButtonType() {
let app = getApp() || {};
if (app && app.getUid()) {
if (app && app.getUid() && app.globalData.userInfo.wechat) {
return ''; // 已经是登录状态,合法用户
}
let isUnionID = app && app.globalData.unionID && app.globalData.userInfo.head_img;// 如果有unionID情况
let isUnionID = app && app.globalData.unionID && app.globalData.userInfo.wechat;// 如果有unionID情况
let isPhoneNumber = isUnionID ? !(app && app.getUid()) : false; // 如果有unionID且没有uid,可以获取手机号自动绑定登录
if (app._getSync('disableAutoLogin')) { // 手动退出,走手机号登录页面
... ...
... ... @@ -233,5 +233,17 @@ export default {
return api.get({
url: '/smart/way',
});
},
/**
* 获取限购码列表
*/
getLimitCodes() {
return api.get({
url: '',
data: {
method: 'app.limitcode.query'
}
});
}
};
... ...
// index.js
import wx from '../../utils/wx';
import event from '../../common/event';
import { getLoginButtonType } from '../../common/login';
import { parse } from '../../vendors/query-stringify';
import {getLoginButtonType} from '../../common/login';
import {parse} from '../../vendors/query-stringify';
import accountModel from '../../models/account/index';
import Promise from '../../vendors/es6-promise';
import config from '../../common/config';
import Yas from '../../common/yas';
import helper from '../../utils/helper';
let app = getApp();
let yas;
... ... @@ -15,17 +16,52 @@ let router = global.router;
Page({
data: {
loginButtonType: '', // 获取登录button-type
channellist: [],
userInfo: {
phoneNum: '',
avatarUrl: '',
defaultAvatar: false,
nickName: ''
nickName: '',
wechat: ''
},
coinNum: 0,
isBound: false,
myQrCodeUrl: 'https://m.yohobuy.com/home/newQrcode?needLogin=1',
loginText: '点击登录'
loginText: '点击登录',
test_uid: [
349709, // 测试用
500030924,
500030922,
500030918,
500030916,
500030914,
500030912,
500030910,
500030908,
500030906,
500030904,
500030890,
500030888,
500030886,
500030884,
500030876,
500030830,
500030694,
500030690,
500030688
],
now_test_uid_index: 1,
containerHeight: '1006rpx',
h5PageUrl: [
{
title: '如何获得限购码?',
url: 'https://activity.yoho.cn/feature/247.html?nodownload=1'
}
],
limitCodes: {
codes: [],
invalidCodes: []
},
isShow: 0
},
onLoad: function() {
let that = this;
... ... @@ -39,13 +75,14 @@ Page({
loginText: params.text || '点击登录'
});
});
},
onShow: function() {
setTimeout(() => {
app = app || getApp();
this.showBindUserInfo();
}, app ? 0 : 1000);
},
onReady: function() {
... ... @@ -66,15 +103,19 @@ Page({
loginButtonType: getLoginButtonType()
});
if (app && app.getUid()) {
if (app && app.getUid() && app.getUserInfo().wechat) {
return Promise.all([
accountModel.getProfile(),
accountModel.getCoinTotal(),
accountModel.getLimitCodes()
]).then(res => {
let defaultAvatar = '../../static/images/icons/default-avatar.png';
let defaultAvatar = (app.globalData.userInfo.wechat &&
app.globalData.userInfo.wechat.avatarUrl) ||
'../../static/images/icons/default-avatar.png';
let resUserInfo = res[0].data || {};
console.log('resUserInfo:', resUserInfo);
console.log('limitInfo:', res[2]);
let user = Object.assign({}, this.data.userInfo, app.globalData.userInfo, {
nickName: resUserInfo.nickname,
... ... @@ -85,12 +126,13 @@ Page({
app.setUserInfo(user);// 把用户信息写入storage
that.setData({
isBound: true,
userInfo: user,
coinNum: res[1].data && res[1].data.total || 0
});
that.setLimitCodeList(res[2]);
}).catch({});
}
},
... ... @@ -110,5 +152,59 @@ Page({
});
}
});
},
setLimitCodeList: function(res) { // 处理限购码列表的数据
let that = this;
let invalidCodes = [];
let codes = [];
res.data.invalidLimitCodeProducts.forEach((item, index) => {
item.defaultUrl = helper.image(item.defaultUrl, 220, 138, 1);
invalidCodes.push(item);
});
res.data.limitCodeProducts.forEach((item, index) => {
item.defaultUrl = helper.image(item.defaultUrl, 220, 138, 1);
codes.push(item);
});
this.setData({
limitCodes: {
invalidCodes: invalidCodes,
codes: codes
},
isShow: 1
});
// 通过顶部和底部按钮的高度,计算中间限购码部分的高度
let sysInfo = wx.getSystemInfoSync();
let windowHeight = sysInfo.windowHeight;
let query = wx.createSelectorQuery();
query.select('.user-info-bar').boundingClientRect();
query.select('.out-login').boundingClientRect();
query.exec(result => {
let topHeight = result[0].height;
let bottomHeight = result[1].height;
let containerHeight = (windowHeight - topHeight - bottomHeight - 20 - 30) + 'px';
that.setData({
containerHeight: containerHeight
});
});
},
navigateToh5Page: function(e) {
console.log(e);
let type = e.currentTarget.dataset.type || 0;
let type_obj = this.data.h5PageUrl[type];
let url = type_obj.url + '&title=' + type_obj.title;
router.goUrl(url);
},
navigateToLimitListPage: function() {
router.go('home');
}
});
... ...
... ... @@ -17,6 +17,97 @@
<text class="coin">积分:<text class="num">{{coinNum}}</text></text>
</view>
</view>
<!-- 我的限购码 -->
<view wx:if="{{isBound}}" class='container {{!limitCodes.invalidCodes.length && !limitCodes.codes.length ? "no-code" : ""}}' style='{{!limitCodes.invalidCodes.length && !limitCodes.codes.length ? "height:" + containerHeight : ""}}'>
<!--限购码介绍-->
<view class='desc-container'>
<block wx:for='{{h5PageUrl}}' wx:key='item.title'>
<view class='link-menu' bindtap='navigateToh5Page' data-type='{{index}}'>
<text>{{item.title}}</text>
<view class='link-arrow'>
<image src='../../static/images/limit/arrow.png'></image>
</view>
</view>
</block>
<view class='gray-space'></view>
<!--灰色的间隔-->
</view>
<view wx:if='{{isShow}}' class='limit-code-container'>
<block wx:if='{{!limitCodes.invalidCodes.length && !limitCodes.codes.length}}'>
<view class='icon'>
<image src='../../static/images/limit/lock_b.png'></image>
</view>
<view class='text'>
<text>暂无限购码</text>
</view>
<button class='button' bindtap='navigateToLimitListPage'>随便看看</button>
</block>
<block wx:else>
<block wx:for='{{limitCodes.codes}}' wx:key='item.limitCode'>
<view class='limit-code-item'>
<view class='item-container'>
<view class='item-head'>
<image src='../../static/images/limit/lock_s.png'></image>
<text>限购码:{{item.limitCode}}</text>
</view>
<view class='item-content'>
<image src='{{item.defaultUrl}}'></image>
<view class='item-content-info'>
<view class='info-title'>
<text>{{item.productName}}</text>
</view>
<view class='info-uc'>
<text></text>
</view>
<view class='info-price'>
<text>{{item.price}}</text>
</view>
</view>
</view>
</view>
</view>
<view class='gray-space'></view>
<!--灰色的间隔-->
</block>
<block wx:if='{{limitCodes.invalidCodes.length}}'>
<view class='codes-spliter'>
<text>已失效</text>
</view>
<view class='gray-space'></view>
</block>
<block wx:for='{{limitCodes.invalidCodes}}' wx:key='item.limitCode'>
<view class='limit-code-item' data->
<view class='item-container'>
<view class='item-head'>
<image src='../../static/images/limit/lock_s.png'></image>
<text>限购码:{{item.limitCode}}</text>
<view class='item-invalid-icon'>
<text>失效</text>
</view>
</view>
<view class='item-content'>
<image src='{{item.defaultUrl}}'></image>
<view class='item-content-info'>
<view class='info-title'>
<text>{{item.productName}}</text>
</view>
<view class='info-uc'>
<text></text>
</view>
<view class='info-price'>
<text>{{item.price}}</text>
</view>
</view>
</view>
</view>
</view>
<view class='gray-space'></view>
<!--灰色的间隔-->
</block>
</block>
</view>
</view>
<view class="out-login" bindtap="outLogin" wx:if="{{userInfo.uid}}">退出登录</view>
</view>
... ...
... ... @@ -8,86 +8,6 @@ page {
height: 100%;
}
.channel-list {
padding-top: 20rpx;
}
.channel-list .list-item {
width: 690rpx;
height: 176rpx;
background-color: #fff;
margin: 0 30rpx 20rpx;
border-radius: 6rpx;
}
.channel-list .list-item .item-left {
float: left;
border-right: 1rpx solid #e0e0e0;
width: 469rpx;
height: 108rpx;
overflow: hidden;
margin: 35rpx 0 25rpx 0;
}
.channel-list .list-item .item-left .ico {
width: 76rpx;
height: 76rpx;
margin: 15rpx 20rpx 0 30rpx;
}
.channel-list .list-item .item-left .channel-name {
position: relative;
top: -25rpx;
font-size: 34rpx;
color: #444;
}
.channel-list .list-item .item-left .partial {
top: -48rpx;
}
.channel-list .list-item .item-left .vip-growth {
font-size: 28rpx;
color: #b0b0b0;
letter-spacing: -0.4rpx;
display: inline-block;
width: 100%;
position: relative;
top: -27px;
left: 126rpx;
}
.channel-list .list-item .item-left .vip {
margin-right: 10px;
}
.channel-list .list-item .item-right {
width: 220rpx;
height: 100%;
float: right;
}
.channel-list .list-item .item-right .num {
font-size: 60rpx;
color: #222;
letter-spacing: -0.42px;
display: inline-block;
width: 100%;
text-align: center;
margin-top: 22rpx;
font-weight: bold;
}
.channel-list .list-item .item-right .captions {
font-size: 28rpx;
color: #444;
letter-spacing: -0.4rpx;
width: 100%;
display: block;
text-align: center;
margin-top: 3rpx;
}
.userinfo {
display: flex;
flex-direction: column;
... ... @@ -228,3 +148,230 @@ page {
line-height: 88rpx;
text-align: center;
}
/* 限购码 */
scroll-view {
background-color: #f0f0f0;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
box-sizing: border-box;
padding: 0;
background-color: #fff;
margin-top: 20rpx;
}
.desc-container {
display: flex;
flex-direction: column;
justify-content: flex-start;
width: 100%;
}
.link-menu {
display: flex;
flex-direction: row;
align-items: center;
height: 70rpx;
border-bottom: 1px solid #f0f0f0;
font-size: 24rpx;
box-sizing: border-box;
}
.link-menu text {
margin-left: 30rpx;
}
.link-menu .link-arrow {
display: flex;
flex: 1;
justify-content: flex-end;
}
.link-menu image {
width: 12rpx;
height: 24rpx;
margin-right: 30rpx;
}
.limit-code-container {
display: flex;
flex-direction: column;
width: 100%;
background-color: #f0f0f0;
}
.container.no-code .limit-code-container {
background-color: #fff;
}
.limit-code-container view {
background-color: #fff;
}
.limit-code-container .icon {
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
height: 146rpx;
margin-top: 198rpx;
}
.icon image {
width: 120rpx;
height: 146rpx;
}
.limit-code-container .text {
display: flex;
width: 100%;
justify-content: center;
margin-top: 60rpx;
font-size: 28rpx;
line-height: 40rpx;
}
.limit-code-container .button {
width: 472rpx;
height: 88rpx;
margin-top: 130rpx;
font-size: 28rpx;
color: #fff;
line-height: 88rpx;
background-color: #444;
margin-bottom: 20rpx;
}
.limit-code-container .limit-code-item {
display: flex;
flex-direction: row;
justify-content: flex-end;
height: 268rpx;
}
.limit-code-item .item-container {
width: 720rpx;
height: 100%;
box-sizing: border-box;
}
.item-container .item-head {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 88rpx;
font-size: 28rpx;
}
.item-head image {
width: 28rpx;
height: 28rpx;
margin-right: 6rpx;
}
.item-head .item-invalid-icon {
width: 64rpx;
height: 30rpx;
margin-left: 340rpx;
border-radius: 20rpx;
box-sizing: border-box;
font-size: 20rpx;
color: #fff;
text-align: center;
line-height: 30rpx;
background-color: #b0b0b0;
}
.item-container .item-content {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 180rpx;
border-top: 1px solid #f0f0f0;
}
.item-content image {
width: 220rpx;
height: 138rpx;
margin-right: 20rpx;
}
.item-content .item-content-info {
display: flex;
flex-direction: column;
width: 450rpx;
height: 138rpx;
}
.item-content-info .info-title {
height: 68rpx;
line-height: 34rpx;
font-size: 24rpx;
}
.item-content-info .info-uc {
flex-shrink: 0;
height: 34rpx;
margin-top: 4rpx;
font-size: 24rpx;
color: #bdbdbd;
line-height: 34rpx;
}
.item-content-info .info-price {
font-size: 24rpx;
line-height: 34rpx;
}
.gray-space {
height: 20rpx;
background: #f0f0f0 !important;
}
.codes-spliter {
position: relative;
width: 100%;
height: 50rpx;
font-size: 24rpx;
color: #bdbdbd;
text-align: center;
line-height: 50rpx;
background-color: #f0f0f0 !important;
}
.codes-spliter:before {
content: '';
position: absolute;
width: 280rpx;
height: 25rpx;
left: 30rpx;
top: 0;
border-bottom: 2rpx solid #bdbdbd;
transform-origin: 50% 100%;
transform: scaleY(0.3);
box-sizing: border-box;
z-index: 9;
}
.codes-spliter:after {
content: '';
position: absolute;
width: 280rpx;
height: 25rpx;
right: 30rpx;
top: 0;
border-bottom: 2rpx solid #bdbdbd;
transform-origin: 50% 100%;
transform: scaleY(0.3);
box-sizing: border-box;
z-index: 9;
}
... ...
... ... @@ -126,7 +126,7 @@ Page({
if (isBottom) {
list[index].page = page;
list[index].limitProductVoList =
list[index].limitProductVoList.concat(res.data.limitProductVoList);
list[index].limitProductVoList.concat(res.data.limitProductVoList);
} else {
list[index] = res.data;
}
... ...
import {parse, stringify} from '../../vendors/query-stringify';
import config from '../../common/config';
import udid from '../../common/udid';
import event from '../../common/event';
import { verify } from '../../common/api';
import { tapGoLogin } from '../../common/login';
Page({
/**
* 页面的初始数据
*/
data: {
url: ''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
console.log(options);
options.url = decodeURIComponent(options.url || '');
if (options.url) {
let uid = this.getUid();
const search = options.url.split('?')[1] || '';
const qs = parse(search);
if (Number(qs.needLogin) === 1 && uid === 0) {
event.on('user-login-success', () => {
this.generateUrl(options);
});
tapGoLogin();
} else {
this.generateUrl(options);
}
}
},
/**
* 获取 UID
*/
getUid: function() {
const app = getApp() || {};
return app.globalData &&
app.globalData.userInfo &&
app.globalData.userInfo.uid ?
app.globalData.userInfo.uid : 0;
},
/**
* 生成链接
*/
generateUrl: function(options) {
const app = getApp() || {};
let param = {
app_version: config.apiParams.app_version,
session_key: app.globalData && app.globalData.sessionKey || '',
client_type: config.apiParams.client_type,
udid: udid.get()
};
let uid = this.getUid();
if (uid) {
param.uid = uid;
}
let url = options.url;
let params = verify.computeSecret(param);
const [uri, search] = url.split('?');
const qs = parse(search);
this.setData({
url: uri + '?' + stringify(Object.assign({}, params, qs))
});
}
});
... ...
{}
\ No newline at end of file
... ...
<web-view src="{{url}}"></web-view>
\ No newline at end of file
... ...
/* pages/webview.wxss */
... ...
var regExpWidth = new RegExp('{width}', 'g');
var regExpHeight = new RegExp('{height}', 'g');
var regExpMode = new RegExp('{mode}', 'g');
var regExpQg = new RegExp('/q/d+', 'g');
var regExpQ = new RegExp('/q/d+');
var regExpQuality = new RegExp('/quality/d+');
var regExpQualityg = new RegExp('/quality/d+', 'g');
var regExpImageView = new RegExp('imageView');
var regExpImageMogr = new RegExp('imageMogr');
var defaultQuality = 75;
function image(imgUrl, w, h, mode, q) {
var urls,
query,
url;
var params = {
w: w,
h: h,
mode: mode || 2,
q: q || defaultQuality
};
if (imgUrl && (typeof imgUrl === 'string')) {
urls = imgUrl.split('?');
query = urls[1] || '';
url = urls[0];
if (url.indexOf('http:') === 0) {
url = url.replace('http:', 'https:');
}
if (!query || query === 'imageslim') {
url += params.q === defaultQuality ? '?imageslim' : '?imageView2/0/interlace/1/q/' + params.q;
imgUrl = url;
} else {
imgUrl = imgUrl.replace(regExpWidth, params.w)
.replace(regExpHeight, params.h)
.replace(regExpMode, (params.mode));
if (regExpImageView.test(query)) { // imageView2 || imageView
if (!regExpQ.test(query)) {
imgUrl += '/q/' + params.q;
} else {
imgUrl = imgUrl.replace(regExpQg, '/q/' + params.q);
}
} else if (regExpImageMogr.test(query)) {
if (!regExpQuality.test(query)) {
imgUrl += '/quality/' + params.q;
} else {
imgUrl = imgUrl.replace(regExpQualityg, '/quality/' + params.q);
}
}
}
return imgUrl;
} else {
return '';
}
}
// 如果图片没有imageView2,则默认添加imageView2
function imgView(imgSrc, w, h, mode, q) {
var imgUrl = imgSrc || '';
var indexOf = imgUrl.indexOf('?');
if (!imgUrl) {
return '';
}
if (imgUrl.indexOf('http://') === imgUrl.indexOf('https://')) {
return imgUrl;
}
if (['http://', 'https://'].indexOf((imgUrl || '')) === -1) {
return imgUrl;
}
if (indexOf === -1) {
imgUrl += '?imageView2/{mode}/w/{width}/h/{height}';
return image(imgUrl, w, h, mode, q);
}
if (indexOf > -1) {
return image(imgUrl, w, h, mode, q);
}
return imgUrl;
}
module.exports = {
image: image,
imgView: imgView
};
... ...