| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- import * as WebBrowser from 'expo-web-browser';
- import * as React from 'react';
- import { StyleSheet, View, Image } from 'react-native';
- import { Div, Text } from 'react-native-magnus';
- import { Flex } from '@ant-design/react-native';
- import { Modal, TouchableRipple, Badge } from 'react-native-paper';
- import { ScrollView } from 'react-native-gesture-handler';
- import { useCreation, useRequest } from '@umijs/hooks';
- import { useNavigation, useFocusEffect } from '@react-navigation/native';
- import useModel from 'flooks';
- import Detail from './model';
- import MapModel from '../Map/model';
- import Icon from '../../components/SvgIcon';
- import Button from '../../components/Button';
- import Plus from '../../components/Plus';
- import { navigate } from '../../navigation/RootNavigation';
- import { accAdd, accMul } from '../../Utils/NumberUtils';
- import { alert } from '../../Utils/TotastUtils';
- export default function Cart() {
- const {
- id,
- merchantInfo,
- addCart,
- getCart,
- setCartRequest,
- clearCart,
- setCartMap,
- changeNum,
- cartMoneyInfo,
- } = useModel(Detail, ['id', 'merchantInfo', 'cartMoneyInfo']);
- useFocusEffect(
- React.useCallback(() => {
- setshowCart(true);
- }, [])
- );
- const [showCart, setshowCart] = React.useState(false);
- const [cartList, setcartList] = React.useState([]);
- const { startingAmount } = merchantInfo;
- const [showList, setshowList] = React.useState(false);
- const cartRequest = useRequest(getCart, {
- refreshDeps: [id],
- onSuccess: (result) => {
- const value = result || [];
- setcartList(value);
- setCartRequest(cartRequest);
- if (value.length === 0) {
- setshowList(false);
- }
- },
- });
- const num = useCreation(() => {
- return cartList.reduce((total, item) => {
- return accAdd(total, item.num);
- }, 0);
- }, [cartList]);
- const cartMap = useCreation(() => {
- const map = new Map([]);
- cartList.forEach((item) => {
- map.set(item.goodsId, {
- num: map.has(item.goodsId)
- ? map.get(item.goodsId).num + item.num
- : item.num,
- specIds: map.has(item.goodsId)
- ? map.get(item.goodsId).specIds.add(item.id)
- : new Set([item.id]),
- });
- });
- return map;
- }, [cartList]);
- React.useEffect(() => {
- setCartMap(cartMap);
- }, [cartMap]);
- const {
- deliveryAmount,
- goodsTotal,
- fullReduction,
- packingPrice,
- reducedAmount,
- } = cartMoneyInfo;
- // 钱
- const price = useCreation(() => {
- if (goodsTotal) {
- return (goodsTotal - reducedAmount).toFixed(2);
- } else {
- return 0;
- }
- }, [goodsTotal, reducedAmount]);
- const total = useCreation(() => {
- if (goodsTotal) {
- return (goodsTotal + packingPrice - fullReduction).toFixed(2);
- } else {
- return 0;
- }
- }, [goodsTotal, fullReduction, packingPrice]);
- const canSubmit = useCreation(() => {
- if (price >= startingAmount && num > 0) {
- return true;
- } else {
- return false;
- }
- }, [num, startingAmount, price]);
- const goodsList = (list) => {
- return list.map((item) => {
- const { goods } = item;
- return (
- <Flex key={item.id} style={styles.item}>
- <Image
- style={styles.icon2}
- resizeMode="cover"
- source={{ uri: goods.img }}
- />
- <Flex.Item style={styles.goodsMain}>
- <Flex align="stretch">
- <Text>{goods.name}</Text>
- <Text type="error" style={{ marginLeft: 5 }}>
- ¥{item.goodsRealPrice || item.goodsPrice}
- </Text>
- </Flex>
- <Text size="c2" type="info">
- {item.specification}
- </Text>
- <Plus
- num={item.num}
- minus={() => {
- changeNum(new Set([item.id]), item.num - 1);
- }}
- loading={cartRequest.loading}
- plusEvent={() => {
- addCart(item.goodsId, item.specificationId.join(','), 1);
- }}
- />
- </Flex.Item>
- </Flex>
- );
- });
- };
- return (
- <>
- {showCart && (
- <>
- <View style={styles.main}>
- <Flex style={styles.bg}>
- <TouchableRipple
- style={styles.iconTouch}
- disabled={num === 0}
- onPress={() => setshowList(true)}
- >
- <Icon
- type={num > 0 ? 'primary' : ''}
- name="orderCart"
- width={49}
- height={53}
- badge={num}
- />
- </TouchableRipple>
- <Flex.Item style={styles.center}>
- <Div row alignItems="center" h={18}>
- <Text
- fontSize="xl"
- lineHeight={18}
- color={num === 0 ? 'gray300' : 'white'}
- >
- {num === 0 ? '未选购商品' : `¥${price}`}
- </Text>
- <Text
- fontSize="sm"
- color="gray300"
- lineHeight={18}
- textDecorLine="line-through"
- textDecorColor="gray300"
- ml={5}
- >
- ¥{total}
- </Text>
- </Div>
- <Text fontSize="xs" color="gray300">
- 另需配送费¥{deliveryAmount || 0}
- </Text>
- </Flex.Item>
- <Button
- size="large"
- type="primary"
- width={106}
- height={37}
- disabled={!canSubmit}
- radius={0}
- fontColor={!canSubmit ? '#B4B4B4' : '#fff'}
- loading={cartRequest.loading}
- onPress={() => {
- navigate('Submit');
- setshowCart(false);
- }}
- >
- {!canSubmit ? `¥${startingAmount || 0}起送` : '去结算'}
- </Button>
- </Flex>
- </View>
- <Modal
- animationType="slide-up"
- visible={showList}
- onDismiss={() => setshowList(false)}
- contentContainerStyle={styles.contentContainerStyle}
- >
- <Flex justify="between" style={styles.top}>
- <Text>已选商品</Text>
- <TouchableRipple
- disabled={num === 0}
- onPress={() => {
- alert('', '确认要清空购物车吗?', clearCart);
- }}
- >
- <Icon name="delete" type="info" width={20} height={20} />
- </TouchableRipple>
- </Flex>
- <ScrollView contentContainerStyle={styles.scroll}>
- {goodsList(cartList)}
- </ScrollView>
- </Modal>
- </>
- )}
- </>
- );
- }
- const styles = StyleSheet.create({
- main: {
- position: 'absolute',
- left: 0,
- right: 0,
- bottom: 0,
- height: 53,
- zIndex: 2,
- justifyContent: 'flex-end',
- },
- bg: {
- height: 37,
- backgroundColor: 'rgba(120, 120, 120, 1)',
- },
- iconTouch: {
- marginLeft: 15,
- alignSelf: 'flex-end',
- },
- center: {
- paddingHorizontal: 10,
- },
- contentContainerStyle: {
- backgroundColor: '#fff',
- position: 'absolute',
- bottom: 37,
- left: 0,
- right: 0,
- justifyContent: 'flex-start',
- paddingHorizontal: 20,
- paddingTop: 20,
- paddingBottom: 30,
- },
- icon2: {
- width: 40,
- height: 40,
- borderRadius: 3,
- },
- goodsMain: {
- marginLeft: 10,
- },
- top: {
- paddingBottom: 8,
- borderBottomWidth: 1,
- borderColor: '#E5E5E5',
- },
- item: {
- paddingTop: 10,
- overflow: 'hidden',
- },
- scroll: {
- flexGrow: 1,
- paddingBottom: 15,
- borderBottomWidth: 1,
- borderColor: '#e5e5e5',
- },
- });
|