Authored by 陈峰

Merge branch 'release/0718' into 'gray'

Release/0718



See merge request !1482
Showing 46 changed files with 1208 additions and 137 deletions
... ... @@ -51,6 +51,10 @@ exports.check = (req, res, next) => {
};
exports.geetestLoad = (req, res, next) => {
if (req.user.uid) {
return next();
}
req.yoho.captchaShow = false;
res.locals.useGeetest = true;
... ... @@ -72,7 +76,7 @@ exports.geetestLoad = (req, res, next) => {
exports.geetestCheck = (req, res, next) => {
let testCode = req.body.yohobuy;
if (testCode === global.yoho.config.testCode) {
if (testCode === global.yoho.config.testCode || req.user.uid) {
return next();
}
... ... @@ -110,9 +114,6 @@ exports.submit = (req, res, next) => {
exports.detail = (req, res, next) => {
let id = parseInt(`0${req.params.id}`, 10);
req.yoho.captchaShow = false;
res.locals.useGeetest = true;
req.ctx(questionModel).getQuestionDetail(id, req.user.uid).then(result => {
if (result && result.detail && req.yoho.isApp) {
result.detail.uid = req.user.uid;
... ...
... ... @@ -25,8 +25,8 @@ router.post('/check/submit', check.submit);
router.get('/questionnaire', auth, question.list);
router.post('/questionnaire/check', question.check);
router.post('/questionnaire/submit', question.geetestCheck, question.submit);
router.get('/questionnaire/:id', question.geetestLoad, question.detail);
router.post('/questionnaire/submit', question.submit);
router.get('/questionnaire/:id', question.detail);
router.get('/material', auth, materialNew.list);
module.exports = router;
... ...
... ... @@ -51,6 +51,4 @@
</div>
</div>
</div>
<div data-userverify="{{captchaShow}}" data-geetest="{{useGeetest}}" id="js-img-check" {{#unless useGeetest}} class="full-img-verify" {{/unless}}></div>
</div>
... ...
const haveGainModel = require('../models/have-gain');
const headerModel = require('../../../doraemon/models/header');
/**
* 有货-有赚
*/
class HaveGain {
// 列表
index(req, res, next) {
let uid = req.user.uid;
return req.ctx(haveGainModel).index({uid}).then(gainList => {
return res.render('have-gain/index', {
module: 'activity',
page: 'have-gain-index',
width750: true,
localCss: true,
title: '有货有赚',
gainList,
pageHeader: !req.yoho.isApp && headerModel.setNav({
navTitle: '有货有赚',
navBtn: false
}),
});
}).catch(next);
}
// 申请开通
apply(req, res, next) {
let uid = req.user.uid;
let socialMediaList = [
{
name: '微信',
icon: 'img/activity/have-gain/weixin@2x.png',
type: 1,
account: '',
fans: 0
},
{
name: '微信订阅号',
icon: 'img/activity/have-gain/weixin@2x.png',
type: 2,
account: '',
fans: 0
},
{
name: '抖音',
icon: 'img/activity/have-gain/douyin@2x.png',
type: 3,
account: '',
fans: 0
},
{
name: '微博',
icon: 'img/activity/have-gain/weibo@2x.png',
type: 4,
account: '',
fans: 0
},
{
name: 'Instagram',
icon: 'img/activity/have-gain/ins@2x.png',
type: 5,
account: '',
fans: 0
}
];
return req.ctx(haveGainModel).checkApply({uid}).then(result => {
let checkUrl = result.data && result.data.checkUrl || '';
if (checkUrl.indexOf('activity/have-gain/apply') === -1) {
return res.redirect(checkUrl);
}
return res.render('have-gain/apply', {
module: 'activity',
page: 'have-gain-apply',
width750: true,
localCss: true,
title: '有货有赚',
agreementUrl: 'https://activity.yoho.cn/feature/2609.html?openby:yohobuy={"action":"go.h5","params":{"url":"https://activity.yoho.cn/feature/2609.html"}}',
socialMediaList: socialMediaList,
pageHeader: !req.yoho.isApp && headerModel.setNav({
navTitle: '有货有赚',
navBtn: false
}),
});
}).catch(next);
}
// 审核中
verify(req, res) {
return res.render('have-gain/verify', {
module: 'activity',
page: 'have-gain-verify',
width750: true,
localCss: true,
title: '有货有赚',
pageHeader: !req.yoho.isApp && headerModel.setNav({
navTitle: '有货有赚',
navBtn: false
}),
});
}
// 审核拒绝
fail(req, res) {
return res.render('have-gain/fail', {
module: 'activity',
page: 'have-gain-fail',
width750: true,
localCss: true,
title: '有货有赚',
pageHeader: !req.yoho.isApp && headerModel.setNav({
navTitle: '有货有赚',
navBtn: false
}),
});
}
// 审核拒绝,重新申请API
resetApply(req, res, next) {
let uid = req.user.uid;
return req.ctx(haveGainModel).resetApply({uid}).then(result => {
return res.json(result);
}).catch(next);
}
submitApply(req, res, next) {
let body = req.body || {};
let uid = req.user.uid;
body.socialMediaList = JSON.parse(body.socialMediaList || '[]', true);
return req.ctx(haveGainModel).submitApply(Object.assign({uid}, body)).then(result => {
return res.json(result);
}).catch(next);
}
}
module.exports = new HaveGain();
... ...
'use strict';
const utils = '../../../utils';
const productNameProcess = require(`${utils}/product-name-process`);
const helpers = global.yoho.helpers;
const crypto = global.yoho.crypto;
const queryString = require('querystring');
... ... @@ -131,15 +129,8 @@ exports.index = (req, res, next) => {
return item;
});
datas[1].data = datas[1].data || {};
datas[1].data.product_list = (datas[1].data.product_list || []).map(function(value) {
value.goodsId = value.goods_list[0].goods_id;
if (value.cn_alphabet) {
value.cn_alphabet = productNameProcess(value.cn_alphabet);
}
// 商品url改版
value.url = helpers.urlFormat(`/product/${value.product_skn}.html`) + `?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${value.product_skn}}}`; // eslint-disable-line
return value;
... ... @@ -189,7 +180,6 @@ exports.index = (req, res, next) => {
}
}
// console.log(options);
options.studentSwitch = !_.get(req.app.locals.wap, 'user.removeStudentIdentification', true);
res.render('student', options);
});
... ... @@ -337,13 +327,6 @@ exports.verifystudent = (req, res, next) => {
});
}
datas[1].data.product_list = (datas[1].data.product_list || []).map(function(value) {
value.goodsId = value.goods_list[0].goods_id;
value.product_id = value.product_id;
if (value.cn_alphabet) {
value.cn_alphabet = productNameProcess(value.cn_alphabet);
}
// 商品url改版
value.url = helpers.urlFormat(`/product/${value.product_skn}.html`) + `?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${value.product_skn}}}`; // eslint-disable-line
return value;
... ...
'use strict';
const helpers = global.yoho.helpers;
const _ = require('lodash');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
index(params) {
return Promise.all([
this.invitecode(params),
this.checkApply(params)
]).then(res => {
let share = (_.get(res[0], 'data.context', '')).match(/(\d+)/g);
let gainList = [
{
url: _.get(res[0], 'data.url', ''),
img: '//img11.static.yhbimg.com/yhb-img01/2018/07/09/10/010d4f185b1a155449966ef12d3ed41490.jpg?imageView2/{mode}/w/{width}/h/{height}', // eslint-disable-line
totalUser: _.get(share, '[0]', 0),
totalCouponNum: _.get(share, '[1]', 0),
isShow: true
}, {
url: _.get(res[1], 'data.checkUrl', ''),
img: '//img11.static.yhbimg.com/yhb-img01/2018/07/09/10/018092224dc2f48195e3ad15269f981d1f.jpg?imageView2/{mode}/w/{width}/h/{height}', // eslint-disable-line
isShow: false
}
];
return gainList;
}).catch(() => {
return [];
});
}
/**
* [查询参与邀请好友数量]
* @param {[type]} params [{uid:''}]
* @return {[type]} [{}]
*/
invitecode(params) {
return this.get({
data: Object.assign({
method: 'app.invitecode.total'
}, params)
});
}
/**
* [检查是否申请]
* @param {[type]} params [{uid: 0}]
* @return {[type]} [{}]
*/
checkApply(params) {
return this.get({
data: Object.assign({
method: 'app.union.shareOrder.checkApply'
}, params)
}).then(res => {
let checkStatus = _.get(res, 'data.status', 0);
let checkUrl = helpers.urlFormat('/activity/have-gain/apply', {}); // 未申请
if (checkStatus === 1) { // 审核中
checkUrl = helpers.urlFormat('/activity/have-gain/verify', {});
} else if (checkStatus === 2) { // 审核成功
checkUrl = '//m.yohobuy.com?title=有货有赚&openby:yohobuy={"action":"go.minealliance","params":{"title":"有货有赚"}}'; // eslint-disable-line
} else if (checkStatus === 3) { // 申请拒绝
checkUrl = helpers.urlFormat('/activity/have-gain/fail', {});
}
_.set(res, 'data.checkUrl', checkUrl);
return res;
});
}
/**
* [审核拒绝,重新申请API]
* @param {[type]} params [{uid:'']}]
* @return {[type]} [{}]
*/
resetApply(params) {
return this.get({
data: Object.assign({
method: 'app.union.shareOrder.resetApply'
}, params)
});
}
/**
* [提交-申请]
* @param {[type]} params [{uid:'',name:'',mobile:'',socialMediaList:[{type:'',account:'',fans:200}]}]
* @return {[type]} [{}]
*/
submitApply(params) {
let uid = params.uid;
delete params.uid;
return this.get({
data: {
method: 'app.union.shareOrder.userApply',
uid: uid,
parameters: JSON.stringify(params)
}
});
}
};
... ...
... ... @@ -67,6 +67,8 @@ const disableBFCache = require('../../doraemon/middleware/disable-BFCache');
const grouthNew = require(`${cRoot}/grouth-new`);
const haveGain = require(`${cRoot}/have-gain`);
// routers
router.get('/demo', demo.index);
... ... @@ -328,4 +330,11 @@ router.get('/grade/droit', auth, grade.droit); // 权益说明
router.get('/grouth-new/init', auth, grouthNew.grouthInit); // 成长值初始化
router.get('/have-gain/index', auth, haveGain.index); // 有货有赚列表
router.get('/have-gain/apply', auth, haveGain.apply); // 有货有赚申请
router.get('/have-gain/verify', haveGain.verify); // 有货有赚审核
router.get('/have-gain/fail', auth, haveGain.fail); // 有货有赚审核不通过
router.post('/have-gain/resetApply', auth, haveGain.resetApply); // 有货有赚审核不通过,重新申请API
router.post('/have-gain/submitApply', auth, haveGain.submitApply); // 有货有赚-申请开通
module.exports = router;
... ...
<div class="have-gain-apply">
<div class="section">
<div class="apply-title">基本信息</div>
<ul class="section-ul">
<li><span>姓名</span><input type="text" class="name" placeholder="请输入姓名" /></li>
<li class="border-node"><span>手机号码</span><input type="number" class="mobile" placeholder="请输入手机号码" /></li>
</ul>
</div>
<div class="section">
<div class="apply-title">完善信息</div>
{{#socialMediaList}}
<div class="party-icon-item">
<div class="public-info-section">
<img class="public-icon" src="{{imgSrc icon}}" />
<div class="personal">
<div class="public-name">{{name}}</div>
<div class="account-name" data-type="{{type}}">
{{#if account}}
账号:<em>{{account}}</em>&nbsp;&nbsp;
粉丝:<em data-fans="{{fans}}">{{fans}}</em>
{{/if}}
</div>
</div>
</div>
{{#if account}}
<div class="fill-in disable">已填写</div>
{{else}}
<div class="fill-in">填写</div>
{{/if}}
</div>
{{/socialMediaList}}
<p class="other">如果您有其他渠道,可以添加我们的服务号“有货有赚”反馈,也可以了解申请状态,<em class="added">点击添加</em></p>
</div>
<div class="agreement-section">
<div class="agreement">
我已阅读并同意<a href='{{agreementUrl}}'>《有货有赚推广协议》</a>
</div>
<div class="apply-btn disable">申请开通</div>
</div>
</div>
... ...
<div class="have-gain-fail">
<div class="esp-header">审核未通过</div>
<div class="esp-explain">
<div class="explain-title">我们将通过您在有货的历史购物,浏览,分享等行为进行系统及人工筛选,没有通过的原因可能如下:</div>
<ul class="explain-sub">
<li>1.您提供的基本信息有误,请提供真实有效的姓名和手机号码。</li>
<li>2.您提供的完善信息,经工作人员核实后,与事实不符。</li>
<li>3.根据您提供的完善信息,不符合我们对参与用户门槛的最低要求。</li>
<li>4.您在有货的活跃度偏低。</li>
</ul>
</div>
<div class="esp-go">
<div class="reset-btn">重新申请</div>
<div class="again-title">您可以重新提交资料,再次申请</div>
</div>
</div>
... ...
<div class="have-gain-index">
{{#gainList}}
<div class="have-gain-item">
<div class="item-img">
<img src="{{image img 690 430}}" />
</div>
<div class="item-footer">
{{#if isShow}}
<div class="eps">
<span class="num">{{totalUser}}</span>
<span class="people">参与人数</span>
</div>
<div class="eps">
<span class="num">{{totalCouponNum}}</span>
<span class="people">获得优惠券</span>
</div>
<div class="eps">
<div class="accede-btn"><a href="{{url}}">了解详情</a></div>
</div>
{{else}}
<div class="eps">
邀请好友购物返现金
</div>
<div class="eps">
<div class="accede-btn"><a href="{{url}}">立即加入</a></div>
</div>
{{/if}}
</div>
</div>
{{/gainList}}
</div>
... ...
<div class="have-gain-verify">
<div class="esp-audit">审核中,请耐心等待</div>
<div class="esp-progress">审核期间您可以参加我们“邀请好友赚现金券”活动。邀请好友越多,不仅审核通过几率越大,且可以<em>无限赚取现金券</em></div>
<div class="esp-go">
<div class="add-btn">去添加</div>
</div>
</div>
... ...
... ... @@ -21,12 +21,14 @@
<div id="order-detail" data-id="{{orderCode}}">
{{#unless deliveryOffline}}
{{#if isVirtual}}
<section class="block">
<div class="tickets-mobile">
<span class="pull-left">手机号码:</span>
<span class="pull-right">{{mobile}}</span>
</div>
</section>
{{#if mobile}}
<section class="block">
<div class="tickets-mobile">
<span class="pull-left">手机号码:</span>
<span class="pull-right">{{mobile}}</span>
</div>
</section>
{{/if}}
{{else}}
<section class="owner-info block">
<span class="iconfont">&#xe637;</span>
... ... @@ -120,7 +122,15 @@
<div class="info-table">
{{#orderBasicInfo}}
<div class="table-item">{{key}}{{value}}</div>
<div class="table-item">
{{key}}{{value}}
{{# ext}}
{{#if needShowInvoice}}
<a href="{{needShowInvoice}}" class="ext-options invoice-see">查看发票</a>
{{/if}}
{{/ ext}}
</div>
{{/orderBasicInfo}}
<a href="{{serviceUrl}}" target="_blank" class="iconfont">&#xe63c;</a>
</div>
... ...
... ... @@ -472,6 +472,8 @@ module.exports = class extends global.yoho.BaseModel {
dest.feedbacks = {};
return dest;
}
dest.productSkn = origin.product_skn;
dest.goodsName = origin.product_name;
// 线下店商品展示限制
... ...
... ... @@ -2,8 +2,6 @@
const helpers = global.yoho.helpers;
const _ = require('lodash');
const utils = '../../../utils';
const productNameProcess = require(`${utils}/product-name-process`);
class storeHome extends global.yoho.BaseModel {
constructor(ctx) {
... ... @@ -19,14 +17,9 @@ class storeHome extends global.yoho.BaseModel {
_.forEach(list && list.product_list, value => {
if (!value.product_skn || !value.goods_list || !value.goods_list.length) {
if (!value.product_skn) {
return;
}
value.goodsId = value.goods_list && value.goods_list[0] && value.goods_list[0].goods_id;
if (value.cn_alphabet) {
value.cn_alphabet = productNameProcess(value.cn_alphabet);
}
let detailUrl = helpers.urlFormat(`/product/${value.product_skn}.html`);
... ...
'use strict';
const utils = '../../../utils';
const productNameProcess = require(`${utils}/product-name-process`);
const _ = require('lodash');
const serviceAPI = global.yoho.ServiceAPI;
const logger = global.yoho.logger;
... ... @@ -106,14 +104,10 @@ module.exports = class extends global.yoho.BaseModel {
_.forEach(result.data.product_list, function(data, index) {
let one = {};
if (data === null || !data.product_skn || !data.goods_list[0]) {
if (data === null || !data.product_skn) {
return false;
}
if (data.cn_alphabet) {
data.cn_alphabet = productNameProcess(data.cn_alphabet);
}
one = _.assign(one, {
url: '/product/' + data.product_skn + '.html', // 商品url改版
thumb: data.default_images,
... ...
'use strict';
const utils = '../../../utils';
const productNameProcess = require(`${utils}/product-name-process`);
const helpers = global.yoho.helpers;
const _ = require('lodash');
... ... @@ -19,14 +17,9 @@ const getPreferenceData = (data) => {
_.forEach(list && list.product_list, value => {
if (!value.product_skn || !value.goods_list || !value.goods_list.length) {
if (!value || !value.product_skn) {
return;
}
value.goodsId = value.goods_list && value.goods_list[0] && value.goods_list[0].goods_id;
if (value.cn_alphabet) {
value.cn_alphabet = productNameProcess(value.cn_alphabet);
}
let goods = {
product_skn: value.product_skn,
... ...
... ... @@ -7,6 +7,8 @@ module.exports = (req, res, next) => {
return csrfInit(req, res, (e) => {
res.locals.csrfToken = req.csrfToken();
e && (e.code = 403);
return next(e);
});
};
... ...
... ... @@ -103,9 +103,12 @@ exports.notFound = () => {
* @return {[type]}
*/
exports.serverError = () => {
const statusCodeList = [403];
return async(err, req, res, next) => {
const uid = req.user ? req.user.uid : 0;
const udid = _.get(req, 'cookies.udid', 'yoho');
let errorCode = 500;
forceNoCache(res);
... ... @@ -113,6 +116,10 @@ exports.serverError = () => {
err.code = parseInt(err.code || err.statusCode, 10) || 500;
if (statusCodeList.indexOf(err.code) >= 0) {
errorCode = err.code;
}
if (err.type !== 'entity.parse.failed') { // json 解析失败不上报错误
logger.error(`error at path: ${req.url}`);
logger.error(err);
... ... @@ -211,7 +218,7 @@ exports.serverError = () => {
}
if (!res.headersSent) {
return _err500(req, res, 500, err);
return _err500(req, res, errorCode, err);
}
return next(err);
... ...
{
"name": "yohobuywap-node",
"version": "6.6.20",
"version": "6.6.22",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ... @@ -20,7 +20,8 @@
"lint-css": "npm run -s lint:css -- ./**/*.{scss,css,vue}",
"lint-js": "npm run -s lint:js -- .",
"lint-all": "echo \"JS: \";npm run -s lint-js;echo \"CSS: \";npm run -s lint-css",
"precommit": "lint-staged"
"precommit": "lint-staged",
"prod": "git pull && webpack --config ./public/build/webpack.dll.indexcss.config.js && webpack --config ./public/build/webpack.prod.config.js && pm2 reload yohobuywap-node"
},
"lint-staged": {
"*.{js,vue}": [
... ... @@ -120,7 +121,7 @@
"postcss-clearfix": "^2.0.1",
"postcss-crip": "^2.0.1",
"postcss-import": "^11.1.0",
"postcss-loader": "^2.1.4",
"postcss-loader": "^2.1.6",
"postcss-position": "^1.0.0",
"postcss-pxtorem": "^4.0.1",
"postcss-scss": "^1.0.5",
... ...
<div class="dialog-fill-content">
<div class="fill-item">账号 <input type="text" class="account" placeholder="请输入账号昵称" value="{{account}}" /></div>
<div class="fill-item">粉丝数 <input type="number" class="fans" placeholder="请输入粉丝数量"
onkeyup="value=value.replace(/[^\d]/g,'')" value="{{fans}}" maxlength="9" /></div>
</div>
... ...
<div id="dialog-wrapper" class="dialog-wrapper">
<div class="dialog-box">
{{# hasHeader}}
<div class="dialog-header">{{.}}</div>
{{/ hasHeader}}
<div class="dialog-content">{{{dialogText}}}</div>
{{# hasFooter}}
<div class="dialog-footer">
{{# leftBtnText}}
<span class="dialog-left-btn tap-hightlight">{{.}}</span>
{{/ leftBtnText}}
{{# centerBtnText}}
<span class="dialog-center-btn tap-hightlight">{{.}}</span>
{{/ centerBtnText}}
{{# rightBtnText}}
<span class="dialog-right-btn tap-hightlight">{{.}}</span>
{{/ rightBtnText}}
</div>
{{/ hasFooter}}
<div class="dialog-box {{hasClass}}">
{{# hasHeader}}
<div class="dialog-header">{{.}}</div>
{{/ hasHeader}}
<div class="dialog-content">{{{dialogText}}}</div>
{{# hasFooter}}
<div class="dialog-footer">
{{# leftBtnText}}
<span class="dialog-left-btn tap-hightlight">{{.}}</span>
{{/ leftBtnText}}
{{# centerBtnText}}
<span class="dialog-center-btn tap-hightlight">{{.}}</span>
{{/ centerBtnText}}
{{# rightBtnText}}
<span class="dialog-right-btn tap-hightlight">{{.}}</span>
{{/ rightBtnText}}
</div>
{{/ hasFooter}}
</div>
</div>
... ...
... ... @@ -23,7 +23,11 @@
<a id="addtoCart" href="javascript:;" class="addto-cart add-to-cart-url">加入购物车</a>
{{/if}}
{{#if tickets}}
<a id="ticketsToCart" href="javascript:;" class="addto-cart add-to-cart-url">立即购买</a>
{{#if ticketsUrl}}
<a href="{{ticketsUrl}}" class="addto-cart add-to-cart-url">APP购买</a>
{{^}}
<a id="ticketsToCart" href="javascript:;" class="addto-cart add-to-cart-url">立即购买</a>
{{/if}}
{{/if}}
{{#if isDepositAdvance}}
<a id="isDepositAdvance" href="javascript:;" class="addto-cart add-to-cart-url">立即购买</a>
... ...
... ... @@ -3,15 +3,7 @@ require('3party/question-detail.page.css');
let $ = require('yoho-jquery'),
yoho = require('yoho-app'),
tipDg = require('plugin/tip'),
share = require('common/share'),
Validate = require('plugin/validata');
let validate = new Validate('#js-img-check', {
useREM: {
rootFontSize: 40,
picWidth: 150
}
});
share = require('common/share');
let question = {
$base: $('#qs-wrap'),
... ... @@ -222,49 +214,41 @@ let question = {
return;
}
return validate.getResults().then(result => {
if (typeof result === 'undefined') {
return;
}
let params = {
id: this.$base.data('id'),
uid: this.$base.data('cid'),
startTime: this.startTime,
endTime: Date.parse(new Date()) / 1000,
frontAnswers: JSON.stringify(info),
mobile: this.$mobile.val()
};
$.extend(params, result);
$.ajax({
type: 'POST',
url: '/3party/questionnaire/submit',
data: params
}).then(function(data) {
validate.type === 2 && validate.refresh();
let params = {
id: this.$base.data('id'),
uid: this.$base.data('cid'),
startTime: this.startTime,
endTime: Date.parse(new Date()) / 1000,
frontAnswers: JSON.stringify(info),
mobile: this.$mobile.val()
};
$.ajax({
type: 'POST',
url: '/3party/questionnaire/submit',
data: params
}).then(function(data) {
if (data.code === 200 || data.code === 206) {
let tip = '调查问卷已成功提交,感谢您的帮助!';
if (data.code === 206 && data.message) {
tip = data.message;
}
if (data.code === 200 || data.code === 206) {
let tip = '调查问卷已成功提交,感谢您的帮助!';
tipDg.show(tip);
if (data.code === 206 && data.message) {
tip = data.message;
setTimeout(function() {
if (yoho.isApp) {
yoho.invokeMethod('go.back');
} else if (document.referrer && document.referrer.indexOf('/3party/check') > -1) {
window.location.href = location.protocol + '//m.yohobuy.com/3party/questionnaire';
} else {
window.history.go(-1);
}
tipDg.show(tip);
setTimeout(function() {
if (yoho.isApp) {
yoho.invokeMethod('go.back');
} else {
window.history.go(-1);
}
}, 2000);
} else {
tipDg.show(data.message || '网络出了点问题~');
}
});
}, 2000);
} else {
tipDg.show(data.message || '网络出了点问题~');
}
});
}
};
... ...
import 'activity/have-gain-apply.page.css';
import Page from 'yoho-page';
import $ from 'yoho-jquery';
import tip from 'plugin/tip';
import dialog from 'plugin/dialog';
import fillInHbs from 'activity/have-gain/fill-in.hbs';
import yoho from 'yoho-app';
class HaveGainApplyPage extends Page {
constructor() {
super();
this.selector = {
isFlag: false,
$nameInput: $('.section .name'),
$mobileInput: $('.section .mobile'),
$fillIn: $('.party-icon-item .fill-in'),
$added: $('.other .added'),
$agreement: $('.agreement-section .agreement'),
$applyBtn: $('.apply-btn'),
};
this.init();
}
init() {
this.bindEvents();
}
bindEvents() {
let that = this;
this.selector.$nameInput.on('input', this.changeBtnStatus.bind(this));
this.selector.$mobileInput.on('input', this.changeBtnStatus.bind(this));
this.selector.$fillIn.on('click', that.tapFillIn);
this.selector.$agreement.on('click', that.tapAgreement);
this.selector.$added.on('click', this.tapAdded.bind(this));
this.selector.$applyBtn.on('click', this.apply.bind(this));
}
changeBtnStatus() {
let errStatus = 0;
let name = $.trim(this.selector.$nameInput.val());
let mobile = $.trim(this.selector.$mobileInput.val());
if (name === '') {
errStatus = 1;
} else if (mobile === '') {
errStatus = 2;
} else if (!/^1[0-9]{10}$/.test(mobile)) {
errStatus = 21;
}
if (errStatus) {
this.selector.$applyBtn.addClass('disable');
return errStatus;
}
this.selector.$applyBtn.removeClass('disable');
return errStatus;
}
tapFillIn(event) {
let $event = $(event.target);
if ($event.hasClass('disable')) {
return false;
}
let $accountName = $event.closest('.party-icon-item').find('.account-name');
dialog.showDialog({
hasHeader: '填写信息',
hasClass: 'dialog-fill-apply',
dialogText: fillInHbs({
account: $accountName.find('em').eq(0).text() || '',
fans: $accountName.find('em').eq(1).data('fans') || ''
}),
hasFooter: {
leftBtnText: '取消',
rightBtnText: '确定'
}
}, function() {
let account = $.trim($('.dialog-fill-apply .account').val() || '');
let fans = $.trim($('.dialog-fill-apply .fans').val() || '');
let fansFix = Math.round((fans / 10000) * 100) / 100; // 保留二个小数
if (!account) {
return tip.show('请输入账号昵称');
}
if (fans === '') {
return tip.show('请输入粉丝数量');
}
fansFix = fansFix >= 10 ? fansFix + '万' : fans;
$accountName.html(`账号:<em>${account}</em>&nbsp;&nbsp;粉丝:<em data-fans="${fans}">${fansFix}</em>`); // eslint-disable-line
dialog.hideDialog();
$event.text('已填写').addClass('disable');
});
}
tapAdded() {
let that = this;
yoho.invokeMethod('go.copy', {text: '有货有赚'});
dialog.showDialog({
dialogText: '“有货有赚”服务号已经复制,请去微信搜索添加',
hasClass: 'dialog-text-apply',
hasFooter: {
leftBtnText: '取消',
rightBtnText: '去添加'
}
}, function() {
that.awakeWeixin();
});
}
awakeWeixin() {
window.location.href = 'weixin://';
}
tapAgreement(event) {
let $event = $(event.target);
if ($event.closest('a').length) {
return true;
}
$event.hasClass('activate') ? $event.removeClass('activate') : $event.addClass('activate');
}
apply() {
let that = this;
let errStatus = this.changeBtnStatus();
let socialMediaList = [];
if (errStatus === 1) {
tip.show('请输入姓名');
} else if (errStatus === 2) {
tip.show('请输入手机号');
} else if (errStatus === 21) {
tip.show('请输入正确的手机号');
}
if (errStatus) {
$('html,body').animate({scrollTop: 0}, 'slow');
return false;
}
if (!this.selector.$agreement.hasClass('activate')) {
return tip.show('请勾选《我已阅读并同意》');
}
this.selector.$fillIn.each((index, event) => {
let $accountName = $(event).closest('.party-icon-item').find('.account-name');
socialMediaList.push({
type: $accountName.data('type'),
account: $accountName.find('em').eq(0).text() || '',
fans: parseInt(`0${$accountName.find('em').eq(1).data('fans')}`, 10)
});
});
if (this.selector.isFlag) {
return false;
}
this.selector.isFlag = true;
return this.ajax({
type: 'post',
url: '/activity/have-gain/submitApply',
data: {
name: $.trim(this.selector.$nameInput.val()),
mobile: $.trim(this.selector.$mobileInput.val()),
socialMediaList: JSON.stringify(socialMediaList)
}
}).then(res => {
this.selector.isFlag = false;
if (res.code !== 200) {
return tip.show(res.message || '请稍后再试');
}
yoho.invokeMethod('go.copy', {text: '有货有赚'});
dialog.showDialog({
hasHeader: '申请成功',
hasClass: 'dialog-text-apply',
dialogText: '请等待工作人员审核,您可以关注“有货有赚”服务号,了解进度',
hasFooter: {
leftBtnText: '取消',
rightBtnText: '去添加'
}
}, function() {
that.awakeWeixin();
}, function() {
window.location.href = '//m.yohobuy.com/activity/have-gain/verify';
});
}).catch(() => {
this.selector.isFlag = false;
});
}
}
$(() => {
new HaveGainApplyPage();
});
... ...
import 'activity/have-gain-fail.page.css';
import Page from 'yoho-page';
import $ from 'yoho-jquery';
import tip from 'plugin/tip';
class HaveGainFailPage extends Page {
constructor() {
super();
this.selector = {
$resetBtn: $('.esp-go .reset-btn')
};
this.init();
}
init() {
this.bindEvents();
}
bindEvents() {
this.selector.$resetBtn.on('click', this.tapReset.bind(this));
}
tapReset() {
if (this.selector.isFlag) {
return false;
}
this.selector.isFlag = true;
return this.ajax({
type: 'post',
url: '/activity/have-gain/resetApply',
data: {}
}).then(res => {
this.selector.isFlag = false;
if (res.code === 200 && res.data === 'Y') {
window.location.href = '//m.yohobuy.com/activity/have-gain/apply';
return true;
}
return tip.show(res.message || '请稍后再试');
}).catch(() => {
this.selector.isFlag = false;
});
}
}
$(() => {
new HaveGainFailPage();
});
... ...
import 'activity/have-gain-index.page.css';
... ...
import 'activity/have-gain-verify.page.css';
import Page from 'yoho-page';
import $ from 'yoho-jquery';
import dialog from 'plugin/dialog';
import yoho from 'yoho-app';
class HaveGainVerifyPage extends Page {
constructor() {
super();
this.selector = {
$addBtn: $('.esp-go .add-btn')
};
this.init();
}
init() {
this.bindEvents();
}
bindEvents() {
this.selector.$addBtn.on('click', this.tapAdded.bind(this));
}
tapAdded() {
yoho.invokeMethod('go.copy', {text: '有货有赚'});
dialog.showDialog({
dialogText: '“有货有赚”服务号已经复制,请去微信搜索添加',
hasClass: 'dialog-text-apply',
hasFooter: {
leftBtnText: '取消',
rightBtnText: '去添加'
}
}, function() {
window.location.href = 'weixin://';
});
}
}
$(() => {
new HaveGainVerifyPage();
});
... ...
... ... @@ -48,6 +48,10 @@ const getMktcBySeo = function() {
return mktc;
};
const getMktc = () => {
return qs.mkt_code || qs.union_type || getMktcBySeo() || '100000000000349';
};
const canOpenApp = () => {
if (isWechatDevtool || isApp || isFromYOHO || nodownload || qs.nodownload || qs.no_openapp || blackCheck) {
return false;
... ... @@ -57,7 +61,7 @@ const canOpenApp = () => {
const getAppPath = () => {
let appPath = document.getElementById('main-wrap').dataset.apppath || 'yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.home","params":{"gender":"1","channel":"2"}}';
let ct = qs.mkt_code || qs.union_type || getMktcBySeo() || '100000000000349';
let ct = getMktc();
let clientId = cookie.get('_yasvd');
if (ct) {
... ... @@ -103,3 +107,5 @@ if (canOpenApp()) {
}
}, 2000);
}
window._getMktCode = getMktc;
... ...
... ... @@ -54,7 +54,7 @@ applyButton.on('click', function() {
return false;
}
if (!/^1[3|4|5|8|7][0-9]{9}$/.test(formData.mobile)) {
if (!/^1[0-9]{10}$/.test(formData.mobile)) {
tip.show('手机号输入不正确!');
return false;
}
... ...
... ... @@ -71,6 +71,8 @@ exports.showDialog = function(data, callback, callbackForLeft, fullWithBtn) {
$dialogWrapper.fadeOut();
} else if ($(event.target).hasClass('dialog-right-btn')) {
return callback();
} else if ($(event.target).closest('.dialog-box').length) {
return true;
} else {
$('.dialog-wrapper').remove();
$('body').css({
... ...
... ... @@ -46,6 +46,8 @@ let nowShareData = {
imgUrl: productPic
};
const DOWNLOAD_URL = '//union.yoho.cn/union/app-downloads.html';
yoho.ready(function() {
if (yoho.isMarsApp) {
yoho.invokeMethod('set.shareInfo', shareData);
... ... @@ -115,8 +117,24 @@ setTimeout(() => {
data.studentPrice = Math.round(data.studentPrice.toString().replace('¥', ''));
}
$('#placeholder-pricedata').replaceWith(priceDataHbs(data));
if (data.tickets && data.cartInfo) {
let $downloadBtn = $('#download-go');
let ticketsUrl;
if ($downloadBtn.length) {
ticketsUrl = $downloadBtn.attr('href');
}
if (!ticketsUrl) {
let mktCode = window._getMktCode ? window._getMktCode() : '';
ticketsUrl = `${DOWNLOAD_URL}?union_type=${mktCode}&openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${data.productSkn}}}`; // eslint-disable-line
}
data.cartInfo.ticketsUrl = ticketsUrl;
}
$('#placeholder-pricedata').replaceWith(priceDataHbs(data));
$('#placeholder-infodata').replaceWith(infoDataHbs(data));
setTimeout(function() {
... ...
.dialog-wrapper .dialog-box.dialog-text-apply {
background-color: #fff;
padding: 0;
.dialog-header {
font-family: PingFang-SC-Medium, sans-serif;
font-size: 34px;
color: #444;
letter-spacing: -0.82px;
text-align: center;
padding: 40px 0 0;
margin-bottom: -24px;
font-weight: normal;
}
.dialog-content {
font-family: PingFang-SC-Regular, sans-serif;
font-size: 28px;
color: #444;
letter-spacing: -0.09px;
text-align: center;
line-height: 43px;
padding: 40px 60px;
}
.dialog-footer {
font-family: PingFang-SC-Regular, sans-serif;
font-size: 34px;
color: #444;
letter-spacing: -0.82px;
text-align: center;
.dialog-right-btn {
font-family: PingFang-SC-Medium, sans-serif;
color: #d0021b;
}
}
}
.dialog-wrapper .dialog-box.dialog-fill-apply {
background-color: #fff;
padding: 0;
.dialog-header {
font-family: PingFang-SC-Medium, sans-serif;
font-size: 34px;
color: #444;
letter-spacing: -0.82px;
text-align: center;
padding: 40px 0 0;
font-weight: normal;
}
.dialog-content {
padding: 36px 40px 40px;
.fill-item {
font-family: PingFang-SC-Regular, sans-serif;
font-size: 28px;
color: #444;
letter-spacing: -0.34px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
}
input {
width: 360px;
height: 80px;
line-height: 80px;
border: 1px solid #eee;
padding: 0 10px;
-webkit-appearance: none;
}
}
.dialog-footer {
font-family: PingFang-SC-Regular, sans-serif;
font-size: 34px;
color: #444;
letter-spacing: -0.82px;
text-align: center;
.dialog-right-btn {
font-family: PingFang-SC-Medium, sans-serif;
color: #d0021b;
}
}
}
... ...
@import "have-gain-dialog";
.have-gain-apply {
background-color: #f0f0f0;
.section {
background-color: #fff;
padding: 0 30px;
margin-bottom: 30px;
.apply-title {
font-family: PingFang-SC-Medium, sans-serif;
color: #444;
font-size: 40px;
padding: 30px 0;
}
li {
display: flex;
flex-direction: row;
align-items: center;
padding: 30px 0;
border-bottom: 1px solid #e0e0e0;
color: #444;
font-size: 28px;
input {
border: none;
color: #b0b0b0;
}
span {
display: inline-block;
width: 130px;
}
}
li.border-node {
border: none;
}
.party-icon-item {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 30px 0;
border-bottom: 1px solid #e0e0e0;
.fill-in {
font-family: PingFang-SC-Regular, sans-serif;
display: inline-block;
background-color: #444;
border-radius: 4px;
font-size: 24px;
color: #fff;
text-align: center;
padding: 10px 0;
width: 90px;
}
.disable {
background-color: #b0b0b0;
}
}
.public-info-section {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
.public-icon {
width: 80px;
height: 80px;
}
.personal {
font-family: PingFang-SC-Regular, sans-serif;
font-size: 24px;
color: #b0b0b0;
letter-spacing: 0;
margin-left: 30px;
}
.personal em {
display: inline-block;
width: 140px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
vertical-align: text-bottom;
}
.public-name {
font-size: 28px;
color: #444;
margin-bottom: 5px;
}
}
.other {
padding: 30px 0;
font-family: PingFang-SC-Regular, sans-serif;
font-size: 24px;
color: #b0b0b0;
letter-spacing: 0;
em {
color: #d0021b;
text-decoration: underline;
}
}
}
.agreement-section {
margin: 30px 30px 0;
padding-bottom: 30px;
.agreement {
margin-bottom: 28px;
font-family: PingFang-SC-Regular, sans-serif;
font-size: 24px;
color: #b0b0b0;
a {
color: #d0021b;
}
&:before {
content: "";
width: 34px;
height: 34px;
vertical-align: middle;
background-image: url("/activity/have-gain/agree@2x.png");
background-repeat: no-repeat;
background-size: contain;
display: inline-block;
}
&.activate {
&:before {
background-image: url("/activity/have-gain/agree-a@2x.png");
}
}
}
.apply-btn {
height: 100px;
line-height: 100px;
background-color: #d0021b;
border-radius: 10px;
color: #fff;
text-align: center;
}
.disable {
background-color: #b0b0b0;
}
}
}
... ...
.have-gain-fail {
text-align: center;
.esp-header {
font-family: PingFang-SC-Medium, sans-serif;
font-size: 40px;
color: #444;
letter-spacing: 0;
text-align: center;
margin: 120px 0 20px;
}
.esp-explain {
font-family: PingFang-SC-Regular, sans-serif;
letter-spacing: 0;
padding: 0 40px;
text-align: left;
.explain-title {
font-size: 28px;
color: #444;
margin-bottom: 40px;
}
ul li {
font-size: 28px;
color: #b0b0b0;
padding: 0 20px;
margin-bottom: 20px;
line-height: 44px;
}
}
.reset-btn {
font-family: PingFang-SC-Regular, sans-serif;
font-size: 32px;
color: #fff;
text-align: center;
width: 400px;
height: 100px;
line-height: 100px;
background-color: #444;
border-radius: 8px;
margin: 60px auto 20px;
}
.again-title {
font-family: PingFangSC-Regular, sans-serif;
font-size: 28px;
color: #b0b0b0;
letter-spacing: 0;
text-align: center;
}
}
... ...
.have-gain-index {
background-color: #f0f0f0;
.have-gain-item {
padding: 30px;
margin-bottom: 20px;
background-color: #fff;
}
.item-footer {
display: flex;
justify-content: space-between;
align-items: center;
text-align: center;
height: 120px;
margin-bottom: -30px;
padding-left: 20px;
.eps {
font-family: PingFangSC-Regular, sans-serif;
font-size: 28px;
color: #444;
span {
display: block;
}
.num {
font-family: SanFranciscoText-Medium, sans-serif;
font-size: 32px;
color: #444;
}
.people {
font-family: PingFangSC-Regular, sans-serif;
font-size: 24px;
color: #b0b0b0;
}
.accede-btn {
font-family: PingFang-SC-Medium, sans-serif;
font-size: 28px;
color: #444;
letter-spacing: 0;
border: 1px solid #444;
border-radius: 4px;
padding: 10px 30px;
}
}
}
}
... ...
@import "have-gain-dialog";
.have-gain-verify {
text-align: center;
.esp-audit {
font-family: PingFang-SC-Medium, sans-serif;
font-size: 40px;
color: #444;
margin-top: 200px;
}
.esp-progress {
font-family: PingFangSC-Regular, sans-serif;
font-size: 28px;
color: #b0b0b0;
padding: 20px 60px;
em {
color: #000;
}
}
.add-btn {
font-family: PingFang-SC-Regular, sans-serif;
font-size: 32px;
color: #fff;
text-align: center;
width: 400px;
height: 100px;
line-height: 100px;
background-color: #444;
border-radius: 8px;
margin: 30px auto 0;
}
}
... ...
... ... @@ -45,7 +45,6 @@
&:nth-last-of-type(1) {
border-left: 1px solid #ccc;
border-radius: 0 0 10px 10px;
color: #d0021b;
}
}
... ...
... ... @@ -56,6 +56,18 @@
color: #444;
}
.ext-options {
font-size: 26px;
line-height: 38px;
display: inline-block;
padding: 0 4px;
border: 1px solid #ddd;
vertical-align: middle;
position: relative;
top: -1px;
margin-left: 20px;
}
.iconfont {
position: absolute;
top: 30px;
... ...
'use strict';
require('../app');
const _ = require('lodash');
const imageHandle = require('./image');
const helpers = global.yoho.helpers;
const GENDER = {
1: '男',
... ... @@ -113,9 +114,7 @@ exports.processProductList = (list, options) => {
// }
// 商品信息有问题,则不显示
if (!(
(product.product_skn && _.get(product, 'goods_list.length', 0)) || product.recommend_type
)) {
if (!product || !product.product_skn) {
return;
}
... ... @@ -173,6 +172,9 @@ exports.processProductList = (list, options) => {
// if (!flag) {
// product.default_images = _procProductImg(product.goods_list[0], product.gender, options.yh_channel);
// }
//
product.default_images = imageHandle.getSourceUrl(product.default_images, 'goodsimg');
product.is_soon_sold_out = product.is_soon_sold_out === 'Y';
... ...
... ... @@ -9862,9 +9862,9 @@ yoho-md5@^2.0.0:
version "2.1.0"
resolved "http://npm.yohops.com/yoho-md5/-/yoho-md5-2.1.0.tgz#f0c00d343f775e77952ebce0826863ac52e0ad50"
yoho-node-lib@=0.6.17:
version "0.6.17"
resolved "http://npm.yohops.com/yoho-node-lib/-/yoho-node-lib-0.6.17.tgz#9cc931bdd2815603c4848176eda913996c94c31e"
yoho-node-lib@=0.6.19:
version "0.6.19"
resolved "http://npm.yohops.com/yoho-node-lib/-/yoho-node-lib-0.6.19.tgz#f3df50ea9d4a20ef7dc5f629e1725ee530e3570b"
dependencies:
dnscache "^1.0.1"
handlebars "^4.0.5"
... ...