From b2620d5a5053fb476df26b1c201c9576ed338fec Mon Sep 17 00:00:00 2001 From: 孙凯 <sunkai@qjadeMAC-ipv6.local> Date: Fri, 14 Apr 2017 19:06:04 +0800 Subject: [PATCH] add coupon review by hongmo --- js/home/components/home/Home.js | 6 +++--- js/myAssets/components/addCoupon/AddCoupon.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- js/myAssets/components/coupon/Coupon.js | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- js/myAssets/components/coupon/CouponCell.js | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ js/myAssets/components/coupon/CouponFliter.js | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ js/myAssets/components/coupon/NoDataView.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ js/myAssets/constants/actionTypes.js | 10 ++++++++++ js/myAssets/containers/AddCouponContainer.js | 15 +++++++++++++-- js/myAssets/containers/CouponContainer.js | 31 +++++++++++++++++++++++++++++++ js/myAssets/image/coupon1_tip_bg@3x.png | Bin 0 -> 11466 bytes js/myAssets/image/coupon2_tip_bg@3x.png | Bin 0 -> 6743 bytes js/myAssets/image/down_tip_ic@2x.png | Bin 0 -> 222 bytes js/myAssets/image/ljsy_tip_an@3x.png | Bin 0 -> 2518 bytes js/myAssets/image/up_tip_ic@2x.png | Bin 0 -> 209 bytes js/myAssets/image/yhq_icon@3x.png | Bin 0 -> 6078 bytes js/myAssets/reducers/addCoupon/addCouponActions.js | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- js/myAssets/reducers/addCoupon/addCouponInitialState.js | 5 ++++- js/myAssets/reducers/addCoupon/addCouponReducer.js | 25 +++++++++++++++++++++++-- js/myAssets/reducers/coupon/couponActions.js | 15 +++++++++++++++ js/myAssets/reducers/coupon/couponReducer.js | 17 ++++++++++++++++- js/myAssets/services/AddCouponService.js | 17 +++++++++++++++++ 21 files changed, 761 insertions(+), 14 deletions(-) create mode 100644 js/myAssets/components/coupon/CouponCell.js create mode 100644 js/myAssets/components/coupon/CouponFliter.js create mode 100644 js/myAssets/components/coupon/NoDataView.js create mode 100644 js/myAssets/image/coupon1_tip_bg@3x.png create mode 100644 js/myAssets/image/coupon2_tip_bg@3x.png create mode 100644 js/myAssets/image/down_tip_ic@2x.png create mode 100644 js/myAssets/image/ljsy_tip_an@3x.png create mode 100644 js/myAssets/image/up_tip_ic@2x.png create mode 100755 js/myAssets/image/yhq_icon@3x.png diff --git a/js/home/components/home/Home.js b/js/home/components/home/Home.js index 629dba3..41e8765 100644 --- a/js/home/components/home/Home.js +++ b/js/home/components/home/Home.js @@ -545,7 +545,7 @@ export default class Home extends Component { } _onScroll(event) { - + if (event.nativeEvent.contentOffset.y < height) { if (this.state.showBackTop) { this.setState({showBackTop: false, currentY: event.nativeEvent.contentOffset.y}); @@ -701,7 +701,7 @@ export default class Home extends Component { this.props.onRefresh && this.props.onRefresh(); }} onFinishRefreshData={() => { - this.listView && this.listView.yh_updateVisibleSubViews();//ios 专用 + this.listView && this.listView.yh_updateVisibleSubViews && this.listView.yh_updateVisibleSubViews();//ios 专用 }}//ios 专用 onEndReached={() => { this.props.onEndReached && this.props.onEndReached(); @@ -752,7 +752,7 @@ export default class Home extends Component { this._autoScrollToProductList(); }} /> : null} - + {showBackTop ? <TouchableHighlight diff --git a/js/myAssets/components/addCoupon/AddCoupon.js b/js/myAssets/components/addCoupon/AddCoupon.js index dab3334..1dfe37e 100644 --- a/js/myAssets/components/addCoupon/AddCoupon.js +++ b/js/myAssets/components/addCoupon/AddCoupon.js @@ -2,6 +2,8 @@ import React, {Component} from 'react'; import Immutable, {Map} from 'immutable'; +import LoadingIndicator from '../../../common/components/LoadingIndicator'; +import Prompt from '../../../coupon/components/coupon/Prompt'; import ReactNative, { View, @@ -13,6 +15,7 @@ import ReactNative, { TouchableOpacity, InteractionManager, Platform, + TextInput, } from 'react-native'; @@ -35,19 +38,68 @@ export default class AddCoupon extends Component { render() { let {resource} = this.props; + let data = resource?resource.toJS():''; + let isFetching = data?data.isFetching:false; + let needShowToast = data?data.showMessage:false; + let message = data?data.message:false; + + console.log(data); return ( <View style={styles.container}> - <Text>AddCoupon</Text> + <TextInput + autoCapitalize="none" + clearButtonMode="always" + placeholder={'输入优惠劵码'} + onChange={this.props.updateValue} + style={styles.textInput} + maxLength={50} + underlineColorAndroid="transparent" + onFocus={() => { + //this.props.onFocus && this.props.onFocus(refId); + }} + /> + <TouchableOpacity activeOpacity={1} + onPress={() => { + // this.props.onPressUseNow && this.props.onPressUseNow(resource) + }} + > + <View style={{marginTop: 10,marginLeft: 10,width: 70,height: 35 * DEVICE_WIDTH_RATIO,backgroundColor: 'red',borderRadius: 5,alignItems: 'center',justifyContent: 'center'}}> + <Text style={styles.text}>确定</Text> + </View> + </TouchableOpacity> + {needShowToast ? <Prompt + text={message} + duration={1000} + onPromptHidden={this.props.resetReceiveCouponResult} + /> : null} + <LoadingIndicator + isVisible={isFetching} + /> </View> ); } } let {width, height} = Dimensions.get('window'); +const DEVICE_WIDTH_RATIO = width / 320; let styles = StyleSheet.create({ container: { - flex: 1, + flexDirection: 'row', + }, + textInput: { + width: (width - 100), + height: 35 * DEVICE_WIDTH_RATIO, + fontSize: 12 * DEVICE_WIDTH_RATIO, + padding: 10, + marginTop: 10, + marginLeft: 10, + borderWidth: 1, + borderColor:'black', }, + text: { + fontSize: 15 * DEVICE_WIDTH_RATIO, + color: 'white', + }, }); diff --git a/js/myAssets/components/coupon/Coupon.js b/js/myAssets/components/coupon/Coupon.js index e2af23e..a57532f 100644 --- a/js/myAssets/components/coupon/Coupon.js +++ b/js/myAssets/components/coupon/Coupon.js @@ -2,6 +2,11 @@ import React, {Component} from 'react'; import Immutable, {Map} from 'immutable'; +import CouponFliter from './CouponFliter'; +import LoadingIndicator from '../../../common/components/LoadingIndicator'; +import NoDataView from './NoDataView'; +import CouponCell from './CouponCell'; +import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator'; import ReactNative, { View, @@ -21,6 +26,12 @@ export default class Coupon extends Component { constructor(props) { super(props); + + this._renderRow = this._renderRow.bind(this); + this.dataSource = new ListView.DataSource({ + rowHasChanged: (r1, r2) => r1.key != r2.key, + }); + } shouldComponentUpdate(nextProps){ @@ -32,13 +43,61 @@ export default class Coupon extends Component { } } + _renderRow(rowData, sectionID, rowID) { + return( + <CouponCell resource={rowData} onPressUseNow={this.props.onPressUseNow}/> + ); + } + render() { let {resource} = this.props; - console.log(resource?resource.toJS():''); + + if (!resource) { + return null; + } + let fliter = resource.get('fliter'); + let unuseCoupon = resource.get('unuseCoupon'); + let usedCoupon = resource.get('usedCoupon'); + let coupons = fliter==0?unuseCoupon:usedCoupon; + let endReached = coupons.get('endReached'); + let currentPage = coupons.get('currentPage'); + let dataList = coupons.get('couponList'); + let isFetching = coupons.get('isFetching') && currentPage == 0; + let error = coupons.get('error'); + let showNoContent = ((error || dataList.size == 0) && !isFetching); + let isLoadingMore = coupons.get('isFetching') && currentPage > 0; + return ( <View style={styles.container}> - <Text>Coupon</Text> + <CouponFliter + selectID={fliter} + onPressFilter={this.props.onPressFilter} + /> + {showNoContent ? <NoDataView onPressMore={this.props.onPressMore}/> : <ListView + enableEmptySections={true} + initialListSize={5} + dataSource={this.dataSource.cloneWithRows(dataList.toArray())} + renderRow={this._renderRow} + renderFooter={()=>{ + if (endReached) { + return <View style={styles.placeholder} />; + } else { + return <LoadMoreIndicator + isVisible={isLoadingMore} + animating={true} + />; + } + }} + onEndReached={() => { + if (dataList && dataList.size > 0) { + this.props.onEndReached && this.props.onEndReached(); + } + }} + />} + <LoadingIndicator + isVisible={isFetching} + /> </View> ); } @@ -50,4 +109,8 @@ let styles = StyleSheet.create({ container: { flex: 1, }, + placeholder: { + width, + height: 15, + }, }); diff --git a/js/myAssets/components/coupon/CouponCell.js b/js/myAssets/components/coupon/CouponCell.js new file mode 100644 index 0000000..8e859b0 --- /dev/null +++ b/js/myAssets/components/coupon/CouponCell.js @@ -0,0 +1,244 @@ +'use strict'; + +import React from 'react'; +import ReactNative from 'react-native'; + +const { + View, + TouchableOpacity, + StyleSheet, + Dimensions, + Platform, + Text, + Image, +} = ReactNative; + +import Immutable, {Map} from 'immutable'; + +export default class CouponCell extends React.Component { + + constructor(props) { + super (props); + + this.state = { + showDetail: false, + }; + } + + render() { + let resource = this.props.resource?this.props.resource.toJS():null; + let showDetail = this.state.showDetail; + let tipImage = showDetail?require('../../image/up_tip_ic.png'):require('../../image/down_tip_ic.png'); + let couponDetailInfomation = resource.couponDetailInfomation; + let couponValidity = resource.couponValidity; + let rule4ShortName = resource.rule4ShortName; + let couponValue = resource.couponValue; + let overState = resource.overState; + let isNoLimit = resource.isNoLimit; + let brandNameLimit = resource.brandNameLimit; + let sortNameLimit = resource.sortNameLimit; + let bottomText = brandNameLimit.length > 0 ? '限品牌:'+brandNameLimit[0] :''; + bottomText = sortNameLimit.length > 0 ? bottomText + '限品类:'+sortNameLimit[0] : bottomText; + bottomText = isNoLimit=='true' ? '全场通用' : bottomText; + + let backgroundHeigth = showDetail ? topBackgroundHeigth + detailBackgroundHeigth + 20 : topBackgroundHeigth + 20; + return ( + <View style={{width: width, height: backgroundHeigth}}> + <Image source={require('../../image/coupon1_tip_bg.png')} style={styles.couponBackgroundImage}></Image> + <View style={styles.topContent}> + <View style={styles.topTitleView}> + <Text style={styles.topTitle} numberOfLines={1}>{couponDetailInfomation}</Text> + </View> + <View style={styles.topDetail}> + <View style={styles.leftDetail}> + <View style={styles.priceView}> + <Text style={styles.price} numberOfLines={1}>{couponValue}</Text> + </View> + <Text style={styles.priceDetail} numberOfLines={1}>{rule4ShortName}</Text> + </View> + <View style={styles.rigthDetail}> + <View style={styles.timeDetailTopView}> + <Text style={styles.timeDetailTop} numberOfLines={1}>{couponValidity}</Text> + {overState ? <Text style={styles.timeDetail2} numberOfLines={1}>({overState})</Text>:null} + </View> + <View style={styles.timeDetailBottomView}> + <TouchableOpacity activeOpacity={1} style={styles.timeDetailBottomView} + onPress={() => { + this.setState({showDetail: !showDetail}); + }} + > + <Text style={styles.timeDetailSwitch} numberOfLines={1}>详细信息</Text> + <Image source={tipImage} style={styles.timeDetailSwitchIcon}></Image> + </TouchableOpacity> + <TouchableOpacity activeOpacity={1} style={styles.button} + onPress={() => { + this.props.onPressUseNow && this.props.onPressUseNow(resource) + }} + > + <Image source={require('../../image/ljsy_tip_an.png')} style={styles.button}></Image> + </TouchableOpacity> + </View> + </View> + </View> + </View> + {showDetail ? <View style={styles.bottom}> + <Image source={require('../../image/coupon2_tip_bg.png')} style={styles.bottomBackgroundImage}></Image> + <View style={styles.bottomContent}> + <Text style={styles.bottomText1} numberOfLines={1}>{bottomText}</Text> + <View style={styles.bottomText2View}> + <Text style={styles.bottomText2} numberOfLines={2}>特例商品(秒杀、限定、境外、预售等)暂不支持使用优惠卷</Text> + </View> + </View> + </View> : null} + + <View style={{width: width,height: 20,backgroundColor: 'white',}}/> + </View> + ); + } +} + +let {width, height} = Dimensions.get('window'); +let sc = 360/1037;//背景宽高比 +let scTop = 90/360;//上面标题栏占背景比例 +let scLeft = 345/1037;//左侧占背景比例 +let topBackgroundHeigth = sc*(width - 50); +let topBackgroundWidth = width - 50; + +let sc2 = 182/1035;//背景宽高比 +let detailBackgroundHeigth = sc2*(width - 50); +let detailBackgroundWidth = width - 50; + +let styles = StyleSheet.create({ + + couponBackgroundImage: { + width: topBackgroundWidth, + height: topBackgroundHeigth, + marginLeft: 25, + }, + topContent: { + width: topBackgroundWidth, + height: topBackgroundHeigth, + left: 25, + marginTop: -topBackgroundHeigth, + position: 'absolute', + backgroundColor: 'transparent', + }, + topTitleView: { + height: topBackgroundHeigth * scTop, + width: topBackgroundWidth, + marginLeft: 10, + justifyContent: 'center', + }, + topTitle: { + color: 'white', + }, + topDetail: { + height: topBackgroundHeigth - topBackgroundHeigth * scTop, + width: topBackgroundWidth, + backgroundColor: 'transparent', + flexDirection: 'row', + }, + leftDetail: { + height: topBackgroundHeigth - topBackgroundHeigth * scTop, + width: topBackgroundWidth*scLeft, + backgroundColor: 'transparent', + }, + priceView: { + height: ( topBackgroundHeigth - topBackgroundHeigth * scTop ) * 0.55, + width: topBackgroundWidth*scLeft, + backgroundColor: 'transparent', + alignItems: 'center', + justifyContent: 'center', + marginTop: 10, + }, + price: { + color: 'white', + fontSize: 40, + }, + priceDetail: { + color: 'white', + fontSize: 11, + textAlign: 'center', + }, + + rigthDetail: { + height: topBackgroundHeigth - topBackgroundHeigth * scTop, + width: topBackgroundWidth*(1-scLeft), + backgroundColor: 'transparent', + }, + timeDetailTopView: { + height: 50, + width: topBackgroundWidth*(1-scLeft), + backgroundColor: 'transparent', + }, + timeDetailTop: { + color: 'white', + fontSize: 13, + marginLeft: 15, + marginTop: 12, + }, + timeDetail2: { + fontSize: 13, + marginLeft: 15, + }, + timeDetailBottomView: { + height: 30, + width: topBackgroundWidth*(1-scLeft), + backgroundColor: 'transparent', + marginTop: 5, + alignItems: 'center', + flexDirection: 'row', + }, + timeDetailSwitch: { + color: 'white', + fontSize: 12, + marginLeft: 15, + }, + timeDetailSwitchIcon: { + marginLeft: 5, + }, + button: { + width: 50, + height: 20, + position: 'absolute', + right: 15, + top: 5, + }, + + + bottom: { + width: detailBackgroundWidth, + height: detailBackgroundHeigth, + }, + bottomBackgroundImage: { + width: detailBackgroundWidth, + height: detailBackgroundHeigth, + marginLeft: 25, + }, + bottomContent: { + width: detailBackgroundWidth, + height: detailBackgroundHeigth, + left: 25, + marginTop: -detailBackgroundHeigth, + position: 'absolute', + }, + bottomText1: { + color: 'white', + fontSize: 13, + marginLeft: 15, + backgroundColor: 'transparent', + marginTop: 10, + }, + bottomText2View: { + height: 30, + marginLeft: 15, + backgroundColor: 'transparent', + marginTop: 2, + justifyContent: 'center', + }, + bottomText2: { + color: 'white', + fontSize: 13, + marginTop: 2, + }, +}); diff --git a/js/myAssets/components/coupon/CouponFliter.js b/js/myAssets/components/coupon/CouponFliter.js new file mode 100644 index 0000000..806edfa --- /dev/null +++ b/js/myAssets/components/coupon/CouponFliter.js @@ -0,0 +1,129 @@ +'use strict'; + +import React from 'react'; +import ReactNative from 'react-native'; + +const { + View, + Text, + ListView, + TouchableOpacity, + Dimensions, + StyleSheet, +} = ReactNative; + + +export default class CouponFliter extends React.Component { + + constructor(props) { + super (props); + + this._renderRow = this._renderRow.bind(this); + this._renderSeparator = this._renderSeparator.bind(this); + + this.dataSource = new ListView.DataSource({ + rowHasChanged: (r1, r2) => r1.key != r2.key, + }); + + this.state = { + filters: [ + { + key: 'unuseCoupon', + name: '未使用', + isSelect: false, + }, + { + key: 'usedCoupon', + name: '已使用', + isSelect: false, + }, + ], + selectedIndex: this.props.selectID, + }; + } + + _renderRow(rowData, sectionID, rowID) { + + let colorStyle = rowID == this.state.selectedIndex ? {color: '#444444'} : {color: '#b0b0b0'}; + + return ( + <View style={{backgroundColor: 'white'}}> + <TouchableOpacity onPress={() => { + let filters = this.state.filters; + let filter = this.state.filters[rowID]; + if (this.state.selectedIndex == rowID) { + return; + } + + filter.isSelect = !filter.isSelect; + filters[rowID] = filter; + this.setState({ + selectedIndex: rowID, + filters, + }); + this.props.onPressFilter && this.props.onPressFilter(rowID); + }}> + <View key={'row' + rowID} style={styles.rowContainer}> + <Text style={[styles.name, colorStyle]}>{rowData.name}</Text> + </View> + </TouchableOpacity> + </View> + ); + } + + _renderSeparator(sectionID, rowID, adjacentRowHighlighted) { + return ( + <View key={'sep' + rowID} style={styles.separator}> + </View> + ); + } + + render() { + + return ( + <View style={[styles.container]}> + <ListView + contentContainerStyle={[styles.contentContainer]} + enableEmptySections={true} + dataSource={this.dataSource.cloneWithRows(this.state.filters)} + renderRow={this._renderRow} + renderSeparator={this._renderSeparator} + scrollEnabled={false} + scrollsToTop={false} + /> + <View style={{width: width,height: 1,backgroundColor: '#e5e5e5',}}/> + </View> + ); + } +} + +let {width, height} = Dimensions.get('window'); + +let styles = StyleSheet.create({ + container: { + marginLeft: -1, + width: width + 2, + height: 41, + backgroundColor:'white', + }, + contentContainer: { + flexDirection: 'row', + }, + rowContainer: { + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + width: Math.ceil(width / 2), + height: 40, + backgroundColor:'white', + }, + name: { + color: '#b0b0b0', + }, + separator: { + width: 0.5, + top: 12.5, + height: 15, + backgroundColor: '#e5e5e5', + }, +}); diff --git a/js/myAssets/components/coupon/NoDataView.js b/js/myAssets/components/coupon/NoDataView.js new file mode 100644 index 0000000..0f4f75c --- /dev/null +++ b/js/myAssets/components/coupon/NoDataView.js @@ -0,0 +1,81 @@ +'use strict'; + +import React from 'react'; +import ReactNative from 'react-native'; + +const { + View, + TouchableOpacity, + StyleSheet, + Dimensions, + Platform, + Text, + Image, +} = ReactNative; + +import Immutable, {Map} from 'immutable'; + +export default class NoDataView extends React.Component { + + constructor(props) { + super (props); + } + + shouldComponentUpdate(nextProps){ + if (Immutable.is(nextProps.resource, this.props.resource)) { + return false; + } else { + return true; + } + } + + render() { + return ( + <View style={styles.container}> + <Image source={require('../../image/yhq_icon.png')} style={styles.noLimitCodeIcon}></Image> + <Text style={styles.text}>你还没有优惠券</Text> + <TouchableOpacity activeOpacity={1} style={styles.button} + onPress={() => { + this.props.onPressMore && this.props.onPressMore() + }} + > + <Text style={styles.buttonText}>随便逛逛</Text> + </TouchableOpacity> + </View> + ); + } +} + +let {width, height} = Dimensions.get('window'); +let iconHeight = Math.ceil((80 / 640) * width); +let iconWidth = Math.ceil((153 / 640) * width); +let iconTop = Math.ceil((200 / 640) * width); + +let styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + backgroundColor: 'white', + }, + noLimitCodeIcon: { + width: iconWidth, + height: iconHeight, + marginTop: iconTop, + }, + text: { + marginTop: 30, + fontSize: 12, + }, + button: { + marginTop: 60, + width: 200, + height: 40, + backgroundColor: 'black', + alignItems: 'center', + justifyContent: 'center', + }, + buttonText: { + color: 'white', + fontSize: 15, + }, +}); diff --git a/js/myAssets/constants/actionTypes.js b/js/myAssets/constants/actionTypes.js index d583685..b877a46 100644 --- a/js/myAssets/constants/actionTypes.js +++ b/js/myAssets/constants/actionTypes.js @@ -40,7 +40,17 @@ export default keyMirror({ UNUSE_COUPON_LIST_SUCCESS: null, UNUSE_COUPON_LIST_FAILURE: null, + RESET_DATA: null, + USED_COUPON_LIST_REQUEST: null, USED_COUPON_LIST_SUCCESS: null, USED_COUPON_LIST_FAILURE: null, + + SET_FLITER: null, + + ADD_COUPON_REQUEST: null, + ADD_COUPON_SUCCESS: null, + ADD_COUPON_FAILURE: null, + + RESETRECEIVECOUPONRES: null, }); diff --git a/js/myAssets/containers/AddCouponContainer.js b/js/myAssets/containers/AddCouponContainer.js index 2c6827d..5d2a05f 100644 --- a/js/myAssets/containers/AddCouponContainer.js +++ b/js/myAssets/containers/AddCouponContainer.js @@ -44,23 +44,34 @@ function mapDispatchToProps(dispatch) { class AddCouponContainer extends Component { constructor(props) { super(props); + this.resetReceiveCouponResult=this.resetReceiveCouponResult.bind(this); + this.updateValue = this.updateValue.bind(this); } componentDidMount() { - + // this.props.actions.addCoupon('aaaaaaaaa'); } componentWillUnmount() { } + resetReceiveCouponResult() { + this.props.actions.resetReceiveCouponResult(); + } + + updateValue(event) { + console.log(event); + } + render() { let {addCoupon} = this.props; - return ( <View style={styles.container}> <AddCoupon resource={addCoupon} + resetReceiveCouponResult={this.resetReceiveCouponResult} + updateValue={this.updateValue} /> </View> ); diff --git a/js/myAssets/containers/CouponContainer.js b/js/myAssets/containers/CouponContainer.js index 37d268c..75867b2 100644 --- a/js/myAssets/containers/CouponContainer.js +++ b/js/myAssets/containers/CouponContainer.js @@ -44,6 +44,17 @@ function mapDispatchToProps(dispatch) { class CouponContainer extends Component { constructor(props) { super(props); + this._onPressFilter = this._onPressFilter.bind(this); + this._onPressMore = this._onPressMore.bind(this); + this._onEndReached = this._onEndReached.bind(this); + this._onPressUseNow = this._onPressUseNow.bind(this); + this.subscription = NativeAppEventEmitter.addListener( + 'needUpdateCoupon', + (reminder) => { + this.props.actions.resetData(); + this.props.actions.getUnuseCouponsList(); + } + ); } componentDidMount() { @@ -51,7 +62,23 @@ class CouponContainer extends Component { } componentWillUnmount() { + this.subscription && this.subscription.remove(); + } + + _onPressUseNow(data){ + ReactNative.NativeModules.YH_MyAssetsViewHelper.jumpToCouponProductListWithCoupon(data); + } + + _onEndReached() { + this.props.actions.getUnuseCouponsList(); + } + + _onPressFilter(fliter){ + this.props.actions.setFliter(fliter); + } + _onPressMore(){ + ReactNative.NativeModules.YH_MyAssetsViewHelper.lookAroundBtnTappedForCoupon(); } render() { @@ -60,6 +87,10 @@ class CouponContainer extends Component { <View style={styles.container}> <Coupon resource={coupon} + onPressFilter={this._onPressFilter} + onPressMore={this._onPressMore} + onEndReached={this._onEndReached} + onPressUseNow={this._onPressUseNow} /> </View> ); diff --git a/js/myAssets/image/coupon1_tip_bg@3x.png b/js/myAssets/image/coupon1_tip_bg@3x.png new file mode 100644 index 0000000..560bbc8 Binary files /dev/null and b/js/myAssets/image/coupon1_tip_bg@3x.png differ diff --git a/js/myAssets/image/coupon2_tip_bg@3x.png b/js/myAssets/image/coupon2_tip_bg@3x.png new file mode 100644 index 0000000..f0be4bd Binary files /dev/null and b/js/myAssets/image/coupon2_tip_bg@3x.png differ diff --git a/js/myAssets/image/down_tip_ic@2x.png b/js/myAssets/image/down_tip_ic@2x.png new file mode 100644 index 0000000..770bfa1 Binary files /dev/null and b/js/myAssets/image/down_tip_ic@2x.png differ diff --git a/js/myAssets/image/ljsy_tip_an@3x.png b/js/myAssets/image/ljsy_tip_an@3x.png new file mode 100644 index 0000000..67c9953 Binary files /dev/null and b/js/myAssets/image/ljsy_tip_an@3x.png differ diff --git a/js/myAssets/image/up_tip_ic@2x.png b/js/myAssets/image/up_tip_ic@2x.png new file mode 100644 index 0000000..7bc1af6 Binary files /dev/null and b/js/myAssets/image/up_tip_ic@2x.png differ diff --git a/js/myAssets/image/yhq_icon@3x.png b/js/myAssets/image/yhq_icon@3x.png new file mode 100755 index 0000000..f972f7e Binary files /dev/null and b/js/myAssets/image/yhq_icon@3x.png differ diff --git a/js/myAssets/reducers/addCoupon/addCouponActions.js b/js/myAssets/reducers/addCoupon/addCouponActions.js index c581346..0bf1768 100644 --- a/js/myAssets/reducers/addCoupon/addCouponActions.js +++ b/js/myAssets/reducers/addCoupon/addCouponActions.js @@ -4,5 +4,60 @@ import ReactNative from 'react-native'; import AddCouponService from '../../services/AddCouponService'; const { - SET_SERVICE_HOST + ADD_COUPON_REQUEST, + ADD_COUPON_SUCCESS, + ADD_COUPON_FAILURE, + + RESETRECEIVECOUPONRES, } = require('../../constants/actionTypes').default; + +export function resetReceiveCouponResult() { + return { + type: RESETRECEIVECOUPONRES, + } +} + +export function addCouponRequest() { + return { + type: ADD_COUPON_REQUEST, + }; +} + +export function addCouponSuccess(json) { + return { + type: ADD_COUPON_SUCCESS, + payload: json + } +} + +export function addCouponFailure(error) { + return { + type: ADD_COUPON_FAILURE, + payload: error + } +} + +export function addCoupon(coupon_code) { + return (dispatch, getState) => { + let {app, addCoupon} = getState(); + + let fetchAddCoupon = (uid) => { + dispatch(addCouponRequest()); + return new AddCouponService(app.host).addCoupon(uid,coupon_code) + .then(json => { + dispatch(addCouponSuccess(json)); + ReactNative.NativeModules.YH_MyAssetsViewHelper.needUpdateCoupon(); + }) + .catch(error => { + dispatch(addCouponFailure(error)); + }); + } + + ReactNative.NativeModules.YH_CommonHelper.uid() + .then(uid => { + fetchAddCoupon(uid); + }) + .catch(error => { + }); + }; +} diff --git a/js/myAssets/reducers/addCoupon/addCouponInitialState.js b/js/myAssets/reducers/addCoupon/addCouponInitialState.js index db0cca0..07c37a6 100755 --- a/js/myAssets/reducers/addCoupon/addCouponInitialState.js +++ b/js/myAssets/reducers/addCoupon/addCouponInitialState.js @@ -3,7 +3,10 @@ import {Record, List, Map} from 'immutable'; let InitialState = Record({ - aaa: '', + isFetching: false, + error: null, + message: '', + showMessage: false, }); export default InitialState; diff --git a/js/myAssets/reducers/addCoupon/addCouponReducer.js b/js/myAssets/reducers/addCoupon/addCouponReducer.js index f66bfd2..a675ea1 100644 --- a/js/myAssets/reducers/addCoupon/addCouponReducer.js +++ b/js/myAssets/reducers/addCoupon/addCouponReducer.js @@ -4,7 +4,11 @@ import InitialState from './addCouponInitialState'; import Immutable, {Map} from 'immutable'; const { - SET_SERVICE_HOST, + ADD_COUPON_REQUEST, + ADD_COUPON_SUCCESS, + ADD_COUPON_FAILURE, + + RESETRECEIVECOUPONRES, } = require('../../constants/actionTypes').default; @@ -12,8 +16,25 @@ const initialState = new InitialState; export default function detailReducer(state=initialState, action) { switch(action.type) { - case SET_SERVICE_HOST: { + case ADD_COUPON_REQUEST: { + return state.set('isFetching', true) + .set('error', null); + } + case ADD_COUPON_SUCCESS: { + return state.set('isFetching', false) + .set('message', '领取成功') + .set('showMessage', true); + } + case ADD_COUPON_FAILURE: { + return state.set('isFetching', false) + .set('error', action.payload) + .set('message', action.payload.message) + .set('showMessage', true); } + case RESETRECEIVECOUPONRES: { + return state.set('message', '').set('showMessage', false); + } + break; } return state; } diff --git a/js/myAssets/reducers/coupon/couponActions.js b/js/myAssets/reducers/coupon/couponActions.js index d0700df..54efa3d 100644 --- a/js/myAssets/reducers/coupon/couponActions.js +++ b/js/myAssets/reducers/coupon/couponActions.js @@ -4,6 +4,8 @@ import ReactNative from 'react-native'; import CouponService from '../../services/CouponService'; const { + SET_FLITER, + UNUSE_COUPON_LIST_REQUEST, UNUSE_COUPON_LIST_SUCCESS, UNUSE_COUPON_LIST_FAILURE, @@ -12,8 +14,21 @@ const { USED_COUPON_LIST_SUCCESS, USED_COUPON_LIST_FAILURE, + RESET_DATA, } = require('../../constants/actionTypes').default; +export function setFliter(fliter) { + return { + type: SET_FLITER, + payload: fliter, + }; +} + +export function resetData() { + return { + type: RESET_DATA, + }; +} export function unuseCouponListRequest() { return { diff --git a/js/myAssets/reducers/coupon/couponReducer.js b/js/myAssets/reducers/coupon/couponReducer.js index 5e7843d..1799d65 100644 --- a/js/myAssets/reducers/coupon/couponReducer.js +++ b/js/myAssets/reducers/coupon/couponReducer.js @@ -4,6 +4,8 @@ import InitialState from './couponInitialState'; import Immutable, {Map} from 'immutable'; const { + SET_FLITER, + UNUSE_COUPON_LIST_REQUEST, UNUSE_COUPON_LIST_SUCCESS, UNUSE_COUPON_LIST_FAILURE, @@ -11,7 +13,7 @@ const { USED_COUPON_LIST_REQUEST, USED_COUPON_LIST_SUCCESS, USED_COUPON_LIST_FAILURE, - + RESET_DATA, } = require('../../constants/actionTypes').default; const initialState = new InitialState; @@ -52,6 +54,19 @@ export default function detailReducer(state=initialState, action) { return state.setIn(['usedCoupon', 'isFetching'], false) .setIn(['usedCoupon', 'error'], action.payload); } + case SET_FLITER: { + return state.set('fliter', action.payload); + } + case RESET_DATA: { + return state.setIn(['unuseCoupon', 'isFetching'], false) + .setIn(['unuseCoupon', 'currentPage'], 0) + .setIn(['unuseCoupon', 'pageSize'], 10) + .setIn(['unuseCoupon', 'total'], 0) + .setIn(['unuseCoupon', 'endReached'], false) + .setIn(['unuseCoupon', 'couponList'], Immutable.fromJS([])) + .setIn(['unuseCoupon', 'error'], null); + } + break; } return state; } diff --git a/js/myAssets/services/AddCouponService.js b/js/myAssets/services/AddCouponService.js index 1e58630..aaa67b7 100644 --- a/js/myAssets/services/AddCouponService.js +++ b/js/myAssets/services/AddCouponService.js @@ -11,4 +11,21 @@ export default class AddCouponService { } this.api = new Request(baseURL); } + async addCoupon (uid,coupon_code, fromPage = "") { + return await this.api.get({ + url: '', + body: { + method: 'app.coupons.bindPCoupon', + coupon_code, + uid, + fromPage, + } + }) + .then((json) => { + return json; + }) + .catch((error) => { + throw(error); + }); + } } -- libgit2 0.24.0