Răsfoiți Sursa

首页接口

panhui 5 ani în urmă
părinte
comite
be7237f864

+ 13 - 0
Utils/TimeUtils.js

@@ -0,0 +1,13 @@
+import moment from 'moment';
+
+export default class Time {
+  constructor(time = new Date(), format = '') {
+    this.time = moment(time, format);
+  }
+
+  getNowTime(format) {
+    return moment(this.time.format('X') - moment().format('X'), 'X').format(
+      format
+    );
+  }
+}

+ 23 - 0
components/CountDown .js

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

+ 2 - 2
components/SvgIcon.js

@@ -30,8 +30,8 @@ function Icon(props) {
     : [];
   let transform = '';
   if (Flip) {
-    transform = `rotate(180 ${svgInfo.defaultWidth / 2} ${
-      svgInfo.defaultWidth / 2
+    transform = `rotate(180 ${(svgInfo.defaultWidth || 1024) / 2} ${
+      (svgInfo.defaultWidth || 1024) / 2
     })`;
   }
   const pathComList = () => {

+ 1 - 0
package.json

@@ -41,6 +41,7 @@
     "flooks": "^3.0.0",
     "i18n-js": "^3.7.0",
     "mockjs": "^1.1.0",
+    "moment": "^2.26.0",
     "qs": "^6.9.4",
     "react": "16.9.0",
     "react-dom": "16.9.0",

+ 9 - 0
screens/Detail/MerchantDetail.jsx

@@ -0,0 +1,9 @@
+import * as WebBrowser from 'expo-web-browser'
+import * as React from 'react'
+import { StyleSheet, View } from 'react-native'
+
+export default function LinksScreen() {
+	return <View />
+}
+
+const styles = StyleSheet.create({})

+ 15 - 0
screens/Detail/index.js

@@ -0,0 +1,15 @@
+import * as WebBrowser from 'expo-web-browser';
+import * as React from 'react';
+import MerchantDetail from './MerchantDetail';
+
+export default function Bank(Screen) {
+  return (
+    <>
+      <Screen
+        name="MerchantDetail"
+        component={MerchantDetail}
+        initialParams={{ merchantId: 189 }}
+      />
+    </>
+  );
+}

+ 18 - 19
screens/Main/Home/List.jsx

@@ -4,8 +4,10 @@ import { StyleSheet, View } from 'react-native';
 import { WingBlank, Flex } from '@ant-design/react-native';
 import { Menu } from 'react-native-paper';
 import { useBoolean } from '@umijs/hooks';
+import useModel from 'flooks';
 import Button from '../../../components/Button';
 import MerchantCom from './MerchantCom';
+import HomeModel from './model';
 
 const firstMenus = new Map([
   ['综合排序', { id: 1 }],
@@ -19,21 +21,31 @@ const firstMenus = new Map([
 ]);
 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.forEach((value, key) => {
+    return [..._map.keys()].map((item, index) => {
       return (
         <Menu.Item
-          key={value.id}
+          key={index}
           onPress={() => {
-            console.log(value.id);
+            console.log(item.id);
           }}
-          title={key}
+          title={item}
         />
       );
     });
   };
 
+  const MerchantComList = (_list) => {
+    return _list.map((item) => {
+      return <MerchantCom key={item.id} />;
+    });
+  };
+
   return (
     <WingBlank>
       <Flex>
@@ -62,18 +74,7 @@ export default function List() {
             </Button>
           }
         >
-          <Menu.Item
-            onPress={() => {
-              console.log('综合排序');
-            }}
-            title="综合排序"
-          />
-          <Menu.Item
-            onPress={() => {
-              console.log('好评优先');
-            }}
-            title="好评优先"
-          />
+          {menuMap(firstMenus)}
         </Menu>
         <Button
           text
@@ -104,9 +105,7 @@ export default function List() {
         </Button>
       </Flex>
 
-      <View>
-        <MerchantCom />
-      </View>
+      <View>{MerchantComList(list)}</View>
     </WingBlank>
   );
 }

+ 17 - 70
screens/Main/Home/Menu.jsx

@@ -1,92 +1,39 @@
 import * as WebBrowser from 'expo-web-browser';
 import * as React from 'react';
-import { StyleSheet, View } from 'react-native';
+import { StyleSheet } from 'react-native';
 import { Flex, WingBlank } from '@ant-design/react-native';
 import { Card } from 'react-native-paper';
+import useModel from 'flooks';
+import HomeModel from './model';
 import Text from '../../../components/Text';
 
 export default function RecommendStore() {
-  return (
-    <WingBlank style={{ marginTop: 15, marginBottom: 5 }}>
-      <Flex style={styles.content} justify="between">
-        <Text size="s1" bold>
-          新店推荐
-        </Text>
-        <Text size="c2">更多新店 〉</Text>
-      </Flex>
+  const { categories } = useModel(HomeModel);
 
-      <Flex style={styles.content2}>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: 'https://picsum.photos/700' }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                按摩
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
+  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: 'https://picsum.photos/700' }}
+              source={{ uri: item.icon }}
             />
             <Card.Content style={styles.main2}>
               <Text size="c2" type="info" center>
-                按摩
+                {item.name}
               </Text>
             </Card.Content>
           </Card>
         </Flex.Item>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: 'https://picsum.photos/700' }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                按摩
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: 'https://picsum.photos/700' }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                按摩
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: 'https://picsum.photos/700' }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                按摩
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-      </Flex>
+      );
+    });
+  };
+
+  return (
+    <WingBlank style={{ marginTop: 15, marginBottom: 5 }}>
+      <Flex style={styles.content2}>{cardList(categories)}</Flex>
     </WingBlank>
   );
 }

+ 22 - 63
screens/Main/Home/RecommendStore.jsx

@@ -3,80 +3,26 @@ 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 useModel from 'flooks';
+import HomeModel from './model';
 import Text from '../../../components/Text';
 
 export default function RecommendStore() {
-  return (
-    <WingBlank style={{ marginTop: 15, marginBottom: 5 }}>
-      <Flex style={styles.content} justify="between">
-        <Text size="s1" bold>
-          新店推荐
-        </Text>
-        <Text size="c2">更多新店 〉</Text>
-      </Flex>
+  const { newMerchants } = useModel(HomeModel);
 
-      <Flex style={styles.content2}>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: 'https://picsum.photos/700' }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                麦当劳(奥体大街)
-              </Text>
-              <Text size="c2" color="#FF6C00" center>
-                1.1km
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
+  const cards = (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: 'https://picsum.photos/700' }}
+              source={{ uri: item.logo }}
             />
             <Card.Content style={styles.main2}>
               <Text size="c2" type="info" center>
-                麦当劳(奥体大街)
-              </Text>
-              <Text size="c2" color="#FF6C00" center>
-                1.1km
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: 'https://picsum.photos/700' }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                麦当劳(奥体大街)
-              </Text>
-              <Text size="c2" color="#FF6C00" center>
-                1.1km
-              </Text>
-            </Card.Content>
-          </Card>
-        </Flex.Item>
-        <Flex.Item style={{ paddingHorizontal: 5 }}>
-          <Card elevation={0} style={styles.card}>
-            <Card.Cover
-              style={styles.image2}
-              resizeMode="cover"
-              source={{ uri: 'https://picsum.photos/700' }}
-            />
-            <Card.Content style={styles.main2}>
-              <Text size="c2" type="info" center>
-                麦当劳(奥体大街)
+                {item.showName}
               </Text>
               <Text size="c2" color="#FF6C00" center>
                 1.1km
@@ -84,7 +30,20 @@ export default function RecommendStore() {
             </Card.Content>
           </Card>
         </Flex.Item>
+      );
+    });
+  };
+
+  return (
+    <WingBlank style={{ marginTop: 15, marginBottom: 5 }}>
+      <Flex style={styles.content} justify="between">
+        <Text size="s1" bold>
+          新店推荐
+        </Text>
+        <Text size="c2">更多新店 〉</Text>
       </Flex>
+
+      <Flex style={styles.content2}>{cards(newMerchants)}</Flex>
     </WingBlank>
   );
 }

+ 57 - 92
screens/Main/Home/SpecialArea.jsx

@@ -3,116 +3,81 @@ 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 useModel from 'flooks';
+import HomeModel from './model';
 import Text from '../../../components/Text';
+import CountDown from '../../../components/CountDown ';
 
 // 优惠专区
 export default function SpecialArea() {
+  const { promote1, promote2, timeTag } = useModel(HomeModel);
+  const promote1Card = (list) => {
+    return list.map((item) => {
+      const merchant = item.merchant || {};
+      return (
+        <Flex.Item key={item.id} style={{ paddingHorizontal: 1.5 }}>
+          <Card>
+            <Card.Cover
+              style={styles.image}
+              resizeMode="cover"
+              source={{ uri: merchant.logo }}
+            />
+            <Card.Content>
+              <Text size="s1">{merchant.name}</Text>
+              <Text size="c2">
+                倒计时
+                <CountDown
+                  endTime={item.endDateTime}
+                  format="yyyy-MM-DD HH:mm:ss"
+                  valueFormat="D天 HH时mm分ss秒"
+                  size="c2"
+                  type="error"
+                />
+              </Text>
+            </Card.Content>
+          </Card>
+        </Flex.Item>
+      );
+    });
+  };
+
+  const promote2Card = (list) => {
+    return list.map((item) => {
+      const merchant = item.merchant || {};
+      return (
+        <Flex.Item key={item.id} style={{ paddingHorizontal: 1.5 }}>
+          <Card>
+            <Card.Cover
+              style={styles.image2}
+              resizeMode="cover"
+              source={{ uri: merchant.logo }}
+            />
+            <Card.Content style={styles.main2}>
+              <Text size="c2">{merchant.name}</Text>
+            </Card.Content>
+          </Card>
+        </Flex.Item>
+      );
+    });
+  };
   return (
     <>
       <WingBlank style={{ marginTop: 10, marginBottom: 5 }}>
         <Text size="s1" bold>
           优惠专区
         </Text>
-        <Flex style={styles.content}>
-          <Flex.Item style={{ paddingHorizontal: 1.5 }}>
-            <Card>
-              <Card.Cover
-                style={styles.image}
-                resizeMode="cover"
-                source={{ uri: 'https://picsum.photos/700' }}
-              />
-              <Card.Content>
-                <Text size="s1">麦当劳(奥体大街)</Text>
-                <Text size="c2">
-                  倒计时
-                  <Text size="c2" type="error">
-                    {' '}
-                    15小时20分43秒
-                  </Text>
-                </Text>
-              </Card.Content>
-            </Card>
-          </Flex.Item>
-          <Flex.Item style={{ paddingHorizontal: 1.5 }}>
-            <Card>
-              <Card.Cover
-                style={styles.image}
-                resizeMode="cover"
-                source={{ uri: 'https://picsum.photos/700' }}
-              />
-              <Card.Content>
-                <Text size="s1">麦当劳(奥体大街)</Text>
-                <Text size="c2">
-                  倒计时
-                  <Text size="c2" type="error">
-                    {' '}
-                    15小时20分43秒
-                  </Text>
-                </Text>
-              </Card.Content>
-            </Card>
-          </Flex.Item>
-        </Flex>
-        <Flex style={styles.content2}>
-          <Flex.Item style={{ paddingHorizontal: 1.5 }}>
-            <Card>
-              <Card.Cover
-                style={styles.image2}
-                resizeMode="cover"
-                source={{ uri: 'https://picsum.photos/700' }}
-              />
-              <Card.Content style={styles.main2}>
-                <Text size="c2">麦当劳(奥体大街)</Text>
-              </Card.Content>
-            </Card>
-          </Flex.Item>
-          <Flex.Item style={{ paddingHorizontal: 1.5 }}>
-            <Card>
-              <Card.Cover
-                style={styles.image2}
-                resizeMode="cover"
-                source={{ uri: 'https://picsum.photos/700' }}
-              />
-              <Card.Content style={styles.main2}>
-                <Text size="c2">麦当劳(奥体大街)</Text>
-              </Card.Content>
-            </Card>
-          </Flex.Item>
-          <Flex.Item style={{ paddingHorizontal: 1.5 }}>
-            <Card>
-              <Card.Cover
-                style={styles.image2}
-                resizeMode="cover"
-                source={{ uri: 'https://picsum.photos/700' }}
-              />
-              <Card.Content style={styles.main2}>
-                <Text size="c2">麦当劳(奥体大街)</Text>
-              </Card.Content>
-            </Card>
-          </Flex.Item>
-          <Flex.Item style={{ paddingHorizontal: 1.5 }}>
-            <Card>
-              <Card.Cover
-                style={styles.image2}
-                resizeMode="cover"
-                source={{ uri: 'https://picsum.photos/700' }}
-              />
-              <Card.Content style={styles.main2}>
-                <Text size="c2">麦当劳(奥体大街)</Text>
-              </Card.Content>
-            </Card>
-          </Flex.Item>
-        </Flex>
+        <Flex style={styles.content}>{promote1Card(promote1)}</Flex>
+        <Flex style={styles.content2}>{promote2Card(promote2)}</Flex>
       </WingBlank>
       <WingBlank style={{ marginTop: 15, marginBottom: 5 }}>
         <Text size="s1" bold>
-          优惠专区2
+          优惠专区
         </Text>
 
         <Card.Cover
           style={styles.imageMain}
           resizeMode="cover"
-          source={{ uri: 'https://picsum.photos/700' }}
+          source={{ uri: timeTag.icon }}
         />
       </WingBlank>
     </>

+ 56 - 5
screens/Main/Home/model.js

@@ -1,21 +1,72 @@
 import request from '../../../Utils/RequestUtils';
+import Toast from '../../../flooks/Toast';
 
 const HomeModel = (now) => ({
   bannerList: [],
-  initBanner() {
+  categories: [],
+  newMerchants: [],
+  promote1: [],
+  promote2: [],
+  timeTag: {},
+  list: [],
+  page: 0,
+  size: 20,
+  finish: false,
+  loading: false,
+  initHome() {
     now({
       bannerList: [],
+      categories: [],
+      newMerchants: [],
+      promote1: [],
+      promote2: [],
+      timeTag: {},
     });
     return request
-      .get('/banner/all', {
-        sort: {
-          type: 'TOP',
+      .get('/merchant/index', {
+        params: { latitude: '', longitude: '' },
+      })
+      .then((res) => {
+        now({
+          bannerList: res.banner,
+          categories: res.categories.slice(0, 5),
+          newMerchants: res.newMerchants.slice(0, 4),
+          promote1: res.promote1.slice(0, 2),
+          promote2: res.promote2.slice(0, 4),
+          timeTag: res.timeTag,
+        });
+      });
+  },
+  getData() {
+    const { page, size, list } = now();
+    now({
+      loading: true,
+      list: page === 0 ? [] : list,
+    });
+    const { loading, warnning, clearLoading } = now(Toast);
+    loading();
+
+    request
+      .get('/merchant/showAll', {
+        params: {
+          page,
+          size,
+          latitude: '',
+          longitude: '',
+          popularTag: '首单立减',
         },
       })
       .then((res) => {
+        clearLoading();
         now({
-          bannerList: res.content,
+          list: list.concat(res.content),
+          finish: res.last,
+          page: res.last ? page : page + 1,
+          loading: false,
         });
+      })
+      .catch((e) => {
+        warnning(e.error);
       });
   },
 });

+ 36 - 24
screens/Main/HomeScreen.jsx

@@ -3,7 +3,7 @@ import * as React from 'react';
 import { StyleSheet, View } from 'react-native';
 import { ScrollView } from 'react-native-gesture-handler';
 import { WingBlank, Flex } from '@ant-design/react-native';
-import { Menu } from 'react-native-paper';
+import { FAB } from 'react-native-paper';
 import useModel from 'flooks';
 import { useMount, useToggle } from '@umijs/hooks';
 import Button from '../../components/Button';
@@ -15,37 +15,42 @@ import List from './Home/List';
 import RecommendStore from './Home/RecommendStore';
 import SpecialArea from './Home/SpecialArea';
 import HomeModel from './Home/model';
-
-const tabs = [
-  { title: 'First Tab' },
-  { title: 'Second Tab' },
-  { title: 'Third Tab' },
-];
+import Icon from '../../components/SvgIcon';
 
 export default function HomeScreen() {
-  const { initBanner } = useModel(HomeModel, []);
+  const { initHome } = useModel(HomeModel, []);
 
   useMount(() => {
-    initBanner();
+    initHome();
   });
 
   return (
-    <ScrollView style={styles.container}>
-      <Header />
-      <WingBlank>
-        <Button block size="small" type="info" onPress={() => {}}>
-          搜索
-        </Button>
-      </WingBlank>
+    <>
+      <ScrollView style={styles.container}>
+        <Header />
+        <WingBlank>
+          <Button block size="small" type="info" onPress={() => {}}>
+            搜索
+          </Button>
+        </WingBlank>
 
-      <View style={styles.main}>
-        <Banner />
-        <MenuCom />
-        <SpecialArea />
-        <RecommendStore />
-      </View>
-      <List />
-    </ScrollView>
+        <View style={styles.main}>
+          <Banner />
+          <MenuCom />
+          <SpecialArea />
+          <RecommendStore />
+        </View>
+        <List />
+      </ScrollView>
+      <FAB
+        style={styles.fab}
+        icon={({ size }) => (
+          <Icon width={size} height={size} name="cart" type="info" />
+        )}
+        color="#fff"
+        onPress={() => console.log('Pressed')}
+      />
+    </>
   );
 }
 HomeScreen.navigationOptions = {
@@ -69,4 +74,11 @@ const styles = StyleSheet.create({
     paddingTop: 10,
     width: '100%',
   },
+  fab: {
+    position: 'absolute',
+    margin: 16,
+    right: 0,
+    bottom: 0,
+    backgroundColor: '#fff',
+  },
 });