Authored by 陈峰

Merge branch 'feature/cart' into 'release/5.4.1'

Feature/cart



See merge request !216
@@ -321,7 +321,7 @@ const modify = (req, res, next) => { @@ -321,7 +321,7 @@ const modify = (req, res, next) => {
321 data ? res.json(data) : res.status(400).json({ 321 data ? res.json(data) : res.status(400).json({
322 message: '操作失败' 322 message: '操作失败'
323 }); 323 });
324 - }); 324 + }).catch(next);
325 }; 325 };
326 326
327 /** 327 /**
@@ -351,7 +351,7 @@ const modifyPriceGift = (req, res, next) => { @@ -351,7 +351,7 @@ const modifyPriceGift = (req, res, next) => {
351 data ? res.json(data) : res.status(400).json({ 351 data ? res.json(data) : res.status(400).json({
352 message: '操作失败' 352 message: '操作失败'
353 }); 353 });
354 - }); 354 + }).catch(next);
355 }; 355 };
356 356
357 /** 357 /**
@@ -457,7 +457,7 @@ const giftinfo = (req, res, next) => { @@ -457,7 +457,7 @@ const giftinfo = (req, res, next) => {
457 }) : res.status(400).json({ 457 }) : res.status(400).json({
458 message: '操作失败' 458 message: '操作失败'
459 }); 459 });
460 - }); 460 + }).catch(next);
461 }; 461 };
462 462
463 module.exports = { 463 module.exports = {
@@ -7,7 +7,7 @@ const headerModel = require('../../../doraemon/models/header'); @@ -7,7 +7,7 @@ const headerModel = require('../../../doraemon/models/header');
7 const userModel = require('../../serverAPI/user'); 7 const userModel = require('../../serverAPI/user');
8 const addressModel = require('../../serverAPI/user/address'); 8 const addressModel = require('../../serverAPI/user/address');
9 const orderModel = require('../models/order'); 9 const orderModel = require('../models/order');
10 -const crypt = global.yoho.crypt; 10 +const crypto = global.yoho.crypto;
11 11
12 exports.orderEnsure = (req, res, next) => { 12 exports.orderEnsure = (req, res, next) => {
13 let headerData = headerModel.setNav({ 13 let headerData = headerModel.setNav({
@@ -132,7 +132,7 @@ exports.orderCompute = (req, res, next) => { @@ -132,7 +132,7 @@ exports.orderCompute = (req, res, next) => {
132 */ 132 */
133 exports.orderSub = (req, res) => { 133 exports.orderSub = (req, res) => {
134 let uid = req.user.uid; 134 let uid = req.user.uid;
135 - let addressId = crypt.decrypt('', req.body.addressId); 135 + let addressId = parseInt(crypto.decrypt('', req.body.addressId), 10);
136 let cartType = req.body.cartType || 'ordinary'; 136 let cartType = req.body.cartType || 'ordinary';
137 let deliveryTimeId = req.body.deliveryTimeId || 1; 137 let deliveryTimeId = req.body.deliveryTimeId || 1;
138 let deliveryId = req.body.deliveryId || 1; 138 let deliveryId = req.body.deliveryId || 1;
@@ -210,7 +210,7 @@ exports.orderSub = (req, res) => { @@ -210,7 +210,7 @@ exports.orderSub = (req, res) => {
210 yohoCoin, skuList, unionKey, userAgent); 210 yohoCoin, skuList, unionKey, userAgent);
211 } 211 }
212 212
213 - if (unionInfo) { 213 + if (unionInfo && result.data) {
214 result.data.unionCookie = unionInfo; 214 result.data.unionCookie = unionInfo;
215 } 215 }
216 216
@@ -13,10 +13,18 @@ const shoppingAPI = require('../../serverAPI/order/shopping'); @@ -13,10 +13,18 @@ const shoppingAPI = require('../../serverAPI/order/shopping');
13 * @return float|string 转换之后的价格 13 * @return float|string 转换之后的价格
14 */ 14 */
15 const transPrice = (price, isSepcialZero) => { 15 const transPrice = (price, isSepcialZero) => {
  16 + if (!price) {
  17 + price = 0;
  18 + }
  19 +
16 if (!isSepcialZero) { 20 if (!isSepcialZero) {
17 isSepcialZero = false; 21 isSepcialZero = false;
18 } 22 }
19 23
  24 + if (price || isSepcialZero) {
  25 + price = price.toFixed(2);
  26 + }
  27 +
20 return price; 28 return price;
21 }; 29 };
22 30
@@ -588,11 +588,7 @@ let getProductAsyncData = (data) => { @@ -588,11 +588,7 @@ let getProductAsyncData = (data) => {
588 * [商品信息格式化异步接口] 588 * [商品信息格式化异步接口]
589 */ 589 */
590 let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => { 590 let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
591 - let dest = {}, // 结果输出  
592 - thumbImageList = [],  
593 - colorGroup = {},  
594 - sizeGroup = [],  
595 - totalStorageNum = 0; 591 + let dest = {}; // 结果输出
596 592
597 // 用户未登录时 593 // 用户未登录时
598 if (!uid) { 594 if (!uid) {
@@ -679,141 +675,8 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => { @@ -679,141 +675,8 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
679 } 675 }
680 676
681 // 商品信息 677 // 商品信息
682 - if (origin.goods_list.length) {  
683 - let goodsGroup = [],  
684 - sizeName = '',  
685 - colorList = [],  
686 - sizeList = {},  
687 - allSizeList = {},  
688 - colorStorageGroup = {},  
689 - colorStorageNum = 0;  
690 -  
691 - _.forEach(origin.goods_list, function(value) {  
692 - // 未上架也显示  
693 - // if (value.status === 0) {  
694 - // return;  
695 - // }  
696 -  
697 - colorStorageNum = 0;  
698 -  
699 - // 商品分组  
700 - if (value.images_list) {  
701 - _.forEach(value.images_list, function(good) {  
702 - goodsGroup.push({  
703 - goodsId: value.goods_id,  
704 - img: good.image_url  
705 - });  
706 - });  
707 - }  
708 -  
709 - // 商品的尺码列表  
710 - colorStorageGroup[value.product_skc] = {};  
711 - if (value.size_list) {  
712 - sizeList[value.product_skc] = [];  
713 - _.forEach(value.size_list, function(size) {  
714 - sizeList[value.product_skc].push({  
715 - id: size.size_id,  
716 - skuId: size.product_sku,  
717 - goodsId: value.goods_id,  
718 - colorId: value.color_id,  
719 - name: size.size_name,  
720 - sizeNum: size.storage_number,  
721 - sizeInfo: size.size_info ? size.size_info : ''  
722 - });  
723 -  
724 - sizeName = size.size_name;  
725 -  
726 - // 所有尺码列表,赋值用于前端展示默认尺码的时候  
727 - // 判断出没有库存则显示灰色  
728 - let build = {  
729 - id: size.size_id,  
730 - storage: size.storage_number,  
731 - sizeInfo: size.size_info ? size.size_info : ''  
732 - };  
733 -  
734 - allSizeList[sizeName] = (allSizeList[sizeName] === null ||  
735 - typeof allSizeList[sizeName] === 'undefined') ? build : allSizeList[sizeName];  
736 - colorStorageNum += parseInt(size.storage_number, 10);  
737 - colorStorageGroup[value.product_skc][sizeName] = parseInt(size.storage_number, 10);  
738 - });  
739 -  
740 -  
741 - // 颜色分组  
742 - colorList.push({  
743 - id: value.color_id,  
744 - skcId: value.product_skc,  
745 - name: value.factory_goods_name || value.color_name,  
746 - colorNum: colorStorageNum  
747 - });  
748 - }  
749 -  
750 - // 缩略图  
751 - thumbImageList.push({  
752 - img: helpers.image(value.color_image, 300, 395)  
753 - });  
754 -  
755 - // 商品库存总数  
756 - totalStorageNum += _.toNumber(colorStorageNum);  
757 - });  
758 -  
759 - // 遍历所有尺码,构建颜色显示数据  
760 - let i = 1;  
761 -  
762 - sizeGroup[0] = {  
763 - size: []  
764 - };  
765 - _.forEach(allSizeList, (value, key) => {  
766 -  
767 - // 默认尺码  
768 - sizeGroup[0].size.push({  
769 - name: key,  
770 - sizeNum: _.toNumber(value.storage) > 0 ? true : false,  
771 - id: value.id,  
772 - sizeInfo: value.sizeInfo  
773 - });  
774 -  
775 - colorGroup[i] = {  
776 - color: []  
777 - };  
778 -  
779 - // 各个颜色的尺码, 每行显示一个尺码对应的颜色  
780 - _.forEach(colorList, (colorArr) => {  
781 - let tempColorArr = _.cloneDeep(colorArr);  
782 -  
783 - if (colorStorageGroup[tempColorArr.skcId] &&  
784 - colorStorageGroup[tempColorArr.skcId][key]) {  
785 - tempColorArr.colorNum = colorStorageGroup[tempColorArr.skcId][key];  
786 - } else {  
787 - tempColorArr.colorNum = 0;  
788 - }  
789 - colorGroup[i].color.push(Object.assign({}, tempColorArr));  
790 - });  
791 - colorGroup[i].id = value.id;  
792 -  
793 - ++i;  
794 - });  
795 -  
796 - colorGroup[0] = {  
797 - color: []  
798 - };  
799 -  
800 - // 遍历所有颜色, 构建尺码显示数据  
801 - i = 1;  
802 - _.forEach(colorList, function(value) {  
803 -  
804 - // 各个尺码的颜色, 每行显示一个颜色的对应尺码  
805 - sizeGroup[i] = {  
806 - size: sizeList[value.skcId],  
807 - colorId: value.skcId  
808 - };  
809 -  
810 - // 默认颜色  
811 - colorGroup[0].color.push(value);  
812 - ++i;  
813 - });  
814 -  
815 - }  
816 - let soldOut = (origin.storage_sum === 0) || (totalStorageNum === 0); // status 678 + let cartInfo = productProcess.processSizeInfo(origin);
  679 + let soldOut = (origin.storage_sum === 0) || (cartInfo.totalStorageNum === 0); // status
817 let notForSale = origin.attribute === 2; 680 let notForSale = origin.attribute === 2;
818 let preSale = (origin.status === 0 && origin.advance_shelve_time > 0); 681 let preSale = (origin.status === 0 && origin.advance_shelve_time > 0);
819 682
@@ -827,16 +690,9 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => { @@ -827,16 +690,9 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
827 690
828 // 显示加入购物车链接 691 // 显示加入购物车链接
829 if (!soldOut && !notForSale && !preSale || origin.isLimitBuy) { 692 if (!soldOut && !notForSale && !preSale || origin.isLimitBuy) {
830 - _.orderBy(colorGroup);  
831 - Object.assign(dest.cartInfo, {  
832 - productId: origin.product_id,  
833 - thumbs: thumbImageList,  
834 - name: dest.goodsName || '', 693 + Object.assign(dest.cartInfo, cartInfo, {
835 price: dest.goodsPrice.previousPrice ? dest.goodsPrice.previousPrice : '', 694 price: dest.goodsPrice.previousPrice ? dest.goodsPrice.previousPrice : '',
836 salePrice: dest.goodsPrice.currentPrice ? dest.goodsPrice.currentPrice : '', 695 salePrice: dest.goodsPrice.currentPrice ? dest.goodsPrice.currentPrice : '',
837 - totalNum: totalStorageNum,  
838 - colors: _.toArray(colorGroup),  
839 - sizes: sizeGroup  
840 }); 696 });
841 697
842 // 限购商品 698 // 限购商品
@@ -889,33 +745,33 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => { @@ -889,33 +745,33 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
889 dest.cartInfo.preSale = true; 745 dest.cartInfo.preSale = true;
890 } 746 }
891 return resolve(dest); 747 return resolve(dest);
892 - }).then(dest => { 748 + }).then(result => {
893 // 虚拟商品(门票) 749 // 虚拟商品(门票)
894 if (origin.attribute * 1 === 3) { 750 if (origin.attribute * 1 === 3) {
895 - dest.tickets = true;  
896 - dest.ticketsConfirm = helpers.urlFormat('/cart/index/ticketsConfirm'); 751 + result.tickets = true;
  752 + result.ticketsConfirm = helpers.urlFormat('/cart/index/ticketsConfirm');
897 753
898 // 展览票 754 // 展览票
899 if (origin.product_skn * 1 === SINGLE_TICKETS_SKN) { 755 if (origin.product_skn * 1 === SINGLE_TICKETS_SKN) {
900 - dest.single = true; 756 + result.single = true;
901 } else { 757 } else {
902 // 套票 758 // 套票
903 - dest.package = true; 759 + result.package = true;
904 } 760 }
905 761
906 // 购票限制 762 // 购票限制
907 - dest.cartInfo.limit = 4; 763 + result.cartInfo.limit = 4;
908 764
909 // 清空活动 765 // 清空活动
910 - dest.goodsDiscount = []; 766 + result.goodsDiscount = [];
911 } 767 }
912 - dest.id = origin.product_id;  
913 - dest.goodsId = origin.goods_id;  
914 - if (dest.isSecKill === 'Y' && dest.cartInfo.totalNum > 0) {  
915 - dest.totalNum = 1; 768 + result.id = origin.product_id;
  769 + result.goodsId = origin.goods_id;
  770 + if (result.isSecKill === 'Y' && result.cartInfo.totalNum > 0) {
  771 + result.totalNum = 1;
916 } 772 }
917 - return dest;  
918 - }) 773 + return result;
  774 + });
919 }; 775 };
920 776
921 777
  1 +'use strict';
  2 +const md5 = require('md5');
  3 +
  4 +const microtime = function() {
  5 + let unixtimeMs = new Date().getTime();
  6 + let sec = parseInt(unixtimeMs / 1000, 10);
  7 +
  8 + return (unixtimeMs - (sec * 1000)) / 1000 + ' ' + sec;
  9 +};
  10 +
  11 +const getTimestamp = function() {
  12 + let unixtimeMs = new Date().getTime();
  13 +
  14 + return parseInt(unixtimeMs / 1000, 10);
  15 +};
  16 +
  17 +module.exports = function(str, operation, key, expiry) {
  18 + operation = operation ? operation : 'encode';
  19 + key = key ? key : '';
  20 + expiry = expiry ? expiry : 0;
  21 + let tmpstr, tmp;
  22 +
  23 + let ckeyLength = 4;
  24 +
  25 + key = md5(key);
  26 +
  27 + // 密匙a会参与加解密
  28 + let keya = md5(key.substr(0, 16));
  29 +
  30 + // 密匙b会用来做数据完整性验证
  31 + let keyb = md5(key.substr(16, 16));
  32 +
  33 + // 密匙c用于变化生成的密文
  34 + let keyc = operation === 'decode' ?
  35 + str.substr(0, ckeyLength) : md5(microtime()).substr(-ckeyLength);
  36 +
  37 + // 参与运算的密匙
  38 + let cryptkey = keya + md5(keya + keyc);
  39 +
  40 + let strbuf;
  41 +
  42 + if (operation === 'decode') {
  43 + str = str.substr(ckeyLength);
  44 + strbuf = new Buffer(str, 'base64');
  45 +
  46 + // string = b.toString();
  47 + } else {
  48 + expiry = expiry ? expiry + getTimestamp() : 0;
  49 + tmpstr = expiry.toString();
  50 + if (tmpstr.length >= 10) {
  51 + str = tmpstr.substr(0, 10) + md5(str + keyb).substr(0, 16) + str;
  52 + } else {
  53 + let count = 10 - tmpstr.length;
  54 +
  55 + for (let i = 0; i < count; i++) {
  56 + tmpstr = '0' + tmpstr;
  57 + }
  58 + str = tmpstr + md5(str + keyb).substr(0, 16) + str;
  59 + }
  60 + strbuf = new Buffer(str);
  61 + }
  62 +
  63 +
  64 + let box = new Array(256);
  65 + let rndkey = [];
  66 +
  67 + for (let i = 0; i < 256; i++) {
  68 + box[i] = i;
  69 +
  70 + // 产生密匙簿
  71 + rndkey[i] = cryptkey.charCodeAt(i % cryptkey.length);
  72 + }
  73 +
  74 + // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度
  75 + for (let j = 0, i = 0; i < 256; i++) {
  76 + j = (j + box[i] + rndkey[i]) % 256;
  77 + tmp = box[i];
  78 + box[i] = box[j];
  79 + box[j] = tmp;
  80 + }
  81 +
  82 +
  83 + // 核心加解密部分
  84 + let s = '';
  85 +
  86 + for (let a = 0, j = 0, i = 0; i < strbuf.length; i++) {
  87 + a = (a + 1) % 256;
  88 + j = (j + box[a]) % 256;
  89 + tmp = box[a];
  90 + box[a] = box[j];
  91 + box[j] = tmp;
  92 +
  93 + // 从密匙簿得出密匙进行异或,再转成字符
  94 + // s += String.fromCharCode(string[i] ^ (box[(box[a] + box[j]) % 256]));
  95 + /* jshint -W016*/
  96 + strbuf[i] = strbuf[i] ^ (box[(box[a] + box[j]) % 256]);
  97 + }
  98 +
  99 + if (operation === 'decode') {
  100 + s = strbuf.toString();
  101 + if ((s.substr(0, 10) === '0'.repeat(10) ||
  102 + s.substr(0, 10) - getTimestamp() > 0) &&
  103 + s.substr(10, 16) === md5(s.substr(26) + keyb).substr(0, 16)) {
  104 + s = s.substr(26);
  105 + } else {
  106 + s = '';
  107 + }
  108 + } else {
  109 + s = strbuf.toString('base64');
  110 + let regex = new RegExp('=', 'g');
  111 +
  112 + s = s.replace(regex, '');
  113 + s = keyc + s;
  114 + }
  115 +
  116 + return s;
  117 +};
  118 +
  119 +// console.log(module.exports('abcdef123', 'encode', 'key123', 99))
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 6
7 const helpers = global.yoho.helpers; 7 const helpers = global.yoho.helpers;
8 const _ = require('lodash'); 8 const _ = require('lodash');
  9 +const productProcess = require('./product-process');
9 10
10 const regPromoTitle = /^【[^]+】(.*)/; 11 const regPromoTitle = /^【[^]+】(.*)/;
11 12
@@ -209,8 +210,9 @@ const formatPromotion = (promo) => { @@ -209,8 +210,9 @@ const formatPromotion = (promo) => {
209 */ 210 */
210 const procGoodsDetail = (productData, num) => { 211 const procGoodsDetail = (productData, num) => {
211 let data = {}; 212 let data = {};
  213 + let sizeInfo = productProcess.processSizeInfo(productData);
212 214
213 - data.name = productData.product_name; 215 + Object.assign(data, sizeInfo);
214 data.productSkn = productData.product_skn; 216 data.productSkn = productData.product_skn;
215 if (_.has(productData, 'special_price')) { // 加价购或者赠品的销售价字段 217 if (_.has(productData, 'special_price')) { // 加价购或者赠品的销售价字段
216 data.price = productData.format_market_price; 218 data.price = productData.format_market_price;
@@ -228,145 +230,8 @@ const procGoodsDetail = (productData, num) => { @@ -228,145 +230,8 @@ const procGoodsDetail = (productData, num) => {
228 if (num) { 230 if (num) {
229 data.num = _.parseInt(num); 231 data.num = _.parseInt(num);
230 } 232 }
231 -  
232 - // 商品选择  
233 - if (_.has(productData, 'goods_list')) {  
234 - let goodsList = productData.goods_list;  
235 - let sizeName = '',  
236 - colors = [],  
237 - colorList = [],  
238 - sizes = [],  
239 - sizeList = {},  
240 - allSizeList = {}, // 所有尺码列表  
241 - thumbImageList = [],  
242 - colorNum = 0,  
243 - totalStorageNum = 0, // 总库存数  
244 - colorStorageGroup = {}; // 颜色分组的库存总数集合, 多个之间用/分隔  
245 -  
246 - goodsList.forEach(val => {  
247 - // 商品的尺码列表  
248 - if (!colorStorageGroup[val.product_skc]) {  
249 - colorStorageGroup[val.product_skc] = {};  
250 - }  
251 - if (_.has(val, 'size_list')) {  
252 - // 尺码  
253 - if (!sizeList[val.product_skc]) {  
254 - sizeList[val.product_skc] = [];  
255 - }  
256 - val.size_list.forEach(one => {  
257 - sizeName = one.size_name;  
258 - sizeList[val.product_skc].push({  
259 - id: one.size_id,  
260 - skuId: one.product_sku,  
261 - goodsId: val.goods_id,  
262 - colorId: val.color_id,  
263 - name: one.size_name,  
264 - sizeNum: _.parseInt(one.storage_number, 10),  
265 - sizeInfo: one.size_info ? one.size_info : ''  
266 - });  
267 -  
268 - // 所有尺码列表,赋值用于前端展示默认尺码的时候 判断出没有库存则显示灰色  
269 - allSizeList[sizeName] = !_.has(allSizeList, sizeName) ? {  
270 - id: one.size_id,  
271 - storage: one.storage_number,  
272 - sizeInfo: one.size_info ? one.size_info : ''  
273 - } : allSizeList[sizeName];  
274 -  
275 - colorNum += _.parseInt(one.storage_number, 10);  
276 -  
277 - colorStorageGroup[val.product_skc][sizeName] = _.parseInt(one.storage_number, 10);  
278 - });  
279 -  
280 - // 颜色分组  
281 - colorList.push({  
282 - id: val.color_id,  
283 - skcId: val.product_skc,  
284 - name: val.factory_goods_name || val.color_name,  
285 - colorNum: colorNum,  
286 - goodsName: productData.product_name  
287 - });  
288 - }  
289 -  
290 - // 缩略图  
291 - thumbImageList.push({  
292 - img: helpers.image(val.color_image, 300, 395)  
293 - });  
294 -  
295 - // 商品库存总数  
296 - totalStorageNum += colorNum;  
297 - });  
298 -  
299 - // 遍历所有尺码,构建颜色显示数据  
300 - let i = 1;  
301 -  
302 - if (!sizes[0]) {  
303 - sizes[0] = {  
304 - size: []  
305 - };  
306 - }  
307 - if (!colors[0]) {  
308 - colors[0] = {  
309 - color: []  
310 - };  
311 - }  
312 - _.forEach(allSizeList, (value, sName) => {  
313 - // 默认尺码  
314 - sizes[0].size.push({  
315 - name: sName,  
316 - sizeNum: _.toNumber(value.storage) > 0 ? true : false,  
317 - id: value.id,  
318 - sizeInfo: value.sizeInfo  
319 - });  
320 -  
321 - // 各个颜色的尺码, 每行显示一个尺码对应的颜色  
322 - if (!colors[i]) {  
323 - colors[i] = {  
324 - color: []  
325 - };  
326 - }  
327 - colorList.forEach(colorArr => {  
328 - colors[i].color.push({  
329 - id: colorArr.id,  
330 - skcId: colorArr.skcId,  
331 - name: colorArr.name,  
332 - colorNum: _.has(colorStorageGroup, `${colorArr.skcId}.${sName}`) ? _.parseInt(colorStorageGroup[colorArr.skcId][sName], 10) : 0,  
333 - goodsName: colorArr.goodsName  
334 - });  
335 - });  
336 -  
337 - colors[i].id = value.id;  
338 -  
339 - ++i;  
340 - });  
341 -  
342 - // 遍历所有颜色, 构建尺码显示数据  
343 - i = 1;  
344 - if (!sizes[i]) {  
345 - sizes[i] = {  
346 - color: []  
347 - };  
348 - }  
349 - colorList.forEach(value => {  
350 - // 各个尺码的颜色,每行显示一个颜色的对应尺码  
351 - sizes[i] = {  
352 - size: sizeList[value.skcId],  
353 - colorId: value.skcId  
354 - };  
355 -  
356 - // 默认颜色  
357 - colors[0].color.push(value);  
358 -  
359 - ++i;  
360 - });  
361 - data.thumbs = thumbImageList;  
362 - data.colors = colors;  
363 - data.sizes = sizes;  
364 - data.totalNum = totalStorageNum;  
365 -  
366 data.colorName = '颜色'; 233 data.colorName = '颜色';
367 data.sizeName = '尺码'; 234 data.sizeName = '尺码';
368 - }  
369 -  
370 return data; 235 return data;
371 }; 236 };
372 237
@@ -344,3 +344,158 @@ exports.processFilter = (list, options) => { @@ -344,3 +344,158 @@ exports.processFilter = (list, options) => {
344 344
345 return filters; 345 return filters;
346 }; 346 };
  347 +
  348 +/**
  349 + * 解析尺码弹出框数据
  350 + */
  351 +exports.processSizeInfo = (origin) => {
  352 + let cartInfo = {},
  353 + thumbImageList = [],
  354 + colorGroup = {},
  355 + sizeGroup = [],
  356 + totalStorageNum = 0;
  357 +
  358 + if (origin.goods_list.length) {
  359 + let goodsGroup = [],
  360 + sizeName = '',
  361 + colorList = [],
  362 + sizeList = {},
  363 + allSizeList = {},
  364 + colorStorageGroup = {},
  365 + colorStorageNum = 0;
  366 +
  367 + _.forEach(origin.goods_list, function(value) {
  368 + // 未上架也显示
  369 + // if (value.status === 0) {
  370 + // return;
  371 + // }
  372 +
  373 + colorStorageNum = 0;
  374 +
  375 + // 商品分组
  376 + if (value.images_list) {
  377 + _.forEach(value.images_list, function(good) {
  378 + goodsGroup.push({
  379 + goodsId: value.goods_id,
  380 + img: good.image_url
  381 + });
  382 + });
  383 + }
  384 +
  385 + // 商品的尺码列表
  386 + colorStorageGroup[value.product_skc] = {};
  387 + if (value.size_list) {
  388 + sizeList[value.product_skc] = [];
  389 + _.forEach(value.size_list, function(size) {
  390 + sizeList[value.product_skc].push({
  391 + id: size.size_id,
  392 + skuId: size.product_sku,
  393 + goodsId: value.goods_id,
  394 + colorId: value.color_id,
  395 + name: size.size_name,
  396 + sizeNum: size.storage_number,
  397 + sizeInfo: size.size_info ? size.size_info : ''
  398 + });
  399 +
  400 + sizeName = size.size_name;
  401 +
  402 + // 所有尺码列表,赋值用于前端展示默认尺码的时候
  403 + // 判断出没有库存则显示灰色
  404 + let build = {
  405 + id: size.size_id,
  406 + storage: size.storage_number,
  407 + sizeInfo: size.size_info ? size.size_info : ''
  408 + };
  409 +
  410 + allSizeList[sizeName] = (allSizeList[sizeName] === null ||
  411 + typeof allSizeList[sizeName] === 'undefined') ? build : allSizeList[sizeName];
  412 + colorStorageNum += parseInt(size.storage_number, 10);
  413 + colorStorageGroup[value.product_skc][sizeName] = parseInt(size.storage_number, 10);
  414 + });
  415 +
  416 +
  417 + // 颜色分组
  418 + colorList.push({
  419 + id: value.color_id,
  420 + skcId: value.product_skc,
  421 + name: value.factory_goods_name || value.color_name,
  422 + colorNum: colorStorageNum
  423 + });
  424 + }
  425 +
  426 + // 缩略图
  427 + thumbImageList.push({
  428 + img: helpers.image(value.color_image, 300, 395)
  429 + });
  430 +
  431 + // 商品库存总数
  432 + totalStorageNum += _.toNumber(colorStorageNum);
  433 + });
  434 +
  435 + // 遍历所有尺码,构建颜色显示数据
  436 + let i = 1;
  437 +
  438 + sizeGroup[0] = {
  439 + size: []
  440 + };
  441 + _.forEach(allSizeList, (value, key) => {
  442 +
  443 + // 默认尺码
  444 + sizeGroup[0].size.push({
  445 + name: key,
  446 + sizeNum: _.toNumber(value.storage) > 0 ? true : false,
  447 + id: value.id,
  448 + sizeInfo: value.sizeInfo
  449 + });
  450 +
  451 + colorGroup[i] = {
  452 + color: []
  453 + };
  454 +
  455 + // 各个颜色的尺码, 每行显示一个尺码对应的颜色
  456 + _.forEach(colorList, (colorArr) => {
  457 + let tempColorArr = _.cloneDeep(colorArr);
  458 +
  459 + if (colorStorageGroup[tempColorArr.skcId] &&
  460 + colorStorageGroup[tempColorArr.skcId][key]) {
  461 + tempColorArr.colorNum = colorStorageGroup[tempColorArr.skcId][key];
  462 + } else {
  463 + tempColorArr.colorNum = 0;
  464 + }
  465 + colorGroup[i].color.push(Object.assign({}, tempColorArr));
  466 + });
  467 + colorGroup[i].id = value.id;
  468 +
  469 + ++i;
  470 + });
  471 +
  472 + colorGroup[0] = {
  473 + color: []
  474 + };
  475 +
  476 + // 遍历所有颜色, 构建尺码显示数据
  477 + i = 1;
  478 + _.forEach(colorList, function(value) {
  479 +
  480 + // 各个尺码的颜色, 每行显示一个颜色的对应尺码
  481 + sizeGroup[i] = {
  482 + size: sizeList[value.skcId],
  483 + colorId: value.skcId
  484 + };
  485 +
  486 + // 默认颜色
  487 + colorGroup[0].color.push(value);
  488 + ++i;
  489 + });
  490 + _.orderBy(colorGroup);
  491 + Object.assign(cartInfo, {
  492 + productId: origin.product_id,
  493 + thumbs: thumbImageList,
  494 + name: origin.product_name || '',
  495 + totalNum: totalStorageNum,
  496 + colors: _.toArray(colorGroup),
  497 + sizes: sizeGroup
  498 + });
  499 + }
  500 + return cartInfo;
  501 +};