Authored by 沈志敏

merge

... ... @@ -138,6 +138,7 @@ tags
### YOHO ###
public/dist/
public/img/sprite.*
public/css/*
public/bundle/*
.eslintcache
... ...
... ... @@ -7,7 +7,12 @@ const favModel = require('../models/favorite');
const fav = {
favorite: (req, res) => {
if (req.query.tab === 'brand') {
if (req.query.tab === 'article') {
res.render('favorite-article', {
module: 'me',
page: 'favorite-article'
});
} else if (req.query.tab === 'brand') {
res.render('favorite-brand', {
module: 'me',
page: 'favorite-brand'
... ... @@ -23,8 +28,13 @@ const fav = {
const uid = req.user.uid;
const tab = req.query.tab;
const page = req.query.page;
const udid = req.sessionID;
if (tab === 'brand') {
if (tab === 'article') {
favModel.getFavArticleData(uid, udid, page, 10).then(data => {
return res.json(data);
});
} else if (tab === 'brand') {
const gender = '1,2,3';
favModel.getFavBrandData(uid, gender, page, 10).then(data => {
... ... @@ -41,9 +51,15 @@ const fav = {
const favId = req.body.favId;
const type = req.body.type;
favModel.favoriteDelete(uid, favId, type).then(data => {
return res.json(data);
}).catch(next);
if (type === 'article') {
favModel.favArticleDelete(uid, favId).then(data => {
return res.json(data);
}).catch(next);
} else {
favModel.favoriteDelete(uid, favId, type).then(data => {
return res.json(data);
}).catch(next);
}
}
};
... ...
... ... @@ -157,7 +157,14 @@ const component = {
res.render('about', {
module: 'me',
page: 'about',
year: new Date().getFullYear(),
noLocalCSS: true
});
},
provisions: (req, res) => {
res.render('provisions', {
module: 'me',
page: 'provisions',
noLocalJS: true,
noLocalCSS: true
});
},
... ...
... ... @@ -79,6 +79,15 @@ const order = {
return res.json(result);
}).catch(next);
},
readdData: (req, res, next) => {
// 再次购买
const orderCode = req.body.orderCode;
const uid = req.user.uid;
orderModel.readdData(orderCode, uid).then((result) => {
res.json(result);
}).catch(next);
},
confirmOrder: (req, res, next) => {
const orderode = req.body.orderCode;
... ...
'use strict';
const api = global.yoho.API;
const serviceAPI = global.yoho.ServiceAPI;
/**
* 处理用户收藏的商品数据
... ... @@ -46,6 +47,29 @@ exports.getFavBrandData = (uid, gender, page, limit) => {
};
/**
* 处理用户收藏的品牌数据
*
* @param int uid 用户ID
* @param int udid 用户udid
* @param int page 第几页
* @param int limit 限制读取的数目
* @return array 处理之后的收藏的品牌数据
*/
exports.getFavArticleData = (uid, udid, page, limit) => {
return serviceAPI.get('guang/api/v1/favorite/getUserFavArticleList', {
uid: uid,
udid: udid,
client_type: 'h5',
page: page,
limit: limit
}, {
code: 200
}).then(result => {
return result.data || {};
});
};
/**
* 取消收藏的商品/品牌数据
*
* @param int uid 用户ID
... ... @@ -60,4 +84,18 @@ exports.favoriteDelete = (uid, favId, type) => {
type: type,
fav_id: favId
});
};
\ No newline at end of file
};
/**
* 取消收藏的资讯
*
* @param int uid 用户ID
* @param int favId 要取消的收藏id
* @return array 接口返回的数据
*/
exports.favArticleDelete = (uid, favId) => {
return serviceAPI.get('guang/api/v1/favorite/cancelFavorite', {
uid: uid,
article_id: favId
});
};
... ...
'use strict';
const api = global.yoho.API;
const serviceAPI = global.yoho.ServiceAPI;
const singleAPI = global.yoho.SingleAPI;
const helpers = global.yoho.helpers;
const _ = require('lodash');
const config = global.yoho.config;
... ... @@ -48,19 +47,12 @@ const _getInfoNumData = (uid) => {
method: 'app.address.gethidden' // 用户地址的数据
}, {
code: 200
}), singleAPI.get('favorite', {
method: 'app.favorite.getFavoriteCount', // 获取用户收藏商品总数
uid: uid
}, {
code: 200
})]).then(data => {
const res = {
wait_pay_num: '',
wait_cargo_num: '',
send_cargo_num: '',
refund_exchange_num: '',
product_favorite_total: '',
brand_favorite_total: '',
yoho_coin_num: ''
};
... ... @@ -73,13 +65,6 @@ const _getInfoNumData = (uid) => {
}
}
// 收藏商品数另外调接口
if (data[2] && data[2].data && data[2].data.product_favorite_total > 0) {
res.product_favorite_total = data[2].data.product_favorite_total > 99 ? '99+' :
data[2].data.product_favorite_total;
}
return Object.assign(res, {
address_num: data[1].data && data[1].data.length ? data[1].data.length : ''
});
... ...
... ... @@ -56,6 +56,26 @@ exports.cancelOrder = (orderCode, reasonId, reason) => {
});
};
// 再次购买
exports.readdData = (orderCode, uid) => {
return api.get('', {
method: 'app.Shopping.readd',
uid: uid,
order_code: orderCode
}).then((result) => {
if (result && result.code === 200) {
result.message = '商品已重新加入购物车';
} else if (result.code === '400') {
result.message = '缺失参数';
} else {
result.message = '商品加入购物车失败';
result.datat = {};
}
return result;
});
};
/**
* 确认订单
* @param orderCode 订单号
... ...
... ... @@ -29,6 +29,7 @@ router.get('/me/getOrderList', auth, order.getOrderData); // 获取订单数据
router.get('/me/get-order', auth, order.getOrderDetailData); // AJAX 获取订单详情数据
router.get('/me/getCancelOrderReason', auth, order.getCancelReason); // 获取取消订单原因
router.post('/me/cancelOrder', auth, order.cancelOrder); // 取消订单
router.post('/me/readdorder', auth, order.readdData); // 再次购买
router.post('/me/deleteOrder', auth, order.deleteOrder); // AJAX 删除订单
router.post('/me/confirmReceive', auth, order.confirmOrder); // 确认订单
... ... @@ -43,8 +44,8 @@ router.get('/me/feedback', auth, home.feedback); // 个人中心-意见反馈
router.post('/me/save-feedback', auth, home.saveFeedback); // 个人中心-提交意见反馈
router.get('/me/collection', auth, favorite.favorite); // 个人中心 - 收藏
router.get('/me/collection/favpaging', auth, favorite.favpaging); // 个人中心 - 收藏商品/品牌(翻页)
router.post('/me/del-favdel', auth, favorite.deletefav); // 个人中心 - 收藏商品/品牌(刪除)
router.get('/me/collection/favpaging', auth, favorite.favpaging); // 个人中心 - 收藏商品/品牌/资讯(翻页)
router.post('/me/del-favdel', auth, favorite.deletefav); // 个人中心 - 收藏商品/品牌/资讯(刪除)
// 退换货
router.get('/me/return', auth, refund.refundOrders); // 退换货 - 订单列表
... ... @@ -72,6 +73,7 @@ router.get('/me/mydetails', auth, home.mydetails); // 个人信息
router.post('/me/save-mydetails', auth, home.saveMydetails); // AJAX 保存个人信息
router.get('/me/about', home.about); // 个人中心 - 关于我们
router.get('/me/provisions', home.provisions); // 个人中心 - 隐私条款
router.get('/me/logistic', auth, order.logistic); // 个人中心 - 退换货物流设置页面
router.get('/me/get-order-logistic-date', auth, order.getOrderLogisticdate); // 个人中心 - 订单物流详情数据
... ...
<div class="about-us">
<div class="description">
<p>From yoho! {{year}} high-end store</p>
<p>i fancy, you like.</p>
</div>
<div class="icon-container">
<span class="blk-icon icon icon-blk"></span>
<p class="icon-label">YOHO!BLK</p>
</div>
<div class="description">
<p>The world of fashion is</p>
<p>at your fingertips</p>
</div>
<div class="provisions">
<a href="/me/provisions">隐私条款</a>
</div>
<div class="yoho-img">
</div>
</div>
... ...
<div class="yoho-favorite-article-page">
<div class="fav-content" id="fav-content">
<fav-article-list></fav-article-list>
</div>
</div>
... ...
<div class="provisions">
<section class="detail">
<p>欢迎访问YOHO!BLK APP!我们以本隐私申明声明对访问者隐私保护的许诺。</p>
<h4>YOHO!BLK APP的信息收集与使用</h4>
<ul>
<li>YOHO!BLK APP收集用户提交的个人识别信息(下称“个人识别信息”), 一旦注册,YOHO!BLK APP用户即可以建立由一页或多页网页组成的含有用户信息的用户档案。我们将收集用户发布在其用户档案中的数据,包括但不限于: 会员信息,联系信息,购物&着装习惯和喜爱品牌(合称为“用户档案信息”),我们使用这些信息来获得用户的统计资料。我们将会用这些统计数据来给我们的用户分类,以便有针对性地向我们的用户提供新的服务。我们会通过您的邮件地址来通知您这些新的服务。</li>
<li>我们同样从用户处收集其他非个人识别信息(下称“非个人识别信息”),包括IP地址、集合的用户数据和浏览器类型。该等数据会被用来管理YOHO!BLK APP,跟踪使用记录,改进YOHO!BLK APP的服务。该等非个人识别信息通常被用于下列目的:研究和分析站点的使用情况,订制您浏览的广告和内容,满足您对服务的要求,以及改进我们的服务。出于安全和监管的目的,用户的IP地址将会被记录。</li>
<li>我们或其商业伙伴可能在YOHO!BLK APP上不时地进行促销或者抽奖。用户可能会被要求提供个人识别信息,包括姓名,电子邮件地址或家庭住址。因进行促销或者抽奖而收集个人识别信息时,您将清楚地被告知个人识别信息的收集方以及适用的隐私政策。</li>
</ul>
<h4>YOHO!BLK APP收集信息的共享与披露</h4>
<ul>
<li>除本隐私政策另有规定,我们不会在未经您同意的情况下在YOHO!BLK APP及其母公司、子公司或者关联公司(为本隐私政策之目的,包括遵守本隐私政策的技术提供者)之外泄露您的个人识别信息或者用户档案信息,除非我们认为这种披露是有必要的:(1)为遵守法律的要求或者回应我们收到的传票、搜查令或者其他法律程序,而不论该等回应是否为适用法律所要求的;(2)为回应主管政府部门的要求;(3)为了保护公众和服务用户的安全;或者(4)为了维护我们的法律权利和利益。</li>
<li>当我们出售YOHO!BLK APP或其全部资产时,我们保留向其继任者转让个人识别信息和用户档案信息的权利。</li>
<li>我们也可以向某些您明确同意接收其信息的广告合作伙伴转让您的个人识别信息和用户档案信息。因此进行个人识别信息的收集时,您将清楚地被告知适用的隐私政策。</li>
</ul>
<h4>用户名和密码</h4>
<ul>
<li>YOHO!BLK APP用户账号通过用户创设的密码确保其安全性。您应当对您密码的保密负全部责任。请不要和他人分享此信息。如果您泄漏了密码,您可能丢失了您的个人识别信息,并且有可能导致对您不利的司法行为。如果您和他人共享一台电脑,您应该在离开YOHO!BLK APP时退出系统以保证您的信息不被后来使用该电脑者获取。</li>
<li>因此不管任何原因使您的密码安全受到危及,您应该立即通过我们的客服热线:400-889-9646和我们取得联系 。</li>
</ul>
<h4>您的交易行为</h4>
<ul>
<li>我们跟踪IP地址仅仅只是为了安全的必要。如果我们没有发现任何安全问题,我们会及时删除我们收集到的IP地址。我们还跟踪全天的页面访问数据。全天页面访问数据被用来反映网站的流量,我们可以为未来的发展制定计划(例如,增加服务器)。</li>
</ul>
<h4>邮件 / 短信 / 会刊服务</h4>
<ul>
<li>我们保留通过邮件、短信、邮寄会刊的形式,对本网站注册、购物用户发送订单信息、促销活动等告知服务的权利。如果您在YOHO!BLK APP注册、购物,表明您已默示同意接受此项服务。如果您不想接收来自我们的邮件、短信或会刊,您可以向我们的客服提出退阅申请,并注明您的E-mail地址、手机号或相关地址信息,我们会在收到申请后为您办理退阅。</li>
</ul>
<h4>Cookies 的使用</h4>
<ul>
<li>我们使用cookies来储存用户的喜好和记录活动信息以确保用户不会重复收到同样的广告和定制的时事通讯、广告以及基于浏览器类型和用户档案信息的网页内容。我们不会把在cookies中保存的信息与您在我们网站上提交的任何个人识别信息相连接。您可以通过设置您的浏览器以接受或者拒绝全部或部分的cookies,或要求在cookies被设置时通知您。由于每个浏览器是不同的,请查看浏览器的“帮助”菜单来了解如何更改您的cookies选择参数。但是,您应允许来自YOHO!BLK APP的cookies以使您可以使用网站的更多的功能。</li>
</ul>
<h4>外部链接</h4>
<ul>
<li>YOHO!BLK APP包含其他网站的链接。但我们不对其他网站上的隐私政策和/或其执行承担责任。当链接到其他网站时,用户应该阅读该网站贴示的隐私政策。我们的隐私政策仅适用于自YOHO!BLK APP收集的信息。</li>
</ul>
<h4>第三方广告</h4>
<ul>
<li>我们可能会通过与第三方合作向用户提供服务。因此,我们可能向该第三方提供您通过YOHO!BLK APP提交给我们的个人识别信息和用户档案信息;但该第三方应同意承担与我们相同的责任以保护用户的隐私。另外,在不会披露用户的个人识别信息和用户档案信息的前提下,我们可以对集合的用户个人识别信息和用户档案进行分析和商业性使用。</li>
</ul>
<h4>安全</h4>
<ul>
<li>我们会采取合理措施保护存储在我们数据库中的用户个人识别信息和用户档案信息,并且对那些需要履行其工作职责的雇员,比如我们的客户服务人员和技术人员,获取用户个人识别信息和用户档案信息进行限制。请注意,我们无法保证用户个人识别信息和用户档案信息的安全性。未授权的登陆或使用、硬件或软件的故障、以及其他因素均可能在任何时候危及用户个人识别信息的安全性。</li>
</ul>
<h4>隐私政策的变更</h4>
<ul>
<li>我们可能对本隐私政策不时进行修改。如果我们进行任何修改,我们将在YOHO!BLK APP主页上发布为期30天的通知以使用户知道被修改内容的类型以及指示用户审阅更新的隐私政策。如果您在对本隐私政策任何细微修改发布后继续使用网站,则表示您同意遵守任何该等修改。</li>
</ul>
<h4>联系我们</h4>
<ul>
<li>如果您就本隐私政策有任何疑问,请与我们客服联系客服热线:400-889-9646。</li>
</ul>
</section>
</div>
\ No newline at end of file
... ...
... ... @@ -4,6 +4,32 @@ const api = global.yoho.API;
const prettyFilter = require(`${global.utils}/beautify/filters`);
const processProductList = require(`${global.utils}/beautify/product`);
// 排序转换
const getTypeCont = (type, order) => {
switch (type) {
case 'price':
return order === '0' ? 's_p_desc' : 's_p_asc';
case 'discount':
return order === '0' ? 'p_d_desc' : 'p_d_asc';
case 'sale':
return order === '0' ? 's_n_desc' : 's_n_asc';
case 'newest':
return order === '0' ? 's_t_desc' : 's_t_asc';
case 'stock':
return order === '0' ? 's_s_desc' : 's_s_asc';
case 'all':
return order === '0' ? 'd_s_desc' : 'd_s_asc';
case 'category':
return order === '0' ? 's_t_desc' : 's_t_asc';
case 'new':
return order === '0' ? 's_t_desc' : 's_t_asc';
case 'hot':
return order === '0' ? 's_n_desc' : 's_n_asc';
default:
return order === '0' ? 's_t_desc' : 's_t_asc';
}
};
/* 查询最新产品列表 */
exports.getNewData = (params) => {
if (params.hasOwnProperty('priceRange')) {
... ... @@ -11,6 +37,12 @@ exports.getNewData = (params) => {
delete params.priceRange;
}
if (params.order) {
params.order = getTypeCont(params.type || '', params.order);
} else {
params.order = 's_t_asc';
}
params = Object.assign({
method: 'app.search.newProduct',
}, params);
... ... @@ -49,4 +81,4 @@ exports.getNewData = (params) => {
// data: filterConfig
// };
// });
// };
\ No newline at end of file
// };
... ...
... ... @@ -14,7 +14,7 @@
const $ = require('jquery');
function tip(param) {
function tip(param, cb) {
let timer;
const viewData = {
mask: false,
... ... @@ -43,6 +43,9 @@ function tip(param) {
$tip.data('timer', setTimeout(function() {
$tip.remove();
if (typeof cb === 'function') {
cb();
}
}, viewData.delay));
}
... ...
... ... @@ -36,6 +36,63 @@ module.exports = (Vue) => {
});
/**
* 转换为blk的url
*
* @param value
*/
Vue.filter('transformBlk', (value) => {
let protocol = value.match(/^(https?:)?\/\//);
protocol = protocol && protocol.length ? protocol[0] : '';
value = value.replace(protocol, '');
// 新品抢先看
let query = value.match(/^m\.yohobuy\.com\/product\/blknew(\?.*)?/);
if (query) {
query = query[1] || '';
return `${protocol}m.yohoblk.com/new${query}`;
}
// 全部品类
if (value === 'm.yohobuy.com/cate') {
return `${protocol}m.yohoblk.com/cate-all`;
}
// 全部品牌
if (value === 'm.yohobuy.com/brand' || value === 'm.yohobuy.com/brands') {
return `${protocol}m.yohoblk.com/brand`;
}
let subDomain = value.match(/(.+)\.m\.yohobuy\.com/);
subDomain = subDomain ? subDomain[1] : '';
if (subDomain) {
if (subDomain === 'guang') {
// 逛
let editorialId = value.match(/guang\.m\.yohobuy\.com\/info\/index\?id=(\d{1,})/);
if (editorialId) {
editorialId = editorialId[1];
return `${protocol}m.yohoblk.com/editorial/${editorialId}.html`;
}
} else if (subDomain === 'list') {
// 品类
query = value.match(/\?.*/);
query = query ? query[0] : '';
return `${protocol}m.yohoblk.com/product/list${query}`;
} else {
// 品牌
query = value.match(/\?.*/);
query = query ? query[0] : '';
return `${protocol}m.yohoblk.com/product/shop/${subDomain}${query}`;
}
}
return `${protocol}${value}`;
});
/**
* 品牌URL
*
* @param value brand domain
... ... @@ -198,4 +255,4 @@ module.exports = (Vue) => {
return en + cn;
});
};
\ No newline at end of file
};
... ...
const Vue = require('vue');
const infiniteScroll = require('vue-infinite-scroll');
const favArticleList = require('me/fav-article-list.vue');
const VueTouch = require('vue-touch');
const yoho = require('yoho');
require('common/vue-filter')(Vue);
Vue.use(VueTouch);
Vue.use(infiniteScroll);
yoho.ready(() => {
new Vue({
el: '#fav-content',
components: {
favArticleList
}
});
});
... ...
... ... @@ -5,7 +5,7 @@
.description {
position: fixed;
top: 404px;
top: 680px;
width: 425px;
height: 75px;
left: 0;
... ... @@ -21,7 +21,7 @@
.icon-container {
position: fixed;
top: 550px;
top: 404px;
left: 0;
right: 0;
margin-left: auto;
... ... @@ -52,4 +52,54 @@
text-align: center;
font-size: 24px;
}
.provisions {
position: fixed;
left: 0;
right: 0;
bottom: 200px;
text-align: center;
margin-left: auto;
margin-right: auto;
a {
text-decoration: underline;
}
}
.yoho-img {
position: fixed;
bottom: 100px;
width: 214px;
height: 53px;
margin: 0 auto;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
background-image: url('/me/yoho.png');
}
}
.provisions {
margin: 20px 3%;
font-size: 30px;
width: 94%;
overflow: hidden;
h4 {
line-height: 60px;
}
ul {
list-style: disc;
list-style-position: inside;
margin-left: 10px;
margin-bottom: 15px;
}
p {
line-height: 40px;
margin-top: 40px;
}
}
... ...
... ... @@ -25,6 +25,18 @@
}
.deal-main {
margin: 20px 3%;
font-size: 30px;
width: 94%;
overflow: hidden;
ol,
ul {
list-style: disc;
list-style-position: inside;
margin-left: 10px;
}
.detail {
h4 {
line-height: 60px;
... ... @@ -39,4 +51,4 @@
margin-top: 40px;
}
}
}
}
\ No newline at end of file
... ...
.deal-main {
margin: 20px 3%;
font-size: 30px;
width: 94%;
overflow: hidden;
ol,
ul {
list-style: disc;
list-style-position: inside;
margin-left: 10px;
}
}
@import "help";
@import "helpdetail";
@import "feedback";
@import "about-us";
... ...
... ... @@ -39,10 +39,25 @@ $white: #fff;
font-size: 34px;
border-bottom: 1px solid #eee;
line-height: 88px;
position: relative;
> p:first-child {
flex: 1;
}
.exchange {
position: absolute;
top: 50%;
transform: translateY(-50%);
height: 40%;
line-height: 1.2;
padding: 5px 18px;
color: #fffefe;
background: #b0b0b0;
border-radius: 20px;
font-size: 20px;
margin-left: 20px;
}
}
.order-goods {
... ...
... ... @@ -35,6 +35,6 @@
<style>
#channel {
padding-top: 90px;
padding-top: 80px;
}
</style>
... ...
... ... @@ -73,7 +73,7 @@
.item {
position: relative;
display: block;
padding: 0 30px;
padding: 0 45px;
height: 124px;
line-height: 124px;
font-size: 30px;
... ... @@ -81,24 +81,30 @@
font-family: "BrownStd-Bold", "PingFang SC", Helvetica, Roboto, "Heiti SC", "黑体", Arial;
.en {
font-size: 36px;
font-size: 34px;
}
.cn {
font-size: 22px;
margin-left: -6px;
font-family: "PingFang SC", Helvetica, Roboto, "Heiti SC", "黑体", Arial;
}
&:first-child {
font-size: 36px;
font-size: 34px;
height: 142px;
line-height: 142px;
font-family: "PingFang SC", Helvetica, Roboto, "Heiti SC", "黑体", Arial;
.cn {
font-size: 34px;
}
}
&:after {
content: "";
position: absolute;
left: 30px;
left: 45px;
bottom: 0;
width: 100%;
height: 0;
... ...
... ... @@ -81,16 +81,17 @@
z-index: 1;
width: 100%;
max-width: 750px;
height: 90px;
height: 80px;
font-size: 26px;
text-align: center;
background: #fff;
transform: translate(-50%, 0);
border-bottom: 1px solid #eee;
font-family: "BrownStd", "PingFang SC", Helvetica, Roboto, "Heiti SC", "黑体", Arial;
.channel {
display: inline-block;
line-height: 90px;
line-height: 80px;
color: #b0b0b0;
&.focus {
... ...
... ... @@ -11,6 +11,9 @@
<h2 class="card-label">
<a href="{{item | goodsUrl}}" class="line-clamp-2">{{item.product_name}}</a>
</h2>
<h2 class="card-label-desc" v-if="item.product_name1">
<a href="{{item | goodsUrl}}" class="line-clamp-2">{{item.product_name}}</a>
</h2>
<span class="good-price" :class="{'old-price': item.market_price}" v-if="item.market_price">¥ {{item.market_price | toFixed}}</span>
<span class="good-price" :class="{'sale-price': item.market_price}">¥ {{item.sales_price | toFixed}}</span>
</div>
... ... @@ -115,6 +118,18 @@
height: 67.1999999999px;
font-weight: normal;
}
.card-label-desc {
margin: 0 0 14px;
font-size: 20px;
line-height: 1.4;
height: 67.1999999999px;
font-weight: normal;
a {
color: #888;
}
}
}
.good-price {
... ...
<template>
<div class="focus-left-right">
<a v-for="item in floor" href="{{item.url}}" title="{{item.title}}">
<a v-for="item in floor" :href="item.url | transformBlk" :title="item.title">
<img v-bind:src="item.src | resize 250 250">
</a>
</div>
... ...
... ... @@ -2,7 +2,7 @@
<div class="focus-floor">
<swipe class="swipe swipe-{{floor.length}}">
<swipe-item v-for="item in floor" :style="{backgroundColor: item.bgColor}">
<a href="{{item.url}}" title="{{item.title}}">
<a :href="item.url | transformBlk" :title="item.title">
<img :src="item.src | resize 750 365">
</a>
</swipe-item>
... ...
<template>
<div class="recommend-content-five">
<a v-for="item in floor" href="{{item.url}}" title="{{item.title}}">
<a v-for="item in floor" :href="item.url | transformBlk" :title="item.title">
<img v-bind:src="item.src | resize 375 375">
</a>
</div>
... ...
... ... @@ -2,7 +2,7 @@
<div class="floor-header">
{{title.name}}
<a class="more" href="{{title.more_url}}">
<a class="more" :href="title.more_url | transformBlk">
<span v-if="title.more_name === '···'" class="icon icon-more"></span>
<span v-else>{{{title.more_name}}}</span>
</a>
... ... @@ -19,9 +19,9 @@
.floor-header {
position: relative;
width: 100%;
height: 100px;
height: 80px;
font-size: 32px;
line-height: 100px;
line-height: 80px;
text-align: center;
font-weight: bold;
border-top: 1px solid #eee;
... ...
<template>
<div class="title-image">
<title-floor :title="{name: floor.title, more_name: floor.more_name, more_url: floor.more_url}"></title-floor>
<a class="image" :href="floor.image.url">
<a class="image" :href="floor.image.url | transformBlk">
<img v-bind:src="floor.image.src | resize 750 364">
</a>
</div>
... ...
<template>
<div class="fav-type" v-infinite-scroll="loadMore()" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
<ul class="fav-article-list">
<li v-for="item in articleData" track-by="fav_id" id="li-{{item.fav_id}}" v-touch-options:pan="{ direction: 'horizontal', threshold: 100}" v-touch:panstart="panstart(item.fav_id)" v-touch:panmove="panmove(item.fav_id)" v-touch:panend="panend(item.fav_id)">
<div class="fav-del-left {{editmodel ? 'delshow': ''}}" @click="showDelBtn(item.fav_id)">
<span class="fav-del-span"><span class="icon icon-edit-del"></span></span>
</div>
<div class="editorial-box">
<a href="/editorial/{{item.fav_id}}.html">
<div class="img"><img :src="item.src | resize 750 469"/></div>
<div class="title">{{item.title}}</div>
<div class="editorial-des"><p class="line-clamp-2">{{item.intro}}</p></div>
<hr>
<div class="bottom clearfix">
<span class="icon icon-timeshare"></span>
<span class="time">{{item.publish_time}}</span>
<span class="icon icon-share share" @click="share(item.title, item.intro, item.src, item.fav_id)"></span>
</div>
</a>
</div>
<div class="fav-del-right hide" id="del-{{item.fav_id}}" @click="delItem($index, item.fav_id)">
<div class="span-delete">
<span class="icon icon-delete"></span>
<br/>
<span class="fav-del-txt">删 除</span>
</div>
</div>
</li>
</ul>
<div class="fav-null-box {{ nullbox }}">
<span class="fav-null">您暂无收藏任何资讯</span>
<a class="go-shopping" href="/editorial/list">随便逛逛</a>
</div>
</div>
</template>
<script>
const $ = require('jquery');
const tip = require('common/tip');
const interceptClick = require('common/intercept-click');
const yoho = require('yoho');
const bus = require('common/vue-bus');
module.exports = {
data() {
return {
nullbox: 'hide',
busy: false,
editmodel: false,
page: 0,
pageX: 0,
currentX: 0,
pandata: {},
articleData: [],
keys: {}
};
},
created() {
yoho.addNativeMethod('editModel', () => {
this.hideDelBth();
this.editmodel = !this.editmodel;
this.updateNavBar();
});
yoho.store.remove('articleReload');
document.addEventListener('visibilitychange', () => {
if (!document.hidden && yoho.store.get('articleReload')) {
this.reload();
}
});
if (yoho.isApp) {
bus.$on('app.favourite.tabChange', this.updateNavBar);
}
},
methods: {
reload() {
this.nullbox = 'hide';
this.busy = false;
this.editmodel = false;
this.page = 0;
this.pageX = 0;
this.currentX = 0;
this.pandata = {};
this.articleData = [];
this.keys = {};
yoho.store.remove('articleReload');
},
loadMore() {
this.busy = true;
$.ajax({
url: '/me/collection/favpaging',
data: {
page: ++this.page,
tab: 'article'
}
}).then(data => {
if ($.isEmptyObject(data) || data.totalPage === 0) {
this.busy = true;
} else {
if (data.totalPage && this.page === data.totalPage) {
this.busy = true;
} else {
this.busy = false;
}
const list = data.data || [];
list.forEach(o => {
if (!this.keys[o.id]) {
this.keys[o.id] = true;
this.articleData.push({
fav_id: o.id,
src: o.src,
title: o.title,
intro: o.intro,
publish_time: o.publish_time
});
}
});
}
this.nullbox = this.articleData.length ? 'hide' : '';
if (this.page === 1) {
yoho.showLoading(false);
this.updateNavBar();
}
}).fail(() => {
tip('网络错误');
});
},
showDelBtn(id) {
this.hideDelBth();
let delBtn = $('#del-' + id);
let width = delBtn.width();
$('#li-' + id).css('transform', 'translateX(-' + width + 'px)');
delBtn.removeClass('hide');
this.pandata.id = id;
this.pandata.objX = -width;
},
hideDelBth() {
this.articleData.forEach(d => {
$('#li-' + d.fav_id).css('transform', 'translateX(0px)');
$('#del-' + d.fav_id).addClass('hide');
});
this.pandata = {};
},
delItem(index, id) {
$.ajax({
method: 'POST',
url: '/me/del-favdel',
data: {
favId: id,
type: 'article'
}
}).then(data => {
if (data.code === 200) {
this.articleData.splice(index, 1);
this.hideDelBth();
delete this.keys[id];
if (this.articleData.length === 0) {
this.nullbox = '';
this.updateNavBar();
}
} else if (data.code === 400) {
tip(data.message);
} else {
tip('刪除收藏失败');
}
}).fail(() => {
tip('网络错误');
});
},
panstart(id) {
event.preventDefault();
if (this.pandata.id && this.pandata.id !== id) {
$('#li-' + this.pandata.id).css('transform', 'translateX(0px)');
$('#del-' + this.pandata.id).addClass('hide');
return false;
} else {
this.pageX = event.targetTouches[0].pageX;
let delBtn = $('#del-' + id);
if (delBtn.hasClass('hide')) {
delBtn.removeClass('hide');
this.pandata.objX = 0;
this.pandata.id = id;
}
}
},
panmove(id) {
event.preventDefault();
if (this.pandata.id && this.pandata.id !== id) {
return false;
}
let li = $('#li-' + id);
let width = $('#del-' + id).width();
let moveX = event.targetTouches[0].pageX;
let X = moveX - this.pageX;
if (this.pandata.objX === 0) {
if (X >= 0) {
this.currentX = 0;
} else {
this.currentX = -Math.min(Math.abs(X), width);
}
li.css('transform', 'translateX(' + this.currentX + 'px)');
} else if (this.pandata.objX < 0) {
if (X >= 0) {
this.currentX = Math.min(Math.abs(X) - width, 0);
} else {
this.currentX = -width;
}
li.css('transform', 'translateX(' + this.currentX + 'px)');
}
},
panend(id) {
event.preventDefault();
if (this.pandata.id && this.pandata.id !== id) {
this.pandata = {};
return false;
}
let li = $('#li-' + id);
let delBtn = $('#del-' + id);
let width = delBtn.width();
if (this.currentX > -(width / 2)) {
this.pandata.objX = 0;
delBtn.addClass('hide');
} else {
this.pandata.objX = -width;
}
li.css('transform', 'translateX(' + this.pandata.objX + 'px)');
if (this.pandata.objX === 0) {
this.pandata = {};
}
},
updateNavBar() {
const header = Object.assign({}, interceptClick.defaultTitleMap[5]);
header.defaultSelectedIndex = '1';
header.right.des = this.editmodel ? '完成' : '编辑';
if (!this.articleData.length) {
header.right.des = '';
}
yoho.updateNavigationBar({
header: header
});
}
}
};
</script>
<style>
.yoho-favorite-article-page {
width: 100%;
height: auto;
.fav-content {
.fav-type {
display: block;
}
.fav-article-list {
list-style: none;
overflow: hidden;
li {
display: flex;
align-items: center;
position: relative;
border-bottom: 1px solid #e0e0e0;
}
.fav-del-left {
display: none;
width: 50px;
height: 100%;
.fav-del-span {
display: inline-block;
width: 35px;
height: 35px;
margin-right: 15px;
margin-top: 50px;
}
.icon-edit-del {
color: red;
font-size: 35px;
}
}
.editorial-box {
background: #f6f6f6;
border-bottom: #eee 1px solid;
padding-top: 30px;
float: 1;
a {
display: block;
}
.img {
width: 100%;
height: 470px;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
.title {
background: #fff;
font-size: 42px;
line-height: 1.2;
font-weight: 700;
padding: 30px;
}
.editorial-des {
background: #fff;
padding: 0 30px 30px;
color: #b0b0b0;
font-size: 28px;
line-height: 32px;
}
hr {
margin: 0 30px;
border: #eee 1px solid;
border-bottom: 0;
}
.bottom {
padding: 10px 30px;
background: #fff;
color: #b0b0b0;
font-size: 24px;
height: 78px;
span {
display: inline-block;
padding: 12px 0;
}
.share {
float: right;
padding-top: 16px;
}
}
}
.delshow {
display: block;
}
.fav-del-right {
position: absolute;
top: 30px;
right: -126px;
background: #ff3b30;
width: 126px;
height: 100%;
text-align: center;
.span-delete {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.icon-delete {
display: inline-block;
color: white;
font-size: 35px;
margin-top: 30px;
}
.fav-del-txt {
font-size: 24px;
color: #fff;
}
.hide {
display: none;
}
}
}
.fav-null {
font-size: 22px;
color: #444;
display: block;
margin-top: 100px;
text-align: center;
&:before {
content: "";
display: block;
width: 188px;
height: 171px;
background: resolve("me/fav-null.png");
background-size: 100% 100%;
margin: 0 auto 45px;
}
}
.go-shopping {
width: 472px;
height: 88px;
line-height: 88px;
margin: 80px auto 0;
background: #444;
text-align: center;
color: #fff;
display: block;
font-size: 26px;
border-radius: 0.2rem;
}
}
}
</style>
... ...
... ... @@ -46,12 +46,8 @@
</div>
<div class="group-list">
<a class="glist-item auth" href="/me/collection">
收藏的商品
<span class="num">{{data.product_favorite_total}} <span class="icon icon-right"></span></span>
</a>
<a class="glist-item auth" href="/me/collection?tab=brand">
收藏的品牌
<span class="num">{{data.brand_favorite_total}} <span class="icon icon-right"></span></span>
我的收藏
<span class="num">商品/品牌/资讯 <span class="icon icon-right"></span></span>
</a>
<a class="glist-item auth" href="/me/records?type={{recordNum}}">
浏览记录
... ...
... ... @@ -47,7 +47,10 @@
</ul>
</div>
<div class="order-button" v-show="order.status != 1 && order.status != 2 && order.status != 3">
<button v-if="order.is_cancel === 'Y'" @click="deleteOrder(order.order_code)" class="normal">删除订单</button>
<template v-if="order.is_cancel === 'Y'">
<button @click="deleteOrder(order.order_code)" class="leftpad">删除订单</button>
<button @click="readdOrder(order)" class="normal">再次购买</button>
</template>
<template v-else>
<button v-if="order.status == 0" @click="cancelOrder()">取消订单</button>
<button v-if="order.status == 0 " class="countdown" @click="goBuy(order)">去支付 <span class="count-down" v-count-down :left-time="order.pay_lefttime" :callback="autoCancel()"></span></button>
... ... @@ -256,6 +259,23 @@
yoho.store.set('orderReload', true);
});
},
readdOrder(order) {
$.post('/me/readdorder', {
orderCode: order.order_code
}).then((result)=> {
tip({
txt: result.message,
delay: 1000
}, ()=> {
if (result.code === 200) {
if (yoho.goShopingKey && result.data && result.data.shopping_key) {
yoho.goShopingKey({shoppingKey: result.data.shopping_key});
}
yoho.goShopingCart();
}
});
});
},
applyRefund() {
this.genderSel.show(item => {
if (item.url) {
... ...
... ... @@ -4,7 +4,7 @@
<li class="order-item" v-for="(index, order) in orderList">
<div class="order-detail">
<div class="order-code">
<p>订单号:{{order.order_code}}</p>
<p>订单号:{{order.order_code}}<span v-if="order.order_type === 7" class="exchange">换货</span></p>
<p v-if="order.is_cancel === 'Y'">交易已取消</p>
<p v-else>{{order.status | convertOrderState}}</p>
</div>
... ... @@ -32,7 +32,10 @@
<div class="order-option">
<div class="goods-total">合计 <b>&yen;{{order.amount}}</b></div>
<div class="options">
<button v-if="order.is_cancel === 'Y'" @click="deleteOrder(order, index)" class="normal">删除订单</button>
<template v-if="order.is_cancel === 'Y'">
<button @click="deleteOrder(order, index)" class="leftpad">删除订单</button>
<button @click="readdOrder(order)" class="normal">再次购买</button>
</template>
<template v-else>
<button v-if="order.status == 0" @click="cancelOrder(order)" class="leftpad">取消订单</button>
<button v-if="order.status == 0 " class="countdown" @click="goBuy(order)">去支付
... ... @@ -237,6 +240,23 @@
}, () => {
this.reload();
});
},
readdOrder(order) {
$.post('/me/readdorder', {
orderCode: order.order_code
}).then((result)=> {
tip({
txt: result.message,
delay: 1000
}, ()=> {
if (result.code === 200) {
if (yoho.goShopingKey && result.data && result.data.shopping_key) {
yoho.goShopingKey({shoppingKey: result.data.shopping_key});
}
yoho.goShopingCart();
}
});
});
}
}
};
... ...
... ... @@ -17,74 +17,4 @@
reason, product
}
};
</script>
<style>
.product {
position: relative;
padding: 0 30px;
height: 170px;
font-size: 24px;
line-height: 1.5;
background: #fff;
&:after {
content: "";
position: absolute;
left: 30px;
bottom: -1px;
width: 690px;
height: 0;
border-bottom: 1px solid #eee;
z-index: 1;
}
.checkbox {
float: left;
margin-top: 67px;
label:before {
border-radius: 100%;
}
}
.image {
float: left;
margin: 20px;
width: 100px;
height: 130px;
}
.info {
padding: 15px 0;
width: 520px;
.p-title {
color: #000;
font-size: 24px;
height: 72px;
overflow: hidden;
}
.meta {
margin-top: 10px;
color: #b0b0b0;
}
.color {
margin-right: 30px;
}
}
.price {
position: absolute;
top: 15px;
right: 30px;
text-align: right;
.num {
color: #b0b0b0;
}
}
}
</style>
</script>
\ No newline at end of file
... ...
<template>
<div class="product clearfix">
<div class="checkbox">
<div class="checkbox" v-if="product.is_limit_skn !== 'Y'">
<input type="checkbox" v-model="product.checked" id="checkbox-{{product.goods_id}}">
<label for="checkbox-{{product.goods_id}}"></label>
</div>
... ... @@ -20,10 +20,14 @@
x1
</p>
</div>
<div v-if="product.is_limit_skn === 'Y'" @click="showTip" class="tip">
<span class="icon icon-question"></span><span>不支持7天无理由退换货</span>
</div>
</div>
</template>
<script>
const modal = require('common/modal');
module.exports = {
props: {
... ... @@ -35,7 +39,12 @@
if (!this.product.hasOwnProperty('checked')) {
this.$set('product.checked', false);
}
}
},
methods: {
showTip() {
modal.alert('该商品非质量问题不支持退换货,如有疑问请联系在线客服', '不支持无理由退换');
}
},
};
</script>
... ... @@ -44,7 +53,7 @@
.product {
position: relative;
padding: 0 30px;
height: 170px;
min-height: 170px;
font-size: 24px;
line-height: 1.5;
background: #fff;
... ... @@ -67,7 +76,8 @@
}
.image {
float: left;
margin: 20px;
margin: 0 20px;
margin-top: 20px;
width: 100px;
height: 130px;
}
... ... @@ -97,6 +107,25 @@
color: #b0b0b0;
}
}
}
.tip {
position: relative;
height: 70px;
padding: 10px 30px;
font-size: 26px;
background: #fff;
.icon {
margin-right: 15px;
}
&:after {
content: "";
position: absolute;
left: 0;
bottom: -1px;
width: 690px;
height: 0;
border-bottom: 1px solid #eee;
}
}
}
</style>
... ...
<template>
<div v-if="product.checked" class="reason">
<div v-if="product.is_limit_skn === 'Y'" @click="showTip" class="tip">
<span class="icon icon-love"></span>
{{specialNotice.title}}
</div>
<div class="select-reason">
<slot name="type">退货原因</slot>
... ... @@ -39,8 +35,7 @@
return {
bucket: 'evidenceImages',
reasons: [],
specialReasons: [],
specialNotice: {}
specialReasons: []
};
},
computed: {
... ... @@ -58,9 +53,6 @@
}
},
methods: {
showTip() {
modal.alert(this.specialNotice.remark);
},
deleteImage(index) {
this.product.imageList.splice(index, 1);
}
... ... @@ -72,7 +64,6 @@
created() {
this.$set('reasons', reasonConfig.reasons);
this.$set('specialReasons', reasonConfig.specialReasons);
this.$set('specialNotice', reasonConfig.specialNotice);
}
};
... ... @@ -91,24 +82,6 @@
height: 30px;
}
.tip {
position: relative;
padding: 0 30px;
font-size: 26px;
background: #fff;
.icon {
margin-right: 5px;
}
&:after {
content: "";
position: absolute;
left: 0;
bottom: -1px;
width: 690px;
height: 0;
border-bottom: 1px solid #eee;
}
}
.select-reason {
position: relative;
padding: 0 30px;
... ...