总体结构
server 文件夹名称
ACTION.js 常量定义
action.js 触发器
api.js url定义
httpServer.js 请求网络
reducer.js 构建数据
常量定义
ACTION.js 代码
export const GET_DEFALULT_RECOMEND = 'GET_DEFALULT_RECOMEND';
export const CHECK_PRICE_PACKAGE = 'CHECK_PRICE_PACKAGE';
export const GET_CHANGE_RESOURCE = 'GET_CHANGE_RESOURCE';
export const CHANGE_RESOURCE_NUM = 'CHANGE_RESOURCE_NUM';
export const DELETE_RESOURCE = 'DELETE_RESOURCE';
export const FLUSH_FLIGHT_DETAIL = 'FLUSH_FLIGHT_DETAIL';
export const RESET_FLIGHT_RESULT = 'RESET_FLIGHT_RESULT';
export const SAVE_JOURNEY = 'SAVE_JOURNEY';
export const GET_DEFAULT_RECOMMEND_WHEN_PEOPLE_UPDATE = 'GET_DEFAULT_RECOMMEND_WHEN_PEOPLE_UPDATE'
触发器
import * as ACTION from './ACTION';
import * as server from './httpServer';
let getDefaultRecommend = (params, callback, error) => {
return dispatch => {
server.getDefaultRecommend(params, (d) => {
dispatch({
type: ACTION.GET_DEFALULT_RECOMEND,
error: false,
data: d.data
});
callback && typeof callback == 'function' && callback(d.data);
}, (d) => {
error && typeof error == 'function' && error(d);
dispatch({
type: ACTION.GET_DEFALULT_RECOMEND,
error: true
});
})
}
};
let getDefaultRecommendWhenPeopleUpdate = (params, callback, error) => {
return dispatch => {
server.getDefaultRecommendWhenPeopleUpdate(params, (d) => {
dispatch({
type: ACTION.GET_DEFAULT_RECOMMEND_WHEN_PEOPLE_UPDATE,
error: false,
data: d.data
});
callback && typeof callback == 'function' && callback(d.data);
}, (d) => {
error && typeof error == 'function' && error(d);
dispatch({
type: ACTION.GET_DEFAULT_RECOMMEND_WHEN_PEOPLE_UPDATE,
error: true
});
})
}
};
/**
* 更改资源,如果更换机票,更换酒店请求接口
* @param params
* @param callback
* @param error
* @returns {function()}
*/
let getChangedResouces = (params, callback, error) => {
return dispatch => {
server.getChangedResouces(params, (d) => {
callback && typeof callback == 'function' && callback(d.data);
return dispatch({
type: ACTION.GET_CHANGE_RESOURCE,
error: false,
data: d.data
});
}, (d) => {
error && typeof error == 'function' && error(d);
return dispatch({
type: ACTION.GET_CHANGE_RESOURCE,
error: true
});
})
}
};
/**
* 保存购物车
* @param params
* @param callback
* @param error
* @returns {function()}
*/
let saveJourney = (params, callback, error) => {
return dispatch => {
server.saveJourney(params, (d) => {
callback && typeof callback == 'function' && callback(d.data);
return dispatch({
type: ACTION.SAVE_JOURNEY,
error: false,
data: d.data
});
}, (d) => {
error && typeof error == 'function' && error(d);
return dispatch({
type: ACTION.SAVE_JOURNEY,
error: true
});
})
}
};
/**
* 验价接口
* @param params 验价传入服务端参数
* @param source 验价接口原始数据
* @param dData 默认推荐数据
* @param callback
* @param error
* @returns {function()}
*/
let checkPricePackage = (params, source,dData, callback, error) => {
return dispatch => {
server.checkPricePackage(params, (d) => {
if(!!d && !!d.data && d.data.handleType == 1 && !!source){
let temp = Object.assign(source, {});
temp.failedDesc = d.data.failedDesc;
temp.allSuccess = d.data.allSuccess;
d.data = temp;
}
//handleType 为2时,验价才会有优惠信息
if (!!d && !!d.data && !!dData && d.data.handleType == 2) {
let result = d.data;
if (!!result.promotions) {
//优惠提示更改
dData.promotions = result.promotions;
}else{
dData.promotions = [];
}
if (!!dData.journeyInfo) {
let temp = Object.assign(dData.journeyInfo, {});//生成新的对象地址,刷新数据
//机票十分钟刷新,提示更改
if(!!result.journeyNotice){
temp.journeyNotice = result.journeyNotice;
}
//机票十分钟刷新,优惠信息更改
if (!!result.promotionTips && result.promotionTips.length > 0) {
temp.promotionTips = result.promotionTips;
}else{
temp.promotionTips = [];
}
dData.journeyInfo = temp;
}
}
dispatch({
type: ACTION.CHECK_PRICE_PACKAGE,
data: d.data
});
callback && typeof callback == 'function' && callback(d.data);
}, (d) => {
error && typeof error == 'function' && error(d);
return dispatch({
type: ACTION.CHECK_PRICE_PACKAGE
//data: pack
});
//end
})
}
};
/**
* 修改酒店房间数
* @param params
* @param callback
* @param error
* @returns {function()}
*/
let changeResourceNumber = (params, callback, error) => {
return dispatch => {
server.changeResourceNumber(params, (d) => {
callback && typeof callback == 'function' && callback(d);
return dispatch({
type: ACTION.CHANGE_RESOURCE_NUM,
data: d.data,
error: false
});
}, (d) => {
error && typeof error == 'function' && error(d);
return dispatch({
type: ACTION.CHANGE_RESOURCE_NUM,
error: true
})
})
}
};
/**
* 机票十分钟刷新接口
* @param params
* @param callback
* @param error
* @returns {function()}
*/
let flushFlightDetails = (params, data, callback, error) => {
return dispatch => {
server.flushFlightDetails(params, (d) => {
//十分中刷新替换数据
let result = d.data;
if (!result) {
//返回数据为空
dispatch({
type: ACTION.FLUSH_FLIGHT_DETAIL,
flightResult: {},
data: {}
});
} else {
data.flightList = result.flightList;
data.promotions = result.promotions;
data.lackFlag = result.lackFlag;
if (!!data.journeyInfo) {
//机票十分钟刷新,提示更改
data.journeyInfo.journeyNotice = result.journeyNotice;
//机票十分钟刷新,优惠信息更改
if (!!result.promotionTips && result.promotionTips.length > 0) {
data.journeyInfo.promotionTips = result.promotionTips;
}else{
data.journeyInfo.promotionTips = [];
}
}
data.lackDesc = result.lackDesc;
dispatch({
type: ACTION.FLUSH_FLIGHT_DETAIL,
flightResult: result.flightResultMap,
data: data
});
}
callback && typeof callback == 'function' && callback(result);
}, (d) => {
error && typeof error == 'function' && error(d);
return dispatch({
type: ACTION.FLUSH_FLIGHT_DETAIL,
data: data
});
})
}
};
/**
* 删除酒店资源
* @param params
* @param callback
* @param error
* @returns {function()}
*/
let deleteResouce = (params, callBack, error) => {
return dispatch => {
server.deleteResouce(params, (d) => {
callBack && typeof callBack == 'function' && callBack(d);
return dispatch({
type: ACTION.DELETE_RESOURCE,
data: d.data,
error: false
});
}, (d) => {
error && typeof error == 'function' && error(d);
return dispatch({
type: ACTION.DELETE_RESOURCE,
error: true
})
})
}
};
/**
* 还机票验仓验价数据原数据
*/
let resetInvalidFt = ()=> {
return dispatch => {
return dispatch({
type: ACTION.RESET_FLIGHT_RESULT,
flightResult: {}
});
}
};
export {
getDefaultRecommend,
checkPricePackage,
getChangedResouces,
saveJourney,
changeResourceNumber,
deleteResouce,
flushFlightDetails,
resetInvalidFt,
getDefaultRecommendWhenPeopleUpdate
};
URL定义
api.js
/**
* Created by WangJun11 on 2019/3/27.
*/
import {
Platform
} from 'react-native';
let https = 'https://';
let http = 'http://';
let apiHost = 'xxx.xxx.com';
let mHost = 'xxx.xxx.com';
if (Platform.OS == 'android') {
apiHost = 'xxx.xxx.com';
mHost = 'xxx.xxx.com';
}
export default {
// 默认资源推荐接口
getDefaultRecommend: '/res/pack/getDefaultRecommend/app',
// 更换资源推荐接口
getChangedResouces: http + apiHost + '/res/pack/getChangedResouces/app',
// 验价接口
checkPricePackage: '/res/pack/checkPriceAndPackage/app',
//更改酒店房间数
changeResourceNumber: http + apiHost + '/res/pack/changeResourceNumber/app',
//删除酒店资源
deleteResouce: http + apiHost + '/res/pack/deleteResouce/app',
//十分钟刷新接口
flushFlightDetails: '/res/pack/flushFlightDetails/app',
//保存购物车
saveJourney: '/res/pack/saveSavedJourneyForMulti/app',
//人数改变是调的资源推荐接口
getDefaultRecommendWhenPeopleUpdate: '/res/pack/changeTravellersNumber/app'
};
请求网络
/**
* Created by
*/
import api from './api';
let {ajax} = tnGlobal.utils;
/*
*购物车推荐接口
*/
const getDefaultRecommend = (params, success, error) => {
ajax({
url: {
relativeUrl: api.getDefaultRecommend,
timeout: 40000,
isNewSchema: true,
host: 1
},
data: params,
success: success,
error: error
});
};
/*
*人数改变时调的推荐接口
*/
const getDefaultRecommendWhenPeopleUpdate = (params, success, error) => {
ajax({
url: {
relativeUrl: api.getDefaultRecommendWhenPeopleUpdate,
timeout: 40000,
isNewSchema: true,
host: 1
},
data: params,
success: success,
error: error
});
};
const getChangedResouces = (params, success, error)=> {
ajax({
url: api.getChangedResouces,
data: params,
success: success,
error: error
});
};
/**
*保存购物车接口
* @param params
* @param success
* @param error
*/
const saveJourney = (params, success, error)=> {
ajax({
url: {
relativeUrl: api.saveJourney,
timeout: 40000,
isNewSchema: true,
host: 1
},
data: params,
success: success,
error: error
});
};
/**
*验价接口
* @param params
* @param success
* @param error
*/
const checkPricePackage = (params, success, error)=> {
ajax({
url: {
relativeUrl: api.checkPricePackage,
timeout: 40000,
isNewSchema: true,
host: 1
},
data: params,
success: success,
error: error
});
};
/**
* 修改房间数
* @param params
* @param success
* @param error
*/
const changeResourceNumber = (params, success, error)=> {
ajax({
url: api.changeResourceNumber,
data: params,
success: success,
error: error
});
};
/**
* 删除酒店资源
* @param params
* @param success
* @param error
*/
const deleteResouce = (params, success, error)=> {
ajax({
url: api.deleteResouce,
data: params,
success: success,
error: error
});
};
/*
*机票十分钟刷新接口
*/
const flushFlightDetails = (params, success, error)=> {
ajax({
url: {
relativeUrl: api.flushFlightDetails,
timeout: 40000,
isNewSchema: true,
host: 1
},
data: params,
success: success,
error: error
});
};
export {
getDefaultRecommend,
checkPricePackage,
getChangedResouces,
changeResourceNumber,
deleteResouce,
flushFlightDetails,
saveJourney,
getDefaultRecommendWhenPeopleUpdate
}
构建数据
/**
* Created by
*/
import * as ACTION from './ACTION';
/**
* 初始化数据
* @type {{data: {}}}
*/
let initial = {
// 全局数据
dataTest: {
pageName: '初始化数据'
}
};
/**
* 分发数据
* @param state
* @param action
* @returns {*}
*/
export default function items(state = initial, action) {
switch (action.type) {
case ACTION.GET_DEFALULT_RECOMEND:
return {
...state,
data: action.data,
error: action.error,
pricePackage: {},//还原验价数据
flightResult:{}//还原十分钟刷新数据
};
break;
case ACTION.GET_DEFAULT_RECOMMEND_WHEN_PEOPLE_UPDATE:
return {
...state,
data: action.data,
error: action.error,
pricePackage: {},//还原验价数据
flightResult:{}//还原十分钟刷新数据
};
break;
case ACTION.CHECK_PRICE_PACKAGE:
return {
...state,
pricePackage: action.data
};
break;
case ACTION.GET_CHANGE_RESOURCE:
return {
...state,
data: action.data,
error: action.error,
pricePackage: {},//还原验价数据
flightResult:{}//还原十分钟刷新数据
};
break;
case ACTION.CHANGE_RESOURCE_NUM:
return {
...state,
data: action.data,
error: action.error
};
break;
case ACTION.DELETE_RESOURCE:
return {
...state,
data: action.data,
error: action.error
};
break;
case ACTION.FLUSH_FLIGHT_DETAIL:
return {
...state,
flightResult: action.flightResult,
data: action.data,
pricePackage: {}//还原验价数据
};
break;
case ACTION.RESET_FLIGHT_RESULT:
return {
...state,
flightResult: action.flightResult
};
break;
case ACTION.SAVE_JOURNEY:
return {
...state,
saveStatusData: action.data,
};
break;
default:
return state;
}
}
页面入口
/**
* Created by WangJun11 on 2019/3/28.
*/
import React from 'react';
// bridge
import bridge from '@tuniu/rn-bridge';
import {createStore, applyMiddleware} from 'redux';
import {Provider} from 'react-redux';
import thunk from 'redux-thunk';
import reducer from './shop/server/reducer';
import PlaneHotelShop from './shop/PlaneHotelShop';
let dateUtils = tnGlobal.dateUtils;
class ShopProvider extends TNBase.Component {
constructor(props) {
super(props);
this.setPageName();
}
setPageName() {
}
render() {
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const store = createStoreWithMiddleware(reducer);
return (
<Provider store={ store }>
<PlaneHotelShop {...this.props}/>
</Provider>
)
}
}
module.exports = ShopProvider;
页面使用
PlaneHotelShop.js
import React from 'react'
import _ from 'lodash'
let {
View,
Text,
ScrollView,
StyleSheet,
DeviceEventEmitter,
Platform,
Image,
TouchableOpacity,
Modal,
TouchableWithoutFeedback
} = TNBase;
import * as actions from './server/actions';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
class PlaneHotelShop extends TNBase.Component {
// 构造
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount() {
//监听选择人数发生变更的方法
this.checkInInfoListener = bridge.addEventEmitterListener('TNReactNativePlaneHotelCheckInUpdateNotification', (d)=> {
//出游人选择页,清除定时器
});
}
componentWillUnmount() {
//卸载移除监听
this.checkInInfoListener && bridge.removeEventEmitterListener(this.checkInInfoListener);
}
/**
* 获取标题
* @param journeyInfo
*/
getTitle(journeyInfo){
let data = this.props.data;
if(!!data && !!journeyInfo){
if(data.hasFlight || data.hasTrain){
//有机票,标题
return journeyInfo.departCityName + '-' + journeyInfo.destCityName + '自由行';
}else{
//无机票
return journeyInfo.destCityName + '自由行';
}
}else{
return this.title;
}
}
render() {
return (
<View style={{flex: 1,backgroundColor:'#f2f2f2'}}>
<Header renderTitle={this.renderTitle.bind(this,headTitle)}
leftClick={() => {
bridge.setLogEvent({'eventName': '点击_标题栏____返回'}, ()=>{});
bridge.setLinkBack(null,function(d){});
}}
renderRight={this.renderRight.bind(this)}/>
</View>
);
}
/**
* 卡片添加酒店
*/
addHotelCard(params){
if (!!params) {
this.refs.ResourcesModal.changeVisible(true,params)
}
}
// 顶部nav bar右边更多按钮
renderRight() {
return (
<View style={styles.serviceBg}>
</View> )
}
reloadDefault() {
this.setState({
loading: true
});
this.getDefaultRecommend();
}
/**
* 获取是单程还是往返
*/
getJournryType() {
if (!!this.props.data && !!this.props.data.journeyInfo && !!this.props.data.journeyInfo.journeyType) {
return this.props.data.journeyInfo.journeyType;
} else {
return this.props.journeyType;
}
}
/**
* 默认资源推荐接口
*/
getDefaultRecommend(needRecommendProductId = true) {
let that = this;
if (!!this.bookCityCode && !!this.orderCityName) {
that.requestRecommd(needRecommendProductId);
} else {
bridge.getGPS({}, (city = {}) => {
let data = city.data || {};
this.bookCityCode = +(data.orderCityCode || 2500);
this.orderCityName = data.orderCityName || '上海';
that.requestRecommd(needRecommendProductId);
});
}
};
//当人数改变时的更新接口
refreshWhenPeopleUpdate(){
let that = this;
if (!!this.bookCityCode && !!this.orderCityName) {
that.requestWhenPeopleUpdate();
} else {
bridge.getGPS({}, (city = {}) => {
let data = city.data || {};
this.bookCityCode = +(data.orderCityCode || 2500);
this.orderCityName = data.orderCityName || '上海';
that.requestWhenPeopleUpdate();
});
}
}
/**
* 当人数改变时的更新接口请求默认推荐
*/
requestWhenPeopleUpdate() {
let that = this;
//sessionId自动加上
this.props.actions.getDefaultRecommendWhenPeopleUpdate({
packType: this.packType,
bookCityCode: this.bookCityCode, //int,必传,预定城市id
bookCityName: this.orderCityName || '上海', //String,必传,预定城市名称
departCityCode: +this.state.departcity.cityCode, //int,必传,出发城市id
departCityName: this.state.departcity.cityName, //String,必传,出发城市名称
departDate: this.state.date.startDate, //String,必传,出发日期
adultNum: +this.state.people.adultNum, //int,必传,成人数
childNum: +this.state.people.childrenNum, //int,必传,儿童数
childAges: this.state.people.childAges, //array,儿童年龄
journeyType: this.getJournryType() || 2, //int,必传,行程类型:2往返,1单程 默认往返
journeyList: [ //行程
{
cabinType: +this.state.info.cabinType, //int,必传,舱等大类 1.经济舱 2.公务舱 3.头等舱
startCityCode: +this.state.departcity.cityCode, //出发城市code
startCityName: this.state.departcity.cityName, //出发城市名称
startCityIataCode: this.state.departcity.cityIataCode, //出发地城市三字码
destCityCode: +this.state.destcity.cityCode, //目的地城市code
destCityName: this.state.destcity.cityName, //目的地城市名称
destCityIataCode: this.state.destcity.cityIataCode, //目的地城市三字码
journeyDepartDate: this.state.date.startDate, //行程出发时间
journeyEndDate: this.state.date.endDate, //行程结束时间
trainType: this.trainType //火车票类型 1 高铁 动车 0 全部车次
}
],
recommendProductId:this.recommendProductId //系统打包的产品ID
}, (d)=> {
//无需主动调用state data
that.setState({
loading: false
});
that.resetTimer();
}, (error)=> {
//无需主动调用state data
that.setState({
loading: false
});
that.resetTimer();
});
}
/**
* 请求默认推荐
* @param needRecommendProductId
*/
requestRecommd(needRecommendProductId = true) {
let that = this;
//sessionId自动加上
this.props.actions.getDefaultRecommend({
}, (d)=> {
//无需主动调用state data
that.setState({
loading: false
});
that.resetTimer();
}, (error)=> {
//无需主动调用state data
that.setState({
loading: false
});
that.resetTimer();
});
}
/**
* 修改酒店房间数
*/
changeResourceNumber(params) {
let that = this;
this.setState({
priceShow: false,
loading: true
});
if(!!params){
params.packType = this.packType;
}
this.props.actions.changeResourceNumber(params, (d) => {
that.setState({
loading: false
});
}, (error) => {
that.setState({
loading: false
});
});
};
/**
* 删除酒店资源
*/
deleteResource(params) {
if(!params || !params.deleteResourceList || params.deleteResourceList.length == 0){
return;
}
let that = this;
this.setState({
flightShow: false,
priceShow: false,
loading: true
});
this.props.actions.deleteResouce(params, (d) => {
that.setState({
loading: false
});
}, (error) => {
that.setState({
loading: false
});
});
}
}
const styles = StyleSheet.create({
scrollView: {
flex: 1
},
right: {
width: 21,
marginRight: 18,
fontSize: 10,
color: '#383838',
fontFamily: 'PingFang-SC-Medium'
}
});
let dumbComponent = connect(state => ({
data: state.data,
pricePackage: state.pricePackage,
error: state.error,
flushFlight: state.flightResult,
saveStatusData: state.saveStatusData
}), dispatch => ({
actions: bindActionCreators(actions, dispatch)
}))(PlaneHotelShop);
module.exports = dumbComponent;
网友评论