index.js 5.5 KB
import Vue from 'vue';
import {
    FETCH_PRODUCT_DETAIL,
    PRODUCT_FAVORITE,
    FETCH_CART_COUNT,
    PRODUCT_ADD_CART,
    FETCH_PRODUCT_INTRO,
    FETCH_SEARCH_REQUEST,
    FETCH_SEARCH_SUCCESS,
    FETCH_SEARCH_FAILURE
} from './types';

export function createProduct() {
    return {
        state: {
            list: [],
            items: {},
            isFetching: false,
            cartCount: 0,
            isSearching: false,
            searchError: false
        },
        mutations: {
            [FETCH_PRODUCT_DETAIL](state, {product, product: { product_id }}) {
                Vue.set(state.items, product_id, product);
            },
            [FETCH_PRODUCT_INTRO](state, {intro, product_id}) {
                Vue.set(state.items[product_id], 'intro', intro);
            },
            [PRODUCT_FAVORITE](state, {product_id, is_collect}) {
                state.items[product_id].is_collect = is_collect;
            },
            [FETCH_CART_COUNT](state, {cart_goods_count}) {
                state.cartCount = cart_goods_count;
            },
            [FETCH_SEARCH_REQUEST](state) {
                state.searchError = false;
                state.isSearching = true;
            },
            [FETCH_SEARCH_SUCCESS](state) {
                state.searchError = false;
                state.isSearching = false;
            },
            [FETCH_SEARCH_FAILURE](state) {
                state.searchError = true;
                state.isSearching = false;
            }
        },
        actions: {
            [FETCH_PRODUCT_DETAIL]({commit, state}, {product_id}) {
                // let cacheItem = state.items[product_id];

                // if (cacheItem && Date.now() - cacheItem.__lasttime < 1000 * 60 * 3) {
                //     return Promise.resolve();
                // }
                return this.$api.get('/api/product/data', {
                    product_id: parseInt(product_id, 10)
                }).then(res => {
                    if (res.code === 200) {
                        return Promise.all([
                            this.$api.get('/api/product/refundExchange', {
                                product_skn: res.data.product_skn
                            }),
                            this.$api.get('/api/favorite/isFavoriteNew', {
                                id: res.data.product_id
                            })]).then(result => {
                                if (result[0].code === 200) {
                                    res.data.supportRefundExchange = result[0].data[res.data.product_skn] === 'N' ? 'Y' : 'N';
                                }
                                res.data.is_collect = (result[1].code === 200 && result[1].data === 'Y') ? 'Y' : 'N';
                                res.data.__lasttime = Date.now();
                                commit(FETCH_PRODUCT_DETAIL, {product: res.data});
                            });
                    }
                });
            },
            [PRODUCT_FAVORITE]({commit}, {product_id, is_collect}) {
                return this.$api.post('/product/favorite.json', {
                    operation: is_collect === 'Y' ? 'remove' : 'add',
                    id: product_id
                }).then(res => {
                    if (res.code === 200) {
                        commit(PRODUCT_FAVORITE, {product_id, is_collect: is_collect === 'Y' ? 'N' : 'Y'});
                    }
                    return res;
                });
            },
            [FETCH_CART_COUNT]({commit}) {
                return this.$api.get('/product/cart-count.json').then(res => {
                    if (res.code === 200) {
                        commit(FETCH_CART_COUNT, res.data);
                    }
                });
            },
            [PRODUCT_ADD_CART]({commit, rootState}, {productSku, buyNumber}) {
                return this.$api.post('/product/cart.json', {
                    productSku: productSku,
                    buyNumber: buyNumber
                }).then(res=> {
                    if (res.code === 200) {
                        if (Vue.$yoho.goShopingKey && res.data && res.data.shopping_key) {
                            Vue.$yoho.goShopingKey({shoppingKey: res.data.shopping_key});
                        }
                        commit(FETCH_CART_COUNT, {cart_goods_count: res.data.goods_count});
                    } else {
                        return Promise.reject();
                    }
                });
            },
            [FETCH_PRODUCT_INTRO]({commit, state}, {skn, pid}) {
                let cacheItem = state.items[pid];

                if (cacheItem && cacheItem.intro && cacheItem.intro.__lasttime < 1000 * 60 * 3) {
                    return Promise.resolve();
                }
                return this.$api.get(`/product/product/intro_${pid}.json`, {skn}).then(res => {
                    res.__lasttime = Date.now();
                    commit(FETCH_PRODUCT_INTRO, {intro: res, product_id: pid});
                });
            },
            async [FETCH_SEARCH_REQUEST]({commit}, {keyword}) {
                commit(FETCH_SEARCH_REQUEST);
                try {
                    const result = await this.$api.get('/api/search/fuzzy', {keyword});

                    if (result.code === 200) {
                        commit(FETCH_SEARCH_SUCCESS);
                        return result;
                    }
                    commit(FETCH_SEARCH_FAILURE);
                } catch (e) {
                    commit(FETCH_SEARCH_FAILURE);
                }
            }
        }
    };
}