Authored by 叶弯弯

完成库存统计模块。reviewed by shixiang。

... ... @@ -53,6 +53,7 @@ import LogoutContainer from './containers/LogoutContainer'
import ModifyPasswordContainer from './containers/ModifyPasswordContainer'
import AccountSettlementContainer from './containers/AccountSettlementContainer'
import AboutUsContainer from './containers/AboutUsContainer'
import StockStatsContainer from './containers/StockStatsContainer'
import NavBar from './components/NavBar';
import TabIcon from './containers/TabIcon';
... ... @@ -153,7 +154,7 @@ export default function native(platform) {
type='push'
/>
<Scene
<Scene
key='AccountSettlement'
component={AccountSettlementContainer}
title='对账结算'
... ... @@ -165,6 +166,17 @@ export default function native(platform) {
/>
<Scene
key='StockStats'
component={StockStatsContainer}
title='库存统计'
hideNavBar={false}
initial={false}
navBar={NavBar}
titleStyle={styles.navTitle}
type='push'
/>
<Scene
key='AboutUs'
component={AboutUsContainer}
title='关于我们'
... ...
'use strict';
import React, {Component} from 'react';
import PlainTextSection from './PlainTextSection';
import Placeholder from './Placeholder';
import {
StyleSheet,
View,
Text,
ListView,
Image,
Dimensions,
TouchableHighlight,
} from 'react-native';
export default class StockStats extends Component {
constructor(props) {
super (props);
this.ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this._renderRow = this._renderRow.bind(this);
}
_renderRow(rowData, sectionID, rowID) {
return (
<TouchableHighlight underlayColor={'white'} onPress={() => {}}>
<View style={styles.row}>
<Image source={{uri: rowData.thumb}} style={styles.thumb}/>
<View style={styles.detail}>
<Text style={styles.brand}>{rowData.brand}</Text>
<Text style={styles.product}>{rowData.product}</Text>
<Text style={styles.brand}>{'厂家编号:' + rowData.vendor + ' sku:' + rowData.sku}</Text>
<Text style={styles.product}>{'进货价:' + rowData.importPrice + ' 库存:' + rowData.stockNum}</Text>
</View>
</View>
</TouchableHighlight>
);
}
render() {
return (
<View style={styles.container}>
<View style={styles.dateContainer}>
<Image source={require('../images/date.png')}/>
<Text style={styles.date}>{this.props.section1}</Text>
</View>
<Placeholder />
<PlainTextSection content={this.props.section2} />
<Placeholder />
<ListView
dataSource={this.ds.cloneWithRows(this.props.section3)}
renderRow={this._renderRow}
renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator}/>}
onEndReachedThreshold={-50}
onEndReached={this.props.requestData}
enableEmptySections={true} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
dateContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 50,
backgroundColor: 'white',
},
date: {
fontSize: 14,
color: '#444444',
textAlign: 'center',
marginLeft: 10,
},
separator: {
height: 1,
},
row: {
flexDirection: 'row',
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
backgroundColor: 'white',
alignItems: 'center',
},
detail: {
flexDirection: 'column',
justifyContent: 'center',
flex: 1,
paddingLeft: 10,
},
thumb: {
width: 60,
height: 80,
},
brand: {
color: '#B0B0B0',
fontSize: 12,
},
product: {
color: '#444444',
fontSize: 12,
},
});
... ...
... ... @@ -12,12 +12,11 @@ let {
TouchableOpacity
} = React;
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
export default class User extends Component {
constructor(props) {
super(props);
this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
}
componentWillMount() {
... ... @@ -29,7 +28,7 @@ export default class User extends Component {
return (
<ListView
dataSource={ds.cloneWithRows(this.props.items)}
dataSource={this.ds.cloneWithRows(this.props.items)}
renderRow={this._renderItem}
renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator}/>}
style={styles.listView}/>
... ... @@ -82,5 +81,5 @@ const styles = StyleSheet.create({
separator: {
height: 1,
},
},
});
... ...
... ... @@ -58,6 +58,10 @@ export default keyMirror({
SWITCH_SHOP: null,
STOCK_STATS_REQUEST: null,
STOCK_STATS_SUCCESS: null,
STOCK_STATS_FAILURE: null,
/*
GET_PROFILE_REQUEST: null,
GET_PROFILE_SUCCESS: null,
... ...
'use strict';
import React, { Component } from 'react';
import StockStats from '../components/StockStats'
import {
StyleSheet,
View,
Text,
ListView,
Dimensions,
Platform,
} from 'react-native';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {Map} from 'immutable';
import * as stockStatsActions from '../reducers/stockStats/stockStatsActions';
const actions = [
stockStatsActions,
];
function mapStateToProps(state) {
return {
...state
}
};
function mapDispatchToProps(dispatch) {
const creators = Map()
.merge(...actions)
.filter(value => typeof value === 'function')
.toObject();
return {
actions: bindActionCreators(creators, dispatch),
dispatch
};
}
export default class StockStatsContainer extends Component {
constructor(props) {
super(props);
this._requestData = this._requestData.bind(this);
}
componentDidMount() {
this.props.actions.requestData();
}
_requestData() {
this.props.actions.requestData();
}
render() {
let date = new Date();
let section1 = date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日';
let section2 = [
{
top: '库存总数',
bottom: `${this.props.stockStats.sum}`,
},
{
top: '库存总金额(元)',
bottom: `${this.props.stockStats.totalAmount}`,
}
];
return (
<View style={styles.container}>
<StockStats
section1={section1}
section2={section2}
section3={this.props.stockStats.jsonData.toJS()}
requestData={this._requestData}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
let navbarHeight = (Platform.OS === 'android') ? 50 : 64;
let styles = StyleSheet.create({
container: {
top: navbarHeight,
height: height - navbarHeight,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(StockStatsContainer);
... ...
... ... @@ -16,6 +16,7 @@ import home from './home/homeReducer';
import message from './message/messageReducer';
import user from './user/userReducer';
import actStmt from './accountSettlement/accountSettlementReducer'
import stockStats from './stockStats/stockStatsReducer'
import { combineReducers } from 'redux';
... ... @@ -32,6 +33,7 @@ const rootReducer = combineReducers({
message,
user,
actStmt,
stockStats,
});
export default rootReducer;
... ...
'use strict';
import Request from '../../services/Request';
import StockStatsService from '../../services/HomeService';
const {
STOCK_STATS_REQUEST,
STOCK_STATS_SUCCESS,
STOCK_STATS_FAILURE,
} = require('../../constants/actionTypes').default;
export function request() {
return {
type: STOCK_STATS_REQUEST,
}
}
export function success(json) {
return {
type: STOCK_STATS_SUCCESS,
payload: json,
}
}
export function failure(error) {
return {
type: STOCK_STATS_FAILURE,
payload: error,
}
}
export function requestData() {
// return dispatch => {
// dispatch(request());
// return new StockStatsService()
// .stockStatsData()
// .then(json => {
// dispatch(success(json));
// })
// .catch(error => {
// dispatch(failure(error));
// })
// };
return success(testStockStatsData);
}
let testStockStatsData = {
sum: 100,
totalAmount: 100000.00,
list: [
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddddddddddddddddddddddddddd 超清来袭ddddddddddddddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '70',
thumb: 'http://www.ruanyifeng.com/blogimg/asset/2015/bg2015071002.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '71',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '72',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '73',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '74',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '75',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '76',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '77',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '78',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '79',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '80',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '81',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '82',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '83',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '84',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '85',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '86',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '87',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '88',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '89',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '90',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '91',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
{
brand: 'vans',
product: 'dddddddddddddddddddddddd 超清来袭ddddddddddd',
vendor: '222222',
sku: '111111111',
importPrice: '222',
stockNum: '92',
thumb: 'https://facebook.github.io/react/img/logo_og.png',
},
]
}
... ...
'use strict';
import {List, Record} from 'immutable';
let InitialState = Record({
error: null,
isFetching: false,
pageCount: 0,
sum: '0',
totalAmount: '0',
jsonData: List([]),
});
export default InitialState;
... ...
'use strict';
import StockStatsInitialState from './stockStatsInitialState'
import Immutable, {List, Record} from 'immutable';
const {
STOCK_STATS_REQUEST,
STOCK_STATS_SUCCESS,
STOCK_STATS_FAILURE,
} = require('../../constants/actionTypes').default;
const initialState = new StockStatsInitialState;
export default function stockStatsReducer(state = initialState, action) {
if (!(state instanceof StockStatsInitialState)) return initialState.merge(state);
switch (action.type) {
case STOCK_STATS_REQUEST: {
let nextState = state.set('isFetching', true).set('error', null);
return nextState;
}
case STOCK_STATS_SUCCESS: {
const {jsonData} = state;
let origin = jsonData.toJS();
let data = [...origin, ...action.payload.list];
let newPageCount = action.payload.list ? state.pageCount + 1 : state.pageCount;
let nextState = state.set('isFetching',false)
.set('sum', action.payload.sum)
.set('totalAmount', action.payload.totalAmount)
.set('pageCount', newPageCount)
.set('jsonData', List(data));
return nextState;
}
case STOCK_STATS_FAILURE: {
let nextState = state.set('isFetching',false)
.set('error', action.playload);
return nextState;
}
}
return state;
}
... ...
... ... @@ -36,8 +36,19 @@ export default class UserService {
throw(error);
})
}
}
async stockStatsData() {
return await this.api.get({
url: '/'
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
})
}
}
let testData = [
... ...