VIP等级,review by Redding
Showing
17 changed files
with
677 additions
and
8 deletions
@@ -20,8 +20,9 @@ import {Record, List, Map} from 'immutable'; | @@ -20,8 +20,9 @@ import {Record, List, Map} from 'immutable'; | ||
20 | 20 | ||
21 | import appInitialState from './reducers/app/appInitialState'; | 21 | import appInitialState from './reducers/app/appInitialState'; |
22 | import personalInfoInitialState from './reducers/personalInfo/personalInfoInitialState'; | 22 | import personalInfoInitialState from './reducers/personalInfo/personalInfoInitialState'; |
23 | - | 23 | +import vipLevelInitialState from './reducers/vipLevel/vipLevelInitialState'; |
24 | import PersonalInfoContainer from './containers/PersonalInfoContainer'; | 24 | import PersonalInfoContainer from './containers/PersonalInfoContainer'; |
25 | +import VIPLevelContainer from './containers/VIPLevelContainer'; | ||
25 | 26 | ||
26 | import { | 27 | import { |
27 | setPlatform, | 28 | setPlatform, |
@@ -29,10 +30,15 @@ import { | @@ -29,10 +30,15 @@ import { | ||
29 | setServiceHost, | 30 | setServiceHost, |
30 | } from './reducers/app/appActions'; | 31 | } from './reducers/app/appActions'; |
31 | 32 | ||
33 | +import { | ||
34 | + setNickname, | ||
35 | +} from './reducers/vipLevel/vipLevelActions'; | ||
36 | + | ||
32 | function getInitialState() { | 37 | function getInitialState() { |
33 | const _initState = { | 38 | const _initState = { |
34 | app: (new appInitialState()), | 39 | app: (new appInitialState()), |
35 | personalInfo: (new personalInfoInitialState()), | 40 | personalInfo: (new personalInfoInitialState()), |
41 | + vipLevel: (new vipLevelInitialState()), | ||
36 | }; | 42 | }; |
37 | return _initState; | 43 | return _initState; |
38 | } | 44 | } |
@@ -42,12 +48,21 @@ export default function native(platform) { | @@ -42,12 +48,21 @@ export default function native(platform) { | ||
42 | let YH_PersonalInfo = React.createClass({ | 48 | let YH_PersonalInfo = React.createClass({ |
43 | render() { | 49 | render() { |
44 | const store = configureStore(getInitialState()); | 50 | const store = configureStore(getInitialState()); |
45 | - | ||
46 | - return ( | ||
47 | - <Provider store={store}> | ||
48 | - <PersonalInfoContainer /> | ||
49 | - </Provider> | ||
50 | - ); | 51 | + if (this.props.type == 'VIPLevel') { |
52 | + let nickname = this.props.nickname; | ||
53 | + store.dispatch(setNickname(nickname)); | ||
54 | + return( | ||
55 | + <Provider store={store}> | ||
56 | + <VIPLevelContainer /> | ||
57 | + </Provider> | ||
58 | + ); | ||
59 | + } else { | ||
60 | + return ( | ||
61 | + <Provider store={store}> | ||
62 | + <PersonalInfoContainer /> | ||
63 | + </Provider> | ||
64 | + ); | ||
65 | + } | ||
51 | } | 66 | } |
52 | }); | 67 | }); |
53 | 68 |
js/personalInfo/components/VIPLevel.js
0 → 100644
1 | +'use strict' | ||
2 | + | ||
3 | +import React, {Component} from 'react'; | ||
4 | +import { | ||
5 | + StyleSheet, | ||
6 | + Dimensions, | ||
7 | + Platform, | ||
8 | + View, | ||
9 | + Text, | ||
10 | + Image, | ||
11 | + ListView, | ||
12 | + TouchableOpacity, | ||
13 | +} from 'react-native'; | ||
14 | + | ||
15 | +import {Map} from 'immutable'; | ||
16 | +import VIPPrivilegeCell from './VIPPrivilegeCell'; | ||
17 | +import VIPLevelHeader from './VIPLevelHeader'; | ||
18 | + | ||
19 | +export default class VIPLevel extends Component { | ||
20 | + constructor(props) { | ||
21 | + super(props); | ||
22 | + this.renderRow = this.renderRow.bind(this); | ||
23 | + this.renderFooter = this.renderFooter.bind(this); | ||
24 | + this.renderHeader = this.renderHeader.bind(this); | ||
25 | + this.renderSectionHeader = this.renderSectionHeader.bind(this); | ||
26 | + this.renderSeparator = this.renderSeparator.bind(this); | ||
27 | + this.dataSource = new ListView.DataSource({ | ||
28 | + rowHasChanged: (r1, r2) => !Immutable.is(r1, r2), | ||
29 | + }); | ||
30 | + } | ||
31 | + | ||
32 | + renderFooter() { | ||
33 | + let {vipInfo} = this.props; | ||
34 | + return( | ||
35 | + <View style={styles.footer}> | ||
36 | + {vipInfo.get('enjoy_preferential') && vipInfo.get('enjoy_preferential').size ? | ||
37 | + <View style={{width: width,height: 15,backgroundColor: '#e5e5e5',}}/> | ||
38 | + :null | ||
39 | + } | ||
40 | + <TouchableOpacity activeOpacity={1.0} onPress={() => { | ||
41 | + this.props.onPressAllVIPPrivilegeCell && this.props.onPressAllVIPPrivilegeCell(); | ||
42 | + }}> | ||
43 | + <View style={styles.allPrivilegeCell}> | ||
44 | + <Text style={{marginLeft: 15, fontSize: 15}}> | ||
45 | + 查看全部VIP特权 | ||
46 | + </Text> | ||
47 | + <Image style={{marginRight: 15}} | ||
48 | + source={require('../image/cell_indicator.png')} | ||
49 | + /> | ||
50 | + </View> | ||
51 | + </TouchableOpacity> | ||
52 | + </View> | ||
53 | + ); | ||
54 | + } | ||
55 | + | ||
56 | + renderHeader() { | ||
57 | + let {nickname, vipInfo, vipShowPageInfo} = this.props; | ||
58 | + return( | ||
59 | + <VIPLevelHeader | ||
60 | + nickname={nickname} | ||
61 | + vipInfo={vipInfo} | ||
62 | + vipShowPageInfo={vipShowPageInfo} | ||
63 | + /> | ||
64 | + ); | ||
65 | + } | ||
66 | + | ||
67 | + renderSectionHeader(sectionData, sectionID) { | ||
68 | + if (!sectionData.length) { | ||
69 | + return null; | ||
70 | + } | ||
71 | + return( | ||
72 | + <View style={styles.sectionHeader}> | ||
73 | + <Text style={{lineHeight:38,fontSize:17,color:'#444444',height:58}}> | ||
74 | + 当前可享受的特权 | ||
75 | + </Text> | ||
76 | + <View style={{width: width,height: 0.5,backgroundColor: '#e5e5e5',}}/> | ||
77 | + </View> | ||
78 | + ); | ||
79 | + } | ||
80 | + | ||
81 | + renderRow(rowData,sectionID,rowID) { | ||
82 | + return( | ||
83 | + <VIPPrivilegeCell | ||
84 | + dataSource={rowData} | ||
85 | + onPressPrivilegeCell={this.props.onPressPrivilegeCell} | ||
86 | + /> | ||
87 | + ); | ||
88 | + } | ||
89 | + | ||
90 | + renderSeparator(sectionID, rowID, adjacentRowHighlighted) { | ||
91 | + return( | ||
92 | + <View style={{width: width,height: 0.5,backgroundColor: '#e5e5e5',}}/> | ||
93 | + ); | ||
94 | + } | ||
95 | + | ||
96 | + render() { | ||
97 | + let {nickname, isFetching, vipInfo} = this.props; | ||
98 | + let dataSource = {}; | ||
99 | + if (vipInfo.get('enjoy_preferential') && vipInfo.get('enjoy_preferential').size) { | ||
100 | + dataSource = {'privilegeSection':vipInfo.get('enjoy_preferential').toArray()}; | ||
101 | + } | ||
102 | + return ( | ||
103 | + <View style={styles.container}> | ||
104 | + <ListView | ||
105 | + contentContainerStyle={styles.contentContainer} | ||
106 | + enableEmptySections={true} | ||
107 | + dataSource={this.dataSource.cloneWithRowsAndSections(dataSource)} | ||
108 | + renderRow={this.renderRow} | ||
109 | + renderFooter={this.renderFooter} | ||
110 | + renderHeader={this.renderHeader} | ||
111 | + renderSectionHeader={this.renderSectionHeader} | ||
112 | + renderSeparator={this.renderSeparator} | ||
113 | + /> | ||
114 | + </View> | ||
115 | + ); | ||
116 | + } | ||
117 | +} | ||
118 | + | ||
119 | +let {width, height} = Dimensions.get('window'); | ||
120 | +const DEVICE_WIDTH_RATIO = width / 320; | ||
121 | + | ||
122 | +let styles = StyleSheet.create({ | ||
123 | + container: { | ||
124 | + flex: 1, | ||
125 | + backgroundColor: '#ebebeb', | ||
126 | + }, | ||
127 | + allPrivilegeCell: { | ||
128 | + height: 44 * DEVICE_WIDTH_RATIO, | ||
129 | + flexDirection: 'row', | ||
130 | + justifyContent: 'space-between', | ||
131 | + alignItems: 'center', | ||
132 | + backgroundColor: 'white', | ||
133 | + }, | ||
134 | + sectionHeader: { | ||
135 | + height: 59, | ||
136 | + paddingLeft: 15, | ||
137 | + backgroundColor:'white', | ||
138 | + }, | ||
139 | +}); |
js/personalInfo/components/VIPLevelHeader.js
0 → 100644
1 | +'use strict' | ||
2 | + | ||
3 | +import React, {Component} from 'react'; | ||
4 | +import { | ||
5 | + StyleSheet, | ||
6 | + Dimensions, | ||
7 | + Platform, | ||
8 | + View, | ||
9 | + Text, | ||
10 | + Image, | ||
11 | + TouchableOpacity, | ||
12 | +} from 'react-native'; | ||
13 | + | ||
14 | +import {Map} from 'immutable'; | ||
15 | + | ||
16 | +export default class VIPLevelHeader extends Component { | ||
17 | + constructor(props) { | ||
18 | + super(props); | ||
19 | + } | ||
20 | + | ||
21 | + render() { | ||
22 | + let {nickname, vipInfo, vipShowPageInfo} = this.props; | ||
23 | + vipInfo = vipInfo.toJS(); | ||
24 | + let vipImageUrl = ''; | ||
25 | + let VIPLevel = vipInfo.current_vip_level; | ||
26 | + switch (VIPLevel) { | ||
27 | + case '1': | ||
28 | + vipImageUrl = require('../image/mine_vip_1.png'); | ||
29 | + break; | ||
30 | + case '2': | ||
31 | + vipImageUrl = require('../image/mine_vip_2.png'); | ||
32 | + break; | ||
33 | + case '3': | ||
34 | + vipImageUrl = require('../image/mine_vip_3.png'); | ||
35 | + break; | ||
36 | + default: | ||
37 | + vipImageUrl = ''; | ||
38 | + } | ||
39 | + let nextLevelTipMessage = '您已升至最高等级啦!' | ||
40 | + if (VIPLevel != '3') { | ||
41 | + | ||
42 | + } | ||
43 | + | ||
44 | + return ( | ||
45 | + <TouchableOpacity activeOpacity={1.0} onPress={() => { | ||
46 | + this.props.onPressPrivilegeCell && this.props.onPressPrivilegeCell(dataSource); | ||
47 | + }}> | ||
48 | + <View style={[styles.container, {height: 260}]}> | ||
49 | + <View style={styles.nickname}> | ||
50 | + <Text style={{marginLeft:17, color:'#444444'}}> | ||
51 | + {nickname} | ||
52 | + </Text> | ||
53 | + {vipImageUrl !='' ? | ||
54 | + <Image style={{marginLeft:10}} | ||
55 | + source={vipImageUrl} | ||
56 | + />:null | ||
57 | + } | ||
58 | + </View> | ||
59 | + | ||
60 | + {VIPLevel == '3'? | ||
61 | + <Text style={{marginLeft:15,marginTop:5,fontSize:12,color:'#b0b0b0'}}> | ||
62 | + 您已升至最高等级啦! | ||
63 | + </Text> | ||
64 | + :<Text style={{marginLeft:15,marginTop:5,fontSize:12,color:'#b0b0b0'}}> | ||
65 | + 还差 | ||
66 | + <Text style={{marginLeft:15,color:'#444444'}}> | ||
67 | + ¥{vipShowPageInfo.get('upgradeNeedCost')} | ||
68 | + </Text> | ||
69 | + 就可以升级为{vipInfo.next_vip_title} | ||
70 | + </Text> | ||
71 | + } | ||
72 | + <Text style={{marginLeft:15,marginTop:5,fontSize:12,color:'#b0b0b0'}}> | ||
73 | + (VIP金额累计需订单成功签收满15天且无退换货) | ||
74 | + </Text> | ||
75 | + <Text style={{marginLeft:15,marginTop:5,fontSize:12,color:'#444444'}}> | ||
76 | + 年度累计金额: | ||
77 | + <Text style={{marginLeft:5,fontSize:17,color:'#d0021b'}}> | ||
78 | + ¥{vipInfo.current_year_cost} | ||
79 | + </Text> | ||
80 | + </Text> | ||
81 | + <View style={styles.nextLevelNeedProcess}> | ||
82 | + {VIPLevel == '3'?null: | ||
83 | + <View style={styles.nextLevelCost}> | ||
84 | + <Text style={{color:'#b0b0b0',fontSize:13,color:'#b0b0b0'}}> | ||
85 | + ¥0.00{vipInfo.next_need_cost} | ||
86 | + </Text> | ||
87 | + </View> | ||
88 | + | ||
89 | + } | ||
90 | + <View style={styles.nextLevelCompletedProcess}> | ||
91 | + </View> | ||
92 | + </View> | ||
93 | + <View style={styles.curAndNextVIPTitle}> | ||
94 | + <Text style={{marginLeft:15,fontSize:12,color:'#444444',fontStyle:'italic'}}> | ||
95 | + {vipInfo.current_vip_title} | ||
96 | + </Text> | ||
97 | + {vipInfo.next_vip_title =='3' ? | ||
98 | + <Text style={{marginRight:15,fontSize:12,color:'#444444',fontStyle: 'italic'}}> | ||
99 | + {vipInfo.next_vip_title} | ||
100 | + </Text>:null | ||
101 | + } | ||
102 | + </View> | ||
103 | + <View style={{width: width,height: 15,backgroundColor: '#e5e5e5',}}/> | ||
104 | + | ||
105 | + <View style={styles.totalCost}> | ||
106 | + <Text style={{marginLeft:15,fontSize:17,color:'#444444'}}> | ||
107 | + 年度累计金额: | ||
108 | + </Text> | ||
109 | + <Text style={{marginRight:15,fontSize:14,color:'#444444'}}> | ||
110 | + ¥{vipInfo.current_year_cost} | ||
111 | + </Text> | ||
112 | + </View> | ||
113 | + <View style={{height: 1.0,backgroundColor: '#e5e5e5',marginLeft:15}}/> | ||
114 | + | ||
115 | + <View style={styles.totalCost}> | ||
116 | + <Text style={{marginLeft:15,fontSize:17,color:'#444444'}}> | ||
117 | + 历史消费总金额: | ||
118 | + </Text> | ||
119 | + <Text style={{marginRight:15,fontSize:14,color:'#444444'}}> | ||
120 | + ¥{vipInfo.current_total_cost} | ||
121 | + </Text> | ||
122 | + </View> | ||
123 | + | ||
124 | + <View style={{width: width,height: 15,backgroundColor: '#e5e5e5',}}/> | ||
125 | + | ||
126 | + </View> | ||
127 | + </TouchableOpacity> | ||
128 | + ); | ||
129 | + } | ||
130 | +} | ||
131 | + | ||
132 | +let {width, height} = Dimensions.get('window'); | ||
133 | + | ||
134 | +const DEVICE_WIDTH_RATIO = width / 320; | ||
135 | + | ||
136 | +let styles = StyleSheet.create({ | ||
137 | + container: { | ||
138 | + flex: 1, | ||
139 | + backgroundColor: 'white', | ||
140 | + }, | ||
141 | + nickname: { | ||
142 | + flexDirection: 'row', | ||
143 | + marginTop: 15, | ||
144 | + }, | ||
145 | + nextLevelNeedProcess: { | ||
146 | + position: 'relative', | ||
147 | + marginTop: 10, | ||
148 | + height: 10, | ||
149 | + width: width - 30, | ||
150 | + marginLeft: 15, | ||
151 | + backgroundColor: '#b0b0b0', | ||
152 | + borderRadius: 5, | ||
153 | + }, | ||
154 | + nextLevelCompletedProcess: { | ||
155 | + position: 'absolute', | ||
156 | + bottom: 0, | ||
157 | + left: 0, | ||
158 | + height: 10, | ||
159 | + width: width - 30, | ||
160 | + backgroundColor: '#c40016', | ||
161 | + borderRadius: 5, | ||
162 | + }, | ||
163 | + nextLevelCost: { | ||
164 | + position: 'absolute', | ||
165 | + top: 0, | ||
166 | + right: 0, | ||
167 | + marginTop: -17, | ||
168 | + backgroundColor: 'white', | ||
169 | + }, | ||
170 | + curAndNextVIPTitle: { | ||
171 | + flexDirection: 'row', | ||
172 | + justifyContent: 'space-between', | ||
173 | + alignItems: 'center', | ||
174 | + marginBottom: 5, | ||
175 | + marginTop: 5, | ||
176 | + }, | ||
177 | + totalCost: { | ||
178 | + flexDirection: 'row', | ||
179 | + justifyContent: 'space-between', | ||
180 | + alignItems: 'center', | ||
181 | + height: 44, | ||
182 | + } | ||
183 | +}); |
1 | +'use strict' | ||
2 | + | ||
3 | +import React, {Component} from 'react'; | ||
4 | +import { | ||
5 | + StyleSheet, | ||
6 | + Dimensions, | ||
7 | + Platform, | ||
8 | + View, | ||
9 | + Text, | ||
10 | + Image, | ||
11 | + TouchableOpacity, | ||
12 | +} from 'react-native'; | ||
13 | + | ||
14 | +import {Map} from 'immutable'; | ||
15 | +import YH_Image from '../../common/components/YH_Image'; | ||
16 | + | ||
17 | +export default class VIPPrivilegeCell extends Component { | ||
18 | + constructor(props) { | ||
19 | + super(props); | ||
20 | + } | ||
21 | + | ||
22 | + render() { | ||
23 | + let {dataSource} = this.props; | ||
24 | + return ( | ||
25 | + <TouchableOpacity activeOpacity={1.0} onPress={() => { | ||
26 | + this.props.onPressPrivilegeCell && this.props.onPressPrivilegeCell(dataSource); | ||
27 | + }}> | ||
28 | + <View style={styles.container}> | ||
29 | + <YH_Image url={dataSource.get('pic')} style={styles.image} /> | ||
30 | + | ||
31 | + <View style={styles.descriptionContainer}> | ||
32 | + <Text style={styles.title}> | ||
33 | + {dataSource.get('title')} | ||
34 | + </Text> | ||
35 | + <Text style={styles.description}> | ||
36 | + {dataSource.get('description')} | ||
37 | + </Text> | ||
38 | + </View> | ||
39 | + </View> | ||
40 | + </TouchableOpacity> | ||
41 | + ); | ||
42 | + } | ||
43 | +} | ||
44 | + | ||
45 | +let {width, height} = Dimensions.get('window'); | ||
46 | +const DEVICE_WIDTH_RATIO = width / 320; | ||
47 | + | ||
48 | +let styles = StyleSheet.create({ | ||
49 | + container: { | ||
50 | + flex: 1, | ||
51 | + backgroundColor: 'white', | ||
52 | + flexDirection: 'row', | ||
53 | + height: 69, | ||
54 | + }, | ||
55 | + image: { | ||
56 | + marginLeft: 15, | ||
57 | + width: 35, | ||
58 | + height: 35, | ||
59 | + marginTop: 17, | ||
60 | + }, | ||
61 | + descriptionContainer: { | ||
62 | + height: 69, | ||
63 | + width: width - 80, | ||
64 | + justifyContent: 'center', | ||
65 | + }, | ||
66 | + title: { | ||
67 | + textAlign: 'left', | ||
68 | + fontSize: 12, | ||
69 | + marginBottom: 8, | ||
70 | + }, | ||
71 | + description: { | ||
72 | + textAlign: 'left', | ||
73 | + fontSize: 12, | ||
74 | + lineHeight: 15, | ||
75 | + color: '#b0b0b0', | ||
76 | + | ||
77 | + } | ||
78 | +}); |
@@ -6,6 +6,10 @@ export default keyMirror({ | @@ -6,6 +6,10 @@ export default keyMirror({ | ||
6 | FETCH_PROFILE_REQUEST: null, | 6 | FETCH_PROFILE_REQUEST: null, |
7 | FETCH_PROFILE_SUCCESS: null, | 7 | FETCH_PROFILE_SUCCESS: null, |
8 | FETCH_PROFILE_FAILURE: null, | 8 | FETCH_PROFILE_FAILURE: null, |
9 | - | ||
10 | UPDATE_PAGE_CELL_LIST: null, | 9 | UPDATE_PAGE_CELL_LIST: null, |
10 | + | ||
11 | + SET_NICKNAME: null, | ||
12 | + FETCH_VIP_INFO_REQUEST: null, | ||
13 | + FETCH_VIP_INFO_SUCCESS: null, | ||
14 | + FETCH_VIP_INFO_FAILURE: null, | ||
11 | }); | 15 | }); |
1 | +'use strict' | ||
2 | + | ||
3 | +import React, {Component} from 'react'; | ||
4 | +import ReactNative, { | ||
5 | + StyleSheet, | ||
6 | + Dimensions, | ||
7 | + Platform, | ||
8 | + View, | ||
9 | + Text, | ||
10 | + NativeModules, | ||
11 | + InteractionManager, | ||
12 | + NativeAppEventEmitter, | ||
13 | +} from 'react-native' | ||
14 | + | ||
15 | +import {bindActionCreators} from 'redux'; | ||
16 | +import {connect} from 'react-redux'; | ||
17 | +import {Map} from 'immutable'; | ||
18 | +import * as vipLevelActions from '../reducers/vipLevel/vipLevelActions'; | ||
19 | +import VIPLevel from '../components/VIPLevel'; | ||
20 | + | ||
21 | + | ||
22 | +const actions = [ | ||
23 | + vipLevelActions, | ||
24 | +]; | ||
25 | + | ||
26 | +function mapStateToProps(state) { | ||
27 | + return { | ||
28 | + ...state | ||
29 | + }; | ||
30 | +} | ||
31 | + | ||
32 | +function mapDispatchToProps(dispatch) { | ||
33 | + | ||
34 | + const creators = Map() | ||
35 | + .merge(...actions) | ||
36 | + .filter(value => typeof value === 'function') | ||
37 | + .toObject(); | ||
38 | + | ||
39 | + return { | ||
40 | + actions: bindActionCreators(creators, dispatch), | ||
41 | + dispatch | ||
42 | + }; | ||
43 | +} | ||
44 | + | ||
45 | +class VIPLevelContainer extends Component { | ||
46 | + constructor(props) { | ||
47 | + super(props); | ||
48 | + } | ||
49 | + | ||
50 | + componentDidMount() { | ||
51 | + this.props.actions.fetchVIPInfo(); | ||
52 | + } | ||
53 | + | ||
54 | + render() { | ||
55 | + let {vipLevel} = this.props; | ||
56 | + let {nickname, isFetching, vipInfo, vipShowPageInfo} = vipLevel; | ||
57 | + return ( | ||
58 | + <View style={styles.container}> | ||
59 | + <VIPLevel | ||
60 | + nickname={nickname} | ||
61 | + isFetching={isFetching} | ||
62 | + vipInfo={vipInfo} | ||
63 | + vipShowPageInfo={vipShowPageInfo} | ||
64 | + /> | ||
65 | + </View> | ||
66 | + ); | ||
67 | + } | ||
68 | +} | ||
69 | + | ||
70 | +let styles = StyleSheet.create({ | ||
71 | + container: { | ||
72 | + flex: 1, | ||
73 | + }, | ||
74 | +}); | ||
75 | + | ||
76 | +export default connect(mapStateToProps, mapDispatchToProps)(VIPLevelContainer); |
js/personalInfo/image/mine_vip_1@2x.png
0 → 100755
3.37 KB
js/personalInfo/image/mine_vip_1@3x.png
0 → 100755
5.96 KB
js/personalInfo/image/mine_vip_2@2x.png
0 → 100755
3.77 KB
js/personalInfo/image/mine_vip_2@3x.png
0 → 100755
7.36 KB
js/personalInfo/image/mine_vip_3@2x.png
0 → 100755
3.85 KB
js/personalInfo/image/mine_vip_3@3x.png
0 → 100755
7.31 KB
1 | import {combineReducers} from 'redux'; | 1 | import {combineReducers} from 'redux'; |
2 | import app from './app/appReducer'; | 2 | import app from './app/appReducer'; |
3 | import personalInfo from './personalInfo/personalInfoReducer'; | 3 | import personalInfo from './personalInfo/personalInfoReducer'; |
4 | +import vipLevel from './vipLevel/vipLevelReducer'; | ||
4 | 5 | ||
5 | const rootReducer = combineReducers({ | 6 | const rootReducer = combineReducers({ |
6 | app, | 7 | app, |
7 | personalInfo, | 8 | personalInfo, |
9 | + vipLevel, | ||
8 | }); | 10 | }); |
9 | 11 | ||
10 | export default rootReducer; | 12 | export default rootReducer; |
1 | +'use strict'; | ||
2 | + | ||
3 | +import ReactNative from 'react-native'; | ||
4 | +import {Platform} from 'react-native'; | ||
5 | +import VIPLevelService from '../../services/VIPLevelService'; | ||
6 | +import {Record, List, Map} from 'immutable'; | ||
7 | + | ||
8 | +const { | ||
9 | + SET_NICKNAME, | ||
10 | + | ||
11 | + FETCH_VIP_INFO_REQUEST, | ||
12 | + FETCH_VIP_INFO_SUCCESS, | ||
13 | + FETCH_VIP_INFO_FAILURE, | ||
14 | + | ||
15 | +} = require('../../constants/actionTypes').default; | ||
16 | + | ||
17 | +export function fetchVIPInfoRequest() { | ||
18 | + return{ | ||
19 | + type: FETCH_VIP_INFO_REQUEST, | ||
20 | + } | ||
21 | +} | ||
22 | + | ||
23 | +export function fetchVIPInfoSuccess(object) { | ||
24 | + return{ | ||
25 | + type: FETCH_VIP_INFO_SUCCESS, | ||
26 | + payload: object, | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +export function fetchVIPInfoFailure(error) { | ||
31 | + return{ | ||
32 | + type: FETCH_VIP_INFO_FAILURE, | ||
33 | + payload: error, | ||
34 | + } | ||
35 | +} | ||
36 | + | ||
37 | +export function setNickname(nickname) { | ||
38 | + return{ | ||
39 | + type: SET_NICKNAME, | ||
40 | + payload: nickname, | ||
41 | + } | ||
42 | +} | ||
43 | + | ||
44 | +export function fetchVIPInfo() { | ||
45 | + return(dispatch, getState) => { | ||
46 | + let {app, vipLevel} = getState(); | ||
47 | + let fetchVIP = (uid) => { | ||
48 | + dispatch(fetchVIPInfoRequest()); | ||
49 | + return new VIPLevelService(app.host).getVIPInfo(uid) | ||
50 | + .then(json => { | ||
51 | + let vipShowPageInfo = processVIPInfo(json); | ||
52 | + dispatch(fetchVIPInfoSuccess({ | ||
53 | + vipInfo: json, | ||
54 | + upgradeNeedCost: vipShowPageInfo.upgradeNeedCost, | ||
55 | + vipNextLevelProgress: vipShowPageInfo.vipNextLevelProgress, | ||
56 | + })); | ||
57 | + }) | ||
58 | + .catch(error => { | ||
59 | + dispatch(fetchVIPInfoFailure(error)); | ||
60 | + }); | ||
61 | + } | ||
62 | + ReactNative.NativeModules.YH_CommonHelper.uid() | ||
63 | + .then(uid => { | ||
64 | + fetchVIP(uid); | ||
65 | + }) | ||
66 | + .catch(error => { | ||
67 | + fetchVIP(0); | ||
68 | + }); | ||
69 | + } | ||
70 | +} | ||
71 | + | ||
72 | +function processVIPInfo(json) { | ||
73 | + let upgradeNeedCost = 0.0; | ||
74 | + let nextNeedCost = 0.0; | ||
75 | + if (!json.upgrade_need_cost || json.upgrade_need_cost =='') { | ||
76 | + upgradeNeedCost = 0.0; | ||
77 | + } else { | ||
78 | + upgradeNeedCost = parseFloat(json.upgrade_need_cost); | ||
79 | + } | ||
80 | + if (!json.next_need_cost || json.next_need_cost =='') { | ||
81 | + nextNeedCost = 0.0; | ||
82 | + } else { | ||
83 | + nextNeedCost = parseFloat(json.next_need_cost); | ||
84 | + } | ||
85 | + let currentLevelCost = 0.0; | ||
86 | + if (nextNeedCost - upgradeNeedCost >= 0) { | ||
87 | + currentLevelCost = nextNeedCost - upgradeNeedCost; | ||
88 | + } | ||
89 | + let vipNextLevelProgress = 1.0; | ||
90 | + if (nextNeedCost == 0.0) { | ||
91 | + vipNextLevelProgress = 1.0; | ||
92 | + }else{ | ||
93 | + vipNextLevelProgress = currentLevelCost/nextNeedCost; | ||
94 | + } | ||
95 | + return({upgradeNeedCost,vipNextLevelProgress}) | ||
96 | +} |
1 | +'use strict'; | ||
2 | + | ||
3 | +import Immutable,{Record, List, Map} from 'immutable'; | ||
4 | + | ||
5 | +let InitialState = Record({ | ||
6 | + nickname: '', | ||
7 | + isFetching: false, | ||
8 | + vipInfo: Map(), | ||
9 | + vipShowPageInfo: new(Record({ | ||
10 | + upgradeNeedCost: 0.0, | ||
11 | + vipNextLevelProgress: 0.0, | ||
12 | + })) | ||
13 | +}); | ||
14 | + | ||
15 | +export default InitialState; |
1 | +'use strict'; | ||
2 | + | ||
3 | +import InitialState from './vipLevelInitialState'; | ||
4 | +import Immutable, {Map} from 'immutable'; | ||
5 | + | ||
6 | +const { | ||
7 | + SET_NICKNAME, | ||
8 | + | ||
9 | + FETCH_VIP_INFO_REQUEST, | ||
10 | + FETCH_VIP_INFO_SUCCESS, | ||
11 | + FETCH_VIP_INFO_FAILURE, | ||
12 | +} = require('../../constants/actionTypes').default; | ||
13 | + | ||
14 | +const initialState = new InitialState; | ||
15 | + | ||
16 | +export default function brandReducer(state=initialState, action) { | ||
17 | + switch(action.type) { | ||
18 | + case FETCH_VIP_INFO_REQUEST: | ||
19 | + return state.set('isFetching', true); | ||
20 | + case FETCH_VIP_INFO_FAILURE: | ||
21 | + return state.set('isFetching', false); | ||
22 | + case FETCH_VIP_INFO_SUCCESS: | ||
23 | + return state.set('isFetching', false) | ||
24 | + .set('vipInfo', Immutable.fromJS(action.payload.vipInfo)) | ||
25 | + .setIn(['vipShowPageInfo', 'upgradeNeedCost'], action.payload.upgradeNeedCost) | ||
26 | + .setIn(['vipShowPageInfo', 'vipNextLevelProgress'], action.payload.vipNextLevelProgress); | ||
27 | + case SET_NICKNAME: | ||
28 | + return state.set('nickname', action.payload); | ||
29 | + } | ||
30 | + return state; | ||
31 | +} |
js/personalInfo/services/VIPLevelService.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +import Request from '../../common/services/NativeRequest'; | ||
4 | + | ||
5 | +export default class MineGuangService { | ||
6 | + | ||
7 | + constructor (host) { | ||
8 | + let baseURL = 'http://api.yoho.cn'; | ||
9 | + if(host){ | ||
10 | + baseURL = host; | ||
11 | + } | ||
12 | + this.api = new Request(baseURL); | ||
13 | + } | ||
14 | + | ||
15 | + async getVIPInfo(uid) { | ||
16 | + return await this.api.get({ | ||
17 | + url: '', | ||
18 | + body: { | ||
19 | + method: 'app.passport.vip', | ||
20 | + uid, | ||
21 | + } | ||
22 | + }) | ||
23 | + .then((json) => { | ||
24 | + return json; | ||
25 | + }) | ||
26 | + .catch((error) => { | ||
27 | + throw(error); | ||
28 | + }); | ||
29 | + } | ||
30 | +} |
-
Please register or login to post a comment