Commit 4ff2137e authored by shiyunjie's avatar shiyunjie

我的保单详情,保险产品列表

parent c1efe847
......@@ -301,6 +301,7 @@
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.4.tgz",
"integrity": "sha512-z7MpQz3XC/iQJWXH9y+MaWcLPNSMY9RQSthrLzak8R8hCj0fuyNk+Dzi9kfNe/JxxlWQ2g7wkABbgWjW36MTcw==",
"dev": true,
"requires": {
"@babel/helper-create-class-features-plugin": "^7.4.4",
"@babel/helper-plugin-utils": "^7.0.0",
......@@ -364,6 +365,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz",
"integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
......@@ -11556,6 +11558,24 @@
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-1.1.0.tgz",
"integrity": "sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw=="
},
"react-native-root-siblings": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/react-native-root-siblings/-/react-native-root-siblings-3.2.1.tgz",
"integrity": "sha512-WNNhLRFpyK8R00OOdMhQVepeBV+khMTi+Yk3QcPRetMLvao8kLkCP5SObiXpbTFPZlkuSfHo/0jtEKyUA8qWpw==",
"requires": {
"prop-types": "^15.6.2",
"static-container": "^1.0.0"
}
},
"react-native-root-toast": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/react-native-root-toast/-/react-native-root-toast-3.1.2.tgz",
"integrity": "sha512-68OhAjRMwUsNeKC7GE5Sgems6dXY2VzuTsNe4hRbbN23V/bFeItnJAvgV4lib4hsCvO4KZjUtUqRY/nQd8s/7Q==",
"requires": {
"prop-types": "^15.5.10",
"react-native-root-siblings": "^3.0.0"
}
},
"react-native-safe-area-view": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.14.5.tgz",
......@@ -13553,6 +13573,11 @@
"type-fest": "^0.3.0"
}
},
"static-container": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/static-container/-/static-container-1.3.0.tgz",
"integrity": "sha512-OJnvgv6tq9T5QbFUMioEK4WP48pMn/X4qdcrWAhop6boMMz6pMmWPWXgjimn1wKqcClZ6Ff0iSKViRXzwx111w=="
},
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
......
......@@ -9,7 +9,6 @@
"postinstall-devTools": "remotedev-debugger --hostname localhost --port 5678 --injectserver"
},
"dependencies": {
"@babel/plugin-proposal-decorators": "^7.4.4",
"@react-native-community/async-storage": "^1.5.0",
"axios": "^0.18.0",
"lodash": "^4.17.11",
......@@ -25,6 +24,7 @@
"react-native-largelist-v3": "^3.0.14",
"react-native-linear-gradient": "^2.5.4",
"react-native-reanimated": "^1.1.0",
"react-native-root-toast": "^3.1.2",
"react-native-spring-scrollview": "^2.0.22",
"react-native-super-grid": "^3.0.7",
"react-native-svg": "^9.5.1",
......@@ -41,6 +41,7 @@
},
"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/runtime": "^7.4.3",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.7.1",
......
......@@ -11,6 +11,7 @@ export const push = (pageName: String = '', extProps) => ({
type: PUSH,
pageName,
extProps,
message: '暂未开放',
});
export const pop = (pageName: String = '') => ({
type: POP,
......
......@@ -24,6 +24,7 @@ import CheckBoxPage from '../pages/checkBoxDemo';
import RatingPage from '../pages/ratingDemo';
import SliderPage from '../pages/sliderDemo';
import TooltipPage from '../pages/tooltipDemo';
import InsuranceDetail from '../pages/InsuranceList/InsuranceDetail';
import { initialRouteName, RootPageInitialName } from '../utils/constants';
import { TabOptions } from '../components/TabOptions';
......@@ -128,6 +129,9 @@ const navigator = createStackNavigator({
InsuranceList: {
screen: InsuranceList,
},
InsuranceDetail: {
screen: InsuranceDetail,
},
}, {
initialRouteName,
headerMode: 'none',
......@@ -138,7 +142,7 @@ const navigator = createStackNavigator({
disableKeyboardHandling: false,
cardShadowEnabled: true,
cardOverlayEnabled: true,
onTransitionEnd: () => NativeAppEventEmitter.emit('react_navigation_onTransitionEnd_call'),
onTransitionEnd: () => NativeAppEventEmitter.emit('react_navigation_onTransitionEnd_call',),
});
//export default navigator;
......
......@@ -5,7 +5,7 @@
import { NavigationActions } from 'react-navigation';
import NavigationStack from './navigationStack';
import { initialRouteName } from '../utils/constants';
import toast from '../components/Toast';
import { PUSH, POP, TAB } from './actions';
const ActionForTab = NavigationStack.router.getActionForPathAndParams(initialRouteName);
......
/**@flow
* Created by shiyunjie on 2018/8/18.
*/
import React, { Component, Element } from 'react';
import {
StyleSheet,
Text,
View,
TouchableWithoutFeedback,
Animated,
Dimensions,
} from 'react-native';
const screenWidth = Dimensions.get('window').width
const styles = StyleSheet.create({
container: {
backgroundColor: '#fff',
overflow: 'hidden',
marginBottom: 12,
},
titleContainer: {
flexDirection: 'row',
width: screenWidth,
},
button: {
width: 40,
height: 80,
justifyContent: 'center',
paddingRight: 15,
alignItems: 'flex-end',
},
body: {
padding: 10,
paddingTop: 0,
},
orderNum: {
fontSize: 16,
color: '#666',
marginTop: 3,
},
part_text: {
height: 80,
width: screenWidth,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'stretch',
},
})
type Props = {
title : string,
containerHeight : number,
name : string,
index : number,
children? : Element<*>,
amount? : string,
isApprobation? : string,
titleStyle?: Object,
policyTitleColor?: Object,
upIcon:Object,
downIcon:Object,
}
class Panel extends Component {
constructor(props : Props) {
super(props)
this.icons = {
'up': props.upIcon,
'down': props.downIcon,
}
this.state = {
expanded: false,
animation: new Animated.Value((this.props.containerHeight || 80)),
};
}
setMaxHeight = (event) => {
this.setState({
maxHeight: event.nativeEvent.layout.height,
})
}
setMinHeight = (event) => {
this.setState({
minHeight: event.nativeEvent.layout.height,
})
}
toggle = () => {
const initialValue =
this.state.expanded ? this.state.maxHeight + this.state.minHeight : this.state.minHeight
const finalValue =
this.state.expanded ? this.state.minHeight : this.state.maxHeight + this.state.minHeight
this.setState({
expanded: !this.state.expanded,
})
this.state.animation.setValue(initialValue)
Animated.spring(
this.state.animation,
{
toValue: finalValue,
}
).start()
}
render() {
let icon = this.icons.down
if (this.state.expanded) {
icon = this.icons.up;
}
return (
<Animated.View
style={[styles.container, { height: this.state.animation }]}
>
<View
style={styles.titleContainer}
onLayout={this.setMinHeight}
>
<TouchableWithoutFeedback
onPress={this.toggle}
>
<View
style={[styles.part_text, this.props.titleStyle, !!this.props.containerHeight ? {height: this.props.containerHeight}: {}]}
>
<View
style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'flex-start',
paddingLeft: (15),
}}
>
<Text style={[styles.orderNum, this.props.policyTitleColor]} >{this.props.title || '标题'}</Text>
</View>
<View style={[styles.button,!!this.props.containerHeight ? {height: this.props.containerHeight}: {}]} >
{icon}
</View>
</View>
</TouchableWithoutFeedback>
</View>
<View style={styles.body} onLayout={this.setMaxHeight} >
{this.props.children}
</View>
</Animated.View>
)
}
}
export default Panel
......@@ -163,29 +163,6 @@ export function UserPageHeader(props) {
);
}
export function ServicePageHeader() {
return (
<View style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
height: 44,
width: global.SCREEN_WIDTH,
marginTop: Platform.OS === 'ios' ? iosMarginTop : androidTop,
}}
>
<Text style={{
color: '#333',
fontSize: 17,
fontWeight: '400',
}}
>
服务
</Text>
</View>
);
}
export default {
HomeHeader,
UserPageHeader,
......
......@@ -22,6 +22,8 @@ const systemVersion = DeviceInfo.getSystemVersion();
export const iosMarginTop = parseInt(systemVersion, 10) < 11 ? 20 : 0;
export const NavHeight = Platform.OS === 'android' ? 44 + androidTop : 64
const styles = StyleSheet.create({
navBarContainer: {
......@@ -57,9 +59,11 @@ const styles = StyleSheet.create({
textAlign: 'center',
phone: {
fontSize: 18,
fontWeight: '400',
},
pad: {
fontSize: 24,
fontWeight: '400',
},
color: 'white',
alignSelf: 'center',
......
/**
* @flow
*/
import Toast from 'react-native-root-toast';
export default function toast(message) {
Toast.show(message, {
duration: Toast.durations.SHORT,
position: Toast.positions.BOTTOM,
shadow: true,
animation: true,
hideOnPress: true,
delay: 0,
onShow: () => {
// calls on toast\`s appear animation start
},
onShown: () => {
// calls on toast\`s appear animation end.
},
onHide: () => {
// calls on toast\`s hide animation start.
},
onHidden: () => {
// calls on toast\`s hide animation end.
},
});
}
//@flow
import React from 'react';
import {
View,
} from 'react-native';
import Text from '../../components/Text';
function renderPageByConfig(config) {
return (
<View>
<Text>组件</Text>
</View>
);
}
export default {
renderPageByConfig,
};
/**@flow
* Created by shiyunjie on 2018/8/29.
*/
import _ from 'lodash';
import { fetchCoreAPI } from '../../utils/api/BasicAPIRequest';
type RiskTakerParams = {
uid : string,
}
export async function queryInsuranceListByUid(params : RiskTakerParams) {
console.log('queryInsuranceListByUid', params);
const body = await fetchCoreAPI('001001', params);
console.log('fetchCoreAPI:', body);
if (_.get(body, 'code') === '0000' && _.get(body, 'data')) {
return _.get(body, 'data');
}
return [];
}
export async function queryInsuranceDetail(params : RiskTakerParams) {
console.log('queryInsuranceDetail', params);
const body = await fetchCoreAPI('001002', params);
console.log('fetchCoreAPI:', body);
if (_.get(body, 'code') === '0000' && _.get(body, 'data')) {
return _.get(body, 'data');
}
return [];
}
export default {};
/** @flow
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, { useState, useEffect } from 'react';
import { TouchableOpacity, View, ScrollView } from 'react-native';
import { connect } from 'react-redux';
import { compose } from 'redux';
import FastImage from 'react-native-fast-image';
import Text from '../../components/Text';
import InsuranceDetailPanel from './InsuranceDetailPanel';
import Styles from '../../theme/Styles';
import NavigationBar from '../../components/NavigationBar';
import BackButton from '../../components/BackButton';
import { push, tab } from '../../BasicNavigator/actions';
import { ENV, resourceURLMapping } from '../../utils/constants';
function renderInsuranceDetail(props) {
const { params } = props.navigation.state;
const [value, setValue] = useState([
{
title: '险种信息',
content: [
{
key: '险种名称',
value: params.productName,
},
{
key: '险种当前状态',
value: params.productStatus,
},
{
key: '保额',
value: params.amount,
},
{
key: '生效日期',
value: params.date,
},
{
key: '被保人',
value: params.insured,
},
{
key: '保费',
value: params.premium,
},
{
key: '下期缴费日',
value: params.nextDate,
},
],
},
{
title: '投保人',
content: [
{
key: '姓名',
value: params.applicant,
},
{
key: '生日',
value: params.birthday,
},
{
key: '性别',
value: params.gender,
},
{
key: '证件号',
value: params.idno,
},
{
key: '手机号',
value: params.mobile,
},
],
}]);
const renderItem = (item, index) => (
<InsuranceDetailPanel
key={`LoanPanl-${index}`}
item={item}
index={index}
/>
);
const uri = `${resourceURLMapping[ENV]}${
params.company === '太平人寿' ? 'bg_bdxq_rs.png' : 'bg_bdxq_cx.png'}`
console.log('uri:',uri)
return (
<View style={[Styles.container, { backgroundColor: '#F4F5F5' }]}>
<NavigationBar
style={{ backgroundColor: '#fff' }}
textStyle={{
color: '#333',
fontSize: 17,
fontWeight: '400',
}}
left={<BackButton style={{ color: '#333' }} />}
title="保单详情"
/>
<ScrollView
style={{ flex: 1, backgroundColor: '#F4F5F5' }}
>
<View
style={{
height: global.SCREEN_WIDTH * 105 / 375,
}}
>
<FastImage
style={{ width: global.SCREEN_WIDTH, height: global.SCREEN_WIDTH * 105 / 375 }}
source={{
uri,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.stretch}
/>
<View
style={{
height: global.SCREEN_WIDTH * 105 / 375,
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
paddingLeft: 30,
justifyContent: 'flex-end',
}}
>
<Text
style={{
fontSize: 12,
color: '#fff',
marginBottom: global.SCREEN_WIDTH * 4 / 375,
}}
>
保单号
</Text>
<Text
style={{
fontSize: 18,
color: '#fff',
weight: 400,
marginBottom: global.SCREEN_WIDTH * 21 / 375,
}}
>
{params.policyNo}
</Text>
</View>
</View>
{
value.map((item, index) => (
renderItem(item, index)
))
}
</ScrollView>
</View>
);
}
function propsMapping(props) {
const { nav, theme } = props;
return {
nav,
theme,
};
}
function actionMapping(dispatch) {
return {
pushTo: compose(dispatch, push),
tabTo: compose(dispatch, tab),
};
}
export default connect(propsMapping, actionMapping)(renderInsuranceDetail);
/**@flow
* Created by shiyunjie on 2018/8/18.
*/
import React from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
import Panel from '../../components/Agera-App-Base-panel';
import BasicIcon from '../../components/BasicIcon';
const screenWidth = global.SCREEN_WIDTH;
const styles = StyleSheet.create({
explainFont: {
fontSize: 14,
color: '#666666',
},
});
type Props = {
item : Object,
index : number,
}
export default function LoanPanel(props : Props) {
const {
item, index,
} = props;
return (
<Panel
title={item.title}
containerHeight={50}
index={index}
amount=""
upIcon={(
<BasicIcon
suite="Ionicons"
name="ios-arrow-up"
size={24}
color="#666"
/>
)}
downIcon={(
<BasicIcon
suite="Ionicons"
name="ios-arrow-down"
size={24}
color="#666"
/>
)}
>
<View
style={{
//height: (65),
flexDirection: 'column',
justifyContent: 'flex-start',
backgroundColor: '#F9FAFB',
paddingBottom: (8),
alignItems: 'stretch',
//flexWrap: 'wrap',
}}
>
<View
style={{
paddingHorizontal: (15),
}}
>
{
item.content.map((info, index) => (
<View
style={{
//height: 25,
width: screenWidth - 50,
flexDirection: 'row',
justifyContent: 'flex-start',
flexWrap: 'wrap',
marginVertical: 10,
}}
>
<Text style={[styles.explainFont]}>
{info.key}
</Text>
<View style={{ flex: 1 }} />
<View
style={{
flexDirection: 'row',
justifyContent: 'flex-end',
flexWrap: 'nowrap',
}}
>
<Text style={[styles.explainFont, { minWidth: 0, color: '#333' }]}>
{info.value}
</Text>
</View>
</View>
))
}
</View>
<View style={{ backgroundColor: '#fff', height: 20 }} />
</View>
</Panel>
);
}
// @flow
import React from 'react';
import { TouchableOpacity, View } from 'react-native';
import Text from '../../components/Text';
import LinearGradient from 'react-native-linear-gradient';
import BasicIcon from '../../components/BasicIcon';
export default function renderListItem(props) {
const {
section, row, titleHeight, item, onPress, itemHeight,
} = props;
return (
<View
key={`${section}-${row}`}
style={{
alignItems: 'stretch',
paddingHorizontal: 15,
paddingTop: 12,
}}
>
<View style={{
flexDirection: 'row',
backgroundColor: '#FFFFFF',
borderRadius: 10,
height: titleHeight,
}}
>
<View
style={{
flex: 2,
justifyContent: 'space-around',
paddingLeft: 15,
}}
>
<View style={{
flexDirection: 'row',
}}
>
<LinearGradient
start={{ x: 0.0, y: 0.25 }}
end={{ x: 0.5, y: 1.0 }}
locations={[0, 1]}
colors={[item.companyColor[1], item.companyColor[0]]}
style={{
width: 60, height: 18, alignItems: 'center', justifyContent: 'center',
}}
>
<Text style={{ color: '#fff', fontSize: 12 }}>
{item.company}
</Text>
</LinearGradient>
<Text style={{
color: '#666',
fontSize: 14,
marginLeft: 12,
}}
>
{item.policyNo}
</Text>
</View>
<Text style={{
color: '#333',
fontSize: 18,
}}
>
{item.productName}
</Text>
</View>
<TouchableOpacity
style={{
flex: 1,
alignItems: 'flex-end',
justifyContent: 'center',
paddingRight: 15,
}}
onPress={onPress}
>
<BasicIcon suite="Ionicons" name="ios-arrow-forward" size={26} color="#666" />
</TouchableOpacity>
</View>
<View style={{
flexDirection: 'row',
height: itemHeight - 12 - titleHeight,
padding: 15,
backgroundColor: '#fff',
}}
>
<View
style={{
justifyContent: 'space-between',
}}
>
<Text
style={{
color: '#999',
fontSize: 12,
}}
>
被保险人
</Text>
<Text
style={{
color: '#333',
fontSize: 14,
}}
>
{item.applicant}
</Text>
</View>
<View
style={{
justifyContent: 'space-between',
flex: 1,
marginHorizontal: 19,
}}
>
<Text
style={{
color: '#999',
fontSize: 12,
}}
>
保险期间
</Text>
<Text
style={{
color: '#333',
fontSize: 14,
}}
>
{item.duration}
</Text>
</View>
<View
style={{
justifyContent: 'space-between',
}}
>
<Text
style={{
color: '#999',
fontSize: 12,
}}
>
保单状态
</Text>
<Text
style={{
color: '#0E6DCF',
fontSize: 14,
}}
>
{item.status}
</Text>
</View>
</View>
</View>
);
}
......@@ -10,32 +10,38 @@ import React, { useEffect, useState } from 'react';
import {
View,
StyleSheet,
NativeAppEventEmitter, TouchableOpacity,
NativeAppEventEmitter,
TouchableOpacity,
} from 'react-native';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { LargeList } from 'react-native-largelist-v3';
import { CommonLottieHeader } from 'react-native-spring-scrollview/Customize/CommonLottieHeader';
import { TabView, TabBar } from 'react-native-tab-view';
import LinearGradient from 'react-native-linear-gradient';
import { push, tab } from '../../BasicNavigator/actions';
import NavigationBar from '../../components/NavigationBar';
import NavigationBar, { NavHeight } from '../../components/NavigationBar';
import BackButton from '../../components/BackButton';
import { queryInsuranceListByUid } from './InsuranceAPI';
import Styles from '../../theme/Styles';
import ListItem from './ListItem';
import decorator from '../../utils/decorator';
import BasicIcon from '../../components/BasicIcon';
import Text from '../../components/Text';
type Props = {
pushTo: ()=> void,
tabTo: ()=> void,
theme: Object,
pushTo : ()=> void,
tabTo : ()=> void,
theme : Object,
};
const styles = StyleSheet.create({
tabBar: {
backgroundColor: 'white',
},
tab: {
width: SCREEN_WIDTH / 3,
width: global.SCREEN_WIDTH / 3,
},
indicator: {
backgroundColor: '#4ECBFC',
......@@ -47,10 +53,11 @@ const styles = StyleSheet.create({
},
});
const typeArr: Array<> = [
const typeArr : Array<> = [
{ key: 'ALL', title: '全部', type: 1 },
{ key: 'SAVE', title: '保障中', type: 41 },
{ key: 'EXPIRED', title: '已失效', type: 10 },
{ key: 'EXPIRED2', title: '其他', type: 10 },
];
const typeData = {
......@@ -58,22 +65,13 @@ const typeData = {
routes: typeArr,
};
function JSPage(props: Props) {
function InsuranceListPage(props : Props) {
//console.log('JSPage props from lastPage', this.props.navigation.state);
useEffect(() => {
console.log('在 dep 改变时触发,若无 dep 则,每次更新组件都会触发');
const didFocus = NativeAppEventEmitter.addListener('react_navigation_onTransitionEnd_call', () => {
console.log('JSPage__didFocus');
});
return () => {
console.log('在组件 unmount 时触发');
if (didFocus) {
didFocus.remove();
}
};
});
const [type, setType] = useState(typeData);
const [data, setData] = useState([{items: [{ name: '我的保单', page: '' },]}]);
const [isFirst, setIsFirst] = useState(true);
const [data, setData] = useState([{ items: [] }]);
const itemHeight = (global.SCREEN_WIDTH - 30) * 137 / 345 + 12;
const titleHeight = (itemHeight - 12) * 80 / 137;
const _handleIndexChange = (index) => {
const _type = {
......@@ -81,41 +79,68 @@ function JSPage(props: Props) {
routes: typeArr,
};
setType(_type);
}
};
const renderIndexPath = ({ section, row }) => {
const { theme, pushTo } = props;
const item = data[section].items[row];
return (
<View
key={`${section}-${row}`}
style={{ alignItems: 'stretch', justifyContent: 'center', backgroundColor: 'yellow'}}
>
<TouchableOpacity
onPress={() => pushTo(item.page)}
>
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<Text>
{item.name}
</Text>
</View>
</TouchableOpacity>
<View style={Styles.line} />
</View>
);
}
const _renderScene = ({ route, jumpTo }) => {
return (
<LargeList
style={[
{ flex:1},
]}
data={data}
heightForIndexPath={() => 50}
renderIndexPath={renderIndexPath}
<ListItem
section={section}
row={row}
item={item}
titleHeight={titleHeight}
itemHeight={itemHeight}
onPress={() => pushTo('InsuranceDetail', item)}
/>
);
}
};
const queryList = async () => {
const list = await queryInsuranceListByUid({ params: { uid: 'u0000001' } });
console.log('list:', list);
if (list) {
setData([
{
items: list,
},
]);
}
};
useEffect(() => {
if (isFirst) {
queryList();
setIsFirst(false);
}
});
const onRefresh = async () => {
await queryList();
this.scrollView.endRefresh();
};
const endRefresh = () => {
};
const _renderScene = ({ route, jumpTo }) => (
<LargeList
ref={(com) => {
this.scrollView = com;
}}
style={{
backgroundColor: '#F4F5F5',
}}
contentStyle={[
{ height: global.SCREEN_HEIGHT - NavHeight - 50, backgroundColor: '#F4F5F5' },
]}
data={data}
onRefresh={onRefresh}
endRefresh={endRefresh}
refreshHeader={CommonLottieHeader}
heightForIndexPath={() => itemHeight}
heightForSection={() => 0}
renderIndexPath={renderIndexPath}
/>
);
function _renderTabBar(item) {
return (
......@@ -123,7 +148,7 @@ function JSPage(props: Props) {
{...item}
scrollEnabled
indicatorStyle={{ backgroundColor: props.theme.ThemeColor }}
style={{ backgroundColor: '#fff' }}
style={{ backgroundColor: '#fff', height: 50 }}
tabStyle={styles.tab}
labelStyle={[styles.label]}
activeColor={props.theme.ThemeColor}
......@@ -141,21 +166,19 @@ function JSPage(props: Props) {
fontSize: 17,
fontWeight: '400',
}}
left={<BackButton style={{color: '#333',}} />}
left={<BackButton style={{ color: '#333' }} />}
title="我的保单"
/>
<View style={[Styles.container, { justifyContent: 'center' }]}>
<TabView
navigationState={type}
renderScene={_renderScene}
renderTabBar={_renderTabBar}
onIndexChange={_handleIndexChange}
lazy
swipeEnabled={false}
swipeDistanceThreshold={global.SCREEN_WIDTH / 10}
initialLayout={{ width: global.SCREEN_WIDTH }}
/>
</View>
<TabView
navigationState={type}
renderScene={_renderScene}
renderTabBar={_renderTabBar}
onIndexChange={_handleIndexChange}
lazy
swipeEnabled={false}
swipeDistanceThreshold={global.SCREEN_WIDTH / 10}
initialLayout={{ width: global.SCREEN_WIDTH }}
/>
</View>
);
}
......@@ -167,12 +190,14 @@ function propsMapping(props) {
theme,
};
}
function actionMapping(dispatch) {
return {
pushTo: compose(dispatch, push),
tabTo: compose(dispatch, tab),
};
}
//const mapDispatchToProps = dispatch => (bindActionCreators({goNext}, dispatch))
export default connect(propsMapping, actionMapping)(JSPage);
export default connect(propsMapping, actionMapping)(InsuranceListPage);
......@@ -20,7 +20,7 @@ import themeAction from '../../theme/action';
import NavigationBar from '../../components/NavigationBar';
import BackButton from '../../components/BackButton';
import Button from '../../components/ThemeButton';
import decorator from '../../utils/decorator';
type Props = {};
const styles = StyleSheet.create({
......@@ -38,6 +38,10 @@ const styles = StyleSheet.create({
class ThemePage extends Component<Props> {
componentDidMount() : void {
console.log('ThemePage_componentDidMount');
}
render() {
const { theme, setCurrentTheme } = this.props;
......
/**
* Sample React Native App
* https://github.com/facebook/react-native
......@@ -8,21 +7,26 @@
*/
import React, { Component } from 'react';
import { SpringScrollView } from 'react-native-spring-scrollview';
import { CommonLottieHeader } from 'react-native-spring-scrollview/Customize/CommonLottieHeader';
//import CommonLottieFooter from 'react-native-spring-scrollview/Customize/CommonLottieFooter';
import { connect } from 'react-redux';
import { compose } from 'redux';
import {
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import FastImage from 'react-native-fast-image';
import { TabBar, TabView } from 'react-native-tab-view';
import { LargeList } from 'react-native-largelist-v3';
import { CommonLottieHeader } from 'react-native-spring-scrollview/Customize/CommonLottieHeader';
import { push } from '../../BasicNavigator/actions';
import { renderByType } from './serviceRenderUtil';
import { ServicePageHeader } from '../../components/HeaderView';
const data = require('./service.json');
import NavigationBar, { NavHeight } from '../../components/NavigationBar';
import decorator from '../../utils/decorator';
import Text from '../../components/Text';
import { ENV, resourceURLMapping } from '../../utils/constants';
import ListItem from '../InsuranceList/ListItem';
import { queryInsuranceListByUid } from '../InsuranceList/InsuranceAPI';
type Props = {};
const styles = StyleSheet.create({
......@@ -30,59 +34,249 @@ const styles = StyleSheet.create({
flex: 1,
backgroundColor: '#F5FCFF',
},
header: {
height: 150,
},
tab: {
width: global.SCREEN_WIDTH / 4,
},
label: {
fontWeight: 'bold',
fontSize: 16,
//color: '#666',
},
});
const step = 13;
const typeArr : Array<> = [
{ key: 'ALL', title: '全部', type: 1 },
{ key: 'SAVE', title: '保障中', type: 41 },
{ key: 'EXPIRED', title: '已失效', type: 10 },
{ key: 'EXPIRED2', title: '其他', type: 10 },
];
class HomePage extends Component<Props> {
const typeData = {
index: 0,
routes: typeArr,
};
@decorator
class PolicyPage extends Component<Props> {
constructor(props) {
super(props);
this.itemHeight = (global.SCREEN_WIDTH - 30) * 137 / 345 + 12;
this.titleHeight = (this.itemHeight - 12) * 80 / 137;
this.state = {
count: step,
allLoaded: false,
data: [],
type: typeData,
};
this.scrollView = null;
}
_handleIndexChange = (index) => {
const type = {
index,
routes: typeArr,
};
this.setState({ type });
};
renderIndexPath = ({ section, row }) => {
const { theme, pushTo } = this.props;
const item = this.state.data[section].items[row];
_onRefresh = () => {
setTimeout(() => {
this.scrollView.endRefresh();
this.setState({ count: step, allLoaded: false });
}, 3000);
return (
<ListItem
section={section}
row={row}
item={item}
titleHeight={this.titleHeight}
itemHeight={this.itemHeight}
onPress={() => pushTo('InsuranceDetail', item)}
/>
);
};
_onLoading = () => {
setTimeout(() => {
this.scrollView.endLoading();
this.setState(p => ({
count: p.count + step,
allLoaded: false,
}));
}, 3000);
queryList = async () => {
const list = await queryInsuranceListByUid({ params: { uid: 'u0000001' } });
console.log('list:', list);
if (list) {
this.setState({
data: [
{
items: list,
},
],
});
}
};
onRefresh = async () => {
await this.queryList();
this.scrollView.endRefresh();
};
endRefresh = () => {
};
_renderScene = ({ route, jumpTo }) => (
<LargeList
ref={(com) => {
this.scrollView = com;
}}
style={{
backgroundColor: '#F4F5F5',
}}
contentStyle={[
{ height: global.SCREEN_HEIGHT - NavHeight - 50, backgroundColor: '#F4F5F5' },
]}
data={this.state.data}
onRefresh={this.onRefresh}
endRefresh={this.endRefresh}
refreshHeader={CommonLottieHeader}
heightForIndexPath={() => this.itemHeight}
heightForSection={() => 0}
renderIndexPath={this.renderIndexPath}
/>
);
_renderTabBar = item => (
<TabBar
{...item}
scrollEnabled
indicatorStyle={{ width:36, backgroundColor: this.props.theme.ThemeColor }}
style={{ backgroundColor: '#fff', height: 50 }}
tabStyle={styles.tab}
labelStyle={[styles.label]}
activeColor={this.props.theme.ThemeColor}
inactiveColor="#666"
/>
)
render() {
const { pushTo } = this.props;
return (
<View style={[styles.container, { backgroundColor: 'white' }]}>
<ServicePageHeader />
<SpringScrollView
ref={ref => (this.scrollView = ref)}
style={[styles.container, { backgroundColor: '#F4F5F5' }]}
inverted={false}
onRefresh={this._onRefresh}
//onLoading={this._onLoading}
// allLoaded={this.state.allLoaded}
refreshHeader={CommonLottieHeader}
//loadingFooter={CommonLottieFooter}
<View style={[styles.container, { backgroundColor: '#fff' }]}>
<LinearGradient
start={{ x: 0.5, y: 0 }}
end={{ x: 0.5, y: 1 }}
locations={[0, 1]}
colors={['#08BFF9', '#4A98E0']}
style={[styles.header]}
>
<View>
<NavigationBar
style={{ backgroundColor: '#00000000' }}
title="保险"
/>
<View
style={{
height: 25,
flexDirection: 'row',
marginTop: 8,
paddingLeft: 15,
}}
>
<Text style={{
color: '#fff',
fontSize: 18,
}}
>
太平保险
</Text>
<Text
style={{
color: '#fff',
fontSize: 12,
marginTop: 6,
marginLeft: 2,
}}
>
为您精选
</Text>
</View>
</View>
</LinearGradient>
<View
style={{
height: 86,
backgroundColor: '#fff',
borderRadius: 10,
position: 'absolute',
zIndex: 3,
top: 107,
left: 15,
right: 15,
bottom: global.SCREEN_HEIGHT - 193,
elevation: 20,
shadowOffset: { width: 0, height: 0 },
shadowColor: '#D0DBFF',
shadowOpacity: 1,
shadowRadius: 5,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
{data.map((item, index) => (
renderByType(item.type)({
...item,
width: global.SCREEN_WIDTH,
})
))}
</SpringScrollView>
<View style={{
flex: 1,
height: 86,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<FastImage
style={{
width: 36,
height: 36,
}}
source={{
uri: `${resourceURLMapping[ENV]}insure_wodebaodan.png`,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.stretch}
/>
<Text style={{ color: '#333', fontSize: 16, marginLeft: 10 }}>我的保单</Text>
</View>
<View style={{ backgroundColor: '#ccc', height: 43, width: 1 }} />
<View style={{
flex: 1,
height: 86,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<FastImage
style={{
width: 36,
height: 36,
}}
source={{
uri: `${resourceURLMapping[ENV]}insure_wodedingdan.png`,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.stretch}
/>
<Text style={{ color: '#333', fontSize: 16, marginLeft: 10 }}>我的订单</Text>
</View>
</View>
<View style={{ height: 43 }} />
<TabView
navigationState={this.state.type}
renderScene={this._renderScene}
renderTabBar={this._renderTabBar}
onIndexChange={this._handleIndexChange}
lazy
swipeEnabled={false}
swipeDistanceThreshold={global.SCREEN_WIDTH / 10}
initialLayout={{ width: global.SCREEN_WIDTH }}
/>
</View>
);
}
......@@ -91,13 +285,14 @@ class HomePage extends Component<Props> {
function actionMapping(dispatch) {
return {
push: compose(dispatch, push),
pushTo: compose(dispatch, push),
};
}
function propsMapping({ theme }) {
return {
theme,
};
}
export default connect(propsMapping, actionMapping)(HomePage);
export default connect(propsMapping, actionMapping)(PolicyPage);
/**
* Sample React Native App
* https://github.com/facebook/react-native
......@@ -7,79 +8,96 @@
*/
import React, { Component } from 'react';
import { SpringScrollView } from 'react-native-spring-scrollview';
import { CommonLottieHeader } from 'react-native-spring-scrollview/Customize/CommonLottieHeader';
//import CommonLottieFooter from 'react-native-spring-scrollview/Customize/CommonLottieFooter';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { LargeList } from 'react-native-largelist-v3';
import {
StyleSheet,
View,
TouchableOpacity,
} from 'react-native';
import { push } from '../../BasicNavigator/actions';
import { renderByType } from './serviceRenderUtil';
import NavigationBar from '../../components/NavigationBar';
import Text from '../../components/Text';
import Styles from '../../theme/Styles';
import BackButton from '../../components/BackButton';
import decorator from '../../utils/decorator';
import { validateParams, validateAllParams } from '../../utils/validate';
const data = [
{
items: [
{ name: '页面跳转', page: 'JSPage' },
{ name: '设置主题', page: 'ThemePage' },
{ name: '粘性头', page: 'SectionList' },
{ name: '瀑布流', page: 'WaterList' },
{ name: '按钮', page: 'ButtonPage' },
{ name: '头像', page: 'AvatarPage' },
{ name: '徽章', page: 'BadgePage' },
{ name: '选择框', page: 'CheckBoxPage' },
{ name: '评分', page: 'RatingPage' },
{ name: '拖吧', page: 'SliderPage' },
{ name: '气泡', page: 'TooltipPage' },
],
const data = require('./service.json');
type Props = {};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
];
});
type
Props = {
theme: Object,
pushTo: ()=> void
};
const step = 13;
class FramePage extends Component<Props> {
renderIndexPath = ({ section, row }) => {
const { theme, pushTo } = this.props;
const item = data[section].items[row];
return (
<View style={{ alignItems: 'stretch', justifyContent: 'center' }}>
<TouchableOpacity
onPress={() => pushTo(item.page)}
>
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<Text style={theme.titleText}>
{item.name}
</Text>
</View>
</TouchableOpacity>
<View style={Styles.line} />
</View>
);
@decorator
class ServicePage extends Component<Props> {
constructor(props) {
super(props);
console.log('constructor', this);
this.state = {
count: step,
allLoaded: false,
};
this.scrollView = null;
}
_onRefresh = () => {
setTimeout(() => {
this.scrollView.endRefresh();
this.setState({ count: step, allLoaded: false });
}, 3000);
};
render() {
const { theme } = this.props;
_onLoading = () => {
setTimeout(() => {
this.scrollView.endLoading();
this.setState(p => ({
count: p.count + step,
allLoaded: false,
}));
}, 3000);
};
render() {
const { pushTo } = this.props
return (
<View style={theme.container}>
<View style={[styles.container, { backgroundColor: 'white' }]}>
<NavigationBar
title="组件列表"
/>
<LargeList
style={[
theme.largeList,
{ height: global.SCREEN_HEIGHT },
]}
data={data}
heightForIndexPath={() => 50}
renderIndexPath={this.renderIndexPath}
style={{ backgroundColor: '#fff' }}
textStyle={{
color: '#333',
fontSize: 17,
fontWeight: '400',
}}
title="服务"
/>
<SpringScrollView
ref={ref => (this.scrollView = ref)}
style={[styles.container, { backgroundColor: '#F4F5F5' }]}
inverted={false}
onRefresh={this._onRefresh}
//onLoading={this._onLoading}
// allLoaded={this.state.allLoaded}
refreshHeader={CommonLottieHeader}
//loadingFooter={CommonLottieFooter}
>
{data.map((item, index) => (
renderByType(item.type)({
...item,
width: global.SCREEN_WIDTH,
pushTo,
})
))}
</SpringScrollView>
</View>
);
}
......@@ -97,4 +115,4 @@ function propsMapping({ theme }) {
};
}
export default connect(propsMapping, actionMapping)(FramePage);
export default connect(propsMapping, actionMapping)(ServicePage);
......@@ -52,7 +52,7 @@ class FramePage extends Component<Props> {
render() {
const { theme } = this.props;
const { theme,pushTo } = this.props;
const imgWidth = global.SCREEN_WIDTH - 10;
const imgHeight = (global.SCREEN_WIDTH - 10) / 345 * 160;
return (
......@@ -111,6 +111,7 @@ class FramePage extends Component<Props> {
renderByType(item.type)({
...item,
width: global.SCREEN_WIDTH,
pushTo,
})
))}
......@@ -123,7 +124,7 @@ class FramePage extends Component<Props> {
function actionMapping(dispatch) {
return {
push: compose(dispatch, push),
pushTo: compose(dispatch, push),
};
}
function propsMapping({ theme }) {
......
......@@ -32,7 +32,7 @@ import SwiperView from '../../components/Swiper';
我的
type 10 3列九宫格
type 11 带标题4列的九宫格
type 12 icon+title >
type 12 icon+title
* @type {number}
*/
const BANNER = 0;
......
......@@ -17,7 +17,7 @@
},
{
"type": 5,
"title": "理赔",
"title": "框架展示",
"backgroundColor": "#FFFFFF",
"data": [],
"icon": "",
......@@ -36,11 +36,11 @@
"data": [
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_baoan.png",
"tagUrl": "23",
"pageType": "RN",
"tagUrl": "JSPage",
"pageType": "Native",
"authorization": "",
"login": "1",
"title": "报案",
"title": "页面跳转",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -49,11 +49,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_tuanxianlipeishenqing.png",
"tagUrl": "21",
"tagUrl": "ThemePage",
"pageType": "RN",
"authorization": "1",
"login": "1",
"title": "团险理赔申请",
"title": "设置主题",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -62,11 +62,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_yiyuanchaxun.png",
"tagUrl": "31",
"tagUrl": "SectionList",
"pageType": "RN",
"authorization": "",
"login": "",
"title": "医院查询",
"title": "粘性头",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -75,11 +75,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_tuanxianlipeijindu.png",
"tagUrl": "ClaimSearch",
"tagUrl": "WaterList",
"pageType": "native",
"authorization": "1",
"login": "1",
"title": "理赔查询",
"title": "瀑布流",
"detail": "entr=renshou,caixian,yanglao,xianggang&menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -100,7 +100,7 @@
},
{
"type": 5,
"title": "养老金业务",
"title": "组件展示",
"backgroundColor": "#FFFFFF",
"data": [],
"icon": "",
......@@ -119,11 +119,11 @@
"data": [
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_wodebaozhang.png",
"tagUrl": "AssetList",
"tagUrl": "ButtonPage",
"pageType": "native",
"authorization": "1",
"login": "1",
"title": "我的养老保障",
"title": "按钮",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -132,11 +132,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_jiaofeichaxun.png",
"tagUrl": "PaymentInfo",
"tagUrl": "AvatarPage",
"pageType": "native",
"authorization": "1",
"login": "1",
"title": "缴费信息查询",
"title": "头像",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -145,11 +145,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_danweijingzhi3.png",
"tagUrl": "NetWorthQuery",
"tagUrl": "BadgePage",
"pageType": "native",
"authorization": "1",
"login": "1",
"title": "单位净值查询",
"title": "徽章",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -158,11 +158,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_jinshimanqilingqu.png",
"tagUrl": "GoldenAge",
"tagUrl": "CheckBoxPage",
"pageType": "native",
"authorization": "1",
"login": "1",
"title": "金世满期领取",
"title": "选择框",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -171,11 +171,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/icon_service_touzifenpeibiangeng.png",
"tagUrl": "FundAllocation",
"tagUrl": "RatingPage",
"pageType": "native",
"authorization": "1",
"login": "1",
"title": "投资分配变更",
"title": "评分",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -196,7 +196,7 @@
},
{
"type": 5,
"title": "港澳专区",
"title": "组件展示",
"backgroundColor": "#FFFFFF",
"data": [],
"icon": "",
......@@ -215,11 +215,11 @@
"data": [
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/xianggangtuanxian_zh3.png",
"tagUrl": "KHTClaimsChoose",
"tagUrl": "SliderPage",
"pageType": "native",
"authorization": "",
"login": "1",
"title": "太平香港团险",
"title": "拖吧",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......@@ -228,11 +228,11 @@
},
{
"imgUrl": "http://58.49.129.4/static/rn/src/img/gangaozhiyin_zh3.png",
"tagUrl": "CommonHelpQuestionhk",
"tagUrl": "TooltipPage",
"pageType": "native",
"authorization": "",
"login": "1",
"title": "港澳服务指引",
"title": "气泡",
"detail": "menu=service",
"titleColor": "#333333",
"detailColor": "",
......
......@@ -2,7 +2,7 @@
* @flow
*/
import React from 'react';
import { View, ScrollView } from 'react-native';
import { View, ScrollView, TouchableOpacity } from 'react-native';
import FastImage from 'react-native-fast-image';
import { FlatGrid } from 'react-native-super-grid';
import Text from '../../components/Text';
......@@ -88,38 +88,45 @@ export function renderGrid(props) {
console.log('renderGrid:', gridWidth);
return (
<FlatGrid
style={{ backgroundColor: props.backgroundColor, }}
style={{ backgroundColor: props.backgroundColor }}
itemDimension={gridWidth}
items={props.data}
spacing={0}
renderItem={({ item, index }) => (
<View
key={`${index}${item.imgUrl}`}
style={{
width: gridWidth - 1,
justifyContent: 'center',
alignItems: 'center',
marginVertical: 25,
<TouchableOpacity
onPress={() => {
console.log(props, item.tagUrl);
props.pushTo(item.tagUrl);
}}
>
<FastImage
style={{ width: 36, height: 36 }}
source={{
uri: item.imgUrl,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.stretch}
/>
<Text
<View
key={`${index}${item.imgUrl}`}
style={{
fontSize: 14,
color: '#333',
marginTop: 5,
width: gridWidth - 1,
justifyContent: 'center',
alignItems: 'center',
marginVertical: 25,
}}
>
{item.title}
</Text>
</View>
<FastImage
style={{ width: 36, height: 36 }}
source={{
uri: item.imgUrl,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.stretch}
/>
<Text
style={{
fontSize: 14,
color: '#333',
marginTop: 5,
}}
>
{item.title}
</Text>
</View>
</TouchableOpacity>
)}
/>
);
......@@ -127,7 +134,7 @@ export function renderGrid(props) {
export function renderOnlyTitle(props) {
return (
<View style={{ marginTop: 10, backgroundColor: '#FFF'}}>
<View style={{ marginTop: 10, backgroundColor: '#FFF' }}>
{
renderTitle(props.title)
}
......@@ -139,9 +146,9 @@ export function renderUsedList(props) {
return (
<View style={{ marginTop: 10, backgroundColor: '#FFF' }}>
{
renderTitle(props.title,)
renderTitle(props.title)
}
<View style={{height:10,backgroundColor: '#FFF'}} />
<View style={{ height: 10, backgroundColor: '#FFF' }} />
</View>
);
}
......@@ -155,7 +162,7 @@ export function renderGridWithTitle(props) {
}
<View style={{ marginVertical: 10 }}>
{
renderGrid({...props,backgroundColor: '#F7FBFF'})
renderGrid({ ...props, backgroundColor: '#F7FBFF' })
}
</View>
</View>
......@@ -163,7 +170,7 @@ export function renderGridWithTitle(props) {
}
export function renderOnlyGrid(props) {
return renderGrid({ ...props,backgroundColor: '#FFF' });
return renderGrid({ ...props, backgroundColor: '#FFF' });
}
export function renderByType(type) {
......
......@@ -3,6 +3,7 @@
*/
import React from 'react';
import {
TouchableOpacity,
View,
} from 'react-native';
import { ListItem } from 'react-native-elements';
......@@ -65,33 +66,40 @@ function renderGrid(props) {
items={props.data}
spacing={0}
renderItem={({ item, index }) => (
<View
key={`${index}${item.imgUrl}`}
style={{
width: gridwidth - 1,
justifyContent: 'center',
alignItems: 'center',
marginVertical: 10,
<TouchableOpacity
onPress={() => {
console.log(props, item.tagUrl);
props.pushTo(item.tagUrl);
}}
>
<FastImage
style={{ width: 32, height: 32 }}
source={{
uri: item.imgUrl,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.stretch}
/>
<Text
<View
key={`${index}${item.imgUrl}`}
style={{
marginTop: 5,
color: '#333',
fontSize: 12,
width: gridwidth - 1,
justifyContent: 'center',
alignItems: 'center',
marginVertical: 10,
}}
>
{item.title}
</Text>
</View>
<FastImage
style={{ width: 32, height: 32 }}
source={{
uri: item.imgUrl,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.stretch}
/>
<Text
style={{
marginTop: 5,
color: '#333',
fontSize: 12,
}}
>
{item.title}
</Text>
</View>
</TouchableOpacity>
)}
/>
</View>
......
......@@ -30,12 +30,13 @@ function JSPage(props: Props) {
useEffect(() => {
console.log('在 dep 改变时触发,若无 dep 则,每次更新组件都会触发')
const didFocus = NativeAppEventEmitter.addListener('react_navigation_onTransitionEnd_call', () => {
console.log('JSPage__didFocus');
console.log('JSPage__didFocus',props.nav);
})
return () => {
console.log('在组件 unmount 时触发');
if(didFocus){
didFocus.remove();
console.log('JSPage__didFocus.remove');
}
};
})
......
/**
* @flow
*/
import validate from './validate';
export default {
validate,
};
/**
* 此注解如果赋值的时候匹配到的类型有问题,会在控制台显示警告
* @param type CheckType 中定义的类型
* @returns {Function}
* @constructor
*/
export default function validateDecorator(type){
return function (target, name, descriptor){
let v = descriptor.initializer && descriptor.initializer.call(this);
/**
* 将属性名字以及需要的类型的对应关系记录到类的原型上
*/
if (!target.constructor.__checkers__) {
// 将这个隐藏属性定义成 not enumerable,遍历的时候是取不到的。
Object.defineProperty(target.constructor, "__checkers__", {
value: {},
enumerable: false,
writeable: true,
configurable: true
});
}
target.constructor.__checkers__[name] = {
type: type,
};
return descriptor;
};
}
......@@ -33,3 +33,15 @@ export const findPopKey = (routes: Array, pageName) => {
}
return key;
};
export const RandomNumBoth = (Min,Max) => {
const Range = Max - Min;
const Rand = Math.random();
const num = Min + Math.round(Rand * Range); //四舍五入
return num;
};
/**
* @flow
*/
import moment from 'moment';
import {
baseCoreURLMapping,
} from '../constants';
import type { ENV_TYPE } from '../constants';
export const ServiceContent = ''
export const APICodeToUrl = {
'001001': '/sysapp/getpolicylist', // 获取我的保单
'001002': '/sysapp/getpolicyDetail', // 获取保单详情
//实时贷请求
'06001': '/lifems/loan/checkLoanLimit', // 获取保单列表,额度
'06002': '/lifems/loan/policyLoanAgreementSign', // 签订可贷协议
'06003': '/lifems/kht/loan/repayLoanMent/getPolicyInfoList', // 查询还款保单列表
'06004': '/lifems/loan/checkPolicyloan', // 贷款保单列表
'06005': '/lifems/loan/queryPolicyInfoFromPolicy', // 贷款保单列表
'06006': '/lifems/queryBankInfo', // 查询还款银行
'06007': '/lifems/kht/loan/appApplyPolicyDischargeLoan', // 提交还款申请
'06008': '/lifems/queryLimitQuotaInfo', // 查询还款限额
'06009': '/lifems/kht/loan/repayLoanMent/sendVerifyCode', //发送验证码
'06010': '/lifems/kht/loan/repayLoanMent/verifyMsgCode', //验证验证码
'06011': '/lifems/loan/applyPolicyLoan', //提交贷款申请
'06012': '/lifems/kht/loan/reapy/firstPage', //查询还款
'06013': '/lifems/kht/loan/getUser/userInfo', //查询用户开户名
'06014': '/lifems/loan/queryLimitQuatoInfo', //查询贷款限额
// 理赔报案
'05001': '/pensionms/claimReport/getRiskTakerList', // 养老获取理赔服务出险人
'05003': '/pensionms/claimReport/submitClaimReport', // 养老理赔报案提交
'05005': '/lifems/claimsBusiness/getInsuredInfo', // 获取人寿报案被保人
'05006': '/lifems/claimsBusiness/claimReport', // 人寿理赔报案
'05007': '/caixianms/claimReport/queryByUserInfo', // 查询车牌、人名
'05008': '/caixianms/claimReport/queryByUserOrCar', // 财险查询
'05009': '/caixianms/claimReport/submitClaimReport', // 财险提交报案
'05010': '/pensionms/common/getHospitalList', // 获取医院列表
'05011': '/lifems/claimsBusiness/queryHospitalInfo', // 人寿根据地址获取医院列表
'05012': '/pensionms/hospitalInquiry/getHospitalInfo', // 人寿根据地址获取医院列表
//门诊
'07001': '/pensionms/claimApplicate/modifyCommonInsured', //修改常用被保险人接口
'07002': '/pensionms/claimApplicate/getCommonInsuredList', //修改常用被保人接口(删除和新增)
'07003': '/pensionms/claimApplicate/permissionCheck', //下一步权限接口(门诊选择出险人页面)
'07004': '/pensionms/claimApplicate/getHospitalCompensateList', //门诊快赔医院查询接口
'07005': '/pensionms/claimApplicate/verifyPolicyAvailable', //验证是否有可用保单接口
'07006': '/pensionms/claimApplicate/getHospitalCompensationInfo', //获取医院快赔信息接口
'07007': '/pensionms/claimApplicate/saveHospitalVisitDate', //医院和就诊日期保存接口
'07008': '/pensionms/claimApplicate/claimsControl', //理赔申请次数控制接口
'07009': '/pensionms/claimApplicate/submitClaimApplicate', //提交理赔申请
'07010': '/pensionms/claimApplicate/addClaimApplication', //新增理赔申请接口
'07011': '/pensionms/claimApplicate/getHosCardInpatientInfo', //用户卡号记录接口
'07012': '/pensionms/claimApplicate/updateHosCardInpatientInfo', //反欺诈接口记录第一次显示
'07018': '/lifems/accountChange/verifyDealPassword', //保险服务密码校验
'07021': '/pensionms/claimApplicate/imageDataProcessing', // 理赔申请异步影像上传
'07022': '/pensionms/claimApplicate/antiMoneyLaunderingInfo', // 反洗钱
// 系统
'09001': '/commonms/sys/getSystemParamsApp', //系统字典
// 文件上传
'00003': '/commonms/file/authUploadFile',
// 实名认证
'00007': '/sysapp/tencentIdascStartSign',
// 实名认证验证
'00008': '/sysapp/tencentIdascResultVerfy',
// 日志
'98001': '/log/appLog',
// 金币任务
'08001': '/campaignsms/integral/queryIntegralDetailList',
'08002': '/campaignsms/integral/queryUserPoints',
'08003': '/campaignsms/sign/signCalendar',
'08004': '/campaignsms/coin/queryTasks',
'08005': '/campaignsms/coin/queryConsumeList',
'08006': '/campaignsms/coin/coinBaseInfo',
'08007': '/campaignsms/vigorouswalk/getVigorousWalk',
'08008': '/campaignsms/vigorouswalk/updateVigorousWalkMonth',
// 在线客服
'10001': '/imms/ws/getImInfo',
'10002': '/imms/ws/sendMQ',
'10003': '/imms/ws/sendMsg',
'10004': '/imms/ws/ccchatmessage/pager',
'10005': '/imms/ws/ccchatmessage/unreadmessages',
'10006': '/imms/ws/customerServiceConnect',
'10007': '/imms/ws/customerServiceDisConnect',
// 邀请有礼
'02101': '/campaignsms/qrcode/getQrcodeInfo', //二维码
'02102': '/campaignsms/getRewardForInvit/inviteRecord', //获取被邀请人记录及邀请人奖励接口
'02103': '/campaignsms/getRewardForInvit/bindReferral', //绑定邀请人
}
export const getCoreAPIRequestUrl = ({ env = 'DEV', APICode = '' } : {
env : ENV_TYPE,
APICode : string,
}) => {
const url = APICodeToUrl[APICode]
return `${baseCoreURLMapping[env]}${url}?traceno=${moment()},}`;
};
///**
// * @flow
// */
////import _ from 'lodash'
//import moment from 'moment'
////import { Toast } from 'antd-mobile-rn'
//import DeviceInfo from 'react-native-device-info'
//import axios from 'axios'
//// import { writeLog } from '../middleware'
//import { AssetsModule, ExitRNModule } from '../native-utils'
//import { getLanuage } from '../lanuageUtils'
//import {
// getCoreAPIRequestUrl,
//} from './APIConfig'
//import { ENV, ppkVersion } from '../constants'
//import responseCode from '../responseCode'
//
//export const APIDeps = {
// sessionid: '',
// ppkPath: '',
// deviceInfo: {},
// mobile: '',
// agentcode: '',
// employno: '',
// accesstokeninfo: '',
// source: null,
//}
//
//let accesstokeninfo = ''
//
//axios.interceptors.request.use(config => {
// //console.log(config)
// if (config.config.shouldLoading) {
// AssetsModule.showToast('拼命加载中')
// }
// return config
//},
//err => {
// AssetsModule.showToast('拼命加载中')
// const msg = responseCode.networkError
// Toast.show(msg, Toast.SHORT)
// return Promise.reject(err)
//})
//
//axios.interceptors.response.use(response => {
// //console.log(response)
// if (response.config.config.hiddenLoading) {
// AssetsModule.dismisToast()
// }
// if (response.data.code === '0000') {
// return response
// } else if (responseCode.businessError.indexOf(response.data.code) !== -1) {
// if (AssetsModule.sendNeedLoginCode) {
// AssetsModule.sendNeedLoginCode(response.data.code)
// }
// return Promise.resolve(response)
// } else if (responseCode.needExitError.indexOf(response.data.code) !== -1) {
// Toast.show(response.data.desc, Toast.SHORT)
// ExitRNModule.exitRN()
// //return Promise.resolve(response)
// } else if (response.data.code[0] === '9') {
// if (response.config.config.shouldHandleError) {
// Toast.show(responseCode.systemError, Toast.SHORT)
// }
// return Promise.resolve(response)
// } else if (Number(response.data.code[0]) >= 0 && Number(response.data.code[0]) <= 8) {
// if (response.config.config.shouldHandleError) {
// Toast.show(response.data.desc, Toast.SHORT)
// }
// return Promise.resolve(response)
// }
// if (response.config.config.shouldHandleError) {
// Toast.show(responseCode.systemError, Toast.SHORT)
// }
// return Promise.resolve(response)
//}, err => {
// AssetsModule.dismisToast()
// if (err.message === '用户取消') {
// return Promise.resolve(err.response)
// }
// if (err.toString().indexOf('Network') !== -1) {
// Toast.show(responseCode.networkError, Toast.SHORT)
// return Promise.resolve(err.response)
// }
// Toast.show(responseCode.networkError, Toast.SHORT)
// return Promise.resolve(err.response)
//})
//
//export async function fetchCoreAPI(APICode, {
// params,
// method = 'POST',
// shouldHandleError = true,
// shouldLoading = true, // 是否显示loading(非必传,默认为true)
// hiddenLoading = true,
// requestTimeout = 30 * 1000,
// }
//) {
// let url = getCoreAPIRequestUrl({ env: ENV, APICode })
// const language = await getLanuage()
// url = `${url}&language=${language}`
// const CancelToken = axios.CancelToken
// //console.log('url =', url)
// APIDeps.source = CancelToken.source()
// accesstokeninfo = await AssetsModule.getStorageValue('authToken')
// let data
// if (params) {
// data = JSON.stringify(params)
// }
// const config = {
// method,
// data,
// headers: {
// 'Content-Type': 'application/json;charset=UTF-8',
// 'x-ac-app-version': DeviceInfo.getVersion() || '',
// 'x-ac-channel-id': 'KHT',
// 'x-ac-device-id': DeviceInfo.getUniqueID() || '',
// 'x-ac-os-info': DeviceInfo.getUserAgent(),
// 'x-ac-ppk-version': ppkVersion,
// 'x-ac-sign': 'RNRNRNRNRNRN',
// 'x-ac-time': `${moment()}`,
// 'Accept': 'application/json;charset=UTF-8',
// 'x-ac-token-ticket': accesstokeninfo,
// },
// timeout: requestTimeout,
// cancelToken: APIDeps.source.token,
// config: {
// shouldHandleError,
// shouldLoading,
// hiddenLoading,
// },
// }
// if (method === 'GET' && !params) {
// delete (config.data)
// }
// // console.log('token:', accesstokeninfo)
// // console.log('请求参数:', config.data)
// // console.log('请求参数:', JSON.stringify(config.data))
//
// return new Promise((resolve, reject) => {
// axios(url, config)
// .then(response => {
// if (response && response.data && response.data.code === '0000') {
// // console.log('response:', response)
// resolve(response.data)
// } else if (response && response.data) {
// resolve(response.data)
// } else {
// resolve([])
// }
// })
// .catch(error => {
// Toast.show(responseCode.systemError, Toast.SHORT)
// reject(error)
// })
// })
//}
/**
* @flow
*/
import moment from 'moment';
import DeviceInfo from 'react-native-device-info';
import axios from 'axios';
import {
getCoreAPIRequestUrl,
} from './APIConfig';
import { ENV, ppkVersion, MOCK } from '../constants';
import responseCode from './responseCode';
import { AssetsModule } from '../native-utils';
import toast from '../../components/Toast';
import mockUtil from './mockUtil';
export const APIDeps = {
sessionid: '',
ppkPath: '',
deviceInfo: {},
mobile: '',
source: null,
loadingQueue: 0,
};
function showToast() {
APIDeps.loadingQueue += 1;
console.log('拼命加载中');
//AssetsModule.showToast('拼命加载中');
}
function dismissToast() {
APIDeps.loadingQueue = Math.max(0, APIDeps.loadingQueue - 1);
if (APIDeps.loadingQueue === 0) {
console.log('关闭转圈');
//AssetsModule.dismissToast();
}
}
axios.interceptors.request.use((config) => {
//console.log(config)
if (config.config.shouldLoading) {
showToast();
}
return config;
},
(err) => {
showToast();
const msg = responseCode.networkError;
toast(msg);
return Promise.reject(err);
});
axios.interceptors.response.use((response) => {
//console.log(response)
if (response.config.config.hiddenLoading) {
dismissToast();
}
if (response.data.code === '0000') {
return response;
} if (responseCode.businessError.indexOf(response.data.code) !== -1) {
//跳转登录
return Promise.resolve(response);
} if (response.data.code[0] === '9') {
if (response.config.config.shouldHandleError) {
toast(responseCode.systemError);
}
return Promise.resolve(response);
} if (Number(response.data.code[0]) >= 0 && Number(response.data.code[0]) <= 8) {
if (response.config.config.shouldHandleError) {
toast(response.data.desc);
}
return Promise.resolve(response);
}
if (response.config.config.shouldHandleError) {
toast(responseCode.systemError);
}
return Promise.resolve(response);
}, (err) => {
dismissToast();
if (err.message === '用户取消') {
return Promise.resolve(err.response);
}
if (err.toString().indexOf('Network') !== -1) {
toast(responseCode.networkError);
return Promise.resolve(err.response);
}
toast(responseCode.networkError);
return Promise.resolve(err.response);
});
export async function fetchCoreAPI(APICode, {
params,
method = 'POST',
shouldHandleError = true,
shouldLoading = true, // 是否显示loading(非必传,默认为true)
hiddenLoading = true,
requestTimeout = 30 * 1000,
}) {
const url = getCoreAPIRequestUrl({ env: ENV, APICode });
const { CancelToken } = axios;
//console.log('url =', url)
APIDeps.source = CancelToken.source();
let data;
if (params) {
data = JSON.stringify(params);
}
const config = {
method,
data,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'x-ac-app-version': DeviceInfo.getVersion() || '',
'x-ac-channel-id': 'channel',
'x-ac-device-id': DeviceInfo.getUniqueID() || '',
'x-ac-os-info': DeviceInfo.getUserAgent(),
'x-ac-ppk-version': ppkVersion,
'x-ac-sign': 'RNRNRNRNRNRN',
'x-ac-time': `${moment()}`,
'Accept': 'application/json;charset=UTF-8',
'x-ac-token-ticket': 'accesstokeninfo',
},
timeout: requestTimeout,
cancelToken: APIDeps.source.token,
config: {
shouldHandleError,
shouldLoading,
hiddenLoading,
},
APICode,
};
if (method === 'GET' && !params) {
delete (config.data);
}
console.log('请求参数:', config.data);
// console.log('请求参数:', JSON.stringify(config.data))
//mock
if (MOCK) {
if (config.config.shouldLoading) {
showToast();
}
return new Promise((resolve, reject) => {
mockUtil(url, config,
(responseData) => {
console.log('incallback_responseData', responseData);
resolve({ code: '0000', data: responseData });
if (config.config.shouldLoading) {
dismissToast();
}
});
});
}
return new Promise((resolve, reject) => {
axios(url, config)
.then((response) => {
if (response && response.data && response.data.code === '0000') {
// console.log('response:', response)
resolve(response.data);
} else if (response && response.data) {
resolve(response.data);
} else {
resolve([]);
}
})
.catch((error) => {
toast(responseCode.systemError);
reject(error);
});
});
}
// @flow
export default {
// 本地假数据
user: [{
uid: 'u0000001',
name: '江渔剑',
userName: '18588880005',
pwd: '123456',
}],
policy: [
{
uid: 'u0000001',
policyId: 'p000001',
company: '太平人寿',
companyColor: ['#3DC69D', '#69D5AF'],
policyNo: 'TX20190701000210',
productName: '驾年华两全',
insured: '江渔剑',
applicant: '江渔剑',
duration: '2019-7-01 至 2020-7-01',
status: '保障中',
productStatus: '有效',
amount: '500000元',
premium: '2320元',
date: '2019年7月1日',
nextDate: '2020年7月2日',
birthday: '1980年1月1日',
gender: '男',
idno: '31029******7792',
mobile: '18588880005',
},
{
uid: 'u0000001',
policyId: 'p000003',
company: '太平财险',
productName: '机动车商业险',
companyColor: ['#60A1FA', '#7CC6FF'],
policyNo: 'TX20190511000201',
insured: '江渔剑',
applicant: '江渔剑',
duration: '2019-5-11 至 2020-5-11',
status: '保障中',
productStatus: '有效',
amount: '1000000元',
premium: '3520元',
date: '2019年5月11日',
nextDate: '2020年5月12日',
birthday: '1980年1月1日',
gender: '男',
idno: '31029******7792',
mobile: '18588880005',
},
],
orders: [{
}],
product: [
{
blueId: '2001',
company: 'PROPERTY',
iconUrl: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=435466660,1319228756&fm=26&gp=0.jpg',
detail: {
name: '“驾乘至尊宝”驾乘人员人身意外综合保险',
description: '不限被保险人、最高50万保障',
detailsPageWxshareUrl: '',
guaranteeContent: '[{"text":[{"name":"驾乘意外身故、残疾","value":"25万元/份"},{"name":"驾乘意外伤害医疗","value":"1万元/份"}]},{"text":[{"name":"驾乘意外身故、残疾","value":"50万元/份"},{"name":"驾乘意外伤害医疗","value":"3万元/份"}]}]',
bannerIconUrl: 'https://58.49.129.4/static/insurance_img/201901/01/dbf8648cdca04b20af889f07e3938b5f.png',
productIntroductionUrl: 'https://58.49.129.4/static/insurance_img/201906/11/1755eb7f49934157b6fc65f09ef9015a.png',
serviceProcessUrl: 'https://58.49.129.4/static/insurance_img/201906/11/2c0eb0145bf1498bb677897a8b03b179.png',
importantNotificationUrl: '',
tagNameList: [
'1-75周岁',
],
},
},
{
blueId: '200000156',
company: 'PROPERTY',
iconUrl: 'https://58.49.129.4/static/insurance_img/201906/03/1babf50701374e79b2d0e1758d7e6d42.png',
detail: {
name: '“驾乘至尊宝”驾乘人员人身意外综合保险',
description: '不限被保险人、最高50万保障',
detailsPageWxshareUrl: '',
guaranteeContent: '[{"text":[{"name":"驾乘意外身故、残疾","value":"25万元/份"},{"name":"驾乘意外伤害医疗","value":"1万元/份"}]},{"text":[{"name":"驾乘意外身故、残疾","value":"50万元/份"},{"name":"驾乘意外伤害医疗","value":"3万元/份"}]}]',
bannerIconUrl: 'https://58.49.129.4/static/insurance_img/201901/01/dbf8648cdca04b20af889f07e3938b5f.png',
productIntroductionUrl: 'https://58.49.129.4/static/insurance_img/201906/11/1755eb7f49934157b6fc65f09ef9015a.png',
serviceProcessUrl: 'https://58.49.129.4/static/insurance_img/201906/11/2c0eb0145bf1498bb677897a8b03b179.png',
importantNotificationUrl: '',
tagNameList: [
'1-75周岁',
],
},
},
{
blueId: '200000155',
company: 'PENSION',
iconUrl: 'https://58.49.129.4/static/insurance_img/201906/03/fd0db92ce55645b3b00c4035d25902c7.png',
detail: {
name: '“驾乘至尊宝”驾乘人员人身意外综合保险',
description: '不限被保险人、最高50万保障',
detailsPageWxshareUrl: '',
guaranteeContent: '[{"text":[{"name":"驾乘意外身故、残疾","value":"25万元/份"},{"name":"驾乘意外伤害医疗","value":"1万元/份"}]},{"text":[{"name":"驾乘意外身故、残疾","value":"50万元/份"},{"name":"驾乘意外伤害医疗","value":"3万元/份"}]}]',
bannerIconUrl: 'https://58.49.129.4/static/insurance_img/201901/01/dbf8648cdca04b20af889f07e3938b5f.png',
productIntroductionUrl: 'https://58.49.129.4/static/insurance_img/201906/11/1755eb7f49934157b6fc65f09ef9015a.png',
serviceProcessUrl: 'https://58.49.129.4/static/insurance_img/201906/11/2c0eb0145bf1498bb677897a8b03b179.png',
importantNotificationUrl: '',
tagNameList: [
'1-75周岁',
],
},
},
{
blueId: '200000152',
company: 'LIFE',
iconUrl: 'https://58.49.129.4/static/insurance_img/201906/03/dac832df067341aa958e417b909573c9.png',
detail: {
name: '“驾乘至尊宝”驾乘人员人身意外综合保险',
description: '不限被保险人、最高50万保障',
detailsPageWxshareUrl: '',
guaranteeContent: '[{"text":[{"name":"驾乘意外身故、残疾","value":"25万元/份"},{"name":"驾乘意外伤害医疗","value":"1万元/份"}]},{"text":[{"name":"驾乘意外身故、残疾","value":"50万元/份"},{"name":"驾乘意外伤害医疗","value":"3万元/份"}]}]',
bannerIconUrl: 'https://58.49.129.4/static/insurance_img/201901/01/dbf8648cdca04b20af889f07e3938b5f.png',
productIntroductionUrl: 'https://58.49.129.4/static/insurance_img/201906/11/1755eb7f49934157b6fc65f09ef9015a.png',
serviceProcessUrl: 'https://58.49.129.4/static/insurance_img/201906/11/2c0eb0145bf1498bb677897a8b03b179.png',
importantNotificationUrl: '',
tagNameList: [
'1-75周岁',
],
},
},
],
};
/**
* @flow
*/
import { RandomNumBoth } from '../Tool';
import localData from './localData';
// 获取用户保单列表
function get001001(data) {
const { policy } = localData;
const param = JSON.parse(data);
const result = [];
console.log('policy:',policy)
console.log('data:',param)
policy.forEach((item) => {
if (item.uid === param.uid) {
result.push(item);
}
});
return result;
}
//获取保单详情
function get001002() {
}
const mockMap = {
'001001': get001001,
'001002': get001002,
};
export default function getMockData(url, config, callback) {
console.log('getMockData:', url, config);
const time = RandomNumBoth(1, 3);
// 随机暂停 1 - 3秒
console.log('模拟请求:', time, '秒');
setTimeout(
() => {
const result = mockMap[config.APICode](config.data)
console.log('result:',result)
callback(result);
},
time * 1000,
);
}
/**
* @flow
*/
const responseCode = {
businessError: ['9794', '9894', '9896', '9797', '9796', '9795', '9793'],
networkError: '网络繁忙,请稍后再试',
systemError: '系统繁忙,请稍后再试',
needExitError: ['9012', '9014'],
};
export default responseCode;
/**
* @flow
*/
/**
* 过滤数组
* @param arr
* @returns {*}
*/
export function arrFilter(arr) {
if (arr) {
const result = arr.filter(function (element, index, self) {
console.log(element); // 依次打印'A', 'B', 'C'
console.log(index); // 依次打印0, 1, 2
console.log(self); // self就是变量arr
return true;
});
return result
}
return arr
}
/**
* 检测数组所有元素是否都符合指定条件
* @param arr
*/
export function arrEvery(arr,callback) {
arr.every(function(currentValue,index,arr){
}, callback)
}
......@@ -4,54 +4,60 @@
import React from 'react';
export const MOCK = true;
export type ENV_TYPE = 'SIT' | 'UAT' | 'PRO'
export const ENV = 'SIT'
export const ENV = 'SIT';
//export const ENV = 'UAT'
//export const ENV = 'PRO'
//默认路由
export const initialRouteName = 'TabPage'
export const RootPageInitialName = 'HomePage'
export const initialRouteName = 'TabPage';
export const RootPageInitialName = 'HomePage';
// 最后更新日期,用于在‘关于’页面显示
export const ppkVersion = '1'
export const ppkVersion = '1';
export const baseCoreURLMapping = {
SIT: 'http://58.49.129.4/sit',
UAT: 'http://58.49.129.4',
SIT: 'https://ecustomer.tp95589.com/sit',
UAT: 'https://ecustomer.tp95589.com',
PRO: 'https://ecustomer.cntaiping.com',
}
};
export const htmlURLMapping = {
SIT: 'http://smarket.tp95589.com',
UAT: 'http://smarket.tp95589.com',
PRO: 'http://mall.itaiping.com',
}
SIT: 'https://smarket.tp95589.com',
UAT: 'https://smarket.tp95589.com',
PRO: 'https://mall.itaiping.com',
};
export const staticResourceMapping = {
SIT: 'http://58.49.129.4/sit',
UAT: 'http://58.49.129.4',
SIT: 'https://ecustomer.tp95589.com/sit',
UAT: 'https://ecustomer.tp95589.com',
PRO: 'https://ecustomer.cntaiping.com',
}
};
export const resourceURLMapping = {
SIT: `${staticResourceMapping.UAT}/static/rn/src/img/`,
UAT: `${staticResourceMapping.UAT}/static/rn/src/img/`,
PRO: `${staticResourceMapping.PRO}/static/rn/src/img/`,
}
};
export const wxUserNameMapping = {
SIT: 'gh_b0cac2def4b1',
UAT: 'gh_b0cac2def4b1',
PRO: 'gh_104e2261b2fc',
}
SIT: 'gh_b0cac',
UAT: 'gh_b0cac',
PRO: 'gh_104e',
};
export function updateInfoURL(env?: ENV_TYPE = ENV) {
return `${staticResourceMapping[String(env)]}/rn/updateIXX.json?ver=${Math.random()}`
return `${staticResourceMapping[String(env)]}/rn/updateIXX.json?ver=${Math.random()}`;
}
export const StoreContext = React.createContext({});
export const appFileDir = () => 'com.basic';
export default {
baseCoreURLMapping,
};
/**
* @flow
* 此注解如果赋值的时候匹配到的类型有问题,会在控制台显示警告
* @param type CheckType 中定义的类型
* @returns {Function}
* @constructor
*/
import React, { Component, Fragment } from 'react';
/**
* 这里是真正的 decorator
* @target 装饰的属性所述的类的原型,注意,不是实例后的类。如果装饰的是 Car 的某个属性,这个 target 的值就是 Car.prototype
* @name 装饰的属性的 key
* @descriptor 装饰的对象的描述对象
*/
// function d(target, name, descriptor){
// // 以此可以获取实例化的时候此属性的默认值
// let v = descriptor.initializer && descriptor.initializer.call(this);
// // 返回一个新的描述对象,或者直接修改 descriptor 也可以
// return {
// enumerable: true,
// configurable: true,
// get: function() {
// return v;
// },
// set: function(c) {
// v = c;
// }
// }
//}
function decorator(Comp) {
if(typeof Comp === 'function'){
console.log('isFunction')
return Comp;
}
class WrapComp extends Component {
componentDidMount() : void {
console.log('WrapComp_name', Comp.name);
console.log('WrapComp_componentDidMount', Comp);
}
render() {
return (
<Fragment>
<Comp {...this.props} />
</Fragment>
);
}
}
return (WrapComp);
}
export default decorator;
/**
* @flow
*/
import _ from 'lodash'
import { applyMiddleware } from 'redux'
import _ from 'lodash';
import { applyMiddleware } from 'redux';
//import stringify from 'json-stringify-safe'
import Alert from './Alert'
import toast from '../components/Toast';
//import { startLoading, finishLoading } from '../actions/loading'
function thunkState({ dispatch, getState }) {
return next => action => {
return next => (action) => {
try {
if (getState().loading.loadingQueue.length <= 0) {
//dispatch(finishLoading())
......@@ -19,33 +19,33 @@ function thunkState({ dispatch, getState }) {
//dispatch(finishLoading())
}
if (action && typeof action === 'function') {
return dispatch(action(getState()))
return dispatch(action(getState()));
}
return next(action)
}
return next(action);
};
}
function promise({ dispatch }) {
return next => action => {
return next => (action) => {
if (action && typeof action.then === 'function') {
//dispatch(startLoading())
const finishLoadingAndDispatch = (input) => {
//dispatch(finishLoading())
dispatch(input)
}
return action.then(finishLoadingAndDispatch).catch(finishLoadingAndDispatch)
dispatch(input);
};
return action.then(finishLoadingAndDispatch).catch(finishLoadingAndDispatch);
}
return next(action)
}
return next(action);
};
}
function multiDispatcher({ dispatch }) {
return next => actions => {
return next => (actions) => {
if (Array.isArray(actions)) {
return actions.map(action => dispatch(action))
return actions.map(action => dispatch(action));
}
return next(actions)
}
return next(actions);
};
}
//export function writeLog(msg:string) {
......@@ -59,33 +59,33 @@ function multiDispatcher({ dispatch }) {
// }
//}
function errorHandler({ dispatch }) {
return next => action => {
return next => (action) => {
if (action instanceof Error) {
const chinesePatten = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/gi
const msg = action.message || ''
const chinesePatten = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/gi;
const msg = action.message || '';
const isFaceBookError = (msg || '').toLowerCase().includes('facebook.github.io')
const isFaceBookError = (msg || '').toLowerCase().includes('facebook.github.io');
if (!isFaceBookError) {
const position = ['\npos:{ line:', action.line, ',col:', action.column, ' }']
const devMsg = [msg, ...position].join('')
const position = ['\npos:{ line:', action.line, ',col:', action.column, ' }'];
const devMsg = [msg, ...position].join('');
if (__DEV__) {
Alert.alert('', devMsg)
toast(devMsg);
} else if (chinesePatten.test(msg)) {
Alert.alert('', msg)
toast(msg);
}
//logger({ error: true, message: devMsg, action })
}
// writeLog(msg)
return action
return action;
}
try {
return next(action)
return next(action);
} catch (error) {
return dispatch(error)
return dispatch(error);
}
}
};
}
//
//function logTracker({ getState }) {
......@@ -112,19 +112,19 @@ function errorHandler({ dispatch }) {
// }
//}
const filterNil = () => (next) => (action) => {
const filterNil = () => next => (action) => {
if (action != null) {
next(action)
next(action);
}
}
};
const businessHandle = ({ dispatch }) => (next) => (action) => {
const businessHandle = ({ dispatch }) => next => (action) => {
if (action && !_.isEmpty(action.action)) {
// writeLog(`actionId:${action.action} actionName: ${action.name}`)
return dispatch(action.method(action.params))
return dispatch(action.method(action.params));
}
return next(action)
}
return next(action);
};
export default applyMiddleware(
multiDispatcher,
......@@ -133,4 +133,4 @@ export default applyMiddleware(
thunkState,
filterNil,
businessHandle,
)
);
......@@ -4,5 +4,5 @@
import { NativeModules } from 'react-native';
//export const ShareModule = NativeModules.nShareModel
export const AssetsModule = NativeModules.AssetsModule
//export const ExitRNModule = NativeModules.ExitRNRootView
/**
* @flow
*/
import React from 'react';
const checkFuns = {
userNum,
};
function userNum(param) {
console.log('userNum', param);
if (param < 1) {
return '<2';
}
return '';
}
function checkParams(funName, params) {
const msg = checkFuns[funName] ? checkFuns[funName](params[funName]) : '';
return msg;
}
function getKeys(param) {
const keys = []
for (let i in param) {
keys.push(i); //属性
//arr.push(obj[i]); //值
}
return keys
}
export const validateParams = (fun, params, errCallback = () => {}) => {
console.log('validateParams_in', getKeys(params) )
if (params && getKeys(params)) {
let msg = '';
getKeys(params).some((element, index, self) => {
msg = checkParams(element, params);
return !!msg;
});
console.log('validateParams',msg)
return msg ? () => errCallback(msg) : () => fun(params);
}
return () => fun(params);
}
export function validateAllParams(fun, params, errCallback = () => {}) {
if (params && getKeys(params)) {
const messages = [];
getKeys(params).forEach((element) => {
const msg = checkParams(element, params);
if (msg) {
messages.unshift(msg);
}
});
return messages.length > 0 ? () => errCallback(messages) : fun;
}
return () => fun(params);
}
export default {
validateParams,
validateAllParams,
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment