Authored by 沈志敏

个人中心

... ... @@ -4,6 +4,7 @@
* @date: 2016/07/18
*/
'use strict';
const homeModel = require('../models/index');
const _ = require('lodash');
const helpers = global.yoho.helpers;
... ... @@ -12,20 +13,95 @@ const helpers = global.yoho.helpers;
*/
const component = {
index: (req, res, next) => {
var testData = {
isLogin: false,
head_ico: '',
profile_name: 'XXX',
signinUrl: '/home',
wait_pay_num: 1,
wait_cargo_num: 2,
send_cargo_num: 3
let uid = req.user.uid;
if (!uid && req.xhr) {
return res.json({
code: 400,
message: '抱歉,您暂未登录!'
});
}
homeModel.getUserHomeData(uid).then(data => {
let result = {
module: 'home',
page: 'index',
head_ico: uid ? '' : '',
profile_name: uid ? 'James Sen' : '登录/注册',
userinfourl: uid ? '/home/mydetails' : helpers.urlFormat('/signin.html', {
refer: req.originalUrl
}),
};
res.render('index', _.merge(result, data[1]));
}).catch(next);
},
help: (req, res, next) => {
homeModel.getHelpInfo().then(helpList => {
res.render('help', {
module: 'home',
page: 'help',
helpList: helpList
});
}).catch(next);
},
helpDetail: (req, res, next) => {
var helpDetailPara = {
code: req.query.code,
caption: req.query.caption
};
res.render('index', _.merge({
homeModel.getHelpDetail(helpDetailPara).then(helpDetail => {
res.render('help-detail', {
module: 'home',
page: 'help',
helpDetail: helpDetail
});
}).catch(next);
},
favorite: (req, res, next) => {
let tab = req.query.tab;
let testData = {
brandUrl: helpers.urlFormat('/product/new'),
productUrl: helpers.urlFormat('/product/new')
}
res.render('favorite', _.merge({
module: 'home',
page: 'index'
page: 'favorite',
}, testData));
},
favpaging: (req, res, next) => {
let tab = req.query.tab;
let page = req.query.page;
console.log("page: " + page);
if (tab === 'brand') {
}
if (page > 3) return res.json([]);
let testData = []
for (var i = 1; i <= 9; i++) {
testData.push({
fav_id: Number(page + i),
title: "商品名测试测试测试测试测试测试测试测试" + Number(page + i),
invalidGoods: true,
discountPrice: '¥' + 900,
price: '¥' + 990
})
}
return res.json(testData);
},
favdel: (req, res, next) => {
let id = req.body.id;
return res.json({
code: 200
});
}
};
module.exports = component;
module.exports = component;
\ No newline at end of file
... ...
'use strict';
const api = global.yoho.API;
const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const helpers = global.yoho.helpers;
/**
* 处理用户个人详情数据
*
* @param int uid 用户ID
* @return Object 处理之后的个人详情数据
*/
const _getUserProfileData = (uid) => {
return co(function*() {
// 调用接口获取个人详情
const data = {};
return data;
// return api.get('operations/api/v5/resource/get', {
// uid: uid
// }, {
// cache: true,
// code: 200
// });
})();
};
/**
* 处理个人中心页面优惠券,收藏的商品等的数目数据
*
* @param int uid 用户ID
* @return Object 处理之后的个人中心页面收藏的商品等的数目数据
*/
const _getInfoNumData = (uid) => {
return co(function*() {
const data = {
wait_pay_num: 1,
wait_cargo_num: 2,
send_cargo_num: 3,
address_num: 4,
product_favorite_total: 5,
brand_favorite_total: 6,
yoho_coin_num: 7
};
return data;
})();
};
exports.getUserHomeData = (uid) => {
return Promise.all([_getUserProfileData(uid), _getInfoNumData(uid)]);
};
const helpListDataProc = (helpData) => {
const formatData = [];
helpData = helpData || [];
_.forEach(helpData, (item) => {
formatData.push({
name: item.caption,
code: item.code,
url: helpers.urlFormat('/home/helpDetail', {
code: item.code,
caption: item.caption,
})
});
});
return formatData;
};
/**
* 帮助中心列表页
*
* @param data
*
*/
exports.getHelpInfo = (data) => {
var defaultParam = {
method: 'app.help.li'
},
infoData = Object.assign(defaultParam, data);
return api.get('', infoData).then(result => {
return helpListDataProc(result.data);
});
};
/**
* 帮助中心详情页
*
* @param data
*/
exports.getHelpDetail = (data) => {
var defaultParam = {
method: 'app.help.detail',
return_type: 'html'
},
detailData = Object.assign(defaultParam, data);
return api.get('', detailData).then(result => {
return result;
});
};
... ...
... ... @@ -13,4 +13,12 @@ const home = require(cRoot);
// Your controller here
router.get('/', home.index); // 个人中心主页
module.exports = router;
router.get('/help', home.help); // 帮助中心列表页
router.get('/helpDetail', home.helpDetail); // 帮助中心详情页
router.get('/favorite', home.favorite); // 个人中心 - 收藏
router.get('/favorite/favpaging', home.favpaging); // 个人中心 - 收藏商品/品牌(翻页)
router.post('/favorite/favdel', home.favdel); // 个人中心 - 收藏商品/品牌(刪除)
module.exports = router; >>> >>> > feature / home
\ No newline at end of file
... ...
<div class="yoho-favorite-page yoho-page">
<div class="fav-content" id="fav-content">
<fav-product-list product-url={{productUrl}}></fav-product-list>
</div>
</div>
\ No newline at end of file
... ...
<div class="help">
<ul>
{{# helpList}}
<li><a href="{{url}}"><span>{{ name}}</span><i class="icon num">&#xe607;</i></a></li>
{{/ helpList}}
</ul>
</div>
... ...
<div class="my-page yoho-page">
<div class="my-header">
{{#isLogin}}
<a class="user-info" href="/home/mydetails">
<a class="user-info" href={{userinfourl}}>
<span class="user-avatar" data-avatar="{{head_ico}}"></span>
<br><span class="username">{{profile_name}}</span>
</a>
{{/isLogin}}
{{^isLogin}}
<div class="user-info">
<a class="login-btn" href="{{signinUrl}}">
登录/注册
</a>
</div>
{{/isLogin}}
</div>
<div class="my-order">
<a class="order-title" href="/home/orders">
我的订单
<span>
<span class="read-order">
查看全部订单 <span class="icon icon-right"></span>
</span>
</a>
... ... @@ -55,23 +46,23 @@
<div class="group-list">
<a class="list-item" href="/home/address">
地址管理
<span class="num">3 <span class="icon icon-right"></span></span>
<span class="num">{{address_num}} <span class="icon icon-right"></span></span>
</a>
</div>
<div class="group-list">
<a class="list-item" href="/home/favorite">
收藏的商品
<span class="num">120 <span class="icon icon-right"></span></span>
<span class="num">{{product_favorite_total}} <span class="icon icon-right"></span></span>
</a>
<a class="list-item" href="/home/favorite?tab=brand">
收藏的品牌
<span class="num">100 <span class="icon icon-right"></span></span>
<span class="num">{{brand_favorite_total}} <span class="icon icon-right"></span></span>
</a>
</div>
<div class="group-list">
<a class="list-item" href="/home/mycurrency">
YOHO 币
<span class="num">100 <span class="icon icon-right"></span></span>
<span class="num">{{yoho_coin_num}} <span class="icon icon-right"></span></span>
</a>
</div>
<div class="group-list">
... ...
const Vue = require('yoho-vue');
const infiniteScroll = require('yoho-vue-infinite-scroll');
const ProductList = require('home/fav-product-list.vue');
Vue.use(infiniteScroll)
new Vue({
el: '#fav-content',
components: {
'fav-product-list': ProductList
}
});
\ No newline at end of file
... ...
.yoho-favorite-page {
width: 100%;
height: auto;
.fav-content {
.fav-type {
display: none;
}
.show {
display: block;
}
.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("home/fav/fav-null.png");
background-size: 100% 100%;
margin: 0 auto 45px auto;
}
}
.go-shopping {
width: 472px;
height: 88px;
line-height: 88px;
margin: 80px auto 0 auto;
background: #444;
text-align: center;
color: #fff;
display: block;
font-size: 26px;
border-radius:.2rem;
}
.fav-product-list {
list-style: none;
li {
height: auto;
overflow: hidden;
margin-top: 20px;
}
.fav-del {
float: left;
display: none;
}
.show {
display: block;
}
.delhide {
display: block;
}
.fav-img-box {
width: 152px;
height: 203px;
float: left;
margin-right: 24px;
img {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
}
}
.fav-info-list {
color: #444;
font-size: 24px;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 20px;
margin-right: 5px;
height: 203px;
overflow: hidden;
position: relative;
.title {
width: 430px;
text-overflow: ellipsis;
font-size: 28px;
margin: 0;
}
.fav-price {
margin-top: 20px;
.new-price {
color: #d1021c;
font-size: 24px;
}
.price-underline {
text-decoration: line-through;
margin-left: 15px;
color: #b0b0b0;
font-size: 24px;
}
}
.save-price {
position: absolute;
bottom: 20px;
left: 0;
width: 100%;
min-height: 24px;
span {
&.sell-out {
float: right;
padding: 5px 18px;
color: #b0b0b0;
border-radius: 20px;
font-size: 22px;
}
}
}
}
}
}
}
\ No newline at end of file
... ...
.help {
width: 100%;
height: auto;
overflow: hidden;
ul {
width: 100%;
height: auto;
overflow: hidden;
display: block;
border-top: 1px solid #e0e0e0;
padding-left: 0;
margin: 0;
li {
width: 100%;
height: 80px;
line-height: 84px;
overflow: hidden;
font-size: 28px;
border-bottom: 1px solid #e0e0e0;
float: right;
color: #444;
list-style: none;
&:last-of-type {
border-bottom: none;
}
a:visited {
color: #444;
}
span {
width: 90%;
height: 100%;
overflow: hidden;
float: left;
padding-left: 5%;
}
i {
color: #e0e0e0;
}
}
}
.iconfont {
color: #fff;
}
}
... ...
.my-page {
color: #444;
background: #f0f0f0;
a {
color: #000;
}
.user-info {
display: block;
position: relative;
padding: 0 30px;
color: #000;
font-size: 34px;
line-height: 138px;
height: 469px;
background-size: cover;
background: resolve("home/header-bg.png");
text-align: center;
.user-avatar {
display: inline-block;
position: relative;
top: 90px;
width: 200px;
height: 200px;
border-radius: 50%;
border: 6px solid #a7a8a9;
background: resolve("home/user-icon.png");
background-size: 100%;
}
.username {
display: inline-block;
padding: 0 16px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-size: 32px;
max-width: 260px;
}
}
.login-btn {
display: inline-block;
top: 40px;
left: 194px;
width: 244px;
height: 82px;
line-height: 82px;
color: #fff;
border: 4px solid #fff;
margin: 150px auto;
}
.my-order {
margin-bottom: 30px;
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
background: #fff;
.order-title {
display: block;
padding: 0 29px;
font-size: 34px;
line-height: 88px;
span {
color: #e0e0e0;
float: right;
}
&.highlight {
background: #eee;
}
.read-order {
font-size: 30px;
}
}
.order-type {
padding: 20px 30px;
text-align: center;
border-top: 1px solid #e0e0e0;
.type-item {
position: relative;
float: left;
color: #444;
font-size: 24px;
line-height: 1.5;
width: 170px;
&.highlight {
background: #eee;
}
.num {
position: absolute;
top: -24px;
right: 36px;
width: 72px;
height: 72px;
font-size: 34px;
line-height: 72px;
color: #fff;
background: #f03d35;
text-align: center;
border-radius: 50%;
transform: scale(0.5);
}
}
}
}
.group-list {
margin-bottom: 30px;
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
background: #fff;
.list-item {
display: block;
position: relative;
padding: 0 30px;
font-size: 34px;
line-height: 90px;
overflow: hidden;
&.highlight {
background: #eee;
}
&:after {
content: "";
position: absolute;
right: 0;
bottom: 0;
width: 100%;
height: 0;
border-top: 1px solid #f0f0f0;
}
&:last-child:after {
content: none;
}
}
.icon {
margin-right: 5px;
font-size: 34px;
vertical-align: top;
}
.num {
color: #b0b0b0;
float: right;
}
}
}
... ...
.my-page {
color: #444;
background: #f0f0f0;
a {
color: #444;
}
.user-info {
display: block;
position: relative;
padding: 0 30px;
color: #fff;
font-size: 34px;
line-height: 138px;
height: 449px;
background-size: cover;
background: #444;
/*background: resolve("home/header-bg.jpg"); */
text-align: center;
.user-avatar {
display: inline-block;
position: relative;
top: 88px;
width: 200px;
height: 200px;
border-radius: 50%;
border: 6px solid #a7a8a9;
background: #a7a8a9;
background-size: 100%;
}
.username {
display: inline-block;
padding: 0 16px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 260px;
}
}
.login-btn {
display: inline-block;
top: 40px;
left: 194px;
width: 244px;
height: 82px;
line-height: 82px;
color: #fff;
border: 4px solid #fff;
margin: 120px auto;
}
.my-order {
margin-bottom: 30px;
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
background: #fff;
.order-title {
display: block;
padding: 0 30px;
font-size: 16PX;
line-height: 88px;
span {
color: #e0e0e0;
float: right;
}
&.highlight {
background: #eee;
}
}
.order-type {
padding: 20px 30px;
text-align: center;
border-top: 1px solid #e0e0e0;
.type-item {
position: relative;
float: left;
color: #444;
font-size: 14PX;
line-height: 1.5;
width: 170px;
&.highlight {
background: #eee;
}
.num {
position: absolute;
top: -24px;
right: 36px;
width: 72px;
height: 72px;
font-size: 40px;
line-height: 72px;
color: #fff;
background: #f03d35;
text-align: center;
border-radius: 50%;
transform: scale(0.5);
}
}
}
}
.group-list {
margin-bottom: 30px;
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
background: #fff;
.list-item {
display: block;
position: relative;
padding: 0 30px;
font-size: 16PX;
line-height: 90px;
&.highlight {
background: #eee;
}
&:after {
content: '';
position: absolute;
right: 0;
bottom: 0;
width: 100%;
height: 0;
border-top: 1px solid #f0f0f0;
}
&:last-child:after {
content: none;
}
}
.icon {
margin-right: 5px;
font-size: 30px;
vertical-align: top;
}
.num {
color: #e0e0e0;
float: right;
}
}
}
@import "home";
@import "help";
@import "fav";
... ...
<template>
<div class="fav-type show" v-infinite-scroll="loadMore()" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
<ul class="fav-product-list">
<li v-for="item in productData" track-by="fav_id">
<div class="fav-del {{editmodel ? 'show': ''}}">
<button @click="delProduct($index, item.fav_id)">删除</button>
</div>
<a :href="item.link">
<div class="fav-img-box">
<img :src="item.imgUrl" alt=""/>
</div>
<div class="fav-info-list">
<span class="title">{{item.title}}</span>
<br/>
<div class="fav-price">
<span class="new-price" v-if="item.discountPrice">{{item.discountPrice}}</span>
<span class="fav-price {{ item.discountPrice ? 'price-underline' : ''}}">{{item.price}}</span>
</div>
<br/>
<div class="save-price">
<span class="sell-out" v-if="item.sellOut || item.invalidGoods">{{item.sellOut ? '已售罄' : '已下架'}}</span>
</div>
</div>
</a>
</li>
</ul>
<div class="fav-null-box {{ nullbox }}">
<span class="fav-null">您暂无收藏任何商品}}</span>
<a slot="go-shopping" class="go-shopping" :href="productUrl">随便逛逛</a>
</div>
</div>
</template>
<script>
const $ = require('yoho-jquery');
const tip = require('common/tip');
const Loading = require('common/loading');
const modal = require('common/modal');
const loading = new Loading();
module.exports = {
props: ['productUrl'],
data() {
return {
nullbox : 'hide',
busy: false,
editmodel: false,
page: 0,
productData: []
};
},
methods: {
loadMore: function() {
loading.show();
let _this = this;
this.busy = true;
$.ajax({
url: '/home/favorite/favpaging',
data: {
page : ++_this.page
}
}).then(result => {
if (result.length) {
result.forEach(function(o){
_this.productData.push(o);
});
_this.busy = false;
} else {
_this.busy = true;
}
_this.nullbox = _this.productData.length ? "hide" : "";
loading.hide();
}).fail(() => {
tip('网络错误');
});
},
editProduct(action) {
this.editmodel = action;
},
delProduct(index, id) {
let _this = this;
$.modal.confirm('', '确定刪除该收藏吗?', function() {
this.hide();
$.ajax({
method: 'post',
url: '/home/favorite/favdel',
data: {
id: id
}
}).then(function(data) {
if (data.code === 200) {
_this.productData.splice(index, 1);
} else if (data.code === 400) {
$.modal.alert(data.message, '出错了!');
} else {
$.modal.alert('', '取消收藏失败');
}
}).fail(function() {
$.modal.alert('', '网络错误');
});
});
}
}
};
</script>
... ...