Authored by 叶弯弯

库存统计接口调试。reviewed by yuliang。

@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 import React, {Component} from 'react'; 3 import React, {Component} from 'react';
4 import PlainTextSection from './PlainTextSection'; 4 import PlainTextSection from './PlainTextSection';
5 import Placeholder from './Placeholder'; 5 import Placeholder from './Placeholder';
  6 +import LoadMoreIndicator from './indicator/LoadMoreIndicator';
6 7
7 import { 8 import {
8 StyleSheet, 9 StyleSheet,
@@ -20,45 +21,82 @@ export default class StockStats extends Component { @@ -20,45 +21,82 @@ export default class StockStats extends Component {
20 super (props); 21 super (props);
21 22
22 this.ds = new ListView.DataSource({ 23 this.ds = new ListView.DataSource({
23 - rowHasChanged: (r1, r2) => r1 !== r2, 24 + rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
  25 + sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
24 }); 26 });
25 27
26 this._renderRow = this._renderRow.bind(this); 28 this._renderRow = this._renderRow.bind(this);
27 } 29 }
28 30
29 _renderRow(rowData, sectionID, rowID) { 31 _renderRow(rowData, sectionID, rowID) {
30 - return (  
31 - <TouchableHighlight underlayColor={'white'} onPress={() => {}}>  
32 - <View style={styles.row}>  
33 - <Image source={{uri: rowData.thumb}} style={styles.thumb}/>  
34 - <View style={styles.detail}>  
35 - <Text style={styles.brand}>{rowData.brand}</Text>  
36 - <Text style={styles.product}>{rowData.product}</Text>  
37 - <Text style={styles.brand}>{'厂家编号:' + rowData.vendor + ' sku:' + rowData.sku}</Text>  
38 - <Text style={styles.product}>{'进货价:' + rowData.importPrice + ' 库存:' + rowData.stockNum}</Text> 32 + switch (sectionID) {
  33 + case 'SECTION_HEADER':
  34 + return (
  35 + <View style={styles.container}>
  36 + <PlainTextSection content={rowData.section2} />
  37 + <Placeholder />
39 </View> 38 </View>
40 - </View>  
41 - </TouchableHighlight>  
42 - ); 39 + );
  40 +
  41 +
  42 + case 'SECTION_TIME':
  43 + return (
  44 + <View style={styles.container}>
  45 + <View style={styles.dateContainer}>
  46 + <Image source={require('../images/date.png')}/>
  47 + <Text style={styles.date}>{rowData.section1}</Text>
  48 + </View>
  49 + <Placeholder />
  50 + </View>
  51 + );
  52 +
  53 + case 'SECTION_CONTENT':
  54 + return (
  55 + <TouchableHighlight underlayColor={'white'} onPress={() => {}}>
  56 + <View style={styles.row}>
  57 + <Image source={{uri: rowData.thumb}} style={styles.thumb}/>
  58 + <View style={styles.detail}>
  59 + <Text style={styles.brand}>{rowData.brand}</Text>
  60 + <Text style={styles.product}>{rowData.product}</Text>
  61 + <Text style={styles.brand}>{'厂家编号:' + rowData.vendor + ' sku:' + rowData.sku}</Text>
  62 + <Text style={styles.product}>{'进货价:' + rowData.importPrice + ' 库存:' + rowData.stockNum}</Text>
  63 + </View>
  64 + </View>
  65 + </TouchableHighlight>
  66 + );
  67 + default:
  68 + return (
  69 + <Text>Error data source</Text>
  70 + );
  71 + }
43 } 72 }
44 73
45 render() { 74 render() {
  75 +
  76 + let isFetching = this.props.isFetching;
  77 +
  78 + let loadText = '暂无更多数据';
  79 + if (!this.props.reachEnd) {
  80 + loadText = isFetching ? '正在加载...' : '上拉加载更多';
  81 + }
  82 +
46 return ( 83 return (
47 <View style={styles.container}> 84 <View style={styles.container}>
48 - <View style={styles.dateContainer}>  
49 - <Image source={require('../images/date.png')}/>  
50 - <Text style={styles.date}>{this.props.section1}</Text>  
51 - </View>  
52 - <Placeholder />  
53 - <PlainTextSection content={this.props.section2} />  
54 - <Placeholder />  
55 <ListView 85 <ListView
56 - dataSource={this.ds.cloneWithRows(this.props.section3)} 86 + dataSource={this.ds.cloneWithRowsAndSections(this.props.section.toJS())}
57 renderRow={this._renderRow} 87 renderRow={this._renderRow}
58 renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator}/>} 88 renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator}/>}
59 - onEndReachedThreshold={-10} 89 + onEndReachedThreshold={-50}
60 onEndReached={this.props.requestData} 90 onEndReached={this.props.requestData}
61 - enableEmptySections={true} /> 91 + enableEmptySections={true}
  92 + renderFooter={()=>{
  93 + return <LoadMoreIndicator
  94 + hidden={this.props.hideLoadingFooter}
  95 + loadingText={loadText}
  96 + animating={isFetching}
  97 + />
  98 + }}
  99 + />
62 </View> 100 </View>
63 ); 101 );
64 } 102 }
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 'use strict'; 2 'use strict';
3 3
4 import React, { Component } from 'react'; 4 import React, { Component } from 'react';
  5 +import Immutable, {List, Record} from 'immutable';
5 6
6 import StockStats from '../components/StockStats' 7 import StockStats from '../components/StockStats'
7 8
@@ -53,11 +54,16 @@ export default class StockStatsContainer extends Component { @@ -53,11 +54,16 @@ export default class StockStatsContainer extends Component {
53 } 54 }
54 55
55 componentDidMount() { 56 componentDidMount() {
56 - this.props.actions.requestData(); 57 + this._requestData();
57 } 58 }
58 59
59 _requestData() { 60 _requestData() {
60 - this.props.actions.requestData(); 61 + let params = {
  62 + page: this.props.stockStats.currentPage + 1,
  63 + size: 12,
  64 + brandId: this.props.home.get('brandId'),
  65 + };
  66 + this.props.actions.requestData(params);
61 } 67 }
62 68
63 render() { 69 render() {
@@ -74,14 +80,22 @@ export default class StockStatsContainer extends Component { @@ -74,14 +80,22 @@ export default class StockStatsContainer extends Component {
74 bottom: `${this.props.stockStats.totalAmount}`, 80 bottom: `${this.props.stockStats.totalAmount}`,
75 } 81 }
76 ]; 82 ];
  83 + let dataBlob = {
  84 + 'SECTION_TIME': [{section1}],
  85 + 'SECTION_HEADER': [{section2}],
  86 + 'SECTION_CONTENT': this.props.stockStats.jsonData,
  87 + }
  88 + let mapBlob = Immutable.fromJS(dataBlob);
  89 + let end = this.props.stockStats.currentPage >= this.props.stockStats.pageCount;
77 90
78 return ( 91 return (
79 <View style={styles.container}> 92 <View style={styles.container}>
80 <StockStats 93 <StockStats
81 - section1={section1}  
82 - section2={section2}  
83 - section3={this.props.stockStats.jsonData.toJS()} 94 + section={mapBlob}
84 requestData={this._requestData} 95 requestData={this._requestData}
  96 + isFetching={this.props.stockStats.isFetching}
  97 + hideLoadingFooter={this.props.stockStats.currentPage<1}
  98 + reachEnd={end}
85 /> 99 />
86 </View> 100 </View>
87 ); 101 );
@@ -29,19 +29,24 @@ export function failure(error) { @@ -29,19 +29,24 @@ export function failure(error) {
29 } 29 }
30 } 30 }
31 31
32 -export function requestData() {  
33 - // return dispatch => {  
34 - // dispatch(request());  
35 - // return new StockStatsService()  
36 - // .stockStatsData()  
37 - // .then(json => {  
38 - // dispatch(success(json));  
39 - // })  
40 - // .catch(error => {  
41 - // dispatch(failure(error));  
42 - // })  
43 - // };  
44 - return success(testStockStatsData); 32 +export function requestData(params) {
  33 + return (dispatch, getState) => {
  34 + const {stockStats} = getState();
  35 +
  36 + if (stockStats.currentPage >= stockStats.pageCount || stockStats.isFetching) {//Last page reached....
  37 + return;
  38 + }
  39 +
  40 + dispatch(request());
  41 + return new StockStatsService()
  42 + .stockStatsData(params)
  43 + .then(json => {
  44 + dispatch(success(json));
  45 + })
  46 + .catch(error => {
  47 + dispatch(failure(error));
  48 + })
  49 + };
45 } 50 }
46 51
47 let testStockStatsData = { 52 let testStockStatsData = {
@@ -5,10 +5,11 @@ import {List, Record} from 'immutable'; @@ -5,10 +5,11 @@ import {List, Record} from 'immutable';
5 let InitialState = Record({ 5 let InitialState = Record({
6 error: null, 6 error: null,
7 isFetching: false, 7 isFetching: false,
8 - pageCount: 0, 8 + pageCount: 1,
  9 + currentPage: 0,
9 sum: '0', 10 sum: '0',
10 - totalAmount: '0',  
11 - jsonData: List([]), 11 + totalAmount: '0.00',
  12 + jsonData: List(),
12 }); 13 });
13 14
14 export default InitialState; 15 export default InitialState;
@@ -25,13 +25,14 @@ export default function stockStatsReducer(state = initialState, action) { @@ -25,13 +25,14 @@ export default function stockStatsReducer(state = initialState, action) {
25 case STOCK_STATS_SUCCESS: { 25 case STOCK_STATS_SUCCESS: {
26 const {jsonData} = state; 26 const {jsonData} = state;
27 let origin = jsonData.toJS(); 27 let origin = jsonData.toJS();
28 - let data = [...origin, ...action.payload.list];  
29 - let newPageCount = action.payload.list ? state.pageCount + 1 : state.pageCount; 28 + let {additionInfo, list} = action.payload;
  29 + let data = [...origin, ...(list || [])];
30 let nextState = state.set('isFetching',false) 30 let nextState = state.set('isFetching',false)
31 - .set('sum', action.payload.sum)  
32 - .set('totalAmount', action.payload.totalAmount)  
33 - .set('pageCount', newPageCount)  
34 - .set('jsonData', List(data)); 31 + .set('sum', additionInfo.storageTotalNum)
  32 + .set('totalAmount', additionInfo.storageTotalMoney)
  33 + .set('currentPage', action.payload.page)
  34 + .set('pageCount', action.payload.totalPage)
  35 + .set('jsonData', Immutable.fromJS(data));
35 return nextState; 36 return nextState;
36 } 37 }
37 case STOCK_STATS_FAILURE: { 38 case STOCK_STATS_FAILURE: {
@@ -94,9 +94,13 @@ export default class UserService { @@ -94,9 +94,13 @@ export default class UserService {
94 }) 94 })
95 } 95 }
96 96
97 - async stockStatsData() { 97 + async stockStatsData(params) {
98 return await this.api.get({ 98 return await this.api.get({
99 - url: '/' 99 + url: '',
  100 + body: {
  101 + method: 'app.shops.storagestatistics',
  102 + ...params,
  103 + }
100 }) 104 })
101 .then((json) => { 105 .then((json) => {
102 return json; 106 return json;