React Native 版本执行0.57的规则
第一版设计需求是点击个人总览信息跳入订单详情页面,比较好处理,首先得到用户总览信息,通过制定参数得到订单列表数据,数据结构如下图
第二版设计需求是,总览信息与订单列表一块显示,就需要整合数据结构,将两者整合到一块便于页面渲染
import React, { Component } from 'react';
import { StyleSheet, Text, View, FlatList, Image, Modal, TouchableOpacity, StatusBar } from 'react-native';
import Nav from '../../components/Nav';
import { CachedImage } from "react-native-img-cache";
import Fetch from '../../network/Fetch'
import Loading from '../../components/Loading'; // 加载层
import { requestUrl } from '../../network/Url';// 请求url
import LoadingMore from '../../components/LoadingMore';
export default class AllProfit extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
source: "", //TAB来源
checkYear: 0, //保存入参年份
infoData: [], //保存用户信息
saveInfoData: [], //保存商品列表
dataFlag: true,// 是否还有下一页
isRefresh: false,// 加载图标
}
}
componentDidMount() {
let newDate = new Date();
let year = newDate.getFullYear();
this.setState({
checkYear: year
})
this._waitProfit(year)
}
componentWillMount() {
if (this.props.navigation.state.params) {
this.setState({
source: this.props.navigation.state.params.source
})
}
}
render() {
const { goBack } = this.props.navigation;
return (
<View style={styles.container}>
<StatusBar
animated={true}//是否动画
hidden={false}//是否隐藏
backgroundColor={'#000'}//android 设置状态栏背景颜色
translucent={false}//android 设置状态栏是否为透明
showHideTransition="fade"//IOS状态栏改变时动画 fade:默认 slide
networkActivityIndicatorVisible={this.state.isLoading}//IOS设定网络活动指示器(就是那个菊花)是否显示在状态栏。
statusBarStyle={"default"}//状态栏样式 default 默认(IOS为白底黑字、Android为黑底白字)
barStyle={"default"}// 状态栏文本的颜色。
/>
<Nav title={this.state.source == "All" ? "总收益详情" : "待收益详情"} leftClick={() => { goBack() }} />
{/* 收益列表 */}
<FlatList
style={styles.FlatListStyle}// 样式
data={this.state.saveInfoData}// 数据源
initialNumToRenƒder={10}//
keyExtractor={(item, index) => index.toString()}
ListFooterComponent={() => {
return (
<LoadingMore dataFlag={this.state.dataFlag} dataLength={this.state.saveInfoData.length} />
)
}}// 尾部组件
renderItem={({ item }) => this.renderItem(item)}// 渲染
onRefresh={() => {
this.setState({
saveInfoData: [],
onEndReached: false,
})
let newDate = new Date();
let year = newDate.getFullYear();
this._waitProfit(year)
}}//头部刷新组件
refreshing={this.state.isLoading}//加载图标
onEndReached={() => this.onEndReached()} // 加载更多
onEndReachedThreshold={0.1}// 加载更多触发时机
ListEmptyComponent={() => {
// 无数据时显示的内容
return (
!this.state.dataFlag && this.state.saveInfoData.length <= 0 ?
<View style={styles.profitList}>
<Text style={{ textAlign: "center" }}>暂无收益信息</Text>
</View>
: null
)
}}
/>
{/* 加载loading */}
{this.state.isLoading ? <Loading /> : null}
</View>
);
}
//列表
renderItem = (item) => {
return (
<View>
<View style={{ backgroundColor: Colors.mainBg }}>
<Text style={styles.monthTxt}>{item.year}年{item.month}月{this.state.source == "All" ? "共¥" + (item.sumPrice / 100).toFixed(2) : null}</Text>
</View>
<View style={styles.info}>
<CachedImage style={styles.personInfoImg} source={item.head_url ? { uri: item.head_url } : require('../../images/logo.jpeg')} />
<View style={styles.infoTop}>
<View>
<Text style={styles.infoTopTxt}>{item.nick_name}</Text>
{/* <Text style={styles.dateTxt}>购买时间:{item.create_time}</Text> */}
</View>
<Text style={styles.infoTopPrice}>共:{(item.sumPrice / 100).toFixed(2)}</Text>
</View>
</View>
{
item.goodsMap && item.goodsMap.map((items, ind) => {
return (
<View style={[styles.profitList]} key={ind}>
{
items.detail.map((i, indexs) => {
return (
<View style={styles.infoBox} key={indexs}>
<CachedImage style={{ width: Px2dp(70), height: Px2dp(70) }} source={{ uri: i.list_image }} />
<View>
<Text numberOfLines={2} style={styles.infoBoxTxt}>{i.goods_name}</Text>
<Text style={styles.infoBoxTxtSx}>规格:{i.shuxin}</Text>
</View>
<View>
<Text style={styles.infoBoxPrice}>¥{(i.price / 100).toFixed(2)}</Text>
<Text style={styles.infoBoxMoney}>+¥{(i.earn / 100).toFixed(2)}</Text>
</View>
</View>
)
})
}
</View>
)
})
}
</View>
)
}
onEndReached() {
if (this.state.dataFlag) {
let year = this.state.checkYear * 1 - 1;
this._waitProfit(year)
}
}
//待收益表头
_waitProfit(checkVal) {
if (checkVal == 2016) {
this.setState({
dataFlag: false
})
return true
}
console.log(checkVal)
Fetch(requestUrl, {
"userId": id,
"role": "person",
"param": String(checkVal),
}).then(data => {
console.log(data)
if (data.status == "SUCCESS") {
if (data.data.length > 0) {
for (let i = 0; i < data.data.length; i++) {
this._profitList(data.data[i].year, data.data[i].month)
}
this.setState({
isLoading: false,
infoData: data.data,
dataFlag: true
})
}
else {
this.setState({
dataFlag: false
})
}
} else if (data.status == "ERROR") {
this.setState({
isLoading: false,
})
ToastShow({ "text": '获取待收益数据接口失败' })
} else {
this.setState({
isLoading: false,
})
}
})
}
//待收益商品列表
_profitList(year, month) {
Fetch(requestUrl, {
"userId": id,
"year": year,
"role": "person",
"month": month
}).then(data => {
console.log(data)
if (data.status == "SUCCESS") {
let tempArr = this.state.infoData;
for (let i = 0; i < tempArr.length; i++) {
if (year == tempArr[i].year && month == tempArr[i].month) {
tempArr[i]["goodsMap"] = data.data;
this.setState({
saveInfoData: tempArr,
})
}
}
} else if (data.status == "ERROR") {
this.setState({
isLoading: false,
})
ToastShow({ "text": '获取个人收益订单列表接口失败' })
} else {
this.setState({
isLoading: false,
})
}
})
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.mainBg,
},
//收益列表
FlatListStyle: {
flex: 1,
backgroundColor: "#fff",
},
monthTxt: {
fontSize: Px2dp(14),
color: Colors.text666,
lineHeight: Px2dp(20),
marginBottom: Px2dp(8),
marginTop: Px2dp(16),
paddingLeft: Px2dp(16)
},
profitList: {
paddingLeft: Px2dp(16),
paddingRight: Px2dp(16),
},
info: {
flexDirection: "row",
paddingLeft: Px2dp(16),
paddingRight: Px2dp(16),
paddingTop: Px2dp(16)
},
personInfoImg: {
width: Px2dp(44),
height: Px2dp(44),
backgroundColor: Colors.white,
borderRadius: Px2dp(22),
marginRight: Px2dp(10)
},
infoTop: {
flexDirection: "row",
flex: 1,
justifyContent: "space-between",
borderBottomWidth: Pixel,
borderBottomColor: "#ececec"
},
infoTopTxt: {
fontSize: Px2dp(15),
color: Colors.text333,
},
infoTopPrice: {
fontSize: Px2dp(16),
color: Colors.red,
textAlign: "right"
},
dateTxt: {
fontSize: Px2dp(12),
color: Colors.text999,
marginTop: Px2dp(4),
lineHeight: Px2dp(17)
},
infoBox: {
flexDirection: "row",
justifyContent: 'space-between',
marginTop: Px2dp(10),
marginBottom: Px2dp(10)
},
infoBoxTxt: {
fontSize: Px2dp(14),
color: Colors.text333,
lineHeight: Px2dp(20),
width: Px2dp(180),
marginBottom: Px2dp(10)
},
infoBoxPrice: {
fontSize: Px2dp(13),
color: Colors.text666,
lineHeight: Px2dp(18),
textAlign: "right"
},
infoBoxMoney: {
fontSize: Px2dp(15),
color: Colors.red,
lineHeight: Px2dp(21),
marginTop: Px2dp(31),
textAlign: "right"
},
infoBoxTxtSx: {
fontSize: Px2dp(12),
color: Colors.text666,
lineHeight: Px2dp(17)
},
// 选择年份
maskClick: {
flex: 1,
backgroundColor: Colors.maskColor,
justifyContent: 'flex-end',
},
OptionBoxTit: {
fontSize: Px2dp(15),
color: Colors.text333,
marginTop: Px2dp(24),
textAlign: "center",
marginBottom: Px2dp(16)
},
OptionBoxs: {
flexDirection: "row",
alignItems: "center",
borderColor: '#ececec',
borderBottomWidth: Pixel,
height: Px2dp(40)
},
OptionBox: {
justifyContent: "center",
paddingLeft: Px2dp(16),
paddingRight: Px2dp(16),
paddingBottom: TabBar,
position: "relative",
backgroundColor: Colors.white,
},
OptionBoxTxt: {
fontSize: Px2dp(15),
color: Colors.text333,
flex: 1,
},
closeImg: {
position: "absolute",
top: Px2dp(16),
right: Px2dp(6),
padding: Px2dp(10),
justifyContent: "center",
alignItems: "center"
},
});
新版总收益与待收益页面,加入分页功能,因为无法统计一页返回多少条数据,每一页代表一个月份,返回的是一个对象,所有就的把返回的数据整合到一个数组里面。
import React, { Component } from 'react';
import { StyleSheet, Text, View, FlatList, Image, Modal, TouchableOpacity, StatusBar } from 'react-native';
import Nav from '../../components/Nav';
import { CachedImage } from "react-native-img-cache";
import Fetch from '../../network/Fetch'
import Loading from '../../components/Loading'; // 加载层
import { requestUrl } from '../../network/Url';// 请求url
import LoadingMore from '../../components/LoadingMore';
import NoNetwork from '../../components/NoNetwork';
import * as Public from '../../utils/Public';
import StatusBarModule from '../../components/StatusBarModule';
export default class AllProfit extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
source: "", //TAB来源
infoData: {}, //保存用户信息
saveInfoData: [], //保存商品列表
dataFlag: true,// 是否还有下一页
isRefresh: false,// 加载图标
networkFlag: true,// 网络是否畅通
pageNum: 1,// 页码
}
}
componentDidMount() {
this._getEarnOrder(this.state.pageNum, this.state.source == "All" ? "0" : "1")
}
componentWillMount() {
if (this.props.navigation.state.params) {
this.setState({
source: this.props.navigation.state.params.source
})
}
}
render() {
const { goBack } = this.props.navigation;
return (
<View style={styles.container}>
<StatusBarModule isLoading={this.state.isLoading} />
<Nav title={this.state.source == "All" ? "总收益详情" : "待收益详情"} leftClick={() => { goBack() }} />
{/* 收益列表 */}
{
this.state.networkFlag ?
<FlatList
style={styles.FlatListStyle}// 样式
data={this.state.saveInfoData}// 数据源
initialNumToRenƒder={10}//
keyExtractor={(item, index) => index.toString()}
ListFooterComponent={() => {
return (
<LoadingMore dataFlag={this.state.dataFlag} dataLength={this.state.saveInfoData.length} />
)
}}// 尾部组件
renderItem={({ item }) => this.renderItem(item)}// 渲染
onRefresh={() => {
this.setState({
saveInfoData: [],
pageNum: 1,
onEndReached: false,
})
this._getEarnOrder(1, this.state.source == "All" ? "0" : "1");
}}//头部刷新组件
refreshing={this.state.isLoading}//加载图标
onEndReached={() => this.onEndReached()} // 加载更多
onEndReachedThreshold={0.1}// 加载更多触发时机
ListEmptyComponent={() => {
// 无数据时显示的内容
return (
!this.state.dataFlag && this.state.saveInfoData.length <= 0 ?
<View style={styles.noprofitList}>
<Image source={require('../../images/AllProfit.png')} />
<Text style={{ fontSize: Px2dp(13), color: Colors.text888, marginTop: Px2dp(18) }}>暂无收益信息</Text>
</View>
: null
)
}}
/>
: <NoNetwork click={() => {
this.setState({
networkFlag: true,
})
this._getEarnOrder(this.state.pageNum, this.state.source == "All" ? "0" : "1")
}} />
}
{/* 加载loading */}
{this.state.isLoading ? <Loading /> : null}
</View>
);
}
//列表
renderItem = (item) => {
return (
<View style={{ backgroundColor: Colors.mainBg }}>
<View style={{ backgroundColor: Colors.mainBg }}>
<Text style={styles.monthTxt}>{item.year}年{item.month}月{this.state.source == "All" ? "共¥" + (item.sumEarn / 100).toFixed(2) : null}</Text>
</View>
{
item.orderList.map((info, index) => {
return (
<View key={index} style={{ marginBottom: item.orderList.length - 1 != index ? Px2dp(20) : 0, backgroundColor: "#fff" }}>
<View style={styles.info}>
<CachedImage style={styles.personInfoImg} source={info.userIamge ? { uri: info.userIamge } : require('../../images/logo.jpeg')} />
<View style={styles.infoTop}>
<View>
<Text style={styles.infoTopTxt}>{info.userName}</Text>
<Text style={styles.dateTxt}>购买时间:{Public.TimeFormatting(info.buyTime)}</Text>
</View>
<Text style={styles.infoTopPrice}>共:{info.orderEarn / 100}</Text>
</View>
</View>
<View style={{ paddingLeft: Px2dp(16), paddingRight: Px2dp(16) }}>
{
info.goodsList && info.goodsList.map((i, indexs) => {
return (
<View style={styles.infoBox} key={indexs}>
<CachedImage style={{ width: Px2dp(70), height: Px2dp(70) }} source={{ uri: i.goodsImage }} />
<View>
<Text numberOfLines={2} style={styles.infoBoxTxt}>{i.goodsName}</Text>
<Text style={styles.infoBoxTxtSx}>数量:{i.sum}</Text>
</View>
<View>
<Text style={styles.infoBoxPrice}><Text>¥</Text>{(i.goodsPrice / 100).toFixed(2)}</Text>
{
//没有退款的状态
i.refunded == "0" ?
<Text style={styles.infoBoxMoney}><Text>+¥</Text>{i.goodsEarn / 100}</Text>
:
<Text style={[styles.infoBoxMoney, { color: Colors.text666 }]}>已退款</Text>
}
</View>
</View>
)
})
}
</View>
</View>
)
})
}
</View>
)
}
onEndReached() {
if (this.state.dataFlag) {
let pageNum = this.state.pageNum * 1 + 1;
this.setState({
pageNum: pageNum,
})
this._getEarnOrder(pageNum, this.state.source == "All" ? "0" : "1");
}
}
//查看用户返佣订单信息
_getEarnOrder(pageNum, type) {
Fetch(requestUrl.URL, {
"userId": UserInfo.id,
"page": pageNum,
"type": type
}).then(data => {
console.log(data)
if (data.status == "SUCCESS") {
let tempArr = this.state.saveInfoData;
tempArr = tempArr.concat(data.data);
this.setState({
dataFlag: true,
saveInfoData: tempArr,
isLoading: false,
})
} else if (data.status == "ERROR") {
this.setState({
isLoading: false,
dataFlag: false,
})
ToastShow({ "text": '查看用户返佣订单信息接口失败' })
} else {
this.setState({
isLoading: false,
dataFlag: false,
})
}
})
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.mainBg,
},
//收益列表
FlatListStyle: {
flex: 1,
backgroundColor: "#fff",
},
monthTxt: {
fontSize: Px2dp(14),
color: Colors.text666,
lineHeight: Px2dp(20),
marginBottom: Px2dp(8),
marginTop: Px2dp(16),
paddingLeft: Px2dp(16)
},
profitList: {
paddingLeft: Px2dp(16),
paddingRight: Px2dp(16)
},
noprofitList: {
justifyContent: "center",
alignItems: "center",
paddingTop: SCREEN_HEIGHT * .25,
},
info: {
flexDirection: "row",
paddingLeft: Px2dp(16),
paddingRight: Px2dp(16),
paddingTop: Px2dp(16)
},
personInfoImg: {
width: Px2dp(44),
height: Px2dp(44),
backgroundColor: Colors.white,
borderRadius: Px2dp(22),
marginRight: Px2dp(10)
},
infoTop: {
flexDirection: "row",
flex: 1,
justifyContent: "space-between",
borderBottomWidth: Pixel,
borderBottomColor: "#ececec"
},
infoTopTxt: {
fontSize: Px2dp(15),
color: Colors.text333,
},
infoTopPrice: {
fontSize: Px2dp(16),
color: Colors.red,
textAlign: "right"
},
dateTxt: {
fontSize: Px2dp(12),
color: Colors.text999,
marginTop: Px2dp(4),
lineHeight: Px2dp(17)
},
infoBox: {
flexDirection: "row",
justifyContent: 'space-between',
marginTop: Px2dp(10),
marginBottom: Px2dp(10)
},
infoBoxTxt: {
fontSize: Px2dp(14),
color: Colors.text333,
lineHeight: Px2dp(20),
width: Px2dp(180),
marginBottom: Px2dp(10)
},
infoBoxPrice: {
fontSize: Px2dp(13),
color: Colors.text666,
lineHeight: Px2dp(18),
textAlign: "right"
},
infoBoxMoney: {
fontSize: Px2dp(15),
color: Colors.red,
lineHeight: Px2dp(21),
marginTop: Px2dp(31),
textAlign: "right"
},
infoBoxTxtSx: {
width: Px2dp(180),
fontSize: Px2dp(12),
color: Colors.text666,
lineHeight: Px2dp(17)
},
// 选择年份
maskClick: {
flex: 1,
backgroundColor: Colors.maskColor,
justifyContent: 'flex-end',
},
OptionBoxTit: {
fontSize: Px2dp(15),
color: Colors.text333,
marginTop: Px2dp(24),
textAlign: "center",
marginBottom: Px2dp(16)
},
OptionBoxs: {
flexDirection: "row",
alignItems: "center",
borderColor: '#ececec',
borderBottomWidth: Pixel,
height: Px2dp(40)
},
OptionBox: {
justifyContent: "center",
paddingLeft: Px2dp(16),
paddingRight: Px2dp(16),
paddingBottom: TabBar,
position: "relative",
backgroundColor: Colors.white,
},
OptionBoxTxt: {
fontSize: Px2dp(15),
color: Colors.text333,
flex: 1,
},
closeImg: {
position: "absolute",
top: Px2dp(16),
right: Px2dp(6),
padding: Px2dp(10),
justifyContent: "center",
alignItems: "center"
},
});
关于商品详情页面规格页面怎么渲染,怎么传参数,后台会给你一个格式参数按给出的格式整合,我就遇到一个这样的问题,组合成这样的
yanse:樱粉金@banben:6G+128GB@wangluo:全网通
下面是数据结构的截图 详情参考 选项切换方法 分为有参数和无参数两种情况, 先拿到最后一位 因为最后一位没有@符号
{this.state.goodsDetailInfo.templateFieldList && this.state.goodsDetailInfo.templateFieldList.map((item, index) => {
return (
<View key={index} style={{ paddingLeft: Px2dp(16), paddingRight: Px2dp(16) }}>
<Text style={styles.optionTitle}>{item.field_name}</Text>
<View style={styles.optionBox}>
{item.validAttributeList.map((option, inx) => {
return (
<TouchableOpacity
key={inx}
activeOpacity={.8}
onPress={() => {
this.changeSelected(item, option);
}}
style={[
styles.optionClick,
item.field_value == option.fieldValue ? { borderColor: Colors.red } : null
]}>
<Text style={[
styles.optionText,
item.field_value == option.fieldValue ? { color: Colors.red } : null
]}>{option.fieldValue}</Text>
</TouchableOpacity>
)
})}
</View>
</View>
)
})}
// 选项切换 分为有参数和无参数两种情况, 先拿到最后一位 因为最后一位没有@符号
changeSelected(item, option) {
console.log(item,option)
let attributeStr = '';
for (let i = 0; i < this.state.goodsDetailInfo.templateFieldList.length; i++) {
if (item.field_code == this.state.goodsDetailInfo.templateFieldList[i].field_code) {
if (i == this.state.goodsDetailInfo.templateFieldList.length - 1) {
attributeStr += this.state.goodsDetailInfo.templateFieldList[i].field_code + ':' + option.fieldValue
} else {
attributeStr += this.state.goodsDetailInfo.templateFieldList[i].field_code + ':' + option.fieldValue + "@"
}
} else {
if (i == this.state.goodsDetailInfo.templateFieldList.length - 1) {
attributeStr += this.state.goodsDetailInfo.templateFieldList[i].field_code + ':' + this.state.goodsDetailInfo.templateFieldList[i].field_value
} else {
attributeStr += this.state.goodsDetailInfo.templateFieldList[i].field_code + ':' + this.state.goodsDetailInfo.templateFieldList[i].field_value + "@"
}
}
}
this.getProductDetailInfo(attributeStr)
}