Authored by ccbikai

Merge branch 'develop' of git.yoho.cn:fe/yohoblk-wap into develop

... ... @@ -35,10 +35,10 @@ exports.subFilter = (req, res) => {
exports.fetchFilters = (req, res, next) => {
const params = {
uid: 14741796, // mock data
page: req.body.page || 1,
order: req.body.order || 1,
yh_channel: req.body.yh_channel || 'all',
channel: req.body.channel || 'all',
page: req.query.page || 1,
order: req.query.order || 1,
yh_channel: req.query.yh_channel || 'all',
channel: req.query.channel || 'all',
};
const data = _.merge({
... ... @@ -65,14 +65,14 @@ exports.fetchFilters = (req, res, next) => {
.catch(next);
};
/* 查询 产品列表 */
/* 查询 产品列表 method:GET */
exports.fetchProducts = (req, res, next) => {
const params = {
uid: 14741796, // mock data
page: req.body.page || 1,
order: req.body.order || 1,
yh_channel: req.body.yh_channel || 'all',
channel: req.body.channel || 'all',
page: req.query.page || 1,
order: req.query.order || 1,
yh_channel: req.query.yh_channel || 'all',
channel: req.query.channel || 'all',
};
const data = _.merge({
... ...
... ... @@ -3,7 +3,7 @@ const $ = require('yoho-jquery');
const search = require('product/list/index.vue');
$(function() {
const buildSort = function() {
const buildOrder = function() {
return [
{
txt: '默认',
... ... @@ -26,5 +26,5 @@ $(function() {
let app = new Vue(search);
app.sortConfig = buildSort();
app.orderConfig = buildOrder();
});
... ...
... ... @@ -3,7 +3,7 @@ const $ = require('yoho-jquery');
const search = require('product/search/index.vue');
$(function() {
const buildSort = function() {
const buildOrder = function() {
return [
{
txt: '默认',
... ... @@ -26,5 +26,5 @@ $(function() {
let app = new Vue(search);
app.$set('sortConfig', buildSort());
app.$set('orderConfig', buildOrder());
});
... ...
<template>
<div class="header">
<div class="header-left">
<slot name="left">
<i class="icon icon-left" @click="goBack"></i>
</slot>
</div>
<div class="header-right">
<slot name="right"></slot>
</div>
<div class="header-main">
<span class="header-title">{{title}}</span>
</div>
</div>
<div class="header-gap"></div>
</template>
<script>
const yoho = require('yoho');
const $ = require('yoho-jquery');
const tip = require('common/tip');
module.exports = {
props: ['title'],
methods: {
goBack() {
yoho.goBack({}, function() {}, function() {});
}
}
}
</script>
<style>
.header {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 210;
padding-left: 30px;
padding-right: 30px;
width: 100%;
height: 60px;
line-height: 60px;
font-size: 48px;
background-color: #fff;
.icon, .header-title {
vertical-align: middle;
}
}
.header-main {
display: block;
text-align: center;
margin-left: auto;
margin-right: auto;
}
.header-left {
float: left;
}
.header-right {
float: right;
.icon {
margin-left: 30px;
}
}
.header-gap {
height: 60px;
}
</style>
\ No newline at end of file
... ...
<template>
<div class="drawer" :class="{'drawer-open': on }" v-show="on">
<div class="drawer-main" v-el:main>
<slot></slot>
</div>
<div class="drawer-mask" @click="close"></div>
</div>
</template>
<script>
module.exports = {
props: {
on: Boolean
},
methods: {
close() {
this.on = false;
}
},
watch: {
on(newVal) {
if(newVal) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
}
}
};
</script>
<style>
.drawer {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.drawer-mask {
position: absolute;
z-index: 199;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.6);
}
.drawer-main {
position: absolute;
z-index: 200;
top: 0;
right: 0%;
bottom: 0;
min-width: 80%;
max-width: 100%;
background-color: #fff;
transition: all 0.3s 0.2s;
}
</style>
<template>
<div class="filter">
<div class="filter" :class="{ 'filter-open': isVisible}">
<div class="filter-actions">
<a href="javascript:;" class="filter-action" @click="clearVals">清空</a>
<button class="button button-small filter-action" @click="okAction">确定</button>
... ... @@ -16,134 +16,169 @@
</div>
</template>
<script>
const $ = require('yoho-jquery');
const bus = require('common/vue-bus');
module.exports = {
props: {
config: Object
},
data: function() {
return {
// 选择的值
params: {},
// 确定的值
selected: {}
};
},
watch: {},
methods: {
clearVals: function() {
// remove all value
this.$set('params', {});
const $ = require('yoho-jquery');
const bus = require('common/vue-bus');
const Overlay = require('common/overlay');
module.exports = {
props: {
config: Object,
isVisible: Boolean
},
data: function() {
return {
// 选择的值
params: {},
/**
* 当二级筛选, 返回数据时, 调用该方法
* @param {[type]} cate [description]
* @param {[type]} val [description]
*/
setCateParams: function(cate, val) {
this.$set(`params.${cate}`, val);
// 确定的值
selected: {}
};
},
okAction: function() {
bus.$emit('filter.change', {
val: this.params,
ref: this._uid
});
watch: {
isVisible(newVal) {
if (newVal) {
this.overlay.show();
} else {
this.overlay.hide();
}
}
},
entrySub: function(key) {
bus.$emit('filter.sub.show', {
val: key,
ref: this._uid
});
}
},
filters: {
unifyTxt: function(val, category) {
let txt = '';
let arr = [];
let foo = $.noop;
if ($.isArray(val)) { // [{categoryName,..},{}..]
foo = (index, obj) => {
arr.push(obj[category + 'Name']);
};
methods: {
clearVals: function() {
// remove all value
this.$set('params', {});
},
/**
* 当二级筛选, 返回数据时, 调用该方法
* @param {[type]} cate [description]
* @param {[type]} val [description]
*/
setCateParams: function(cate, val) {
this.$set(`params.${cate}`, val);
},
okAction: function() {
bus.$emit('filter.change', {
val: this.params,
ref: this._uid
});
},
entrySub: function(key) {
bus.$emit('filter.sub.show', {
val: key,
ref: this._uid
});
}
$.each(val, foo);
txt = arr.join(',');
return txt;
},
txt: function(val) {
const dict = {
color: 'Color颜色',
gender: 'Gender性别',
size: 'Size尺寸',
brand: 'Brand品牌',
priceRange: 'Price价格',
groupSort: 'Category品类',
discount: 'Sale折扣'
};
filters: {
unifyTxt: function(val, category) {
let txt = '';
let arr = [];
let foo = $.noop;
if ($.isArray(val)) { // [{categoryName,..},{}..]
foo = (index, obj) => {
arr.push(obj[category + 'Name']);
};
}
$.each(val, foo);
txt = arr.join(',');
return txt;
},
txt: function(val) {
const dict = {
color: 'Color颜色',
gender: 'Gender性别',
size: 'Size尺寸',
brand: 'Brand品牌',
priceRange: 'Price价格',
groupSort: 'Category品类',
discount: 'Sale折扣'
};
return dict[val] || '';
return dict[val] || '';
}
},
created () {
const self = this;
this.overlay = new Overlay({
disableScrolling: true,
onClose: function() {
self.isVisible = false;
}
});
}
}
};
};
</script>
<style>
@import "../../../scss/common/color";
.filter {
padding: 0 30px;
}
.filter-actions {
font-size: 34px;
text-align: right;
padding: 45px 0;
}
.filter-action {
font-size: inherit;
margin-left: 40px;
}
.filter-actions,
.filter-cate {
border-bottom: 1px solid $grey;
}
.filter-cates {
list-style: none;
margin: 0;
padding: 0;
}
.filter-cate .icon-right {
margin-left: 24px;
}
.filter-cate,
.icon-right {
height: 118px;
line-height: 118px;
}
.filter-cate-label {
font-size: 36px;
font-weight: bold;
}
.filter-cate-val {
float: right;
font-size: 28px;
}
@import "../../../scss/common/color";
.filter {
position: fixed;
z-index: 1001;
top: 0;
right: 0;
bottom: 0;
left: 20%;
background-color: #fff;
transform: translate3d(100%, 0, 0);
transition: all 0.3s 0.2s;
padding: 0 30px;
&.filter-open {
transform: translate3d(0, 0, 0);
}
}
.filter-actions {
font-size: 34px;
text-align: right;
padding: 45px 0;
}
.filter-action {
font-size: inherit;
margin-left: 40px;
}
.filter-actions,
.filter-cate {
border-bottom: 1px solid $grey;
}
.filter-cates {
list-style: none;
margin: 0;
padding: 0;
}
.filter-cate .icon-right {
margin-left: 24px;
}
.filter-cate,
.icon-right {
height: 118px;
line-height: 118px;
}
.filter-cate-label {
font-size: 36px;
font-weight: bold;
}
.filter-cate-val {
float: right;
font-size: 28px;
}
.filter-cate-val,
.filter-cate .icon {
color: $grey;
}
.filter-cate-val,
.filter-cate .icon {
color: $grey;
}
</style>
... ...
<template>
<ul class="sort-navs clearfix">
<ul class="order-navs clearfix">
<template v-for="item in config">
<simple v-if="(item.type || 'simple') === 'simple'" :txt="item.txt" :val="item.val">
</simple>
... ... @@ -11,13 +11,13 @@
<script>
const $ = require('yoho-jquery');
const bus = require('common/vue-bus');
const simple = require('./sort/simple.vue');
const updown = require('./sort/updown.vue');
const simple = require('./order/simple.vue');
const updown = require('./order/updown.vue');
module.exports = {
props: {
/**
* sort 配置
* order 配置
* @type {Array} [{type, txt, val}]
* type: 类型 simple, updown
* txt: 文字,
... ... @@ -35,7 +35,7 @@ module.exports = {
methods: {},
watch: {
val: function(newVal, oldVal) {
bus.$emit('sort.change', {
bus.$emit('order.change', {
val: newVal,
ref: this._uid
});
... ... @@ -46,14 +46,14 @@ module.exports = {
<style>
@import "../../../scss/common/color";
.sort-navs {
.order-navs {
list-style: none;
margin: 0;
padding: 25px 0;
color: $grey;
}
.sort-item {
.order-item {
position: relative;
display: block;
width: 25%;
... ... @@ -69,10 +69,10 @@ module.exports = {
&:last-of-type:after {
display: none;
}
.sort-name {
.order-name {
font-size: 28px;
}
.sort-icon {
.order-icon {
position: relative;
margin-left: 10px;
.icon-sort-asc,
... ...
<template>
<li class="sort-item" :class="active" @click="click">
<span class="sort-name">{{txt}}</span>
<li class="order-item" :class="active" @click="click">
<span class="order-name">{{txt}}</span>
</li>
</template>
<script>
... ...
<template>
<li class="sort-item" :class="active" @click="clickHandler">
<span class="sort-name">{{txt}}</span>
<span class="sort-icon">
<li class="order-item" :class="active" @click="clickHandler">
<span class="order-name">{{txt}}</span>
<span class="order-icon">
<i class="icon icon-sort-asc" :class="{active: $parent.val === vals[0]}"></i>
<i class="icon icon-sort-desc" :class="{active: $parent.val === vals[1]}"></i>
</span>
</li>
</template>
<style>
.sort-item .icon {
.order-item .icon {
color: #b0b0b0;
&.active {
color: #000;
... ...
<template>
<div>
<Sort :config="sortConfig" :val="sort">
</Sort>
<cheader :title="sortName">
<i class="icon icon-filter" slot="right" @click="openFilter"></i>
</cheader>
<order :config="orderConfig" :val="order"></order>
<List :data="productList"></List>
<Drawer v-ref:drawer>
<Filter :config="filterConfig"></Filter>
</Drawer>
<Filter :config="filterConfig" v-ref:filter></Filter>
</div>
</template>
<script>
const Vue = require('yoho-vue');
const lazyload = require('yoho-vue-lazyload');
const infinitScroll = require('yoho-vue-infinite-scroll');
const qs = require('yoho-qs');
const bus = require('common/vue-bus');
const tip = require('common/tip');
const sort = require('component/product/sort.vue');
const cheader = require('component/header.vue');
const order = require('component/product/order.vue');
const list = require('component/product/list.vue');
const drawer = require('component/product/drawer.vue');
const filter = require('component/product/filter.vue');
Vue.use(lazyload);
Vue.use(infinitScroll);
require('common/vue-filter');
module.exports = {
el: '#product-list',
data: function() {
return {
sortConfig: [],
sortName: decodeURIComponent(qs.sort_name),
orderConfig: [],
filterConfig: null,
// query
url: '/product/list.json',
sort: '',
order: '',
filter: {},
page: 0, // 未搜索 page=0; 全部加载完 page = totalPage; 无数据: page !=0 && productList.length=0
totalPage: null,
... ... @@ -46,15 +47,16 @@
};
},
components: {
cheader,
list,
sort,
filter,
drawer
order,
filter
},
methods: {
search: function() {
const self = this;
const nextPage = this.page + 1;
console.log(nextPage)
if (this.inSearching) {
return;
... ... @@ -66,9 +68,8 @@
}
this.inSearching = true;
console.log(nextPage);
$.get(this.url, {
sort: this.sort,
order: this.order,
filter: this.filter,
page: nextPage
})
... ... @@ -91,6 +92,10 @@
});
},
openFilter() {
this.$refs.filter.isVisible = true;
},
openFilterSub: function(classify) {
console.log('TODO: open filter sub', classify);
},
... ... @@ -105,8 +110,8 @@
}
},
watch: {
/* sort 和 filter 改变 都会触发 重新搜索 */
sort: function() {
/* order 和 filter 改变 都会触发 重新搜索 */
order: function() {
this.research();
},
filter: function() {
... ... @@ -122,11 +127,11 @@
self.search();
});
bus.$on('sort.change', function({
bus.$on('order.change', function({
val
}) {
console.log(val);
self.sort = val;
self.order = val;
});
/**
... ... @@ -134,12 +139,10 @@
* 1. 重新搜索
* 2. 关闭 drawer 组件
*/
bus.$on('filter.change', function({
val
}) {
bus.$on('filter.change', function({val}) {
console.log(val);
self.filter = val;
self.$refs.drawer.on = false;
self.$refs.filter.isVisible = false;
});
/**
... ...
<template>
<div>
<template v-if="productList.length">
<Sort :config="sortConfig" :val="sort">
<order :config="orderConfig" :val="order">
</Sort>
<List :data="productList"></List>
</template>
... ... @@ -21,7 +21,7 @@
const bus = require('common/vue-bus');
const tip = require('common/tip');
const sort = require('component/product/sort.vue');
const sort = require('component/product/order.vue');
const list = require('component/product/list.vue');
Vue.use(lazyload);
... ... @@ -33,12 +33,12 @@
el: '#product-new',
data: function() {
return {
sortConfig: global.sortConfig,
orderConfig: global.orderConfig,
filterConfig: global.filterConfig,
// query
url: '/product/search.json',
sort: null,
order: null,
query: qs.query,
page: 0, // 未搜索 page=0; 全部加载完 page = totalPage; 无数据: page !=0 && productList.length=0
totalPage: null,
... ... @@ -58,7 +58,7 @@
},
components: {
list,
sort
order
},
methods: {
search: function() {
... ... @@ -77,7 +77,7 @@
this.inSearching = true;
console.log(nextPage);
$.get(this.url, {
order: this.sort, // 排序 信息
order: this.order, // 排序 信息
query: this.query,
page: nextPage
})
... ... @@ -106,8 +106,8 @@
}
},
watch: {
/* sort 改变 都会触发 重新搜索 */
sort: function() {
/* order 改变 都会触发 重新搜索 */
order: function() {
this.research();
}
},
... ... @@ -120,10 +120,10 @@
self.search();
});
bus.$on('sort.change', function({
bus.$on('order.change', function({
val
}) {
self.sort = val;
self.order = val;
});
this.search();
... ...
<template>
<div>
<template v-if="productList.length">
<Sort :config="sortConfig" :val="sort">
</Sort>
<Order :config="orderConfig" :val="order">
</Order>
<List :data="productList"></List>
</template>
<div class="empty-tip" v-if="empty">
... ... @@ -21,7 +21,7 @@
const bus = require('common/vue-bus');
const tip = require('common/tip');
const sort = require('component/product/sort.vue');
const order = require('component/product/order.vue');
const list = require('component/product/list.vue');
Vue.use(lazyload);
... ... @@ -33,12 +33,12 @@
el: '#product-search',
data: function() {
return {
sortConfig: global.sortConfig,
orderConfig: global.orderConfig,
filterConfig: global.filterConfig,
// query
url: '/product/search.json',
sort: '',
order: '',
query: qs.query,
page: 0, // 未搜索 page=0; 全部加载完 page = totalPage; 无数据: page !=0 && productList.length=0
totalPage: null,
... ... @@ -58,7 +58,7 @@
},
components: {
list,
sort
order
},
methods: {
search: function() {
... ... @@ -77,7 +77,7 @@
this.inSearching = true;
console.log(nextPage);
$.get(this.url, {
order: this.sort, // 排序 信息
order: this.order, // 排序 信息
query: this.query,
page: nextPage
})
... ... @@ -106,8 +106,8 @@
}
},
watch: {
/* sort 改变 都会触发 重新搜索 */
sort: function() {
/* order 改变 都会触发 重新搜索 */
order: function() {
this.research();
}
},
... ... @@ -120,10 +120,10 @@
self.search();
});
bus.$on('sort.change', function({
bus.$on('order.change', function({
val
}) {
self.sort = val;
self.order = val;
});
this.search();
... ...
<template>
<shop-top v-bind:shop-info="shopInfo"></shop-top>
<goods-list v-bind:data="productList"></goods-list>
<drawer v-ref:drawer>
<filter :config="filterConfig"></filter>
</drawer>
<filter :config="filterConfig" v-ref:filter></filter>
<top-bar v-bind:share-data="shareData"></top-bar>
</template>
... ... @@ -16,7 +14,6 @@
const topBar = require('product/shop/top-bar.vue'); // 顶部栏,包括返回、收藏店铺、分享,打开筛选页面
const shopTop = require('product/shop/shop-top.vue'); // 店铺头部信息
const goodsList = require('component/product/list.vue');
const drawer = require('component/product/drawer.vue');
const filter = require('component/product/filter.vue');
const shareSubTitle = '我在BLK发现了一个不错的品牌,赶快来看看吧!';
... ... @@ -129,7 +126,6 @@
topBar,
shopTop,
goodsList,
drawer,
filter
},
created() {
... ... @@ -148,12 +144,12 @@
/**
* 筛选组件 筛选值变更,触发 filter.change事件
* 1. 重新搜索
* 2. 关闭 drawer 组件
* 2. 关闭 filter 组件
*/
bus.$on('filter.change', ({val}) => {
Object.assign(this.filter, val);
this.search();
this.$refs.drawer.on = false;
this.$refs.filter.on = false;
});
/**
... ...
<template>
<div class="top-box clearfix" v-bind:class='{"top-box-left" : this.$parent.$refs.drawer.on}'>
<div class="top-box clearfix" v-bind:class='{"top-box-left" : this.$parent.$refs.filter.on}'>
<span class="icon back" @click="goBack()">&#xe606;</span>
<div class="right">
<span v-if="shareData.isFav" class="icon" @click="collectShop()">&#xe60d;</span>
... ...