Authored by 陈轩

Merge branch 'feature/seckill' into release/5.1

Showing 62 changed files with 4342 additions and 100 deletions

Too many changes to show.

To preserve performance only 62 of 62+ files are displayed.

... ... @@ -4,7 +4,9 @@
"sourceType": "module"
},
"rules": {
"max-len": [0, 50, 4]
"max-len": [0, 50, 4],
"camelcase": "off",
"vars-on-top": "off"
}
}
... ...
... ... @@ -8,13 +8,11 @@ const co = require('bluebird').coroutine;
function humanNum_wan(num) {
return num;
// if (num > 9999) {
// num = (num / 10000).toFixed(2) + '万'
// }
if (num > 9999) {
num = (num / 10000).toFixed(2) + '万';
}
// return num;
return num;
}
exports.beforeIn = (req, res, next) => {
... ...
... ... @@ -105,7 +105,7 @@ exports.getGoods = cate => {
let skn = product.productSkn;
let imgSrc = url.parse(product.defaultImages);
product.defaultImages = ['//', imgSrc.hostname, imgSrc.pathname].join('');
product.defaultImages = ['//', imgSrc.hostname, imgSrc.pathname].join('');
product.url = helpers.appUrlFormat(product.url, 'go.productDetail', {
product_skn: skn
... ...
/**
* 秒杀结算
*/
'use strict';
const co = require('bluebird').coroutine;
const seckillModel = require('../models/seckill');
const buyNowModel = require('../models/buynow');
const BAD_REQUEST = '非法请求';
exports.ensure = (req, res, next) => {
const sku = Number.parseInt(req.query.sku, 10);
const skn = Number.parseInt(req.query.skn, 10);
const uid = req.user.uid;
// require skn, sku;
if (!(sku && skn)) {
return next('error');
}
co(function*() {
let paymentOption = {
buy_number: 1,
yoho_coin_mode: 1,
product_sku: sku,
sku_type: 'S',
uid
};
let skillData = yield seckillModel.skillData(skn); // 根据skn查活动信息
skillData = skillData.data;
if (!(
skillData &&
skillData.status &&
skillData.secKillSku.some(obj => obj.productSku === sku) // skn has sku;
)) {
return Promise.reject('活动不存在');
}
paymentOption.activity_id = skillData.activityId;
// 获取结算 数据
let paymentInfo = yield buyNowModel.payment(paymentOption);
if (paymentInfo.code !== 200) {
return Promise.reject('结算请求失败');
}
// 渲染
let view = Object.assign({
seckill: skillData,
orderEnsure: true,
sku,
}, paymentInfo.data);
// console.log(view);
res.locals.title = '确认订单';
res.render('order-ensure', view);
})().catch(next);
};
exports.compute = (req, res, next) => {
const uid = req.user.uid,
sku = req.body.sku,
activityId = req.body.activityId;
if (!req.xhr) {
return next(400);
}
// 必填字段
if ([uid, sku, activityId].some(field => !field)) {
return res.status(400).json({
code: 400,
msg: BAD_REQUEST
});
}
const options = {
sku_type: 'S', // 秒杀
buy_number: 1,
yoho_coin_mode: 1,
payment_type: 1,
uid: req.user.uid,
product_sku: sku,
delivery_way: req.body.deliveryId || 1,
use_yoho_coin: req.body.use_yoho_coin || 0,
activity_id: activityId
};
return buyNowModel.compute(options)
.then(result => {
res.json(result.data);
})
.catch(next);
};
exports.submit = (req, res, next) => {
const uid = req.user.uid,
sku = req.body.sku,
activityId = req.body.activityId,
addressId = Number.parseInt(req.body.addressId, 10),
deliveryTime = Number.parseInt(req.body.deliveryTime, 10),
deliveryWay = Number.parseInt(req.body.deliveryWay, 10),
paymentId = Number.parseInt(req.body.paymentId, 10),
paymentType = Number.parseInt(req.body.paymentType, 10);
if (!req.xhr) {
return next(404);
}
if ([uid, sku, activityId, addressId, deliveryTime,
deliveryWay, paymentId, paymentType
].some(field => !field)) {
return res.status(400).json({
code: 400,
msg: BAD_REQUEST
});
}
const options = {
sku_type: 'S',
buy_number: 1,
invoices_title: req.body.invoicesTitle || '',
invoices_type_id: req.body.invoicesTypeId || '',
use_yoho_coin: Number.parseFloat(req.body.useYohoCoin) || 0,
remark: req.body.remark || '',
address_id: addressId,
delivery_time: deliveryTime,
delivery_way: deliveryWay,
payment_id: paymentId,
payment_type: paymentType
};
return buyNowModel.submit(options)
.then(result => {
res.clearCookie('order-info');
res.json(result);
})
.catch(next);
};
... ...
/**
* sub app cart
* @author: xuan.chen@yoho.cn<xuan.chen@yoho.cn>
* @date: 2016/09/26
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
var app = express();
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
helpers: global.yoho.helpers
}));
// router
app.use(require('./router'));
module.exports = app;
... ...
/**
* doc: http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/%E8%AE%A2%E5%8D%95/%E7%AB%8B%E5%8D%B3%E8%B4%AD%E4%B9%B0.md
*/
'use strict';
const API = global.yoho.API;
const paymentProcess = require(global.utils + '/payment-process');
exports.payment = options => {
let queryData = Object.assign({
method: 'app.Buynow.payment',
}, options);
return API.post('', queryData)
.then(result => {
// TODO 数据处理
if (result.code === 200 && result.data) {
}
return result;
});
// mock
// .catch()
// .then(() => {
// let mockData = require('./_buynow-mock').payment;
// return {
// code: 200,
// data: paymentProcess.tranformPayment(mockData.data)
// };
// });
};
exports.compute = options => {
let url = '';
let queryData = Object.assign({
method: 'app.Buynow.compute',
}, options);
return API.post(url, queryData);
// mock
// .catch()
// .then(() => {
// let mockData = require('./_buynow-mock').compute;
// return mockData;
// });
};
exports.submit = options => {
let url = '';
let queryData = Object.assign({
method: 'app.Buynow.submit'
}, options);
return API.post(url, queryData);
};
... ...
'use strict';
const API = global.yoho.API;
/**
* 获取 获取秒杀信息接口
* doc: http://git.yoho.cn/yoho-documents/api-interfaces/blob/master/%E5%95%86%E5%93%81%E5%88%97%E8%A1%A8/seckill.md
*/
exports.skillData = product_skn => {
let queryData = {
method: 'app.seckill.data',
product_skn
};
return API.post('', queryData);
};
... ...
/**
* router of sub app cart
* @author: xuan.chen@yoho.cn<xuan.chen@yoho.cn>
* @date: 2016/09/26
*/
'use strict';
const router = require('express').Router(); //eslint-disable-line
const cRoot = './controllers';
const authMW = require('../../doraemon/middleware/auth');
const seckill = require(cRoot + '/seckill');
// Your controller here
router.all('/seckill/', authMW);
router.all('/seckill/*', authMW);
router.get('/seckill/', seckill.ensure);
router.post('/seckill/compute', seckill.compute);
router.post('/seckill/submit', seckill.submit);
module.exports = router;
... ...
<div class="order-ensure-page yoho-page">
{{# orderEnsure}}
{{#if addressInfo}}
<div class="address block address-wrap {{#if pageHeader.boys}} boys{{/if}}{{#if pageHeader.girls}} girls{{/if}}{{#if pageHeader.kids}} kids{{/if}}{{#if pageHeader.lifeStyle}} life-style{{/if}}" data-id ="{{addressId}}">
<div class="info">
<span class="info-name">{{name}}</span>
<span class="info-phone">{{phoneNum}}</span>
<a href="/cart/index/selectAddress"><span class="info-address">{{addressInfo}}</span></a>
<i class="iconfont">&#xe637;</i>
</div>
<a class="rest" href="/cart/index/selectAddress">其他地址<span class="iconfont">&#xe614;</span></a>
</div>
{{else}}
<div class="address block address-wrap not-address">
<i class="iconfont">&#xe637;</i>
<a class="choose" href="/cart/index/selectAddress">请选择收货地址<span class="iconfont">&#xe614;</span></a>
</div>
{{/if}}
<section class="dispatch block">
<div class="sub-block payment-type">
<h3>
<p>支付方式</p>
{{#each paymentWay}}
{{#if recommend}}<span>{{name}}</span>{{/if}}
{{/each}}
<i class="iconfont down">&#xe616;</i>
<i class="iconfont hide up">&#xe615;</i>
</h3>
<ul>
{{#each paymentWay}}
{{#if isSupport}}
<li {{#if recommend}}class="chosed"{{/if}}>
<span>{{name}}</span>
<i class="right iconfont {{#if recommend}}icon-cb-radio{{else}}icon-radio{{/if}}" data-id="{{paymentType}}"></i>
</li>
{{/if}}
{{/each}}
</ul>
</div>
<div class="sub-block delivery-id">
<h3>
<p>配送方式</p>
{{#each dispatchMode}}
{{#if isSelected}}<span>{{name}}:运费¥{{cost}}</span>{{/if}}
{{/each}}
<i class="iconfont down">&#xe616;</i>
<i class="iconfont hide up">&#xe615;</i>
</h3>
<ul class="dispatch-mode">
{{#each dispatchMode}}
<li {{#if isSelected}}class="chosed"{{/if}} data-id="{{id}}">
<span>{{name}}:运费¥{{cost}}</span>
<i class="right iconfont {{#if isSelected}}icon-cb-radio{{else}}icon-radio{{/if}}" data-id="{{id}}"></i>
</li>
{{/each}}
</ul>
</div>
<div class="sub-block dispatch-time">
<h3>
<p>送货时间</p>
{{#each dispatchTime}}
{{#if isSelected}}<span>{{name}}</span>{{/if}}
{{/each}}
<i class="iconfont down">&#xe616;</i>
<i class="iconfont hide up">&#xe615;</i>
</h3>
<ul>
{{#each dispatchTime}}
<li {{#if isSelected}}class="chosed"{{/if}} data-id="{{id}}">
<span>{{name}}</span>
<i class="right iconfont radio {{#if isSelected}}icon-cb-radio{{else}}icon-radio{{/if}}" ></i>
</li>
{{/each}}
</ul>
</div>
</section>
{{#if isJit}}
{{> me/order/jit-more}}
{{/if}}
<section class="block goods-bottom">
{{#each goods}}
{{> me/order/good}}
{{/each}}
<div class="goods-num">{{num}}件商品 合计<span>{{goodsPrice}}</span></div>
</section>
<section class="block">
<ul class="sale-invoice">
{{#if isOrdinaryCart}}
<li class="coupon">
<a href="{{#if isLimit}}javascript:void(0);{{else}}/cart/index/selectCoupon{{/if}}">
<span class="title">优惠券</span>
{{# coupon}}
<span class="coupon-count">
{{count}}张可用
</span>
{{#if couponName}}
<span class="used coupon-use" data-name="{{couponName}}">
{{couponName}}
<i class="iconfont">&#xe614;</i>
</span>
{{^}}
<span class="not-used coupon-use">
{{#if isLimit}}该商品不可使用优惠券{{else}}未使用{{/if}}
<i class="iconfont">&#xe614;</i>
</span>
{{/if}}
{{/coupon}}
</a>
</li>
{{/if}}
<li class="coin" data-yoho-coin="{{yohoCoin}}">
<span class="title">有货币</span>
{{#if yohoCoin}}
<span class="desc used {{#unless useYohoCoin}}hide{{/unless}}">已抵¥{{useYohoCoin}}</span>
<span class="desc can-use {{#if useYohoCoin}}hide{{/if}}">可抵¥{{yohoCoin}}</span>
{{#if useYohoCoin}}
<span class="coin-check">
<!-- <em>- ¥ {{useYohoCoin}}</em> -->
<i class="iconfont checkbox icon-cb-radio"></i>
</span>
{{else}}
<span class="coin-check">
<!-- <em style="display: none;">- ¥ {{useYohoCoin}}</em> -->
<i class="iconfont checkbox icon-radio"></i>
</span>
{{/if}}
{{^}}
<span class="not-used coin-check">
无有货币可用
</span>
{{/if}}
</li>
{{#if invoice}}
<li class="invoice {{#if needInvoice}}focus{{/if}}">
<input type="hidden" class="user-mobile" value="{{userMobile}}" />
<span class="title">发票</span>
<span class="iconfont checkbox {{#if needInvoice}}icon-cb-radio{{else}}icon-radio{{/if}}"></span>
<a id="invoice" class="invoice-info" href="invoiceInfo">
<span class="title">发票信息</span>
<span class="invoice-type"><i class="iconfont">&#xe614;</i></span>
</a>
<!-- <form id="invoice">
<input type="text" name="invoice-title" value="{{invoiceText}}" maxlength="30" placeholder="发票抬头">
<label>
发票类型
<select class="invoice-type" name="invoice-type">
{{# invoice}}
<option value="{{id}}" {{#if isSelected}}selected{{/if}}>{{name}}</option>
{{/ invoice}}
</select>
</label>
</form> -->
</li>
{{/if}}
</ul>
<form id="msg" action="" method="post">
<input type="text" name="msg" value="{{msg}}" maxlength="40" placeholder="留言">
</form>
</section>
<section class="price-cal block">
<ul class="total">
{{#cartPayData}}
<li>
<p>{{promotion}}</p>
<span>{{promotion_amount}}</span>
</li>
{{/cartPayData}}
</ul>
<div class="price-cost">
实付金额
<span>¥{{price}}</span>
</div>
{{#if returnYohoCoin}}
<div class="yoho-coin">
共返有货币: {{yohoCoinNum}}
</div>
{{/if}}
</section>
<div class="bill">
您需要支付:<span>¥{{price}}</span>
<a href="javascript:;">提交订单</a>
</div>
<input type="hidden" id="product-sku" name="product-sku" value="{{sku}}">
{{#with seckill}}
<input type="hidden" id="activity-id" name="activity-id" value="{{activityId}}">
{{/with}}
{{/ orderEnsure}}
</div>
... ...
... ... @@ -38,6 +38,17 @@ let _channelPage = (req, res, data) => {
gender: data.gender,
uid: _.toString(req.user.uid)
}).then(result => {
// result.content = [{
// seckill: true,
// data: {
// title: {
// name: '限时秒抢',
// title: '限时秒抢',
// moreUrl: 'http://m.yohobuy.com'
// }
// }
// }].concat(result.content);
// console.log(result.content[9]);
res.render('channel', Object.assign({}, _renderData, data, result));
});
};
... ...
{{#content}}
{{! 头部banner}}
{{#if focus}}
... ... @@ -55,6 +56,10 @@
{{#if newUserFloor}}
{{> resources/fresh-only}}
{{/if}}
{{! 秒杀}}
{{#if seckill}}
{{> resources/seckill}}
{{/if}}
{{! 标题楼层}}
{{#if titleFloor}}
{{> resources/title-floor}}
... ...
... ... @@ -259,3 +259,17 @@ exports.consultsubmit = (req, res, next) => {
return res.json(data);
}).catch(next);
};
exports.getSeckillData = (req, res) => {
detailModel.getSeckillData({
productskn: req.params.productskn
}, req).then(result => {
return res.json(result);
});
};
... ...
/**
* 秒杀页面
* @author: 陈峰<feng.chen@yoho.cn>
* @date: 2016/09/08
*/
'use strict';
const moment = require('moment');
const mRoot = '../models';
const headerModel = require('../../../doraemon/models/header');
const seckillModel = require(`${mRoot}/seckill`);
/**
* [时间缺0补0]
*/
const _timeFormat = (tick) => {
return tick < 10 ? `0${tick}` : tick;
};
/**
* 秒杀商品 添加 秒杀按钮状态
*
* @param isApp app才有提醒功能
* @param productList 秒杀商品列表
*
* 默认: 去抢购
* 已抢光 over=true
* 在APP中未开抢 wait=true
*/
function _productAddFlag(productList) {
let now = Date.now();
productList.sort((a, b) => a.orderBy < b.orderBy);
productList.forEach(product => {
if (now < product.startTime * 1000) { // 未开抢
product.wait = true;
} else if (product.secKillStatus === 0) { // 已开抢-已抢光
product.over = true;
}
});
return productList;
}
let _helpers = {
statusClass: (nav) => {
if (nav.over) {
return 'over';
} else if (nav.now) {
return 'now';
} else if (nav.wait) {
return 'wait';
} else {
return '';
}
},
readaleTime: (unixStamp) => {
return moment.unix(unixStamp).format('MM月DD日 hh:mm');
}
};
/**
* [秒杀列表页面]
*/
const index = (req, res, next) => {
let headerData = headerModel.setNav({
navTitle: '秒杀活动',
navBtn: true,
}),
result = {},
hbsHelper = {
helpers: _helpers
};
let uid = req.yoho.isApp && req.query.uid;
return seckillModel.queryActivity().then((resultActivity) => {
// console.log(resultActivity)
if (resultActivity.code !== 200 || resultActivity.data.secKillProductVoList.length === 0) {
return next();
}
result.activitys = resultActivity.data.secKillProductVoList.sort((a, b) => a.startTime > b.startTime);
let nowTime = Date.parse(new Date());
result.activitys.forEach((activity, i) => {
let date,
hour = 0,
minute = 0;
activity.startTime *= 1000;
date = new Date(activity.startTime);
hour = date.getHours();
minute = date.getMinutes();
activity.time = `${_timeFormat(hour)}:${_timeFormat(minute)}`;
if (nowTime > activity.startTime) { // 当前时间大于这个时间段,已经开始和即将开始两种情况
if (i < result.activitys.length - 1) {
let nextTime = result.activitys[i + 1].startTime * 1000;
if (nowTime < nextTime) { // 下一个时间段与当前时间来区别是否正在抢购
activity.now = true;
activity.focus = true;
} else {
activity.over = true;
}
} else { // 大于这个时间段但是后面没有秒抢时间端了,则依然显示抢购中
activity.now = true;
}
} else {
activity.wait = true;
}
});
if (result.activitys.length && result.activitys.findIndex(activity => activity.focus) < 0) {
result.activitys[0].focus = true;
}
let focusActivity = result.activitys.find(activity => activity.focus);
return seckillModel.queryProductList(focusActivity.activityId, uid).then((resultProducts) => {
result.products = _productAddFlag(resultProducts.data, req.yoho.isApp);
// console.log(result);
res.render('seckill', Object.assign({
pageHeader: headerData,
pageFooter: true,
width750: true,
times: 12
}, result, hbsHelper));
});
});
};
/**
* [xhr根据活动id获取商品列表]
*/
const getProductList = (req, res, next) => {
if (!req.xhr) {
return next();
}
let activityId = Number(req.query.activityId);
let uid = req.yoho.isApp && req.query.uid;
if (!activityId) {
return next();
}
return seckillModel.queryProductList(activityId, uid).then((resultProducts) => {
let result = {
products: _productAddFlag(resultProducts.data)
};
res.render('seckill/product-list', Object.assign(result, {
layout: false
}, {helpers: _helpers}));
});
};
// only app
const remind = (req, res, next) => {
if (!(req.yoho.isApp && req.xhr)) {
return res.status(404).json({
msg: '请求不合法'
});
}
return seckillModel.remind({
on_off: req.body.on_off,
activity_id: Number.parseInt(req.body.activity_id, 10),
product_skn: Number.parseInt(req.body.product_skn, 10),
uid: Number.parseInt(req.body.uid, 10),
sec_kill_id: Number.parseInt(req.body.sec_kill_id, 10),
app_type: 0
})
.then(result=> {
return res.json(result);
});
};
module.exports = {
index,
getProductList,
remind
};
... ...
... ... @@ -921,7 +921,7 @@ const _detailDataPkg = (origin, uid, vipLevel, ua) => {
};
let _getShopsInfo = (brandId) => {
if(!brandId) {
if (!brandId) {
return Promise.resolve([]);
}
return api.get('', {
... ... @@ -974,6 +974,32 @@ const _getCommonConsult = () => {
});
};
/**
* 获取秒杀列表
*/
const getSeckillData = (param) => {
let params = {
method: 'app.seckill.data',
product_skn: param.productskn
};
return api.get('', params, {
code: 200
})
// mock
.catch()
.then(result => {
let data = {};
if (result.data) {
data = result.data;
}
return data;
});
};
let getProductData = (data) => {
let finalResult;
let params = {
... ... @@ -995,6 +1021,7 @@ let getProductData = (data) => {
}
return _getUserProfile(params.uid).then((user) => {
data.vipLevel = (user.data && user.data.vip_info && user.data.vip_info.cur_level) || '0';
data.isStudent = (user.data && user.data.vip_info && user.data.vip_info.is_student) ? true : false;
params.is_student = data.isStudent ? 1 : 0;
... ... @@ -1014,8 +1041,51 @@ let getProductData = (data) => {
productId: result.productId
}),
_getCommonConsult(),
comment.getConsults(result.productId, 1, 2)
comment.getConsults(result.productId, 1, 2),
getSeckillData({productskn: result.productSkn})
]).then((info) => {
// 根据app.product.data接口是否返回isSecKill,判断是否是秒杀
let isSecKills = result.isSecKill === 'Y' ? true : false;
let gList = result.goodsList;
// 统计非秒杀库存数
let commonNum = 0;
gList.forEach(row => {
row.sizeList.forEach(val => {
commonNum = commonNum + val.storageNumber;
});
});
// 统计秒杀库存数
let leftCount = 0;
if (info && info[5] && info[5].secKillSku) {
info[5].secKillSku.forEach(val => {
leftCount = leftCount + val.storageNum;
});
}
// 如果秒杀库存不为0,将商品库存链接至秒杀库存
let i = 0;
if (isSecKills && info[5] && leftCount) {
gList.forEach(row => {
row.sizeList.forEach(val => {
val.storageNumber = info[5].secKillSku[i].storageNum;
val.productSku = info[5].secKillSku[i].productSku;
i++;
});
});
}
// 秒杀详情页弹出层价格
if (isSecKills && leftCount && info[5]) {
result.formatMarketPrice = info[5].formatSecKillPrice;
}
result.promotionBoList = info[1];
finalResult = _detailDataPkg(result, data.uid, data.vipLevel, data.ua);
finalResult.enterStore = info[0];
... ... @@ -1023,7 +1093,35 @@ let getProductData = (data) => {
Object.assign(finalResult.feedbacks, info[2]);
/* 如果有咨询,显示咨询,否则显示常见问题 */
// 秒杀详情页
if (isSecKills && info[5]) {
let end = info[5].status === 3 ? true : false;
if (!end) {
let notStart = info[5].status === 1 ? true : false;
let startIng = info[5].status === 2 ? true : false;
Object.assign(finalResult, {
isSecKill: {
notStart: notStart,
startIng: startIng,
end: end,
productSkn: data.productSkn,
secKillPrice: info[5].formatSecKillPrice,
noneLeft: leftCount === 0 && commonNum === 0 ? true : false
}
});
}
}
/* 如果有咨询,显示咨询,否则显示常见问题 */
if (info[4].total) {
finalResult.feedbacks.consultsNum = parseInt(info[4].total, 10);
... ... @@ -1049,5 +1147,6 @@ let getProductData = (data) => {
module.exports = {
getProductData,
getUserProfile: _getUserProfile
getUserProfile: _getUserProfile,
getSeckillData
};
... ...
/**
* 秒杀models
* @author: 陈峰<feng.chen@yoho.cn>
* @date: 2016/9/18
*/
'use strict';
const api = global.yoho.API;
/**
* [获取秒杀时间栏接口]
* @return {[object]}
*/
const queryActivity = () => {
return api.get('', {
method: 'app.seckill.queryActivity'
});
};
/**
* [获取指定秒杀活动商品列表接口]
* @param {[int]} activityId [秒杀活动id]
* @param {[int]} uid only app use
* @return {[object]}
*/
const queryProductList = (activityId, uid) => {
return api.get('', {
method: 'app.seckill.queryProductList',
activityId: activityId,
uid: uid
}, {
cache: true
});
};
const remind = (options) => {
let url = '';
let formData = Object.assign({
method: !options.on_off ? 'app.seckill.cancelUserReminder' : 'app.seckill.addUserReminder',
}, options);
return api.get(url, formData);
};
module.exports = {
queryActivity,
queryProductList,
remind
};
... ...
... ... @@ -27,6 +27,9 @@ const recommendForYou = require(`${cRoot}/recommend-for-you`);
// recom
const recom = require(`${cRoot}/recom`);
// 秒杀 controller
const seckill = require(`${cRoot}/seckill`);
// routers
// /pro_136349_455445/HEARTSOFARMianMaShuJiaoXiuXianKuPS1684.html
... ... @@ -39,9 +42,13 @@ router.get('/detail/consults', detail.consults); // 商品咨询页
router.get('/detail/consultform', auth, detail.consultform); // 商品咨询表单页
router.get('/detail/comments', detail.comments); // 商品评价
router.post('/detail/consultsubmit', auth, detail.consultsubmit); // 商品咨询提交接口
router.get('/recom/maylike', recom.mayLike);// 你可能喜欢
router.get('/recom/maylikekids', recom.mayLikeKids); // 潮童你可能喜欢
router.get('/detail/seckillData/:productskn', detail.getSeckillData); // 秒杀数据接口
router.post('/detail/consultupvote', detail.consultUpvoteOrUseful); // 商品咨询提交接口
router.post('/detail/consultuseful', detail.consultUpvoteOrUseful); // 商品咨询提交接口
... ... @@ -62,4 +69,9 @@ router.get('/outlet/activityinfo', outlet.activityList);
router.get('/recommend-for-you/userCenter', recommendForYou.userCenter);
router.get('/recommend-for-you/cart', recommendForYou.cart);
router.get('/seckill', seckill.index); // 秒杀列表页
router.post('/seckill/remind', seckill.remind); // only app; 秒杀提醒
router.get(/\/seckill\/detail\/pro_([\d]+)_([\d]+)\/(.*)/, detail.getUser, detail.index); // 秒杀详情页
router.get(/\/seckill\/detail\/show_([\d]+)/, detail.getUser, detail.indexSkn); // 秒杀详情页 SKN 进入
router.get('/seckill/get-product-list', seckill.getProductList); // 秒杀列表根据活动id获取商品列表
module.exports = router;
... ...
... ... @@ -38,7 +38,11 @@
<div class="price-date">
{{# goodsPrice}}
<div class="goods-price">
{{#if ../isSecKill/secKillPrice}}
<h1 class="current-price">{{../isSecKill/secKillPrice}}</h1>
{{else}}
<h1 class="current-price">{{currentPrice}}</h1>
{{/if}}
<h1 class="previous-price">{{previousPrice}}</h1>
</div>
{{/ goodsPrice}}
... ... @@ -63,6 +67,24 @@
<h1 >{{periodOfMarket}}</h1>
</div>
{{/if}}
{{#isSecKill}}
{{#if startIng}}
<div class="seckill-time seckill-time-border">
<span>距结束 </span>
<span class="end-time">
<i class="tick hour">00</i>:
<i class="tick minute">00</i>:
<i class="tick second">00</i>
</span>
</div>
{{/if}}
{{#if notStart}}
<div class="seckill-time notStart">
<span class="seckill-time-pic">秒杀预告</span>
<span class="seckill-time-c">月日</span>
</div>
{{/if}}
{{/isSecKill}}
</div>
{{#if studentPrice}}
... ... @@ -158,40 +180,61 @@
<div id="productDesc" {{#if limit}}class="limit"{{/if}}> </div>
{{> detail/recommend-for-you}}
{{> cart/chose-panel}}
{{# isSecKill}}
{{# notStart}}
<div class="seckill-count">
<div class="seckill-count-bg"></div>
<div class="seckill-count-num">距秒杀开始:
<i class="tick hour">00</i>
<i class="tick minute">00</i>
<i class="tick second">00</i>
</div>
</div>
{{/notStart}}
{{/isSecKill}}
{{#cartInfo}}
<div class="cart-bar">
<a href="{{cartUrl}}" class="num-incart iconfont"><span class="num-tag hide"></span>&#xe62c;</a>
{{#if ../isSecKill/noneLeft}}
<a href="javascript:;" class="sold-out">已售罄</a>
{{else if ../isSecKill/startIng}}
<a href="javascript:;" id="addtoCart" class="addto-cart">立即购买</a>
{{else if ../isSecKill/notStart}}
<a href="javascript:;" class="sold-out">即将开抢</a>
{{else}}
{{#if addToCartUrl}}
<a id="addtoCart" href="javascript:;" class="addto-cart">{{#if ../tickets}}立即购买{{else}}加入购物车{{/if}}</a>
{{/if}}
{{#if addToCartUrl}}
<a id="addtoCart" href="javascript:;" class="addto-cart">{{#if ../tickets}}立即购买{{else}}加入购物车{{/if}}</a>
{{/if}}
{{#if soldOut}}
<a href="javascript:;" class="sold-out">已售罄</a>
{{/if}}
{{#if soldOut}}
<a href="javascript:;" class="sold-out">已售罄</a>
{{/if}}
{{#if notForSale}}
<a href="javascript:;" class="sold-out">非卖品</a>
{{/if}}
{{#if notForSale}}
<a href="javascript:;" class="sold-out">非卖品</a>
{{/if}}
{{#if limitNotForSale}}
<a href="javascript:;" class="sold-out limit">即将发售</a>
{{/if}}
{{#if limitNotForSale}}
<a href="javascript:;" class="sold-out limit">即将发售</a>
{{/if}}
{{#if canBuyLimit}}
<a href="javascript:;" id="addtoCart" class="addto-cart">立即购买</a>
{{/if}}
{{#if canBuyLimit}}
<a href="javascript:;" id="addtoCart" class="addto-cart">立即购买</a>
{{/if}}
{{#if noLimitCode}}
<a href="javascript:;" class="sold-out limit">立即购买</a>
{{/if}}
{{#if noLimitCode}}
<a href="javascript:;" class="sold-out limit">立即购买</a>
{{/if}}
<input type="hidden" id="limitCodeUrl" name="limitCodeUrl" value="{{limitCodeUrl}}">
<input type="hidden" id="limitProductPay" name="limitProductPay" value="{{limitProductPay}}">
{{#limitProductCode}}
<input type="hidden" id="limitProductCode" name="limitProductCode" value="{{.}}">
{{/limitProductCode}}
<input type="hidden" id="limitCodeUrl" name="limitCodeUrl" value="{{limitCodeUrl}}">
<input type="hidden" id="limitProductPay" name="limitProductPay" value="{{limitProductPay}}">
{{#limitProductCode}}
<input type="hidden" id="limitProductCode" name="limitProductCode" value="{{.}}">
{{/limitProductCode}}
{{/if}}
<a href="javascript:;" id="likeBtn" class="favorite iconfont {{#isCollect}}liked{{/isCollect}}">&#xe605;</a>
</div>
{{/cartInfo}}
... ... @@ -223,4 +266,7 @@
{{/if}}
</div>
{{# isSecKill}}
<input type="hidden" class="productSkn-text" value={{productSkn}} />
{{/isSecKill}}
{{/ result}}
... ...
<div class="seckill-list">
{{> seckill/nav}}
<div class="product-list">
{{# products}}
{{> seckill/product}}
{{/products}}
</div>
<section class="tips">
<h5>秒杀活动说明</h5>
<ol>
<li>秒杀商品限活动开始后,在详情页抢购,提前加入购物车无效</li>
<li>秒杀数量有限,抢完即止</li>
<li>活动最终解释权归YOHO!BUY有货所有</li>
</ol>
</section>
</div>
... ...
{{# products}}
{{> seckill/product}}
{{/products}}
\ No newline at end of file
... ...
<nav class="nav-list">
<ul class="nav-ul hide">
{{# activitys}}
<li class="time-item {{# if @last}}last{{/if}} {{# if focus}}focus{{/if}} {{statusClass this}}">
<input type="hidden" name="" class="date" value="{{startTime}}">
<input type="hidden" name="" class="activityId" value="{{activityId}}">
<div class="normal">
<p class="time">{{time}}</p>
<p class="status tip-over">已开抢</p>
<p class="status tip-now">抢购中</p>
<p class="status tip-wait">即将开抢</p>
</div>
<div class="selected">
<p class="time">
<span>{{time}}</span>
<span class="status tip-over">已开抢</span>
<span class="status tip-now">抢购中</span>
<span class="status tip-wait">即将开抢</span>
</p>
<div class="status info-over">
<p>还有商品可以继续抢购</p>
</div>
<div class="status info-now">
<div class="last-info">
<p class="status tip-over">已开抢</p>
<p class="status tip-now">抢购中</p>
<p class="status tip-wait">即将开抢</p>
</div>
<div class="last-count-down">
<p class="countdown">剩余:<i class="tick hour">00</i><i class="tick minute">00</i><i class="tick second">00</i></p>
</div>
</div>
<div class="status info-wait">
<p class="countdown">距开抢:<i class="tick hour">00</i><i class="tick minute">00</i><i class="tick second">00</i></p>
</div>
</div>
</li>
{{/activitys}}
</ul>
</nav>
\ No newline at end of file
... ...
<div class="item" data-activity="{{activityId}}" data-skn="{{productSkn}}">
<div class="item-img">
<img src="{{image defaultImages 235 314}}" alt="">
</div>
<div class="item-info">
<div class="item-title">
{{productName}}
</div>
{{# if wait}}
<div class="item-price">
<ins>¥{{secKillPrice}}</ins><del>¥{{marketPrice}}</del>
</div>
{{/if}}
<div class="item-foot">
{{# if wait}}
<div class="item-time" data-start="{{startTime}}"><span><i class="iconfont">&#xe603;</i><time>{{readaleTime startTime}}</time>开始</span></div>
{{else}}
<div class="item-price">
<ins>¥{{secKillPrice}}</ins><del>¥{{marketPrice}}</del>
</div>
{{/if}}
<div class="item-button">
{{#if over}}
<span class="old-price">还可以原价购买</span>
<a href='/product/show_{{{productSkn}}}{{#if isApp}}?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"{{productSkn}}"}}{{/if}}' class="btn btn-over">已抢光</a>
{{else if wait}}
{{#if @root.isApp}}
<button class="btn btn-remind-off" data-remind data-action="cancel" {{#unless remindFlag}}style="display: none;"{{/unless}}>取消提醒</button>
<button class="btn btn-remind-on" data-remind data-action="add" {{#if remindFlag}}style="display: none;"{{/if}}>提醒我</button>
{{else}}
<a href='/product/seckill/detail/show_{{productSkn}}.html' class="btn btn-buy">即将开抢</a>
{{/if}}
{{else}}
<a href='/product/seckill/detail/show_{{productSkn}}.html?{{#if isApp}}?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"{{productSkn}}"}}{{/if}}' class="btn btn-buy">去抢购</a>
{{/if}}
</div>
</div>
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -16,10 +16,11 @@ module.exports = {
siteUrl: '//m.yohobuy.com',
assetUrl: '//localhost:5001',
domains: {
api: 'http://dev-api.yohops.com:9999/',
service: 'http://service-test1.yohops.com:9999/',
liveApi: 'http://testapi.live.yohops.com:9999/',
singleApi: 'http://api-test1.yohops.com:9999/'
// service: 'http://devservice.yoho.cn:58077/'
// api: 'http://dev-api.yohops.com:9999/',
api: 'http://api.yoho.cn/',
service: 'http://dev-service.yohops.com:9999/',
liveApi: 'http://testapi.live.yohops.com:9999/'
},
subDomains: {
host: '.m.yohobuy.com',
... ...
... ... @@ -17,6 +17,7 @@ module.exports = app => {
app.use('/product', require('./apps/product'));
app.use('/guang', require('./apps/guang'));
app.use('/activity', require('./apps/activity'));
app.use('/cart', require('./apps/cart'));
// 分期付款
app.use('/home', require('./apps/home'));
... ...
... ... @@ -8,6 +8,7 @@
const helpers = global.yoho.helpers;
module.exports = (req, res, next) => {
console.log('....');
if (!req.user.uid) {
if (req.xhr) {
return res.json({
... ...
... ... @@ -38,7 +38,7 @@
{{> updata}}
{{/if}}
{{#unless isApp}}
{{> header}}
{{> header}}
{{/unless}}
{{{body}}}
{{> footer}}
... ...
... ... @@ -9,11 +9,28 @@
<div class="text-info">
<p class="name">{{name}}</p>
<p class="price">
<span class="sale-price{{^price}} no-price{{/price}}">{{salePrice}}</span>
{{#if price}}
<span class="market-price">{{price}}</span>
{{#if ../isSecKill/startIng}}
<span class="sale-price">{{../isSecKill/secKillPrice}}</span>
{{#if price}}
<span class="market-price">{{price}}</span>
{{/if}}
{{else}}
<span class="sale-price{{^price}} no-price{{/price}}">{{salePrice}}</span>
{{#if price}}
<span class="market-price">{{price}}</span>
{{/if}}
{{/if}}
</p>
{{#if ../isSecKill/startIng}}
<div class="seckill-time seckill-time-border seckill-chose">
<span>距结束 </span>
<span class="end-time">
<i class="tick hour">00</i>:
<i class="tick minute">00</i>:
<i class="tick second">00</i>
</span>
</div>
{{/if}}
</div>
</div>
<div class="chose-items">
... ... @@ -45,15 +62,26 @@
<div class="num">
<span>数量</span>
<div class="clearfix">
<a class="btn btn-minus" href="javascript:void(0);">
<span class="iconfont {{#if promotionId}}disabled{{/if}}">&#xe625;</span>
</a>
<input id="good-num" class="good-num disabled" type="text" value="1" disabled="true">
<a class="btn btn-plus" href="javascript:void(0);">
<span class="iconfont {{#if promotionId}}disabled{{/if}}">&#xe624;</span>
</a>
{{#if ../isSecKill/startIng}}
<a class="btn" href="javascript:void(0);">
<span class="iconfont {{#if promotionId}}disabled{{/if}}">&#xe625;</span>
</a>
<input id="good-num" class="good-num disabled" type="text" value="1" disabled="true">
<a class="btn" href="javascript:void(0);">
<span class="iconfont {{#if promotionId}}disabled{{/if}}">&#xe624;</span>
</a>
<span class="limit-num-text">限购1件</span>
{{else}}
<a class="btn btn-minus" href="javascript:void(0);">
<span class="iconfont {{#if promotionId}}disabled{{/if}}">&#xe625;</span>
</a>
<input id="good-num" class="good-num disabled" type="text" value="1" disabled="true">
<a class="btn btn-plus" href="javascript:void(0);">
<span class="iconfont {{#if promotionId}}disabled{{/if}}">&#xe624;</span>
</a>
{{/if}}
</div>
<span class="left-num"></span>
<span class="left-num {{#if ../isSecKill}}hide{{/if}}"></span>
<input id="left-num" type="hidden" value="0">
<input id="limitNum" type="hidden" value="{{limit}}">
</div>
... ... @@ -61,7 +89,20 @@
</div>
</div>
<div class="btn-wrap">
<button id="chose-btn-sure" class="btn btn-sure">{{#if ../tickets}}立即购买{{else}}加入购物车{{/if}}</button>
{{#if ../isSecKill/startIng}}
<button id="chose-btn-sure" class="btn btn-sure go-pay isSecKill">
立即抢购
</button>
{{else}}
<button id="chose-btn-sure" class="btn btn-sure go-pay">
{{#if ../tickets}}
立即购买
{{else}}
加入购物车
{{/if}}
</button>
{{/if}}
</div>
</div>
</div>
... ...
<div class="order-good" data-id="{{id}}">
<div class="thumb-wrap">
{{#if link}}
<a href="{{link}}"><img class="thumb lazy" data-original="{{thumb}}"></a>
{{else}}
<img class="thumb lazy" data-original="{{thumb}}">
{{/if}}
<p class="tag{{#if gift}} gift-tag{{/if}}{{#if advanceBuy}} advance-buy-tag{{/if}}"></p>
</div>
<div class="deps">
<p class="name row">{{name}}</p>
<p class="row">
{{#if color}}
<span class="color">
{{#if tickets}}日期{{else}}颜色{{/if}}:{{color}}
</span>
{{/if}}
{{#if size}}
<span class="size">
{{#if tickets}}区域{{else}}尺码{{/if}}:{{size}}
</span>
{{/if}}
</p>
{{#if isLimitSkn}}
<p class="limit">不支持7天无理由退换货</p>
{{/if}}
<p class="row price-wrap">
<span class="price">
¥{{price}}
</span>
<span class="count">
×{{count}}
</span>
{{#if appearDate}}
<span class="appear-date">上市期:{{appearDate}}</span>
{{/if}}
</p>
</div>
</div>
\ No newline at end of file
... ...
<section class="block more-jit">
<a href="{{jitDetailUrl}}">
<div class="more-jit">
<span>商品需要分仓调拨</span>
<span class="iconfont icon-right-arrow">&#xe614;</span>
</div>
</a>
</section>
... ...
<div class="order" data-id="{{orderNum}}" data-href="{{detailUrl}}">
<header class="header">
订单编号:{{orderNum}}
<span class="order-status">{{orderStatus}}</span>
</header>
<section class="order-goods">
{{# goods}}
{{> me/order/good}}
{{/ goods}}
</section>
<footer class="footer">
{{count}}件商品 实付<span class="sum-cost">¥{{sumCost}}</span>
{{#shippingCost}}(含运费¥{{.}}){{/shippingCost}}
</footer>
{{!-- 对应订单状态的操作逻辑 --}}
{{!-- 完成和取消订单显示删除按钮 --}}
{{#unless unpaid}}
<div class="order-opt">
{{#unless unreceived}}
<span class="btn del">删除订单</span>
{{#if isVirtual}}
<!--虚拟商品-->
{{else}}
<span class="btn rebuy">再次购买</span>
{{/if}}
{{/unless}}
{{#if qrcode}}
<a class="locHref" href="{{qrcode}}">
<span class="btn check-logistics">查看二维码</span>
</a>
{{/if}}
</div>
{{/unless}}
{{#if unpaid}}
<div class="order-opt">
<ul class="count-down hide">
<li>
<span class="iconfont count-down-icon">&#xe64a;</span>
</li>
<li>
<span class="hours">{{leftTime}}</span>
</li>
</ul>
<span class="btn cancel">取消订单</span>
{{#if payUrl}}
<a class="locHref" href="{{payUrl}}">
<span class="btn pay">立即付款</span>
</a>
{{/if}}
</div>
{{/if}}
{{!-- 包含未发货和已发货状态,未发货不传logisticsUrl --}}
{{#if unreceived}}
{{#if logisticsUrl}}
<div class="order-opt">
<a class="locHref" href="{{logisticsUrl}}">
<span class="btn check-logistics">查看物流</span>
</a>
</div>
{{/if}}
{{/if}}
</div>
\ No newline at end of file
... ...
{{#if walkwayUrl}}
<div class="no-order">
<div class="icon"></div>
<span>你还没有订单!</span>
<a class="walk-way" href="{{walkwayUrl}}">随便逛逛</a>
</div>
{{^}}
{{#each orders}}
{{> me/order/order}}
{{/each}}
{{/if}}
\ No newline at end of file
... ...
{{#data}}
{{> common/floor-header-more}}
<div class="seckill">
<div class="seckill-times">
<ul>
<li class="time-item">
<div class="normal">
<p class="time">12:00</p>
<p>已开抢</p>
</div>
<div class="selected">
<p class="time"><span>12:00</span>已开抢</p>
<p>还有商品可以继续抢购哦!</p>
</div>
</li>
<li class="time-item foucs">
<div class="normal">
<p class="time">15:00</p>
<p>抢购中</p>
</div>
<div class="selected">
<p class="time"><span>15:00</span>抢购中</p>
<p>剩余:<i class="hour">02</i><i class="minute">02</i><i class="second">02</i></p>
</div>
</li>
<li class="time-item">
<div class="normal">
<p class="time">15:00</p>
<p>即将开抢</p>
</div>
<div class="selected">
<p class="time"><span>15:00</span>即将开抢</p>
<p>距开抢:<i class="hour">02</i><i class="minute">02</i><i class="second">02</i></p>
</div>
</li>
</ul>
</div>
<div class="seckill-products">
</div>
</div>
{{/data}}
\ No newline at end of file
... ...
... ... @@ -44,6 +44,7 @@
"uuid": "^2.0.3",
"winston": "^2.2.0",
"winston-daily-rotate-file": "^1.3.0",
"yoho-cookie": "^1.2.0",
"yoho-node-lib": "0.0.49"
},
"devDependencies": {
... ...
... ... @@ -58,6 +58,8 @@ var limitProductCode,
// 限购商品的skn。只有限购商品时才会设置。
skn;
var isSecKills = $('.isSecKill').length;// 秒杀标记
// 禁用数字编辑
function disableNumEdit() {
var $numBtn = $('.chose-panel').find('.num .btn>.iconfont');
... ... @@ -203,15 +205,30 @@ function hide() {
}
// 修改加入购物车的文字和背景
var isSeckill = $('.limit-num-text').length;
function updateConformButtonClassAndText() {
$chosed = $allChoseItems.find('.chosed');
if ($chosed.closest('.zero-stock').length === 2) {
$('#chose-btn-sure').css('background-color', '#c0c0c0').html('已售罄');
} else if (limitProductCode || ticketsLimit) {
$('#chose-btn-sure').css('background-color', '#eb0313').html('立即购买');
if (isSeckill > 0) {
$chosed = $allChoseItems.find('.chosed');
if ($chosed.closest('.zero-stock').length === 2) {
$('#chose-btn-sure').css('background-color', '#c0c0c0').html('已售罄');
} else if (limitProductCode || ticketsLimit) {
$('#chose-btn-sure').css('background-color', '#eb0313').html('立即购买');
} else {
$('#chose-btn-sure').css('background-color', '#eb0313').html(isEdit ? '确认' : '立即结算');
}
} else {
$('#chose-btn-sure').css('background-color', '#eb0313').html(isEdit ? '确认' : '加入购物车');
$chosed = $allChoseItems.find('.chosed');
if ($chosed.closest('.zero-stock').length === 2) {
$('#chose-btn-sure').css('background-color', '#c0c0c0').html('已售罄');
} else if (limitProductCode || ticketsLimit) {
$('#chose-btn-sure').css('background-color', '#eb0313').html('立即购买');
} else {
$('#chose-btn-sure').css('background-color', '#eb0313').html(isEdit ? '确认' : '加入购物车');
}
}
}
// 显示剩余件数
... ... @@ -549,8 +566,9 @@ $yohoPage.on('touchstart', '.btn-minus', function() {
if (!ticketsLimit) {
confirming = true;
}
loading.showLoadingMask();
if (!isSecKills) {
loading.showLoadingMask();
}
// 立即购买门票
if (ticketsLimit) {
... ... @@ -578,7 +596,10 @@ $yohoPage.on('touchstart', '.btn-minus', function() {
productSku + '&skn=' + skn + '&buy_number=' + buyNumber;
removePannel();
loading.showLoadingMask();
if (!isSecKills) {
loading.showLoadingMask();
}
// 调用接口判断商品是否可以购买
$.ajax({
... ... @@ -615,47 +636,63 @@ $yohoPage.on('touchstart', '.btn-minus', function() {
url = '/cart/index/add';
}
$.ajax({
method: 'POST',
url: url,
data: cartGoodData
}).done(function(res) {
var cartNum;
loading.hideLoadingMask();
if (res.code === 200 && !isEdit) {
cartNum = res.data.goods_count;
if (cartNum > 99) {
cartNum = '99+';
if (!isSecKills) {
$.ajax({
method: 'POST',
url: url,
data: cartGoodData
}).done(function(res) {
var cartNum;
loading.hideLoadingMask();
if (res.code === 200 && !isEdit) {
cartNum = res.data.goods_count;
if (cartNum > 99) {
cartNum = '99+';
}
$('.num-tag').html(cartNum).removeClass('hide');
confirming = false;
if (cbFn) {
cbFn();
}
}
$('.num-tag').html(cartNum).removeClass('hide');
confirming = false;
if (res.message && !isEdit) {
tip.show(res.message);
}
hide();
if (isEdit) {
loading.showLoadingMask();
// 延迟刷新,否则面板可能无法隐藏
setTimeout(function() {
if (cbFn) {
cbFn();
// 获取当前页面商品类型:普通商品/预售商品
window.location.href = '/cart/index/index?cartType=' + $('#cartType').val();
}, 1);
}
}
if (res.message && !isEdit) {
tip.show(res.message);
}
}).fail(function() {
tip.show('网络出了点问题~');
}).always(function() {
confirming = false;
});
hide();
} else {
if (isEdit) {
loading.showLoadingMask();
$('#chose-btn-sure').click(
function() {
var thisSkn = $('#productSkn').val();
var thisSku = '';
// 延迟刷新,否则面板可能无法隐藏
setTimeout(function() {
thisSku = $('.size-row:last').find('.chosed').attr('data-skuid');
window.location.href = '/cart/seckill?skn=' + thisSkn + '&sku=' + thisSku;
}
);
}
// 获取当前页面商品类型:普通商品/预售商品
window.location.href = '/cart/index/index?cartType=' + $('#cartType').val();
}, 1);
}
}).fail(function() {
tip.show('网络出了点问题~');
}).always(function() {
confirming = false;
});
}
});
... ...
/**
* 订单信息读取
* @author: bikai<kai.bi@yoho.cn>
* @date: 2015/12/14
*/
require('../common');
var info = window.cookie('order-info');
function init() {
info = {
uid: window.getUid(),
deliveryId: $('.dispatch-mode .chosed').data('id') || 1,
deliveryTimeId: 1,
paymentTypeId: 1,
yohoCoin: 0,
addressId: null,
couponCode: null,
couponName: null,
invoice: null,
invoiceText: null,
invoiceType: null,
invoiceTitle: null,
receiverMobile: null,
isModifyTel: false,
invoicesType: null,
msg: null,
cartType: 'ordinary'
};
window.setCookie('order-info', JSON.stringify(info));
}
// info 必须是 JSON 字符串
try {
info = JSON.parse(info);
// 2015/12/31 hf: fixes bug to 购物车页面调用该JS, 会导致有有货币,值却没有传给服务端. 因此需要再设置一下
// info['yohoCoin'] = $('.coin').data('yoho-coin') || 0;
} catch (e) {
init();
}
exports.init = init;
exports.orderInfo = function(key, value) {
if (value === undefined) {
return info[key];
}
info[key] = value;
window.setCookie('order-info', JSON.stringify(info));
};
... ...
'use strict';
require('./seckill/order-ensure');
... ...
/* eslint-disable vars-on-top */
/**
* 订单确认
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/11/12
*/
require('common.js');
var lazyLoad = require('yoho-jquery-lazyload'),
tip = require('plugin/tip'),
loading = require('plugin/loading'),
order = require('../order-info');
var $invoice = $('.invoice'),
$couponUse = $('.coupon-use.used'),
$addressWrap = $('.address-wrap'),
$coinCheck = $('.coin-check'),
$coinUsed = $('.coin .used'),
$subBlock = $('.sub-block'),
$ticketsMobile = $('#mobile'),
payType,
queryString = $.queryString(),
orderInfo = order.orderInfo,
isSubmiting,
dispatchInfo,
total,
activityId = $('#activity-id').val(),
productSku = $('#product-sku').val();
var orderCont = window.cookie('order-info') && JSON.parse(window.cookie('order-info'));
var invoiceCont = {
7: '服装',
1: '图书',
9: '配件',
11: '日用品',
3: '办公用品',
6: '体育用品',
10: '数码产品'
},
invoicesType = {
1: '纸质',
2: '电子'
};
lazyLoad();
// 初始化发票信息
function invoiceInit() {
if (orderCont.invoiceType) {
$('.invoice-type').text(invoiceCont[orderCont.invoiceType] + '(' + invoicesType[orderCont.invoicesType] + ')');
} else {
$('.invoice-type').text('服装(电子)');
// $('.invoice-type').text('服装(纸质)');
}
}
function getQueryParam() {
var queryArray = location.search.substr(1).split('&'),
i,
subArr = [],
obj = {};
for (i = 0; i < queryArray.length; i++) {
subArr = queryArray[i].split('=');
obj[subArr[0]] = subArr[1];
subArr = [];
}
return obj;
}
function isLimitGood() {
return getQueryParam().limitproductcode;
}
if (window.getUid() !== orderInfo('uid')) {
order.init();
window.location.reload();
}
if ($couponUse.data('name') !== orderInfo('couponName')) {
orderInfo('couponCode', null);
orderInfo('couponName', null);
}
// 来自购物车的链接默认不使用优惠券
if (document.referrer && document.referrer.indexOf('/cart/index/index') !== -1) {
orderInfo('couponCode', null);
orderInfo('couponName', null);
}
isLimitGood() && (function() {
var a = [];
var data = getQueryParam();
data.type = 'limitcode';
a.push(data);
orderInfo('skuList', JSON.stringify(a));
orderInfo('limitUrlSufix', location.search);
})();
if (queryString.cartType || queryString.carttype || !orderInfo('cartType')) {
orderInfo('cartType', queryString.cartType || queryString.carttype || 'ordinary');
}
// function dispacthTapEvt(e) {
// var $cur = $(e.target).closest('li');
// if ($cur.length === 0 || $cur.hasClass('chosed')) {
// return;
// }
// $cur.siblings('li.chosed').removeClass('chosed');
// $cur.addClass('chosed');
// }
$('.checkbox').on('touchstart', function() {
var $this = $(this);
if ($this.hasClass('icon-cb-radio')) {
$this.removeClass('icon-cb-radio').addClass('icon-radio');
return;
}
if ($this.hasClass('icon-radio')) {
$this.removeClass('icon-radio').addClass('icon-cb-radio');
}
});
$invoice.on('touchend', '.checkbox', function() {
var $this = $(this);
if ($this.hasClass('icon-cb-radio')) {
$invoice.addClass('focus');
orderInfo('invoiceText', '');
orderInfo('invoiceType', '7');
orderInfo('receiverMobile', $('.user-mobile').val());
orderInfo('invoicesType', '2');
orderInfo('invoiceTitle', '个人');
}
if ($this.hasClass('icon-radio')) {
$invoice.removeClass('focus');
orderInfo('invoiceText', null);
orderInfo('invoiceType', null);
orderInfo('receiverMobile', null);
orderInfo('invoicesType', null);
orderInfo('invoiceTitle', null);
}
orderCont = window.cookie('order-info') && JSON.parse(window.cookie('order-info'));
invoiceInit();
});
function updateDeliverId(id) {
var $moreJit = $('.more-jit a').get(0),
url;
if ($moreJit) {
url = $moreJit.href;
} else {
return;
}
if (url.indexOf('deliveryId') < 0) {
$moreJit.href = url + '&deliveryId=' + id;
} else {
$moreJit.href = url.replace(/deliveryId=(\d)/, 'deliveryId=' + id);
}
}
function orderCompute() {
var yohoCoin = orderInfo('yohoCoin'),
deliverId = orderInfo('deliveryId'),
data = {
cartType: orderInfo('cartType') || 'ordinary',
deliveryId: orderInfo('deliveryId'),
paymentTypeId: orderInfo('paymentTypeId'),
yohoCoin: yohoCoin,
sku: productSku,
activityId: activityId
};
loading.showLoadingMask();
$.ajax({
method: 'POST',
url: '/cart/seckill/compute',
data: data
}).then(function(res) {
if ($.type(res) !== 'object') {
window.location.reload();
} else {
if (typeof res.last_order_amount !== undefined) {
res.last_order_amount = (+res.last_order_amount).toFixed(2);
}
if (res.use_yoho_coin) {
$coinCheck.find('em').html('- ¥ ' + res.use_yoho_coin);
$coinUsed.html('已抵¥' + res.use_yoho_coin);
$coinCheck.find('em').show();
$coinUsed.show();
}
total = '';
if (res.promotion_formula_list) {
$.each(res.promotion_formula_list, function(index, value) {
total += '<li>' +
'<p>' + value.promotion + '</p>' +
'<span>' + value.promotion_amount + '</span>' +
'</li>';
});
$('.price-cost span').html('¥' + res.last_order_amount);
$('.bill span').html('¥' + res.last_order_amount);
$('.total').html(total);
}
updateDeliverId(deliverId);
}
}).fail(function() {
window.location.reload();
}).always(function() {
loading.hideLoadingMask();
});
}
function submitOrder() {
var invoiceText = $invoice.find('[name="invoice-title"]').val() || orderInfo('invoiceText'),
msg = $('#msg').find('input').val() || orderInfo('msg');
if (isSubmiting) {
return false;
}
// if (orderInfo('invoice')) {
// if (!invoiceText) {
// tip.show('请输入发票抬头');
// return;
// }
// if (invoiceText.length > 30) {
// tip.show('发票抬头不得超过30个汉字');
// return;
// }
// }
if (msg) {
if (msg.length > 40) {
tip.show('留言不得超过40个汉字');
return;
}
}
loading.showLoadingMask();
isSubmiting = true;
$.ajax({
method: 'POST',
url: '/cart/seckill/submit',
data: {
activityId: activityId,
sku: productSku,
addressId: orderInfo('addressId'),
cartType: orderInfo('cartType') || 'ordinary',
deliveryWay: orderInfo('deliveryId'),
deliveryTime: orderInfo('deliveryTimeId'),
invoiceTitle: orderInfo('invoice') ? invoiceText : null,
invoiceTypeId: orderInfo('invoice') ? ($invoice.find('.invoice-type').val() ||
orderInfo('invoiceType')) : null,
remark: msg,
paymentId: orderInfo('paymentTypeId'),
paymentType: orderInfo('paymentType'), // 支付方式
useYohoCoin: orderInfo('yohoCoin')
}
}).then(function(res) {
var url;
if (!res) {
tip.show('系统繁忙,请稍后再试!');
return;
}
if (res.code === 200) {
if (payType === 2) {
// 货到付款的进入订单页面
url = '/home/orderDetail?order_code=' + res.data.order_code;
} else {
url = '/home/orders/pay?order_code=' + res.data.order_code;
}
window.setCookie('order-info', '');
window.location.href = url;
} else if (res.message) {
tip.show(res.message);
}
}).fail(function() {
tip.show('系统繁忙,请稍后再试!');
}).always(function() {
isSubmiting = false;
loading.hideLoadingMask();
});
}
// 界面点击,状态存 cookie
if (!orderInfo('addressId')) {
orderInfo('addressId', $addressWrap.data('id'));
}
// 配送方式 发生改变
$('.delivery-id').on('touchend', 'li', function() {
orderInfo('deliveryId', $(this).data('id'));
orderCompute();
});
$('.payment-type').on('touchend', 'li', function() {
orderInfo('paymentType', $('.icon-cb-radio', this).data('id'));
});
$('.dispatch-time').on('touchend', 'li', function() {
orderInfo('deliveryTimeId', $(this).data('id'));
});
$('.coin').on('touchend', function() {
var $this = $(this);
if ($this.find('.checkbox').hasClass('icon-cb-radio')) {
orderInfo('yohoCoin', $this.data('yoho-coin'));
$this.find('.can-use').hide();
} else {
orderInfo('yohoCoin', 0);
$this.find('.coin-check em').hide();
$this.find('.can-use').show();
$this.find('.used').hide();
}
orderCompute();
});
$invoice.on('touchend', '.checkbox', function(e) {
var $this = $(this);
orderInfo('invoice', $this.hasClass('icon-cb-radio'));
e.preventDefault();
e.stopPropagation();
});
$invoice.find('[name="invoice-title"]').on('blur', function() {
orderInfo('invoiceText', $(this).val());
}).end().find('.invoice-type').on('change', function() {
orderInfo('invoiceType', $(this).val());
});
$('#msg').find('textarea').on('blur', function() {
orderInfo('msg', $(this).val());
});
$('.pay-mode').on('click', 'li', function() {
var $this = $(this);
orderInfo('paymentTypeId', $this.data('pay-id'));
orderInfo('paymentType', $this.data('pay-type'));
payType = $this.data('pay-type');
});
$('form').on('submit', function() {
return false;
});
// xwg 2016/3/21 13:22
$('.dispatch').on('touchend', 'h3', function() {
if ($(this).siblings('ul').is(':hidden')) {
$('.dispatch h3').removeClass('border-none');
$(this).addClass('border-none');
$('.down').removeClass('hide');
$('.up').addClass('hide');
$('.up', this).removeClass('hide');
$('.down', this).addClass('hide');
$('.dispatch ul').hide();
$(this).siblings('ul').show();
} else {
$(this).removeClass('border-none');
$('.down', this).removeClass('hide');
$('.up', this).addClass('hide');
$(this).siblings('ul').hide();
}
});
$subBlock.on('touchstart', 'li', function() {
$.each($(this).parents('ul').find('i'), function() {
$(this).parents('ul').find('i').removeClass('icon-cb-radio').addClass('icon-radio');
});
$(this).parents('ul').hide();
$('.down').removeClass('hide');
$('.up').addClass('hide');
$('.dispatch h3').removeClass('border-none');
dispatchInfo = $(this).find('span').html();
$(this).parents('.sub-block').find('h3 span').html(dispatchInfo);
if ($(this).find('i').hasClass('icon-cb-radio')) {
$(this).find('i').addClass('icon-radio');
} else if ($(this).find('i').hasClass('icon-radio')) {
$(this).find('i').addClass('icon-cb-radio');
}
});
$('.bill a').on('touchstart', function() {
orderInfo('paymentTypeId', $('.delivery-id .icon-cb-radio').data('id'));
orderInfo('paymentType', $('.payment-type .icon-cb-radio').data('id'));
payType = $('.payment-type .icon-cb-radio').data('id');
submitOrder();
});
function phoneHidden(phone) {
phone = phone || '';
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
$('.info-phone').html(phoneHidden($('.info-phone').html()));
if (orderInfo('address') && orderInfo('address').is_support === 'N') {
orderInfo('deliveryId', $('.delivery-id .icon-cb-radio').data('id'));
orderCompute();
}
// 校验手机号
$ticketsMobile.blur(function function_name(e) {
var reg = /^[0123456789]{1,30}$/;
var mobile = $ticketsMobile.val();
if (!reg.test(mobile)) {
tip.show('手机号码不正确!');
}
});
// 初始化发票信息内容
invoiceInit();
... ...
... ... @@ -23,6 +23,8 @@ var dialog = require('../plugin/dialog');
require('../common');
require('./tick');
// add extra marign-bottom for footer to show the yoho copyright
function showFooter() {
var $cartBar = $('.cart-bar');
... ...
/**
* [秒抢页面js]
* author: 陈峰<feng.chen@yoho.cn>
* date: 2016/09/08
*/
require('common.js');
var yoho = require('../yoho-app');
var $ = require('yoho-jquery'),
IScroll = require('yoho-iscroll'),
loading = require('plugin/loading'),
tip = require('plugin/tip');
var seckillObj = {};
seckillObj = {
$productList: null, // DOMContentLoaded的时候 赋值,即init
el: {
// doms
$navUl: $('.nav-ul'),
$navList: $('.nav-list'),
// 变量
times: $('.nav-ul>li').length,
startX: 0,
timeWidth: 0,
focusTimeWidth: 0,
iScroll: null,
currentTick: null
},
/**
* [初始化界面]
*/
init: function() {
var $el = this.el, that = this;
var focus = $el.$navUl.find('>li.focus');
this.$productList = $('.product-list');
$el.$navUl.find('>li').click(function() {
that.selectTime(this);
});
$(window).resize(function() {
that.initNav();
});
that.initNav();
if (focus.length && (focus.hasClass('now') || focus.hasClass('wait'))) {
that.initTick($el.$navUl.find('>li.focus'));
}
this.bindEvents();
},
/**
* [初始化时间段]
*/
initNav: function() {
var $el = this.el, that = this;
$el.timeWidth = ($el.$navUl.find('>li:not(.focus)').width() + 1);
$el.focusTimeWidth = ($el.$navUl.find('>li.focus').width() + 1);
$el.$navUl.width($el.times * $el.timeWidth + $el.focusTimeWidth).removeClass('hide');
// 只有时间段大于3个才需要定位
if ($el.$navUl.find('>li').length > 3 && $el.$navUl.find('>li.focus').length) {
$el.startX = (0 - ($el.$navUl.find('>li.focus').index() - 1) * $el.timeWidth);
}
if ($el.iScroll) {
$el.iScroll.destroy();
}
$el.iScroll = new IScroll($el.$navList[0], {
scrollX: true,
scrollY: false,
startX: $el.startX,
tap: true,
eventPassthrough: true,
preventDefault: true,
bounceTime: 400,
bounceEasing: {
style: 'cubic-bezier(0.333333, 0.666667, 0.666667, 1)'
}
});
that.registerScrollEvents($el.iScroll);
},
/**
* [注册iscroll事件,滑动停止时判断位置自动选中居中时间段]
*/
registerScrollEvents: function(iScroll) {
var $el = this.el, that = this;
iScroll.on('scrollStart', function() {
$el.$navList.addClass('srolling');
});
iScroll.on('scrollEnd', function() {
var offsetLeft = 0;
var i = 0;
// 避免死循环
if ($el.$navList.hasClass('srolling')) {
$el.$navList.removeClass('srolling');
offsetLeft = this.x - $(window).width() / 2;
for (; i < $el.$navUl.find('>li').length; i++) {
offsetLeft += $el.$navUl.find('>li').eq(i).width();
if (offsetLeft >= 0) { // 判断选中时间段
that.selectTime($el.$navUl.find('>li').eq(i));
break;
}
}
}
});
},
/**
* [选中时间段]
*/
selectTime: function(elem) {
var $el = this.el, that = this;
var index = 0;
$el.$navUl.find('>li').removeClass('focus');
index = $(elem).index();
$(elem).addClass('focus');
// 点击切换时遇到首尾特殊处理选中时间段位置,大于3个才需要滑动选中
if ($el.$navUl.find('>li').length > 3) {
if (index === 0) {
$el.iScroll.scrollTo(0, 0, 400);
} else if (index === $el.$navUl.find('>li').length - 1) {
$el.iScroll.scrollTo(0 - $el.$navUl.width() + $el.timeWidth * 2 + $el.focusTimeWidth, 0, 400);
} else {
$el.iScroll.scrollTo((0 - (index - 1) * $el.timeWidth), 0, 400);
}
}
if ($el.currentTick) {
clearTimeout($el.currentTick);
$el.currentTick = undefined;
}
if ($(elem).hasClass('now') || $(elem).hasClass('wait')) {
// 初始化倒计时并开始计时
that.initTick(elem);
}
// 刷新商品列表
that.refreshProductList($(elem).find('input.activityId').val());
},
/**
* [刷新状态]
*/
refreshList: function(elem) {
var $el = this.el, that = this, time, nowTime, nextTime;
// 刷新时间段状态
$el.$navUl.find('>li').each(function() {
$(this).removeClass('now over wait');
time = new Date($(this).find('input.date').val());
nowTime = new Date();
if (nowTime > time) { // 当前时间大于这个时间段,已经开始和即将开始两种情况
if ($(this).next('.time-item').length) {
nextTime = new Date($(this).next().find('input.date').val());
if (nowTime < nextTime) { // 下一个时间段与当前时间来区别是否正在抢购
$(this).addClass('now');
} else {
$(this).addClass('over');
}
} else { // 大于这个时间段但是后面没有秒抢时间端了,则依然显示抢购中
$(this).addClass('now');
}
} else {
$(this).addClass('wait');
}
});
// 刷新商品列表
var focusElem = $el.$navUl.find('>li.focus');
if (focusElem.length) {
that.refreshProductList(focusElem.find('input.activityId').val());
}
},
/**
* [异步加载商品列表]
*/
refreshProductList: function(activityId) {
loading.show();
$.ajax({
url: '/product/seckill/get-product-list',
data: {
uid: yoho.isLogin(), // only app use;
activityId: activityId
},
beforeSend: function(jqXhr, config) {
if (yoho.isApp) {
config.url += '&app_version=1';
}
},
success: function(data) {
$('.product-list').html(data);
},
error: function(data) {
tip.show('网络断开连接了~');
}
})
.always(function() {
loading.hide();
});
},
/**
* [初始化倒计时]
*/
initTick: function(elem) {
var $el = this.el, that = this,
time,
nowTime = Date.parse(new Date()) / 1000,
offsetTime;
if ($(elem).hasClass('now')) {
time = $(elem).next().find('input.date').val() / 1000;
} else {
time = $(elem).find('input.date').val() / 1000;
}
offsetTime = time - nowTime;
that.startTick(elem, offsetTime);
},
/**
* [开始倒计时]
*/
startTick: function(elem, offsetTime) {
var that = this,
$el = this.el,
hour = parseInt(offsetTime / (60 * 60), 10),
minute = parseInt(offsetTime % (60 * 60) / 60, 10),
second = offsetTime % 60;
if (offsetTime) {
$(elem).find('.tick.hour').text(hour < 0 ? '00' : (hour < 10 ? ('0' + hour) : hour));
$(elem).find('.tick.minute').text(minute < 0 ? '00' : (minute < 10 ? ('0' + minute) : minute));
$(elem).find('.tick.second').text(second < 0 ? '00' : (second < 10 ? ('0' + second) : second));
if (offsetTime <= 0) { // 结束倒计时刷新状态
that.refreshList(elem);
} else {
$el.currentTick = setTimeout(function() {
that.startTick(elem, --offsetTime);
}, 1000);
}
}
},
bindEvents: function() {
if (yoho.isApp) {
this.$productList.on('click', '[data-remind]', $.proxy(this.toggleRemind, this));
}
},
/*
only app
添加/删除提醒
*/
toggleRemind: function(event) {
var $remindBtn,
$product;
var actionName,
action,
params,
on_off;
var okTip,
failTip,
onsuccess;
if (!yoho.isLogin()) {
yoho.invokeMethod('go.login');
return;
}
$remindBtn = $(event.currentTarget);
$product = $remindBtn.closest('.item');
actionName = $remindBtn.data('action');
// default
on_off = true;
action = 'go.addSecKill';
params = {
skn: $product.data('skn'),
startTime: $product.find('[data-start]').data('start'),
productName: $.trim($product.find('.item-title').text())
};
okTip = '添加成功';
failTip = '添加失败';
onsuccess = $.noop;
if (actionName === 'cancel') {
on_off = false;
action = 'go.delSecKill';
okTip = '取消成功';
failTip = '取消失败';
}
onsuccess = function() {
$.post('/product/seckill/remind?app_version=1', {
on_off: on_off,
activity_id: $product.data('activity'),
product_skn: $product.data('skn'),
uid: yoho.isLogin(),
sec_kill_id: 1,
app_type: 0
})
.done(function(res) {
if (res.code === 200 && res.data === 'success') {
$remindBtn.hide().siblings().show();
tip.show(okTip);
} else {
tip.show(failTip);
}
})
.fail(function() {
tip.show(failTip);
});
};
yoho.invokeMethod(action, params, onsuccess, function() {
tip.show(failTip);
});
}
};
$(function() {
seckillObj.init();
});
... ...
/**
* [秒抢页面js]
* author: 陈峰<feng.chen@yoho.cn>
* date: 2016/09/08
*/
var $ = require('yoho-jquery'),
tip = require('../plugin/tip'),
seckillObj = {};
var timeObj = '';
var offsetTime = 0;
var nowTime = Date.parse(new Date()) / 1000;
var startTime = 0;
var endTime = 0;
var dateText = 0,
newDate = 0,
newMonth = 0,
newDay = 0,
newHour = 0,
newMinus = 0;
require('../common');
seckillObj = {
el: {
iScroll: null,
currentTick: null
},
startTick: function(elem, offsetTime) {
var that = this,
$el = this.el,
hour = parseInt(offsetTime / (60 * 60), 10),
minute = parseInt(offsetTime % (60 * 60) / 60, 10),
second = offsetTime % 60;
if (offsetTime) {
$(elem).find('.tick.hour').text(hour < 0 ? '00' : (hour < 10 ? ('0' + hour) : hour));
$(elem).find('.tick.minute').text(minute < 0 ? '00' : (minute < 10 ? ('0' + minute) : minute));
$(elem).find('.tick.second').text(second < 0 ? '00' : (second < 10 ? ('0' + second) : second));
if (offsetTime <= 0) { // 结束倒计时刷新状态
window.location.reload();
} else {
$el.currentTick = setTimeout(function() {
that.startTick(elem, --offsetTime);
}, 1000);
}
}
}
};
$(
function() {
var ajaxUrl = '/product/detail/seckillData/' + $('.productSkn-text').val();
$.ajax({
type: 'GET',
url: ajaxUrl,
success: function(data) {
startTime = data.startTime;
endTime = data.endTime;
if (startTime > nowTime) {
offsetTime = startTime - nowTime;
timeObj = $('.seckill-count-num');
} else if (nowTime > startTime && nowTime < endTime) {
offsetTime = endTime - nowTime;
timeObj = $('.end-time');
}
dateText = Number(data.startTime * 1000);
newDate = new Date(dateText);
newMonth = newDate.getMonth() + 1;
newDay = newDate.getDate();
newHour = newDate.getHours();
newMinus = newDate.getMinutes();
$('.notStart').find('.seckill-time-c').text(newMonth + '月' + newDay + '日' + newHour + ':' + newMinus);
seckillObj.startTick(timeObj, offsetTime);
},
error: function() {
tip.show('网络异常~');
}
});
}
);
... ...
... ... @@ -7,8 +7,11 @@
* 浏览器不支持的功能,给出提示,控制台不能报错,不影响后续代码执行
*
* 希望能与 微信 JS-SDK 一样方便
* http://git.yoho.cn/mobile/AppJSBridge/blob/master/AppH5Bridge.md
* http://git.yoho.cn/mobile/appbridge old、sick、ugly
*/
var tip = require('./plugin/tip');
var cookie = require('yoho-cookie');
/* 空方法 */
var emptyFn = function() { };
... ... @@ -29,6 +32,13 @@ var yoho = {
*/
data: window.yohoInterfaceData,
/**
* 判断是否是 登录
*/
isLogin: function() {
return cookie.get('_YOHOUID');
},
ready: function(callback) {
if (this.isApp) {
document.addEventListener('deviceready', callback);
... ...
.gift-advance-page {
.gift-advance-good {
position: relative;
padding: 20px 0;
margin-left: 34px;
height: 160px;
border-bottom: 1px solid #e0e0e0;
}
.advance-block:last-child .gift-advance-good:last-child {
border-bottom: 1px solid #e0e0e0;
}
.thumb-wrap {
position: relative;
float: left;
width: 120px;
height: 160px;
.thumb {
width: 100%;
height: 100%;
}
}
.tag {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 25px;
color: #fff;
text-align: center;
background: #eb76aa;
&:before {
content: '加价购';
display: block;
font-size: 12px;
line-height: 25px;
transform: scale(0.833);
}
}
.deps {
margin-left: 135px;
}
.gift-advance-good .name {
margin-bottom: 20px;
width: 440px;
font-size: 28px;
}
.row:nth-child(2) {
font-size: 22px;
height: 45px;
line-height: 45px;
> span {
margin-right: 15px;
}
}
.row:nth-child(3) {
position: relative;
}
.color, .size {
color: #b6b6b6;
}
.price {
font-size: 24px;
color: #f1545b;
&.market-price {
color: #999;
text-decoration: line-through;
}
}
.count {
font-size: 20px;
color: #999;
margin-left: 22px;
}
.chose {
position: absolute;
width: 88px;
height: 58px;
background: #f8f8f8;
border: 1px solid #ccc;
right: 20px;
top: 71px;
font-size: 26px;
line-height: 58px;
text-align: center;
}
.title {
width: 600px;
height: 60px;
line-height: 60px;
padding: 0 20px;
font-size: 24px;
background: #f8f8f8;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.gift-block .tag {
background: #a1ce4e;
&:before {
content: '赠品';
}
}
}
... ...
.shopping-cart-good {
$cartRed: #d0253b;
position: relative;
padding-left: 16px;
.prevent-img-click {
position: absolute;
width: 20px;
height: 200px;
background-color: transparent;
z-index: 99;
}
.none{
display: none;
}
.checkbox {
position: absolute;
top: 50%;
margin-top: -34px;
margin-left: 8px;
font-size: 28px;
&.icon-cb-checked {
color: #000;
}
&.disabled {
color: #f0f0f0;
}
}
.few-tag {
width: 150px;
position: absolute;
text-align: center;
top: 72%;
color: #fff;
span {
display: inline-block;
transform: scale(0.833);
}
}
.gift-tag {
background-color: #88BE51;
}
.plus-tag {
background-color: #FC1264;
}
.few-tag-expire {
position: absolute;
top: 40%;
left: 20px;
background-color: #7f7f7f;
display: inline-block;
color: #fff;
border-radius: 12px;
padding: 4px;
font-size: 20px;
width: 48px;
text-align: center;
}
.info {
float: left;
margin-left: 60px;
padding: 16px 0;
padding-right: 20px;
}
.fixed-height {
height: 2.7rem;
}
.thumb {
float: left;
width: 150px;
background-size: 100%;
background-repeat: no-repeat;
}
.deps {
position: relative;
width: 380px;
margin-left: 180px;
border-bottom: 1px solid #e0e0e0;
padding: 0.5rem 0;
}
.name {
display: inline-block;
width: 80%;
color: #5a5a5a;
font-size: 0.6rem;
line-height: 0.7rem;
}
.color-size-row > span {
margin-right: 15px;
}
.color, .size {
font-size: 0.6rem;
color: #b6b6b6;
}
.appear-date {
float: left;
color: $cartRed;
display: block;
font-size: 0.5rem;
}
.price {
font-size: 0.6rem;
color: $cartRed;
display: inline;
.sale-price{
color: #b0b0b0;
text-decoration: line-through;
}
}
.count {
font-size: 20px;
color: #999;
display: inline-block;
width: 22%;
position: absolute;
text-align: center;
}
.low-stocks {
display: inline-block;
width: 100px;
height: 30px;
line-height: 30px;
font-size: 22px;
border: none;
color: #fff;
text-align: center;
float: right;
margin-right: 16px;
padding: 4px;
border-radius: 20px;
}
.low-stocks {
background: #7f7f7f;
}
.vip {
display: inline-block;
color: #fff;
background: #e01;
border-radius: 16px;
padding: 0 12px;
margin-left: 8px;
font-size: 20px;
}
.la-tag {
margin-top: 0.3rem;
min-height: 1rem;
}
.icon-del,
.icon-edit {
position: absolute;
color: #ccc;
font-size: 30px;
}
.icon-del {
right: 20px;
}
.icon-edit {
right: 72px;
}
.opt-panel {
position: absolute;
width: 220px;
right: 0;
top: 0;
bottom: 0;
color: #fff;
> div {
float: left;
box-sizing: border-box;
width: 110px;
height: 100%;
text-align: center;
padding: 40px 20px 0;
font-size: 15px;
}
span {
display: block;
}
.put-in-favorite {
background: #bbb;
}
.del {
background: #999;
.iconfont {
margin-bottom: 20px;
}
}
}
.calculate-num{
float: right;
.calculate{
float: right;
border:1px solid #b0b0b0;
border-radius:.2rem;
p{
color: #444;
&:first-child{
height: 60px;
border-bottom:1px solid #b0b0b0;
span {
border-left:1px solid #b0b0b0;
border-right:1px solid #b0b0b0;
}
}
i{
width: 72px;
height: 60px;
float: left;
line-height: 60px;
text-align: center;
}
span{
width: 96px;
height: 60px;
float: left;
font-size: 40px;
line-height: 60px;
text-align: center;
}
&:last-child {
span{
width: 168px;
overflow: hidden;
font-size: 36px;
text-overflow:ellipsis;
white-space:nowrap;
}
}
}
}
.price{
line-height: 60px;
font-size: 46px;
font-weight: bold;
}
.count {
position: absolute;
right: 20px;;
top: 20px;;
font-size: 46px;
}
}
}
.shopping-cart-good:last-child {
.deps {
border: none;
}
}
... ...
@import "good";
@import "chose-panel";
@import "gift-advance-good";
@import "order-ensure";
@import "invoice-info";
@import "select-coupon";
@import "select-address";
@import "jit-detail";
.icon-checkbox:before { content: "\e61c"; }
.icon-cb-checked:before { content: "\e61d"; }
.icon-radio:before { content: "\e647"; }
.icon-cb-radio:before { content: "\e646"; }
.shopping-cart-page {
margin-bottom: 120px;
overflow-x: hidden;
background: #f0f0f0;
display: none;
.yoho-tip {
z-index: 4;
}
.cart-content > * {
background: #fff;
&:first-child {
border-top: none;
margin-top: 0;
}
}
.cart-nav {
color: #c6c6c6;
border-bottom: 1px solid #e0e0e0;
background: #fff;
li {
float: left;
width: 50%;
padding: 30px 0;
height: 30px;
}
li.active {
color: #000;
}
span {
display: block;
box-sizing: border-box;
width: 100%;
height: 30px;
line-height: 30px;
font-size: 30px;
text-align: center;
}
li:first-child span {
border-right: 1px solid #e0e0e0;
}
li:last-child {
position: relative;
}
.presell-tip {
position: absolute;
z-index: 1;
left: -2rem;
top: 1.75rem;
}
.triangle {
width: 0;
height: 0;
border-left: 8PX solid transparent;
border-right: 8PX solid transparent;
border-bottom: 12PX solid #000;
margin-left: 6rem;
}
.pt-content {
position: relative;
padding: 10px;
background: #000;
color: #fff;
font-size: 12px;
border-radius: 5PX;
text-align: center;
width: 7rem;
}
}
.login-info {
height: 46px;
padding: 17px 20px;
color: #24acaa;
text-align: center;
font-size: 28px;
.btn {
display: inline-block;
background: #ed0010;
color: #fff;
width: 80px;
height: 46px;
line-height: 46px;
}
}
.presell-info {
height: 60px;
padding: 15px 30px;
font-size: 22px;
background: #f0f0f0;
color: #b7b7b7;
> span {
display: block;
}
.iconfont {
float: left;
font-size: 45px;
}
.txt {
height: 30px;
line-height: 30px;
margin-left: 80px;
}
}
.cart-goods {
border-bottom: 1px solid #e0e0e0;
margin-bottom: 0.75rem;
.shopping-cart-good:last-child .info {
border-bottom: none;
}
}
.invalid-goods {
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
margin: 0.75rem 0;
}
.freebie-and-advance-buy {
font-size: 24px;
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
margin-bottom: 30px;
> li {
box-sizing: border-box;
height: 80px;
line-height: 80px;
margin-bottom: 10px;
padding: 0 20px;
&:last-child {
margin-bottom: 0;
}
a {
float: right;
width: 100%;
}
.under-line {
display: inline-block;
height: 1px;
width: 91%;
position: absolute;
left: 9%;
background-color: #f1f1f1;
}
}
> li:first-child {
.under-line {
display: none;
}
}
.count {
color: #7b7b7b;
float: right;
}
.icon-right-arrow {
color: #8f8f8f;
float: right;
}
}
.activity-title{
border-top: 1px solid #e0e0e0;
font-size: 32px;
padding: 20px 20px 0;
}
.activity{
padding: 8px 20px 20px 32px;
font-size: 26px;
li:before {
content: "";
display: inline-block;
margin-right: 10px;
width: 8px;
height: 8px;
background-color: #000;
border-radius: 50%;
position: relative;
left: 0;
top: -.12rem;
}
}
.price-compute {
padding: 20px;
border-top: 1px solid #e0e0e0;
font-size: 28px;
margin-bottom: 37px;
.title {
display: inline-block;
width: 175px;
}
.minus {
float: right;
}
}
.balance {
position: fixed;
box-sizing: border-box;
bottom: 0;
width: 100%;
padding: 20px;
height: 120px;
border-top: 1px solid #e0e0e0;
background: #fff;
.iconfont {
position: absolute;
top: 50%;
margin-top: -14px;
font-size: 28px;
}
p {
float: right;
margin-right: 32px;
font-size: 26px;
span {
display: block;
height: 40px;
line-height: 40px;
color: #d0253b;
font-weight: bold;
}
.tip {
color: #666;
font-size: 22px;
text-align: right;
font-weight:normal;
}
}
.btn-balance {
float: right;
width: 140px;
height: 80px;
line-height: 80px;
text-align: center;
background: #e01;
color: #fff;
border: none;
font-size: 28px;
}
}
.cart-zero{
width: 100%;
height: auto;
padding-top:2rem;
padding-bottom:20%;
i{
font-size: 6em;
display: block;
margin: 0 auto;
text-align: center;
color: #505050;
}
p{
display: block;
text-align: center;
font-size: 1.0em;
color: #444444;
padding:.6rem 0;
}
a{
width: 27%;
height: 1.2rem;
overflow: hidden;
line-height: 1.2rem;
border:1px solid #505050;
border-radius:.2rem;
display: block;
margin: 0 auto;
text-align: center;
color: #fff;
background: #444;
}
}
}
... ...
.invoice-info-page {
background: #f0f0f0;
.invoice-btn {
position: absolute;
right: 30px;
width: auto;
font-size: 28px;
}
.title {
color: #444;
font-size: 28px;
float: left;
position: relative;
.txt-point {
position: absolute;
left: -15px;
top: 5px;
display: block;
}
}
.invoice-form {
background: #fff;
border-bottom: 1px solid #e0e0e0;
padding: 0 30px;
box-sizing: border-box;
overflow: hidden;
padding-bottom: 15px;
li {
width: 100%;
clear: both;
margin-top: 15px;
line-height: 60px;
float: left;
}
li:first-child {
margin-bottom: 5px;
}
.company {
width: 100%;
height: 88px;
line-height: 88px;
border-radius: 8px;
border: 1px solid #e0e0e0;
font-size: 28px;
color: #b0b0b0;
padding: 0 20px;
margin-bottom: 15px;
}
.tel {
border: none;
font-size: 24px;
line-height: 60px;
width: 400px;
}
.invoice-type {
float: left;
span {
width: 120px;
height: 60px;
line-height: 60px;
text-align: center;
font-size: 24px;
color: #b0b0b0;
border-radius: 5px;
border: 1px solid #b0b0b0;
display: inline-block;
background: #fff;
margin-right: 20px;
}
.on {
background: #444;
border-color: #444;
color: #fff;
}
}
.invoice-top {
float: left;
span {
color: #444;
font-size: 28px;
margin-right: 55px;
}
}
.phone {
color: #b0b0b0;
font-size: 28px;
}
}
.invoice-cont {
background: #fff;
margin-top: 30px;
border-top: 1px solid #e0e0e0;
padding: 0 30px;
box-sizing: border-box;
color: #444;
font-size: 28px;
line-height: 48px;
overflow: hidden;
padding-bottom: 20px;
li {
width: 100%;
margin-top: 28px;
float: left;
}
.choose-cont {
float: right;
}
}
.choose {
font-size: 44px;
display: inline-block;
vertical-align: top;
margin-right: 20px;
}
.icon-radio {
color: #b0b0b0;
}
.btn-area {
width: 100%;
border-top: 1px solid #e0e0e0;
background: #fff;
.confirm-btn {
width: 259px;
height: 88px;
line-height: 88px;
text-align: center;
background: #d0021b;
color: #fff;
display: block;
margin: 0 auto;
border-radius: 8px;
font-size: 28px;
margin-top: 18px;
}
}
.invoice-notice {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: none;
z-index: 9;
.mask-bg {
background: rgba(0,0,0,0.4);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.notice-area {
width: 540px;
height: 400px;
background: #fafafa;
border-radius: 10px;
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
.notice-cont {
padding: 40px;
}
h2 {
text-align: center;
font-size: 28px;
color: #444;
padding-bottom: 4px;
}
p {
font-size: 24px;
color: #444;
line-height: 38px;
}
.think-ok {
width: 100%;
border-top: 1px solid #c5c5c5;
height: 90px;
line-height: 90px;
box-sizing: border-box;
text-align: center;
color: #d1021c;
font-size: 34px;
}
}
}
}
\ No newline at end of file
... ...
.jit-detail-page {
background-color: #f0f0f0;
.top, .middle, .bottom {
display: none;
background-color: #fff;
}
.top, .bottom {
height: 88px;
line-height: 88px;
color: #444;
padding: 0 20px;
}
.top {
margin-bottom: 1PX;
font-size: 34px;
}
.bottom {
font-size: 28px;
margin-bottom: 28px;
}
.swiper-container {
padding: 30px 0 0px;
width: 100%;
height: 209px;
overflow-y: hidden;
.swiper-wrapper-jit {
height: 209px;
}
.swiper-slide {
margin: 0 10px;
float: left;
width: 156px;
position: relative;
&:first-child {
margin-left: 30px;
}
&:last-child {
margin-right: 30px;
}
img {
width: 152px;
height: 204px;
}
.tag {
display: inline-block;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 0.8rem;
line-height: 0.8rem;
color: #fff;
text-align: center;
font-size: 12PX;
&.add {
background: #eb76aa;
}
&.gift {
background: #a1ce4e;
}
}
}
}
}
... ...
.order-ensure-page {
background: #f0f0f0;
.block {
background: #fff;
margin: 20px 0;
padding: 30px 20px;
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
}
.title {
font-size: 32px;
color: #444;
}
/*xwg 2016-3-19 10:53*/
.price-cost{
span{
color: #f00;
}
}
.border-none{
border-bottom:none !important;
}
.boys{
background:resolve('shopping-cart/boys.png') bottom left repeat-x #fff;
}
.girls{
background:resolve('shopping-cart/girls.png') bottom left repeat-x #fff;
}
.kids{
background:resolve('shopping-cart/kids.png') bottom left repeat-x #fff;
}
.life-style{
background:resolve('shopping-cart/lifeStyle.png') bottom left repeat-x #fff !important;
}
.not-address{
position: relative;
i{
position: absolute;
left: 16px;
top: 0%;
font-size: 44px;
}
.choose{
display: block;
color: #000;
height: 64px;
overflow: hidden;
position: static;
padding-left:40px;
font-size: 32px;
line-height: 82px;
span{
position: absolute;
right: 20px;
top: 28px;
font-size: 32px;
}
}
}
.address{
display: block;
position: relative;
margin-top: 0;
border-top: none;
padding-bottom:.8rem;
.info{
width: 90%;
height: auto;
overflow: hidden;
padding-left: 10%;
padding-bottom: 12px;
position: relative;
span{
display: inline-block;
}
i{
position: absolute;
left: 0;
top: 0%;
font-size: 44px;
}
}
.info-name{
width: 48%;
height: 40px;
font-size: 32px;
overflow: hidden;
text-overflow:ellipsis;
white-space:nowrap;
}
.info-phone{
width: 48%;
font-size: 24px;
text-align: right;
}
.info-address{
width: 100%;
font-size: 24px;
line-height: 38px;
}
.rest{
position: absolute;
right: 32px;
bottom:20px;
color: #f00;
font-size: 24px;
span{
font-size: 24px;
}
}
}
.dispatch{
padding:0%;
margin:0;
.sub-block{
color: #444;
&:last-child h3{
border-bottom:none;
}
h3{
width: 95%;
height: 80px;
overflow: hidden;
line-height: 80px;
font-size: 32px;
margin-left: 5%;
border-bottom:1px solid #e0e0e0;
.hide{
display: none !important;
}
p{
display: inline-block;
height: 80px;
overflow: hidden;
text-overflow:ellipsis;
white-space:nowrap;
}
i{
font-size: 36px;
margin-left: 8px;
height: 80px;
display: inline-block;
overflow: hidden;
text-overflow:ellipsis;
white-space:nowrap;
}
span{
display: inline-block;
width: 65%;
height: 80px;
text-align: right;
font-size: 28px;
overflow: hidden;
text-overflow:ellipsis;
white-space:nowrap;
}
}
ul{
height:auto;
overflow: hidden;
line-height: 80px;
font-size: 28px;
background: #e0e0e0;
padding-left:10%;
display: none;
padding-bottom: 8px;
.right{
float: right;
margin-right: 40px;
}
li{
border-bottom:1px solid #fff;
&:last-child{
border-bottom:none;
}
}
}
}
}
.goods-num{
width: 100%;
height: 52px;
color: #b0b0b0;
background:#fff;
padding:20px 0;
text-align: right;
font-size: 28px;
line-height: 52px;
span{
padding-right:20px;
color: #f00;
}
}
.bill{
position: fixed;
background:#fff;
left: 0;
bottom: 0;
right: 0;
height: 100px;
overflow: hidden;
line-height: 100px;
font-size: 28px;
padding-left: 4%;
span{
color: #f00;
}
a{
position: absolute;
right: 20px;
top: 10px;
background:#d0021b;
display: inline-block;
color: #fff;
width: 25%;
height: 80px;
overflow: hidden;
border-radius: 10px;
line-height: 80px;
text-align: center;
font-size: 30px;
}
}
.price-cal{
margin-bottom: 90px;
font-size: 28px;
position: relative;
span{
position: absolute;
right: 28px;
text-align: right;
}
li{
font-size: 28px;
p{
display: inline-block;
}
span{
display: inline-block;
}
}
.yoho-coin {
margin: 50px 0 30px;
background: resolve('product/yoho_icon.png') no-repeat;
padding-left: 68px;
font-size: 28px;
height: 52px;
}
}
.order-good {
position: relative;
padding: 20px 0;
margin-left: 34px;
border-bottom: 1px solid #e0e0e0;
font-size: 26px;
overflow: hidden;
&:last-child {
border-bottom: none;
}
.thumb-wrap {
position: relative;
float: left;
width: 120px;
height: 160px;
}
.thumb {
width: 100%;
height: 100%;
}
.tag {
position: absolute;
bottom: 0;
left: 0;
right: 0;
color: #fff;
text-align: center;
font-size: 12px;
&:before {
display: block;
line-height: 1;
transform:scale(0.833);
}
}
.gift-tag {
height: 25px;
background: #a1ce4e;
&:before {
content: '赠品';
}
}
.advance-buy-tag {
height: 25px;
background: #eb76aa;
&:before {
content: '加价购';
}
}
.deps {
margin-left: 135px;
}
.name {
font-size: 28px;
max-width: 70%;
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.row:nth-child(2) {
height: 45px;
line-height: 45px;
> span {
margin-right: 15px;
}
}
.color, .size {
color: #b6b6b6;
}
.price-wrap {
position: absolute;
top: 20px;
right: 30px;
text-align: right;
}
.price {
color: #e01;
}
.count {
display: block;
color: #999;
text-align: right;
line-height: 45px;
}
.appear-date {
color: #f00;
}
}
.sale-invoice {
margin-top: -20px;
font-size: 24px;
li {
height: 90px;
line-height: 90px;
border-bottom: 1px solid #f7f7f7;
overflow: hidden;
a {
display: block;
}
}
.coupon-count {
padding: 5px 15px;
background: #d0021b;
color: #fff;
border-radius: 10px;
margin-left: 20px;
}
.coupon-use {
box-sizing: border-box;
position: relative;
float: right;
padding-right: 30px;
color: #999;
text-align: right;
width: 320px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
.iconfont {
position: absolute;
top:0;
right: 0;
color: #999;
}
}
.checkbox {
display: inline-block;
width: 80px;
text-align: center;
margin-right: -20px;
}
.coin-check {
float: right;
color: #999;
.checkbox {
margin-left: 5px;
color: #000;
}
&.used {
color: #f00;
}
em {
color: #f00;
}
}
.checkbox.icon-checkbox {
color: #ccc;
}
.invoice {
.checkbox {
float: right;
}
&.focus {
height: auto;
}
}
.desc {
color: #999;
}
}
.block {
input, textarea {
box-sizing: border-box;
margin: 20px 0;
padding: 0 12px;
width: 100%;
height: 72px;
color: #444;
background: #efefef;
font-size: 24px;
line-height: 1;
outline: 0;
border: 0;
border-radius: 4px;
}
textarea {
padding: 12px;
height: auto;
resize: none;
}
&.mt0 {
margin-top: 0;
}
&.more-jit {
padding-top: 0;
padding-bottom: 0;
margin-bottom: -0.5rem;
border-bottom: none;
}
.more-jit {
height: 88px;
line-height: 88px;
position: relative;
span {
font-size: 34px;
color: #444;
}
.iconfont {
position: absolute;
right: 0;
}
}
}
#invoice {
border-top: 1px solid #f7f7f7;
.invoice-type {
float: right;
font-size: 28px;
color: #444;
}
label {
display: block;
border-top: 1px solid #f7f7f7;
}
select {
position: relative;
float: right;
width: 40%;
height: 50px;
top: 20px;
border: 1px solid #f7f7f7;
}
}
#msg {
padding-top: 20px;
input {
margin: 0;
}
}
.total {
font-size: 22px;
margin-top: 20px;
span {
display: inline-block;
width: 130px;
}
}
.cost {
border-top: 1px solid #f7f7f7;
line-height: 100px;
margin-top: 10px;
font-size: 34px;
em {
color: #f00;
}
}
.pay-mode {
background: #fff;
padding: 0 20px;
margin-top: -22px;
li {
height: 88px;
line-height: 88px;
margin-bottom: 28px;
border-radius: 5px;
font-size: 32px;
color: #fff;
text-align: center;
background: #000;
}
.default {
background: #57b038;
}
.iconfont {
margin-right: 20px;
font-size: 32px;
}
}
}
.tickets-confirm-page {
.sorry-tips {
border-bottom: 1px solid #e0e0e0;
height: 50px;
line-height: 50px;
p {
color: #d0021b;
font-size: 24px;
margin-left: 5%;
}
}
.delivery-id {
h3 {
border: 0px;
}
h4 {
width: 95%;
margin-left: 5%;
font-size: 30px;
color: #b0b0b0;
margin-bottom: 20px;
}
}
.yoho-coin {
margin-left: 5%;
width: 90%;
overflow: hidden;
border-bottom: 1px solid #e0e0e0;
.sale-invoice {
margin-top: 0px;
}
}
.dispatch {
.sub-block {
h3 {
width: 90%;
span {
color: #afafaf;
font-size: 26px;
float: right;
}
}
}
}
.tickets-mobile {
position: relative;
input {
background: #fff;
border: 1px solid #b0b0b0;
height: 85px;
line-height: 85px;
margin: 0px;
outline: none;
-webkit-appearance: none;
}
.mobile-tips {
display: inline-block;
position: absolute;
height: 85px;
line-height: 85px;
right: 30px;
top: 50%;
margin-top: -43px;
font-size: 22px;
color: #b0b0b0;
}
}
}
... ...
.select-address-page {
padding-bottom: 20px;
.add-address {
margin-bottom: 0;
}
}
... ...
@define-extend line {
content: "";
position: absolute;
top: 50%;
border-top: 1px solid #b0b0b0;
width: 120px;
height: 0;
}
.select-coupon-page {
margin-top: 30px;
margin-bottom: 30px;
#new-coupon {
margin-bottom: 30px;
padding-left: 30px;
padding-right: 30px;
font-size: 24px;
input {
padding: 0 12px;
width: 384px;
height: 80px;
border: 1px solid #b0b0b0;
border-radius: .1rem;
outline: 0;
}
.submit {
margin-left: 30px;
width: 130px;
height: 80px;
color: #fff;
background: #b0b0b0;
border-radius: .1rem;
border: none;
outline: 0;
}
}
.coupon-list {
.employ-main:first-child {
margin-top: 0;
}
.employ-main:last-child {
margin-bottom: 0;
}
}
.not-use {
display: block;
width: 560px;
margin: 30px auto 0;
text-align: center;
font-size: 32px;
line-height: 2.5;
border: 1px solid #444;
border-radius: 4PX;
}
.not-avaliable-coupon-line {
position: relative;
margin-top: 30px;
margin-bottom: 30px;
font-size: 28px;
line-height: 2;
color: #b0b0b0;
text-align: center;
&:before {
@extend line;
left: 60px;
}
&:after {
@extend line;
right: 60px;
}
}
.not-avaliable {
background-image: resolve("me/employ/employ-grey.jpg") !important;
}
}
... ...
... ... @@ -24,6 +24,7 @@
@import "discount-list";
@import "left-right";
@import "cate";
@import "seckill";
@import "three-picture";
@import "six-lines-floor";
... ...
.seckill {
.seckill-times{
height: 119px;
border-top: 1px solid #e1e1e1;
border-bottom: 1px solid #e1e1e1;
.time-item {
float: left;
}
}
}
\ No newline at end of file
... ...
... ... @@ -23,7 +23,7 @@
@import "activity/invite";
@import "passport/index";
@import "guang/index";
@import "cart/chose-panel";
@import "cart/index";
@import "home/index";
@import "me/index";
@import "home/index";
... ...
... ... @@ -10,7 +10,6 @@
box-sizing: border-box;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
html,
body {
width: 100%;
... ... @@ -18,6 +17,15 @@ body {
font-family: helvetica, Arial, "黑体";
line-height: 1.4;
}
.width750 {
font-size: 28px;
.main-wrap {
max-width: 750px;
}
.good-failure {
background-size: 155px !important;
}
}
button,
input,
... ...
.width750 {
.yoho-footer {
font-size: 28px;
}
.op-row {
padding: 0 35px;
height: 140px;
line-height: 140px;
.user-name {
margin-right: 1.17em;
margin-left: 0.35em;
max-width: 234px;
}
.back-to-top {
right: 47px;
}
.sep-line {
margin: 0 0.35em;
}
}
.copyright {
height: 140px;
line-height: 140px;
}
}
.yoho-footer {
position: relative;
width: 100%;
... ...
... ... @@ -10,7 +10,36 @@
font-size: 20PX;
line-height: 90px;
}
.width750 {
.yoho-header {
height: 105px;
line-height: 105px;
.nav-back {
left: 12px;
width: 105px;
height: 105px;
line-height: 105px;
}
.nav-home {
right: 12px;
width: 105px;
height: 105px;
line-height: 105px;
}
.nav-btn {
right: 12px;
width: 105px;
height: 105px;
line-height: 105px;
}
.nav-title {
margin-right: 117px;
margin-left: 117px;
font-size: 42px;
font-weight: normal;
}
}
}
.yoho-header {
position: relative;
z-index: 1;
... ... @@ -76,6 +105,18 @@
}
}
.width750 {
.system-update {
height: 105px;
line-height: 105px;
.system-header {
font-size: 70px;
}
span {
font-size: 94px;
}
}
}
.system-update {
display: none;
overflow: hidden;
... ... @@ -106,6 +147,24 @@
}
}
.width750 {
.homebuttom {
height: 105px;
ul {
padding-top: 14px;
li {
i {
margin-bottom: 9px;
}
span {
line-height: 47px;
font-size: 16px;
}
}
}
}
}
.homebuttom {
position: relative;
z-index: 2;
... ...
... ... @@ -14,7 +14,19 @@
opacity: 1;
}
}
.width750 {
.loading {
margin-top: -23px;
margin-left: -70px;
width: 140px;
height: 47px;
> div {
margin: 5px;
width: 35px;
height: 35px;
}
}
}
.loading-mask {
position: fixed;
top: 0;
... ...
@import "sale/index";
@import "detail/index";
@import "outlet/index";
@import "seckill/index";
... ...
... ... @@ -371,6 +371,52 @@ $basicBtnC: #eb0313;
}
}
.seckill-time {
float: right;
color: #d0021b;
font-size: 24px;
span {
display: inline-block;
line-height: 88px;
}
.seckill-time-pic {
background-color: #d0021b;
color: #fff;
line-height: 35px;
font-size: 18px;
padding: 0 10px;
border-radius: 5px;
}
}
.seckill-chose {
position: absolute;
bottom: 0px;
right: 0px;
}
.limit-num-text {
color: #d0021b;
font-size: 30px;
line-height: 80px;
position: absolute;
left: 380px;
bottom: 0;
}
.seckill-time-border {
border: solid 1px #d0021b;
margin-top: 26px;
border-radius: 19px;
padding: 0 10px;
span {
line-height: 34px;
}
}
.vip-level {
box-sizing: box-border;
padding-right: 28px;
... ... @@ -711,7 +757,41 @@ $basicBtnC: #eb0313;
}
}
}
/*
秒杀倒计时栏
*/
.seckill-count {
position: relative;
position: fixed;
bottom: 120px;
left: 50%;
margin-left: -320px;
z-index: 2;
box-sizing: border-box;
width: 640px;
height: 70px;
text-align: left;
.seckill-count-bg {
background-color: #000;
opacity: 0.7;
width: 640px;
height: 70px;
}
.seckill-count-num {
position: absolute;
top: 0;
left: 0;
padding: 0 30px;
color: white;
width: 640px;
height: 70px;
line-height: 70px;
box-sizing: border-box;
font-size: 28px;
}
}
/*
底部固定栏
*/
... ...
@import "nav";
@import "product";
@import "seckill";
\ No newline at end of file
... ...
.seckill-list {
.nav-list {
background-color: #fff;
width: auto;
border-top: solid 1PX #e1e1e1;
height: 119px;
overflow: hidden;
ul {
width: auto;
overflow: hidden;
height: 100%;
padding-top: 20px;
li{
width: 226px;
height: 79px;
border-right: solid 1PX #e1e1e1;
text-align: center;
float: left;
$status-list: over, now, wait;
@each $status in $status-list {
&.$(status) {
.tip-$(status),
.info-$(status) {
display: initial;
}
}
}
&.last {
.last-info {
display: block;
},
.last-count-down {
display: none
}
}
.status,
.last-info {
display: none;
}
p {
font-size: 22px;
}
&:last-child {
border: none;
}
&.focus {
width: 300px;
.selected {
display: block;
}
.normal {
display: none;
}
}
.selected {
display: none;
color: #d0021b;
height: 79px;
}
.normal {
display: block;
height: 79px;
}
.time {
font-size: 30px;
span {
margin-right: 5px;
}
}
.tick {
font-size: 20px;
background-color: #d60117;
color: #fff;
margin-left: 10px;
border-radius: 3PX;
padding-left: 5px;
padding-right: 5px;
}
}
}
}
}
... ...