Authored by shangjf

品类商品列表相关代码 review by 孙凯

@@ -24,6 +24,7 @@ import productListForShopInitialState from './reducers/productListForShop/produc @@ -24,6 +24,7 @@ import productListForShopInitialState from './reducers/productListForShop/produc
24 import ProductListForShopContainer from './containers/ProductListForShopContainer'; 24 import ProductListForShopContainer from './containers/ProductListForShopContainer';
25 import ProductListPoolContainer from './containers/ProductListPoolContainer'; 25 import ProductListPoolContainer from './containers/ProductListPoolContainer';
26 import ProductListPoolInitialState from './reducers/productListPool/productListPoolInitialState'; 26 import ProductListPoolInitialState from './reducers/productListPool/productListPoolInitialState';
  27 +import CategoryProListInitialState from './reducers/categoryProList/categoryProListInitialState';
27 28
28 import screenInitialState from './reducers/screen/screenInitialState'; 29 import screenInitialState from './reducers/screen/screenInitialState';
29 import screenCategoryInitialState from './reducers/screenCategory/screenCategoryInitialState'; 30 import screenCategoryInitialState from './reducers/screenCategory/screenCategoryInitialState';
@@ -33,6 +34,8 @@ import ScreenContainer from './containers/ScreenContainer'; @@ -33,6 +34,8 @@ import ScreenContainer from './containers/ScreenContainer';
33 import ScreenCategoryContainer from './containers/ScreenCategoryContainer'; 34 import ScreenCategoryContainer from './containers/ScreenCategoryContainer';
34 import ScreenSubContainer from './containers/ScreenSubContainer'; 35 import ScreenSubContainer from './containers/ScreenSubContainer';
35 36
  37 +import CategoryProductListContainer from './containers/CategoryProListContainer'
  38 +
36 39
37 import { 40 import {
38 setPlatform, 41 setPlatform,
@@ -56,6 +59,7 @@ function getInitialState() { @@ -56,6 +59,7 @@ function getInitialState() {
56 screenSub: (new screenSubInitialState()), 59 screenSub: (new screenSubInitialState()),
57 productListForShop: (new productListForShopInitialState()), 60 productListForShop: (new productListForShopInitialState()),
58 productListPool: (new ProductListPoolInitialState()), 61 productListPool: (new ProductListPoolInitialState()),
  62 + categoryProList: (new CategoryProListInitialState()),
59 }; 63 };
60 return _initState; 64 return _initState;
61 } 65 }
@@ -68,6 +72,7 @@ export default function native(platform) { @@ -68,6 +72,7 @@ export default function native(platform) {
68 const store = configureStore(getInitialState()); 72 const store = configureStore(getInitialState());
69 store.dispatch(setPlatform(platform)); 73 store.dispatch(setPlatform(platform));
70 let {host,serviceHost, channel,type,brand_id,shop_id,dictParams,saleType,activityId} = this.props; 74 let {host,serviceHost, channel,type,brand_id,shop_id,dictParams,saleType,activityId} = this.props;
  75 +
71 store.dispatch(setHost(host)); 76 store.dispatch(setHost(host));
72 store.dispatch(setServiceHost(serviceHost)); 77 store.dispatch(setServiceHost(serviceHost));
73 store.dispatch(setChannel(channel)); 78 store.dispatch(setChannel(channel));
@@ -114,7 +119,14 @@ export default function native(platform) { @@ -114,7 +119,14 @@ export default function native(platform) {
114 <ProductListPoolContainer /> 119 <ProductListPoolContainer />
115 </Provider> 120 </Provider>
116 ); 121 );
  122 + } else if (type == 'YH_CategoryProList') {
  123 + return (
  124 + <Provider store={store}>
  125 + <CategoryProductListContainer />
  126 + </Provider>
  127 + );
117 } 128 }
  129 +
118 return null; 130 return null;
119 } 131 }
120 }); 132 });
  1 +'use strict'
  2 +import React, {Component} from 'react';
  3 +
  4 +import ReactNative, {
  5 + StyleSheet,
  6 + Dimensions,
  7 + NativeAppEventEmitter,
  8 + View,
  9 +} from 'react-native'
  10 +
  11 +import YH_CategoryListHeader from './YH_CategoryListHeader'
  12 +
  13 +export default class CategoryListHeader extends Component {
  14 + constructor(props) {
  15 + super(props);
  16 + this.onClick = this.onClick.bind(this);
  17 + this.clearClick = this.clearClick.bind(this);
  18 + }
  19 +
  20 + onClick(event: Event) {
  21 + let type = event.nativeEvent.type;
  22 + let data = event.nativeEvent.data;
  23 + if (type == 'clear') {
  24 + this.props.clearClick&&this.props.clearClick(data);
  25 + }else if (type == 'click') {
  26 + this.props.onClick&&this.props.onClick(data);
  27 + }
  28 + }
  29 +
  30 + clearClick(event: Event) {
  31 + let item = event.nativeEvent;
  32 + console.log(item);
  33 + }
  34 +
  35 + render() {
  36 + let {dataSource} = this.props;
  37 + return (
  38 + <View style={styles.container}>
  39 + <YH_CategoryListHeader
  40 + style={styles.header}
  41 + dataSource={dataSource.toJS()}
  42 + onClick={this.onClick}
  43 + />
  44 + </View>
  45 + )
  46 + }
  47 +}
  48 +
  49 +let {width} = Dimensions.get('window');
  50 +const DEVICE_WIDTH_RATIO = width / 375;
  51 +let styles = StyleSheet.create({
  52 + container: {
  53 + width,
  54 + height: 45,
  55 + backgroundColor: 'white',
  56 + },
  57 + header: {
  58 + width: width,
  59 + height: 45,
  60 + },
  61 +
  62 +
  63 +
  64 +});
  1 +'use strict'
  2 +
  3 +import React, {Component} from 'react';
  4 +import ReactNative, {
  5 + StyleSheet,
  6 + Dimensions,
  7 + InteractionManager,
  8 + NativeAppEventEmitter,
  9 + View,
  10 + ListView,
  11 +} from 'react-native'
  12 +
  13 +import LoadingIndicator from '../../../common/components/LoadingIndicator';
  14 +import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator';
  15 +import BrandProductFilter from '../cell/BrandProductFilter';
  16 +import ProductListCell from '../../../common/components/ListCell/ProductListCell';
  17 +import CategoryListHeader from './CategoryListHeader'
  18 +
  19 +export default class CategoryProList extends Component {
  20 + constructor(props) {
  21 + super(props);
  22 + this.renderRow = this.renderRow.bind(this);
  23 + this.dataSource = new ListView.DataSource({
  24 + rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
  25 + sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
  26 + });
  27 + }
  28 +
  29 + renderRow(rowData, sectionID, rowID, highlightRow) {
  30 + switch(sectionID) {
  31 + case 'productListHeader': {
  32 + let noFilterValue = true;
  33 + this.props.filterFactors.map((value, key) => {
  34 + if (value) {
  35 + noFilterValue = false;
  36 + }
  37 + });
  38 + let productListIsEmpty = !this.props.productList || !this.props.productList.list || this.props.productList.list.size == 0;
  39 + if (productListIsEmpty && noFilterValue) {
  40 + return null;
  41 + }
  42 + return (
  43 + <View style={styles.brandFilterContainer} onLayout={(evt) => {yPosition = evt.nativeEvent.layout.y;}}>
  44 + <BrandProductFilter
  45 + onPressFilter={this.props.onPressProductFilter}
  46 + selectOrder={this.props.productList.order}
  47 + />
  48 + </View>
  49 + )
  50 + }
  51 + case 'categoryListHeader': {
  52 + let {
  53 + standardFilterList,
  54 + } = this.props;
  55 + return (
  56 + <CategoryListHeader
  57 + dataSource={standardFilterList}
  58 + onClick={this.props.onClickStandardFilter}
  59 + clearClick={this.props.clearClickStandardFilter}
  60 + />
  61 + )
  62 + }
  63 + case 'productList': {
  64 + let similarIndex = this.props.similarIndex;
  65 + let paddingLeft = rowID % 2 == 1 ? rowMarginHorizontal / 2 : rowMarginHorizontal;
  66 + let customStyle = rowID == 0 || rowID == 1 ? {paddingLeft} : {paddingLeft};
  67 + return (
  68 + <ProductListCell
  69 + style={[styles.listContainer, customStyle]}
  70 + key={'row' + rowID}
  71 + rowID={rowID}
  72 + data={rowData}
  73 + similarIndex={similarIndex}
  74 + onPressProduct={this.props.onPressProductCell}
  75 + onLongPressProduct={this.props.onLongPressProduct}
  76 + onPressFindSimilar={this.props.onPressFindSimilar}
  77 + onPressDislike={this.props.onPressDislike}/>
  78 + )
  79 + }
  80 + default:
  81 + return null;
  82 + }
  83 + return null;
  84 + }
  85 +
  86 +
  87 + render() {
  88 +
  89 + let {
  90 + productList,
  91 + standardFilterList,
  92 + } = this.props;
  93 + let isFetching = (productList.isFetching && productList.currentPage == 0);
  94 + let dataSource = {};
  95 + if (productList.list.toArray().length > 0) {
  96 + if (standardFilterList&&standardFilterList.size > 0) {
  97 + dataSource = {
  98 + productListHeader: ['1'],
  99 + categoryListHeader: ['1'],
  100 + productList: productList.list.toArray(),
  101 + };
  102 + }else {
  103 + dataSource = {
  104 + productListHeader: ['1'],
  105 + productList: productList.list.toArray(),
  106 + };
  107 + }
  108 + }
  109 +
  110 + let isLoadingMore = productList.isFetching && productList.currentPage > 0;
  111 + let endReached = productList.endReached;
  112 +
  113 + return (
  114 + <View style={styles.container}>
  115 + <ListView
  116 + ref='CategoryProList'
  117 + contentContainerStyle={styles.contentContainer}
  118 + enableEmptySections={true}
  119 + dataSource={this.dataSource.cloneWithRowsAndSections(dataSource)}
  120 + renderRow={this.renderRow}
  121 + renderFooter={()=>{
  122 + if (endReached) {
  123 + return <View style={styles.placeholder} />;
  124 + } else {
  125 + return <LoadMoreIndicator isVisible={isLoadingMore} animating={true}/>;
  126 + }
  127 + }}
  128 + onEndReached={() => {
  129 + if (productList && productList.list && productList.list.size > 0) {
  130 + this.props.onEndReached && this.props.onEndReached();
  131 + }
  132 + }}
  133 + />
  134 + <LoadingIndicator
  135 + isVisible={isFetching}
  136 + />
  137 + </View>
  138 + );
  139 + }
  140 +}
  141 +
  142 +let {width, height} = Dimensions.get('window');
  143 +let rowWidth = Math.ceil(137.5 * width / 320);
  144 +let rowHeight = Math.ceil(254 * width / 320);
  145 +let rowMarginTop = Math.ceil(10 * width / 320);
  146 +let rowMarginHorizontal = (width - rowWidth * 2) / 3;
  147 +let yPosition = 0;
  148 +
  149 +let styles = StyleSheet.create({
  150 + container: {
  151 + flex: 1,
  152 + },
  153 + contentContainer:{
  154 + flexDirection: 'row',
  155 + flexWrap: 'wrap',
  156 + },
  157 + placeholder: {
  158 + width,
  159 + height: 15,
  160 + },
  161 + listContainer: {
  162 + width: width / 2,
  163 + },
  164 + brandFilterContainer: {
  165 + marginLeft: -1,
  166 + width: width + 2,
  167 + height: 40,
  168 + },
  169 + categoryListContainer: {
  170 + width: width,
  171 + height: 45,
  172 + }
  173 +});
  1 +import React from 'react';
  2 +import ReactNative from 'react-native';
  3 +import ImmutablePropTypes from 'react-immutable-proptypes';
  4 +
  5 +let {
  6 + requireNativeComponent,
  7 + View
  8 +} = ReactNative;
  9 +
  10 +let YH_CategoryListHeader = requireNativeComponent('YH_CategoryListHeader', null);
  11 +
  12 +export default class CategoryListHeader extends React.Component {
  13 +
  14 + static propTypes = {
  15 + ...View.propTypes // 包含默认的View的属性
  16 + };
  17 +
  18 + constructor(props) {
  19 + super(props);
  20 + }
  21 +
  22 + render() {
  23 + return <YH_CategoryListHeader {...this.props} data={this.props.data} />;
  24 + }
  25 +}
@@ -59,4 +59,6 @@ export default keyMirror({ @@ -59,4 +59,6 @@ export default keyMirror({
59 GET_ACTIVITY_REQUEST: null, 59 GET_ACTIVITY_REQUEST: null,
60 GET_ACTIVITY_SUCCESS: null, 60 GET_ACTIVITY_SUCCESS: null,
61 GET_ACTIVITY_FAILURE: null, 61 GET_ACTIVITY_FAILURE: null,
  62 +
  63 + SELECT_STANDARDFILTER_ITEM: null,
62 }); 64 });
  1 +'use strict'
  2 +
  3 +import React, {Component} from 'react';
  4 +import ReactNative, {
  5 + StyleSheet,
  6 + Platform,
  7 + InteractionManager,
  8 + NativeAppEventEmitter,
  9 +} from 'react-native'
  10 +
  11 +import {bindActionCreators} from 'redux';
  12 +import {connect} from 'react-redux';
  13 +import {Map} from 'immutable';
  14 +import * as categoryProListActions from '../reducers/categoryProList/categoryProListActions';
  15 +import CategoryProList from '../components/category/CategoryProList';
  16 +
  17 +const actions = [
  18 + categoryProListActions,
  19 +];
  20 +
  21 +function mapStateToProps(state) {
  22 + return {
  23 + ...state
  24 + };
  25 +}
  26 +
  27 +function mapDispatchToProps(dispatch) {
  28 +
  29 + const creators = Map()
  30 + .merge(...actions)
  31 + .filter(value => typeof value === 'function')
  32 + .toObject();
  33 +
  34 + return {
  35 + actions: bindActionCreators(creators, dispatch),
  36 + dispatch
  37 + };
  38 +}
  39 +
  40 +class CategoryProductListContainer extends Component {
  41 + constructor(props) {
  42 + super(props);
  43 + this._onEndReached = this._onEndReached.bind(this);
  44 + this._onLongPressProduct = this._onLongPressProduct.bind(this);
  45 + this._onPressFindSimilar = this._onPressFindSimilar.bind(this);
  46 + this._onPressProductCell = this._onPressProductCell.bind(this);
  47 + this._onPressProductFilter = this._onPressProductFilter.bind(this);
  48 + this._onClickStandardFilter = this._onClickStandardFilter.bind(this);
  49 + this._clearClickStandardFilter = this._clearClickStandardFilter.bind(this);
  50 +
  51 + this.subscription = NativeAppEventEmitter.addListener(
  52 + 'updateProductByFilter',
  53 + (array) => {
  54 + if (array.length > 0) {
  55 + this.props.actions.setProductFilterFactors(array);
  56 + this.props.actions.resetListPageInfo();
  57 + this.props.actions.getProductList(true);
  58 + this.props.actions.setSimilarIndex(-1);
  59 + }
  60 + }
  61 + );
  62 + }
  63 +
  64 + componentDidMount() {
  65 + this.props.actions.getProductList();
  66 + }
  67 +
  68 + componentWillUnmount() {
  69 + this.subscription && this.subscription.remove();
  70 + }
  71 +
  72 + _onPressProductFilter(value) {
  73 + this.props.actions.resetListPageInfo();
  74 + this.props.actions.setProductListFilter(value);
  75 + this.props.actions.getProductList(true);
  76 + this.props.actions.setSimilarIndex(-1);
  77 + }
  78 +
  79 + _onEndReached() {
  80 + this.props.actions.getProductList();
  81 + }
  82 +
  83 + _onPressProductCell(product, rowId=0) {
  84 + let productSkn = product && product.get('product_skn', 0);
  85 + if (!productSkn) {
  86 + return;
  87 + }
  88 + let url = `http://m.yohobuy.com?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"${productSkn}"}}`;
  89 + ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
  90 + }
  91 +
  92 + _onLongPressProduct(rowID) {
  93 + if (rowID) {
  94 + this.props.actions.setSimilarIndex(rowID);
  95 + }
  96 + }
  97 +
  98 + _onPressFindSimilar(product) {
  99 + if (!product) {
  100 + return;
  101 + }
  102 +
  103 + ReactNative.NativeModules.YH_CommonHelper.jumpFindSimilar(product.toJS());
  104 + }
  105 +
  106 + _clearClickStandardFilter(standarFilterItem) {
  107 + this.props.actions.clearStandardFilter(standarFilterItem);
  108 + this.props.actions.resetListPageInfo();
  109 + this.props.actions.getProductList(true);
  110 + this.props.actions.setSimilarIndex(-1);
  111 + }
  112 +
  113 + _onClickStandardFilter(standarFilterItem) {
  114 + this.props.actions.selectStandardFilter(standarFilterItem);
  115 + this.props.actions.resetListPageInfo();
  116 + this.props.actions.getProductList(true);
  117 + this.props.actions.setSimilarIndex(-1);
  118 + }
  119 +
  120 + render() {
  121 + let {
  122 + productList,
  123 + similarIndex,
  124 + filterFactors,
  125 + filterNameFactors,
  126 + standardFilterList
  127 + } = this.props.categoryProList;
  128 +
  129 + return (
  130 + <CategoryProList
  131 + similarIndex={similarIndex}
  132 + productList={productList}
  133 + filterFactors={filterFactors}
  134 + filterNameFactors={filterNameFactors}
  135 + standardFilterList={standardFilterList}
  136 + onClickStandardFilter={this._onClickStandardFilter}
  137 + clearClickStandardFilter={this._clearClickStandardFilter}
  138 + onEndReached={this._onEndReached}
  139 + onPressProductCell={this._onPressProductCell}
  140 + onLongPressProduct={this._onLongPressProduct}
  141 + onPressFindSimilar={this._onPressFindSimilar}
  142 + onPressProductFilter={this._onPressProductFilter}
  143 + />
  144 + );
  145 + }
  146 +}
  147 +
  148 +let styles = StyleSheet.create({
  149 + container: {
  150 + flex: 1,
  151 + },
  152 +});
  153 +
  154 +export default connect(mapStateToProps, mapDispatchToProps)(CategoryProductListContainer);
  1 +'use strict';
  2 +
  3 +import ReactNative from 'react-native';
  4 +import CategoryProListService from '../../services/CategoryProListService';
  5 +import * as _ from 'lodash';
  6 +import Utils from '../../utils/Utils'
  7 +
  8 +const {
  9 + PRODUCT_LIST_REQUEST,
  10 + PRODUCT_LIST_SUCCESS,
  11 + PRODUCT_LIST_FAILURE,
  12 + PRODUCT_FILTER_ACTION,
  13 + RESET_LIST_PAGE_INFO,
  14 + SET_PRODUCT_LIST_FILTER,
  15 + SET_SIMILAR_PRODUCT_INDEX,
  16 + SELECT_STANDARDFILTER_ITEM
  17 +} = require('../../constants/actionTypes').default;
  18 +
  19 +export function productListRequest() {
  20 + return {
  21 + type: PRODUCT_LIST_REQUEST,
  22 + };
  23 +}
  24 +
  25 +export function productListSuccess(json) {
  26 + return {
  27 + type: PRODUCT_LIST_SUCCESS,
  28 + payload: json
  29 + }
  30 +}
  31 +
  32 +export function productListFailure(error) {
  33 + return {
  34 + type: PRODUCT_LIST_FAILURE,
  35 + payload: error
  36 + }
  37 +}
  38 +
  39 +export function getProductList(reload=false) {
  40 + return (dispatch, getState) => {
  41 +
  42 + let {app, categoryProList} = getState();
  43 + let {productList, filterFactors, standardFilterList} = categoryProList;
  44 + let {originParams} = app;
  45 +
  46 + if (reload) {
  47 +
  48 + } else {
  49 + if (productList.isFetching || productList.endReached || productList.error) {
  50 + return;
  51 + }
  52 + }
  53 + let page = productList.currentPage + 1;
  54 + let pageSize = productList.pageSize;
  55 + let order = productList.order;
  56 +
  57 + let bSelectedFilterFactor,allFilterFactors;
  58 + allFilterFactors = filterFactors.toJS();
  59 +
  60 + for (let prop in allFilterFactors) {
  61 + if (allFilterFactors.hasOwnProperty(prop)) {
  62 + if (allFilterFactors[prop] === '' || !allFilterFactors[prop]) {
  63 + delete allFilterFactors[prop];
  64 + }
  65 + if (prop == 'sizeKey' && allFilterFactors[prop]) {
  66 + allFilterFactors['size'] = allFilterFactors[prop];
  67 + delete allFilterFactors[prop];
  68 + }
  69 + }
  70 + }
  71 +
  72 + let standard = '';
  73 + let standardList = standardFilterList.toJS();
  74 +
  75 + for (var i = 0; i < standardList.length; i++) {
  76 + let filterItem = standardList[i]
  77 + if (filterItem.isSelect) {
  78 + let selectFilter = filterItem.selectFilter;
  79 + if (standard.length == 0) {
  80 + standard = filterItem.standard_id + '_' + selectFilter.standard_id;
  81 + } else {
  82 + standard = standard + ',' + filterItem.standard_id + '_' + selectFilter.standard_id;
  83 + }
  84 + }
  85 + }
  86 +
  87 + allFilterFactors['standard'] = standard;
  88 +
  89 + console.log(allFilterFactors);
  90 +
  91 + dispatch(productListRequest());
  92 + return new CategoryProListService(app.host).productList(page, pageSize, originParams, allFilterFactors, order, '')
  93 + .then(json => {
  94 + let payload = Utils.parseProductList(json);
  95 + payload.endReached = payload.currentPage == payload.pageCount;
  96 +
  97 + if (payload.currentPage > 1) {
  98 + let oldList = productList.list.toJS();
  99 + let list = [...oldList, ...payload.list];
  100 + payload.list = list;
  101 + }
  102 +
  103 + let categoryFilterList = payload.categoryFilterList;
  104 + let filterCategoryDetailFilterList = payload.filterCategoryDetailFilterList;
  105 + let filters = Utils.parsecategoryFilter({categoryFilterList,filterCategoryDetailFilterList});
  106 + ReactNative.NativeModules.YH_ProductListRNViewHelper.setFilterData(filters);
  107 + ReactNative.NativeModules.YH_ScreenCategoryViewHelper.enableBrandFilter();
  108 + dispatch(productListSuccess(payload));
  109 + })
  110 + .catch(error => {
  111 + dispatch(productListFailure(error));
  112 + });
  113 + };
  114 +}
  115 +
  116 +
  117 +export function resetListPageInfo() {
  118 + return {
  119 + type: RESET_LIST_PAGE_INFO,
  120 + }
  121 +}
  122 +
  123 +export function setProductListFilter(value) {
  124 + return {
  125 + type: SET_PRODUCT_LIST_FILTER,
  126 + payload: value
  127 + }
  128 +}
  129 +
  130 +export function setSimilarIndex(rowID) {
  131 + return {
  132 + type: SET_SIMILAR_PRODUCT_INDEX,
  133 + payload: rowID
  134 + }
  135 +}
  136 +
  137 +export function setProductFilterFactors(array) {
  138 + return (dispatch, getState) => {
  139 + let {app, categoryProList} = getState();
  140 + let {filterFactors} = categoryProList;
  141 + filterFactors = filterFactors.toJS();
  142 +
  143 + for (var i = 0; i < array.length; i++) {
  144 + let item = array[i];
  145 + filterFactors[item._key] = item._value;
  146 + }
  147 + dispatch({
  148 + type: PRODUCT_FILTER_ACTION,
  149 + payload: filterFactors
  150 + });
  151 + };
  152 +}
  153 +
  154 +export function selectStandardFilter(item) {
  155 + return (dispatch, getState) => {
  156 + let {categoryProList} = getState();
  157 + let {standardFilterList} = categoryProList;
  158 + standardFilterList = standardFilterList ? standardFilterList.toJS() : [];
  159 + for (var i = 0; i < standardFilterList.length; i++) {
  160 + let filterItem = standardFilterList[i];
  161 + if (filterItem.standard_id == item.standard_id) {
  162 + filterItem.isSelect = true;
  163 + filterItem.selectFilter = item.selectFilter;
  164 + break
  165 + }
  166 + }
  167 + dispatch({
  168 + type: SELECT_STANDARDFILTER_ITEM,
  169 + payload: standardFilterList
  170 + })
  171 + }
  172 +}
  173 +
  174 +export function clearStandardFilter(item) {
  175 + return (dispatch, getState) => {
  176 + let {categoryProList} = getState();
  177 + let {standardFilterList} = categoryProList;
  178 + standardFilterList = standardFilterList ? standardFilterList.toJS() : [];
  179 + for (var i = 0; i < standardFilterList.length; i++) {
  180 + let filterItem = standardFilterList[i];
  181 + if (filterItem.standard_id == item.standard_id) {
  182 + filterItem.isSelect = false;
  183 + filterItem.selectFilter = {
  184 + standard_id: '',
  185 + standard_name: '',
  186 + };
  187 + break
  188 + }
  189 + }
  190 + dispatch({
  191 + type: SELECT_STANDARDFILTER_ITEM,
  192 + payload: standardFilterList
  193 + })
  194 + }
  195 +}
  1 +'use strict';
  2 +
  3 +import {Record, List, Map} from 'immutable';
  4 +
  5 +
  6 +let InitialState = Record({
  7 + similarIndex : -1,
  8 + productList: new (Record({
  9 + isFetching: false,
  10 + error: null,
  11 + list: List(),
  12 + order: '',
  13 + currentPage: 0,
  14 + pageCount: 0,
  15 + pageSize: 60,//60,
  16 + total: 0,
  17 + endReached: false,
  18 + sourceType: 0, // 0 - 默认,1 - 购,全球2 - 奥莱
  19 + })),
  20 + categoryFilterList: List(),
  21 + filterCategoryDetailFilterList: List(),
  22 + standardFilterList: List(),
  23 + filterFactors: new (Record({
  24 + gender: '', //性别
  25 + color: '', //颜色
  26 + price: '', //价格
  27 + sizeKey: '', //尺码
  28 + p_d: '', //折扣
  29 + sort: '', //品类
  30 + brand: '', //品牌
  31 + })),
  32 + filterNameFactors: new (Record({
  33 + gender: '所有性别', //性别
  34 + color: '所有颜色', //颜色
  35 + price: '所有价格', //价格
  36 + sizeKey: '所有尺码', //尺码
  37 + p_d: '所有折扣', //折扣
  38 + sort: '所有品类', //品类
  39 + brand: '所有品牌', //品牌
  40 + })),
  41 +});
  42 +
  43 +export default InitialState;
  1 +'use strict';
  2 +
  3 +import InitialState from './categoryProListInitialState';
  4 +import Immutable, {Map} from 'immutable';
  5 +
  6 +const {
  7 + RESET_LIST_PAGE_INFO,
  8 + SET_PRODUCT_LIST_FILTER,
  9 + PRODUCT_LIST_REQUEST,
  10 + PRODUCT_LIST_SUCCESS,
  11 + PRODUCT_LIST_FAILURE,
  12 + PRODUCT_FILTER_ACTION,
  13 + SET_SIMILAR_PRODUCT_INDEX,
  14 + SELECT_STANDARDFILTER_ITEM
  15 +} = require('../../constants/actionTypes').default;
  16 +
  17 +
  18 +const initialState = new InitialState;
  19 +
  20 +export default function categoryProListReducer(state=initialState, action) {
  21 + switch(action.type) {
  22 + case RESET_LIST_PAGE_INFO: {
  23 + return state.setIn(['productList', 'currentPage'], 0)
  24 + .setIn(['productList', 'pageCount'], 0)
  25 + .setIn(['productList', 'total'], 0)
  26 + .setIn(['productList', 'endReached'], false);
  27 + }
  28 + case SET_PRODUCT_LIST_FILTER: {
  29 + return state.setIn(['productList', 'order'], action.payload);
  30 + }
  31 + case PRODUCT_LIST_REQUEST: {
  32 + return state.setIn(['productList', 'isFetching'], true)
  33 + .setIn(['productList', 'error'], null);
  34 + }
  35 + case PRODUCT_LIST_SUCCESS: {
  36 +
  37 + let {
  38 + list,
  39 + categoryFilterList,
  40 + filterCategoryDetailFilterList,
  41 + standard,
  42 + currentPage,
  43 + pageCount,
  44 + total,
  45 + recId,
  46 + endReached,
  47 + } = action.payload;
  48 +
  49 + let newState = state.setIn(['productList', 'isFetching'], false)
  50 + .setIn(['productList', 'error'], null)
  51 + .setIn(['productList', 'list'], Immutable.fromJS(list))
  52 + .setIn(['productList', 'currentPage'], currentPage)
  53 + .setIn(['productList', 'pageCount'], pageCount)
  54 + .setIn(['productList', 'total'], total)
  55 + .setIn(['productList', 'endReached'], endReached);
  56 +
  57 + if (currentPage == 1 && state.categoryFilterList.size == 0 && state.filterCategoryDetailFilterList.size == 0) {
  58 + newState = newState.set('categoryFilterList', Immutable.fromJS(categoryFilterList))
  59 + .set('filterCategoryDetailFilterList', Immutable.fromJS(filterCategoryDetailFilterList));
  60 + }
  61 +
  62 + if (currentPage == 1 && state.standardFilterList.size == 0) {
  63 + newState = newState.set('standardFilterList', Immutable.fromJS(standard));
  64 + }
  65 + return newState;
  66 + }
  67 + case PRODUCT_LIST_FAILURE: {
  68 + return state.setIn(['productList', 'isFetching'], false)
  69 + .setIn(['productList', 'error'], action.payload);
  70 + }
  71 + case PRODUCT_FILTER_ACTION: {
  72 + return state.set('filterFactors', Immutable.fromJS(action.payload));
  73 + }
  74 + case SET_SIMILAR_PRODUCT_INDEX: {
  75 + return state.set('similarIndex', action.payload);
  76 + }
  77 + case SELECT_STANDARDFILTER_ITEM: {
  78 + return state.set('standardFilterList', Immutable.fromJS(action.payload));
  79 + }
  80 + }
  81 +
  82 + return state;
  83 +}
@@ -8,6 +8,8 @@ import productForBrand from './productListForBrand/productListForBrandReducer'; @@ -8,6 +8,8 @@ import productForBrand from './productListForBrand/productListForBrandReducer';
8 import productListForShop from './productListForShop/productListForShopReducer'; 8 import productListForShop from './productListForShop/productListForShopReducer';
9 import productListPool from './productListPool/productListPoolReducer'; 9 import productListPool from './productListPool/productListPoolReducer';
10 10
  11 +import categoryProList from './categoryProList/categoryProListReducer';
  12 +
11 const rootReducer = combineReducers({ 13 const rootReducer = combineReducers({
12 app, 14 app,
13 productForBrand, 15 productForBrand,
@@ -16,6 +18,7 @@ const rootReducer = combineReducers({ @@ -16,6 +18,7 @@ const rootReducer = combineReducers({
16 screenSub, 18 screenSub,
17 productListForShop, 19 productListForShop,
18 productListPool, 20 productListPool,
  21 + categoryProList,
19 }); 22 });
20 23
21 export default rootReducer; 24 export default rootReducer;
  1 +'use strict';
  2 +
  3 +import Request from '../../common/services/Request';
  4 +
  5 +export default class CategoryProListService {
  6 + constructor(host) {
  7 + let baseURL = 'http://api.yoho.cn';
  8 + if(host){
  9 + baseURL = host;
  10 + }
  11 + this.api = new Request(baseURL);
  12 + }
  13 +
  14 + async productList(page=1, limit=60, originParams={}, filterFactors={}, order, firstProductSkn='') {
  15 +
  16 + return await this.api.get({
  17 + url: '',
  18 + body: {
  19 + method: 'app.search.category',
  20 + page,
  21 + limit,
  22 + ...originParams,
  23 + ...filterFactors,
  24 + fromPage: 'iFP_CategoryProList',
  25 + order,
  26 + firstProductSkn
  27 + }
  28 + })
  29 + .then((json) => {
  30 + return json;
  31 + })
  32 + .catch((error) => {
  33 + throw(error);
  34 + });
  35 + }
  36 +}
@@ -262,10 +262,23 @@ function parseProductList(json) { @@ -262,10 +262,23 @@ function parseProductList(json) {
262 } 262 }
263 263
264 let recId = randomString(40); 264 let recId = randomString(40);
  265 +
  266 + let standard = json && json.standard ? json.standard : [];
  267 +
  268 + for (var i = 0; i < standard.length; i++) {
  269 + let standardItem = standard[i]
  270 + standardItem.isSelect = false;
  271 + standardItem.selectFilter = {
  272 + standard_id: '',
  273 + standard_name: '',
  274 + }
  275 + }
  276 +
265 return { 277 return {
266 list, 278 list,
267 categoryFilterList, 279 categoryFilterList,
268 filterCategoryDetailFilterList, 280 filterCategoryDetailFilterList,
  281 + standard,
269 currentPage, 282 currentPage,
270 pageCount, 283 pageCount,
271 total, 284 total,