panhui před 5 roky
rodič
revize
a6e5d2da9b
41 změnil soubory, kde provedl 1231 přidání a 810 odebrání
  1. 1 0
      App.js
  2. 75 0
      Utils/MerchantUtils.js
  3. 5 5
      Utils/TimeUtils.js
  4. 3 3
      components/CountDown .js
  5. 3 3
      components/HomeHeader.js
  6. 1 0
      constants/ThemeMagnus.js
  7. 10 7
      flooks/User.js
  8. 6 1
      navigation/BaseNavigator.jsx
  9. 1 1
      navigation/BottomTabNavigator.jsx
  10. 54 33
      screens/Address/AddressScreen.jsx
  11. 1 1
      screens/Address/EditAddressScreen.jsx
  12. 16 0
      screens/Address/model.js
  13. 3 2
      screens/Detail/Classification.jsx
  14. 29 40
      screens/Detail/Comment.jsx
  15. 52 57
      screens/Detail/Merchant.jsx
  16. 66 25
      screens/Detail/MerchantDetailScreen.jsx
  17. 1 1
      screens/Detail/SelectSpecification.jsx
  18. 5 0
      screens/Detail/model.js
  19. 19 4
      screens/Main/AddressScreen.jsx
  20. 36 15
      screens/Main/Home/Banner.jsx
  21. 15 4
      screens/Main/Home/HomeHeader.js
  22. 15 32
      screens/Main/Home/List.jsx
  23. 132 62
      screens/Main/Home/ListTop.jsx
  24. 23 25
      screens/Main/Home/Menu.jsx
  25. 205 0
      screens/Main/Home/MerchantCom.js
  26. 0 179
      screens/Main/Home/MerchantCom.jsx
  27. 46 41
      screens/Main/Home/RecommendStore.jsx
  28. 23 18
      screens/Main/Home/SpecialArea.jsx
  29. 42 24
      screens/Main/Home/model.js
  30. 23 14
      screens/Main/HomeScreen.jsx
  31. 32 0
      screens/Main/MerchantsListScreen.jsx
  32. 30 174
      screens/Map/MapScreen.jsx
  33. 2 3
      screens/Map/SearchMapScreen copy.jsx
  34. 111 0
      screens/Map/SearchMapScreen.jsx
  35. 6 1
      screens/Map/model.js
  36. 19 0
      screens/Order/OrderDetailScreen.jsx
  37. 88 26
      screens/Order/OrderScreen.jsx
  38. 3 0
      screens/Order/model.js
  39. 2 2
      screens/User/CollectionScreen.jsx
  40. 2 2
      screens/User/SettingScreen.jsx
  41. 25 5
      screens/User/UserScreen.jsx

+ 1 - 0
App.js

@@ -53,6 +53,7 @@ export default function App() {
           routes: [
             {
               name: initName,
+              // name: 'MerchantDetail',
             },
           ],
         })

+ 75 - 0
Utils/MerchantUtils.js

@@ -0,0 +1,75 @@
+const popularTagMap = new Map([
+  [
+    '',
+    {
+      name: '综合排序',
+      showType: 'sort',
+    },
+  ],
+  [
+    '1',
+    {
+      name: '首单立减',
+    },
+  ],
+  [
+    '2',
+    {
+      name: '满减优惠',
+    },
+  ],
+  [
+    '3',
+    {
+      name: '折扣商家',
+    },
+  ],
+  [
+    '4',
+    {
+      name: '下单返红包',
+    },
+  ],
+  [
+    '5',
+    {
+      name: '可用红包',
+    },
+  ],
+  [
+    '6',
+    {
+      name: '人均最高',
+    },
+  ],
+  [
+    '7',
+    {
+      name: '距离',
+      showType: 'top',
+    },
+  ],
+  [
+    '8',
+    {
+      name: '销量',
+      showType: 'top',
+    },
+  ],
+]);
+const tagMap = new Map([
+  [
+    '1',
+    {
+      name: '新商家',
+    },
+  ],
+  [
+    '2',
+    {
+      name: '明星商家',
+    },
+  ],
+]);
+
+export { popularTagMap, tagMap };

+ 5 - 5
Utils/TimeUtils.js

@@ -53,9 +53,9 @@ export default class Time {
     }
 
     return list.flat();
-	}
-	
-	getFormat(formatType){
-		return this.time.format(formatType);
-	}
+  }
+
+  getFormat(formatType) {
+    return this.time.format(formatType);
+  }
 }

+ 3 - 3
components/CountDown .js

@@ -1,10 +1,10 @@
 import * as React from 'react';
 import { useThrottleFn } from '@umijs/hooks';
-import Text from './Text';
+import { Text } from 'react-native-magnus';
 import Time from '../Utils/TimeUtils';
 
 export default function CountDown(props) {
-  const { endTime, format, size, type, valueFormat } = props;
+  const { endTime, format, size, color, valueFormat } = props;
   const [value, setValue] = React.useState(
     new Time(endTime, format).getNowTime(valueFormat)
   );
@@ -16,7 +16,7 @@ export default function CountDown(props) {
   }, 1000);
   run();
   return (
-    <Text size={size} type={type}>
+    <Text fontSize={size} color={color}>
       {value}
     </Text>
   );

+ 3 - 3
components/HomeHeader.js

@@ -46,10 +46,10 @@ export default function Header() {
         }}
       >
         <Button onPress={locationEvent} block bg="hiden" p={0} flex={1}>
-          <Div flex={1} row>
+          <Div flex={1} row color="brand500">
             <Icon
               name="navigation"
-              color="brand500"
+              // color="brand500"
               fontFamily="Feather"
               ml={15}
             />
@@ -72,7 +72,7 @@ export default function Header() {
           anchor={<Appbar.Action icon="dots-vertical" onPress={setTrue} />}
         >
           <Menu.Item onPress={logout} title="退出登录" />
-        
+
           <Menu.Item
             onPress={() => {
               setlocal();

+ 1 - 0
constants/ThemeMagnus.js

@@ -15,6 +15,7 @@ export default {
     gray600: '#000',
     blue500: '#2EAEE7',
     green500: '#43B045',
+    black600: 'rgba(0,0,0,0.6)',
   },
   spacing: {
     xs: 2,

+ 10 - 7
flooks/User.js

@@ -5,6 +5,7 @@ import {
 } from '../Utils/AsyncStorageUtils';
 import submitPhone from '../Utils/FormUtils';
 import Toast from './Toast';
+import { alert } from '../Utils/TotastUtils';
 
 const app = (now) => ({
   id: null,
@@ -51,13 +52,15 @@ const app = (now) => ({
       });
   },
   logout() {
-    const { loading, success } = now(Toast);
-    loading();
-    // 移除 token
-    return removeAsyncStorage('token').then(() => {
-      // 清除用户信息
-      now({ id: 0, userInfo: {} });
-      success('退出成功');
+    alert('', '确定要退出该账号吗?', () => {
+      const { loading, success } = now(Toast);
+      loading();
+      // 移除 token
+      removeAsyncStorage('token').then(() => {
+        // 清除用户信息
+        now({ id: 0, userInfo: {} });
+        success('退出成功');
+      });
     });
   },
   uploadInfo({ ...info }) {

+ 6 - 1
navigation/BaseNavigator.jsx

@@ -35,8 +35,10 @@ import AddressScreen from '../screens/Address/AddressScreen';
 
 // 首页选地址
 import HomeAddress from '../screens/Main/AddressScreen';
+// 首页新店推荐
+import MerchantsList from '../screens/Main/MerchantsListScreen';
 // 搜索地图
-import SearchMap from '../screens/Main/SearchMapScreen';
+import SearchMap from '../screens/Map/SearchMapScreen';
 // 搜索地图
 import MapScreen from '../screens/Map/MapScreen';
 // 搜索地图
@@ -111,6 +113,9 @@ export default function BasicScreens(Screen) {
       {/* 编辑address */}
       <Screen name="EditAddress" component={EditAddress} />
       <Screen name="HomeAddress" component={HomeAddress} />
+      {/* 新店推荐 */}
+      <Screen name="MerchantsList" component={MerchantsList} />
+
       <Screen name="SearchMap" component={SearchMap} />
       <Screen name="MapScreen" component={MapScreen} />
       <Screen name="MapMarkScreen" component={MapMarkScreen} />

+ 1 - 1
navigation/BottomTabNavigator.jsx

@@ -10,7 +10,7 @@ const BottomTab = createBottomTabNavigator();
 
 export default function BottomTabNavigator() {
   return (
-    <BottomTab.Navigator initialRouteName="Order">
+    <BottomTab.Navigator initialRouteName="Home">
       <BottomTab.Screen
         name="Home"
         component={HomeScreen}

+ 54 - 33
screens/Address/AddressScreen.jsx

@@ -1,6 +1,8 @@
 import * as WebBrowser from 'expo-web-browser';
 import * as React from 'react';
 import { Div, Button, Image, Text, Avatar } from 'react-native-magnus';
+
+import { Flex, SwipeAction } from '@ant-design/react-native';
 import { ScrollView } from 'react-native-gesture-handler';
 
 import { useRequest, useCreation } from '@umijs/hooks';
@@ -9,47 +11,63 @@ import AddressModel from './model'; // detail模块通用方法
 
 import Header from '../../components/Header';
 
-const AddressItem = ({ info, goNext }) => {
+const AddressItem = ({ info, goNext, del }) => {
+  const right = [
+    {
+      text: '删除',
+      onPress: () => {
+        console.log('删除');
+        del();
+      },
+      style: { backgroundColor: 'red', color: 'white' },
+    },
+  ];
   return (
-    <Div bg="white" px={15} py={10} my={5} mx={10}>
-      <Text fontSize="xl" textAlign="left">
-        {info.addressName}
-      </Text>
-      <Div row>
-        <Text fontSize="xs" color="gray300" textAlign="left">
-          {info.name}
-        </Text>
-        <Text fontSize="xs" color="gray300" textAlign="left">
-          {info.sex}
-        </Text>
-        <Text ml={15} fontSize="xs" color="gray300" textAlign="left">
-          {info.phone}
+    <SwipeAction
+      autoClose
+      style={{ backgroundColor: 'transparent' }}
+      right={right}
+    >
+      <Div bg="white" px={15} py={10} my={5} mx={10}>
+        <Text fontSize="xl" textAlign="left">
+          {info.addressName}
         </Text>
-      </Div>
-      <Div row justifyContent="flex-end">
-        {info.isDefault && (
-          <Button fontSize="xs" bg="brand500">
-            默认
+        <Div row>
+          <Text fontSize="xs" color="gray300" textAlign="left">
+            {info.name}
+          </Text>
+          <Text fontSize="xs" color="gray300" textAlign="left">
+            {info.sex}
+          </Text>
+          <Text ml={15} fontSize="xs" color="gray300" textAlign="left">
+            {info.phone}
+          </Text>
+        </Div>
+        <Div row justifyContent="flex-end">
+          {info.isDefault && (
+            <Button fontSize="xs" bg="brand500">
+              默认
+            </Button>
+          )}
+          <Button
+            fontSize="xs"
+            ml={15}
+            bg="white"
+            color="gray600"
+            borderColor="gray300"
+            borderWidth={1}
+            onPress={goNext}
+          >
+            编辑
           </Button>
-        )}
-        <Button
-          fontSize="xs"
-          ml={15}
-          bg="white"
-          color="gray600"
-          borderColor="gray300"
-          borderWidth={1}
-          onPress={goNext}
-        >
-          编辑
-        </Button>
+        </Div>
       </Div>
-    </Div>
+    </SwipeAction>
   );
 };
 
 export default function AddressScreen({ navigation }) {
-  const { addressList, getAddressList } = useModel(AddressModel, [
+  const { addressList, getAddressList, delAddress } = useModel(AddressModel, [
     'addressList',
   ]);
   const addressRequest = useRequest(getAddressList);
@@ -63,6 +81,9 @@ export default function AddressScreen({ navigation }) {
             <AddressItem
               key={item.id}
               info={item}
+              del={() => {
+                delAddress(item.id);
+              }}
               goNext={() => {
                 navigation.navigate('EditAddress', {
                   id: item.id,

+ 1 - 1
screens/Address/EditAddressScreen.jsx

@@ -37,7 +37,7 @@ export default function EditAddressScreen({ navigation }) {
   const sexEvent = useToggle('先生', '女士');
 
   const canSub = useCreation(() => {
-    if (phone && name && addressName && number && addressTag) {
+    if (phone && name && addressName && number) {
       return true;
     } else {
       return false;

+ 16 - 0
screens/Address/model.js

@@ -2,6 +2,7 @@ import request from '../../Utils/RequestUtils';
 import Toast from '../../flooks/Toast';
 import User from '../../flooks/User';
 import submitPhone from '../../Utils/FormUtils';
+import { alert } from '../../Utils/TotastUtils';
 
 const AddressModel = (now) => ({
   addressList: [],
@@ -14,6 +15,7 @@ const AddressModel = (now) => ({
         params: {
           query: {
             userId: id,
+            enabled: true,
           },
         },
       })
@@ -66,6 +68,20 @@ const AddressModel = (now) => ({
         success('保存成功');
       });
   },
+  delAddress(id) {
+    alert('', '确定要删除该地址吗?删除后不可恢复!', () => {
+      const { success } = now(Toast);
+      const { getAddressList } = now();
+      return request
+        .post(`/address/del/${id}`)
+        .then(() => {
+          return getAddressList();
+        })
+        .then(() => {
+          success('删除成功');
+        });
+    });
+  },
   setShow(bool) {
     now({
       goEdit: bool,

+ 3 - 2
screens/Detail/Classification.jsx

@@ -33,9 +33,10 @@ export default function Classification({ height }) {
       const params = {
         query: {
           merchantId: id,
-          page: 0,
-          size: 100,
+          isOpen: true,
         },
+        page: 0,
+        size: 100,
       };
       const urls = Object.keys(params).map((item) => {
         return `${item}=${encodeURI(JSON.stringify(params[item]))}`;

+ 29 - 40
screens/Detail/Comment.jsx

@@ -106,48 +106,37 @@ export default function Comment() {
 
   return (
     <>
-      <DetailHeader type="comment" noRight />
-      <ScrollView
-        contentContainerStyle={{ flexGrow: 1, backgroundColor: '#fff' }}
-        refreshControl={
-          <RefreshControl
-            refreshing={appraisalRequest.loading}
-            onRefresh={appraisalRequest.run}
-          />
-        }
-      >
-        <Div row p={15}>
-          {[...AppraisalSortMap.keys()].map((item) => {
-            const info = AppraisalSortMap.get(item);
-            const isChoose = appraisalSort === item;
-            return (
-              <Tag
-                key={item}
-                bg={isChoose ? 'brand500' : info.isBad ? 'gray200' : 'brand100'}
-                color={isChoose ? 'white' : info.isBad ? 'gray500' : 'brand500'}
-                fontSize="sm"
-                mr={5}
-                mb={5}
-                onPress={() => setappraisalSort(item)}
-              >
-                {info.name}
-              </Tag>
-            );
-          })}
-        </Div>
-
-        {comments.map((item) => {
-          return <CommentItem info={item} key={item.goodsAppraise} />;
+      <Div row p={15}>
+        {[...AppraisalSortMap.keys()].map((item) => {
+          const info = AppraisalSortMap.get(item);
+          const isChoose = appraisalSort === item;
+          return (
+            <Tag
+              key={item}
+              bg={isChoose ? 'brand500' : info.isBad ? 'gray200' : 'brand100'}
+              color={isChoose ? 'white' : info.isBad ? 'gray500' : 'brand500'}
+              fontSize="sm"
+              mr={5}
+              mb={5}
+              onPress={() => setappraisalSort(item)}
+            >
+              {info.name}
+            </Tag>
+          );
         })}
+      </Div>
 
-        {comments.length === 0 && (
-          <Div px={10} py={20}>
-            <Text color="gray300" textAlign="center">
-              暂无数据
-            </Text>
-          </Div>
-        )}
-      </ScrollView>
+      {comments.map((item) => {
+        return <CommentItem info={item} key={item.goodsAppraise} />;
+      })}
+
+      {comments.length === 0 && (
+        <Div px={10} py={20}>
+          <Text color="gray300" textAlign="center">
+            暂无数据
+          </Text>
+        </Div>
+      )}
     </>
   );
 }

+ 52 - 57
screens/Detail/Merchant.jsx

@@ -33,67 +33,62 @@ export default function Merchant() {
 
   return (
     <>
-      <DetailHeader type="merchat" noRight />
-      <ScrollView
-        contentContainerStyle={{ flexGrow: 1, backgroundColor: '#eee' }}
-      >
-        <Div bg="white" py={20} px={15}>
-          <Div row>
-            {imgList.map((item, index) => {
-              return (
-                <Image
-                  mr={3}
-                  mb={10}
-                  h={87}
-                  w={87}
-                  key={index}
-                  source={{ uri: item }}
-                />
-              );
-            })}
-          </Div>
-          <Text fontSize="xl" fontWeight="bold" textAlign="left">
-            商家名称 -{name}
+      <Div bg="white" py={20} px={15}>
+        <Div row>
+          {imgList.map((item, index) => {
+            return (
+              <Image
+                mr={3}
+                mb={10}
+                h={87}
+                w={87}
+                key={index}
+                source={{ uri: item }}
+              />
+            );
+          })}
+        </Div>
+        <Text fontSize="xl" fontWeight="bold" textAlign="left">
+          商家名称 -{name}
+        </Text>
+        <Text p={10} fontSize="xs" textAlign="left">
+          {introduction}
+        </Text>
+      </Div>
+      <Div bg="white" mt={10} py={5} px={15}>
+        <Div row py={12}>
+          <Text flex={1} fontSize="sm" textAlign="left">
+            商家品类
           </Text>
-          <Text p={10} fontSize="xs" textAlign="left">
-            {introduction}
+          <Text fontSize="sm" color="gray300" textAlign="left">
+            {categoryName}
           </Text>
         </Div>
-        <Div bg="white" mt={10} py={5} px={15}>
-          <Div row py={12}>
-            <Text flex={1} fontSize="sm" textAlign="left">
-              商家品类
-            </Text>
-            <Text fontSize="sm" color="gray300" textAlign="left">
-              {categoryName}
-            </Text>
-          </Div>
-          <Div row py={12}>
-            <Text flex={1} fontSize="sm" textAlign="left">
-              商家地址
-            </Text>
-            <Text fontSize="sm" color="gray300" textAlign="left">
-              {address}
-            </Text>
-          </Div>
-          <Div row py={12}>
-            <Text flex={1} fontSize="sm" textAlign="left">
-              商家电话
-            </Text>
-            <Text fontSize="sm" color="gray300" textAlign="left">
-              {phone}
-            </Text>
-          </Div>
-          <Div row py={12}>
-            <Text flex={1} fontSize="sm" textAlign="left">
-              营业时间
-            </Text>
-            <Text fontSize="sm" color="gray300" textAlign="left">
-              {startTime}~{endTime}
-            </Text>
-          </Div>
+        <Div row py={12}>
+          <Text flex={1} fontSize="sm" textAlign="left">
+            商家地址
+          </Text>
+          <Text fontSize="sm" color="gray300" textAlign="left">
+            {address}
+          </Text>
+        </Div>
+        <Div row py={12}>
+          <Text flex={1} fontSize="sm" textAlign="left">
+            商家电话
+          </Text>
+          <Text fontSize="sm" color="gray300" textAlign="left">
+            {phone}
+          </Text>
+        </Div>
+        <Div row py={12}>
+          <Text flex={1} fontSize="sm" textAlign="left">
+            营业时间
+          </Text>
+          <Text fontSize="sm" color="gray300" textAlign="left">
+            {startTime}~{endTime}
+          </Text>
         </Div>
-      </ScrollView>
+      </Div>
     </>
   );
 }

+ 66 - 25
screens/Detail/MerchantDetailScreen.jsx

@@ -11,8 +11,10 @@ import { Flex } from '@ant-design/react-native';
 import { ScrollView } from 'react-native-gesture-handler';
 import { Div, Text, Button } from 'react-native-magnus';
 import Constants from 'expo-constants';
+import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
 
 import { useRoute } from '@react-navigation/native';
+import { useDebounceFn } from '@umijs/hooks';
 // import { useAnimation } from 'react-native-animation-hooks';
 
 import useModel from 'flooks';
@@ -25,23 +27,39 @@ import Center from './Center';
 
 import Order from './Order';
 import Cart from './Cart'; // order 页面的选购
+import Comment from './Comment'; // order 页面的选购
+import Merchant from './Merchant'; // order 页面的选购
 import SelectSpecification from './SelectSpecification'; // order 页面的选购
 
+const Tab = createMaterialTopTabNavigator();
+
 export default function MerchantDetail({ navigation }) {
   const route = useRoute();
   const { params } = route;
 
   const { init, merchantInfo, setHeaderColor } = useModel(Detail, ['id']);
   const [tabTop, settabTop] = React.useState(0);
+  const [screenName, setscreenName] = React.useState('Order');
 
   const { banner } = merchantInfo;
 
   const scorellRef = React.createRef();
 
+  const { run } = useDebounceFn(() => {
+    scorellRef.current.scrollTo({
+      x: 0,
+      y: tabTop,
+      animated: true,
+    });
+  }, 1500);
+
   React.useEffect(() => {
     if (params.merchantId) {
       init(params.merchantId);
     }
+    if (params.screen) {
+      setscreenName(params.screen);
+    }
   }, [params]);
 
   return (
@@ -49,8 +67,10 @@ export default function MerchantDetail({ navigation }) {
       <Header />
       <ScrollView
         ref={scorellRef}
-        stickyHeaderIndices={[2]}
-        style={{ flexGrow: 1 }}
+        stickyHeaderIndices={[1]}
+        style={{
+          flexGrow: 1,
+        }}
         contentContainerStyle={{ backgroundColor: '#eee' }}
         keyboardDismissMode="on-drag"
         onScroll={({ nativeEvent }) => {
@@ -65,34 +85,34 @@ export default function MerchantDetail({ navigation }) {
         }}
         scrollEventThrottle={16}
       >
-        <ImageBackground
-          style={{
-            height: 118 + Constants.statusBarHeight,
-          }}
-          resizeMode="cover"
-          source={{ uri: banner }}
-        >
-          <View style={{ flex: 1, backgroundColor: 'rgba(0,0,0,.1)' }} />
-        </ImageBackground>
-        <Center />
         <Div
-          bg="brand500"
-          pt={56 + Constants.statusBarHeight}
           onLayout={(e) => {
-            settabTop(e.nativeEvent.layout.y);
+            settabTop(e.nativeEvent.layout.height);
           }}
+          zIndex={12}
         >
+          <ImageBackground
+            style={{
+              height: 118 + Constants.statusBarHeight,
+            }}
+            resizeMode="cover"
+            source={{ uri: banner }}
+          >
+            <View style={{ flex: 1, backgroundColor: 'rgba(0,0,0,.1)' }} />
+          </ImageBackground>
+          <Center />
+        </Div>
+        <Div bg="brand500" pt={56 + Constants.statusBarHeight}>
           <Div row bg="gray200">
             <Button
               flex={1}
               bg="hide"
-              color="brand500"
+              color={screenName === 'Order' ? 'brand500' : 'gray600'}
               h={60}
               onPress={() => {
-                scorellRef.current.scrollTo({
-                  x: 0,
-                  y: tabTop,
-                  animated: true,
+                run();
+                navigation.navigate('MerchantDetail', {
+                  screen: 'Order',
                 });
               }}
             >
@@ -101,24 +121,45 @@ export default function MerchantDetail({ navigation }) {
             <Button
               flex={1}
               bg="hide"
-              color="gray600"
+              color={screenName === 'Comment' ? 'brand500' : 'gray600'}
               h={60}
-              onPress={() => navigation.navigate('MerchantDetailComment')}
+              onPress={() => {
+                run();
+
+                navigation.navigate('MerchantDetail', {
+                  screen: 'Comment',
+                });
+              }}
             >
               评论
             </Button>
             <Button
               flex={1}
               bg="hide"
-              color="gray600"
+              color={screenName === 'Merchant' ? 'brand500' : 'gray600'}
               h={60}
-              onPress={() => navigation.navigate('MerchantDetailMerchant')}
+              onPress={() => {
+                run();
+                navigation.navigate('MerchantDetail', {
+                  screen: 'Merchant',
+                });
+              }}
             >
               商家
             </Button>
           </Div>
         </Div>
-        <Order />
+        <Div minH={Dimensions.get('window').height}>
+          <Tab.Navigator
+            lazy={false}
+            initialRouteName="Order"
+            tabBarOptions={{ showLabel: false, style: { height: 0 } }}
+          >
+            <Tab.Screen name="Order" component={Order} />
+            <Tab.Screen name="Comment" component={Comment} />
+            <Tab.Screen name="Merchant" component={Merchant} />
+          </Tab.Navigator>
+        </Div>
       </ScrollView>
       <Cart />
       <SelectSpecification />

+ 1 - 1
screens/Detail/SelectSpecification.jsx

@@ -55,7 +55,7 @@ export default function SelectSpecification() {
     const list = [...selectMap.values()].map((item) => {
       return [...item.values()];
     });
-    return list.flat();
+    return [...selectMap.values()].length > 0 ? list.flat() : [];
   }, [selectMap]);
 
   // 全部选中的二级分类id list

+ 5 - 0
screens/Detail/model.js

@@ -1,6 +1,7 @@
 import request from '../../Utils/RequestUtils';
 import Toast from '../../flooks/Toast';
 import User from '../../flooks/User';
+import MapModel from '../Map/model';
 
 const DetailModel = (now) => ({
   id: 0,
@@ -95,12 +96,16 @@ const DetailModel = (now) => ({
   addCart(goodsId, goodsSpecificationIds, num) {
     const { warnning } = now(Toast);
     const { cartRequest } = now();
+    const { chooseInfo } = now(MapModel);
+    const { location } = chooseInfo;
     return request
       .post('/shoppingCart/cart', {
         data: {
           goodsId,
           goodsSpecificationIds,
           num,
+          longitude: location.lng,
+          latitude: location.lat,
         },
         requestType: 'form',
       })

+ 19 - 4
screens/Main/AddressScreen.jsx

@@ -4,13 +4,26 @@ import { StatusBar } from 'expo-status-bar';
 import { Div, Button, Image, Text, Avatar, Icon } from 'react-native-magnus';
 import { Appbar } from 'react-native-paper';
 import { ScrollView } from 'react-native-gesture-handler';
+import { useCreation } from '@umijs/hooks';
 
 import useModel from 'flooks';
 import HomeModel from './Home/model';
+import MapModel from '../Map/model';
 import HomeAddressCom from '../Address/HomeAddressCom';
 
 export default function AddressScreen({ navigation }) {
-  const { addressName, locationEvent, changeChooseMap } = useModel(HomeModel);
+  const { locationInfo, getNowLocation, changeChooseInfo } = useModel(
+    MapModel,
+    ['locationInfo', 'getNowLocation']
+  );
+
+  const addressName = useCreation(() => {
+    if (locationInfo) {
+      return locationInfo.addressName;
+    } else {
+      return '';
+    }
+  }, [locationInfo]);
 
   return (
     <>
@@ -69,7 +82,9 @@ export default function AddressScreen({ navigation }) {
             <Button
               onPress={() => {
                 navigation.navigate('Home');
-                changeChooseMap('location');
+                if (addressName) {
+                  changeChooseInfo(locationInfo);
+                }
               }}
               block
               bg="hiden"
@@ -86,13 +101,13 @@ export default function AddressScreen({ navigation }) {
                   fontWeight="bold"
                   flex={1}
                 >
-                  {locationEvent.loading
+                  {getNowLocation.loading
                     ? '加载中...'
                     : addressName || '定位失败'}
                 </Text>
               </Div>
             </Button>
-            <Button onPress={locationEvent} bg="hiden" color="brand500">
+            <Button onPress={getNowLocation} bg="hiden" color="brand500">
               重新定位
             </Button>
           </Div>

+ 36 - 15
screens/Main/Home/Banner.jsx

@@ -2,14 +2,30 @@ import * as WebBrowser from 'expo-web-browser';
 import * as React from 'react';
 import { StyleSheet } from 'react-native';
 import { Carousel } from '@ant-design/react-native';
-import { Card } from 'react-native-paper';
+import { Image } from 'react-native-magnus';
+import { useCreation } from '@umijs/hooks';
 import useModel from 'flooks';
 import HomeModel from './model';
 
-export default function Banner() {
-  const { bannerList } = useModel(HomeModel);
+export default function Banner({ type, height, round, noDots }) {
+  const { bannerList } = useModel(HomeModel, ['bannerList']);
   const [index, setIndex] = React.useState(0);
-  if (bannerList.length > 0) {
+
+  const showList = useCreation(() => {
+    if (type) {
+      return bannerList.filter((item) => {
+        return item.type === type;
+      });
+    } else {
+      return bannerList;
+    }
+  }, [type, bannerList]);
+
+  React.useEffect(() => {
+    setIndex(0);
+  }, [type]);
+
+  if (showList.length > 0) {
     return (
       <Carousel
         style={styles.wrapper}
@@ -17,17 +33,22 @@ export default function Banner() {
         autoplay
         infinite
         afterChange={setIndex}
+        dots={!noDots}
       >
-        {bannerList.map((item) => (
-          <Card key={item.id}>
-            <Card.Cover
-              source={{ uri: item.pic }}
-              resizeMode="cover"
-              style={{ height: 80 }}
-              borderRadius={0}
-            />
-          </Card>
-        ))}
+        {showList.map(
+          (item) =>
+            !!item.pic && (
+              <Image
+                key={item.id}
+                rounded={round ? 'xs' : 'none'}
+                source={{
+                  uri: item.pic,
+                }}
+                w="100%"
+                h={height || 80}
+              />
+            )
+        )}
       </Carousel>
     );
   } else {
@@ -37,6 +58,6 @@ export default function Banner() {
 
 const styles = StyleSheet.create({
   wrapper: {
-    height: 80,
+    // height: 80,
   },
 });

+ 15 - 4
screens/Main/Home/HomeHeader.js

@@ -1,24 +1,35 @@
 import * as React from 'react';
 import { StatusBar } from 'expo-status-bar';
 import { Appbar, Menu } from 'react-native-paper';
-import { useBoolean } from '@umijs/hooks';
+import { useBoolean, useCreation } from '@umijs/hooks';
 import { Icon, Text, Button, Div } from 'react-native-magnus';
 
 import useModel from 'flooks';
 import { useNavigation } from '@react-navigation/native';
 import words from '../../../flooks/Words';
 import user from '../../../flooks/User';
-import HomeModel from './model';
+import MapModel from '../../Map/model';
 
 export default function Header() {
+  const { chooseInfo, getChooseInfo } = useModel(MapModel, [
+    'chooseInfo',
+    'getChooseInfo',
+  ]);
   const { state, setTrue, setFalse } = useBoolean(false);
   const { setlocal, TchangeToth, TchangeToChinese, local } = useModel(words);
 
   const { logout } = useModel(user, []);
-  const { addressName, locationEvent } = useModel(HomeModel);
 
   const navigation = useNavigation();
 
+  const addressName = useCreation(() => {
+    if (chooseInfo) {
+      return chooseInfo.addressName;
+    } else {
+      return '';
+    }
+  }, [chooseInfo]);
+
   return (
     <>
       <StatusBar backgroundColor="transparent" style="dark" translucent />
@@ -58,7 +69,7 @@ export default function Header() {
               fontWeight="bold"
               flex={1}
             >
-              {locationEvent.loading ? '加载中...' : addressName}
+              {getChooseInfo.loading ? '加载中...' : addressName}
             </Text>
           </Div>
         </Button>

+ 15 - 32
screens/Main/Home/List.jsx

@@ -1,44 +1,27 @@
 import * as WebBrowser from 'expo-web-browser';
 import * as React from 'react';
-import { StyleSheet, View } from 'react-native';
-import { WingBlank, Flex } from '@ant-design/react-native';
-import { Div, Button } from 'react-native-magnus';
-import { Menu } from 'react-native-paper';
-import { useBoolean } from '@umijs/hooks';
+import { Dimensions } from 'react-native';
+import Constants from 'expo-constants';
+import { Div } from 'react-native-magnus';
 import useModel from 'flooks';
 import MerchantCom from './MerchantCom';
 import HomeModel from './model';
 
-export default function List() {
-  const firstSortMenu = useBoolean(false);
-  const { list, page, size, finish, loading, getData } = useModel(HomeModel);
-
-  if (!loading && !finish) {
-    getData();
-  }
-  const menuMap = (_map) => {
-    return [..._map.keys()].map((item, index) => {
-      return (
-        <Menu.Item
-          key={index}
-          onPress={() => {
-            console.log(item.id);
-          }}
-          title={item}
-        />
-      );
-    });
-  };
+const { height } = Dimensions.get('window');
 
-  const MerchantComList = (_list) => {
-    return _list.map((item, index) => {
-      return <MerchantCom key={index} info={item} />;
-    });
-  };
+export default function List() {
+  const { list } = useModel(HomeModel, ['list']);
 
   return (
-    <Div py={15} zIndex={1}>
-      {MerchantComList(list)}
+    <Div
+      zIndex={1}
+      py={10}
+      minH={height - 46 - 35 - 49 - Constants.statusBarHeight}
+    >
+      {list.length > 0 &&
+        list.map((item, index) => {
+          return <MerchantCom key={index} info={item} />;
+        })}
     </Div>
   );
 }

+ 132 - 62
screens/Main/Home/ListTop.jsx

@@ -2,82 +2,152 @@ import * as WebBrowser from 'expo-web-browser';
 import * as React from 'react';
 import { StyleSheet, Animated, UIManager, findNodeHandle } from 'react-native';
 import Constants from 'expo-constants';
-import { Div, Button } from 'react-native-magnus';
-import { Menu } from 'react-native-paper';
-import { useBoolean, useDebounceFn } from '@umijs/hooks';
+import { Div, Button, Text, Icon } from 'react-native-magnus';
+import { Menu, Portal } from 'react-native-paper';
+import { useBoolean, useDebounceFn, useCreation } from '@umijs/hooks';
+import { useAnimation } from 'react-native-animation-hooks';
 import useModel from 'flooks';
 import MerchantCom from './MerchantCom';
 import HomeModel from './model';
+import { popularTagMap } from '../../../Utils/MerchantUtils';
 
-const firstMenus = new Map([
-  ['综合排序', { id: 1 }],
-  ['好评优先', { id: 2 }],
-  ['起送价最低', { id: 3 }],
-  ['配送最快', { id: 4 }],
-  ['配送费最低', { id: 5 }],
-  ['人均从低到高', { id: 6 }],
-  ['人均从高到低', { id: 7 }],
-  ['通用排序', { id: 8 }],
-]);
-export default function List({ animatedScrollYValue, tabBox }) {
+export default function List({ animatedScrollYValue, topHeight }) {
   const firstSortMenu = useBoolean(false);
-  const {
-    list,
-    page,
-    size,
-    finish,
-    loading,
-    getData,
-    loadingTop,
-  } = useModel(HomeModel, ['loadingTop']);
-  const [top, setTop] = React.useState(200);
+  const { popularTag, changeTag } = useModel(HomeModel, [
+    'loadingTop',
+    'popularTag',
+  ]);
+
+  const top = useCreation(() => {
+    return topHeight ? topHeight + 56 : 200;
+  }, [topHeight]);
+
   const translateY = animatedScrollYValue.interpolate({
     inputRange: [-1, 0, top, top + 1],
     outputRange: [0, 0, 0, 1],
   });
 
-  const { run } = useDebounceFn(() => {
-    UIManager.measure(
-      findNodeHandle(tabBox.current),
-      (x, y, width, height, pageX, pageY) => {
-        let scrollTop = pageY - 48 - Constants.statusBarHeight;
-        setTop(scrollTop);
-      }
-    );
-  }, 500);
+  const [selectHeight, setSelectHeight] = React.useState(0);
+
+  const soltType = useCreation(() => {
+    return 'first';
+  }, [popularTag]);
 
-  React.useEffect(() => {
-    if (tabBox.current) {
-      run();
-    } else {
-      setTop(200);
-    }
-  }, [tabBox, loadingTop]);
+  const popularInfo = useCreation(() => {
+    return popularTagMap.get(popularTag);
+  }, [popularTag]);
+
+  const height = useAnimation({
+    type: 'timing',
+    initialValue: 0,
+    duration: 100,
+    toValue: firstSortMenu.state ? 230 : 0,
+  });
 
   return (
-    <Animated.View style={{ zIndex: 100, transform: [{ translateY }] }}>
-      <Div row bg="white">
-        <Button
-          bg="hide"
-          fontSize="xl"
-          px={10}
-          color="brand500"
-          onPress={() => {}}
+    <>
+      <Animated.View
+        style={{
+          zIndex: 100,
+          backgroundColor: 'rgba(0,0,0,0)',
+          transform: [{ translateY }],
+        }}
+      >
+        <Div row bg="white">
+          <Button
+            onPress={firstSortMenu.setTrue}
+            bg="hide"
+            fontSize="xl"
+            px={10}
+            color={soltType === 'first' ? 'brand500' : 'gray600'}
+          >
+            推荐商家
+          </Button>
+          {/* <View style={{ width: 33 }} /> */}
+          <Button
+            bg="hide"
+            fontSize="xl"
+            color="gray600"
+            px={10}
+            mx={10}
+            onPress={() => {}}
+          >
+            发现美食
+          </Button>
+        </Div>
+        <Div row bg="white" alignItems="center">
+          <Button onPress={() => firstSortMenu.toggle()} bg="hide" px={10}>
+            <Text
+              fontSize="xs"
+              color={
+                popularTag && popularInfo.showType !== 'top'
+                  ? 'brand500'
+                  : 'gray600'
+              }
+            >
+              {popularInfo.name}
+            </Text>
+            <Icon
+              name="down"
+              fontSize="xs"
+              color={
+                popularTag && popularInfo.showType !== 'top'
+                  ? 'brand500'
+                  : 'gray600'
+              }
+            />
+          </Button>
+
+          <Button fontSize="xs" bg="hide" color="gray600" px={10}>
+            距离
+          </Button>
+          <Button fontSize="xs" bg="hide" color="gray600" px={10}>
+            销量
+          </Button>
+        </Div>
+
+        <Animated.View
+          style={{ height, overflow: 'hidden', backgroundColor: '#fff' }}
         >
-          推荐商家
-        </Button>
-        {/* <View style={{ width: 33 }} /> */}
+          {[...popularTagMap.keys()].map((item, index) => {
+            const info = popularTagMap.get(item);
+            return info.showType !== 'top' ? (
+              <Button
+                key={index}
+                block
+                bg="white"
+                rounded="none"
+                onPress={() => {
+                  firstSortMenu.setFalse();
+                  changeTag(item);
+                }}
+              >
+                <Text
+                  fontSize="xs"
+                  flex={1}
+                  color={popularTag === item ? 'brand500' : 'gray600'}
+                >
+                  {info.name}
+                </Text>
+              </Button>
+            ) : (
+              <></>
+            );
+          })}
+        </Animated.View>
+      </Animated.View>
+      {firstSortMenu.state && (
         <Button
-          bg="hide"
-          fontSize="xl"
-          color="gray600"
-          px={10}
-          mx={10}
-          onPress={() => {}}
-        >
-          发现美食
-        </Button>
-      </Div>
-    </Animated.View>
+          bg="black600"
+          position="absolute"
+          top={top + 60}
+          left={0}
+          right={0}
+          bottom={0}
+          zIndex={2}
+          onPress={firstSortMenu.setFalse}
+        />
+      )}
+    </>
   );
 }

+ 23 - 25
screens/Main/Home/Menu.jsx

@@ -3,38 +3,36 @@ import * as React from 'react';
 import { StyleSheet } from 'react-native';
 import { Flex, WingBlank } from '@ant-design/react-native';
 import { Card } from 'react-native-paper';
+import { Icon, Text, Button, Div } from 'react-native-magnus';
 import useModel from 'flooks';
 import HomeModel from './model';
-import Text from '../../../components/Text';
 
 export default function RecommendStore() {
-  const { categories } = useModel(HomeModel);
+  const { categories, timeTag } = useModel(HomeModel);
 
-  const cardList = (list) => {
-    return list.map((item) => {
-      return (
-        <Flex.Item key={item.id} style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: item.icon }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                {item.name}
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-      );
-    });
-  };
+  const CardCom = ({ info }) => (
+    <Div flex={1}>
+      <Card elevation={0} style={styles.card}>
+        <Card.Cover
+          style={styles.image2}
+          resizeMode="cover"
+          source={{ uri: info.icon }}
+        />
+        <Card.Content style={styles.main2}>
+          <Text fontSize="xs" textAlign="center">
+            {info.name}
+          </Text>
+        </Card.Content>
+      </Card>
+    </Div>
+  );
 
   return (
-    <WingBlank style={{ marginTop: 15, marginBottom: 5 }}>
-      <Flex style={styles.content2}>{cardList(categories)}</Flex>
-    </WingBlank>
+    <Div row px={15}>
+      {categories.concat([timeTag]).map((item, index) => {
+        return <CardCom key={index} info={item} />;
+      })}
+    </Div>
   );
 }
 

+ 205 - 0
screens/Main/Home/MerchantCom.js

@@ -0,0 +1,205 @@
+import * as WebBrowser from 'expo-web-browser';
+import * as React from 'react';
+import { StyleSheet, View } from 'react-native';
+import { Div, Text, Image } from 'react-native-magnus';
+import { Flex, SwipeAction } from '@ant-design/react-native';
+import { TouchableRipple } from 'react-native-paper';
+
+import { useCreation } from '@umijs/hooks';
+import { useNavigation } from '@react-navigation/native';
+import Chip from '../../../components/Chip';
+import Icon from '../../../components/SvgIcon';
+import useModel from 'flooks';
+import DetailModel from '../../Detail/model';
+
+// 首页商家组件
+
+export default function MerchantCom(props) {
+  const { info, isCollection, CollectionId, freash } = props;
+  const navigation = useNavigation();
+
+  const { delLike } = useModel(DetailModel, []);
+
+  const {
+    showName,
+    logo,
+    distance,
+    category,
+    merchantNature,
+    startingAmount,
+    monthSales,
+    goodNum,
+    badNum,
+    preparationTime,
+    mid,
+  } = info || { showName: '' };
+
+  const tags = useCreation(() => {
+    let list = [];
+    if (merchantNature) {
+      list.push({
+        name: merchantNature.name,
+      });
+    }
+    if (category) {
+      list = list.concat(
+        category.map((item) => {
+          return { name: item.name };
+        })
+      );
+    }
+    return list;
+  }, [category, merchantNature]);
+
+  const long = useCreation(() => {
+    if (distance < 1000) {
+      return `${distance}米`;
+    } else if (distance) {
+      return `${(distance / 1000).toFixed(1)}km`;
+    } else {
+      return false;
+    }
+  }, [distance]);
+
+  const right = [
+    {
+      text: '删除',
+      onPress: () => {
+        console.log('删除');
+        delLike(CollectionId).then(() => freash());
+      },
+      style: { backgroundColor: 'red', color: 'white' },
+    },
+  ];
+
+  return (
+    <SwipeAction
+      autoClose
+      style={{ backgroundColor: 'transparent' }}
+      right={right}
+      disabled={!isCollection}
+    >
+      <Div my={isCollection ? 5 : 0}>
+        <TouchableRipple
+          onPress={() => {
+            navigation.navigate('MerchantDetail', {
+              merchantId: isCollection ? info.id : mid,
+            });
+          }}
+        >
+          <Div row px={10} pt={10} bg="white">
+            {logo ? (
+              <Image
+                w={67}
+                h={67}
+                bg="gray200"
+                rounded="sm"
+                source={{ uri: logo || '' }}
+              />
+            ) : (
+              <Div w={67} h={67} bg="gray200" />
+            )}
+            <Div
+              flex={1}
+              ml={10}
+              pb={4}
+              borderColor="gray300"
+              borderBottomWidth={1}
+            >
+              <Text size="xl" fontWeight="bold" textAlign="left">
+                {showName}
+              </Text>
+              {tags.length > 0 && (
+                <Flex>
+                  {tags.map((item, index) => {
+                    return <Chip key={index}>{item.name}</Chip>;
+                  })}
+                </Flex>
+              )}
+
+              <Flex>
+                <Flex>
+                  <Icon name="zan" type="primary" width={18} height={18} />
+                  <Text fontSize="sm" color="brand500" textAlign="left">
+                    {goodNum || 0}
+                  </Text>
+                </Flex>
+                <Flex style={styles.text}>
+                  <Icon name="zan" Flip color="#000" width={18} height={18} />
+                  <Text fontSize="sm" color="gray300" textAlign="left">
+                    {badNum || 0}
+                  </Text>
+                </Flex>
+                <Flex style={styles.text}>
+                  <Text size="c1" color="gray300" textAlign="left">
+                    月售
+                    {monthSales}
+                  </Text>
+                </Flex>
+              </Flex>
+              <Flex>
+                <Text fontSize="sm" color="gray300" textAlign="left">
+                  起送$
+                  {startingAmount || 0}
+                </Text>
+                <Flex.Item style={styles.text}>
+                  <Text fontSize="sm" color="gray300" textAlign="left">
+                    配送$ 10
+                  </Text>
+                </Flex.Item>
+                <Text fontSize="sm" color="gray300" textAlign="left">
+                  {preparationTime || 60}
+                  分钟
+                </Text>
+                {!!long && (
+                  <View style={styles.text}>
+                    <Text fontSize="sm" color="gray300" textAlign="left">
+                      {long}
+                    </Text>
+                  </View>
+                )}
+              </Flex>
+              <Flex style={styles.label2}>
+                <Chip size="mini" color="#FFE3B9" fontColor="#FF0000">
+                  “喜欢您来金拱门喜欢您来金拱门”
+                </Chip>
+                <Chip size="mini" color="#FFE3B9" fontColor="#FF0000">
+                  “喜欢您来金拱门喜欢您来金拱门”
+                </Chip>
+              </Flex>
+              <Flex style={styles.label2} wrap="wrap">
+                <Chip size="mini" outline color="#FF0000">
+                  12减5
+                </Chip>
+              </Flex>
+            </Div>
+          </Div>
+        </TouchableRipple>
+      </Div>
+    </SwipeAction>
+  );
+}
+
+const styles = StyleSheet.create({
+  image: {
+    width: 67,
+    height: 67,
+    borderRadius: 3,
+  },
+  text: {
+    marginLeft: 6,
+  },
+  label2: {
+    marginTop: 4,
+    overflow: 'hidden',
+  },
+  main: {
+    marginLeft: 10,
+    borderBottomWidth: 1,
+    borderBottomColor: '#C9C9C9',
+    paddingBottom: 4,
+  },
+  merchant: {
+    paddingTop: 10,
+  },
+});

+ 0 - 179
screens/Main/Home/MerchantCom.jsx

@@ -1,179 +0,0 @@
-import * as WebBrowser from 'expo-web-browser';
-import * as React from 'react';
-import { StyleSheet, View } from 'react-native';
-import { Div, Text, Image } from 'react-native-magnus';
-import { Flex } from '@ant-design/react-native';
-import { TouchableRipple } from 'react-native-paper';
-import { useCreation } from '@umijs/hooks';
-import { useNavigation } from '@react-navigation/native';
-import Chip from '../../../components/Chip';
-import Icon from '../../../components/SvgIcon';
-
-// 首页商家组件
-
-export default function MerchantCom(props) {
-  const { info, isCollection, id } = props;
-  const navigation = useNavigation();
-
-  const {
-    showName,
-    logo,
-    distance,
-    firstOrder,
-    category,
-    merchantNature,
-    startingAmount,
-    monthSales,
-    goodNum,
-    badNum,
-    preparationTime,
-    mid,
-  } = info || { showName: '' };
-
-  const tags = useCreation(() => {
-    let list = [];
-    if (merchantNature) {
-      list.push({
-        name: merchantNature.name,
-      });
-    }
-    if (category) {
-      list = list.concat(
-        category.map((item) => {
-          return { name: item.name };
-        })
-      );
-    }
-    return list;
-  }, [category, merchantNature]);
-
-  const long = useCreation(() => {
-    if (distance < 1000) {
-      return `${distance}米`;
-    } else if (distance) {
-      return `${(distance / 1000).toFixed(1)}km`;
-    } else {
-      return false;
-    }
-  }, [distance]);
-
-  return (
-    <Div my={isCollection ? 5 : 0}>
-      <TouchableRipple
-        onPress={() => {
-          navigation.navigate('MerchantDetail', {
-            merchantId: isCollection ? info.id : mid,
-          });
-        }}
-      >
-        <Div row px={10} pt={10} bg="white">
-          <Image
-            w={67}
-            h={67}
-            bg="gray200"
-            rounded="sm"
-            source={{ uri: logo || '' }}
-          />
-          <Div
-            flex={1}
-            ml={10}
-            pb={4}
-            borderColor="gray300"
-            borderBottomWidth={1}
-          >
-            <Text size="xl" fontWeight="bold" textAlign="left">
-              {showName}
-            </Text>
-            {tags.length > 0 && (
-              <Flex>
-                {tags.map((item, index) => {
-                  return <Chip key={index}>{item.name}</Chip>;
-                })}
-              </Flex>
-            )}
-
-            <Flex>
-              <Flex>
-                <Icon name="zan" type="primary" width={18} height={18} />
-                <Text fontSize="sm" color="brand500" textAlign="left">
-                  {goodNum || 0}
-                </Text>
-              </Flex>
-              <Flex style={styles.text}>
-                <Icon name="zan" Flip color="#000" width={18} height={18} />
-                <Text fontSize="sm" color="gray300" textAlign="left">
-                  {badNum || 0}
-                </Text>
-              </Flex>
-              <Flex style={styles.text}>
-                <Text size="c1" color="gray300" textAlign="left">
-                  月售
-                  {monthSales}
-                </Text>
-              </Flex>
-            </Flex>
-            <Flex>
-              <Text fontSize="sm" color="gray300" textAlign="left">
-                起送$
-                {startingAmount || 0}
-              </Text>
-              <Flex.Item style={styles.text}>
-                <Text fontSize="sm" color="gray300" textAlign="left">
-                  配送$ 10
-                </Text>
-              </Flex.Item>
-              <Text fontSize="sm" color="gray300" textAlign="left">
-                {preparationTime || 60}
-                分钟
-              </Text>
-              {!!long && (
-                <View style={styles.text}>
-                  <Text fontSize="sm" color="gray300" textAlign="left">
-                    {long}
-                  </Text>
-                </View>
-              )}
-            </Flex>
-            <Flex style={styles.label2}>
-              <Chip size="mini" color="#FFE3B9" fontColor="#FF0000">
-                “喜欢您来金拱门喜欢您来金拱门”
-              </Chip>
-              <Chip size="mini" color="#FFE3B9" fontColor="#FF0000">
-                “喜欢您来金拱门喜欢您来金拱门”
-              </Chip>
-            </Flex>
-            <Flex style={styles.label2} wrap="wrap">
-              <Chip size="mini" outline color="#FF0000">
-                12减5
-              </Chip>
-            </Flex>
-          </Div>
-        </Div>
-      </TouchableRipple>
-    </Div>
-  );
-}
-
-const styles = StyleSheet.create({
-  image: {
-    width: 67,
-    height: 67,
-    borderRadius: 3,
-  },
-  text: {
-    marginLeft: 6,
-  },
-  label2: {
-    marginTop: 4,
-    overflow: 'hidden',
-  },
-  main: {
-    marginLeft: 10,
-    borderBottomWidth: 1,
-    borderBottomColor: '#C9C9C9',
-    paddingBottom: 4,
-  },
-  merchant: {
-    paddingTop: 10,
-  },
-});

+ 46 - 41
screens/Main/Home/RecommendStore.jsx

@@ -3,58 +3,63 @@ import * as React from 'react';
 import { StyleSheet, View } from 'react-native';
 import { Flex, WingBlank } from '@ant-design/react-native';
 import { Card } from 'react-native-paper';
+import { Div, Button, Text, Image } from 'react-native-magnus';
 import { useNavigation } from '@react-navigation/native';
 import useModel from 'flooks';
 import HomeModel from './model';
-import Text from '../../../components/Text';
+
+function CardCom({ info, onPress }) {
+  return (
+    <Div px={5} flex={1} alignItems="center">
+      <Image w={46} h={46} rounded="xs" source={{ uri: info.logo }} />
+      <Text fontSize="xs" textAlign="center" color="gray300">
+        {info.showName}
+      </Text>
+      <Text fontSize="xs" textAlign="center" color="red500">
+        1.1km
+      </Text>
+    </Div>
+  );
+}
 
 export default function RecommendStore() {
-  const { newMerchants } = useModel(HomeModel);
+  const { newMerchants } = useModel(HomeModel, ['newMerchants']);
   const navigation = useNavigation();
 
-  const cards = (list) => {
-    return list.map((item) => {
-      return (
-        <Flex.Item key={item.id} style={{ paddingHorizontal: 5 }}>
-          <Card
-            elevation={0}
-            style={styles.card}
-            onPress={() => {
-              navigation.navigate('MerchantDetail', {
-                merchantId: item.id,
-              });
-            }}
-          >
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: item.logo }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                {item.showName}
-              </Text>
-              <Text size="c2" color="#FF6C00" center>
-                1.1km
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-      );
-    });
-  };
-
   return (
-    <WingBlank style={{ marginTop: 15, marginBottom: 5 }}>
-      <Flex style={styles.content} justify="between">
-        <Text size="s1" bold>
+    <Div p={15}>
+      <Div row>
+        <Text flex={1} fontSize="xl" textweight="bold">
           新店推荐
         </Text>
-        <Text size="c2">更多新店 〉</Text>
-      </Flex>
+        <Button
+          bg="hide"
+          fontSize="xs"
+          color="gray600"
+          onPress={() => {
+            navigation.navigate('MerchantsList');
+          }}
+        >
+          更多新店&gt;
+        </Button>
+      </Div>
 
-      <Flex style={styles.content2}>{cards(newMerchants)}</Flex>
-    </WingBlank>
+      <Div row>
+        {newMerchants.map((item) => {
+          return (
+            <CardCom
+              key={item.id}
+              info={item}
+              onPress={() => {
+                navigation.navigate('MerchantDetail', {
+                  merchantId: item.id,
+                });
+              }}
+            />
+          );
+        })}
+      </Div>
+    </Div>
   );
 }
 

+ 23 - 18
screens/Main/Home/SpecialArea.jsx

@@ -8,12 +8,13 @@ import { Card } from 'react-native-paper';
 import useModel from 'flooks';
 import HomeModel from './model';
 import CountDown from '../../../components/CountDown ';
+import Banner from './Banner';
 
 // 优惠专区
 export default function SpecialArea() {
   const navigation = useNavigation();
 
-  const { promote1, promote2, timeTag } = useModel(HomeModel);
+  const { promote1, promote2, bannerList } = useModel(HomeModel);
   const promote1Card = (list) => {
     return list.map((item) => {
       const merchant = item.merchant || {};
@@ -32,19 +33,21 @@ export default function SpecialArea() {
               resizeMode="cover"
               source={{ uri: merchant.logo }}
             />
-            <Card.Content>
-              <Text size="s1">{merchant.name}</Text>
-              <Text size="c2">
-                倒计时
+            <Div py={8} px={10}>
+              <Text>{merchant.name}</Text>
+              <Div row>
+                <Text fontSize="sm" mr={5}>
+                  倒计时
+                </Text>
                 <CountDown
                   endTime={item.endDateTime}
                   format="yyyy-MM-DD HH:mm:ss"
                   valueFormat="D天 HH时mm分ss秒"
-                  size="c2"
-                  type="error"
+                  size="sm"
+                  color="red500"
                 />
-              </Text>
-            </Card.Content>
+              </Div>
+            </Div>
           </Card>
         </Div>
       );
@@ -55,7 +58,7 @@ export default function SpecialArea() {
     return list.map((item) => {
       const merchant = item.merchant || {};
       return (
-        <Div key={item.id} flex={1} mx={1.5} maxW="25%">
+        <Div key={item.id} flex={1} mx={1.5} maxW="25%" shadow="xs">
           <Card
             onPress={() => {
               navigation.navigate('MerchantDetail', {
@@ -69,7 +72,9 @@ export default function SpecialArea() {
               source={{ uri: merchant.logo }}
             />
             <Card.Content style={styles.main2}>
-              <Text size="c2">{merchant.name}</Text>
+              <Text fontSize="xs" numberOfLines={1} ellipsizeMode="tail">
+                {merchant.name}
+              </Text>
             </Card.Content>
           </Card>
         </Div>
@@ -82,18 +87,18 @@ export default function SpecialArea() {
         <Text fontSize="xl" fontWeight="bold" py={5}>
           优惠专区
         </Text>
-        <Div row>{promote1Card(promote1)}</Div>
-        <Div row>{promote2Card(promote2)}</Div>
+        <Div row mb={5}>
+          {promote1Card(promote1)}
+        </Div>
+        <Div row mb={10}>
+          {promote2Card(promote2)}
+        </Div>
 
         <Text fontSize="xl" fontWeight="bold" py={5}>
           优惠专区
         </Text>
 
-        <Card.Cover
-          style={styles.imageMain}
-          resizeMode="cover"
-          source={{ uri: timeTag.icon }}
-        />
+        <Banner type="AREA" round noDots />
       </Div>
     </>
   );

+ 42 - 24
screens/Main/Home/model.js

@@ -1,11 +1,12 @@
 import request from '../../../Utils/RequestUtils';
 import Toast from '../../../flooks/Toast';
-import { getLocation } from '../../../Utils/MapUtils';
+import MapModel from '../../Map/model';
 
 const HomeModel = (now) => ({
   bannerList: [],
   categories: [],
   newMerchants: [],
+  allnewMerchants: [],
   promote1: [],
   promote2: [],
   timeTag: {},
@@ -17,21 +18,29 @@ const HomeModel = (now) => ({
   location: {},
   addressName: '',
   loadingTop: true,
+  popularTag: '',
   initHome() {
     now({
       bannerList: [],
+      list: [],
       categories: [],
       newMerchants: [],
+      allnewMerchants: [],
       promote1: [],
       promote2: [],
       timeTag: {},
       loadingTop: true,
+      popularTag: '',
     });
+
     const { locationEvent } = now();
     locationEvent()
-      .then((res) => {
+      .then(() => {
+        const { chooseInfo } = now(MapModel);
+        const { location } = chooseInfo;
+
         return request.get('/merchant/index', {
-          params: { latitude: res.lat, longitude: res.lng },
+          params: { latitude: location.lat, longitude: location.lng },
         });
       })
       .then((res) => {
@@ -39,44 +48,44 @@ const HomeModel = (now) => ({
           bannerList: res.banner,
           categories: res.categories.slice(0, 5),
           newMerchants: res.newMerchants.slice(0, 4),
+          allnewMerchants: res.newMerchants,
           promote1: res.promote1.slice(0, 2),
           promote2: res.promote2.slice(0, 4),
           timeTag: res.timeTag,
           loadingTop: false,
         });
+        const { changeTag } = now();
+        return changeTag('');
       });
   },
   locationEvent() {
-    return getLocation().then((res) => {
-      now({ location: res, addressName: res.addressName });
-      return Promise.resolve(res);
-    });
+    const { chooseInfo, getChooseInfo } = now(MapModel);
+    if (chooseInfo) {
+      return Promise.resolve();
+    } else {
+      return getChooseInfo();
+    }
   },
   getData() {
-    const { page, size, list } = now();
-    now({
-      loading: true,
-      list: page === 0 ? [] : list,
-    });
+    const { page, size, list, popularTag } = now();
     const { loading, warnning, clearLoading } = now(Toast);
     loading();
-
+    const { chooseInfo } = now(MapModel);
+    const { location } = chooseInfo;
+    const params = { latitude: location.lat, longitude: location.lng };
+    if (popularTag) {
+      params.filter = popularTag;
+    }
     request
-      .get('/merchant/showAll', {
-        params: {
-          page,
-          size,
-          latitude: '1',
-          longitude: '1',
-          // popularTag: '首单立减',
-        },
+      .get('/settings/show', {
+        params,
       })
       .then((res) => {
         clearLoading();
         now({
-          list: list.concat(res.content),
-          finish: res.last,
-          page: res.last ? page : page + 1,
+          list: list.concat(res),
+          finish: true,
+          page: 0,
           loading: false,
         });
       })
@@ -87,6 +96,15 @@ const HomeModel = (now) => ({
   changeChooseMap(info) {
     console.log(info);
   },
+  changeTag(type) {
+    now({
+      popularTag: type,
+      page: 0,
+      list: [],
+    });
+    const { getData } = now();
+    getData();
+  },
 });
 
 export default HomeModel;

+ 23 - 14
screens/Main/HomeScreen.jsx

@@ -21,16 +21,18 @@ import HomeModel from './Home/model';
 import Icon from '../../components/SvgIcon';
 
 export default function HomeScreen({ navigation }) {
-  const { initHome } = useModel(HomeModel);
+  const { initHome, list, loadingTop } = useModel(HomeModel, [
+    'list',
+    'loadingTop',
+  ]);
+
+  const [topHeight, settopHeight] = React.useState(100);
 
   const animatedScrollYValue = React.useRef(new Animated.Value(0)).current;
   useMount(() => {
     initHome();
   });
 
-
-  const tabBox = React.createRef();
-
   return (
     <>
       <Div h={Constants.statusBarHeight} bg="white" />
@@ -67,16 +69,23 @@ export default function HomeScreen({ navigation }) {
             搜索
           </Button>
         </Div>
-        <Banner />
-        <MenuCom />
-        <SpecialArea />
-        <RecommendStore />
-        <View style={{ zIndex: 100 }} ref={tabBox}>
-          <ListTop
-            animatedScrollYValue={animatedScrollYValue}
-            tabBox={tabBox}
-          />
-        </View>
+        {!loadingTop && (
+          <View
+            onLayout={({ nativeEvent }) => {
+              settopHeight(nativeEvent.layout.height);
+            }}
+          >
+            <Banner />
+            <MenuCom />
+            <SpecialArea />
+            <RecommendStore />
+          </View>
+        )}
+
+        <ListTop
+          animatedScrollYValue={animatedScrollYValue}
+          topHeight={topHeight}
+        />
         <List />
       </Animated.ScrollView>
       <FAB

+ 32 - 0
screens/Main/MerchantsListScreen.jsx

@@ -0,0 +1,32 @@
+import * as WebBrowser from 'expo-web-browser';
+import * as React from 'react';
+import { Div, Button, Image, Text, Avatar } from 'react-native-magnus';
+import { ScrollView } from 'react-native-gesture-handler';
+
+import useModel from 'flooks';
+import HomeModel from './Home/model';
+
+import Header from '../../components/Header';
+
+export default function MerchantsListScreen() {
+  const { allnewMerchants } = useModel(HomeModel, ['allnewMerchants']);
+
+  return (
+    <>
+      <Header title="新店推荐" />
+      <ScrollView
+        contentContainerStyle={{
+          flexGrow: 1,
+          backgroundColor: '#fff',
+        }}
+      >
+				<Div >
+
+				</Div>
+        {/* {allnewMerchants.map((item) => {
+          return <MerchantCom key={item.id} info={item} isCollection />;
+        })} */}
+      </ScrollView>
+    </>
+  );
+}

+ 30 - 174
screens/Map/MapScreen.jsx

@@ -24,191 +24,47 @@ import { alert } from '../../Utils/TotastUtils';
 export default function MapScreen({ navigation }) {
   const key = 'c4faf80125b298f93bbc1477db10e69c';
   const html = `
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
+<head lang="zh-CN">
 	<meta charset="UTF-8">
-	<meta name="viewport" content="width=device-width, initial-scale=1.0">
-	<meta http-equiv="X-UA-Compatible" content="ie=edge">
-	<title>DOMOverlay</title>
-</head>
-<script charset="utf-8"
-	src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=GLFBZ-ZR2W6-76XSA-MF7CQ-GDJ6Z-6FB5K"></script>
-<style type="text/css">
-	html,
-	body {
-		height: 100%;
-		margin: 0px;
-		padding: 0px;
-	}
-
-	#container {
-		width: 100%;
-		height: 100%;
-	}
-</style>
-
-<body onload="initMap()">
-	<div id="container"></div>
-	<script>
-		var SVG_NS = 'http://www.w3.org/2000/svg';
-		// 自定义环状饼图 - 继承DOMOverlay
-		function Donut(options) {
-			TMap.DOMOverlay.call(this, options);
+	<meta name="viewport"
+		content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
+	<meta name="mobile-web-app-capable" content="yes">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<meta name="apple-mobile-web-app-status-bar-style" content="black">
+	<meta name="format-detection" content="address=no">
+	<script type="text/javascript"
+		src="https://3gimg.qq.com/lightmap/components/locationPicker2/js/main-62c2e3b971.js"></script>
+	<title>locationPicker Components Demo - iframe</title>
+	<style>
+		* {
+			margin: 0;
+			padding: 0;
 		}
 
-		Donut.prototype = new TMap.DOMOverlay();
-
-		// 初始化
-		Donut.prototype.onInit = function (options) {
-			this.position = options.position;
-			this.data = options.data;
-			this.minRadius = options.minRadius || 0;
-			this.maxRadius = options.maxRadius || 50;
-		};
-
-		// 销毁时需解绑事件监听
-		Donut.prototype.onDestroy = function () {
-			if (this.onClick) {
-				this.dom.removeEventListener(this.onClick);
-			}
-		};
-
-		// 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素
-		Donut.prototype.createDOM = function () {
-			let svg = document.createElementNS(SVG_NS, 'svg');
-			svg.setAttribute('version', '1.1');
-			svg.setAttribute('baseProfile', 'full');
-
-			let r = this.maxRadius;
-			svg.setAttribute('viewBox', [-r, -r, r * 2, r * 2].join(' '));
-			svg.setAttribute('width', r * 2);
-			svg.setAttribute('height', r * 2);
-			svg.style.cssText = 'position:absolute;top:0px;left:0px;';
-
-			let donut = createDonut(this.data, this.minRadius, this.maxRadius);
-			svg.appendChild(donut);
-
-			// click事件监听
-			this.onClick = () => {
-				// DOMOverlay继承自EventEmitter,可以使用emit触发事件
-				this.emit('click');
-			};
-			svg.addEventListener('click', this.onClick);
-			return svg;
-		};
-
-		// 更新DOM元素,在地图移动/缩放后执行
-		Donut.prototype.updateDOM = function () {
-			if (!this.map) {
-				return;
-			}
-
-			// 经纬度坐标转容器像素坐标
-			let pixel = this.map.projectToContainer(this.position);
-
-			// 使饼图中心点对齐经纬度坐标点
-			let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
-			let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
-			this.dom.style.transform = 'translate('+left+', '+top+')';
-		};
-
-		// 使用SVG创建环状饼图
-		function createDonut(data, minRadius, maxRadius) {
-			const colorList = [
-				'#7AF4FF',
-				'#67D7FF',
-				'#52B5FF',
-				'#295BFF'
-			];
-			let sum = data.reduce((prev, curr) => prev + curr, 0);
-			let angle = 0;
-
-			let group = document.createElementNS(SVG_NS, "g");
-			data.forEach((d, i) => {
-				let delta = d / sum * Math.PI * 2;
-				color = colorList[i],
-					r = maxRadius,
-					startAngle = angle,
-					endAngle = angle + delta;
-				angle += delta;
-
-				// 对每个数据创建一个扇形
-				let fanShape = document.createElementNS(SVG_NS, 'path');
-				fanShape.setAttribute('style', 'fill: '+ color+';');
-				fanShape.setAttribute('d', [
-					'M0 0',
-					'L'+(r * Math.sin(startAngle))+(-r * Math.cos(startAngle)),
-					'A'+r+' '+r+' 0 '+(delta > Math.PI ? 1 : 0)+' 1 '+(r * Math.sin(endAngle))+' '+(-r * Math.cos(endAngle)),
-				].join(' ') + ' z');
-				group.appendChild(fanShape);
-			});
+		body,
+		html {
+			overflow: hidden;
+		}
+	</style>
 
-			// 在中心创建一个圆形
-			let circleShape = document.createElementNS(SVG_NS, 'circle');
-			circleShape.setAttribute('style', 'fill: #FFFFFF');
-			circleShape.setAttribute('cx', 0);
-			circleShape.setAttribute('cy', 0);
-			circleShape.setAttribute('r', minRadius);
-			group.appendChild(circleShape);
+</head>
 
-			// 绘制文字
-			let textShape = document.createElementNS(SVG_NS, 'text');
-			textShape.setAttribute('x', 0);
-			textShape.setAttribute('y', '0.3em');
-			textShape.setAttribute('text-anchor', 'middle');
-			textShape.innerHTML = sum;
-			group.appendChild(textShape);
+<body>
+	<!-- 通过 iframe 嵌入地图选点组件 -->
+	<iframe id="iframe" style="width:100vw;height:100vh" frameborder=0 scrolling="no"
+		src="https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=GLFBZ-ZR2W6-76XSA-MF7CQ-GDJ6Z-6FB5K&referer=Dingdong">
+	</iframe>
 
-			return group;
-		}
+	<script>
 
-		window.Donut = Donut;
-	</script>
-	<script type="text/javascript">
-		var map;
-		function initMap() {
-			// 初始化地图
-			map = new TMap.Map("container", {
-				zoom: 12, // 设置地图缩放级别
-				center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标
-			});
+		window.addEventListener('message', function (event) {
+			var loc = event.data;
+			window.ReactNativeWebView.postMessage(JSON.stringify(loc))
+		}, false);
 
-			let donutList = [
-				new Donut({
-					map,
-					position: new TMap.LatLng(39.96030543872138, 116.25809083213608),
-					data: [12, 24],
-					minRadius: 13,
-					maxRadius: 20
-				}),
-				new Donut({
-					map,
-					position: new TMap.LatLng(39.9986945980902, 116.33598362780685),
-					data: [23, 99, 101, 400],
-					minRadius: 25,
-					maxRadius: 35
-				}),
-				new Donut({
-					map,
-					position: new TMap.LatLng(40.02906301748584, 116.25499991104516),
-					data: [18, 41, 50],
-					minRadius: 20,
-					maxRadius: 28
-				})
-			];
 
-			donutList.forEach((donut, index) => {
-				donut.on('click', () => {
-					console.log('第'+index+'个环形图被点击,位置为'+donut.position);
-				});
-			});
-		}
 	</script>
 </body>
-
-</html>
 	`;
   return (
     <>

+ 2 - 3
screens/Main/SearchMapScreen.jsx → screens/Map/SearchMapScreen copy.jsx

@@ -15,11 +15,11 @@ import { Appbar } from 'react-native-paper';
 import { ScrollView } from 'react-native-gesture-handler';
 
 import useModel from 'flooks';
-import HomeModel from './Home/model';
 import { getSearch } from '../../Utils/MapUtils';
 
+// 搜索
+
 export default function SearchMapScreen({ navigation }) {
-  const { changeChooseMap } = useModel(HomeModel, []);
 
   const [points, setPoints] = React.useState([]);
 
@@ -90,7 +90,6 @@ export default function SearchMapScreen({ navigation }) {
                 key={item.id}
                 onPress={() => {
                   navigation.navigate('Home');
-                  changeChooseMap(item);
                 }}
               />
             );

+ 111 - 0
screens/Map/SearchMapScreen.jsx

@@ -0,0 +1,111 @@
+import * as WebBrowser from 'expo-web-browser';
+import * as React from 'react';
+import { StatusBar } from 'expo-status-bar';
+import {
+  Div,
+  Button,
+  Image,
+  Text,
+  Avatar,
+  Icon,
+  Input,
+} from 'react-native-magnus';
+import { Appbar } from 'react-native-paper';
+import { ScrollView } from 'react-native-gesture-handler';
+import { WebView } from 'react-native-webview';
+
+import useModel from 'flooks';
+import MapModel from './model';
+
+import Header from '../../components/Header';
+
+import { alert } from '../../Utils/TotastUtils';
+
+export default function MapScreen({ navigation }) {
+  const { changeChooseInfo } = useModel(MapModel, []);
+  const html = `
+<head lang="zh-CN">
+	<meta charset="UTF-8">
+	<meta name="viewport"
+		content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
+	<meta name="mobile-web-app-capable" content="yes">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<meta name="apple-mobile-web-app-status-bar-style" content="black">
+	<meta name="format-detection" content="address=no">
+	<script type="text/javascript"
+		src="https://3gimg.qq.com/lightmap/components/locationPicker2/js/main-62c2e3b971.js"></script>
+	<title>locationPicker Components Demo - iframe</title>
+	<style>
+		* {
+			margin: 0;
+			padding: 0;
+		}
+
+		body,
+		html {
+			overflow: hidden;
+		}
+	</style>
+
+</head>
+
+<body>
+	<!-- 通过 iframe 嵌入地图选点组件 -->
+	<iframe id="iframe" style="width:100vw;height:100vh" frameborder=0 scrolling="no"
+		src="https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=GLFBZ-ZR2W6-76XSA-MF7CQ-GDJ6Z-6FB5K&referer=Dingdong">
+	</iframe>
+
+	<script>
+
+		window.addEventListener('message', function (event) {
+			var loc = event.data;
+			window.ReactNativeWebView.postMessage(JSON.stringify(loc))
+		}, false);
+
+
+	</script>
+</body>
+	`;
+  return (
+    <>
+      <StatusBar backgroundColor="#fff" style="dark" translucent />
+
+      <Appbar.Header
+        theme={{ colors: { primary: '#fff' } }}
+        style={{
+          elevation: 0,
+          shadowOffset: {
+            width: 0,
+            height: 0,
+          },
+          shadowOpacity: 0,
+          zIndex: 2,
+        }}
+      >
+        <Appbar.BackAction onPress={navigation.goBack} />
+        <Appbar.Content
+          title="选择收货地址"
+          titleStyle={{ textAlign: 'center', fontSize: 16 }}
+        />
+        <Div w={56} h={56} />
+      </Appbar.Header>
+      <WebView
+        source={{
+          html,
+        }}
+        style={{ flexGrow: 1, width: '100%' }}
+        onMessage={({ nativeEvent }) => {
+          const info = JSON.parse(nativeEvent.data);
+          changeChooseInfo({
+            addressName: info.poiname,
+            location: info.latlng,
+          });
+          navigation.navigate('Home');
+          // alert('', `您当前选择的是:${info.poiaddress}`, () => {
+          //   navigation.goBack();
+          // });
+        }}
+      />
+    </>
+  );
+}

+ 6 - 1
screens/Map/model.js

@@ -16,7 +16,7 @@ const MapModel = (now) => ({
   getNowLocation() {
     return getLocation().then((res) => {
       now({ locationInfo: res });
-      return Promise.reslove(res);
+      return Promise.resolve(res);
     });
   },
   searchInfo(searchKey, type, callBack) {
@@ -40,6 +40,11 @@ const MapModel = (now) => ({
       now({ chooseInfo: res });
     });
   },
+  changeChooseInfo(info) {
+    now({
+      chooseInfo: info,
+    });
+  },
 });
 
 export default MapModel;

+ 19 - 0
screens/Order/OrderDetailScreen.jsx

@@ -187,6 +187,25 @@ export default function OrderScreen({ navigation }) {
                 立即评价
               </Button>
             )}
+            {finish && (
+              <Button
+                fontSize="xs"
+                flex={1}
+                mx={5}
+                bg="white"
+                color="gray600"
+                borderColor="brand500"
+                borderWidth={1}
+                rounded={3}
+                onPress={() => {
+                  navigation.navigate('MerchantDetail', {
+                    merchantId: order.merchantId,
+                  });
+                }}
+              >
+                再来一单
+              </Button>
+            )}
           </Div>
         </View>
 

+ 88 - 26
screens/Order/OrderScreen.jsx

@@ -7,8 +7,10 @@ import { TouchableRipple } from 'react-native-paper';
 
 import { useCreation, useRequest } from '@umijs/hooks';
 import { useFocusEffect } from '@react-navigation/native';
-import Header from './Header'; // 头部
+import useModel from 'flooks';
+import Toast from '../../flooks/Toast';
 
+import Header from './Header'; // 头部
 import Time from '../../Utils/TimeUtils';
 import MapMarkImg from '../Map/MapMarkImg';
 import { getStatusInfo } from '../../Utils/OrderUtils';
@@ -16,6 +18,7 @@ import { getStatusInfo } from '../../Utils/OrderUtils';
 export default function OrderScreen({ navigation }) {
   const [orderList, setorderList] = React.useState();
 
+  const { success, warnning } = useModel(Toast, []);
   const orderRequest = useRequest('/orderInfo/my?sort=id,desc', {
     manual: true,
     onSuccess: (result) => {
@@ -43,12 +46,22 @@ export default function OrderScreen({ navigation }) {
             merchant={item.merchant}
             info={item}
             orderGoodsSpecs={item.orderGoodsSpecs}
-            goNext={() => {
-              navigation.navigate('OrderDetail', {
+            goNext={(name) => {
+              navigation.navigate(name || 'OrderDetail', {
                 orderId: item.id,
               });
             }}
+            goMerchant={() => {
+              navigation.navigate('MerchantDetail', {
+                merchantId: item.merchantId,
+              });
+            }}
             index={index}
+            connect={(type) => {
+              if (type === 'merchant') {
+                warnning('正在帮您联系商家');
+              }
+            }}
           />
         )}
         keyExtractor={(item) => item.id.toString()}
@@ -58,31 +71,48 @@ export default function OrderScreen({ navigation }) {
 }
 
 // 订单组件
-function Item({ merchant, info, goNext, orderGoodsSpecs }) {
+function Item({
+  merchant,
+  info,
+  goNext,
+  orderGoodsSpecs,
+  goMerchant,
+  connect,
+}) {
   const orderInfo =
     orderGoodsSpecs.length > 0 ? orderGoodsSpecs[0].goods.name : '';
 
   const statusInfo = getStatusInfo(info);
+
+  const finish = info.riderStatus === 'CARRY_OUT';
+
+  const Allfinish = info.status === 'COMPLETED';
   return (
-    <Button bg="hide" block p={0} mt={10} onPress={goNext}>
+    <Button bg="hide" block p={0} mt={10} onPress={() => goNext()}>
       <View style={styles.item}>
         <Div row>
-          <Image w={53} h={53} source={{ uri: merchant.logo }} />
+          <Button bg="hide" p={0} onPress={() => goMerchant()}>
+            <Image w={53} h={53} source={{ uri: merchant.logo }} />
+          </Button>
           <Div flex={1} ml={10}>
             <Div row>
               <Text fontSize="xl" flex={1} fontWeight="bold">
                 {merchant.name}
               </Text>
-              <Text fontSize="xs">
-                预计
-                <Text color="red500">
-                  {new Time(
-                    info.timeOfArrival,
-                    'yyyy-MM-DD HH:mm:ss'
-                  ).getFormat('HH:mm')}
+              {finish || Allfinish ? (
+                <Text fontSize="xs">已送达</Text>
+              ) : (
+                <Text fontSize="xs">
+                  预计
+                  <Text color="red500">
+                    {new Time(
+                      info.timeOfArrival,
+                      'yyyy-MM-DD HH:mm:ss'
+                    ).getFormat('HH:mm')}
+                  </Text>
+                  送达
                 </Text>
-                送达
-              </Text>
+              )}
             </Div>
             <Text fontSize="xs" my={10}>
               订单时间: {info.orderTime}
@@ -103,17 +133,49 @@ function Item({ merchant, info, goNext, orderGoodsSpecs }) {
           info={info}
         />
         <Flex justify="end" style={styles.btns}>
-          <Button
-            w={100}
-            fontSize="xs"
-            bg="white"
-            color="gray600"
-            borderColor="brand500"
-            borderWidth={1}
-            rounded={3}
-          >
-            联系商家
-          </Button>
+          {finish && !Allfinish ? (
+            <Button
+              w={100}
+              fontSize="xs"
+              bg="white"
+              color="gray600"
+              borderColor="brand500"
+              borderWidth={1}
+              rounded={3}
+              onPress={() => goNext('Evaluate')}
+            >
+              立即评价
+            </Button>
+          ) : (
+            <Button
+              w={100}
+              fontSize="xs"
+              bg="white"
+              color="gray600"
+              borderColor="brand500"
+              borderWidth={1}
+              rounded={3}
+              onPress={() => connect('merchant')}
+            >
+              联系商家
+            </Button>
+          )}
+
+          {finish && (
+            <Button
+              w={100}
+              fontSize="xs"
+              bg="white"
+              color="gray600"
+              borderColor="brand500"
+              borderWidth={1}
+              rounded={3}
+              ml={10}
+              onPress={goMerchant}
+            >
+              再来一单
+            </Button>
+          )}
         </Flex>
       </View>
     </Button>

+ 3 - 0
screens/Order/model.js

@@ -1,5 +1,6 @@
 import request from '../../Utils/RequestUtils';
 import Toast from '../../flooks/Toast';
+import MapModel from '../Map/model';
 
 const OrderModel = (now) => ({
   // 投诉
@@ -65,6 +66,8 @@ const OrderModel = (now) => ({
   submitOrder(shoppingCartId, addressId, payMethod, remark) {
     const { loading, warnning, success } = now(Toast);
     loading();
+    const { chooseInfo } = now(MapModel);
+    const { location } = chooseInfo;
     return request
       .post(`/orderInfo/order`, {
         data: {

+ 2 - 2
screens/User/CollectionScreen.jsx

@@ -34,7 +34,6 @@ export default function CollectionScreen() {
       },
     }
   );
-
   return (
     <>
       <Header title="我的收藏" />
@@ -53,9 +52,10 @@ export default function CollectionScreen() {
           return (
             <MerchantCom
               key={item.id}
-              id={item.id}
+              CollectionId={item.id}
               isCollection
               info={item.merchant}
+              freash={CollectionRequest.run}
             />
           );
         })}

+ 2 - 2
screens/User/SettingScreen.jsx

@@ -56,9 +56,9 @@ export default function LinksScreen() {
           </Div>
         </TouchableRipple>
 
-        <Button block bg="brand500" m={10} onPress={logout}>
+        {/* <Button block bg="brand500" m={10} onPress={logout}>
           退出登录
-        </Button>
+        </Button> */}
       </ScrollView>
     </>
   );

+ 25 - 5
screens/User/UserScreen.jsx

@@ -6,6 +6,7 @@ import { List } from 'react-native-paper';
 import { ScrollView } from 'react-native-gesture-handler';
 import { StatusBar } from 'expo-status-bar';
 import Constants from 'expo-constants';
+import { useCreation } from '@umijs/hooks';
 
 import useModel from 'flooks';
 import User from '../../flooks/User'; // detail模块通用方法
@@ -19,6 +20,22 @@ export default function UserScreen({ navigation }) {
   const { avatar, nickname, username } = userInfo || {
     nickname: '未登录',
   };
+  const showNick = useCreation(() => {
+    if (nickname) {
+      return nickname;
+    } else {
+      return showUser;
+    }
+  }, [nickname]);
+
+  const showUser = useCreation(() => {
+    let name = username.substring(4, 7);
+    if (name) {
+      return username.replace(name, '****');
+    } else {
+      return username;
+    }
+  }, [username]);
   return (
     <>
       <StatusBar backgroundColor="transparent" style="dark" translucent />
@@ -44,17 +61,20 @@ export default function UserScreen({ navigation }) {
                 }}
               />
             ) : (
-              <Avatar bg="red300" color="white" h={53} w={53}>
-                {nickname ? nickname.substr(0, 1) : ''}
-              </Avatar>
+              <Image
+                h={53}
+                w={53}
+                rounded="circle"
+                source={require('../../assets/images/logo_1.png')}
+              />
             )}
           </Button>
           <Div justifyContent="space-between" ml={10}>
             <Text fontSize="xl" fontWeight="bold" textAlign="left">
-              {nickname}
+              {showNick}
             </Text>
             <Text fontSize="sm" textAlign="left">
-              叮咚外卖{username}
+              叮咚外卖{showUser}
             </Text>
           </Div>
         </Div>