Răsfoiți Sursa

feat:游记列表页面

qiao 3 luni în urmă
părinte
comite
4c0f85a62f
2 a modificat fișierele cu 179 adăugiri și 32 ștergeri
  1. BIN
      src/assets/img/yuanchuang.png
  2. 179 32
      src/pages/travel-notes/index.vue

BIN
src/assets/img/yuanchuang.png


+ 179 - 32
src/pages/travel-notes/index.vue

@@ -1,34 +1,160 @@
 <template>
-  <div>
+  <div class="">
     <!-- <Navbar :title="`${menuName ?? ''}精品旅游`" /> -->
+    <div class="sticky top-0 z-50 bg-white w-full">
+      <van-dropdown-menu active-color="#FF9300" ref="dropDownMenuRef">
+        <van-dropdown-item @closed="onAreaFilterClose" :title="areaFilterTitle" ref="itemRef">
+          <van-tree-select @click-nav="handleAreaClick" @click-item="handleFilterClick" v-model:active-id="activeId"
+            v-model:main-active-index="areaIndex" :items="filterList" />
+        </van-dropdown-item>
+        <van-dropdown-item :title="writeTypeText" v-model="travelWriteType"
+          :options="writeTypeList"></van-dropdown-item>
+      </van-dropdown-menu>
+    </div>
     <div class="px-10 pt-20">
-      <van-search
-        v-model="searchStr"
-        placeholder="请输入搜索关键词"
-        shape="round"
-        @search="onSearch"
-      >
-      </van-search>
-      <van-list
-        v-if="dataList.length"
-        v-model:loading="loading"
-        :immediate-check="false"
-        :finished="finished"
-        finished-text=""
-        @load="loadMore"
-      >
-        <TravelProjectItem
-          v-for="item in dataList"
-          :key="item.id"
-          :item-data="item"
-        />
+      <van-list v-if="dataList.length" v-model:loading="loading" :immediate-check="false" :finished="finished"
+        finished-text="" @load="loadMore">
+        <template v-for="itemData in dataList">
+          <NuxtLink class="group flex relative cursor-pointer bg-white  pb-10 mb-20" :to="`/yj/${itemData.id}`"
+            target="_blank">
+            <div class="aspect-[120/80] h-80 shrink-0 rounded overflow-hidden bg-[#ddd]">
+              <img :src="itemData.tourismUrl" class="w-full h-full rounded object-cover" alt="" srcset="" />
+            </div>
+            <div class="h-80  pl-[5px] flex flex-col text-[#FD9A00] justify-between  w-[calc(100%-120px)]">
+              <div class="truncate w-full text-[14px] ">
+                <img v-if="itemData.isOriginal == 1" src="~/assets/img/yuanchuang.png"  class="mt-3 w-[30px] h-[16px]" alt="" style="float:left;">
+                {{ itemData.projectTitle }}
+              </div>
+              <div class="w-full overflow-x-auto scrollbar" v-if="itemData.noteLabel">
+                <div class="flex flex-nowrap">
+                  <div v-for="tag in convertTag(itemData.noteLabel)" class="p-2 rounded-full border border-[#FD9A00] text-[10px] pr-12 pl-12 float-left mr-10 shrink-0">{{ tag }}</div>
+                </div>
+              </div>
+              <div class="flex justify-end items-center text-[12px] text-[#999]">
+                <div class="flex items-center mr-10">
+                  <van-icon name="eye-o" class="mr-5" />{{ itemData.pageViewCount }}
+                </div>
+                <div class="flex items-center mr-10">
+                  <van-icon name="good-job-o" class="mr-5" />{{ itemData.likeCount }}
+                </div>
+                <div class="flex items-center mr-10">
+                  <van-icon name="like-o" class="mr-5" />{{ itemData.hotValue }}
+                </div>
+              </div>
+            </div>
+            <div class="w-full h-10 absolute top-[100%] left-0 flex items-center justify-between">
+              <div v-for="item in 40" class="w-[2%] h-[1px] border border-[#ddd]"></div>
+            </div>
+          </NuxtLink>
+        </template>
       </van-list>
-      <Empty v-else-if="!dataList.length && !loading" />
+      <Empty v-if="!dataList.length && !loading" />
     </div>
   </div>
 </template>
 
 <script setup>
+const AREA_TEXT = '地域'
+
+const filterList = ref([])//地域列表
+
+const curFilter = ref({})//当前筛选条件(国家)
+
+const areaIndex = ref(0)//地域索引
+
+const areaFilterTitle = ref(AREA_TEXT)
+
+const activeId = computed(() => curFilter.value.id)
+
+const activeIndex = ref('');
+
+const dropDownMenuRef = ref(null)
+// 获取筛选列表
+async function getFilters() {
+  const { data } = await request(`website/tourism/projectTravelNotes/travelNotesDirectoryList`)
+  if (!Array.isArray(data)) return
+  data.map((item, index) => {
+    data[index].id = item.areaId
+    data[index].text = item.areaName
+    if (Array.isArray(item.children)) {
+      item.children.map((item2, index2) => {
+        data[index].children[index2].id = item2.countryId
+        data[index].children[index2].text = item2.countryName
+        data[index].children[index2].areaId = item.areaId
+      })
+    }
+  })
+  filterList.value = [{ id: 0, text: '全部', children: [{ id: 0, text: '全部' }] }, ...data]
+}
+
+// 监听地域筛选框收起
+function onAreaFilterClose() { areaIndex.value = activeIndex.value }
+
+const pageNum = ref(1)
+const pageSize = ref(10)
+const dataList = ref([])
+const loading = ref(false)
+const finished = ref(false)
+// 是否原创 0 全部 1 原创 
+const travelWriteType = ref(0)
+const writeTypeList = ref([
+  { text: '全部', value: 0 },
+  { text: '原创', value: 1 },
+])
+const writeTypeText = computed(() => writeTypeList.value[travelWriteType.value].value ? '原创' : '是否原创')
+watch(travelWriteType, () => {
+  pageNum.value = 1
+  dataList.value = []
+  getList()
+})
+
+// 获取游记列表
+async function getList() {
+  const param = {
+    pageNum: pageNum.value,
+    pageSize: pageSize.value,
+  }
+
+  if (curFilter.value.id) {
+    param.areaId = curFilter.value.areaId
+    param.countryId = curFilter.value.id
+  }
+  if (travelWriteType.value) {
+    param.travelWriteType = travelWriteType.value
+  }
+  loading.value = true
+  const { data } = await request(`website/tourism/projectTravelNotes/travelNotesPageList`, { query: param })
+
+  dataList.value = dataList.value.concat(data.dataList)
+  loading.value = false
+  if (dataList.value.length >= data.totalCount) {
+    finished.value = true;
+  } else {
+    finished.value = false;
+  }
+}
+// 选择洲
+function handleAreaClick(index) { areaIndex.value = index }
+
+// 选择国家
+function handleFilterClick(item) {
+  curFilter.value = item
+  if (!item.id) {
+    areaFilterTitle.value = AREA_TEXT
+  } else {
+    const areaText = filterList.value[areaIndex.value].text || ''
+    const cityText = item.text || ''
+    activeIndex.value = areaIndex.value
+    areaFilterTitle.value = areaText + '-' + cityText
+  }
+  pageNum.value = 1
+  dataList.value = []
+  getList()
+  dropDownMenuRef.value && dropDownMenuRef.value.close()
+  document.title=`${item.id?'游记-'+item.text:'旅游笔记'}`
+}
+
+
 const menuName = useRouteQuery("menuName");
 
 const areaId = useRouteQuery("areaId");
@@ -38,11 +164,8 @@ const countryId = useRouteQuery("countryId");
 // const id = useRouteParam("id");
 
 const searchStr = ref("");
-const dataList = ref([]);
-const loading = ref(false);
-const finished = ref(false);
-const pageNum = ref(1);
-const pageSize = ref(10);
+
+
 async function getProjects() {
   const { data } = await request(
     `website/tourism/projectTravelNotes/travelNotesPageList`,
@@ -68,9 +191,12 @@ async function getProjects() {
 
 function loadMore() {
   pageNum.value++;
-  getProjects();
+  getList()
+}
+function convertTag(str=''){
+  if(typeof str!=='string') return []
+  return str.split('&')
 }
-
 function onSearch() {
   pageNum.value = 1;
   dataList.value = [];
@@ -79,12 +205,33 @@ function onSearch() {
 }
 
 onMounted(() => {
-  getProjects();
+  getFilters()
+  getList()
 });
 
 useSeoMeta({
-  title: `${menuName.value}精品旅游`,
+  title: `旅游笔记`,
 });
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+:root {
+  --tree-select-item-active-color: red;
+  /* 选中项背景颜色 */
+  --tree-select-item-active-text-color: red;
+  /* 选中项文本颜色 */
+  --van-tree-select-item-active-color: red;
+}
+.scrollbar::-webkit-scrollbar {
+  width: 0px;
+  height: 0px;
+  background-color: #ccc;
+}
+
+/* 滚动条滑块样式 */
+.scrollbar::-webkit-scrollbar-thumb {
+  border-radius: 10px;
+  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+  background-color: #555;
+}
+</style>