Authored by TaoHuang

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

# Conflicts:
#	config/order-api-map.js
Showing 43 changed files with 1004 additions and 137 deletions
1 const config = { 1 const config = {
2 development: { 2 development: {
3 - axiosBaseUrl: 'http://m.yohobuy.com/xianyu', 3 + axiosBaseUrl: 'http://m.yohobuy.com:6001/xianyu',
4 axiosResponseType: 'json', 4 axiosResponseType: 'json',
5 - reportUrl: '//badjs.yoho.cn/apm/yas2.gif' 5 + reportUrl: '//badjs.yoho.cn/apm/yas2.gif',
6 }, 6 },
7 production: { 7 production: {
8 axiosBaseUrl: 'http://m.yohobuy.com/xianyu', 8 axiosBaseUrl: 'http://m.yohobuy.com/xianyu',
9 axiosResponseType: 'json', 9 axiosResponseType: 'json',
10 - reportUrl: '//badjs.yoho.cn/apm/yas2.gif'  
11 - } 10 + reportUrl: '//badjs.yoho.cn/apm/yas2.gif',
  11 + },
12 }; 12 };
13 13
14 export default config[process.env.NODE_ENV]; 14 export default config[process.env.NODE_ENV];
  1 +<template>
  2 + <LayoutApp :show-back="true">
  3 + <div class="root-content">
  4 + <div class="left-content">
  5 + <Scroll>
  6 + <div >
  7 + <li
  8 + class="category-left-item"
  9 + :class="{'category-left-item-select' : item.isSelect }"
  10 + v-for="(item, index) in categoryParent"
  11 + :key="index"
  12 + :data-id="item"
  13 + @click="onClick(item)">{{item.name}}</li>
  14 +
  15 + </div>
  16 + </Scroll>
  17 + </div>
  18 + <div class="left-right-split-line"></div>
  19 + <div class="right-content">
  20 + <Scroll>
  21 + <div v-for="(itemSub, index) in categorySubList" :key="index">
  22 + <p class="sub-title">————{{itemSub.name}}————</p>
  23 + <div class="category-sub-root">
  24 + <div class="item-imge-div"
  25 + v-for="(item, index) in itemSub.sub"
  26 + :key="index"
  27 + :data-id="item.id"
  28 + >
  29 + <ImgSize
  30 + class="item-imge"
  31 + :src="item.image"
  32 + :width="60"
  33 + :height="60"
  34 + />
  35 + </div>
  36 + </div>
  37 + </div>
  38 + </Scroll>
  39 + </div>
  40 +
  41 + </div>
  42 + </LayoutApp>
  43 +</template>
  44 +<script>
  45 +import { Scroll }from 'cube-ui'
  46 +import {createNamespacedHelpers} from 'vuex';
  47 +import Vue from 'vue';
  48 +import ImgSize from '../../components/img-size';
  49 +
  50 +const {mapState, mapActions} = createNamespacedHelpers('category');
  51 +export default {
  52 + name: 'category',
  53 + components: {
  54 + Scroll,
  55 + ImgSize
  56 + },
  57 + data() {
  58 + return {
  59 +
  60 + };
  61 + },
  62 + mounted() {
  63 + this.fetchCategoryParentList();
  64 + this.fetchBrandList({});
  65 + },
  66 + methods: {
  67 + ...mapActions(['fetchCategoryParentList', 'selectCategoryParent', 'fetchBrandList', 'fetchCategorySubList']),
  68 + onClick(item){
  69 + if(!item.isSelect){
  70 + let id = item.id;
  71 + if(id === "-1"){
  72 + this.fetchBrandList({id});
  73 + }else {
  74 + this.fetchCategorySubList({id})
  75 + }
  76 + }
  77 + },
  78 + },
  79 + computed: {
  80 + ...mapState(['categoryParent','categorySubList']),
  81 + },
  82 +};
  83 +</script>
  84 +
  85 +<style>
  86 + .root-content{
  87 + width: 100%;
  88 + height: 100%;
  89 + display: flex;
  90 + flex-direction: row;
  91 + background-color: #FFFFFF;
  92 +
  93 + }
  94 + .left-right-split-line{
  95 + height: 100%;
  96 + width: 1px;
  97 + background-color: #999999;
  98 + }
  99 + .left-content{
  100 + width: 25%;
  101 + height: 100%;
  102 +
  103 + }
  104 + .right-content{
  105 + display: flex;
  106 + flex-direction: column;
  107 + width: 75%;
  108 + height: 100%;
  109 + }
  110 + .category-left-item{
  111 + display: flex;
  112 + width: 100%;
  113 + height: 100px;
  114 + align-items: center;
  115 + justify-content: center;
  116 + font-size: 28px;
  117 + color: #EEEEEE;
  118 +
  119 + }
  120 + .category-left-item-select{
  121 + font-size: 48px;
  122 + color: #000000;
  123 +
  124 + }
  125 + .category-sub-root {
  126 + display: flex;
  127 + flex-flow: row wrap;
  128 + align-content: flex-start;
  129 + }
  130 + .sub-title{
  131 + /* background-color: brown; */
  132 + font-size: 24px;
  133 + color: #000;
  134 + text-align: center;
  135 + }
  136 + .item-imge-div {
  137 + display: flex;
  138 + flex: 0 0 33%;
  139 + height: 150px;
  140 + align-items: center;
  141 + justify-content: center;
  142 + }
  143 + .item-imge {
  144 + object-fit: contain;
  145 + }
  146 +
  147 +</style>
  1 +
  2 +export default [
  3 + {
  4 + name: 'category',
  5 + path: '/xianyu/category',
  6 + component: () => import(/* webpackChunkName: "notice" */ './category')
  7 + }
  8 + ];
  9 +
1 <template> 1 <template>
2 - <div class="body" ref="body">  
3 - <div v-for="(item, index) in channelData" :key="index">  
4 - <template v-if="item.template_name == 'focus'">  
5 - <Slider :list="list"></Slider>  
6 - </template> 2 + <LayoutApp :show-back="true">
  3 + <div class="scroll-list-wrap">
  4 + <Scroll
  5 + ref="scroll"
  6 + :options="options"
  7 + @pulling-up="onPullingUp">
  8 + <div class="body" ref="body">
  9 + <div v-for="(item, index) in channelList.list" :key="index">
  10 + <template v-if="item.template_name == 'focus'">
  11 + <Slider :list="list"></Slider>
  12 + </template>
7 13
8 - <template v-if="item.template_name == 'hotSeries'">  
9 - <Hot :list="item.data"></Hot>  
10 - </template> 14 + <template v-if="item.template_name == 'hotSeries'">
  15 + <Hot :list="item.data"></Hot>
  16 + </template>
11 17
12 - <template v-if="item.template_name == 'single_image'">  
13 - <Banner :linkUrl="linkUrl" :imgUrl="imgUrl"></Banner>  
14 - </template> 18 + <template v-if="item.template_name == 'single_image'">
  19 + <Banner :linkUrl="linkUrl" :imgUrl="imgUrl"></Banner>
  20 + </template>
15 21
16 - <template v-if="item.template_name == 'twoPicture'">  
17 - <TwoBanner :list="item.data"></TwoBanner>  
18 - </template>  
19 - </div>  
20 - <!-- <ScrollNav></ScrollNav> --> 22 + <template v-if="item.template_name == 'twoPicture'">
  23 + <TwoBanner :list="item.data"></TwoBanner>
  24 + </template>
  25 + </div>
  26 + <ScrollNav></ScrollNav>
  27 + <ProductList :list="channelList.productlist"></ProductList>
  28 + </div>
  29 + </Scroll>
21 </div> 30 </div>
  31 + </LayoutApp>
22 </template> 32 </template>
23 33
24 <script> 34 <script>
25 -import Slider from './components/slider'; // 轮播图  
26 -import Banner from './components/banner'; // 一张图广告位  
27 -import TwoBanner from './components/twoBanner'; // 两张图广告位  
28 -import Hot from './components/hot'; // 热门系列  
29 -import ScrollNav from './components/scrollNav'; // 滑动导航 35 +import { Style, Scroll } from 'cube-ui'
30 import { createNamespacedHelpers } from 'vuex'; 36 import { createNamespacedHelpers } from 'vuex';
31 -const {mapState, mapActions} = createNamespacedHelpers('home/channel'); 37 +import Slider from './components/slider';
  38 +import Banner from './components/banner';
  39 +import TwoBanner from './components/twoBanner';
  40 +import Hot from './components/hot';
  41 +import ScrollNav from './components/scrollNav';
  42 +import ProductList from '../../list/components/productList';
  43 +
  44 +const { mapState, mapActions } = createNamespacedHelpers('home/channel');
32 45
33 export default { 46 export default {
34 data() { 47 data() {
35 return { 48 return {
  49 + options: {
  50 + bounce: {
  51 + top: false
  52 + },
  53 + pullUpLoad: true
  54 + },
  55 + items: [1,2,3,4,5,6,7,8,9],
36 list: [ 56 list: [
37 { 57 {
38 url: 'http://www.didichuxing.com/', 58 url: 'http://www.didichuxing.com/',
@@ -195,28 +215,42 @@ export default { @@ -195,28 +215,42 @@ export default {
195 } 215 }
196 }, 216 },
197 computed: { 217 computed: {
198 - ...mapState(['channelData']), 218 + ...mapState(['channelList']),
199 }, 219 },
200 created() { 220 created() {
201 221
202 }, 222 },
203 mounted() { 223 mounted() {
204 this.fetchChannelList(); 224 this.fetchChannelList();
  225 + this.fetchProductList();
205 }, 226 },
206 methods: { 227 methods: {
207 - ...mapActions(['fetchChannelList']), 228 + ...mapActions(['fetchChannelList','fetchProductList']),
  229 +
  230 + async onPullingUp() {
  231 + await this.fetchProductList();
  232 + setTimeout(() => { this.$refs.scroll.forceUpdate() }, 1000)
  233 + }
  234 +
208 }, 235 },
209 components: { 236 components: {
210 Slider, 237 Slider,
211 Banner, 238 Banner,
212 TwoBanner, 239 TwoBanner,
213 Hot, 240 Hot,
214 - ScrollNav 241 + ScrollNav,
  242 + Style,
  243 + Scroll,
  244 + ProductList
215 } 245 }
216 }; 246 };
217 </script> 247 </script>
218 248
219 <style lang="scss" scoped> 249 <style lang="scss" scoped>
  250 +.scroll-list-wrap {
  251 + height: 100%;
  252 + width: 100%;
  253 +}
220 .body { 254 .body {
221 height: 100%; 255 height: 100%;
222 overflow-y: auto; 256 overflow-y: auto;
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <ul> 3 <ul>
4 <li v-for="(item, index) in list" :key="index" @click="goProduct(item)"> 4 <li v-for="(item, index) in list" :key="index" @click="goProduct(item)">
5 <div class="hot-image"> 5 <div class="hot-image">
6 - <img :src="item.image_url" alt="" /> 6 + <ImgSize class="item-imge" :src="item.image_url" :width="100" :height="80"/>
7 </div> 7 </div>
8 <div class="hot-name">{{item.series_name}}</div> 8 <div class="hot-name">{{item.series_name}}</div>
9 </li> 9 </li>
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 </template> 16 </template>
17 17
18 <script> 18 <script>
  19 +import ImgSize from '../../../../components/img-size';
  20 +
19 export default { 21 export default {
20 name: 'hot', 22 name: 'hot',
21 props: { 23 props: {
@@ -25,6 +27,9 @@ export default { @@ -25,6 +27,9 @@ export default {
25 }, 27 },
26 28
27 }, 29 },
  30 + components: {
  31 + ImgSize,
  32 + },
28 methods: { 33 methods: {
29 goProduct() { 34 goProduct() {
30 alert('跳转列表!'); 35 alert('跳转列表!');
@@ -45,6 +50,7 @@ export default { @@ -45,6 +50,7 @@ export default {
45 50
46 <style lang="scss" scoped> 51 <style lang="scss" scoped>
47 .hot { 52 .hot {
  53 + margin: 40px 0;
48 ul { 54 ul {
49 overflow: hidden; 55 overflow: hidden;
50 li { 56 li {
1 <template> 1 <template>
2 <div class="ScrollNav"> 2 <div class="ScrollNav">
3 - <ScrollNav>  
4 - <ScrollNav-panel  
5 - v-for="item in [1,2,3,4,5]"  
6 - :key="item"  
7 - :label="item">  
8 - <div v-for="item in [1,2,3,4,5]" :key="item" :label="item">22222</div>  
9 - </ScrollNav-panel>  
10 - </ScrollNav> 3 + <ScrollNavBar :current="current" :labels="labels">
  4 + <span slot-scope="props" @click="changeHandler(props.index)">
  5 + {{props.txt}}
  6 + </span>
  7 + </ScrollNavBar>
11 </div> 8 </div>
12 </template> 9 </template>
13 10
14 <script> 11 <script>
15 import Vue from 'vue' 12 import Vue from 'vue'
16 -import { Style, ScrollNav } from 'cube-ui'; 13 +import { Style, ScrollNavBar } from 'cube-ui';
  14 +import { createNamespacedHelpers } from 'vuex';
  15 +const { mapState, mapActions } = createNamespacedHelpers('home/channel');
17 16
18 export default { 17 export default {
19 name: 'slide', 18 name: 'slide',
@@ -23,15 +22,36 @@ export default { @@ -23,15 +22,36 @@ export default {
23 // default: true 22 // default: true
24 // }, 23 // },
25 }, 24 },
  25 + data() {
  26 + return {
  27 + index: 0,
  28 + current: '快车',
  29 + labels: [
  30 + '快车',
  31 + '小巴',
  32 + '专车',
  33 + '顺风车',
  34 + '代驾',
  35 + '公交',
  36 + '自驾租车',
  37 + '豪华车',
  38 + '二手车',
  39 + '出租车'
  40 + ]
  41 + }
  42 + },
26 components: { 43 components: {
27 Style, 44 Style,
28 - ScrollNav 45 + ScrollNavBar
29 }, 46 },
30 computed: { 47 computed: {
31 - // ...mapState(['resource']) 48 + ...mapState(['channelList','scrollnavidList']),
32 }, 49 },
33 methods: { 50 methods: {
34 - 51 + changeHandler(index) {
  52 + console.log(this.channelList.scrollnavList[index]); // value
  53 + // console.log(this.channelList.scrollnavidList[index]); // id
  54 + }
35 } 55 }
36 }; 56 };
37 </script> 57 </script>
  1 +<template>
  2 + <LayoutApp :show-back="true">
  3 + <Scroll :scrollEvents="['scroll']" :options="scrollOptions" @scroll="scroll"
  4 + @pulling-up="onPullingUp">
  5 + <ProductList :list="favoriteProductList"></ProductList>
  6 + </Scroll>
  7 + </LayoutApp>
  8 +</template>
  9 +<script>
  10 +import ProductList from '../../list/components/productList';
  11 +import {Scroll} from 'cube-ui';
  12 +import {createNamespacedHelpers} from 'vuex';
  13 +
  14 +const {mapState, mapActions} = createNamespacedHelpers('home/favorite');
  15 +
  16 +export default {
  17 + name: 'list',
  18 + components: {
  19 + ProductList,
  20 + Scroll
  21 + },
  22 + data() {
  23 + return {
  24 + scrollOptions: {
  25 + bounce: {
  26 + top: false
  27 + },
  28 + pullUpLoad: true
  29 + },
  30 + fixed: false
  31 + };
  32 + },
  33 + mounted() {
  34 + this.fetchFavoriteList();
  35 + },
  36 + methods: {
  37 + ...mapActions(['fetchFavoriteList']),
  38 +
  39 + async onPullingUp() {
  40 + await this.fetchFavoriteList();
  41 + },
  42 + scroll({ y }) {
  43 + const height = this.$refs.banner.$el.offsetHeight + this.$refs.header.offsetHeight;
  44 +
  45 + if (-y >= height) {
  46 + this.fixed = true;
  47 + } else {
  48 + this.fixed = false;
  49 + }
  50 + }
  51 + },
  52 + computed: {
  53 + ...mapState(['favoriteProductList']),
  54 + // getFa(){
  55 + // let length = this.favoriteProductList.product_list.lenght;
  56 + // console.log("length:"+length)
  57 + // },
  58 + },
  59 +};
  60 +</script>
  61 +
  62 +<style scoped>
  63 +</style>
  1 +export default [{
  2 + name: 'favorite',
  3 + path: '/xianyu/home/favorite.html',
  4 + component: () => import(/* webpackChunkName: "mine" */ './favorite')
  5 + }];
1 import Mine from './mine'; 1 import Mine from './mine';
2 import Trade from './tradeIncome'; 2 import Trade from './tradeIncome';
  3 +import Favorite from './favorite';
  4 +
3 export default [ 5 export default [
4 { 6 {
5 name: 'channel', 7 name: 'channel',
@@ -8,4 +10,5 @@ export default [ @@ -8,4 +10,5 @@ export default [
8 }, 10 },
9 ...Mine, 11 ...Mine,
10 ...Trade, 12 ...Trade,
  13 + ...Favorite,
11 ]; 14 ];
@@ -6,5 +6,7 @@ import Home from './home'; @@ -6,5 +6,7 @@ import Home from './home';
6 import Passport from './passport'; 6 import Passport from './passport';
7 import Address from './address'; 7 import Address from './address';
8 import Notice from './notice'; 8 import Notice from './notice';
  9 +import Category from './category';
  10 +
  11 +export default [...Order, ...Common, ...List, ...Product, ...Home, ...Passport, ...Address, ...Notice, ...Category];
9 12
10 -export default [...Order, ...Common, ...List, ...Product, ...Home, ...Passport, ...Address, ...Notice];  
@@ -45,6 +45,7 @@ export default { @@ -45,6 +45,7 @@ export default {
45 } 45 }
46 46
47 .item-price { 47 .item-price {
  48 + height: 32px;
48 margin-bottom: 38px; 49 margin-bottom: 38px;
49 font-size: 28px; 50 font-size: 28px;
50 color: #000; 51 color: #000;
@@ -64,5 +65,10 @@ export default { @@ -64,5 +65,10 @@ export default {
64 line-height: 40px; 65 line-height: 40px;
65 margin-top: 38px; 66 margin-top: 38px;
66 margin-bottom: 44px; 67 margin-bottom: 44px;
  68 + word-break: break-all;
  69 + display: -webkit-box;
  70 + -webkit-line-clamp: 2;
  71 + -webkit-box-orient: vertical;
  72 + overflow: hidden;
67 } 73 }
68 </style> 74 </style>
1 <template> 1 <template>
2 <LayoutApp :show-back="true"> 2 <LayoutApp :show-back="true">
3 - <Scroll :scrollEvents="['scroll']" :options="scrollOptions" @scroll="scroll" 3 + <div class="filter">
  4 + <div class="filter-tab">
  5 + <div class="tab-item" :class="selectedType === 2 && 'selected-tab'" @click="pressType(2)">人气</div>
  6 + <div class="tab-item middle" :class="selectedType === 1 && 'selected-tab'" @click="pressType(1)">
  7 + <span>价格</span>
  8 + <div :class="arrowImage"></div>
  9 + </div>
  10 + <div class="tab-item" :class="selectedType === 3 && 'selected-tab'" @click="pressType(3)">新品</div>
  11 + </div>
  12 + <div class="screen middle">
  13 + <div class="screen-img"></div>
  14 + 筛选
  15 + </div>
  16 + </div>
  17 + <Scroll :options="scrollOptions"
  18 + :data="productList.list"
4 @pulling-up="onPullingUp"> 19 @pulling-up="onPullingUp">
5 <ProductList :list="productList.list"></ProductList> 20 <ProductList :list="productList.list"></ProductList>
6 </Scroll> 21 </Scroll>
@@ -27,33 +42,143 @@ export default { @@ -27,33 +42,143 @@ export default {
27 }, 42 },
28 pullUpLoad: true 43 pullUpLoad: true
29 }, 44 },
30 - fixed: false 45 + fixed: false,
  46 + selectedType: 2,
  47 + priceDesc: true,
  48 + arrowImage: '',
  49 + searchKey: '',
  50 + listType: 1
31 }; 51 };
32 }, 52 },
33 mounted() { 53 mounted() {
34 - this.fetchProductList(); 54 + this.changeArrow();
  55 + let params = this.$route.params;
  56 +
  57 + if (Object.keys(params).length && params.listType) {
  58 + this.listType = params.listType;
  59 + }
  60 + this.fetchProductList({listType: this.listType, isReset: true});
  61 +
35 }, 62 },
36 methods: { 63 methods: {
37 ...mapActions(['fetchProductList']), 64 ...mapActions(['fetchProductList']),
38 65
  66 + // 上拉加载
39 async onPullingUp() { 67 async onPullingUp() {
40 - await this.fetchProductList(); 68 + await this.fetchProductList({listType: this.listType});
41 }, 69 },
42 - scroll({ y }) {  
43 - const height = this.$refs.banner.$el.offsetHeight + this.$refs.header.offsetHeight;  
44 70
45 - if (-y >= height) {  
46 - this.fixed = true;  
47 - } else {  
48 - this.fixed = false; 71 + // 点击tab type, 0: 推荐, 1: 价格, 2: 人气, 3: 新品
  72 + pressType(type) {
  73 + if (type === this.selectedType && type !== 1) {
  74 + return;
49 } 75 }
50 - } 76 + let params = {
  77 + type: 6,
  78 + query: this.searchKey,
  79 + sort: this.filterParams.sort.join(','),
  80 + brand: this.filterParams.brand.join(','), // 品牌id
  81 + gender: this.filterParams.gender.join(','), // 性别
  82 + size: this.filterParams.size.join(','), // 尺码id
  83 + };
  84 +
  85 + if (this.listType === 4) {
  86 + delete params.type;
  87 + }
  88 +
  89 + this.selectedType = type;
  90 + if (type === 1) {
  91 + this.priceDesc = !this.priceDesc;
  92 + params.order = !this.priceDesc ? 'p_desc' : 'p_asc';
  93 + } else if (type === 2) {
  94 + this.priceDesc = true;
  95 + params.order = 'sale_desc';
  96 + } else if (type === 3) {
  97 + this.priceDesc = true;
  98 + params.order = 'st_desc';
  99 + }
  100 + params.listType = this.listType;
  101 + params.isReset = true;
  102 + this.changeArrow();
  103 + this.fetchProductList(params);
  104 + },
  105 + changeArrow() {
  106 + this.arrowImage = (this.selectedType === 3 || this.selectedType === 2) ? 'price-arrow' :
  107 + this.priceDesc ? 'desc-arrow' : 'asc-arrow';
  108 + },
51 }, 109 },
52 computed: { 110 computed: {
53 - ...mapState(['productList']), 111 + ...mapState(['productList', 'filterParams']),
54 }, 112 },
55 }; 113 };
56 </script> 114 </script>
57 115
58 <style scoped> 116 <style scoped>
  117 + .filter {
  118 + display: flex;
  119 + height: 120px;
  120 + flex-direction: row;
  121 + justify-content: space-between;
  122 + align-items: center;
  123 + padding-left: 42px;
  124 + padding-right: 38px;
  125 + }
  126 +
  127 + .filter-tab {
  128 + display: flex;
  129 + flex-direction: row;
  130 + align-items: center;
  131 + font-size: 32px;
  132 + color: #999;
  133 + text-align: center;
  134 + }
  135 +
  136 + .selected-tab {
  137 + font-size: 40px;
  138 + color: #000;
  139 + font-weight: bold;
  140 + }
  141 +
  142 + .tab-item {
  143 + margin-right: 60px;
  144 + }
  145 +
  146 + .screen {
  147 + font-size: 32px;
  148 + color: #000;
  149 + letter-spacing: 0;
  150 + }
  151 +
  152 + .middle {
  153 + display: flex;
  154 + align-items: center;
  155 + }
  156 +
  157 + .asc-arrow {
  158 + width: 40px;
  159 + height: 40px;
  160 + background: url(~statics/image/list/asc_arrow@3x.png) no-repeat;
  161 + background-size: cover;
  162 + }
  163 +
  164 + .desc-arrow {
  165 + width: 40px;
  166 + height: 40px;
  167 + background: url(~statics/image/list/desc_arrow@3x.png) no-repeat;
  168 + background-size: cover;
  169 + }
  170 +
  171 + .price-arrow {
  172 + width: 40px;
  173 + height: 40px;
  174 + background: url(~statics/image/list/price_arrow@3x.png) no-repeat;
  175 + background-size: cover;
  176 + }
  177 +
  178 + .screen-img {
  179 + width: 40px;
  180 + height: 40px;
  181 + background: url(~statics/image/list/filter@3x.png) no-repeat;
  182 + background-size: cover;
  183 + }
59 </style> 184 </style>
@@ -21,10 +21,18 @@ export default [ @@ -21,10 +21,18 @@ export default [
21 component: () => import(/* webpackChunkName: "order" */ './pay-ok'), 21 component: () => import(/* webpackChunkName: "order" */ './pay-ok'),
22 }, 22 },
23 { 23 {
24 - name: 'buyerAskOrder', //买家求购确认 24 + name: 'buyerAskOrder', // 买家求购确认
25 path: '/xianyu/order/buyeraskorder.html', 25 path: '/xianyu/order/buyeraskorder.html',
26 component: () => import('./buyer-ask-order'), 26 component: () => import('./buyer-ask-order'),
27 }, 27 },
  28 +
  29 + // 物流信息
  30 + // code: 订单编码
  31 + {
  32 + name: 'orderLogisticsInfo',
  33 + path: '/xianyu/:owner/order/logistics/:code',
  34 + component: () => import('./order-logistics-info'),
  35 + },
28 ...PriceChange, 36 ...PriceChange,
29 ...OrderList, 37 ...OrderList,
30 ...OrderDetail, 38 ...OrderDetail,
  1 +<template>
  2 + <div class="address-wrapper">
  3 + <i class="address-icon"></i>
  4 + <div>
  5 + <p class="consignee">{{ userAddress.consignee }}</p>
  6 + <p class="area">{{ userAddress.area }}</p>
  7 + <p class="mobile">{{ userAddress.mobile }}</p>
  8 + </div>
  9 + </div>
  10 +</template>
  11 +
  12 +<script>
  13 +import { createNamespacedHelpers } from "vuex";
  14 +const { mapGetters } = createNamespacedHelpers("order/orderDetail");
  15 +
  16 +export default {
  17 + computed: {
  18 + ...mapGetters(["userAddress"])
  19 + }
  20 +};
  21 +</script>
  22 +
  23 +<style lang="scss" scoped>
  24 +.address-wrapper {
  25 + display: flex;
  26 + align-items: center;
  27 +
  28 + .consignee {
  29 + font-size: 32px;
  30 + font-weight: bold;
  31 + }
  32 +
  33 + .area {
  34 + color: #999;
  35 + margin: 12px 0;
  36 + }
  37 +
  38 + .mobile {
  39 + font: 28px;
  40 + }
  41 +
  42 + .address-icon {
  43 + width: 48px;
  44 + height: 48px;
  45 + display: block;
  46 + background-size: contain;
  47 + margin-right: 40px;
  48 + background-image: url("~statics/image/order/addr-icon@3x.png");
  49 + }
  50 +}
  51 +</style>
@@ -7,43 +7,49 @@ @@ -7,43 +7,49 @@
7 <p class="status-desc">{{ statusDetail.detailDesc }}</p> 7 <p class="status-desc">{{ statusDetail.detailDesc }}</p>
8 </div> 8 </div>
9 <!-- 物流信息 --> 9 <!-- 物流信息 -->
10 - <div class="logistics item-wrapper">  
11 - <div class="detail">  
12 - <p>{{ lastExpressInfo.acceptRemark }}</p>  
13 - <p>{{ lastExpressInfo.createTimeStr }}</p> 10 + <router-link :to="{ name: 'orderLogisticsInfo', params: $route.params }">
  11 + <div class="logistics-info item-wrapper">
  12 + <div class="content">
  13 + <i class="logistics-icon"></i>
  14 + <div class="info">
  15 + <p>{{ lastExpressInfo.acceptRemark }}</p>
  16 + <p>{{ lastExpressInfo.createTimeStr }}</p>
  17 + </div>
  18 + </div>
  19 + <i class="right-icon"></i>
14 </div> 20 </div>
15 - </div> 21 + </router-link>
16 <!-- 地址信息 --> 22 <!-- 地址信息 -->
17 - <logistic-info class="item-wrapper" /> 23 + <address-info class="item-wrapper" />
18 <!-- 商品信息 --> 24 <!-- 商品信息 -->
19 <order-item-info class="item-wrapper" /> 25 <order-item-info class="item-wrapper" />
20 <!-- 价格信息 --> 26 <!-- 价格信息 -->
21 <div class="price-info item-wrapper"> 27 <div class="price-info item-wrapper">
22 <p> 28 <p>
23 - <span>商品金额:</span>  
24 - <span>{{ priceInfo.goodPrice }}</span> 29 + <span class="label">商品金额:</span>
  30 + <span>¥{{ priceInfo.goodPrice }}</span>
25 </p> 31 </p>
26 - <p>  
27 - <span>运费:</span>  
28 - <span>{{ priceInfo.feePrice }}</span> 32 + <p class="delivery-fee">
  33 + <span class="label">运费:</span>
  34 + <span>¥{{ priceInfo.feePrice }}</span>
29 </p> 35 </p>
30 <p> 36 <p>
31 - <span>实际金额:</span>  
32 - <span>{{ priceInfo.realPayPrice }}</span> 37 + <span class="label">实际金额:</span>
  38 + <span class="pay-price">¥{{ priceInfo.realPayPrice }}</span>
33 </p> 39 </p>
34 </div> 40 </div>
35 <!-- 交易信息 --> 41 <!-- 交易信息 -->
36 <div class="trade-info item-wrapper"> 42 <div class="trade-info item-wrapper">
37 <p> 43 <p>
38 - <span>创建时间:</span> 44 + <span class="label">创建时间:</span>
39 <span>{{ orderDetail.createTime }}</span> 45 <span>{{ orderDetail.createTime }}</span>
40 </p> 46 </p>
41 <p> 47 <p>
42 - <span>订单编号:</span> 48 + <span class="label">订单编号:</span>
43 <span>{{ orderDetail.orderCode }}</span> 49 <span>{{ orderDetail.orderCode }}</span>
44 </p> 50 </p>
45 <p> 51 <p>
46 - <span>支付方式:</span> 52 + <span class="label">支付方式:</span>
47 <span>{{ orderDetail.paymentStr }}</span> 53 <span>{{ orderDetail.paymentStr }}</span>
48 </p> 54 </p>
49 </div> 55 </div>
@@ -59,7 +65,7 @@ @@ -59,7 +65,7 @@
59 65
60 <script> 66 <script>
61 import { createNamespacedHelpers } from "vuex"; 67 import { createNamespacedHelpers } from "vuex";
62 -import LogisticInfo from "./components/logistics-info"; 68 +import AddressInfo from "./components/address-info";
63 import OrderItemInfo from "./components/order-detail-item"; 69 import OrderItemInfo from "./components/order-detail-item";
64 import { Button } from "cube-ui"; 70 import { Button } from "cube-ui";
65 71
@@ -68,12 +74,12 @@ const { mapActions, mapState, mapGetters } = createNamespacedHelpers( @@ -68,12 +74,12 @@ const { mapActions, mapState, mapGetters } = createNamespacedHelpers(
68 ); 74 );
69 export default { 75 export default {
70 components: { 76 components: {
71 - LogisticInfo, 77 + AddressInfo,
72 OrderItemInfo, 78 OrderItemInfo,
73 Button 79 Button
74 }, 80 },
75 asyncData({ store, router }) { 81 asyncData({ store, router }) {
76 - store.dispatch("order/orderDetail/fetchOrderDetail", router.params); 82 + // store.dispatch("order/orderDetail/fetchOrderDetail", router.params);
77 }, 83 },
78 mounted() { 84 mounted() {
79 this.fetchOrderDetail(this.$route.params); 85 this.fetchOrderDetail(this.$route.params);
@@ -101,6 +107,7 @@ export default { @@ -101,6 +107,7 @@ export default {
101 height: 100vh; 107 height: 100vh;
102 overflow-x: hidden; 108 overflow-x: hidden;
103 overflow-y: auto; 109 overflow-y: auto;
  110 + font-size: 24px;
104 111
105 .item-wrapper { 112 .item-wrapper {
106 border-top: 1px solid #eee; 113 border-top: 1px solid #eee;
@@ -117,15 +124,79 @@ export default { @@ -117,15 +124,79 @@ export default {
117 } 124 }
118 125
119 .status-desc { 126 .status-desc {
120 - font-size: 24px;  
121 color: #999; 127 color: #999;
122 letter-spacing: 0; 128 letter-spacing: 0;
123 margin-top: 30px; 129 margin-top: 30px;
124 } 130 }
125 } 131 }
126 132
127 - .logistics { 133 + .logistics-info {
128 margin-top: 40px; 134 margin-top: 40px;
  135 + display: flex;
  136 + align-items: center;
  137 + justify-content: space-between;
  138 +
  139 + .content {
  140 + display: flex;
  141 + align-items: center;
  142 +
  143 + .info :last-child {
  144 + color: #999;
  145 + margin-top: 12px;
  146 + }
  147 + }
  148 +
  149 + .logistics-icon,
  150 + .right-icon {
  151 + width: 48px;
  152 + height: 48px;
  153 + display: block;
  154 + background-size: contain;
  155 + }
  156 +
  157 + .logistics-icon {
  158 + margin-right: 40px;
  159 + background-image: url("~statics/image/order/logistics-icon@3x.png");
  160 + }
  161 +
  162 + .right-icon {
  163 + background-image: url("~statics/image/order/right-arrow-icon@3x.png");
  164 + }
  165 + }
  166 +
  167 + .price-info {
  168 + font-size: 28px;
  169 +
  170 + & > p {
  171 + display: flex;
  172 + justify-content: space-between;
  173 + }
  174 +
  175 + & > p:first-child {
  176 + color: #999;
  177 + }
  178 +
  179 + .delivery-fee {
  180 + margin: 12px 0;
  181 + color: #999;
  182 + }
  183 +
  184 + .pay-price {
  185 + color: #d0021b;
  186 + }
  187 + }
  188 +
  189 + .trade-info {
  190 + font-size: 28px;
  191 +
  192 + & > :first-child + p {
  193 + margin: 20px 0;
  194 + }
  195 + }
  196 +
  197 + .label {
  198 + font-size: 28px;
  199 + margin-right: 12px;
129 } 200 }
130 201
131 .actions { 202 .actions {
1 <template> 1 <template>
2 <div class="logistics-wrapper"> 2 <div class="logistics-wrapper">
3 - <p>{{ userAddress.consignee }}</p>  
4 - <p>{{ userAddress.area }}</p>  
5 - <p>{{ userAddress.mobile }}</p> 3 + 物流信息
6 </div> 4 </div>
7 </template> 5 </template>
8 6
9 <script> 7 <script>
10 import { createNamespacedHelpers } from "vuex"; 8 import { createNamespacedHelpers } from "vuex";
11 -const { mapGetters } = createNamespacedHelpers("order/orderDetail"); 9 +const { mapActions } = createNamespacedHelpers("order/logisticsInfo");
12 10
13 export default { 11 export default {
14 - computed: {  
15 - ...mapGetters(["userAddress"]) 12 + computed: {},
  13 + mounted() {
  14 + this.fetchLogisticInfo(this.$route.params);
  15 + },
  16 + methods: {
  17 + ...mapActions(["fetchLogisticInfo"])
16 } 18 }
17 }; 19 };
18 </script> 20 </script>
19 21
20 <style lang="scss" scoped> 22 <style lang="scss" scoped>
  23 +.logistics-wrapper {
  24 + height: 100vh;
  25 + -webkit-box-orient: vertical;
  26 +}
21 </style> 27 </style>
  1 +import {get} from 'lodash';
  2 +import Vue from 'vue';
  3 +
  4 +export default function() {
  5 + return {
  6 + namespaced: true,
  7 + state: {
  8 + categoryParent: [],
  9 + categorySubList: [],
  10 + },
  11 + mutations: {
  12 + addCategoryParentList(state, {data}) {
  13 + let brand = {
  14 + id:'-1',
  15 + name: '品牌',
  16 + image: '',
  17 + linkType: '',
  18 + isSelect: true,
  19 + }
  20 + state.categoryParent.push(brand);
  21 + if (data && data.length) {
  22 + data.forEach(val => {
  23 + val.isSelect = false;
  24 + state.categoryParent.push(val);
  25 + });
  26 + }
  27 +
  28 + },
  29 +
  30 + addCategorySubList(state, {data}) {
  31 + if(data && data.category){
  32 + state.categorySubList = data.category;
  33 + }
  34 + },
  35 + addBrandList(state, {data}){
  36 + if(data && data.brand_list){
  37 + let sub = [];
  38 +
  39 + data.brand_list.forEach(val => {
  40 + val.isSelect = false;
  41 + let subItem = {
  42 + id: val.id,
  43 + name: val.brand_name,
  44 + image: val.brand_logo,
  45 + type: 1,//表示 品牌
  46 + linkType: '',
  47 + link: '',
  48 + }
  49 + sub.push(subItem);
  50 + });
  51 + let category = [{
  52 + id:'',
  53 + image:'',
  54 + linkType:'',
  55 + name:'全部品牌',
  56 + sub: sub,
  57 + }];
  58 + state.categorySubList = category;
  59 +
  60 + }
  61 + },
  62 + updateCategoryParentList(state, {id}) {
  63 + if (id) {
  64 + state.categoryParent.forEach((val, index) => {
  65 + if(id === val.id){
  66 + val.isSelect = true;
  67 + }else {
  68 + val.isSelect = false;
  69 + }
  70 + Vue.set(state.categoryParent, index, val);
  71 + });
  72 + }
  73 + }
  74 + },
  75 + actions: {
  76 + async fetchCategoryParentList({commit, state}) {
  77 +
  78 + const result = await this.$api.get('/api/ufo/category/saleCategory');
  79 + if (result.code === 200) {
  80 + commit('addCategoryParentList', {data: result.data});
  81 + }
  82 +
  83 + return result.data ? result.data.length : 0;
  84 + },
  85 + async fetchBrandList({commit, state}, {id}) {
  86 + if(id){
  87 + commit('updateCategoryParentList', {id: id});
  88 + }
  89 +
  90 + const result = await this.$api.get('/api/ufo/category/search/brandList');
  91 +
  92 + console.log(result);
  93 + if (result.code === 200) {
  94 + commit('addBrandList', {data: result.data});
  95 + }
  96 +
  97 + return result.data ? result.data.length : 0;
  98 + },
  99 + async fetchCategorySubList({commit, state},{id}) {
  100 +
  101 + commit('updateCategoryParentList', {id: id});
  102 + const result = await this.$api.get('/api/ufo/category/saleCategoryDetail',{ id });
  103 +
  104 + console.log(result);
  105 + if (result.code === 200) {
  106 + commit('addCategorySubList', {data: result.data});
  107 + }
  108 +
  109 + return result.data ? result.data.length : 0;
  110 + },
  111 + },
  112 + };
  113 +}
  1 +import Vue from 'vue';
1 import * as Types from './types'; 2 import * as Types from './types';
2 -import { get, set } from 'lodash';  
3 -import { getImgUrl } from '../../common/utils';  
4 3
5 export default function() { 4 export default function() {
6 return { 5 return {
7 namespaced: true, 6 namespaced: true,
8 state: { 7 state: {
9 - channelData: [], 8 + // channelData: [],
  9 + channelList: {
  10 + list: [], // 资源列表
  11 + productlist: [], // 资源列表
  12 + page: 0, // 当前页
  13 + page_size: 10, // 每页数量
  14 + page_total: 0, // 总共多少页
  15 + total: 0, // 总共多少条
  16 + scrollnavList: [], // 导航菜单
  17 + // scrollnavidList: [], // 导航菜单id
  18 + },
10 }, 19 },
11 mutations: { 20 mutations: {
12 [Types.FETCH_CHANNEL](state, { list }) { 21 [Types.FETCH_CHANNEL](state, { list }) {
13 - state.channelData = list; 22 + state.channelList.list = list;
  23 + state.channelList.list.map(res => {
  24 + if (res.template_name === 'hotSeries') {
  25 + for (let i = 0; i < res.data.length; i++) {
  26 + state.channelList.scrollnavList.push(res.data[i].series_name);
  27 + // state.channelList.scrollnavidList.push(res.data[i].series_id);
  28 + }
  29 + }
  30 + });
  31 + },
  32 + [Types.FETCH_PRODUCT](state, { productlist }) {
  33 + // state.channelList.productlist = productlist;
  34 + Vue.set(state.channelList, 'productlist', state.channelList.productlist.concat(productlist.product_list));
  35 + Vue.set(state.channelList, 'page', productlist.page);
14 }, 36 },
15 }, 37 },
16 actions: { 38 actions: {
  39 + async fetchProductList({ commit, state }) {
  40 + let page = state.channelList.page;
  41 + let size = state.channelList.page_size;
  42 + const result = await this.$api.get('/api/ufo/list/productList', {
  43 + page: page + 1,
  44 + size,
  45 + });
  46 +
  47 + if (result.code === 200) {
  48 + commit(Types.FETCH_PRODUCT, {productlist: result.data});
  49 + }
  50 + },
17 async fetchChannelList({ commit }) { 51 async fetchChannelList({ commit }) {
18 const result = await this.$api.get('/api/ufo/channel/channelList', { 52 const result = await this.$api.get('/api/ufo/channel/channelList', {
19 content_code: '9cb6138be8e60c96f48107da481816c3', 53 content_code: '9cb6138be8e60c96f48107da481816c3',
20 uid: '64668089', 54 uid: '64668089',
21 }); 55 });
22 if (result.code === 200) { 56 if (result.code === 200) {
23 - result.data.map(res => {  
24 - // 焦点图  
25 - if(res.template_name === 'focus') {  
26 - for (let i = 0; i < res.data.length; i++) {  
27 - let url = "https:" + getImgUrl(get(res.data[i], "src") || '', 750, 200);  
28 - set(res.data[i], "src", url);  
29 - }  
30 - }  
31 - // 热门系列  
32 - if(res.template_name === 'hotSeries') {  
33 - for (let i = 0; i < res.data.length; i++) {  
34 - let url = "https:" + getImgUrl(get(res.data[i], "image_url") || '', 100, 80);  
35 - set(res.data[i], "image_url", url);  
36 - }  
37 - }  
38 - })  
39 - console.log(result.data);  
40 commit(Types.FETCH_CHANNEL, { list: result.data }); 57 commit(Types.FETCH_CHANNEL, { list: result.data });
41 } 58 }
42 } 59 }
  1 +import { get, set } from 'lodash';
  2 +import { getImgUrl } from '../../common/utils';
  3 +import Vue from 'vue';
  4 +const uid = '500031170';
  5 +
  6 +export default function() {
  7 + return {
  8 + namespaced: true,
  9 + state: {
  10 + page: 1,
  11 + pageTotal: 0,
  12 + recId: '',
  13 + favoriteProductList: [],
  14 + },
  15 + mutations: {
  16 + addList(state, { data }) {
  17 + if(data && data.product_list){
  18 + let list = state.favoriteProductList.list.concat(data.product_list);
  19 + Vue.set(state.favoriteProductList, "list", list);
  20 + }
  21 +
  22 + },
  23 +
  24 + },
  25 + actions: {
  26 + async fetchFavoriteList({ commit }) {
  27 + const result = await this.$api.get('/api/ufo/home/favoriteProduct', {uid});
  28 + if (result.code === 200) {
  29 + let data =result.data;
  30 + commit('addList', { data:data });
  31 + }
  32 + return result.data || [];
  33 + },
  34 + },
  35 + };
  36 +}
1 import mine from './mine'; 1 import mine from './mine';
2 import channel from './channel' 2 import channel from './channel'
  3 +import favorite from './favorite'
3 export default function() { 4 export default function() {
4 return { 5 return {
5 namespaced: true, 6 namespaced: true,
@@ -16,7 +17,8 @@ export default function() { @@ -16,7 +17,8 @@ export default function() {
16 }, 17 },
17 modules: { 18 modules: {
18 mine: mine(), 19 mine: mine(),
19 - channel: channel() 20 + channel: channel(),
  21 + favorite: favorite(),
20 } 22 }
21 }; 23 };
22 } 24 }
@@ -3,3 +3,9 @@ export const FETCH_NOTICE_LIST_FAILD = 'FETCH_NOTICE_LIST_FAILD'; @@ -3,3 +3,9 @@ export const FETCH_NOTICE_LIST_FAILD = 'FETCH_NOTICE_LIST_FAILD';
3 export const FETCH_NOTICE_LIST_SUCCESS = 'FETCH_NOTICE_LIST_SUCCESS'; 3 export const FETCH_NOTICE_LIST_SUCCESS = 'FETCH_NOTICE_LIST_SUCCESS';
4 4
5 export const FETCH_CHANNEL = 'FETCH_CHANNEL'; 5 export const FETCH_CHANNEL = 'FETCH_CHANNEL';
  6 +export const FETCH_PRODUCT = 'FETCH_PRODUCT';
  7 +
  8 +
  9 +export const FETCH_FAVORITE_LIST_REQUEST = 'FETCH_FAVORITE_LIST_REQUEST';
  10 +export const FETCH_FAVORITE_LIST_FAILD = 'FETCH_FAVORITE_LIST_FAILD';
  11 +export const FETCH_FAVORITE_LIST_SUCCESS = 'FETCH_FAVORITE_LIST_SUCCESS';
@@ -10,6 +10,7 @@ import storeHome from './home'; @@ -10,6 +10,7 @@ import storeHome from './home';
10 10
11 import storeAddress from './address'; 11 import storeAddress from './address';
12 import storeNotice from './notice'; 12 import storeNotice from './notice';
  13 +import storeCategory from './category';
13 14
14 Vue.use(Vuex); 15 Vue.use(Vuex);
15 16
@@ -27,6 +28,10 @@ export function createStore(context) { @@ -27,6 +28,10 @@ export function createStore(context) {
27 28
28 // 买家订单列表 29 // 买家订单列表
29 notice: storeNotice(), 30 notice: storeNotice(),
  31 +
  32 + category: storeCategory(),
  33 + // buyerOderList: buyerOderList(),
  34 +
30 }, 35 },
31 36
32 strict: process.env.NODE_ENV !== 'production', 37 strict: process.env.NODE_ENV !== 'production',
1 import {get} from 'lodash'; 1 import {get} from 'lodash';
2 -import Vue from 'vue';  
3 2
4 export default function() { 3 export default function() {
5 return { 4 return {
@@ -19,7 +18,7 @@ export default function() { @@ -19,7 +18,7 @@ export default function() {
19 }, 18 },
20 searchParams: { 19 searchParams: {
21 type: 0, // type:0,推荐;1,热销;2,即将发售; 3,品类; 4,品牌;5,系列;6,搜索 7, 收藏 20 type: 0, // type:0,推荐;1,热销;2,即将发售; 3,品类; 4,品牌;5,系列;6,搜索 7, 收藏
22 - order: null, // 指定排序 21 + order: 'sale_desc', // 指定排序
23 productPool: null, // 商品池id 22 productPool: null, // 商品池id
24 sort: null, // 品类id 23 sort: null, // 品类id
25 brand: null, // 品牌id 24 brand: null, // 品牌id
@@ -43,25 +42,83 @@ export default function() { @@ -43,25 +42,83 @@ export default function() {
43 }, 42 },
44 mutations: { 43 mutations: {
45 addProductList(state, {data}) { 44 addProductList(state, {data}) {
46 - Vue.set(state.productList, 'list', state.productList.list.concat(data.product_list));  
47 - Vue.set(state.productList, 'page', data.page); 45 + let {productList} = state;
  46 +
  47 + if (typeof data === 'object' && Object.keys(data).length) {
  48 + for (let key in data) {
  49 + if (key === 'product_list') {
  50 + productList.list = data.page > 1 ? productList.list.concat(data.product_list) : data.product_list;
  51 + } else {
  52 + productList[key] = data[key];
  53 + }
  54 + }
  55 + state.productList = productList;
  56 + }
48 }, 57 },
  58 + setSearchParams(state, {params}) {
  59 + state.searchParams = Object.assign(state.searchParams, params);
  60 + },
  61 + addFilterData(state, {filter}) {
  62 + state.filterData = filter;
  63 + }
49 }, 64 },
50 actions: { 65 actions: {
51 - async fetchProductList({commit, state}) {  
52 - let page = state.productList.page;  
53 - let size = state.productList.page_size;  
54 - const result = await this.$api.get('/api/ufo/list/productList', {  
55 - page: page + 1,  
56 - size: size 66 + fetchProductList: async function({commit, state}, params) {
  67 + let searchParams = state.searchParams;
  68 + let list = state.productList;
  69 + let pageSize = list.page_size;
  70 + let isReset = false;
  71 +
  72 + if (params && params.isReset) {
  73 + isReset = true;
  74 + delete params.isReset;
  75 + }
  76 + if (params && Object.keys(params).length) {
  77 + searchParams = Object.assign(searchParams, params);
  78 + commit('setSearchParams', {params: searchParams});
  79 + }
  80 +
  81 + if (!isReset && (list.endReached || (!list.endReached && list.page_total === 1))) {
  82 + return;
  83 + }
  84 + let page = isReset ? 1 : (list.page + 1);
  85 +
  86 + for (let key in searchParams) {
  87 + if (!searchParams[key]) {
  88 + delete searchParams[key];
  89 + }
  90 + }
  91 + let result = await this.$api.get('/api/ufo/list/productList', {
  92 + ...searchParams,
  93 + page,
  94 + pageSize
57 }); 95 });
58 96
59 if (result.code === 200) { 97 if (result.code === 200) {
60 - commit('addProductList', {data: result.data}); 98 + let {data} = result;
  99 +
  100 + data.endReached = (data.page === data.page_total) && (data.page_size !== 1);
  101 + commit('addProductList', {data});
61 } 102 }
62 103
63 return result.data ? result.data.length : 0; 104 return result.data ? result.data.length : 0;
64 }, 105 },
65 }, 106 },
  107 + fetchFilterData: async function({commit, state}) {
  108 + let searchParams = state.searchParams;
  109 +
  110 + for (let key in searchParams) {
  111 + if (!searchParams[key]) {
  112 + delete searchParams[key];
  113 + }
  114 + }
  115 + let result = await this.$api.get('/api/ufo/list/filterData', {...searchParams});
  116 +
  117 + if (result.code === 200) {
  118 + let {data} = result;
  119 +
  120 + commit('addFilterData', {filter: data.filter});
  121 + }
  122 + }
66 }; 123 };
67 } 124 }
@@ -2,6 +2,7 @@ import priceChange from './price-change'; @@ -2,6 +2,7 @@ import priceChange from './price-change';
2 import orderList from './order-list'; 2 import orderList from './order-list';
3 import orderConfirm from './order-confirm'; 3 import orderConfirm from './order-confirm';
4 import orderDetail from './order-detail'; 4 import orderDetail from './order-detail';
  5 +import orderLogistics from './order-logistics';
5 6
6 export default function() { 7 export default function() {
7 return { 8 return {
@@ -11,6 +12,7 @@ export default function() { @@ -11,6 +12,7 @@ export default function() {
11 orderList: orderList(), 12 orderList: orderList(),
12 orderConfirm: orderConfirm(), 13 orderConfirm: orderConfirm(),
13 orderDetail: orderDetail(), 14 orderDetail: orderDetail(),
  15 + logisticsInfo: orderLogistics(),
14 }, 16 },
15 }; 17 };
16 } 18 }
@@ -27,7 +27,7 @@ export default function() { @@ -27,7 +27,7 @@ export default function() {
27 async fetchOrderDetail({ commit }, { owner, code } = {}) { 27 async fetchOrderDetail({ commit }, { owner, code } = {}) {
28 const res = await this.$api.get('/api/order/detail', { 28 const res = await this.$api.get('/api/order/detail', {
29 tabType: owner, 29 tabType: owner,
30 - orderCode: code, 30 + orderCode: +code,
31 31
32 // Todo 删除 32 // Todo 删除
33 uid: 600043484, 33 uid: 600043484,
  1 +export default function() {
  2 + return {
  3 + namespaced: true,
  4 + state: {
  5 + logisticInfo: {},
  6 + },
  7 + mutations: {
  8 + initData: (state, data) => {
  9 + state.logisticInfo = data;
  10 + },
  11 + },
  12 + actions: {
  13 + // 获取物流信息
  14 + async fetchLogisticInfo({ commit }, { owner, code } = {}) {
  15 + const res = await this.$api.get('/api/order/express', {
  16 + tabType: owner,
  17 + orderCode: +code,
  18 +
  19 + // Todo 删除
  20 + uid: 600043484,
  21 + });
  22 +
  23 + if (res.code === 200) {
  24 + commit('initData', res.data);
  25 + }
  26 + },
  27 + },
  28 + };
  29 +}
@@ -13,6 +13,7 @@ const webpackConfig = merge(baseConfig, { @@ -13,6 +13,7 @@ const webpackConfig = merge(baseConfig, {
13 entry: { 13 entry: {
14 app: './apps/entry-client.js', 14 app: './apps/entry-client.js',
15 }, 15 },
  16 + devtool: isProd ? 'source-map' : 'cheap-module-eval-source-map',
16 optimization: { 17 optimization: {
17 runtimeChunk: true, 18 runtimeChunk: true,
18 splitChunks: { 19 splitChunks: {
@@ -3,51 +3,52 @@ const merge = require('webpack-merge'); @@ -3,51 +3,52 @@ const merge = require('webpack-merge');
3 const nodeExternals = require('webpack-node-externals'); 3 const nodeExternals = require('webpack-node-externals');
4 const VueSSRServerPlugin = require('vue-server-renderer/server-plugin'); 4 const VueSSRServerPlugin = require('vue-server-renderer/server-plugin');
5 let baseConfig = require('./webpack.base.conf'); 5 let baseConfig = require('./webpack.base.conf');
6 -const isProd = process.env.NODE_ENV === 'production';  
7 6
8 let webpackConfig = merge(baseConfig, { 7 let webpackConfig = merge(baseConfig, {
9 entry: { 8 entry: {
10 - app: './apps/entry-server.js' 9 + app: './apps/entry-server.js',
11 }, 10 },
12 - devtool: isProd ? 'source-map' : 'cheap-module-source-map',  
13 target: 'node', 11 target: 'node',
14 resolve: { 12 resolve: {
15 alias: { 13 alias: {
16 'create-api': 'common/create-api-server.js', 14 'create-api': 'common/create-api-server.js',
17 - 'report-error': 'common/report-error-server.js'  
18 - } 15 + 'report-error': 'common/report-error-server.js',
  16 + },
19 }, 17 },
20 module: { 18 module: {
21 rules: [ 19 rules: [
22 { 20 {
23 test: /\.s?css$/, 21 test: /\.s?css$/,
24 - use: 'ignore-loader'  
25 - }, { 22 + use: 'ignore-loader',
  23 + },
  24 + {
26 test: /\.styl(us)?$/, 25 test: /\.styl(us)?$/,
27 - use: 'ignore-loader'  
28 - }, { 26 + use: 'ignore-loader',
  27 + },
  28 + {
29 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 29 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
30 - use: 'ignore-loader'  
31 - }, { 30 + use: 'ignore-loader',
  31 + },
  32 + {
32 test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 33 test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
33 - use: 'ignore-loader'  
34 - }  
35 - ] 34 + use: 'ignore-loader',
  35 + },
  36 + ],
36 }, 37 },
37 output: { 38 output: {
38 libraryTarget: 'commonjs2', 39 libraryTarget: 'commonjs2',
39 }, 40 },
40 externals: nodeExternals({ 41 externals: nodeExternals({
41 - whitelist: [/cube-ui/] 42 + whitelist: [/cube-ui/],
42 }), 43 }),
43 plugins: [ 44 plugins: [
44 new VueSSRServerPlugin({ 45 new VueSSRServerPlugin({
45 - filename: '../../manifest.server.json' 46 + filename: '../../manifest.server.json',
46 }), 47 }),
47 new webpack.DefinePlugin({ 48 new webpack.DefinePlugin({
48 - 'process.env.VUE_ENV': '"server"'  
49 - })  
50 - ] 49 + 'process.env.VUE_ENV': '"server"',
  50 + }),
  51 + ],
51 }); 52 });
52 53
53 module.exports = webpackConfig; 54 module.exports = webpackConfig;
@@ -4,6 +4,8 @@ const listApi = require('./list-api-map'); @@ -4,6 +4,8 @@ const listApi = require('./list-api-map');
4 const homeApi = require('./home-api-map'); 4 const homeApi = require('./home-api-map');
5 const passportApi = require('./passport-api-map'); 5 const passportApi = require('./passport-api-map');
6 const addressApi = require('./address-api-map'); 6 const addressApi = require('./address-api-map');
  7 +const orderListApi = require('./order-api-map');
  8 +const categoryApi = require('./category-api-map');
7 9
8 module.exports = { 10 module.exports = {
9 ...orderApi, 11 ...orderApi,
@@ -12,4 +14,6 @@ module.exports = { @@ -12,4 +14,6 @@ module.exports = {
12 ...homeApi, 14 ...homeApi,
13 ...passportApi, 15 ...passportApi,
14 ...addressApi, 16 ...addressApi,
  17 + ...orderListApi,
  18 + ...categoryApi,
15 }; 19 };
  1 +module.exports = {
  2 + '/api/ufo/category/saleCategory': {
  3 + ufo: true,
  4 + api: 'ufo.product.saleCategory',
  5 + params: {},
  6 + },
  7 + '/api/ufo/category/search/brandList': {
  8 + ufo: true,
  9 + api: 'ufo.product.search.brandList',
  10 + params: {
  11 + },
  12 + },
  13 + '/api/ufo/category/saleCategoryDetail': {
  14 + ufo: true,
  15 + api: 'ufo.product.saleCategoryDetail',
  16 + params: {
  17 + id: { type: String }
  18 + },
  19 + },
  20 + };
  21 +
@@ -17,4 +17,11 @@ module.exports = { @@ -17,4 +17,11 @@ module.exports = {
17 coupon_token: {type: String}, // 优惠券token 17 coupon_token: {type: String}, // 优惠券token
18 }, 18 },
19 }, 19 },
  20 + '/api/ufo/list/filterData': {
  21 + ufo: true,
  22 + api: 'ufo.product.search.list.filter',
  23 + params: {
  24 +
  25 + }
  26 + }
20 }; 27 };
@@ -31,7 +31,7 @@ module.exports = { @@ -31,7 +31,7 @@ module.exports = {
31 auth: true, 31 auth: true,
32 api: 'ufo.buyer.confirm', 32 api: 'ufo.buyer.confirm',
33 params: { 33 params: {
34 - order_code: { type: Number, require: true }, // 订单编号 34 + orderCode: { type: Number, require: true }, // 订单编号
35 }, 35 },
36 }, 36 },
37 37
@@ -69,4 +69,14 @@ module.exports = { @@ -69,4 +69,14 @@ module.exports = {
69 api: 'ufo.user.aliPayAccountQuery', 69 api: 'ufo.user.aliPayAccountQuery',
70 }, 70 },
71 71
  72 + // 订单物流信息
  73 + '/api/order/express': {
  74 + ufo: true,
  75 + auth: true,
  76 + api: 'ufo.order.expressDetailInfo',
  77 + params: {
  78 + tabType: { type: String, require: true }, // 订单来源
  79 + orderCode: { type: Number, require: true }, // 订单编号
  80 + },
  81 + },
72 }; 82 };