Browse Source

feat: 更新

zqf 5 months ago
parent
commit
042ea67526

+ 3 - 0
src/App.vue

@@ -13,6 +13,9 @@ export default {
 </script>
 
 <style>
+@import 'tailwindcss/base';
+@import 'tailwindcss/components';
+@import 'tailwindcss/utilities';
 /*每个页面公共css */
 ::v-deep.rich-txt-img {
   max-width: 100%;

+ 10 - 8
src/api/common.js

@@ -1,9 +1,9 @@
-import { request } from "@/utils/request.js";
+import { request } from '@/utils/request.js';
 
 export const getBannerList = (data) => {
   return request({
-    url: "/website/basic/bannerList",
-    method: "GET",
+    url: '/website/basic/bannerList',
+    method: 'GET',
     data,
     showLoading: false,
     showErrorToast: false,
@@ -12,15 +12,17 @@ export const getBannerList = (data) => {
 
 export const getTravelProjectList = (data) => {
   return request({
-    url: "/website/tourism/project/list",
-    method: "GET",
+    url: '/website/tourism/project/list',
+    method: 'GET',
     data,
   });
 };
 export const getDirectoryList = (data) => {
+  const query = `?${Object.keys(data)
+    .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)
+    .join('&')}`;
   return request({
-    url: "/website/basic/directoryList",
-    method: "GET",
-    data,
+    url: `/website/basic/directoryList${query}`,
+    method: 'GET',
   });
 };

+ 40 - 0
src/components/Home/Banner.vue

@@ -0,0 +1,40 @@
+<template>
+  <div>
+    <swiper class="swiper" circular autoplay :interval="5000">
+      <swiper-item
+        v-for="item in bannerList"
+        :key="item.id"
+        class="swiper-item"
+      >
+        <image :src="item.imgUrlsAfterConvert[0]" mode="aspectFill" />
+      </swiper-item>
+    </swiper>
+  </div>
+</template>
+
+<script setup>
+import { getBannerList } from '@/api/common';
+
+const bannerList = ref([]);
+async function requestBannerList() {
+  const { data } = await getBannerList({ belongTab: 10 });
+  bannerList.value = data.dataList;
+}
+
+onMounted(() => {
+  requestBannerList();
+});
+</script>
+
+<style lang="scss" scoped>
+.swiper {
+  height: 500rpx;
+  .swiper-item {
+    height: 100%;
+    image {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+</style>

+ 53 - 0
src/components/Travel/FirstLevelDirectoryMenu/index.vue

@@ -0,0 +1,53 @@
+<template>
+  <div class="flex flex-col w-80 bg-[#F6F8FA] box-border">
+    <div
+      v-for="item in menuData"
+      :key="item.id"
+      @click="handleChange(item)"
+      class="h-40 flex items-center rounded-r-lg justify-start pl-10 transition-all text-base"
+      :class="[
+        currentMenu.id === item.id
+          ? 'bg-primary text-white'
+          : 'bg-transparent text-black-3',
+      ]"
+    >
+      {{ item.menuName }}
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { getDirectoryList } from '@/api/common';
+const emit = defineEmits(['change']);
+
+const dataList = ref([]);
+async function requestDirectoryList(parentId) {
+  const { data } = await getDirectoryList({parentId});
+  dataList.value = data.dataList;
+}
+
+const firstMenu = {
+  menuName: '全部',
+  id: null,
+};
+
+onLoad((option) => {
+  requestDirectoryList(option.parentId || 0);
+});
+
+const menuData = computed(() => {
+  return [
+    firstMenu,
+    ...(dataList.value.filter((x) => x.id != '16' && x.id != '10') ?? []),
+  ];
+});
+
+const currentMenu = ref(firstMenu);
+
+function handleChange(item) {
+  currentMenu.value = item;
+  emit('change', item);
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 3 - 4
src/pages/labour/index.vue

@@ -13,9 +13,7 @@
 </template>
 
 <script setup>
-import {
-  getBannerList,
-} from "@/api/common";
+import { getBannerList } from '@/api/common';
 
 const bannerList = ref([]);
 async function requestBannerList() {
@@ -38,4 +36,5 @@ onMounted(() => {
       height: 100%;
     }
   }
-}</style>
+}
+</style>

+ 59 - 29
src/pages/travel/index.vue

@@ -1,41 +1,71 @@
 <template>
-  <div>
-    <swiper class="swiper" circular autoplay :interval="5000">
-      <swiper-item
-        v-for="item in bannerList"
-        :key="item.id"
-        class="swiper-item"
-      >
-        <image :src="item.imgUrlsAfterConvert[0]" mode="aspectFill" />
-      </swiper-item>
-    </swiper>
+  <div class="flex flex-col h-screen-reduced">
+    <HomeBanner class="h-250 shrink" />
+    <div
+      class="z-[999] flex-1 flex overflow-auto pt-20 -mt-15 bg-white rounded-t-2xl"
+    >
+      <TravelFirstLevelDirectoryMenu
+        class="shrink"
+        @change="handleMenuChange"
+      />
+      <div class="flex-1 pt-10 flex flex-col">
+        <div class="text-black-3 pl-10 text-base font-semibold shrink">
+          热门目的地
+        </div>
+        <div
+          class="flex flex-wrap px-10 items-start gap-x-10 gap-y-15 mt-15 pb-30 flex-1 content-start overflow-auto"
+        >
+          <div
+            v-for="item in rightData"
+            :key="item"
+            :to="`/travel/${item.id}?menuName=${item.menuName}`"
+            class="flex flex-1 flex-col w-83 aspect-1 space-y-8 art items-center"
+          >
+            <image
+              :src="
+                item.hotPictureUrlsAfterConvert?.length
+                  ? item.hotPictureUrlsAfterConvert[0]
+                  : ''
+              "
+              mode="widthFix"
+              class="aspect-[84/63] h-62 w-full object-cover rounded-lg overflow-hidden"
+            />
+            <span class="text-sm text-black-3 truncate">{{
+              item.menuName
+            }}</span>
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <script setup>
-import {
-  getBannerList,
-} from "@/api/common";
+import HomeBanner from '../../components/Home/Banner.vue';
+import TravelFirstLevelDirectoryMenu from '../../components/Travel/FirstLevelDirectoryMenu/index.vue';
+import { getDirectoryList } from '@/api/common';
 
-const bannerList = ref([]);
-async function requestBannerList() {
-  const { data } = await getBannerList({ belongTab: 10 });
-  bannerList.value = data.dataList;
+function handleMenuChange(menu) {
+  getRightData(menu.id);
 }
 
-onMounted(() => {
-  requestBannerList();
+const rightData = ref([]);
+
+async function getRightData(id) {
+  const { data } = await getDirectoryList({
+    parentId: id ?? '',
+    isAll: !id ? 1 : 0,
+  });
+  rightData.value = data.dataList;
+}
+
+onLoad((option) => {
+  getRightData(option.parentId);
 });
 </script>
 
 <style lang="scss" scoped>
-.swiper {
-  height: 500rpx;
-  .swiper-item {
-    height: 100%;
-    image {
-      width: 100%;
-      height: 100%;
-    }
-  }
-}</style>
+.h-screen-reduced {
+  height: calc(100vh - 50px);
+}
+</style>

+ 72 - 6
tailwind.config.js

@@ -1,14 +1,80 @@
 /** @type {import('tailwindcss').Config} */
+const generateSpacingMap = () => {
+  const tmpList = {};
+  for (let index = 0; index < 500; index++) {
+    tmpList[index] = `${index}px`;
+  }
+  return tmpList;
+};
 module.exports = {
   content: [
-    "./src/components/**/*.{js,vue,ts}",
-    "./src/layouts/**/*.vue",
-    "./src/pages/**/*.vue",
-    "./src/plugins/**/*.{js,ts}",
-    "./src/app.vue",
+    './src/components/**/*.{js,vue,ts}',
+    './src/layouts/**/*.vue',
+    './src/pages/**/*.vue',
+    './src/plugins/**/*.{js,ts}',
+    './src/app.vue',
   ],
   theme: {
-    extend: {},
+    spacing: generateSpacingMap(),
+    fontSize: {
+      sm: '12px',
+      base: '14px',
+      xl: '16px',
+      '2xl': '18px',
+      '3xl': '20px',
+      '4xl': '22px',
+      '5xl': '24px',
+      '6xl': '26px',
+      '7xl': '28px',
+      '8xl': '30px',
+    },
+    lineHeight: {
+      sm: '12px',
+      base: '14px',
+      xl: '16px',
+      '2xl': '18px',
+      '3xl': '20px',
+      '4xl': '22px',
+      '5xl': '24px',
+      '6xl': '26px',
+      '7xl': '28px',
+      '8xl': '30px',
+    },
+    borderRadius: {
+      sm: '2px',
+      DEFAULT: '4px',
+      md: '6px',
+      lg: '8px',
+      xl: '10px',
+      '2xl': '12px',
+      full: '9999px',
+    },
+    extend: {
+      colors: {
+        primary: '#FE8E2C',
+        'black-3': '#333333',
+        'black-6': '#666666',
+        'black-9': '#999999',
+        'black-c': '#cccccc',
+        'black-d': '#dddddd',
+        'black-e': '#eeeeee',
+        'black-f5': '#f5f5f5',
+        'black-fa': '#fafafa',
+        'black-ed': '#EDEDED',
+        'black-a3': '#a3a3a3',
+        'black-f9': '#f9f9f9',
+        'black-f3': '#f3f3f3',
+        'black-f4': '#f4f4f4',
+        'black-a': '#aaaaaa',
+      },
+      fontFamily: {
+        youSheBiaoti: ['YouSheBiaoTiHei'],
+        DIN: ['DINAlternate-Bold, DINAlternate'],
+      },
+      letterSpacing: {
+        1: '1px',
+      },
+    },
   },
   plugins: [],
 };