Authored by 郁健超

砍价列表分区展示&&增加资源位请求 review by孙凯

/*
* @Author: QC.L
* @Date: 2018-09-11 16:07:56
* @Author: QC.L
* @Date: 2018-09-11 16:07:56
* @Last Modified by: QC.L
* @Last Modified time: 2018-09-11 16:14:40
* @Description 弹框 Alert 效果
... ...
... ... @@ -4,73 +4,107 @@ import React, { Component } from 'react';
import { Dimensions, ListView, Image, StyleSheet, View ,Text, TouchableOpacity} from 'react-native';
import { Immutable } from 'immutable';
import ProductCell from './cell/productCell';
import Focus from './floor/Focus';
const DEVICE_WIDTH_RATIO = Dimensions.get('window').width / 375;
export default class HaggleList extends Component {
constructor(props) {
super(props);
this.state = {categoryType:0};
this._renderRow = this._renderRow.bind(this);
this._changeCategory = this._changeCategory.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
});
}
_renderRow(rowData, sectionID, rowID) {
_renderResourceInfoListRow(item) {
if (item.get('template_name') === 'focus' && item.get('data')) {
return (
<ProductCell
key={'row' + rowID}
rowID={rowID}
data={rowData}
onPressProduct={this.props.onPressProduct}
firstHaggle={this.props.firstHaggle}
continueHaggle={this.props.continueHaggle}
onStop = {this.props.onStop && this.props.onStop(this.state.categoryType)}
<View style={styles.topImageView}>
<Focus
data={item.get('data')}
height={121}
resourceJumpWithUrl={this.props.resourceJumpWithUrl}
/>
</View>
);
}
return null;
}
_renderRow(rowData, sectionID, rowID) {
if(sectionID === 'resourceInfoList'){
return this._renderResourceInfoListRow(rowData)
}else if (sectionID === 'productList') {
return (
<ProductCell
key={'row' + rowID}
rowID={rowID}
data={rowData}
onPressProduct={this.props.onPressProduct}
firstHaggle={this.props.firstHaggle}
continueHaggle={this.props.continueHaggle}
onStop = {this.props.onStop}
/>
);
}else {
return null;
}
}
_changeCategory(index) {
if (index == this.state.categoryType) {
let {
categoryType,
} = this.props;
if (index == categoryType) {
return
}
console.log(this.state.categoryType);
this.setState({categoryType:index});
this.props.onPressCategory && this.props.onPressCategory(index);
}
render() {
let {
data,
categoryType,
resourceInfo,
} = this.props;
let productList = data.list ? data.list.toArray() : [];
let color = this.state.categoryType == 0 ? '#444444' : '#b0b0b0';
let subcolor = this.state.categoryType == 1 ? '#444444' : '#b0b0b0';
let productList = data.list ? data.list.toArray() : [];
let color = categoryType == 0 ? '#444444' : '#b0b0b0';
let subcolor = categoryType == 1 ? '#444444' : '#b0b0b0';
let dataSource = null;
if (categoryType == 0) {
dataSource = {
resourceInfoList: resourceInfo.resourceList ? resourceInfo.resourceList.toArray() : [],
productList: data.list ? data.list.toArray() : [],
}
}else {
dataSource = {
productList: data.list ? data.list.toArray() : [],
}
}
return (
<View style={styles.container}>
{this.state.categoryType == 0 ? <View style={styles.topImageView}>
<Image style={styles.topImageView} source={{uri:'https://cdn.yoho.cn/app/yohogain/invite/banner.jpg'}} resizeMode={'contain'}/>
</View>
: null }
<ListView
ref={(c) => {
this.listView = c;
}}
contentContainerStyle={styles.contentContainer}
enableEmptySections={true}
dataSource={this.dataSource.cloneWithRows(productList)}
renderRow={this._renderRow}
renderFooter={this._renderFooter}
onEndReached={() => {
if (productList.size !== 0) {
this.props.onEndReached && this.props.onEndReached(this.state.categoryType);
}
}}/>
<ListView
ref={(c) => {
this.listView = c;
}}
enableEmptySections={true}
contentContainerStyle={styles.contentContainer}
dataSource={this.dataSource.cloneWithRowsAndSections(dataSource)}
renderRow={this._renderRow}
renderHeader={this._renderHeader}
renderFooter={this._renderFooter}
onEndReached={() => {
if (productList.size !== 0) {
this.props.onEndReached && this.props.onEndReached(categoryType);
}
}}/>
<View style={styles.bottomView}>
<TouchableOpacity activeOpacity={1} style={styles.textItemStyle} onPress={() => {
... ... @@ -78,7 +112,7 @@ _renderRow(rowData, sectionID, rowID) {
}}>
<Text style={[styles.textsStyle, {color: color}]}>砍价商品</Text>
</TouchableOpacity>
<View style={styles.separator}/>
<TouchableOpacity activeOpacity={1} style={styles.textItemStyle} onPress={() => {
this._changeCategory && this._changeCategory(1);
}}>
... ... @@ -100,7 +134,7 @@ let styles = StyleSheet.create({
},
topImageView: {
width: width,
height: 118 * DEVICE_WIDTH_RATIO,
height: 121 * DEVICE_WIDTH_RATIO,
},
contentContainer: {
... ... @@ -116,7 +150,10 @@ let styles = StyleSheet.create({
bottom: 0,
flexDirection: 'row',
backgroundColor: 'white',
borderTopColor: '#e0e0e0',
borderTopWidth: 1,
},
textItemStyle: {
width: width/2,
height: 50 * DEVICE_WIDTH_RATIO,
... ... @@ -132,6 +169,11 @@ let styles = StyleSheet.create({
height: 50 * DEVICE_WIDTH_RATIO,
backgroundColor: '#f0f0f0'
},
topLineSeparator: {
width:width,
height: 1,
bottom: 55,
backgroundColor: '#f0f0f0'
},
})
;
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import YH_Swiper from '../../../common/components/YH_Swiper';
import YH_Image from '../../../common/components/YH_Image';
import Immutable from 'immutable';
const {
View,
Image,
TouchableOpacity,
StyleSheet,
Dimensions,
Platform,
} = ReactNative;
export default class ImageSlider extends React.Component {
constructor(props) {
super(props);
this._handleParamsJumpWithUrl = this._handleParamsJumpWithUrl.bind(this);
}
shouldComponentUpdate(nextProps) {
if (Immutable.is(nextProps.resource, this.props.resource)
&& nextProps.sliderWidth == this.props.sliderWidth
&& nextProps.sliderHeight == this.props.sliderHeight) {
return false;
} else {
return true;
}
}
_handleParamsJumpWithUrl(index, url) {
// 为埋点提供参数组装
// 后期请将所有的点击事件由 resourceJumpWithUrl 修改为自己独有的事件
// 由于多数组件都使用的 resourceJumpWithUrl ,埋点传参无法正常进行
let params = {
I_INDEX: index,
F_URL: url
};
this.props.resourceJumpWithUrl && this.props.resourceJumpWithUrl(url, 'banner', params);
}
render() {
let {resource, sliderWidth, sliderHeight} = this.props;
if (!resource || resource.size == 0) {
return null;
}
let data = this.props.resource.toJS();
if (data.length == 1) {
let imageUrl = YH_Image.getSlicedUrl(data[0].src, sliderWidth, sliderHeight, 2);
return (
<TouchableOpacity
activeOpacity={1}
yh_exposureData={data[0].yh_exposureData}
style={{width: sliderWidth, height: sliderHeight}}
onPress={() => {
this._handleParamsJumpWithUrl(1, data[0].url)
}}
>
<YH_Image
url={imageUrl}
style={{width: sliderWidth, height: sliderHeight}}
/>
</TouchableOpacity>
);
} else {
return (
<YH_Swiper
showsButtons={false}
loop={true}
autoplay={true}
autoplayTimeout={8}
width={sliderWidth}
height={sliderHeight}
paginationStyle={{
backgroundColor: 'rgba(68, 68, 68, 0.2)',
bottom: 10,
height: 10,
width: data.length * 12,
borderRadius: 5,
marginLeft: (sliderWidth - data.length * 12) / 2,
paddingBottom: 0,
}}
>
{data.map((item, i) => {
let imageUrl = YH_Image.getSlicedUrl(item.src, sliderWidth, sliderHeight, 2);
return (
<TouchableOpacity
key={i}
activeOpacity={1}
yh_exposureData={item.yh_exposureData}
onPress={() => {
this._handleParamsJumpWithUrl(i + 1, item.url);
}}
>
<YH_Image
url={imageUrl}
style={{width: sliderWidth, height: sliderHeight}}
/>
</TouchableOpacity>
);
})}
</YH_Swiper>
);
}
}
}
... ...
/*
* @Author: QC.L
* @Date: 2018-09-11 16:07:56
* @Last Modified by: QC.L
* @Last Modified time: 2018-09-11 16:14:40
* @Description 弹框 Alert 效果
*/
'use strict';
import React from 'react';
import ReactNative from 'react-native';
const {
StyleSheet,
Text,
View,
Dimensions,
TouchableOpacity,
Modal,
} = ReactNative;
import PropTypes from 'prop-types';
/**
* 参数1: showStatus 值 sure/cancel
* 参数2: handleAction 要处理的事件
*/
function YHAlertItem(props) {
return (
<TouchableOpacity style={styles.click} onPress={() => {
props.handleAction && props.handleAction(props.param ? props.param: {});
}}>
<Text style={styles[props.showStatus]}>{props.children}</Text>
</TouchableOpacity>
);
}
/**
* 参数1: isShow true 显示 false 隐藏
*/
class YHAlert extends React.Component {
static propTypes = {
show: PropTypes.func, // 显示
hide: PropTypes.func, // 隐藏
};
constructor(props) {
super(props);
this._renderChildren = this._renderChildren.bind(this);
}
static defaultProps = {
confirmTitle:{},
};
_renderChildren(children) {
if('[object Array]' == Object.prototype.toString.call(children)){
return children.map((element, index) => {
if (index === children.length) return element
return (
<React.Fragment>
{element}
<View style={{width: 0.5, height: '100%', backgroundColor: '#e0e0e0'}}></View>
</React.Fragment>
)
});
}else {
return children
}
}
render() {
let { children } = this.props;
return (
<Modal
visible={this.props.isShow}
animationType={'none'}
transparent={true}
onRequestClose={() => {}}>
<View style={styles.modalContainer}>
<View style={styles.modalView}>
{this.props.title ? <View style={styles.confirmTitleContainer}>
<Text style={[styles.confirmTitle,this.props.titleStyle]} numberOfLines={1}>{this.props.title}</Text>
</View>: null}
{this.props.content ? <View style={styles.confirmContentContainer}>
<Text style={[styles.confirmContent,this.props.contentStyle]}numberOfLines={3}>{this.props.content}</Text>
</View>: null}
<View style={{width: '100%', height: 0.5, backgroundColor: '#e0e0e0'}}/>
<View style={styles.confirmBtnContainer}>
{this._renderChildren(children)}
</View>
</View>
</View>
</Modal>
);
}
};
export { YHAlert, YHAlertItem };
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
modalContainer: {
flex: 1,
width: width,
height: height,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.4)',
},
modalView: {
width: 270,
alignItems: 'center',
backgroundColor: '#ffffff',
borderRadius : 5
},
confirmBtnContainer: {
width: '100%',
height: 50,
flexDirection: 'row',
justifyContent: 'space-between',
},
confirmTitleContainer: {
alignItems: 'center'
},
confirmTitle: {
paddingTop: 20,
paddingLeft: 30,
paddingRight: 30,
paddingBottom: 10,
color: '#000000',
fontSize: 16,
lineHeight: 24,
textAlign: 'center',
letterSpacing: -0.09,
fontFamily: 'PingFang-SC-Regular',
fontWeight: '600',
},
confirmContentContainer: {
alignItems: 'center'
},
confirmContent: {
paddingLeft: 30,
paddingRight: 30,
paddingBottom: 20,
color: '#999999',
fontSize: 14,
lineHeight: 24,
textAlign: 'center',
letterSpacing: -0.09,
fontFamily: 'PingFang-SC-Regular',
},
click: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
cancel: {
fontSize: 17,
color: '#000000',
letterSpacing: -0.41,
fontFamily: 'PingFang-SC-Regular',
fontWeight: 'bold',
},
sure: {
fontSize: 17,
color: '#999999',
letterSpacing: -0.41,
},
blackButton: {
fontSize: 17,
color: 'black',
letterSpacing: -0.41,
},
LightGrayButton: {
fontSize: 17,
color: '#999999',
letterSpacing: -0.41,
fontFamily: 'PingFang-SC-Regular',
},
redButton: {
fontSize: 17,
color: 'red',
letterSpacing: -0.41,
fontFamily: 'PingFang-SC-Regular',
},
});
... ...
... ... @@ -29,14 +29,14 @@ export default class productCell extends Component {
}
return (
<View>
<ImageBackground source={require('../../images/timeBgBig.png')} style={styles.timeBg}>
<View style={styles.timeContainer}>
<Image source={require('../../images/timeIcon.png')} style={styles.timeIcon}></Image>
{data.get('cutStatus')==1? <TimerLabel leftTime = {leftTime} style={styles.timeCount} onStop = {this.props.onStop}/>:null }
<Text style={styles.timeDes}>{des}</Text>
</View>
<View style= {styles.timeFatherContainer}>
<ImageBackground source={require('../../images/timeBg.png')} style={styles.timeBg}>
</ImageBackground>
<View style={styles.timeContainer}>
{data.get('cutStatus')==1? <TimerLabel leftTime = {leftTime} style={styles.timeCount} onStop = {this.props.onStop}/>:null }
<Text style={styles.timeDes}>{des}</Text>
</View>
</View>
);
... ... @@ -87,23 +87,15 @@ export default class productCell extends Component {
return (
<View >
{data.get('cutStatus') ?
<TouchableOpacity style={styles.continueCutContainer} onPress={() => {
this.props.continueHaggle && this.props.continueHaggle(data);
}}>
<View>
<View style={styles.continueCutContainer}>
<Text style={styles.continueCut}>继续砍价</Text>
</View>
</TouchableOpacity>
:
<TouchableOpacity style={styles.cutActionContainer} onPress={() => {
this.props.firstHaggle && this.props.firstHaggle(data);
}}>
<View>
<View style={styles.cutActionContainer}>
<Image source={require('../../images/cutPriceBg.png')} style={styles.cutPriceBg}></Image>
<Text style={styles.cutPrice}>-¥{data && data.get('lowPrice')}</Text>
</View>
</TouchableOpacity>
}
</View>
)
... ... @@ -112,13 +104,12 @@ export default class productCell extends Component {
render() {
let data = this.props.data;
let prdImage = YH_Image.getSlicedUrl(data && data.get('defaultImages', ''), 98, 130, 2);
let yh_exposureData = this.props.yh_exposureData ? this.props.yh_exposureData : null;
return (
<View>
<View style={styles.fatherContainer}>
{data.get('cutStatus')?this._topTimerView(data):null}
<TouchableOpacity
yh_exposureData={yh_exposureData} activeOpacity={1} style={[styles.container]}
activeOpacity={1} style={[styles.container]}
onPress={() => {
this.props.onPressProduct && this.props.onPressProduct(data);
}}>
... ... @@ -170,6 +161,10 @@ let styles = StyleSheet.create({
width: nameWidth,
letterSpacing: -0.34,
},
timeFatherContainer: {
flexDirection: 'row',
},
priceFatherContainer: {
flex:1,
marginBottom: 0,
... ... @@ -241,17 +236,18 @@ let styles = StyleSheet.create({
},
timeBg:{
justifyContent: 'center',
width: 120,
width: 21,
height: 31,
marginLeft:-3,
},
timeContainer :{
alignItems: 'center',
flexDirection: 'row',
marginTop: -5,
marginLeft:2,
marginLeft:-2,
backgroundColor: '#222222',
height: 24,
},
timeIcon:{
width: 9,
... ... @@ -267,6 +263,7 @@ let styles = StyleSheet.create({
fontSize: 12,
color: 'white',
marginLeft:3,
marginRight:10,
fontFamily: 'PingFang-SC-Medium',
},
invalidDes: {
... ...
'use strict';
import React from 'react';
import ReactNative from 'react-native';
import ImageSlider from '../cell/ImageSlider';
import Immutable from 'immutable';
const {
StyleSheet,
Dimensions,
View,
} = ReactNative;
export default class Focus extends React.Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(nextProps) {
if (Immutable.is(nextProps.data, this.props.data)) {
return false;
} else {
return true;
}
}
render() {
let {data} = this.props;
let sliderHeight = Math.ceil(this.props.height * DEVICE_WIDTH_RATIO);
return (
<View style={{height:sliderHeight, width:width}}>
<ImageSlider
resource={data}
sliderWidth={width}
sliderHeight={sliderHeight}
resourceJumpWithUrl={this.props.resourceJumpWithUrl}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
const DEVICE_WIDTH_RATIO = width / 375;
let styles = StyleSheet.create({
banner: {},
});
... ...
... ... @@ -9,6 +9,15 @@ export default keyMirror({
PRODUCT_LIST_REQUEST: null,
PRODUCT_LIST_SUCCESS: null,
PRODUCT_LIST_FAILURE: null,
MYHAGGLE_PRODUCT_LIST_REQUEST: null,
MYHAGGLE_PRODUCT_LIST_SUCCESS: null,
MYHAGGLE_PRODUCT_LIST_FAILURE: null,
RESOURCE_INFO_REQUEST: null,
RESOURCE_INFO_SUCCESS: null,
RESOURCE_INFO_FAILURE: null,
SET_SELECTED_CATEGORY: null,
REFRESH_PRODUCT_LIST:null,
HAGGLE_STATUS_SUCCESS:null,
... ...
... ... @@ -10,6 +10,7 @@ import * as allianceActions from '../reducers/haggleListReducer/haggleActions';
import HaggleList from '../components/HaggleList'
import LoadingIndicator from '../../common/components/LoadingIndicator';
import { TipsAlertItem, TipsAlert } from '../../common/components/YH_TipsAlert';
import { YHAlert, YHAlertItem } from '../components/cell/YH_Alert.js';
const actions = [
allianceActions,
... ... @@ -37,23 +38,43 @@ function mapDispatchToProps(dispatch) {
class HaggleListContainer extends Component {
constructor(props) {
super(props);
this.state = {showAlert:false};
this.state = {showAlert:false, productItem:null};
this._onEndReached = this._onEndReached.bind(this);
this._onPressProduct = this._onPressProduct.bind(this);
this._jumpHaggleDetail = this._jumpHaggleDetail.bind(this);
this._onPressCategory = this._onPressCategory.bind(this);
this._hiddenTipsAlertDialog = this._hiddenTipsAlertDialog.bind(this);
this._timerStop = this._timerStop.bind(this);
this._resourceJumpWithUrl = this._resourceJumpWithUrl.bind(this);
}
componentDidMount() {
this.props.actions.getProductList();
this.props.actions.getResourceInfo(function (json) {
json && json.forEach(item => {
})
});
}
componentWillUnmount() {
}
_resourceJumpWithUrl(url, type, params) {
if (!url) {
return;
}
if (type === 'icon' && params) {
ReactNative.NativeModules.YH_CommonHelper.logEvent('YB_CPS_MAIN_ICON_C', params);
} else if (type === 'banner' && params) {
ReactNative.NativeModules.YH_CommonHelper.logEvent('YB_CPS_MAIN_BANNER_C', params);
} else if (type && params) {
ReactNative.NativeModules.YH_CommonHelper.logEvent('YB_CPS_MAIN_ACTIVITY_C', params);
}
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
}
_onEndReached(categoryType) {
if (categoryType == 0) {
this.props.actions.getProductList();
... ... @@ -62,7 +83,8 @@ class HaggleListContainer extends Component {
}
}
_timerStop(categoryType) {
_timerStop() {
this.props.actions.refreshProductList(1);
}
_showTipsAlertDialog(){
... ... @@ -70,14 +92,14 @@ class HaggleListContainer extends Component {
}
_hiddenTipsAlertDialog(){
this.setState({showAlert:false});
this.setState({showAlert:false, productItem:null});
}
_onPressCategory(index) {
this.props.actions.setSelectedCategory(index);
}
_jumpHaggleDetail(product, status, cutRecordId) {
_jumpHaggleDetail(product, status) {
let productSkn = product && product.get('productSkn', 0);
let activityId = product && product.get('activityId', 0);
if (!productSkn) {
... ... @@ -95,9 +117,11 @@ class HaggleListContainer extends Component {
if (product.get('cutStatus')) {
this._jumpHaggleDetail(product, null);
}else {
this.props.actions.getHaggleStatus(product.get('productSkn'), product.get('activityId'), function (json){
if (json) {
that.setState({showAlert:true});
that.setState({showAlert:true, productItem:product});
}else {
that._jumpHaggleDetail(product, json);
}
... ... @@ -106,26 +130,40 @@ class HaggleListContainer extends Component {
}
render() {
let {productList, isShowAlert} = this.props.haggle;
let isFetching = productList.isFetching;
let {productList, myHaggleProductList, resourceInfo, isShowAlert, categoryType} = this.props.haggle;
let isFetching = productList.isFetching || myHaggleProductList.isFetching;
return (
<View style={styles.container}>
<TipsAlert
tips='该商品正在砍价中,去邀请好友帮忙砍价吧!'
isShow={this.state.showAlert}
>
<TipsAlertItem showStatus='sure' >查看详情</TipsAlertItem>
<TipsAlertItem showStatus='cancel' handleAction={this._hiddenTipsAlertDialog}>取消</TipsAlertItem>
</TipsAlert>
<YHAlert
ref='YHAlert'
isShow = {this.state.showAlert}
title = '当前有未完成的砍价!'
content={'该商品正在砍价中,去邀请好友帮忙砍价吧!'}
>
<YHAlertItem key={'minCancel'} param={this.state.productItem} showStatus='LightGrayButton'
handleAction={(param) => {
{this._hiddenTipsAlertDialog()};
}}>取消</YHAlertItem>
<YHAlertItem key={'minSure'} param={this.state.productItem} showStatus='redButton'
handleAction={(param) => {
{this._hiddenTipsAlertDialog()};
{this._jumpHaggleDetail(param, null)};
}}>查看详情</YHAlertItem>
</YHAlert>
<HaggleList
data={productList}
data= {categoryType==0 ? productList : myHaggleProductList}
resourceInfo = {resourceInfo}
onEndReached={this._onEndReached}
categoryType={categoryType}
onPressProduct={this._onPressProduct}
firstHaggle={this._firstHaggle}
continueHaggle={this._continueHaggle}
onPressCategory={this._onPressCategory}
onStop={this._timerStop}/>
onStop={this._timerStop}
resourceJumpWithUrl={this._resourceJumpWithUrl}/>
<LoadingIndicator isVisible={isFetching}/>
</View>
);
... ...
... ... @@ -13,17 +13,33 @@ const {
SHOW_HASCUT_ALERT,
HAGGLE_STATUS_SUCCESS,
REFRESH_PRODUCT_LIST,
MYHAGGLE_PRODUCT_LIST_REQUEST,
MYHAGGLE_PRODUCT_LIST_SUCCESS,
MYHAGGLE_PRODUCT_LIST_FAILURE,
RESOURCE_INFO_REQUEST,
RESOURCE_INFO_SUCCESS,
RESOURCE_INFO_FAILURE,
} = require('../../constants/actionTypes').default;
export function setSelectedCategoryType(index) {
return {
type: SET_SELECTED_CATEGORY,
payload: index
};
}
export function setSelectedCategory(index) {
return (dispatch, getState) => {
dispatch({
type: SET_SELECTED_CATEGORY,
payload: {index}
});
if (index == 0) {
dispatch(setSelectedCategoryType(index));
let {haggle} = getState();
let productList = haggle.productList;
let myproductList = haggle.myHaggleProductList;
let list = productList.list ? productList.list.toArray() : [];
let myList = myproductList.list ? myproductList.list.toArray() : [];
if (index == 0 && list.length == 0) {
dispatch(getProductList());
}else if (index == 1){
}else if (index == 1 && myList.length == 0){
dispatch(getMyHaggleProductList());
}
};
... ... @@ -76,6 +92,45 @@ export function productListFailure(error) {
};
}
export function myHaggleProductListRequest() {
return {
type: MYHAGGLE_PRODUCT_LIST_REQUEST,
};
}
export function myHaggleProductListSuccess(json) {
return {
type: MYHAGGLE_PRODUCT_LIST_SUCCESS,
payload: json
};
}
export function myHaggleProductListFailure(error) {
return {
type: MYHAGGLE_PRODUCT_LIST_FAILURE,
payload: error
};
}
export function getResourceRequest() {
return {
type: RESOURCE_INFO_REQUEST,
};
}
export function getResourceSuccess(json) {
return {
type: RESOURCE_INFO_SUCCESS,
payload: json
};
}
export function getResourceFailure(error) {
return {
type: RESOURCE_INFO_FAILURE,
payload: error
};
}
export function getProductList() {
return (dispatch, getState) => {
let {app, haggle} = getState();
... ... @@ -114,7 +169,7 @@ export function getProductList() {
export function getMyHaggleProductList() {
return (dispatch, getState) => {
let {app, haggle} = getState();
let list = haggle.productList;
let list = haggle.myHaggleProductList;
/**
* page: 0, //当前页面
... ... @@ -123,6 +178,7 @@ export function getMyHaggleProductList() {
* page_total: 0, //总共多少页
* endReached: false, //到达底部
*/
if (list.isFetching || list.endReached || list.error || (!list.endReached && list.page_total === 1)) {
return;
}
... ... @@ -130,7 +186,7 @@ export function getMyHaggleProductList() {
let page = list.page + 1;
let pageSize = list.page_size;
let fetchMyHaggleProductList = (uid) => {
dispatch(productListRequest());
dispatch(myHaggleProductListRequest());
return new haggleService(app.host).fetchMyHaggleProductList(uid, page, pageSize)
.then(json => {
let payload = json;
... ... @@ -140,10 +196,10 @@ export function getMyHaggleProductList() {
let newList = [...oldList, ...payload.list];
payload.list = newList;
}
dispatch(productListSuccess(payload));
dispatch(myHaggleProductListSuccess(payload));
})
.catch(error => {
dispatch(productListFailure(error));
dispatch(myHaggleProductListFailure(error));
});
};
... ... @@ -183,3 +239,18 @@ export function getHaggleStatus(productSkn, activityId, callBack) {
});
};
}
export function getResourceInfo(callback) {
return (dispatch, getState) => {
let {app} = getState();
dispatch(getResourceRequest());
return new haggleService(app.host).fetchResourceInfo('b688fc3b15100d23f247271b7dbe1193')
.then(json => {
dispatch(getResourceSuccess(json));
callback && typeof callback === 'function' && callback(json)
})
.catch(error => {
dispatch(getResourceFailure(error));
});
};
}
... ...
... ... @@ -15,7 +15,26 @@ let InitialState = Record({
endReached: false, //到达底部
list: List(),
})),
myHaggleProductList: new (Record({
isFetching: false,
error: null,
page: 0, //当前页面
page_size: 20, //每页显示的数量
total: 0, //总共多少条
page_total: 0, //总共多少页
endReached: false, //到达底部
list: List(),
})),
resourceInfo: new (Record({
isFetching: false,
error: null,
resourceList: List(),
})),
isShowAlert: false,
categoryType: 0,
});
export default InitialState;
... ...
... ... @@ -7,6 +7,12 @@ const {
PRODUCT_LIST_REQUEST,
PRODUCT_LIST_SUCCESS,
PRODUCT_LIST_FAILURE,
MYHAGGLE_PRODUCT_LIST_REQUEST,
MYHAGGLE_PRODUCT_LIST_SUCCESS,
MYHAGGLE_PRODUCT_LIST_FAILURE,
RESOURCE_INFO_REQUEST,
RESOURCE_INFO_SUCCESS,
RESOURCE_INFO_FAILURE,
SET_SELECTED_CATEGORY,
SHOW_HASCUT_ALERT,
REFRESH_PRODUCT_LIST,
... ... @@ -45,24 +51,71 @@ export default function couponReducer(state = initialState, action) {
.setIn(['productList', 'error'], action.payload);
}
case MYHAGGLE_PRODUCT_LIST_REQUEST: {
return state.setIn(['myHaggleProductList', 'isFetching'], true)
.setIn(['myHaggleProductList', 'error'], null);
}
case MYHAGGLE_PRODUCT_LIST_SUCCESS: {
let {
page,
page_total,
endReached,
list,
} = action.payload;
return state.setIn(['myHaggleProductList', 'isFetching'], false)
.setIn(['myHaggleProductList', 'page'], page)
.setIn(['myHaggleProductList', 'page_total'], page_total)
.setIn(['myHaggleProductList', 'endReached'], endReached)
.setIn(['myHaggleProductList', 'list'], Immutable.fromJS(list))
.setIn(['myHaggleProductList', 'error'], null);
}
case MYHAGGLE_PRODUCT_LIST_FAILURE: {
return state.setIn(['myHaggleProductList', 'isFetching'], false)
.setIn(['myHaggleProductList', 'error'], action.payload);
}
case SET_SELECTED_CATEGORY: {
let {index} = action.payload;
return state.setIn(['productList', 'page'], 0)
.setIn(['productList', 'page_total'], 0)
.setIn(['productList', 'endReached'], false)
.setIn(['productList', 'error'], null);
return state.set('categoryType', action.payload);
}
case REFRESH_PRODUCT_LIST: {
return state.setIn(['productList', 'page'], 0)
.setIn(['productList', 'page_total'], 0)
.setIn(['productList', 'endReached'], false)
.setIn(['productList', 'error'], null)
.setIn(['productList', 'isFetching'], false);
}
if (action.payload == 0) {
return state.setIn(['productList', 'page'], 0)
.setIn(['productList', 'page_total'], 0)
.setIn(['productList', 'endReached'], false)
.setIn(['productList', 'error'], null)
.setIn(['productList', 'isFetching'], false);
}else {
return state.setIn(['myHaggleProductList', 'page'], 0)
.setIn(['myHaggleProductList', 'page_total'], 0)
.setIn(['myHaggleProductList', 'endReached'], false)
.setIn(['myHaggleProductList', 'error'], null)
.setIn(['myHaggleProductList', 'isFetching'], false);
}
}
break;
case SHOW_HASCUT_ALERT: {
return state.setIn(['isShowAlert'], true);
return state.set('isShowAlert', true);
}
case RESOURCE_INFO_REQUEST: {
return state.setIn(['resourceInfo', 'isFetching'], true)
.setIn(['resourceInfo', 'error'], action.payload);
}
case RESOURCE_INFO_SUCCESS: {
return state.setIn(['resourceInfo', 'isFetching'], false)
.setIn(['resourceInfo', 'resourceList'], Immutable.fromJS(action.payload))
.setIn(['resourceInfo', 'error'], null);
}
case RESOURCE_INFO_FAILURE: {
return state.setIn(['resourceInfo', 'isFetching'], false)
.setIn(['resourceInfo', 'error'], null);
}
}
... ...
... ... @@ -66,4 +66,20 @@ export default class haggleService {
});
}
async fetchResourceInfo(content_code) {
return await this.api.get({
url: '/operations/api/v5/resource/get',
body: {
content_code,
}
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
});
}
}
... ...