MineRecordScreen.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import { StackScreenProps } from '@react-navigation/stack';
  2. import * as React from 'react';
  3. import * as Animatable from 'react-native-animatable';
  4. import { Div, Button, Image, Text, Avatar, Icon } from 'react-native-magnus';
  5. import { FlatList } from 'react-native-gesture-handler';
  6. import { RefreshControl } from 'react-native';
  7. import { useTranslation } from 'react-i18next';
  8. import { useRequest } from 'ahooks';
  9. import { FinancialType } from '../utils/MoneyUtils';
  10. import { MonthDate, getSearchDate } from '../utils/TimeUtils';
  11. import request from '../utils/RequestUtils';
  12. import ReacordCom from './ReacordCom';
  13. // import { PopoverPicker } from 'teaset';
  14. interface Result {
  15. list: Item[];
  16. last: boolean;
  17. current: number;
  18. }
  19. export default function MineRecordScreen({ navigation }: StackScreenProps) {
  20. const { t } = useTranslation();
  21. const [type, settype] = React.useState<string>('all');
  22. const [show, setshow] = React.useState<boolean>(false);
  23. const monthDate = new MonthDate();
  24. const [showDate, setshowDate] = React.useState<string>(monthDate.showList[0]);
  25. const [layout, setLayout] = React.useState<any>();
  26. const { data, loading, loadMore, loadingMore, reload } = useRequest(
  27. (d: Result | undefined) => {
  28. let current = 0;
  29. if (d && d.current) {
  30. current = Number(d.current) + 1;
  31. }
  32. return request.get(__DEV__ ? '/moneyRecord/all' : '/moneyRecord/my', {
  33. params: {
  34. query: {
  35. time: getSearchDate(showDate),
  36. type: type != 'all' ? type : '',
  37. },
  38. size: 10,
  39. page: current,
  40. },
  41. });
  42. },
  43. {
  44. refreshDeps: [showDate, type],
  45. formatResult: (response) => {
  46. return {
  47. list: response.content,
  48. current: response.number.toString(),
  49. last: response.last,
  50. empty: response.empty,
  51. };
  52. },
  53. isNoMore: (r: Result) => {
  54. if (r.last) {
  55. return true;
  56. } else {
  57. return false;
  58. }
  59. },
  60. defaultLoading: true,
  61. debounceInterval: 1000,
  62. loadMore: true,
  63. }
  64. );
  65. navigation.setOptions({
  66. headerTitle: () => {
  67. let name = '我的对账单';
  68. if (type !== 'all') {
  69. name += '(' + t(FinancialType.get(type).name) + ')';
  70. }
  71. return (
  72. <Button bg="yellow500" onPress={() => setshow(!show)}>
  73. {name}
  74. </Button>
  75. );
  76. },
  77. });
  78. return (
  79. <Div bg="gray100" flex={1}>
  80. {show && (
  81. <Div
  82. position="absolute"
  83. bg="black600"
  84. top={0}
  85. left={0}
  86. right={0}
  87. bottom={0}
  88. zIndex={2}
  89. >
  90. <Animatable.View animation="slideInDown" duration={300}>
  91. <Div bg="white">
  92. {[...FinancialType.keys()].map((item, index) => {
  93. const info = FinancialType.get(item);
  94. return (
  95. <Button
  96. bg="white"
  97. block
  98. key={index}
  99. onPress={() => {
  100. settype(item);
  101. setshow(false);
  102. }}
  103. >
  104. <Div row flex={1} alignItems="center">
  105. <Icon
  106. name={info.icon}
  107. fontSize="6xl"
  108. fontFamily="FontAwesome5"
  109. color={type == item ? 'yellow500' : 'gray200'}
  110. />
  111. <Text fontSize="lg" ml={10} flex={1}>
  112. {t(info.name)}
  113. </Text>
  114. {type == item && (
  115. <Div p={2} rounded="circle" bg="yellow500">
  116. <Icon
  117. name="check"
  118. fontSize="md"
  119. color="white"
  120. fontFamily="FontAwesome5"
  121. />
  122. </Div>
  123. )}
  124. </Div>
  125. </Button>
  126. );
  127. })}
  128. </Div>
  129. </Animatable.View>
  130. </Div>
  131. )}
  132. <FlatList
  133. refreshControl={
  134. <RefreshControl refreshing={loading} onRefresh={reload} />
  135. }
  136. onEndReached={() => {
  137. if (!data.last && !loading && !loadingMore) {
  138. loadMore();
  139. }
  140. }}
  141. onEndReachedThreshold={0.5}
  142. contentContainerStyle={{
  143. flexGrow: 1,
  144. backgroundColor: '#f2f2f2',
  145. }}
  146. data={data.list}
  147. renderItem={({ item }) => {
  148. return (
  149. <Div px={15} bg="white">
  150. <ReacordCom info={item} />
  151. </Div>
  152. );
  153. }}
  154. keyExtractor={(item) => item.id.toString()}
  155. onLayout={(e) => {
  156. console.log(e);
  157. }}
  158. ListFooterComponent={() => {
  159. return (
  160. <>
  161. {!data.empty && (
  162. <Text p={15} textAlign="center">
  163. {data.last ? '到底了' : '加载中...'}
  164. </Text>
  165. )}
  166. </>
  167. );
  168. }}
  169. stickyHeaderIndices={[0]}
  170. ListEmptyComponent={() => {
  171. return (
  172. <>
  173. {data.empty && (
  174. <Text textAlign="center" p={15}>
  175. 无数据
  176. </Text>
  177. )}
  178. </>
  179. );
  180. }}
  181. ListHeaderComponent={() => {
  182. return (
  183. <Div px={15} py={10} bg="gray100">
  184. <Button
  185. bg="gray100"
  186. borderWidth={1}
  187. borderColor="yellow500"
  188. color="yellow500"
  189. fontSize="sm"
  190. onPress={(e) => {
  191. const { nativeEvent } = e;
  192. PopoverPicker.show(
  193. {
  194. x: nativeEvent.pageX,
  195. y: nativeEvent.pageY,
  196. width: 120,
  197. },
  198. monthDate.showList,
  199. showDate,
  200. (item, index) => setshowDate(item)
  201. );
  202. }}
  203. >
  204. {showDate}
  205. </Button>
  206. </Div>
  207. );
  208. }}
  209. />
  210. </Div>
  211. );
  212. }