Authored by 叶弯弯

Merge branch 'develop' of http://git.dev.yoho.cn/mobile/yh_vendor into develop

# Conflicts:
#	js/Vendor.js
#	js/constants/actionTypes.js
#	js/reducers/index.js
#	js/services/HomeService.js
... ... @@ -40,6 +40,7 @@ import homeInitialState from './reducers/home/homeInitialState';
import messageInitialState from './reducers/message/messageInitialState';
import userInitialState from './reducers/user/userInitialState';
import accountSettlementInitialState from './reducers/accountSettlement/accountSettlementInitialState';
import saleStatisticsInitialState from './reducers/saleStatistics/saleStatisticsInitialState';
import App from './containers/App';
... ... @@ -54,6 +55,7 @@ import ModifyPasswordContainer from './containers/ModifyPasswordContainer'
import AccountSettlementContainer from './containers/AccountSettlementContainer'
import AboutUsContainer from './containers/AboutUsContainer'
import StockStatsContainer from './containers/StockStatsContainer'
import SaleStatisticsContainer from './containers/SaleStatisticsContainer'
import NavBar from './components/NavBar';
import TabIcon from './containers/TabIcon';
... ... @@ -75,6 +77,8 @@ function getInitialState() {
message: (new messageInitialState),
user: (new userInitialState),
actStmt: (new accountSettlementInitialState),
saleStats: (new saleStatisticsInitialState()),
stockStats: (new stockStatsInitialState()),
};
return _initState;
}
... ... @@ -100,7 +104,7 @@ export default function native(platform) {
// setup the router table with App selected as the initial component
return (
<Provider store={store}>
<NewRouter hideNavBar={false}>
<NewRouter hideNavBar={false} sceneStyle={styles.scene}>
<Scene key="root" >
<Scene
key="App"
... ... @@ -145,12 +149,13 @@ export default function native(platform) {
type="push"
/>
<Scene
key="Test"
component={GuideContainer}
title='Test'
key="SaleStats"
component={SaleStatisticsContainer}
title='销售统计'
hideNavBar={false}
initial={false}
navBar={NavBar}
titleStyle={styles.navTitle}
type='push'
/>
... ... @@ -188,7 +193,7 @@ export default function native(platform) {
/>
<Scene key="Drawer" component={DrawerContainer} type="replace" hideNavBar={true} >
<Scene key="Tabbar" tabs={true} initial={false} type="replace" component={TabBar} >
<Scene key="Tabbar" tabs={true} initial={false} type="replace" component={TabBar}>
<Scene
key="Home"
title="首页"
... ... @@ -239,6 +244,9 @@ export default function native(platform) {
}
let styles = StyleSheet.create({
scene: {
backgroundColor:'#F0F0F0',
},
navTitle: {
color: 'white',
},
... ...
... ... @@ -19,7 +19,7 @@ export default class Placeholder extends Component {
};
render() {
return (
<View style={[styles.container, this.props.containerStyle]} />
);
... ... @@ -32,7 +32,8 @@ let styles = StyleSheet.create({
container: {
width,
height: 15,
backgroundColor: '#F0F0F0',
backgroundColor: 'transparent',
// backgroundColor: '#F0F0F0',
},
});
\ No newline at end of file
});
... ...
'use strict';
import React from 'react-native';
import TrendTextSection from './TrendTextSection';
import Placeholder from './Placeholder';
let {
Component,
View,
Text,
ScrollView,
Platform
} = React;
export default class SaleStatistics extends Component {
static propTypes = {
section1: React.PropTypes.arrayOf(
React.PropTypes.shape({
top: React.PropTypes.string,
bottom: React.PropTypes.string,
style: View.propTypes.style,
arrowUp: React.PropTypes.bool,
})
),
section2: React.PropTypes.arrayOf(
React.PropTypes.shape({
top: React.PropTypes.string,
bottom: React.PropTypes.string,
style: View.propTypes.style,
arrowUp: React.PropTypes.bool,
})
),
};
render() {
return (
<ScrollView>
<TrendTextSection content={this.props.section1} />
<Placeholder />
<TrendTextSection content={this.props.section2} />
<Placeholder />
</ScrollView>
);
}
}
... ...
... ... @@ -28,18 +28,19 @@ export default class TrendText extends Component {
};
render() {
let arrow = this.props.arrowUp ? require('../images/arrow_up.png') : require('../images/arrow_down.png');
let bottomTextColor = this.props.arrowUp ? styles.bottomTextUp : styles.bottomTextDown;
return (
<View style={[styles.container, this.props.containerStyle]}>
<Text style={[styles.topText, this.props.topTextStyle]}>{this.props.topText}</Text>
<View style={styles.richContainer}>
<Image source={arrow} style={[styles.image, this.props.imageStyle]} />
<Text style={[styles.bottomText, this.props.bottomTextStyle]}>{this.props.bottomText}</Text>
<Text style={[styles.bottomText, bottomTextColor, this.props.bottomTextStyle]}>{this.props.bottomText}</Text>
<Text style={[styles.smallText, this.props.smallTextStyle]}>{this.props.smallText}</Text>
</View>
</View>
);
}
... ... @@ -72,14 +73,19 @@ let styles = StyleSheet.create({
},
bottomText: {
fontSize: 17,
color: '#D0021B',
fontWeight: 'bold',
textAlign: 'center',
},
bottomTextUp: {
color: '#D0021B',
},
bottomTextDown: {
color: '#86BF4A',
},
smallText: {
fontSize: 12,
textAlign: 'center',
color: '#444444',
},
});
\ No newline at end of file
});
... ...
... ... @@ -24,7 +24,7 @@ export default class User extends Component {
}
render() {
var items = this.props.items;
let items = this.props.items;
return (
<ListView
... ... @@ -36,7 +36,7 @@ export default class User extends Component {
}
_renderItem(item) {
var icon = item.icon;
let icon = item.icon;
return (
<TouchableOpacity activeOpacity={0.5} onPress={() => this.props.onItemPressed(item)}>
<View style={styles.row}>
... ... @@ -75,7 +75,7 @@ const styles = StyleSheet.create({
padding: 10,
},
listView: {
marginTop: 120,
marginTop: 56,
},
separator: {
... ...
... ... @@ -61,6 +61,9 @@ export default keyMirror({
STOCK_STATS_REQUEST: null,
STOCK_STATS_SUCCESS: null,
STOCK_STATS_FAILURE: null,
SALE_STATS_REQUEST: null,
SALE_STATS_SUCCESS: null,
SALE_STATS_FAILURE: null,
/*
GET_PROFILE_REQUEST: null,
... ...
'use strict';
/*
* ## Imports
*
*
* Imports from redux
*/
import { bindActionCreators } from 'redux';
... ... @@ -22,7 +22,7 @@ import * as userActions from '../reducers/user/userActions';
* The components we need from ReactNative
*/
import React,
{
{
StatusBar,
StyleSheet,
View,
... ... @@ -65,27 +65,11 @@ function mapDispatchToProps(dispatch) {
dispatch
};
}
let styles = StyleSheet.create({
container: {
borderTopWidth: 2,
borderBottomWidth:2,
marginTop: 80,
padding: 10
},
summary: {
fontFamily: 'BodoniSvtyTwoITCTT-Book',
fontSize: 18,
fontWeight: 'bold'
}
});
/**
* ## App class
*/
class App extends Component {
componentDidMount() {
this.props.actions.getDisplayState();
... ... @@ -94,7 +78,7 @@ class App extends Component {
render() {
return (
<StatusBar
hidden={false}
hidden={false}
barStyle={'light-content'}
/>
);
... ... @@ -104,4 +88,4 @@ class App extends Component {
/**
* Connect the properties
*/
export default connect(mapStateToProps, mapDispatchToProps)(App);
\ No newline at end of file
export default connect(mapStateToProps, mapDispatchToProps)(App);
... ...
... ... @@ -14,6 +14,7 @@ import CONFIG from '../constants/config';
let {
Component,
StatusBar,
ScrollView,
View,
StyleSheet,
... ... @@ -58,7 +59,7 @@ class HomeContainer extends Component {
constructor(props) {
super(props);
this._onPressCategory = this._onPressCategory.bind(this);
this.category = [
... ... @@ -133,7 +134,11 @@ class HomeContainer extends Component {
return (
<View style={styles.container}>
<Home
<StatusBar
hidden={false}
barStyle={'light-content'}
/>
<Home
section1={section1}
section2={section2}
section3={this.category}
... ... @@ -151,7 +156,7 @@ let styles = StyleSheet.create({
top: 64,
height: height - 64 - 49,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(HomeContainer);
... ...
... ... @@ -13,8 +13,11 @@ import * as messageActions from '../reducers/message/messageActions';
let {
Component,
StatusBar,
View,
Text
Text,
StyleSheet,
Dimensions
} = React;
const actions = [
... ... @@ -42,11 +45,27 @@ function mapDispatchToProps(dispatch) {
class MessageContainer extends Component {
render() {
return (
<Message/>
<View style={styles.container}>
<StatusBar
hidden={false}
barStyle={'light-content'}
/>
<Message/>
</View>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MessageContainer);
\ No newline at end of file
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
container: {
top: 64,
height: height - 64 - 49,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(MessageContainer);
... ...
'use strict';
/**
* 销售统计
*/
import React from 'react-native';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {Map} from 'immutable';
import SaleStatistics from '../components/SaleStatistics';
import * as saleStatisticsActions from '../reducers/saleStatistics/saleStatisticsActions';
let {
Component,
ScrollView,
View,
StyleSheet,
Dimensions
} = React;
const actions = [
saleStatisticsActions
];
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
};
}
class SalestisticsContainer extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
}
render() {
let section1 = [
{
top: '有效订单的商品金额(元)',
bottom: `${this.props.saleStats.goodsAmount}`,
},
{
top: '环比',
arrowUp: this.props.saleStats.amountRise,
bottom: `${this.props.saleStats.amountRisePercent}`,
bottom: '1.8%',
}
];
let section2 = [
{
top: '有效订单的商品件数',
bottom: `${this.props.saleStats.goodsCount}`,
},
{
top: '环比',
arrowUp: this.props.saleStats.countRise,
arrowUp: false,
bottom: `${this.props.saleStats.countRisePercent}`,
bottom: '10.8%',
}
];
return (
<View style={styles.container}>
<SaleStatistics
section1={section1}
section2={section2}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
container: {
top: 64,
height: height - 64 - 49,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(SalestisticsContainer);
... ...
... ... @@ -13,8 +13,11 @@ import * as userActions from '../reducers/user/userActions';
let {
Component,
StatusBar,
View,
Text
Text,
StyleSheet,
Dimensions
} = React;
const actions = [
... ... @@ -44,9 +47,28 @@ class UserContainer extends Component {
render() {
return (
<User items={this.props.user.listItems.toArray()} onItemPressed={(item) => this.props.actions.userItemsPressed(item)}/>
<View style={styles.container}>
<StatusBar
hidden={false}
barStyle={'light-content'}
/>
<User
items={this.props.user.listItems.toArray()}
onItemPressed={(item) => this.props.actions.userItemsPressed(item)}
/>
</View>
);
}
}
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
container: {
top: 64,
height: height - 64 - 49,
},
});
export default connect(mapStateToProps, mapDispatchToProps)(UserContainer);
... ...
... ... @@ -43,7 +43,7 @@ export default function userReducer(state = initialState, action) {
case HOME_OVERVIEW_REQUEST: {
let nextState = state.set('isFetching', true)
.set('error', null)
.set('shopId', action.payload.shopId);
.set('shopId', action.payload);
return nextState;
}
... ...
... ... @@ -15,8 +15,9 @@ import guide from './guide/guideReducer';
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 stockStats from './stockStats/stockStatsReducer';
import actStmt from './accountSettlement/accountSettlementReducer';
import saleStats from './saleStatistics/saleStatisticsReducer';
import { combineReducers } from 'redux';
... ... @@ -34,6 +35,7 @@ const rootReducer = combineReducers({
user,
actStmt,
stockStats,
saleStats
});
export default rootReducer;
... ...
/**
* # guideActions.js
*
* App user guide
*
*/
'use strict';
import {Actions} from 'react-native-router-flux';
import CONFIG from '../../constants/config';
import HomeService from '../../services/HomeService';
const {
SALE_STATS_REQUEST,
SALE_STATS_SUCCESS,
SALE_STATS_FAILURE,
} = require('../../constants/actionTypes').default;
export function saleStatsRequest(shopId) {
return {
type: SALE_STATS_REQUEST,
payload: shopId
};
}
export function saleStatsSuccess(json) {
return {
type: SALE_STATS_SUCCESS,
payload: json
};
}
export function saleStatsFailure(error) {
return {
type: SALE_STATS_FAILURE,
payload: error
};
}
export function saleStats(shopId) {
return dispatch => {
dispatch(saleStatsRequest(shopId));
return new HomeService().saleStats(shopId)
.then(json => {
dispatch(saleStatsSuccess({
rank: 76,
rise: true,
riseCount: 28,
goodsCount: 7600,
goodsAmount: 19800.00,
}));
})
.catch(error => {
dispatch(saleStatsFailure(error));
});
};
}
... ...
/**
* # guideInitialState.js
*
*
*/
'use strict';
/**
* ## Import immutable record
*/
import {List, Record} from 'immutable';
/**
* ## InitialState
*
* The fields we're concerned with
*/
let InitialState = Record({
isFetching: false,
error: null,
type: 0,
day: '',
startDay: '',
endDay: '',
month: '',
goodsAmount: 0,
amountRise: true,
amountRisePercent: '',
goodsCount: 0,
countRise: true,
countRisePercent: '',
trendInSevenDays: List(),
});
export default InitialState;
... ...
/**
* # guideReducer.js
*
* The reducer for all the actions from the various log states
*/
'use strict';
/**
* ## Imports
*
* InitialState
*/
import InitialState from './saleStatisticsInitialState';
import Immutable, {List, Record} from 'immutable';
const {
SALE_STATS_REQUEST,
SALE_STATS_SUCCESS,
SALE_STATS_FAILURE,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
/**
* ## guideReducer function
* @param {Object} state - initialState
* @param {Object} action - type and payload
*/
export default function saleStatisticsReducer(state = initialState, action) {
if (!(state instanceof InitialState)) return initialState.merge(state);
switch (action.type) {
case SALE_STATS_REQUEST: {
let nextState = state.set('isFetching', true)
.set('error', null)
return nextState;
}
case SALE_STATS_SUCCESS: {
let nextState = state.set('isFetching', false)
.set('error', null)
.set('goodsAmount', action.payload.goodsAmount)
.set('amountRise', action.payload.amountRise)
.set('goodsCount', action.payload.goodsCount)
.set('countRise', action.payload.countRise)
.setIn('trendInSevenDays', Immutable.fromJS(action.payload.trendInSevenDays));
return nextState;
}
case SALE_STATS_FAILURE:
return state.set('isFetching', false)
.set('error', action.payload);
}
return state;
}
... ...
... ... @@ -37,6 +37,19 @@ export default class UserService {
})
}
async saleStats() {
return await this.api.get({
url:'/operations/api/v6/category/getCategory'
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
})
}
}
async stockStatsData() {
return await this.api.get({
url: '/'
... ...