Authored by zhangwenxue

商品详情:调整state

@@ -3,18 +3,18 @@ @@ -3,18 +3,18 @@
3 <LayoutHeader class="layout-header" :show-back="true"> 3 <LayoutHeader class="layout-header" :show-back="true">
4 <template> 4 <template>
5 <transition name="fade"> 5 <transition name="fade">
6 - <img-size v-show="headThumbnailVisible" class="title-thumbnail" :src="imageList[0] && imageList[0].image_url" :width="300" :height="300"/> 6 + <img-size v-show="headThumbnailVisible" class="title-thumbnail" :src="imageList && imageList[0] && imageList[0].image_url" :width="300" :height="300"/>
7 </transition> 7 </transition>
8 </template> 8 </template>
9 9
10 <template #opts> 10 <template #opts>
11 - <cube-button class="icon-fav" :light="true" v-if="productDetail.isFav" @click="_toggleFav(true)"> 11 + <cube-button class="icon-fav" :light="true" v-if="productDetail.isFav" @click="_toggleFav(false)">
12 <svg id="icon-heart" style="width: 1rem; height: 1rem;" viewBox="0 0 28 28"> 12 <svg id="icon-heart" style="width: 1rem; height: 1rem;" viewBox="0 0 28 28">
13 <title>heart</title> 13 <title>heart</title>
14 <path d="M14 26c-0.25 0-0.5-0.094-0.688-0.281l-9.75-9.406c-0.125-0.109-3.563-3.25-3.563-7 0-4.578 2.797-7.313 7.469-7.313 2.734 0 5.297 2.156 6.531 3.375 1.234-1.219 3.797-3.375 6.531-3.375 4.672 0 7.469 2.734 7.469 7.313 0 3.75-3.437 6.891-3.578 7.031l-9.734 9.375c-0.187 0.187-0.438 0.281-0.688 0.281z"></path> 14 <path d="M14 26c-0.25 0-0.5-0.094-0.688-0.281l-9.75-9.406c-0.125-0.109-3.563-3.25-3.563-7 0-4.578 2.797-7.313 7.469-7.313 2.734 0 5.297 2.156 6.531 3.375 1.234-1.219 3.797-3.375 6.531-3.375 4.672 0 7.469 2.734 7.469 7.313 0 3.75-3.437 6.891-3.578 7.031l-9.734 9.375c-0.187 0.187-0.438 0.281-0.688 0.281z"></path>
15 </svg> 15 </svg>
16 </cube-button> 16 </cube-button>
17 - <cube-button class="icon-fav" :light="true" v-else @click="_toggleFav(false)"> 17 + <cube-button class="icon-fav" :light="true" v-else @click="_toggleFav(true)">
18 <svg id="icon-heart-o" style="width: 1rem; height: 1rem;" viewBox="0 0 28 28"> 18 <svg id="icon-heart-o" style="width: 1rem; height: 1rem;" viewBox="0 0 28 28">
19 <title>heart-o</title> 19 <title>heart-o</title>
20 <path d="M26 9.312c0-4.391-2.969-5.313-5.469-5.313-2.328 0-4.953 2.516-5.766 3.484-0.375 0.453-1.156 0.453-1.531 0-0.812-0.969-3.437-3.484-5.766-3.484-2.5 0-5.469 0.922-5.469 5.313 0 2.859 2.891 5.516 2.922 5.547l9.078 8.75 9.063-8.734c0.047-0.047 2.938-2.703 2.938-5.563zM28 9.312c0 3.75-3.437 6.891-3.578 7.031l-9.734 9.375c-0.187 0.187-0.438 0.281-0.688 0.281s-0.5-0.094-0.688-0.281l-9.75-9.406c-0.125-0.109-3.563-3.25-3.563-7 0-4.578 2.797-7.313 7.469-7.313 2.734 0 5.297 2.156 6.531 3.375 1.234-1.219 3.797-3.375 6.531-3.375 4.672 0 7.469 2.734 7.469 7.313z"></path> 20 <path d="M26 9.312c0-4.391-2.969-5.313-5.469-5.313-2.328 0-4.953 2.516-5.766 3.484-0.375 0.453-1.156 0.453-1.531 0-0.812-0.969-3.437-3.484-5.766-3.484-2.5 0-5.469 0.922-5.469 5.313 0 2.859 2.891 5.516 2.922 5.547l9.078 8.75 9.063-8.734c0.047-0.047 2.938-2.703 2.938-5.563zM28 9.312c0 3.75-3.437 6.891-3.578 7.031l-9.734 9.375c-0.187 0.187-0.438 0.281-0.688 0.281s-0.5-0.094-0.688-0.281l-9.75-9.406c-0.125-0.109-3.563-3.25-3.563-7 0-4.578 2.797-7.313 7.469-7.313 2.734 0 5.297 2.156 6.531 3.375 1.234-1.219 3.797-3.375 6.531-3.375 4.672 0 7.469 2.734 7.469 7.313z"></path>
@@ -46,10 +46,9 @@ @@ -46,10 +46,9 @@
46 <img-size :src="sizeImg(resource.src)" :width="300" :height="60"/> 46 <img-size :src="sizeImg(resource.src)" :width="300" :height="60"/>
47 </a> 47 </a>
48 <div class="info-list"> 48 <div class="info-list">
49 - <div class="info-list-item" v-if="activity && activity.length !== 0"> 49 + <div class="info-list-item" v-if="activity && activity.length !== 0" @click="showActivity">
50 <div class="info-list-name">促销</div> 50 <div class="info-list-name">促销</div>
51 - <div class="info-list-value info-promote" @click="showActivity"  
52 - > 51 + <div class="info-list-value info-promote">
53 <span>{{activity[0].promotionTypeStr}}</span> 52 <span>{{activity[0].promotionTypeStr}}</span>
54 <i class="cubeic-arrow"></i> 53 <i class="cubeic-arrow"></i>
55 </div> 54 </div>
@@ -166,16 +165,23 @@ export default { @@ -166,16 +165,23 @@ export default {
166 }, 165 },
167 }, 166 },
168 beforeRouteUpdate(to, from, next) { 167 beforeRouteUpdate(to, from, next) {
169 - const loading = this.createLoading(); 168 + // const loading = this.createLoading();
170 169
171 - this.loadData(to.params.productId, loading).then(next); 170 + this.loadData(to.params.productId).then(next);
172 }, 171 },
173 mounted() { 172 mounted() {
174 this.loadData(this.productId); 173 this.loadData(this.productId);
175 this.imageHideThreadhold = -window.innerWidth * 0.8; 174 this.imageHideThreadhold = -window.innerWidth * 0.8;
176 }, 175 },
  176 + activated() {
  177 + this.refresh();
  178 + },
177 methods: { 179 methods: {
178 ...mapActions(['fetchProductInfo', 'toggleFav', 'updateTradeInfo', 'getSelectedTradeProduct']), 180 ...mapActions(['fetchProductInfo', 'toggleFav', 'updateTradeInfo', 'getSelectedTradeProduct']),
  181 + refresh() {
  182 + this.$refs.slide.refresh();
  183 + this.headThumbnailVisible = false;
  184 + },
179 handleScroll(e) { 185 handleScroll(e) {
180 this.headThumbnailVisible = e.y < this.imageHideThreadhold; 186 this.headThumbnailVisible = e.y < this.imageHideThreadhold;
181 }, 187 },
@@ -194,6 +200,9 @@ export default { @@ -194,6 +200,9 @@ export default {
194 200
195 return this.fetchProductInfo({productId}).then(() => { 201 return this.fetchProductInfo({productId}).then(() => {
196 loading && loading.hide(); 202 loading && loading.hide();
  203 + setTimeout(() => {
  204 + this.refresh();
  205 + }, 200);
197 }).catch(() => { 206 }).catch(() => {
198 loading && loading.hide(); 207 loading && loading.hide();
199 }); 208 });
@@ -217,9 +226,6 @@ export default { @@ -217,9 +226,6 @@ export default {
217 onSizeSelectSheetHidden() { 226 onSizeSelectSheetHidden() {
218 this.showSizeSelectSheet = false; 227 this.showSizeSelectSheet = false;
219 }, 228 },
220 - gotoProduction(productId) {  
221 - this.$router.push({name: this.$route.name, params: {productId}});  
222 - },  
223 buy() { 229 buy() {
224 this.showBuySheet = true; 230 this.showBuySheet = true;
225 }, 231 },
@@ -234,6 +240,7 @@ export default { @@ -234,6 +240,7 @@ export default {
234 name: 'OrderSellConfirm', 240 name: 'OrderSellConfirm',
235 query: tradeProduct 241 query: tradeProduct
236 }); 242 });
  243 + this.showSizeSelectSheet = false;
237 }, 244 },
238 onRequestSize() { 245 onRequestSize() {
239 this.showSizeSelectSheet = false; 246 this.showSizeSelectSheet = false;
@@ -283,6 +290,11 @@ export default { @@ -283,6 +290,11 @@ export default {
283 } 290 }
284 } 291 }
285 292
  293 + .cube-slide-item {
  294 + img {
  295 + margin: 0 auto;
  296 + }
  297 + }
286 .banner { 298 .banner {
287 padding: 20px 0 0; 299 padding: 20px 0 0;
288 display: block; 300 display: block;
@@ -3,26 +3,27 @@ import { get } from 'lodash'; @@ -3,26 +3,27 @@ import { get } from 'lodash';
3 3
4 export default { 4 export default {
5 async fetchProductInfo({commit}, {productId}) { 5 async fetchProductInfo({commit}, {productId}) {
6 - const queryTasks = ['', '/resource', '/activity', '/recommend'].map(path => { 6 + const queryTasks = ['', '/fav', '/resource', '/activity', '/recommend'].map(path => {
7 return this.$api.get(`/api/ufo/product${path}`, {product_id: productId}).then(result => { 7 return this.$api.get(`/api/ufo/product${path}`, {product_id: productId}).then(result => {
8 if (result.code === 200) { 8 if (result.code === 200) {
9 return result.data; 9 return result.data;
10 } else { 10 } else {
11 - throw new Error(result.message); 11 + return null;
12 } 12 }
13 }); 13 });
14 }); 14 });
15 15
16 - let [detail,resource, activity, recommend] = await Promise.all(queryTasks);  
17 - resource = []; 16 + const [detail, isFav, resource, activity, recommend] = await Promise.all(queryTasks);
  17 +
18 commit(Types.UPDATE_PRODUCT_DETAIL, Object.assign(detail.product_info, { 18 commit(Types.UPDATE_PRODUCT_DETAIL, Object.assign(detail.product_info, {
19 resource: get(resource, '[0].data[0]', null), 19 resource: get(resource, '[0].data[0]', null),
20 - activity, 20 + isFav,
  21 + activity: activity || [],
21 recommend: recommend && recommend.product_list || [], 22 recommend: recommend && recommend.product_list || [],
22 })); 23 }));
23 }, 24 },
24 async toggleFav({commit}, {productId, isFav}) { 25 async toggleFav({commit}, {productId, isFav}) {
25 - const result = await this.$api.get(`/api/ufo/product/${isFav ? 'add' : 'cancel'}`, {product_id: productId}); 26 + const result = await this.$api.get(`/api/ufo/product/${isFav ? 'add' : 'cancel'}`, {productId});
26 27
27 if (result && result.code === 200) { 28 if (result && result.code === 200) {
28 commit(Types.UPDATE_PRODUCT_FAV, {productId, isFav}); 29 commit(Types.UPDATE_PRODUCT_FAV, {productId, isFav});
@@ -48,8 +49,7 @@ export default { @@ -48,8 +49,7 @@ export default {
48 productId = parseInt(productId, 10); 49 productId = parseInt(productId, 10);
49 storageId = parseInt(storageId, 10); 50 storageId = parseInt(storageId, 10);
50 tradeTypeId = parseInt(tradeTypeId, 10); 51 tradeTypeId = parseInt(tradeTypeId, 10);
51 - if (!(state.selectedProductInfo && state.selectedProductInfo.productId === productId ||  
52 - state.products.byId[productId])) { 52 + if (state.selectedProductInfo.productId !== productId && state.product.product_id !== productId) {
53 await dispatch('fetchProductInfo', {productId}); 53 await dispatch('fetchProductInfo', {productId});
54 } 54 }
55 55
1 import actions from './actions'; 1 import actions from './actions';
2 import mutations from './mutations'; 2 import mutations from './mutations';
3 -import { get } from 'lodash';  
4 3
5 -export default function() { 4 +export function defaultState() {
6 return { 5 return {
7 - namespaced: true,  
8 - state: {  
9 - products: {  
10 - byId: {}, 6 + product: {
  7 + brand_name: '',
  8 + canPublishSecondHand: false,
  9 + gender: '通用',
  10 + goods_list: [
  11 + {
  12 + canAddSize: false,
  13 + color_name: '',
  14 + goods_id: null,
  15 + goods_name: '-',
  16 + image_list: [
  17 + ],
  18 + size_list: [
  19 + ]
  20 + }
  21 + ],
  22 + least_price: null,
  23 + max_price: null,
  24 + max_sort_id: null,
  25 + min_price: null,
  26 + offer_price: null,
  27 + product_code: null,
  28 + product_id: null,
  29 + product_name: null,
  30 + sale_time: null,
  31 + sellerCanPublish: true,
  32 + series_name: null,
  33 + shelve_status: null,
  34 + resource: null,
  35 + activity: [],
  36 + recommend: [],
11 }, 37 },
12 - currentId: null,  
13 38
14 /** 39 /**
15 * 用户在商品详情页选择的交易信息 40 * 用户在商品详情页选择的交易信息
16 * productId: 商品id 41 * productId: 商品id
17 * product: 商品详情 42 * product: 商品详情
18 * sizeId: 尺寸id 43 * sizeId: 尺寸id
  44 + * storageId: 库存id
19 * size: 尺寸信息 45 * size: 尺寸信息
20 * tradeTypeId: 交易类型id 46 * tradeTypeId: 交易类型id
21 * tradeType: 交易类型 47 * tradeType: 交易类型
@@ -29,30 +55,30 @@ export default function() { @@ -29,30 +55,30 @@ export default function() {
29 tradeTypeId: null, 55 tradeTypeId: null,
30 tradeType: {}, 56 tradeType: {},
31 }, 57 },
32 - }, 58 + };
  59 +}
  60 +
  61 +export default function() {
  62 + return {
  63 + namespaced: true,
  64 + state: defaultState(),
33 mutations, 65 mutations,
34 actions, 66 actions,
35 getters: { 67 getters: {
36 productDetail(state) { 68 productDetail(state) {
37 - return state.products.byId[state.currentId] || {}; 69 + return state.product;
38 }, 70 },
39 - imageList(state, getters) {  
40 - return get(getters.productDetail, 'goods_list[0].image_list', []); 71 + imageList(state) {
  72 + return state.product.goods_list[0].image_list;
41 }, 73 },
42 - resource(state, getters) {  
43 - return get(getters.productDetail, 'resource', {}); 74 + resource(state) {
  75 + return state.product.resource;
44 }, 76 },
45 - activity(state, getters) {  
46 - return get(getters.productDetail, 'activity', []); 77 + activity(state) {
  78 + return state.product.activity;
47 }, 79 },
48 - recommend(state, getters) {  
49 - const list = get(getters.productDetail, 'recommend', []);  
50 -  
51 - if (list && list.length !== 0) {  
52 - return list;  
53 - }  
54 -  
55 - return null; 80 + recommend(state) {
  81 + return state.product.recommend;
56 }, 82 },
57 selectedSize(state) { 83 selectedSize(state) {
58 return state.selectedProductInfo.size; 84 return state.selectedProductInfo.size;
1 import * as Types from './types'; 1 import * as Types from './types';
2 -import {get, find } from 'lodash'; 2 +import { find } from 'lodash';
3 3
4 function ensureSelectedProduct(state, productId) { 4 function ensureSelectedProduct(state, productId) {
5 if (!state.selectedProductInfo || state.selectedProductInfo.productId !== productId) { 5 if (!state.selectedProductInfo || state.selectedProductInfo.productId !== productId) {
6 state.selectedProductInfo = { 6 state.selectedProductInfo = {
7 productId, 7 productId,
8 - product: state.products.byId[productId], 8 + product: state.product,
9 sizeId: null, 9 sizeId: null,
10 storageId: null, 10 storageId: null,
11 size: {}, 11 size: {},
@@ -17,31 +17,31 @@ function ensureSelectedProduct(state, productId) { @@ -17,31 +17,31 @@ function ensureSelectedProduct(state, productId) {
17 17
18 export default { 18 export default {
19 [Types.UPDATE_PRODUCT_DETAIL](state, payload) { 19 [Types.UPDATE_PRODUCT_DETAIL](state, payload) {
20 - state.products.byId[state.currentId] = null;  
21 - state.currentId = payload.product_id;  
22 - state.products.byId[state.currentId] = payload;  
23 - ensureSelectedProduct(state, state.currentId); 20 + state.product = payload;
  21 + ensureSelectedProduct(state, state.product.product_id);
24 }, 22 },
25 [Types.UPDATE_PRODUCT_FAV](state, { productId, isFav}) { 23 [Types.UPDATE_PRODUCT_FAV](state, { productId, isFav}) {
26 - if (state.products.byId[productId]) {  
27 - state.products.byId[productId].isFav = isFav; 24 + if (state.product.product_id === productId) {
  25 + state.product.isFav = isFav;
28 } 26 }
29 }, 27 },
30 [Types.UPDATE_SELECTED_RPODUCT_SIZE](state, { productId, sizeId, storageId}) { 28 [Types.UPDATE_SELECTED_RPODUCT_SIZE](state, { productId, sizeId, storageId}) {
31 ensureSelectedProduct(state, productId); 29 ensureSelectedProduct(state, productId);
32 30
33 - const sizeList = get(state.selectedProductInfo.product, 'goods_list[0].size_list', []); 31 + const sizeList = state.selectedProductInfo.product.goods_list[0].size_list;
34 32
35 let sizeInfo; 33 let sizeInfo;
36 34
37 if (storageId) { 35 if (storageId) {
38 - sizeInfo = find(sizeList, (size) => size.storage_id === storageId) || {}; 36 + sizeInfo = find(sizeList, (size) => size.storage_id === storageId);
39 } else { 37 } else {
40 - sizeInfo = find(sizeList, (size) => size.size_id === sizeId) || {}; 38 + sizeInfo = find(sizeList, (size) => size.size_id === sizeId);
41 } 39 }
42 40
  41 + if (sizeInfo) {
43 state.selectedProductInfo.sizeId = sizeInfo.size_id; 42 state.selectedProductInfo.sizeId = sizeInfo.size_id;
44 state.selectedProductInfo.storageId = sizeInfo.storage_id; 43 state.selectedProductInfo.storageId = sizeInfo.storage_id;
  44 + }
45 state.selectedProductInfo.size = sizeInfo; 45 state.selectedProductInfo.size = sizeInfo;
46 }, 46 },
47 [Types.UPDATE_SELECTED_TRADE_TYPE](state, { productId, tradeTypeId}) { 47 [Types.UPDATE_SELECTED_TRADE_TYPE](state, { productId, tradeTypeId}) {
@@ -2,5 +2,4 @@ export const UPDATE_PRODUCT_DETAIL = 'UPDATE_PRODUCT_DETAIL'; @@ -2,5 +2,4 @@ export const UPDATE_PRODUCT_DETAIL = 'UPDATE_PRODUCT_DETAIL';
2 export const UPDATE_PRODUCT_FAV = 'UPDATE_PRODUCT_FAV'; 2 export const UPDATE_PRODUCT_FAV = 'UPDATE_PRODUCT_FAV';
3 export const UPDATE_SELECTED_RPODUCT_SIZE = 'UPDATE_SELECTED_RPODUCT_SIZE'; 3 export const UPDATE_SELECTED_RPODUCT_SIZE = 'UPDATE_SELECTED_RPODUCT_SIZE';
4 export const UPDATE_SELECTED_TRADE_TYPE = 'UPDATE_SELECTED_TRADE_TYPE'; 4 export const UPDATE_SELECTED_TRADE_TYPE = 'UPDATE_SELECTED_TRADE_TYPE';
5 -export const PRODUCT_REQUEST_SIZE = 'PRODUCT_REQUEST_SIZE';  
6 5
@@ -25,7 +25,7 @@ module.exports = { @@ -25,7 +25,7 @@ module.exports = {
25 auth: true, 25 auth: true,
26 api: 'ufo.user.favoriteAdd', 26 api: 'ufo.user.favoriteAdd',
27 params: { 27 params: {
28 - product_id: {type: Number}, // 商品id 28 + productId: {type: Number}, // 商品id
29 }, 29 },
30 }, 30 },
31 31
@@ -33,9 +33,9 @@ module.exports = { @@ -33,9 +33,9 @@ module.exports = {
33 '/api/ufo/product/favorite/cancel': { 33 '/api/ufo/product/favorite/cancel': {
34 ufo: true, 34 ufo: true,
35 auth: true, 35 auth: true,
36 - api: 'ufo.user.ufo.user.favoriteCancel', 36 + api: 'ufo.user.favoriteCancel',
37 params: { 37 params: {
38 - product_id: {type: Number}, // 商品id 38 + productId: {type: Number}, // 商品id
39 }, 39 },
40 }, 40 },
41 41