Authored by 刘传洋

m

... ... @@ -6,6 +6,8 @@
'use strict';
const crypto = global.yoho.crypto;
const authcode = require(`${global.utils}/authcode`);
const headerModel = require('../../../doraemon/models/simple-header');
const oeModel = require('../models/order-ensure');
... ... @@ -54,6 +56,7 @@ const compute = (req, res, next) => {
// 提交订单
const submit = (req, res, next) => {
let cartType = req.body.cartType === '2' ? 'advance' : 'ordinary';
let uid = req.user.uid;
if (!req.body.addressId) {
res.send({
... ... @@ -63,7 +66,56 @@ const submit = (req, res, next) => {
return;
}
oeModel.submit(req.user.uid, cartType, req.body).then(data => {
/* 判断是否是友盟过来的用户 */
let userAgent = null;
let unionKey = '';
let unionInfo = {};
if (req.cookies.mkt_code || req.cookies._QYH_UNION) {
/* eslint-disable */
/*
*1、http://union.yohobuy.com/go?client_id=3415&aid=0118&channel=3415&cid=3601&wi=NDgwMDB8dGVzdA==&target=http://m.yohobuy.com/
*2、http://union.yoho.cn/union/jump?channel_id=51fanli&u_id=6&tracking_code=fanli123&target_url=http%3a%2f%2fm.yohobuy.com%3funion_type%3d3063%26utm_source%3dmfanli%26utm_medium%3dcps%26utm_campaign%3dmpfanli
*3、union.yohobuy.com/go/proxy?utm_medium=none&utm_campaign=none&client_id=991002&ads_code=&go_url=https%253A%252F%252Fm.yohobuy.com%252F%253Futm_source%253Dhyyx%2526utm_medium%253Dnone%2526utm_campaign%253Dnone%2526union_type%253D991002&channel_code=hyyx&append=&mbr_name=&u_id=&aid=&channel=cps&cid=&wi=
**/
/* tar modified 161108 添加新的联盟数据处理逻辑,兼容原有联盟数据处理,
区别是旧的北京写 cookie 加密过来,新的 node 写 cookie,没有加密 */
/* eslint-enable */
if (req.cookies._QYH_UNION) {
unionKey = authcode(req.cookies._QYH_UNION, 'q_union_yohobuy');
if (!unionKey) {
let encryData, testQyhUnion;
encryData = crypto.decrypt('', decodeURIComponent(req.cookies._QYH_UNION));
encryData = encryData.substr(0, encryData.lastIndexOf('}') + 1);
testQyhUnion = JSON.parse(encryData);
unionKey = testQyhUnion.client_id ? encryData : '';
}
} else {
unionKey = '{"client_id":' + req.cookies.mkt_code + '}';
}
/* 检查联盟参数是否有效 */
unionInfo = unionKey ? JSON.parse(unionKey) : {};
/* 模拟APP的User-Agent */
userAgent = unionInfo.client_id ? 'YOHO!Buy/3.8.2.259(Model/PC;Channel/' +
unionInfo.client_id + ';uid/' + uid + ')' : null;
}
Object.assign(req.body, {
qhyUnion: unionKey,
userAgent: userAgent
});
oeModel.submit(uid, cartType, req.body).then(data => {
if (data && data.code === 200 && unionKey) {
data.data.unionKey = {
client_id: unionInfo.client_id
};
}
res.send(data);
}).catch(next);
};
... ...
... ... @@ -42,6 +42,9 @@ const getShoppingKeyByCookie = (req) => {
const transPrice = (price) => {
return price ? (price * 1).toFixed(2) : '0.00';
};
const trans = (x) => {
return x*1;
};
/**
* 生成公开的TOKEN凭证
... ... @@ -410,19 +413,21 @@ const formatPromotion = (it, selectedGiftsList) => {
if (status === 0) {
let tipTxtMoney = `还差${ toDecimal(info.conditionValue)}`;
let tipTxtMoney = `${ toDecimal(info.conditionValue)}`;
let tipTxt = `还差${ -(Math.round(parseFloat(info.conditionValue) * 100) / 100)}`;
let tipTxt = `${ -(Math.round(parseFloat(info.conditionValue) * 100) / 100)}`;
if (info.conditionUnit === 1) {
tipTxt += '件满足';
tipTxt += '件';
} else if (info.conditionUnit === 2) {
tipTxt = tipTxtMoney + '元满足';
tipTxt = tipTxtMoney + '元';
}
info.promotionTitle = tipTxt + info.promotionTitle;
tipTxt = "<span style='color:#ff575c'>" + tipTxt + "</span>";
info.promotionTitle = '还差' + tipTxt + '满足' + "&nbsp;&nbsp;&nbsp;" + info.promotionTitle;
} else if (status === 10) {
info.promotionTitle = '已满足' + info.promotionTitle;
info.promotionTitle = '已满足' + "&nbsp;&nbsp;&nbsp;" +info.promotionTitle;
}
if (info.giftGoodsList) {
... ...
... ... @@ -163,7 +163,13 @@ const orderSubmitAsync = (uid, cartType, addressId, deliveryTime, deliveryWay, p
Object.assign(param, {
is_continue_buy: 'Y'
});
}
// 友盟有关信息的传递
if (other.qhyUnion) {
Object.assign(param, {
qhy_union: other.qhyUnion
});
}
return api.get('', param);
... ...
... ... @@ -3,11 +3,12 @@
data-promotionid="{{promotionId}}">
<code class="order-pay-mark {{#unless isReach}}order-pay-mark-white{{/unless}}">
{{tag}}
</code>{{promotionTitle}}
</code>{{{promotionTitle}}}
{{> mix/cart/cart-promotion-btn}}
{{#if isNotReach}}
<a class="btn-clear blue order-pay-link" target="_blank" href="{{promotionPageUrl}}">去凑单&nbsp;<i class="iconfont">&#xe6ef;</i></a>
{{/if}}
</div>
... ...
... ... @@ -720,14 +720,20 @@ $('#order-submit').click(function() {
});
});
// yas统计
yas.givePoint('YB_SC_TOPAY_CLICK', {ORDER_CODE: rdata.order_code, PRD_NUM: tongJi.num,
ORDER_AMOUNT: rdata.order_amount, PRO_SKN: tongJi.skn.join(','), PRO_SKU: tongJi.sku.join(','),
UNIONCOOKIE: encodeURIComponent(rdata.unionKey + '') || ''});
window.py('event', 'order', {
id: rdata.order_code,
money: rdata.order_amount,
items: tongJi.py
}).track('MC.ROh.yqkx8jgGASmo3McexF7XE0');
UNIONCOOKIE: rdata.unionKey || ''});
// 品友统计
if (window.py) {
window.py('event', 'order', {
id: rdata.order_code,
money: rdata.order_amount,
items: tongJi.py
}).track('MC.ROh.yqkx8jgGASmo3McexF7XE0');
}
location.href = rdata.url;
}
} else if (data.message) {
... ...
'use strict';
const md5 = require('md5');
const microtime = function() {
let unixtimeMs = new Date().getTime();
let sec = parseInt(unixtimeMs / 1000, 10);
return (unixtimeMs - (sec * 1000)) / 1000 + ' ' + sec;
};
const getTimestamp = function() {
let unixtimeMs = new Date().getTime();
return parseInt(unixtimeMs / 1000, 10);
};
module.exports = function(str, key, expiry, operation) {
operation = operation ? operation : 'decode';
key = key ? key : '';
expiry = expiry ? expiry : 0;
let tmpstr, tmp;
let ckeyLength = 4;
key = md5(key);
// 密匙a会参与加解密
let keya = md5(key.substr(0, 16));
// 密匙b会用来做数据完整性验证
let keyb = md5(key.substr(16, 16));
// 密匙c用于变化生成的密文
let keyc = operation === 'decode' ?
str.substr(0, ckeyLength) : md5(microtime()).substr(-ckeyLength);
// 参与运算的密匙
let cryptkey = keya + md5(keya + keyc);
let strbuf;
if (operation === 'decode') {
str = str.substr(ckeyLength);
strbuf = new Buffer(str, 'base64');
// string = b.toString();
} else {
expiry = expiry ? expiry + getTimestamp() : 0;
tmpstr = expiry.toString();
if (tmpstr.length >= 10) {
str = tmpstr.substr(0, 10) + md5(str + keyb).substr(0, 16) + str;
} else {
let count = 10 - tmpstr.length;
for (let i = 0; i < count; i++) {
tmpstr = '0' + tmpstr;
}
str = tmpstr + md5(str + keyb).substr(0, 16) + str;
}
strbuf = new Buffer(str);
}
let box = new Array(256);
let rndkey = [];
for (let i = 0; i < 256; i++) {
box[i] = i;
// 产生密匙簿
rndkey[i] = cryptkey.charCodeAt(i % cryptkey.length);
}
// 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度
for (let j = 0, i = 0; i < 256; i++) {
j = (j + box[i] + rndkey[i]) % 256;
tmp = box[i];
box[i] = box[j];
box[j] = tmp;
}
// 核心加解密部分
let s = '';
for (let a = 0, j = 0, i = 0; i < strbuf.length; i++) {
a = (a + 1) % 256;
j = (j + box[a]) % 256;
tmp = box[a];
box[a] = box[j];
box[j] = tmp;
// 从密匙簿得出密匙进行异或,再转成字符
// s += String.fromCharCode(string[i] ^ (box[(box[a] + box[j]) % 256]));
/* jshint -W016*/
strbuf[i] = strbuf[i] ^ (box[(box[a] + box[j]) % 256]);
}
if (operation === 'decode') {
s = strbuf.toString();
if ((s.substr(0, 10) === '0'.repeat(10) ||
s.substr(0, 10) - getTimestamp() > 0) &&
s.substr(10, 16) === md5(s.substr(26) + keyb).substr(0, 16)) {
s = s.substr(26);
} else {
s = '';
}
} else {
s = strbuf.toString('base64');
let regex = new RegExp('=', 'g');
s = s.replace(regex, '');
s = keyc + s;
}
return s;
};
... ...