Authored by Aiden Xu

Merge remote-tracking branch 'origin/develop' into develop

... ... @@ -24,6 +24,11 @@ module.exports = {
return res.json(result);
}).catch(next);
},
goods(req, res, next) {
channelModel.getGoodsData(req.query).then(result => {
return res.json(result);
}).catch(next);
},
sidebar(req, res, next) {
if (!req.xhr) {
return res.render('sidebar', {
... ...
'use strict';
const api = global.yoho.ServiceAPI;
const resourcesProcess = require('../../../utils/beautify/resources');
const service = global.yoho.ServiceAPI;
const api = global.yoho.API;
const processResources = require(`${global.utils}/beautify/resources`);
const processProductList = require(`${global.utils}/beautify/product`);
let channel = {
getResourcesData(params) {
if (!params.contentCode) {
return Promise.resolve([]);
}
return api.get('operations/api/v5/resource/get', {
return service.get('operations/api/v5/resource/get', {
content_code: params.contentCode
}, {
cache: true,
code: 200
}).then(result => {
return resourcesProcess(result.data);
return processResources(result.data);
});
},
getSidebarData() {
return api.get('operations/api/v6/category/getCategory', {
return service.get('operations/api/v6/category/getCategory', {
parent_id: 1155
}, {
cache: true,
code: 200
}).then(global.yoho.camelCase);
}
},
getGoodsData(params) {
if (!params.productSkn || !params.productSkn.length) {
return Promise.resolve([]);
}
return api.get('', {
method: 'h5.product.batch',
productSkn: params.productSkn
}, {
cache: true,
code: 200
}).then(result => {
return result.data ? processProductList(result.data['process-list']) : [];
});
},
};
module.exports = channel;
... ...
... ... @@ -14,7 +14,8 @@ const brand = require(cRoot + '/brand');
const router = expressRouter();
router.get('/', channel.index); // 首页
router.get('/resources', channel.resources); // 资源位接口
router.get('/channel/resources.json', channel.resources); // 资源位接口
router.get('/channel/goods.json', channel.goods); // 首页查询商品列表
router.get('/brand', brand.index); // 店铺首页
router.get('/get-brand-intro', brand.getBrandIntro); // 店铺介绍
router.post('/get-brand-shop-goods', brand.getBrandShopGoods); // 店铺介绍
... ...
... ... @@ -28,15 +28,13 @@ const refund = {
res.json(result);
}).catch(next);
},
logistics(req, res) {
res.render('logistics', {
module: 'home',
page: 'logistics'
});
},
companylist(req, res, next) {
logistics(req, res, next) {
refundModel.getExpressCompany().then(result => {
res.json(result);
res.render('logistics', {
module: 'home',
page: 'logistics',
company_list: result ? JSON.stringify(result.data) : ""
});
}).catch(next);
},
saveLogistics(req, res) {
... ...
... ... @@ -35,13 +35,13 @@ const _getInfoNumData = (uid) => {
method: 'app.address.gethidden' // 用户地址的数据
})]).then(data => {
let res = {
wait_pay_num: 0,
wait_cargo_num: 0,
send_cargo_num: 0,
refund_exchange_num: 0,
product_favorite_total: 0,
brand_favorite_total: 0,
yoho_coin_num: 0
wait_pay_num: '',
wait_cargo_num: '',
send_cargo_num: '',
refund_exchange_num: '',
product_favorite_total: '',
brand_favorite_total: '',
yoho_coin_num: ''
};
if (data[0].data) {
... ...
... ... @@ -23,7 +23,7 @@ const camelCase = global.yoho.camelCase;
exports.getOrders = (param) => {
param = Object.assign({method: 'app.SpaceOrders.get'}, param);
return api.get('', param).then(camelCase);
return api.get('978c6bad6c379086.json', param).then(camelCase);
};
/**
... ... @@ -33,7 +33,7 @@ exports.getOrders = (param) => {
* @returns {Promise.<T>|*}
*/
exports.getOrderDetail = (uid, orderCode) => {
return api.get('', {
return api.get('621e0b505983ac8a.json', {
method: 'app.SpaceOrders.detail',
order_code: orderCode,
uid: uid
... ... @@ -49,7 +49,7 @@ exports.getOrderDetail = (uid, orderCode) => {
*/
exports.cancelOrder = (orderCode, reasonId, reason) => {
return api.get('', {
return api.get('057f5f856dff8b58.json', {
method: 'app.SpaceOrders.close',
order_code: orderCode,
reason_id: reasonId,
... ...
... ... @@ -42,7 +42,6 @@ router.get('/refund', refund.refund); // 退换货
router.get('/refund/order', refund.order); // 查询订单数据
router.post('/refund/submit', refund.submit); // 提交信息
router.get('/refund/logistics', refund.logistics); // 退换货 - 商品寄回信息
router.get('/refund/companylist', refund.companylist); // 退换货 - 物流公司列表信息
router.post('/save-logistics', refund.saveLogistics); // 退换货 - 添加寄回物流信息
// 换货
... ...
<div class="logistics-page" id="logistics">
<components :is="currentView" :company_id="company_id" :company_name="company_name" keep-alive></components>
</div>
\ No newline at end of file
<components :is="currentView" :company_id="company_id" :company_name="company_name" company_list={{company_list}} keep-alive></components>
</div>
... ...
... ... @@ -3,12 +3,12 @@
* @author 陈轩 <xuan.chen@yoho.cn>
*/
'use strict';
const path = require('path');
const _ = require('lodash');
const api = global.yoho.API;
const camelCase = global.yoho.camelCase;
const prettyFilter = require(path.join(global.utils, '/beautify/filters'));
const processProductList = require(path.join(global.utils, '/beautify/product')).processProductList;
const prettyFilter = require(`${global.utils}/beautify/filters`);
const processProductList = require(`${global.utils}/beautify/product`);
/* 搜索 页面 */
... ...
... ... @@ -15,8 +15,8 @@ module.exports = {
port: 6004,
siteUrl: '//m.yohoblk.com',
domains: {
api: 'http://192.168.102.202:8080/gateway/',
service: 'http://192.168.102.202:8080/gateway/'
api: 'http://devapi.yoho.cn:58078/',
service: 'http://devservice.yoho.cn:58077/'
},
subDomains: {
host: '.m.yohoblk.com',
... ...
const Vue = require('yoho-vue');
const lazyload = require('yoho-vue-lazyload');
const infinitScroll = require('yoho-vue-infinite-scroll');
const channel = require('channel/index.vue');
require('common/vue-filter');
Vue.use(lazyload);
Vue.use(infinitScroll);
new Vue({
el: '#channel',
... ...
... ... @@ -63,8 +63,8 @@ Vue.filter('brandUrl', (value)=> {
Vue.filter('convertOrderState', (value) => {
let stateTxt = '';
if (value !== undefined) {
value = parseInt(value);
if (typeof value === 'undefined') {
value = parseInt(value, 10);
}
switch (value) {
case 0:
... ... @@ -88,6 +88,9 @@ Vue.filter('convertOrderState', (value) => {
case 6:
stateTxt = '已完成';
break;
default:
stateTxt = '';
break;
}
return stateTxt;
});
... ... @@ -97,7 +100,7 @@ Vue.filter('convertOrderState', (value) => {
* yyyy-MM-dd hh:mm:ss
*/
Vue.filter('convertTime', (value) => {
if (value === undefined) {
if (typeof value === 'undefined') {
return;
}
let date = new Date(parseFloat(value) * 1000);
... ...
const Vue = require('yoho-vue');
const infiniteScroll = require('yoho-vue-infinite-scroll');
const Logistics = require('home/refund/logistics.vue');
const LogisticsCompany = require('home/refund/logistics-company.vue');
Vue.use(infiniteScroll);
new Vue({
el: '#logistics',
data: {
... ...
... ... @@ -17,7 +17,7 @@
margin-top: 20px;
}
.fav-del {
.fav-del-left {
display: none;
float: left;
width: 50px;
... ... @@ -38,6 +38,30 @@
display: block;
}
.fav-del-right {
position: absolute;
top: 0;
right: -126px;
background: #ff3b30;
width: 126px;
height: 200px;
text-align: center;
.fav-del-btn {
display: inline-block;
width: 35px;
height: 43px;
margin-top: 50px;
background: resolve("home/fav/fav-del-btn.png");
background-size: 100%;
}
.fav-del-txt {
font-size: 24px;
color: #fff;
}
}
.fav-img-box {
width: 152px;
height: 203px;
... ... @@ -156,7 +180,7 @@
border-bottom: 1px solid #e0e0e0;
}
.fav-del {
.fav-del-left {
display: none;
float: left;
width: 50px;
... ... @@ -177,6 +201,30 @@
display: block;
}
.fav-del-right {
position: absolute;
top: 0;
right: -126px;
background: #ff3b30;
width: 126px;
height: 125px;
text-align: center;
.fav-del-btn {
display: inline-block;
width: 35px;
height: 43px;
margin-top: 30px;
background: resolve("home/fav/fav-del-btn.png");
background-size: 100%;
}
.fav-del-txt {
font-size: 24px;
color: #fff;
}
}
.fav-img-box {
width: 160px;
height: 125px;
... ...
... ... @@ -108,7 +108,7 @@
margin-left: 30px;
.company-item {
h2 {
.tag {
height: 50px;
line-height: 50px;
font-size: 34px;
... ...
... ... @@ -67,7 +67,7 @@ $white: #fff;
bottom: 0;
width: 100%;
height: 12px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAMBAMAAAAHcycSAAAAElBMVEXu7u7lnJrbSUbkm5qqqqpmZmaVABiUAAAAKUlEQVR4AWNAACElIDBgQAGuoUDggCrGCFKnjCrGAlIXAmINWgNHDQQAWjsd42E4szoAAAAASUVORK5CYII=") repeat-x;
background: resolve("home/order-border.png") repeat-x;
border-bottom: 1px solid #eee;
}
}
... ...
... ... @@ -58,7 +58,7 @@
const $ = require('yoho-jquery');
const bus = require('common/vue-bus');
const tip = require('common/tip');
const indexList = require('channel/index-list.vue');
const indexList = require('component/tool/index-list.vue');
module.exports = {
props: ['channel'],
... ...
<template>
<div class="goods">
<product-list v-bind:data="productList"></product-list>
</div>
</template>
<script>
const titleFloor = require('component/resources/title-floor.vue');
const productList = require('product/list.vue');
module.exports = {
data() {
return {
productList: []
};
},
props: ['floor'],
components: {
titleFloor: titleFloor
titleFloor: titleFloor,
productList
},
created() {
// console.log(this.floor)
let productSkn = [];
this.floor.forEach(item => {
productSkn.push(item.id);
});
$.ajax({
url: '/channel/goods.json',
data: {
productSkn: productSkn.join(',')
}
}).then(result => {
console.log(result);
this.productList = result;
});
}
};
</script>
... ...
... ... @@ -80,7 +80,7 @@
}
return $.ajax({
url: '/resources',
url: '/channel/resources.json',
data: data
}).then(result => {
this.resources = result;
... ...
<template>
<div class="fav-type" v-infinite-scroll="loadMore()" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
<ul class="fav-brand-list">
<li v-for="item in brandData" track-by="fav_id">
<div class="fav-del {{editmodel ? 'delshow': ''}}" @click="delItem($index, item.fav_id)">
<li v-for="item in brandData" track-by="$index" id="li-{{$index}}">
<div class="fav-del-left {{editmodel ? 'delshow': ''}}" @click="showDelBtn($index)">
<span class="fav-del-span"></span>
</div>
<a :href="item.link">
... ... @@ -14,6 +14,11 @@
<span class="down" v-if="item.down">品牌已下架</span>
</div>
</a>
<div class="fav-del-right" id="del-{{$index}}" @click="delItem($index, item.fav_id)">
<span class="fav-del-btn"></span>
<br/>
<span class="fav-del-txt">删除</span>
</div>
</li>
</ul>
<div class="fav-null-box {{ nullbox }}">
... ... @@ -69,6 +74,20 @@
},
editModel(action) {
this.editmodel = action;
if (!action) {
this.hideDelBth();
}
},
showDelBtn(index) {
this.hideDelBth();
var delBtn = $("#del-" + index);
var width = delBtn.width();
$("#li-" + index).css("transform","translateX(-" + width + "px)");
},
hideDelBth() {
this.brandData.forEach(function(d, index){
$("#li-" + index).css("transform","translateX(0px)");
})
},
delItem(index, id) {
let _this = this;
... ... @@ -82,6 +101,7 @@
}).then(function(data) {
if (data.code === 200) {
_this.brandData.splice(index, 1);
_this.hideDelBth();
} else if (data.code === 400) {
tip(data.message);
} else {
... ...
<template>
<div class="fav-type" 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 ? 'delshow': ''}}" @click="delItem($index, item.fav_id)">
<li v-for="item in productData" track-by="$index" id="li-{{$index}}">
<div class="fav-del-left {{editmodel ? 'delshow': ''}}" @click="showDelBtn($index)">
<span class="fav-del-span"></span>
</div>
<a :href="item.link">
... ... @@ -22,6 +22,11 @@
</div>
</div>
</a>
<div class="fav-del-right" id="del-{{$index}}" @click="delItem($index, item.fav_id)">
<span class="fav-del-btn"></span>
<br/>
<span class="fav-del-txt">删除</span>
</div>
</li>
</ul>
<div class="fav-null-box {{ nullbox }}">
... ... @@ -76,6 +81,20 @@
},
editModel(action) {
this.editmodel = action;
if (!action) {
this.hideDelBth();
}
},
showDelBtn(index) {
this.hideDelBth();
var delBtn = $("#del-" + index);
var width = delBtn.width();
$("#li-" + index).css("transform","translateX(-" + width + "px)");
},
hideDelBth() {
this.productData.forEach(function(d, index){
$("#li-" + index).css("transform","translateX(0px)");
})
},
delItem(index, id) {
let _this = this;
... ... @@ -89,6 +108,7 @@
}).then(function(data) {
if (data.code === 200) {
_this.productData.splice(index, 1);
_this.hideDelBth();
} else if (data.code === 400) {
tip(data.message);
} else {
... ...
... ... @@ -5,35 +5,41 @@
</div>
<div class="company-data">
<div class="company-item" v-for="item in showData">
<h2>{{ $key }}</h2>
<a class="tag" :name="$key">{{ $key }}</a>
<span v-for="val in item" track-by="id" @click="select(val.id, val.company_name)">{{val.company_name}}</span>
</div>
</div>
<index-list style="margin-top:70px"></index-list>
</div>
</template>
<script>
const $ = require('yoho-jquery');
const indexList = require('component/tool/index-list.vue');
module.exports = {
props: ['company_list'],
data() {
this.company_list = JSON.parse(this.company_list);
return {
inputname: '',
data: {},
showData: {}
showData: this.company_list
};
},
components: {
indexList
},
methods: {
search: function() {
var inputname = this.inputname;
if (!inputname) {
this.showData = this.data;
this.showData = this.company_list;
return;
}
var filter = {};
for (var k in this.data) {
this.data[k].forEach(function(d){
for (var k in this.company_list) {
this.company_list[k].forEach(function(d){
if (d.company_name.indexOf(inputname) > -1) {
if (!filter[k]) filter[k] = [];
filter[k].push(d);
... ... @@ -51,27 +57,8 @@
// 重置列表
this.inputname = '';
this.showData = this.data;
this.showData = this.company_list;
}
},
activate: function(done) {
let _this = this;
$.ajax({
url: '/home/refund/companylist'
}).then(function(res) {
if ($.type(res) !== 'object') {
res = {};
}
if (res.code === 200) {
_this.data = res.data;
_this.showData = res.data;
}
done();
}).fail(function() {
tip('网络错误');
done();
});
}
};
</script>
\ No newline at end of file
</script>
... ...
... ... @@ -161,6 +161,7 @@
font-size: 24px;
line-height: 40px;
resize: none;
border: 0;
}
}
... ...
... ... @@ -18,62 +18,10 @@ const _procProductImg = (product, gender, yhChannel) => {
return product.cover1 || product.imagesUrl || product.cover2 || '';
};
const toArray = (obj) => {
if (_.isArray(obj)) {
return obj;
}
let arr = [];
_.forEach(obj, (v, k) => {
if (_.isObject(v)) {
v._key = k;
} else {
v = {
_key: k,
_value: v
};
}
arr.push(v);
});
return arr;
};
/**
* 按照数组中指定字段排序二维数组
*
* @param array list 需要排序的数组
* @param string key 字段名称
* @param boolean 有 desc 时候降序排列,默认为false
*/
const _sortListByField = (list, key, desc) => {
let array = toArray(list);
array = array.sort((a, b) => {
let matchNumber = /([\d]+)/g;
// 有键,使用键的值排序
if (a[key] && b[key]) {
let numA = +(_.toArray(a[key].match(matchNumber))[0] || 0); // 取第一个出现的数字排序,如果不存在,取0
let numB = +(_.toArray(b[key].match(matchNumber))[0] || 0);
return (desc ? numA > numB : numA < numB) ? -1 : 1;
}
// 无键, 使用本身
let numA = +(_.toArray(a._value.match(matchNumber))[0] || 0);
let numB = +(_.toArray(b._value.match(matchNumber))[0] || 0);
return numA < numB ? -1 : 1;
});
return array;
};
/**
* 商品搜索商品数据处理
*/
exports.processProductList = (list, options) => {
module.exports = (list, options) => {
const pruductList = [];
options = Object.assign({
... ... @@ -163,149 +111,3 @@ exports.processProductList = (list, options) => {
return pruductList;
};
/**
* 处理筛选数据
* @param list
* @param string | options
* @return array 处理之后的筛选数据
*/
exports.processFilter = (list, options) => {
const filters = {
classify: []
};
const filtersType = {
brand: {
name: '所有品牌',
title: '品牌',
dataId: 'id',
subsName: 'brandName',
firstSub: 0,
dataType: 'brand',
sortNum: '1'
},
color: {
name: '所有颜色',
title: '颜色',
dataId: 'colorId',
subsName: 'colorName',
firstSub: 0,
dataType: 'color',
sortNum: '3'
},
discount: {
name: '所有商品',
title: '折扣',
dataId: 'key',
subsName: 'name',
firstSub: '0.1,0.9',
dataType: 'p_d',
sortNum: '6'
},
gender: {
name: '所有性别',
title: '性别',
dataId: 'key',
subsName: 'flag',
firstSub: '1,2,3',
dataType: 'gender',
sortNum: '0'
},
groupSort: {
name: '所有品类',
title: '品类',
dataId: 'relationParameter',
subsName: 'categoryName',
firstSub: 0,
dataType: 'sort',
sortNum: '2'
},
priceRange: {
name: '所有价格',
title: '价格',
dataId: 'key',
subsName: 'flag',
firstSub: 0,
dataType: 'price',
sortNum: '5'
},
size: {
name: '所有尺码',
title: '尺码',
dataId: 'sizeId',
subsName: 'sizeName',
firstSub: 0,
dataType: 'size',
sortNum: '4'
}
};
options = Object.assign({
gender: '1,2,3', // 默认选择的性别,默认1,2,3表示所有
exclude: null // 需要排除的字段
}, options);
list = camelCase(list);
_.forEach(list, (item, key) => {
let classify = {
subs: []
};
if (key === 'groupSort' || !filtersType[key]) {
return;
}
if ((options.hideSize && key === 'size') || (options.hideSort && key === 'groupSort')) {
return;
}
classify.dataType = filtersType[key].dataType;
classify.name = filtersType[key].name;
classify.title = filtersType[key].title;
classify.subs.push({
chosed: true,
dataId: filtersType[key].firstSub,
name: filtersType[key].name
});
// 折扣,价格区间,需要排序
if (key === 'discount' || key === 'priceRange') {
item = _sortListByField(item, 'name');
}
_.forEach(item, (sub, index) => {
let subs = {};
if (key === 'discount') {
subs.dataId = sub._key;
} else if (key === 'priceRange') {
subs.dataId = sub._key;
} else if (filtersType[key].dataId === 'key') {
subs.dataId = index;
} else if (filtersType[key].dataId === 'relationParameter') {
subs.dataId = sub.relationParameter['sort']; // eslint-disable-line
} else {
subs.dataId = sub[filtersType[key].dataId];
}
if (key === 'priceRange') {
subs.name = sub._value;
} else if (filtersType[key].subsName === 'flag') {
subs.name = sub;
} else {
subs.name = sub[filtersType[key].subsName];
if (key === 'discount') {
subs.name = subs.name + '折商品';
}
}
classify.subs.push(subs);
});
filters.classify[filtersType[key].sortNum] = classify;
});
return filters;
};
... ...