Authored by htoooth

Merge branch 'master' into release/6.0

# Conflicts:
#	config/common.js
Showing 45 changed files with 1179 additions and 821 deletions
... ... @@ -8,6 +8,7 @@ const staticUrls = require('../../../config/staticUrls');
const api = global.yoho.API;
const Service = global.yoho.ServiceAPI;
const headerModel = require('../../../doraemon/models/header');
const redis = global.yoho.redis;
const getStaticUrls = (currentStatics) => {
... ... @@ -35,9 +36,30 @@ const getStaticUrls = (currentStatics) => {
return Promise.resolve(urls);
};
// 关键词页面
const keywordsPage = () => {
return redis.getAsync('golobal:yoho:seo:keywords:allIds').then(function(res) {
let page = [];
_.forEach(JSON.parse(res), val => {
page.push({
url: `https://www.yohobuy.com/chanpin/${val}.html`,
changefreq: 'daily',
priority: 0.5
});
});
return page;
}).catch(()=>{
return {};
});
};
// www 地图数据
const wwwXmlData = () => {// eslint-disable-line
return getStaticUrls(_.get(staticUrls, 'www'));
return Promise.all([keywordsPage(), getStaticUrls(_.get(staticUrls, 'www'))]).then(result => {
return _.concat(result[1], result[0]);
});
};
// list 地图数据
... ...
... ... @@ -19,7 +19,7 @@ const brandsService = require(`${mRoot}/brands-service`); // students 页 model
exports.index = (req, res, next) => {
let channel = req.query.channel || req.cookies._Channel || 'boys';
brandsService.getBrandViewList(channel, req).then(result => {
req.ctx(brandsService).getBrandViewList(channel, req).then(result => {
// 返回null,不cashe
if (result.noCashe) {
res.set('Cache-Control', 'no-cache');
... ... @@ -35,7 +35,7 @@ exports.index = (req, res, next) => {
exports.brandList = (req, res, next) => {
let channel = req.query.channel || req.cookies._Channel || 'boys';
brandsService.getBrandList(channel, req.body.start).then(result => {
req.ctx(brandsService).getBrandList(channel, req.body.start).then(result => {
res.render('brands/brand-list', Object.assign({layout: false}, result));
... ... @@ -52,7 +52,7 @@ exports.brandInfo = (req, res, next) => {
let brandId = req.query.brandId || 0;
brandsService.brandInfo(brandId, req.user.uid).then(result => {
req.ctx(brandsService).brandInfo(brandId, req.user.uid).then(result => {
// 返回null,不cashe
if (result.noCashe) {
res.set('Cache-Control', 'no-cache');
... ... @@ -67,7 +67,7 @@ exports.brandInfo = (req, res, next) => {
exports.plusstarList = (req, res, next) => {
let channel = req.query.channel || req.yoho.channel;
brandsService.plusstarList(channel, req).then(result => {
req.ctx(brandsService).plusstarList(channel, req).then(result => {
// 返回null,不cashe
if (result.noCashe) {
res.set('Cache-Control', 'no-cache');
... ...
... ... @@ -4,100 +4,159 @@
* @date: 2016/9/29
*/
'use strict';
const api = global.yoho.API;
const serviceAPI = global.yoho.ServiceAPI;
const config = global.yoho.config;
/**
* 分开取数,品牌一览 顶部的轮翻广告及热门品牌数据-PC
* 顶部的轮翻广告及热门品牌数据
* @param string $contentCode 获取广告资源需要的位置码
*/
const getBrandTopData = (contentCode) => {
return serviceAPI.get('operations/api/v5/resource/get', {
content_code: contentCode
}, config.apiCache);
};
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
/**
* 分开取数,获取品牌一览 "按字母'A-Z'分组的品牌列表数据"
* @param int $channel 频道标识 1:男,2:女,3:潮童,4:创意生活
*/
const getBrandListData = channel => {
let params = {method: 'app.brand.allBrandList'};
/**
* 分开取数,品牌一览 顶部的轮翻广告及热门品牌数据-PC
* 顶部的轮翻广告及热门品牌数据
* @param string $contentCode 获取广告资源需要的位置码
*/
getBrandTopData(contentCode) {
return this.get({
url: 'operations/api/v5/resource/get',
data: {
content_code: contentCode
},
param: {
cache: true
},
api: global.yoho.ServiceAPI
});
}
/**
* 分开取数,获取品牌一览 "按字母'A-Z'分组的品牌列表数据"
* @param int $channel 频道标识 1:男,2:女,3:潮童,4:创意生活
*/
getBrandListData(channel) {
let data = {
method: 'app.brand.allBrandList'
};
if (!isNaN(channel)) {
params.yh_channel = channel;
if (!isNaN(channel)) {
data.yh_channel = channel;
}
return this.get({
data: data,
param: {
code: 200,
cache: true
}
});
}
return api.get('', params, config.apiCache);
};
/**
* 获取品牌简介
*
* @param integer $brandId 品牌ID
* @param int 用户ID
* @return array 品牌介绍信息
*/
const getBrandIntro = (brandId, uid) => {
let param = {};
/**
* 获取品牌简介
*
* @param integer $brandId 品牌ID
* @param int 用户ID
* @return array 品牌介绍信息
*/
getBrandIntro(brandId, uid) {
let data = {
method: 'app.brand.getBrandIntro',
brand_id: brandId,
uid: uid
};
if (!uid) {
param.cache = 3600;
if (!uid) {
data.cache = 3600;
}
return this.get({
data: data,
param: {
code: 200,
cache: true
}
});
}
return api.get('', {
method: 'app.brand.getBrandIntro',
brand_id: brandId,
uid: uid
}, param, config.apiCache);
};
/**
* 获取品牌中产品图片
* @param int 品牌ID
* @return array 品牌产品信息
*/
const getProductByBrand = (brandId, limit) => {
return api.get('', {
method: 'web.search.search',
brand: brandId,
limit: limit
}, config.apiCache);
};
/**
* 获取品牌中产品图片
* @param int 品牌ID
* @return array 品牌产品信息
*/
getProductByBrand(brandId, limit) {
/**
* 获取品牌信息
*
* @param array $ids
* @return array
*/
const getBrandInfoByIds = (ids) => {
return api.get('', {
method: 'web.brand.info',
ids: ids instanceof Array ? ids.join(',') : parseInt(ids, 10)
}, config.apiCache);
};
let data = {
method: 'web.search.search',
brand: brandId,
limit: limit
};
/**
* 获取品牌列表
*
* @param int $brandType
* @param string $gender
* @param string $type
* @return array
*/
const getPlusstarList = (brandType, gender) => {
return serviceAPI.get('guang/api/v3/plustar/getlist', {
gender: gender,
brand_type: brandType
}, config.apiCache);
};
return this.get({
data: data,
param: {
code: 200,
cache: true
}
});
}
/**
* 获取品牌信息
*
* @param array $ids
* @return array
*/
getBrandInfoByIds(ids) {
let data = {
method: 'web.brand.info',
ids: ids instanceof Array ? ids.join(',') : parseInt(ids, 10)
};
return this.get({
data: data,
param: {
code: 200,
cache: true
}
});
}
/**
* 获取品牌列表
*
* @param int $brandType
* @param string $gender
* @param string $type
* @return array
*/
getPlusstarList(brandType, gender) {
return this.get({
url: 'guang/api/v3/plustar/getlist',
data: {
gender: gender,
brand_type: brandType
},
param: {
cache: true
},
api: global.yoho.ServiceAPI
});
}
getPlusstarBrandListItem(code) {
return this.get({
url: 'operations/api/v5/resource/get',
data: {
content_code: code
},
param: {
cache: 3600
},
api: global.yoho.ServiceAPI
});
}
module.exports = {
getBrandTopData,
getBrandListData,
getBrandIntro,
getProductByBrand,
getPlusstarList,
getBrandInfoByIds
};
... ...
... ... @@ -10,8 +10,9 @@ const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const brandApi = require('./brands-api');
const serviceApi = global.yoho.ServiceAPI;
const BrandApi = require('./brands-api');
const path = require('path');
const imgUtils = require(path.join(global.utils, 'images'));
// 品牌一览资源位CODE码
const channelCode = {
... ... @@ -33,410 +34,431 @@ const LIFESTYLE = 'lifestyle';
const GLOBAL_BASE_URI = '/product/global/list';
/**
* 获取品牌一览资源位&channelType
*
* @param string $channelStr
* @return array
*/
const switchBrandParams = channel => {
let req = {};
switch (channel) {
case BOYS:
req = {
channelType: 1,
brandCode: channelCode.brand_plusstar_banner_boys
};
break;
case GIRLS:
req = {
channelType: 2,
brandCode: channelCode.brand_plusstar_banner_girls
};
break;
case KIDS:
req = {
channelType: 3,
brandCode: channelCode.kids_brand
};
break;
case LIFESTYLE:
req = {
channelType: 4,
brandCode: channelCode.lifestyle_brand
};
break;
default:
req = {
channelType: 1,
brandCode: channelCode.boys_brand
};
break;
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
return req;
};
/**
* 获取品牌一览页面,品牌top
* @param string $channel 频道名称
*/
const getBrandViewTop = channel => {
return co(function*() {
let switchParams = switchBrandParams(channel);
/**
* 获取品牌一览资源位&channelType
*
* @param string $channelStr
* @return array
*/
switchBrandParams(channel) {
let res = yield brandApi.getBrandTopData(switchParams.brandCode);
let req = {};
let result = {},
brandAds = [],
brandLogos = [];
switch (channel) {
if (!res || res.code !== 200) {
return result;
case BOYS:
req = {
channelType: 1,
brandCode: channelCode.brand_plusstar_banner_boys
};
break;
case GIRLS:
req = {
channelType: 2,
brandCode: channelCode.brand_plusstar_banner_girls
};
break;
case KIDS:
req = {
channelType: 3,
brandCode: channelCode.kids_brand
};
break;
case LIFESTYLE:
req = {
channelType: 4,
brandCode: channelCode.lifestyle_brand
};
break;
default:
req = {
channelType: 1,
brandCode: channelCode.boys_brand
};
break;
}
return req;
}
// 头部10个品牌小图块 url
if (res.data && res.data instanceof Array && res.data[1].data && res.data[1].data.list) {
/**
* 获取品牌一览页面,品牌top
* @param string $channel 频道名称
*/
getBrandViewTop(channel) {
let that = this;
let brandData = new BrandApi(that.ctx);
_.forEach(res.data[1].data.list, subValue => {
brandAds.push({
name: subValue.name,
src: helpers.image(subValue.src, 80, 50, 3),
url: subValue.url
});
});
}
return co(function*() {
let switchParams = that.switchBrandParams(channel);
// 头部品牌图块,广告位
if (res.data && res.data instanceof Array && res.data[0].data) {
_.forEach(res.data[0].data, (subValue, k) => {
let srcUrl;
// kids lifestyle 第一张图尺寸不同
if (switchParams.channelType === 1 || switchParams.channelType === 2) {
srcUrl = helpers.image(subValue.src, 222, 180, 3);
} else {
srcUrl = (k === 0) ? helpers.image(subValue.src, 570, 280, 3) :
helpers.image(subValue.src, 280, 280, 3);
}
let brandPlusstarItem = {
name: subValue.title,
src: srcUrl,
url: subValue.url
};
let res = yield brandData.getBrandTopData(switchParams.brandCode);
if (channel === BOYS || channel === GIRLS) {
if (k === 0) {
brandPlusstarItem.url = helpers.urlFormat('/brands/plusstar', {channel: channel});
} else {
brandPlusstarItem.url = helpers.urlFormat('/brands/plusstar', {id: k, channel: channel});
}
}
let result = {},
brandAds = [],
brandLogos = [];
brandLogos.push(brandPlusstarItem);
});
}
if (!res || res.code !== 200) {
return result;
}
// 整合brandTop数据结构,boys、girls
if (switchParams.channelType === 1 || switchParams.channelType === 2) {
result.isTab = true;
}
result.tabHeader = brandLogos;
result.logos = brandAds;
// 头部10个品牌小图块 url
if (res.data && res.data instanceof Array && res.data[1].data && res.data[1].data.list) {
_.forEach(res.data[1].data.list, subValue => {
brandAds.push({
name: subValue.name,
src: helpers.image(imgUtils.getImageUrl(
(subValue.src.match(/(\S*)imageView2/)[1] +
'imageMogr2/thumbnail/{width}x{height}/extent/{width}x{height}/' +
'background/d2hpdGU=/position/center/quality/80'),
136, 57), 136, 57),
url: subValue.url
});
});
}
return result;
})();
};
// 头部品牌图块,广告位
if (res.data && res.data instanceof Array && res.data[0].data) {
_.forEach(res.data[0].data, (subValue, k) => {
let srcUrl;
/**
* 获取品牌一览list
* @param string $channel 频道名称
* @param int start 开始位置 1 开始
* @param int length 取数长度 0 取到最后
*/
const getBrandViewList = (channel, start, length) => {
return co(function*() {
let switchParams = switchBrandParams(channel);
// kids lifestyle 第一张图尺寸不同
if (switchParams.channelType === 1 || switchParams.channelType === 2) {
srcUrl = helpers.image(subValue.src, 222, 180, 3);
} else {
srcUrl = (k === 0) ? helpers.image(subValue.src, 570, 280, 3) :
helpers.image(subValue.src, 280, 280, 3);
}
let brandPlusstarItem = {
name: subValue.title,
src: srcUrl,
url: subValue.url
};
if (channel === BOYS || channel === GIRLS) {
if (k === 0) {
brandPlusstarItem.url = helpers.urlFormat('/brands/plusstar', {channel: channel});
} else {
brandPlusstarItem.url = helpers.urlFormat('/brands/plusstar', {id: k, channel: channel});
}
}
let res = yield brandApi.getBrandListData(switchParams.channelType);
brandLogos.push(brandPlusstarItem);
});
}
let result = [],
numResult = {};
// 整合brandTop数据结构,boys、girls
if (switchParams.channelType === 1 || switchParams.channelType === 2) {
result.isTab = true;
}
result.tabHeader = brandLogos;
result.logos = brandAds;
if (!res || res.code !== 200) {
return result;
}
})();
}
// 品牌list A-Z 0-9
if (res.data && res.data.all_list) {
/**
* 获取品牌一览list
* @param string $channel 频道名称
* @param int start 开始位置 1 开始
* @param int length 取数长度 0 取到最后
*/
getBrandViewList(channel, start, length) {
let that = this;
let brandData = new BrandApi(that.ctx);
_.forEach(res.data.all_list, (subValue, key) => {
let listTmp = [];
return co(function*() {
let switchParams = that.switchBrandParams(channel);
_.forEach(subValue, ssubValue => {
let extQs = {};
let baseUri = '';
let res = yield brandData.getBrandListData(switchParams.channelType);
// 为品牌名称
let href;
let result = [],
numResult = {};
if (switchParams.channelType === 1) {
Object.assign(extQs, {gender: '1,3'});
} else if (switchParams.channelType === 2) {
Object.assign(extQs, {gender: '2,3'});
}
let shopInfo, shopId;
switch (ssubValue.type * 1) {
case 1:
extQs = {
query: ssubValue.brand_name,
brand: ssubValue.id
};
ssubValue.brand_domain = 'search';
break;
case 2:
shopInfo = _.get(ssubValue, 'shop_info.yoho_shop_list[0]', {});
shopId = shopInfo.shop_id || ssubValue.shop_id;
ssubValue.brand_domain = shopInfo.shop_domain || ssubValue.brand_domain;
if (shopId) {
Object.assign(extQs, {shopId: shopId});
}
break;
case 3:
Object.assign(extQs, {brand: ssubValue.global_brand_id});
ssubValue.brand_domain = '';
baseUri = GLOBAL_BASE_URI;
break;
default:
break;
}
if (!res || res.code !== 200) {
return result;
}
href = helpers.urlFormat(baseUri, extQs, ssubValue.brand_domain);
// 品牌list A-Z 0-9
if (res.data && res.data.all_list) {
_.forEach(res.data.all_list, (subValue, key) => {
let listTmp = [];
_.forEach(subValue, ssubValue => {
let extQs = {};
let baseUri = '';
// 为品牌名称
let href;
if (switchParams.channelType === 1) {
Object.assign(extQs, {gender: '1,3'});
} else if (switchParams.channelType === 2) {
Object.assign(extQs, {gender: '2,3'});
}
let shopInfo, shopId;
switch (ssubValue.type * 1) {
case 1:
extQs = {
query: ssubValue.brand_name,
brand: ssubValue.id
};
ssubValue.brand_domain = 'search';
break;
case 2:
shopInfo = _.get(ssubValue, 'shop_info.yoho_shop_list[0]', {});
shopId = shopInfo.shop_id || ssubValue.shop_id;
ssubValue.brand_domain = shopInfo.shop_domain || ssubValue.brand_domain;
if (shopId) {
Object.assign(extQs, {shopId: shopId});
}
break;
case 3:
Object.assign(extQs, {brand: ssubValue.global_brand_id});
ssubValue.brand_domain = '';
baseUri = GLOBAL_BASE_URI;
break;
default:
break;
}
href = helpers.urlFormat(baseUri, extQs, ssubValue.brand_domain);
let brandItem = {
name: ssubValue.brand_name,
key: ssubValue.id,
href: href
};
if (ssubValue.is_hot === 'Y') {
brandItem.hot = 'hot';
}
listTmp.push(brandItem);
let brandItem = {
name: ssubValue.brand_name,
key: ssubValue.id,
href: href
};
});
if (ssubValue.is_hot === 'Y') {
brandItem.hot = 'hot';
if (key.match(/\d+/g)) {
numResult = {// 把0-9提出来
key: key,
val: _.sortBy(listTmp, 'name')// 对name排序
};
} else {
result.push({
key: key,
val: _.sortBy(listTmp, 'name')// 对name排序
});
}
listTmp.push(brandItem);
});
if (key.match(/\d+/g)) {
numResult = {// 把0-9提出来
key: key,
val: _.sortBy(listTmp, 'name')// 对name排序
};
} else {
result.push({
key: key,
val: _.sortBy(listTmp, 'name')// 对name排序
});
}
});
}
// 只取部分数据
let begin;
if (start) {
begin = (start - 1) ? (start - 1) : 0;
begin = (begin > 0) ? begin : 0;
result = length ? result.slice(begin, length + begin) : result.slice(begin);
}
}
result = _.sortBy(result, 'key');// A-Z排序
result.push(numResult); // 0-9放到最后
result.navigation = _.map(result, 'key');
return result;
})();
};
// 只取部分数据
let begin;
/**
* 获取单个广告浮窗内容
*
* @param int $brandId
* @param int $uid
* @return array
*/
const getBrandInfo = (brandId, uid) => {
return co(function*() {
let data = {},
imgs = [];
// 获取品牌简介
let res = yield brandApi.getBrandIntro(brandId, uid);
if (start) {
begin = (start - 1) ? (start - 1) : 0;
begin = (begin > 0) ? begin : 0;
result = length ? result.slice(begin, length + begin) : result.slice(begin);
}
if (!res || res.code !== 200) {
return data;
}
if (res.data) {
// 获取品牌下的产品信息
let proInfo = yield brandApi.getProductByBrand(brandId, 3);
result = _.sortBy(result, 'key');// A-Z排序
result.push(numResult); // 0-9放到最后
result.navigation = _.map(result, 'key');
return result;
})();
}
if (!proInfo || proInfo.code !== 200) {
/**
* 获取单个广告浮窗内容
*
* @param int $brandId
* @param int $uid
* @return array
*/
getBrandInfo(brandId, uid) {
let that = this;
let brandData = new BrandApi(that.ctx);
return co(function*() {
let data = {},
imgs = [];
// 获取品牌简介
let res = yield brandData.getBrandIntro(brandId, uid);
if (!res || res.code !== 200) {
return data;
}
let proInfoTmp = proInfo.data.product_list ? proInfo.data.product_list : [];
if (res.data) {
// 获取品牌下的产品信息
let proInfo = yield brandData.getProductByBrand(brandId, 3);
if (!_.isEmpty(proInfoTmp)) {
_.forEach(proInfoTmp, subValue => {
imgs.push({
src: helpers.image(subValue.default_images, 80, 100, 3)
if (!proInfo || proInfo.code !== 200) {
return data;
}
let proInfoTmp = proInfo.data.product_list ? proInfo.data.product_list : [];
if (!_.isEmpty(proInfoTmp)) {
_.forEach(proInfoTmp, subValue => {
imgs.push({
src: helpers.image(subValue.default_images, 80, 100, 3)
});
});
});
}
// 整合
data = {
key: res.data.brand_id,
icon: helpers.image(res.data.brand_ico, 80, 50, 3),
title: res.data.brand_name,
content: res.data.brand_intro,
subtitle: 'FEATURED ITEMS',
imgs: imgs
};
}
return data;
})();
}
// 整合
data = {
key: res.data.brand_id,
icon: helpers.image(res.data.brand_ico, 80, 50, 3),
title: res.data.brand_name,
content: res.data.brand_intro,
subtitle: 'FEATURED ITEMS',
imgs: imgs
};
}
return data;
})();
};
/**
* 多个品牌ID获取品牌信息
*
* @param array $brandIds
* @return array
*/
getBrandInfoByIds(brandIds) {
let that = this;
let brandData = new BrandApi(that.ctx);
/**
* 多个品牌ID获取品牌信息
*
* @param array $brandIds
* @return array
*/
const getBrandInfoByIds = (brandIds) => {
return co(function*() {
let res = yield brandApi.getBrandInfoByIds(brandIds);
return co(function*() {
let res = yield brandData.getBrandInfoByIds(brandIds);
let brandsInfo = {};
let brandsInfo = {};
if (!res || res.code !== 200) {
return brandsInfo;
}
if (res.data && res.code === 200) {
_.forEach(res.data, (subValue, k) => {
subValue.desc = _.trim(subValue.brand_intro.replace(/(\t)|(\n)|(\r)|( )/g, '')
if (!res || res.code !== 200) {
return brandsInfo;
}
if (res.data && res.code === 200) {
_.forEach(res.data, (subValue, k) => {
subValue.desc = _.trim(subValue.brand_intro.replace(/(\t)|(\n)|(\r)|( )/g, '')
.replace(/<.*?>/ig, ''));
subValue.url = subValue.brand_domain;
delete subValue.brand_intro;
brandsInfo[k] = subValue;
});
}
subValue.url = subValue.brand_domain;
delete subValue.brand_intro;
brandsInfo[k] = subValue;
});
}
return brandsInfo;
})();
};
return brandsInfo;
})();
}
/**
* 获取plusstar品牌列表项目
*
* @param string $channel
* @return array
*/
const getPlusstarBrandListItem = (channel) => {
return co(function*() {
let code = channel === 'girls' ? channelCode.brand_plusstar_banner_girls :
channelCode.brand_plusstar_banner_boys;
/**
* 获取plusstar品牌列表项目
*
* @param string $channel
* @return array
*/
getPlusstarBrandListItem(channel) {
let that = this;
let brandData = new BrandApi(that.ctx);
// 资源位数据
let resource = yield serviceApi.get('operations/api/v5/resource/get', {content_code: code}, {cache: 3600});
return co(function*() {
let code = channel === 'girls' ? channelCode.brand_plusstar_banner_girls :
channelCode.brand_plusstar_banner_boys;
let items = [];
// 资源位数据
let resource = yield brandData.getPlusstarBrandListItem(code);
if (!resource || resource.code !== 200) {
return items;
}
if (resource.data && resource.code === 200) {
items[0] = {name: '所有品牌', src: '', url: helpers.urlFormat('/brands', {channel: channel}), brandType: ''};
items[1] = {name: '设计新潮', src: '', url: '', brandType: 4};
items[2] = {name: '潮流经典', src: '', url: '', brandType: 1};
items[3] = {name: '明星潮牌', src: '', url: '', brandType: 2};
items[4] = {name: '原创潮牌', src: '', url: '', brandType: 3};
let resourceData = resource.data,
pos = 0;
_.forEach(items, (subValue, k) => {
if (_.isEmpty(subValue.url)) {
subValue.url = helpers.urlFormat('/brands/plusstar', {id: k, channel: channel});
}
let items = [];
if (pos in resourceData[0].data) {
subValue.src = helpers.image(resourceData[0].data[pos].src, 222, 180, 1);
subValue.name = resourceData[0].data[pos].title;
}
pos++;
});
}
return items;
})();
};
/**
* 获取Plustar列表
*
* @param string $brandType
* @param string $gender
* @return array
*/
const getPlustarList = (brandType, gender) => {
return co(function*() {
let list = yield brandApi.getPlusstarList(brandType, gender);
if (!resource || resource.code !== 200) {
return items;
}
if (resource.data && resource.code === 200) {
items[0] = {name: '所有品牌', src: '', url: helpers.urlFormat('/brands',
{channel: channel}), brandType: ''};
items[1] = {name: '设计新潮', src: '', url: '', brandType: 4};
items[2] = {name: '潮流经典', src: '', url: '', brandType: 1};
items[3] = {name: '明星潮牌', src: '', url: '', brandType: 2};
items[4] = {name: '原创潮牌', src: '', url: '', brandType: 3};
let resourceData = resource.data,
pos = 0;
_.forEach(items, (subValue, k) => {
if (_.isEmpty(subValue.url)) {
subValue.url = helpers.urlFormat('/brands/plusstar', {id: k, channel: channel});
}
let brandList = {},
data = {},
brandsIds = [],
result = {brandsIds: [], data: {}};
if (pos in resourceData[0].data) {
subValue.src = helpers.image(resourceData[0].data[pos].src, 222, 180, 1);
subValue.name = resourceData[0].data[pos].title;
}
pos++;
});
}
if (!list || list.code !== 200) {
return result;
}
if (list.data && list.data.data && list.data.data.list) {
brandList = list.data.data.list[0];
}
if (brandList.data) {
_.forEach(brandList.data, brand => {
let src = '';
return items;
})();
}
if (brand.data[0]) {
src = helpers.image(brand.data[0].src, 320, 160, 1);
}
data[brand.brand_id] = {
brand_id: brand.brand_id,
name: brand.brand_name,
sort_id: brand.sort_id,
src: src,
desc: '',
url: ''
};
brandsIds.push(brand.brand_id);
});
/**
* 获取Plustar列表
*
* @param string $brandType
* @param string $gender
* @return array
*/
getPlustarList(brandType, gender) {
let that = this;
let brandData = new BrandApi(that.ctx);
return co(function*() {
let list = yield brandData.getPlusstarList(brandType, gender);
let brandList = {},
data = {},
brandsIds = [],
result = {brandsIds: [], data: {}};
if (!list || list.code !== 200) {
return result;
}
if (list.data && list.data.data && list.data.data.list) {
brandList = list.data.data.list[0];
}
if (brandList.data) {
_.forEach(brandList.data, brand => {
let src = '';
result.brandsIds = brandsIds;
result.data = data;
}
if (brand.data[0]) {
src = helpers.image(brand.data[0].src, 320, 160, 1);
}
data[brand.brand_id] = {
brand_id: brand.brand_id,
name: brand.brand_name,
sort_id: brand.sort_id,
src: src,
desc: '',
url: ''
};
brandsIds.push(brand.brand_id);
});
return result;
})();
};
result.brandsIds = brandsIds;
result.data = data;
}
module.exports = {
getBrandViewTop,
getBrandViewList,
getBrandInfo,
getBrandInfoByIds,
getPlusstarBrandListItem,
getPlustarList
return result;
})();
}
};
... ...
... ... @@ -9,7 +9,7 @@ const Promise = require('bluebird');
const co = Promise.coroutine;
const api = global.yoho.API;
const headerModel = require('../../../doraemon/models/header');
const brandsModel = require('./brands-model');
const BrandsModel = require('./brands-model');
const _ = require('lodash');
const helpers = global.yoho.helpers;
const pager = require(`${global.utils}/pager`).setPager;
... ... @@ -20,294 +20,314 @@ const KIDS = 'kids';
const LIFESTYLE = 'lifestyle';
const queryString = require('querystring');
/**
* 获取品牌一览资源位&channelType
*
* @param string $channelStr
* @return array
*/
const getGenderByChannel = channel => {
let gender = '';
switch (channel) {
case BOYS:
gender = '1,3';
break;
case GIRLS:
gender = '2,3';
break;
default:
gender = '1,2,3';
break;
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
return gender;
};
const getHomeurlByChannel = channel => {
let home;
switch (channel) {
case GIRLS:
home = helpers.urlFormat('/woman', {}, 'new');
break;
case LIFESTYLE:
home = helpers.urlFormat('/lifestyle', {}, 'new');
break;
case KIDS:
home = helpers.urlFormat('/kids', {}, 'new');
break;
default:
home = helpers.urlFormat('');
break;
/**
* 获取品牌一览资源位&channelType
*
* @param string $channelStr
* @return array
*/
getGenderByChannel(channel) {
let gender = '';
switch (channel) {
case BOYS:
gender = '1,3';
break;
case GIRLS:
gender = '2,3';
break;
default:
gender = '1,2,3';
break;
}
return gender;
}
return home;
};
// 添加网站的SEO
const seoMap = {
boys: {
title: '品牌一览|男装品牌排行榜,男装品牌大全|YOHO!BUY 有货 100%正品保证',
keywords: '品牌一览,男装品牌,男装品牌排行榜,男装品牌大全,YOHO!BUY 有货',
description: 'YOHO!BUY 有货男装品牌一览汇集国内国际各大男装品牌大全,为广大爱好时尚的男士青年提供品牌男装、' +
'休闲男装、商务男装.YOHO!BUY 有货,100%正品保证'
},
girls: {
title: '品牌一览|女装品牌排行榜,女装品牌大全|YOHO!BUY 有货 100%正品保证',
keywords: '品牌一览,女装品牌,女装品牌排行榜,女装品牌大全,YOHO!BUY 有货',
description: 'YOHO!BUY 有货女装品牌一览汇集国内国际各大女装品牌,为广大爱美女生提供品牌女装、休闲女装、' +
'商务女装.买品牌女装就上YOHO!BUY 有货,100%正品保证'
},
kids: {
title: '品牌一览|童装童鞋品牌,儿童鞋包配饰排行榜,潮童品牌大全|YOHO!BUY 有货 100%正品保证',
keywords: '童装品牌,童装童鞋排行榜,儿童鞋包配饰排行榜,潮童品牌大全,品牌一览,YOHO!BUY 有货',
description: 'YOHO!BUY 有货童装品牌一览汇集国内国际各大童装品牌大全,为广大爱好潮流的儿童提供品牌童装、童鞋,' +
'儿童鞋包配饰.YOHO!BUY 有货,100%正品保证'
},
lifestyle: {
title: '品牌一览|数码3c,居家,玩具娱乐,文具,美妆品牌|YOHO!BUY 有货 100%正品保证',
keywords: '数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,美妆品牌',
description: 'YOHO!BUY 有货女装品牌一览汇集国内国际各大数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,' +
'美妆品牌.买创意生活家居就上YOHO!BUY 有货,100%正品保证'
},
'boys-plusstar': {
title: '品牌plusstar,男装潮流品牌简介|YOHO!BUY有货',
keywords: '品牌plusstar,男装潮流品牌简介',
description: 'YOHO!BUY 有货男装品牌一览汇集国内国际各大男装品牌,为广大爱美男生提供品牌男装、' +
'休闲男装、商务男装.买品牌男装就上YOHO!BUY 有货,100%正品保证'
},
'girls-plusstar': {
title: '品牌plusstar,女装潮流品牌简介|YOHO!BUY有货',
keywords: '品牌plusstar,女装潮流品牌简介',
description: 'YOHO!BUY 有货女装品牌一览汇集国内国际各大女装品牌,为广大爱美女生提供品牌女装、' +
'休闲女装、商务女装.买品牌女装就上YOHO!BUY 有货,100%正品保证'
getHomeurlByChannel(channel) {
let home;
switch (channel) {
case GIRLS:
home = helpers.urlFormat('/woman', {}, 'new');
break;
case LIFESTYLE:
home = helpers.urlFormat('/lifestyle', {}, 'new');
break;
case KIDS:
home = helpers.urlFormat('/kids', {}, 'new');
break;
default:
home = helpers.urlFormat('');
break;
}
return home;
}
};
/**
* plusstar 分页链接伪静态
* @param string uri
* @param string originUrl 动态地址
*/
const staticUrl = (uri, originUrl) => {
originUrl = queryString.parse(_.split(originUrl, '?')[1]);
return `${uri}id${originUrl.id || 0}-p${originUrl.page || 1}/`;
};
/**
* 获取品牌一览list
* @param string $channel 频道名称
* @param int start 开始位置 1 开始
* @param int length 取数长度 0 取到最后
*/
exports.getBrandViewList = (channel) => {
let apiMethod = [
headerModel.requestHeaderData(channel),
brandsModel.getBrandViewTop(channel),
brandsModel.getBrandViewList(channel) // 分屏加载
];
return api.all(apiMethod).then(result => {
let responseData = {
module: 'brands',
page: 'brands',
noCashe: false
// 添加网站的SEO
seoMap() {
return {
boys: {
title: '品牌一览|男装品牌排行榜,男装品牌大全|YOHO!BUY 有货 100%正品保证',
keywords: '品牌一览,男装品牌,男装品牌排行榜,男装品牌大全,YOHO!BUY 有货',
description: 'YOHO!BUY 有货男装品牌一览汇集国内国际各大男装品牌大全,为广大爱好时尚的男士青年提供品牌男装、' +
'休闲男装、商务男装.YOHO!BUY 有货,100%正品保证'
},
girls: {
title: '品牌一览|女装品牌排行榜,女装品牌大全|YOHO!BUY 有货 100%正品保证',
keywords: '品牌一览,女装品牌,女装品牌排行榜,女装品牌大全,YOHO!BUY 有货',
description: 'YOHO!BUY 有货女装品牌一览汇集国内国际各大女装品牌,为广大爱美女生提供品牌女装、休闲女装、' +
'商务女装.买品牌女装就上YOHO!BUY 有货,100%正品保证'
},
kids: {
title: '品牌一览|童装童鞋品牌,儿童鞋包配饰排行榜,潮童品牌大全|YOHO!BUY 有货 100%正品保证',
keywords: '童装品牌,童装童鞋排行榜,儿童鞋包配饰排行榜,潮童品牌大全,品牌一览,YOHO!BUY 有货',
description: 'YOHO!BUY 有货童装品牌一览汇集国内国际各大童装品牌大全,为广大爱好潮流的儿童提供品牌童装、童鞋,' +
'儿童鞋包配饰.YOHO!BUY 有货,100%正品保证'
},
lifestyle: {
title: '品牌一览|数码3c,居家,玩具娱乐,文具,美妆品牌|YOHO!BUY 有货 100%正品保证',
keywords: '数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,美妆品牌',
description: 'YOHO!BUY 有货女装品牌一览汇集国内国际各大数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,' +
'美妆品牌.买创意生活家居就上YOHO!BUY 有货,100%正品保证'
},
'boys-plusstar': {
title: '品牌plusstar,男装潮流品牌简介|YOHO!BUY有货',
keywords: '品牌plusstar,男装潮流品牌简介',
description: 'YOHO!BUY 有货男装品牌一览汇集国内国际各大男装品牌,为广大爱美男生提供品牌男装、' +
'休闲男装、商务男装.买品牌男装就上YOHO!BUY 有货,100%正品保证'
},
'girls-plusstar': {
title: '品牌plusstar,女装潮流品牌简介|YOHO!BUY有货',
keywords: '品牌plusstar,女装潮流品牌简介',
description: 'YOHO!BUY 有货女装品牌一览汇集国内国际各大女装品牌,为广大爱美女生提供品牌女装、' +
'休闲女装、商务女装.买品牌女装就上YOHO!BUY 有货,100%正品保证'
}
};
}
// 头部数据
Object.assign(responseData, result[0]);
// 品牌一览列表
responseData.brands = result[1];
responseData.brands.navigation = result[2].navigation;
responseData.brands.category = result[2];
/**
* plusstar 分页链接伪静态
* @param string uri
* @param string originUrl 动态地址
*/
staticUrl(uri, originUrl) {
originUrl = queryString.parse(_.split(originUrl, '?')[1]);
return `${uri}id${originUrl.id || 0}-p${originUrl.page || 1}/`;
}
// 导航pathNav
responseData.brands.pathNav = [
{
href: getHomeurlByChannel(channel),
name: `${_.toUpper(channel)}首页`,
pathTitle: 'YOHO!BUY 有货'
},
{
href: helpers.urlFormat('/brands'),
name: '品牌一览',
pathTitle: '品牌一览'
}
/**
* 获取品牌一览list
* @param string $channel 频道名称
* @param int start 开始位置 1 开始
* @param int length 取数长度 0 取到最后
*/
getBrandViewList(channel) {
let that = this;
let brandsModelCtx = new BrandsModel(that.ctx);
let apiMethod = [
headerModel.requestHeaderData(channel),
brandsModelCtx.getBrandViewTop(channel),
brandsModelCtx.getBrandViewList(channel) // 分屏加载
];
// SEO
Object.assign(responseData, seoMap[channel]);
// 数据出错不cashe
if (_.isEmpty(result[0].headerData) || _.isEmpty(result[1]) || _.isEmpty(result[2])) {
responseData.noCashe = true;
}
return responseData;
});
};
return api.all(apiMethod).then(result => {
let responseData = {
module: 'brands',
page: 'brands',
noCashe: false
};
// 头部数据
Object.assign(responseData, result[0]);
// 品牌一览列表
responseData.brands = result[1];
responseData.brands.navigation = result[2].navigation;
responseData.brands.category = result[2];
// 导航pathNav
responseData.brands.pathNav = [
{
href: that.getHomeurlByChannel(channel),
name: `${_.toUpper(channel)}首页`,
pathTitle: 'YOHO!BUY 有货'
},
{
href: helpers.urlFormat('/brands'),
name: '品牌一览',
pathTitle: '品牌一览'
}
];
/**
* brandList-Ajax调用
*/
exports.getBrandList = (channel, start) => {
let apiMethod = [
brandsModel.getBrandViewList(channel, start)
];
return api.all(apiMethod).then(result => {
let responseData = {};
// 品牌一览列表
responseData.category = result[0];
return responseData;
});
};
// SEO
Object.assign(responseData, that.seoMap[channel]);
/**
* 品牌接口数据
*
* @param string brandId 获取品牌ID
* @return json
*/
exports.brandInfo = (brandId, uid) => {
let apiMethod = [
brandsModel.getBrandInfo(brandId, uid)
];
return api.all(apiMethod).then(result => {
let responseData = {
code: _.isEmpty(result[0]) ? 400 : 200,
brand: _.isEmpty(result[0]) ? '' : result[0],
noCashe: false
};
// 数据出错不cashe
if (_.isEmpty(result[0])) {
responseData.noCashe = true;
}
return responseData;
});
};
// 数据出错不cashe
if (_.isEmpty(result[0].headerData) || _.isEmpty(result[1]) || _.isEmpty(result[2])) {
responseData.noCashe = true;
}
return responseData;
});
}
/**
* 多个品牌ID获取品牌信息
*
* @param array $brandIds
* @return array
*/
exports.plusstarList = (channel, req) => {
return co(function*() {
let headerData = yield headerModel.requestHeaderData(channel);
let responseData = {
module: 'brands',
page: 'brands',
brandsHomePage: true,
noCashe: false
};
/**
* brandList-Ajax调用
*/
getBrandList(channel, start) {
let that = this;
let brandsModelCtx = new BrandsModel(that.ctx);
let id = req.query.id || '',
gender = req.query.gender || getGenderByChannel(channel),
limit = 20,
page = parseInt(req.query.page, 10) || 1;
let apiMethod = [
brandsModelCtx.getBrandViewList(channel, start)
];
let items = yield brandsModel.getPlusstarBrandListItem(channel);
return api.all(apiMethod).then(result => {
let responseData = {};
let brandType = 1;
// 品牌一览列表
responseData.category = result[0];
return responseData;
});
}
if (+id !== 0 && items[id]) {
brandType = items[id].brandType;
}
let plustarList = yield brandsModel.getPlustarList(brandType, gender);
/**
* 品牌接口数据
*
* @param string brandId 获取品牌ID
* @return json
*/
brandInfo(brandId, uid) {
let that = this;
let brandsModelCtx = new BrandsModel(that.ctx);
let apiMethod = [
brandsModelCtx.getBrandInfo(brandId, uid)
];
let list = plustarList.data;
return api.all(apiMethod).then(result => {
let responseData = {
code: _.isEmpty(result[0]) ? 400 : 200,
brand: _.isEmpty(result[0]) ? '' : result[0],
noCashe: false
};
// 数据出错不cashe
if (_.isEmpty(headerData.headerData) || _.isEmpty(items) || _.isEmpty(list)) {
responseData.noCashe = true;
}
let brandIds = [],
brands = [],
pageList = {};
brandIds = plustarList.brandsIds.slice((page - 1) * limit, page * limit);
if (plustarList.brandsIds.length > limit) {
pageList = pager(Math.ceil(plustarList.brandsIds.length / limit), {
page: page,
id: id
});
// url 伪静态
_.forEach(pageList.pages, (val) => {
val.url = staticUrl(`/${channel}-brands/plusstar/`, val.url);
});
if (pageList.nextPage) {
pageList.nextPage.url = staticUrl(`/${channel}-brands/plusstar/`, pageList.nextPage.url);
}
if (pageList.prePage) {
pageList.prePage.url = staticUrl(`/${channel}-brands/plusstar/`, pageList.prePage.url);
// 数据出错不cashe
if (_.isEmpty(result[0])) {
responseData.noCashe = true;
}
}
return responseData;
});
}
if (brandIds.length > 0) {
// 获取品牌信息
let brandsInfo = yield brandsModel.getBrandInfoByIds(brandIds);
/**
* 多个品牌ID获取品牌信息
*
* @param array $brandIds
* @return array
*/
plusstarList(channel, req) {
let that = this;
let brandsModelCtx = new BrandsModel(that.ctx);
return co(function*() {
let headerData = yield headerModel.requestHeaderData(channel);
let responseData = {
module: 'brands',
page: 'brands',
brandsHomePage: true,
noCashe: false
};
let id = req.query.id || '',
gender = req.query.gender || that.getGenderByChannel(channel),
limit = 20,
page = parseInt(req.query.page, 10) || 1;
let items = yield brandsModelCtx.getPlusstarBrandListItem(channel);
let brandType = 1;
if (+id !== 0 && items[id]) {
brandType = items[id].brandType;
}
let plustarList = yield brandsModelCtx.getPlustarList(brandType, gender);
_.forEach(brandIds, brandId => {
if (brandsInfo[brandId]) {
list[brandId].desc = brandsInfo[brandId].desc;
list[brandId].url = helpers.urlFormat('', {gender: gender}, brandsInfo[brandId].url);
}
brands.push(list[brandId]);
});
let list = plustarList.data;
// 数据出错不cashe
if (_.isEmpty(brandsInfo)) {
if (_.isEmpty(headerData.headerData) || _.isEmpty(items) || _.isEmpty(list)) {
responseData.noCashe = true;
}
}
let data = {
brandsHomePage: true,
brands: {
items: brands,
tabs: items
let brandIds = [],
brands = [],
pageList = {};
brandIds = plustarList.brandsIds.slice((page - 1) * limit, page * limit);
if (plustarList.brandsIds.length > limit) {
pageList = pager(Math.ceil(plustarList.brandsIds.length / limit), {
page: page,
id: id
});
// url 伪静态
_.forEach(pageList.pages, (val) => {
val.url = that.staticUrl(`/${channel}-brands/plusstar/`, val.url);
});
if (pageList.nextPage) {
pageList.nextPage.url = that.staticUrl(`/${channel}-brands/plusstar/`, pageList.nextPage.url);
}
if (pageList.prePage) {
pageList.prePage.url = that.staticUrl(`/${channel}-brands/plusstar/`, pageList.prePage.url);
}
}
if (brandIds.length > 0) {
// 获取品牌信息
let brandsInfo = yield brandsModelCtx.getBrandInfoByIds(brandIds);
_.forEach(brandIds, brandId => {
if (brandsInfo[brandId]) {
list[brandId].desc = brandsInfo[brandId].desc;
list[brandId].url = helpers.urlFormat('', {gender: gender}, brandsInfo[brandId].url);
}
brands.push(list[brandId]);
});
// 数据出错不cashe
if (_.isEmpty(brandsInfo)) {
responseData.noCashe = true;
}
}
};
let data = {
brandsHomePage: true,
brands: {
items: brands,
tabs: items
}
};
// 头部数据
Object.assign(responseData, headerData);
// 头部数据
Object.assign(responseData, headerData);
// 产品信息
Object.assign(responseData, data);
// 产品信息
Object.assign(responseData, data);
// 页码
Object.assign(responseData, pageList);
// 页码
Object.assign(responseData, pageList);
// SEO
Object.assign(responseData, seoMap[`${channel}-plusstar`] || {});
return responseData;
})();
// SEO
Object.assign(responseData, that.seoMap[`${channel}-plusstar`] || {});
return responseData;
})();
}
};
... ...
... ... @@ -36,7 +36,7 @@
<div class="brands-logo clearfix">
{{#each logos}}
<a href="{{url}}" title="{{name}}" target="_blank">
<img class="lazy" data-original="{{image2 src}}">
<img class="lazy" src="{{image2 src w=136 h=57}}">
</a>
{{/each}}
</div>
... ...
... ... @@ -8,6 +8,7 @@
const headerModel = require('../../../doraemon/models/simple-header');
const ticketService = require('../models/ticket-service');
const _ = require('lodash');
const helpers = global.yoho.helpers;
const stepper = [
{ name: '填写订单', focus: true },
... ... @@ -16,14 +17,19 @@ const stepper = [
const ticketEnsure = (req, res, next) => {
let uid = req.user.uid;
let sku = req.body.productSku || 0;
let buyNumber = req.body.buyNumber || 0;
let sku = req.query.productSku || 0;
let buyNumber = req.query.buyNumber || 0;
let skn = req.query.productSkn || 0;
ticketService.addTicket(uid, sku, buyNumber).then(result => {
let header = headerModel.setSimpleHeaderData() || {};
result.stepper = stepper;
if (result.error) {
result.productUrl = helpers.getUrlBySkc(skn);
}
res.render('ticket-ensure', {
title: '填写订单 | ' + (res.locals.title || ''),
page: 'ticket',
... ... @@ -39,7 +45,7 @@ const ticketSubmit = (req, res, next) => {
let sku = req.body.sku || 0;
let count = req.body.count || 0;
let mobile = req.body.mobile || 0;
let yohoCoin = req.body.yohoCoin || 0;
let yohoCoin = req.body.coin || 0;
if (!sku || !count || !mobile) {
return res.json({
... ...
... ... @@ -17,7 +17,8 @@ const PROMOTION_TYPE_TAG_MAP = {
Needpaygift: '加价购',
SpecifiedAmount: '满减', // X件X元
FreeShippingCost: '免运费',
VipFreeShippingCost: '免运费'
VipFreeShippingCost: '免运费',
Payment: '折扣' // apple pay
};
const GOODS_TYPE_TAG_MAP = {
... ...
... ... @@ -26,9 +26,13 @@ const addTicket = co(function * (uid, sku, count, yohoCoin) {
let result = {};
if (ticketInfo.code !== 200) {
return result;
return {
last_order_amount: 0,
error: ticketInfo.message
};
}
result.virtualGood = true;
result.goodsList = _handleGoodsList(_.get(ticketInfo, 'data.goods_list', []));
result.last_order_amount = _handleAmount(ticketInfo);
Object.assign(result, _handleUseYhoCoin(_.get(ticketInfo, 'data.shopping_cart_data', {})));
... ...
... ... @@ -37,7 +37,7 @@ router.get('/easypay', auth, easypay.index); // 限购商品快捷结算页
router.post('/easypay/compute', auth, easypay.compute); // 价格重新计算
router.post('/easypay/submit', auth, easypay.submit); // 限购商品订单提交
router.post('/ticketEnsure', auth, ticket.ticketEnsure);
router.get('/ticketEnsure', auth, ticket.ticketEnsure);
router.post('/ticketSubmit', auth, ticket.ticketSubmit);
router.post('/ticketCompute', auth, ticket.ticketCompute);
... ...
... ... @@ -32,7 +32,7 @@
<tr>
<th width="3%"></th>
<th class="aline-left" width="46%">商品信息</th>
<th>颜色/尺码</th>
<th>时间</th>
<th width="18%">单价</th>
<th width="6%">数量</th>
<th width="3%"></th>
... ... @@ -44,16 +44,18 @@
data-price="{{last_price}}" data-num="{{buy_number}}">
<td{{#if @first}} class="border-top"{{/if}}></td>
<td class="border-top aline-left">
<a class="image" href="{{linkToGoods}}">
<img src="{{image2 goods_images w=64 h=85}}" class="thumb">
<p class="name">
<a class="image ticket-cover" href="{{linkToGoods}}">
<span class="ticket-image">
<img src="{{image2 goods_images w=64 h=85}}" class="thumb">
<span class="ticket-image-tag">虚拟商品</span>
</span>
<p class="ticket-name">
{{product_name}}
</p>
</a>
</td>
<td class="border-top color-size">
颜色:<span class="color">{{color_name}}</span>
尺码:<span class="size">{{size_name}}</span>
<span>{{color_name}}</span>
</td>
<td class="border-top price">
<p class="red">¥ {{round productPrice 2}}</p>
... ... @@ -103,5 +105,12 @@
应付金额:<span id="order-price" class="price">¥ {{round last_order_amount 2}}</span>
<button id="order-submit">提交订单</button>
</div>
{{#if error}}
<div class="error hide">
<span class="info">{{error}}</span>
<span class="url">{{productUrl}}</span>
</div>
{{/if}}
{{/ content}}
</div>
... ...
... ... @@ -12,36 +12,14 @@ const helpers = global.yoho.helpers;
exports.QRcode = (req, res, next) => {
let id = req.query.orderCode || 0;
let bg = {
'16-1': '//img13.static.yhbimg.com/yhb-img02/2016/08/04/14/02004edaf02b52363c27cea0e2cbbe9b59.jpg',
'17-1': '//img12.static.yhbimg.com/yhb-img02/2016/08/04/14/023d0470ffc2b0efe89bfdd1c6b73ab894.jpg',
'16-2': '//img12.static.yhbimg.com/yhb-img02/2016/08/04/14/02fcb3d6cdd6be244c836c520a0d034fed.jpg',
'17-2': '//img12.static.yhbimg.com/yhb-img02/2016/08/04/14/02ed77b564211c3246ab7be81794ed17cd.jpg'
};
let bgkey = '16-1', ticktypeName = '展览票';
QRcodeModel.getQRcodeData(id, req.user.uid).then((result)=>{
if (result) {
result.ticks = result.ticks.map(item=>{
if (+item.ticket_type === 2) {
item.isgroup = true;
}
return item;
});
if (result.ticks.length) {
bgkey = [/月(\d+)/g.exec(result.ticks[0].entrance_time)[1], result.ticks[0].ticket_type].join('-');
ticktypeName = result.ticks[0].ticket_type === '2' ? '套票' : '展览票';
}
}
let vm = {
path: [{href: helpers.urlFormat('/'), name: 'YOHO!BUY 有货首页'},
{name: '个人中心'}, {name: '订单中心'}, {name: '查看二维码'}],
qrcodeData: result,
onlyOne: result.ticks.length === 1,
code: id,
bgsrc: bg[bgkey],
ticktypeName: ticktypeName,
ticktypeName: result.title,
returnOrder: helpers.urlFormat('/home/orders')
};
... ...
... ... @@ -31,7 +31,7 @@ const _homeNav = (switcher) => {
{name: '我的评论', href: '/home/comment'},
// {name: '我的投诉', href: '/home/complaints'},
{name: '我的推广', href: '/home/spread'},
{name: '我的邀请好友', href: '/home/spread'},
{name: '我的信息', href: '/home/message', count: 0},
{
name: '在线客服',
... ...
... ... @@ -225,7 +225,7 @@ const _getGoodsTag = (attribute, goodsType) => {
// 电子
case 'ticket':
goodsTagName = '';
goodsTagName = 'virtualGood';
break;
default:
break;
... ... @@ -235,6 +235,7 @@ const _getGoodsTag = (attribute, goodsType) => {
if (attribute === 3) {
goodsTagName = 'virtualGood';
}
return goodsTagName;
};
... ... @@ -737,13 +738,13 @@ const _getOrderDetail = co(function * (uid, orderId) {
// 虚拟商品
if (+orderDetail.attribute === 3) {
detail.virtualGoods = true;
detail.virtualGood = true;
detail.virtualPayMode = {
payMode: ChannelConfig.payType[orderDetail.payment_type],
phone: _.fill(orderDetail.mobile.split(''), '*', 3, 4).join('')
};
} else {
detail.virtualGoods = false;
detail.virtualGood = false;
detail.noramlPayMode = {
payMode: ChannelConfig.payType[orderDetail.payment_type],
payWay: orderDetail.payment_name,
... ... @@ -798,7 +799,7 @@ const _getOrderDetail = co(function * (uid, orderId) {
num: good.buy_number,
sum: good.goods_amount,
sku: good.product_sku,
[_getGoodsTag(+good.attribute, good.goods_type)]: true
[_getGoodsTag(+orderDetail.attribute, good.goods_type)]: true
};
// 划线的价格
... ...
... ... @@ -218,6 +218,7 @@ const getOrderRefund = (orderCode, uid) => {
// tar note 为每个特殊商品都添加标识
if (value.is_limit_skn === 'Y') {
item.isLimitSkn = true;
item.specialNoticeBo = {
title: _.get(result, 'data.special_notice.title', ''),
remark1: remarks[0] || '',
... ... @@ -568,6 +569,7 @@ const getOrderExchange = (orderCode, uid) => {
// tar note 为每个特殊商品都添加标识
if (value.is_limit_skn === 'Y') {
item.isLimitSkn = true;
item.specialNoticeBo = {
title: _.get(result, 'data.specialNoticeBo.title', ''),
remark1: remarks[0] || '',
... ...
... ... @@ -31,6 +31,8 @@ module.exports = class extends global.yoho.BaseModel {
if (resList.code === 200) {
let list = _.get(resList, 'data.data', []);
resData.rules = _.get(resList, 'data.activityRuleDesc', '');
if (!_.isEmpty(list)) {
resData.list = list;
}
... ...
... ... @@ -6,16 +6,16 @@
<h2 class="title">
</h2>
<div class='subtitle'>
<h2>虚拟商品 <span class='pad20'>2016 YO'HOOD</span> {{ticktypeName}} <i id="qrid"></i></h2>
<h2>虚拟商品 <span class='pad20'>{{ticktypeName}}</span><i id="qrid"></i></h2>
<a class='r-go' href="{{returnOrder}}">返回我的订单</a>
</div>
{{#qrcodeData}}
<div class='qrcmain'>
<div class="qrcmain-switch">
<a class="prev gray" href="javascript:;">
<a class="prev gray {{#if ../onlyOne}}hide{{/if}}" href="javascript:;">
<span class="iconfont">&#xe60e;</span>
</a>
<a class="next" href="javascript:;">
<a class="next {{#if ../onlyOne}}hide{{/if}}" href="javascript:;">
<span class="iconfont">&#xe60c;</span>
</a>
</div>
... ... @@ -27,9 +27,6 @@
<div class='center'>
<img src='{{image2 qr_image}}'>
<p class='bianhao'><label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;号:</label><i>{{ticket_code}}</i></p>
{{#if isgroup}}
<p class='zuoweihao'><label>&nbsp;&nbsp;&nbsp;&nbsp;号:</label>{{seat_no}}</p>
{{/if}}
<p><label>进场时间:</label>{{entrance_time}}</p>
</div>
</li>
... ...
... ... @@ -10,7 +10,7 @@
{{!--防诈骗提示--}}
{{> swindle-info}}
<div class="detail-info{{#if virtualGoods}} virtual-detail{{/if}} {{#if offlineBySelf}}offline-self{{/if}}">
<div class="detail-info{{#if virtualGood}} virtual-detail{{/if}} {{#if offlineBySelf}}offline-self{{/if}}">
<div class="status">
<p>
订单编号:
... ... @@ -21,7 +21,7 @@
{{#if operation.goPay}}
<a class="go-pay oo-btn" href="{{operation.goPay}}">立即付款</a>
{{/if}}
{{#unless virtualGoods}}
{{#unless virtualGood}}
<!--虚拟商品-->
{{#if changeable}}
<span class="edit-order oo-btn">修改地址</span>
... ... @@ -165,6 +165,8 @@
</p>
<div class="content">
<span>付款方式:{{payMode}}</span>
<br />
<br />
<span>电话号码:{{phone}}</span>
</div>
</div>
... ... @@ -236,13 +238,10 @@
</a>
<p class="name-color-size">
<a class="name" href="{{url}}" target="_blank">{{name}}</a>
{{#if virtualGood}}
{{#if ../virtualGood}}
{{#if color}}
日期:{{color}}
{{/if}}
{{#if size}}
区域:{{size}}
{{/if}}
{{else}}
{{#if color}}
<b title="{{color}}">颜色:{{color}}</b>
... ...
... ... @@ -35,7 +35,7 @@
<input type="hidden" value="{{sku}}" name="sku">
<input type="hidden" value="{{price}}" name="price">
<input type="hidden" value="{{goods_type_id}}" name="typeid">
<input type="checkbox" checked="true">
{{#unless isLimitSkn}}<input type="checkbox" checked="true">{{/unless}}
{{/unless}}
</td>
<td width="60">
... ... @@ -89,7 +89,7 @@
</td>
{{^}}
<td class="return-reason-wrap">
<select class="return-reason">
<select class="return-reason" {{#if isLimitSkn}}disabled{{/if}}>
<option value="0">请选择换货原因</option>
{{# reason}}
<option value="{{id}}" {{#if inactive}}disabled{{/if}}>{{name}}</option>
... ... @@ -235,7 +235,7 @@
{{#if banMsg}}
<label>{{banMsg}}</label>
{{^}}
<select class="return-reason">
<select class="return-reason" {{#if isLimitSkn}}disabled{{/if}}>
<option value="0">请选择退货原因</option>
{{# reason}}
<option value="{{id}}">{{name}}</option>
... ...
... ... @@ -7,21 +7,21 @@
{{# spread}}
<div class="spread-wrap clearfix">
<div class="item-card">
<span class="tag">邀请二维码</span>
<span class="tag">方法一:扫描邀请二维码</span>
<div class="card-main">
<div class="spread-code" data-url="{{url}}"></div>
</div>
<p>{{{activityDescribe}}}</p>
</div>
<div class="item-card">
<span class="tag">邀请码</span>
<span class="tag">方法二:使用邀请码</span>
<div class="card-main">
<p class="spread-id">{{inviteCode}}</p>
</div>
<p>1.复制您的邀请码<br>2.粘贴给您的朋友</p>
</div>
<div class="item-card">
<span class="tag">邀请链接</span>
<span class="tag">方法三:使用邀请链接</span>
<div class="card-main">
<div class="spread-url">
<input type="text" value="{{url}}" class
... ... @@ -32,6 +32,10 @@
<p>1.复制您的邀请链接<br>2.选择您的社交平台<br>3.粘贴给您的朋友</p>
</div>
</div>
<div class="spread-wrap clearfix spread-rules">
<h2>活动细则</h2>
<p>{{{rules}}}</p>
</div>
<div class="my-spread-list">
<table>
<thead>
... ... @@ -39,7 +43,6 @@
<th>我邀请的好友</th>
<th>注册时间</th>
<th>首单购物金额</th>
<th>订单状态</th>
<th>我的奖励</th>
<th>奖励状态</th>
<th>发放时间</th>
... ... @@ -51,9 +54,15 @@
<td>{{nickName}}</td>
<td>{{registerTimeDis}}</td>
<td>{{orderAmountDis}}</td>
<td>{{paymentStatusDesc}}</td>
<td>{{couponName}}</td>
<td>{{couponStatusDesc}}</td>
<td class="coupon-status">{{couponStatusDesc}}
{{#if paymentStatusDesc}}
<i class="help-icon"></i>
<div class="coin-tip-help">
<p>{{paymentStatusDesc}}</p>
</div>
{{/if}}
</td>
<td>{{couponSendTimeDis}}</td>
</tr>
{{/ list}}
... ...
... ... @@ -41,9 +41,6 @@
{{#if color}}
日期:{{color}}&nbsp;&nbsp;
{{/if}}
{{#if size}}
区域:{{size}}
{{/if}}
{{else}}
{{#if color}}
<b title="{{color}}">颜色:{{color}}&nbsp;&nbsp;</b>
... ...
... ... @@ -9,4 +9,4 @@
{{/if}}
{{#if preSaleGood}}
<span class="presall-tag">预售</span>
{{/if}}
\ No newline at end of file
{{/if}}
... ...
... ... @@ -38,7 +38,7 @@
</li>
<li class="clearfix" data-index="3">
<input id="invite-code" class="input invite-code" name="inviteCode" placeholder="邀请码" autocomplete="off" maxlength="20" type="text">
<input id="invite-code" class="input invite-code" name="inviteCode" placeholder="邀请码(非必填)" autocomplete="off" maxlength="20" type="text">
</li>
<li class="items-container clearfix">
... ...
... ... @@ -200,6 +200,35 @@ const keyword = (req, res, next) => {
}).catch(next);
};
/**
* 搜索推荐列表页
* @param {[type]} req [description]
* @param {[type]} res [description]
* @return {[type]} [description]
*/
const keyId = (req, res, next) => {
let params = req.query;
let id = req.params.id;
return search.getSearchKeywordDataById(id, params, req.yoho.channel).then(result => {
let query = result.queryKey;
Object.assign(result, {
pageNoFollow: true,
title: `${query}价格_图片_品牌_怎么样-YOHO!BUY有货`,
keywords: `${query},${query}价格,${query}图片,${query}怎么样,${query}品牌,YOHO!BUY有货`,
description: `YOHO!BUY有货网yohobuy.com是国内专业的${query}网上潮流购物商城,为您找到${_.get(result,
'search.totalCount', 0)}${query}、产品的详细参数,实时报价,价格行情,图片、评价、品牌等信息。买${query},就上YOHO!BUY有货`
});
if (!_.get(result, 'search.goods') || !_.get(result, 'search.goods').length) {
_.set(result, 'search.keyWord', query);
return res.render('search/no-result', result);
}
res.render('search/index', result);
}).catch(next);
};
module.exports = {
index,
suggest,
... ... @@ -207,6 +236,7 @@ module.exports = {
searchFilterBrands,
searchHistory, // 搜索历史记录
searchLessRecommend,
keyword
keyword,
keyId
};
... ...
... ... @@ -737,7 +737,7 @@ exports.handleFilterData = (origin, params, total) => {
}];
// 尺码处理
if (!_.isEmpty(origin.size) && ((params.msort && !_.includes(params.msort, ',')) || params.misort || params.sort)) {
if (!_.isEmpty(origin.size) && params.category_id) {
dest.size = [];
... ... @@ -1788,7 +1788,11 @@ exports.handleSuggestData = (origin, query) => {
});
});
leftContent.allSuggest = {all: all, list: list};
leftContent.allSuggest = {
all: all,
title: '相关推荐',
list: list
};
return leftContent;
};
... ...
... ... @@ -10,6 +10,7 @@ const api = global.yoho.API;
const Promise = require('bluebird');
const co = Promise.coroutine;
const helpers = global.yoho.helpers;
const redis = global.yoho.redis;
const saleApi = require('./sale-api');
const searchApi = require('./search-api');
const headerModel = require('../../../doraemon/models/header');
... ... @@ -401,3 +402,50 @@ exports.getSearchKeywordData = (params, channel) => {
return setSearchKeywordData(result, params, channel);
});
};
/**
* 获取搜索建议数据
* @id {[number]} origin [description]
* @param {[object]} origin [description]
* @channel {[string]} origin [description]
* @return {[object]} [description]
*/
exports.getSearchKeywordDataById = (id, params, channel) => {
let that = this;
return co(function * () {
let redisData = yield redis.all([
['get', `golobal:yoho:seo:keywords:id:${id}`]
]);
if (!redisData[0]) {
return Promise.reject('get redis canpin keywords by id error!' +
`key: golobal:yoho:seo:keywords:id:${id} value: ${redisData[0]}`);
}
redisData = JSON.parse(redisData[0]);
params.query = redisData.name;
let resData = yield that.getSearchKeywordData(params, channel);
resData.queryKey = params.query;
if (!_.isEmpty(redisData.data)) {
_.forEach(redisData.data, value => {
if (!value) {
return;
}
Object.assign(value, {
name: value.keyword,
href: helpers.urlFormat(`/chanpin/${value.id}.html`, null, 'www')
});
});
_.set(resData, 'search.leftContent.allSuggest.list', redisData.data);
}
return resData;
})();
};
... ...
... ... @@ -103,6 +103,7 @@ router.get('/api/suggest', search.suggest4Old);
router.get('/search/history', search.searchHistory); // 搜索历史提示
router.get('/search/less/recommend', search.searchLessRecommend);// 搜索少或无 有可能喜欢
router.get('/search/keyword/:id', search.keyword);
router.get('/search/chanpin/:id', search.keyId);
// 商品分类列表页
router.get('/list/index', gbk2utf, list.index);
... ...
... ... @@ -131,9 +131,7 @@
{{#if virtualGoods}}
{{!-- 电子门票按钮 --}}
{{#if isVirtualBtn}}
<form name="ticket-form" action="{{buyNowBase}}" method="POST"
class="hide"></form>
<span id="buy-ticket" class="buy-ticket buy-now item-buy{{#if dis}} dis{{/if}}">立即购买</span>
<span id="buy-ticket" class="buy-ticket buy-now item-buy{{#if dis}} dis{{/if}}" data-base="{{buyNowBase}}">立即购买</span>
{{/if}}
{{else}}
{{!-- 各颜色下所有尺码均售罄则只显示售罄按钮 --}}
... ...
... ... @@ -10,7 +10,10 @@
<span class="bundle {{#if_cond bundle.type "!=" 2}}hide{{/if_cond}}">
{{bundle.count}}件起购{{#if bundle.discount}}{{bundle.discount}}折优惠{{/if}}
</span>
<span class="bundle {{#unless isTicket}}hide{{/unless}}" >
限购4件
</span>
<span class="few-sold hide">
... ...
... ... @@ -10,7 +10,7 @@
</ul>
</div>
<div class="chose-size row clearfix {{#unless isTicket}} hide {{/unless}}">
<div class="chose-size row clearfix hide">
<input type="hidden" name="isTicket" value="{{isTicket}}"/>
<span class="title pull-left">
选区域:
... ...
... ... @@ -17,12 +17,12 @@ module.exports = {
cookieDomain: '.yohobuy.com',
domains: {
// test3
// singleApi: 'http://api-test3.yohops.com:9999/',
// api: 'http://api-test3.yohops.com:9999/',
// service: 'http://service-test3.yohops.com:9999/',
// serviceNotify: 'http://service-test3.yohops.com:9999/',
// global: 'http://global-test-soa.yohops.com:9999/',
// platformApi: 'http://192.168.102.48:8088/',
singleApi: 'http://api-test3.yohops.com:9999/',
api: 'http://api-test3.yohops.com:9999/',
service: 'http://service-test3.yohops.com:9999/',
serviceNotify: 'http://service-test3.yohops.com:9999/',
global: 'http://global-test-soa.yohops.com:9999/',
platformApi: 'http://192.168.102.48:8088/',
// test2
// singleApi: 'http://api-test2.yohops.com:9999/',
... ... @@ -47,11 +47,11 @@ module.exports = {
// platformApi: 'http://172.16.6.210:8088/',
// dev
api: 'http://dev-api.yohops.com:9999/',
service: 'http://dev-service.yohops.com:9999/',
serviceNotify: 'http://dev-service.yohops.com:9999/',
singleApi: 'http://dev-api.yohops.com:9999/',
platformApi: 'http://192.168.102.48:8088/',
// api: 'http://dev-api.yohops.com:9999/',
// service: 'http://dev-service.yohops.com:9999/',
// serviceNotify: 'http://dev-service.yohops.com:9999/',
// singleApi: 'http://dev-api.yohops.com:9999/',
// platformApi: 'http://192.168.102.48:8088/',,
imSocket: 'ws://socket.yohobuy.com:10240',
imCs: 'http://im.yohobuy.com/api',
... ...
... ... @@ -77,6 +77,13 @@ module.exports = [
target: (req, match, p1) => `/product/search/keyword/${p1}`
},
// 推荐词id列表页
{
type: TYPE.rewrite,
origin: /^\/chanpin\/(.*)\.html(.*)/,
target: (req, match, p1) => `/product/search/chanpin/${p1}`
},
// erp2good
{
type: TYPE.rewrite,
... ...
const _ = require('lodash');
const redis = require('redis');
const bluebird = require('bluebird');
const config = require('../../config/common');
... ... @@ -9,6 +11,18 @@ try {
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
client.all = args => {
if (!client.ready) {
if (Array.isArray(args)) {
return Promise.resolve(_.fill(args, false));
} else {
return Promise.resolve(false);
}
}
return client.multi.call(client, args).execAsync();
};
client.on('error', function() {
global.yoho.redis = '';
});
... ... @@ -20,6 +34,4 @@ try {
global.yoho.redis = '';
}
module.exports = client;
... ...
... ... @@ -287,5 +287,6 @@
<div class="code-down-box">
<div class="code-img"></div>
<h5 class="code-title">下载手机客户端</h5>
<i class="iconfont icon-del"></i>
</div>
{{/ headerData}}
... ...
... ... @@ -36,7 +36,7 @@
</div>
<div class="good-detail-img">
<a class="good-thumb" href="{{url}}" target="_blank">
<img class="lazy" data-original="{{image2 thumb w=280 h=382}}">
<img class="lazy" data-original="{{image2 thumb w=280 h=382}}">
</a>
{{# is_few}}
<p class="few-tag">即将售罄</p>
... ...
... ... @@ -89,6 +89,9 @@
{{!-- 搜索推荐--}}
{{# allSuggest}}
<div class="sort-container">
{{# title}}
<h2 class="nav-pic-title">{{.}}</h2>
{{/ title}}
<ul class="sort-child-list suggest-list">
{{#each list}}
<li>
... ... @@ -140,4 +143,4 @@
{{/each}}
</ul>
</div>
{{/signboard}}
\ No newline at end of file
{{/signboard}}
... ...
{
"name": "yohobuy-node",
"version": "5.8.7",
"version": "5.9.0",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ...

5.55 KB | W: | H:

5.85 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
... ... @@ -17,6 +17,28 @@ var submitting = false;
require('../common');
require('../simple-header');
function errorInfo(info, url) {
new dialog.Dialog({
content: info,
className: 'ensure-back-alert',
btns: [{
id: 'back-sure',
btnClass: ['back-sure'],
name: '返回商品详情页',
cb: function() {
window.jumpUrl(url);
}
}]
}).show();
}
if ($('.error').length === 1) {
errorInfo(
$('.error').find('.info').text(),
$('.error').find('.url').text()
);
}
function validateUserInfo(info) {
var errTip = '';
... ... @@ -24,6 +46,10 @@ function validateUserInfo(info) {
errTip = '您还没有填写手机号';
}
if (!errTip && !/^\d{11}$/ig.test(info.mobile)) {
errTip = '手机号只能是11位数字';
}
if (errTip) {
new dialog.Alert((errTip)).show();
return false;
... ...
... ... @@ -987,21 +987,8 @@ function searchSuggestHistory() {
}
$(function() {
var windowWidth = document.documentElement.clientWidth;
if (windowWidth <= 1440) {
$('.code-down-box').bind('click', '.icon-del', function() {
$('.code-down-box').hide();
}
$(window).resize(function() {
var innerWindowWidth = window.innerWidth;
if (innerWindowWidth > 1440 && innerWindowWidth <= windowWidth) {
$('.code-down-box').show();
} else {
$('.code-down-box').hide();
}
});
});
... ...
... ... @@ -942,13 +942,13 @@ bindEvent.add(function() {
sku = $('.size:not(.hide) li.focus').data('sku');
buyNumber = getNum();
var $ticketForm = $('form[name="ticket-form"]'); // eslint-disable-line
$ticketForm.html(
'<input name="productSku" value="' + sku + '" />' +
'<input name="buyNumber" value="' + buyNumber + '" />'
);
$ticketForm.submit();
window.jumpUrl(
[
$(this).data('base'),
'?productSku=', sku,
'&buyNumber=', buyNumber,
'&productSkn=', skn
].join(''));
});
// 立即购买
... ...
... ... @@ -917,6 +917,38 @@
}
}
.ticket-cover {
.ticket-image {
display: inline-block;
position: relative;
}
.ticket-image-tag {
display: block;
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 15px;
line-height: 16px;
text-align: center;
color: #fff;
background: #333;
}
.ticket-name {
display: inline-block;
width: 280px;
max-height: 68px;
font-size: 15px;
padding-left: 20px;
line-height: 1.5;
overflow: hidden;
word-break: break-all;
vertical-align: top;
}
}
.use-coupons {
.tip-box {
width: 60%;
... ...
... ... @@ -1494,7 +1494,7 @@
border: none;
background-color: transparent;
z-index: 990;
display: none;
display: block;
.code-img {
width: 117px;
... ... @@ -1511,10 +1511,17 @@
line-height: 20px;
text-align: center;
}
}
@media screen and (min-width: 1440px) {
.code-down-box {
display: block;
.icon-del {
position: absolute;
top: -13px;
right: -10px;
display: inline-block;
font-size: 30px;
cursor: pointer;
&:before {
content: "\e60d";
}
}
}
... ...
... ... @@ -28,9 +28,10 @@
}
.tag {
width: 76px;
height: 24px;
line-height: 24px;
width: 252px;
margin-left: -1px;
height: 25px;
line-height: 25px;
background-color: #000;
color: #fff;
text-align: center;
... ... @@ -112,5 +113,67 @@
padding: 14px 0;
text-align: center;
}
.coupon-status {
position: relative;
}
.help-icon {
display: block;
width: 16px;
height: 16px;
background: url(/cart/help-mark.png);
position: absolute;
right: 3%;
top: 50%;
margin-top: -8px;
cursor: pointer;
&:hover + .coin-tip-help {
display: block;
}
}
.coin-tip-help {
width: 200px;
padding: 6px 10px;
line-height: 2;
border: 1px solid #000;
background-color: #fff;
text-align: center;
position: absolute;
top: 38px;
right: -100px;
display: none;
z-index: 1000;
}
.coin-tip-help:before {
content: "";
width: 12px;
height: 6px;
background-image: url(../img/sprite.cart.png);
background-position: -325px -76px;
display: block;
position: absolute;
top: -6px;
right: 106px;
}
}
.spread-rules {
border: 1px solid #dedede;
padding: 10px 20px;
width: 736px;
margin: 0 auto;
h2 {
font-size: 14px;
font-weight: 600;
}
p {
line-height: 18px;
}
}
}
... ...
... ... @@ -84,6 +84,10 @@
padding-left: 5px;
color: #bbb;
}
&:first-child {
margin-top: 4px;
}
}
a {
... ... @@ -93,9 +97,13 @@
white-space: nowrap;
display: block;
color: #666;
padding-left: 10px;
height: 22px;
line-height: 22px;
margin-left: 10px;
}
&.suggest-list a {
margin-left: 0;
}
}
... ...