wangfumin 5 месяцев назад
Родитель
Сommit
70af0195b7

+ 11 - 5
src/setup/useCollectionApi.js

@@ -58,10 +58,6 @@ export function useCollectionApi(options = {}) {
 
         // 判断是否还有更多数据
         hasMore.value = response.records.length === pageSize.value
-
-        if (isLoadMore) {
-          currentPage.value++
-        }
       } else {
         artifactList.value = []
         hasMore.value = false
@@ -122,7 +118,17 @@ export function useCollectionApi(options = {}) {
    */
   const loadMore = async () => {
     if (!hasMore.value || loading.value) return
-    await getArtifactList({}, true)
+
+    // 先递增页码
+    currentPage.value++
+
+    try {
+      await getArtifactList({}, true)
+    } catch (error) {
+      // 如果请求失败,回退页码
+      currentPage.value--
+      throw error
+    }
   }
 
   /**

+ 182 - 33
src/views/collection/index.vue

@@ -3,9 +3,15 @@
     <!-- 顶部导航和搜索区域 -->
     <div class="top-section">
       <!-- 顶部导航栏 -->
-      <div class="nav-scroll-container">
-        <el-menu :default-active="activeCategory" class="category-menu" mode="horizontal" :ellipsis="false"
-          background-color="#f8f3e8" @select="handleCategorySelect">
+      <div class="nav-scroll-container" ref="navScrollContainer">
+        <el-menu
+          :default-active="activeCategory"
+          class="category-menu"
+          mode="horizontal"
+          :ellipsis="false"
+          background-color="#f8f3e8"
+          @select="handleCategorySelect"
+        >
           <el-menu-item index="all"><span class="category-text">全部</span></el-menu-item>
           <el-menu-item v-for="(category, index) in categories" :key="index" :index="category.id">
             <span class="category-text">{{ category.name }}</span>
@@ -15,14 +21,21 @@
 
       <!-- 搜索框 -->
       <div class="search-container-collect">
-        <el-input id="realy-input" v-model="searchText" placeholder="请输入要搜索的内容..." class="search-input" clearable>
+        <el-input
+          id="realy-input"
+          v-model="searchText"
+          placeholder="请输入要搜索的内容..."
+          class="search-input"
+          clearable
+        >
           <template #suffix>
             <el-icon :size="16">
               <Search />
             </el-icon>
           </template>
         </el-input>
-        <div id="vir-input" class="vir-input">请输入要搜索的内容...
+        <div id="vir-input" class="vir-input">
+          请输入要搜索的内容...
           <el-icon class="vir-icon" :size="16">
             <Search />
           </el-icon>
@@ -33,12 +46,24 @@
     <!-- 内容区域 -->
     <div class="content-section" ref="contentSection">
       <div class="collection-list">
-        <div class="collection-item" v-for="(item, index) in artifactList" :key="item.artifactId || index">
+        <div
+          class="collection-item"
+          v-for="(item, index) in artifactList"
+          :key="item.artifactId || index"
+        >
           <div class="item-image-container">
-            <img :src="getFieldValue(item, 'image') || getFieldValue(item, 'img') || '@/assets/indexPage/zhanweitu.png'"
-              alt="藏品图片" class="item-image" />
+            <img
+              :src="
+                getFieldValue(item, 'image') ||
+                getFieldValue(item, 'img') ||
+                '@/assets/indexPage/zhanweitu.png'
+              "
+              alt="藏品图片"
+              class="item-image"
+            />
             <div class="view-button" @click="goCollectDetail(item)">
-              <span>查看</span><el-icon>
+              <span>查看</span
+              ><el-icon>
                 <Right />
               </el-icon>
             </div>
@@ -70,7 +95,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted, computed, watch, nextTick } from 'vue'
+import { ref, onMounted, onUnmounted, computed, watch, nextTick } from 'vue'
 import { Search } from '@element-plus/icons-vue'
 import { useRouter, useRoute } from 'vue-router'
 import { useStore } from 'vuex'
@@ -97,17 +122,8 @@ const getFieldValue = (item, fieldName) => {
 }
 
 // 使用典藏API组合式函数
-const {
-  artifactList,
-  loading,
-  hasMore,
-  searchTitle,
-  selectedType,
-  searchArtifacts,
-  changeType,
-  loadMore,
-  initData
-} = useCollectionApi({ isPreviewMode })
+const { artifactList, loading, hasMore, searchArtifacts, changeType, loadMore, initData } =
+  useCollectionApi({ isPreviewMode })
 
 // 搜索文本
 const searchText = ref('')
@@ -118,11 +134,15 @@ const activeCategory = ref('all')
 // 内容区域引用
 const contentSection = ref(null)
 
+// 导航滚动容器引用
+const navScrollContainer = ref(null)
+
 // 分类数据
 const categories = [
-  { id: '1', name: '平面纸质类' },
-  { id: '2', name: '棉麻丝绸类' },
-  { id: '3', name: '专业器物类' },
+  { id: '1', name: '织绣' },
+  { id: '2', name: '铁器、其他金属器' },
+  { id: '3', name: '文物、宣传品' },
+  { id: '4', name: '其他' },
 ]
 
 // 监听搜索文本变化
@@ -132,6 +152,11 @@ watch(searchText, async (newValue) => {
 
 // 处理分类选择
 const handleCategorySelect = async (index) => {
+  // 如果刚刚完成拖拽,忽略点击事件
+  if (justDragged.value) {
+    return
+  }
+
   activeCategory.value = index
   const typeId = index === 'all' ? 0 : parseInt(index)
   await changeType(typeId)
@@ -140,7 +165,7 @@ const handleCategorySelect = async (index) => {
 // 跳转到藏品详情页
 const goCollectDetail = (item) => {
   const query = {
-    id: item.artifactId
+    id: item.artifactId,
   }
 
   // 如果当前URL有preview=1参数,则在跳转时保留
@@ -150,7 +175,7 @@ const goCollectDetail = (item) => {
 
   router.push({
     path: '/collectDetail',
-    query: query
+    query: query,
   })
 }
 
@@ -166,6 +191,77 @@ const handleScroll = async () => {
   }
 }
 
+// 导航拖拽滚动相关变量
+const isMouseDown = ref(false)
+const isDragging = ref(false)
+const startX = ref(0)
+const currentX = ref(0)
+const scrollLeft = ref(0)
+const dragThreshold = 5 // 拖拽阈值,移动超过5px才算拖拽
+const justDragged = ref(false) // 标记是否刚刚完成拖拽
+
+// 鼠标按下事件
+const handleMouseDown = (e) => {
+  if (!navScrollContainer.value) return
+
+  isMouseDown.value = true
+  isDragging.value = false
+  startX.value = e.pageX - navScrollContainer.value.offsetLeft
+  currentX.value = startX.value
+  scrollLeft.value = navScrollContainer.value.scrollLeft
+
+  // 不立即阻止默认行为,让点击事件能正常触发
+}
+
+// 鼠标移动事件
+const handleMouseMove = (e) => {
+  if (!isMouseDown.value || !navScrollContainer.value) return
+
+  currentX.value = e.pageX - navScrollContainer.value.offsetLeft
+  const distance = Math.abs(currentX.value - startX.value)
+
+  // 只有移动距离超过阈值才开始拖拽
+  if (!isDragging.value && distance > dragThreshold) {
+    isDragging.value = true
+    navScrollContainer.value.classList.add('dragging')
+    // 现在才阻止默认行为
+    e.preventDefault()
+  }
+
+  if (isDragging.value) {
+    e.preventDefault()
+    const walk = (currentX.value - startX.value) * 2 // 乘以2增加滚动速度
+    navScrollContainer.value.scrollLeft = scrollLeft.value - walk
+  }
+}
+
+// 鼠标松开事件
+const handleMouseUp = () => {
+  // 如果发生了拖拽,标记为刚刚拖拽过
+  if (isDragging.value) {
+    justDragged.value = true
+    // 50ms后清除标记,确保不影响后续正常点击
+    setTimeout(() => {
+      justDragged.value = false
+    }, 50)
+  }
+
+  isMouseDown.value = false
+  isDragging.value = false
+  if (navScrollContainer.value) {
+    navScrollContainer.value.classList.remove('dragging')
+  }
+}
+
+// 鼠标离开容器事件
+const handleMouseLeave = () => {
+  isMouseDown.value = false
+  isDragging.value = false
+  if (navScrollContainer.value) {
+    navScrollContainer.value.classList.remove('dragging')
+  }
+}
+
 // 初始化
 onMounted(async () => {
   await initData()
@@ -175,6 +271,43 @@ onMounted(async () => {
   if (contentSection.value) {
     contentSection.value.addEventListener('scroll', handleScroll)
   }
+
+  // 添加导航拖拽滚动功能(仅在非移动设备上)
+  if (navScrollContainer.value && !('ontouchstart' in window)) {
+    const container = navScrollContainer.value
+
+    // 鼠标按下事件绑定在容器上
+    container.addEventListener('mousedown', handleMouseDown)
+
+    // 鼠标移动和松开事件绑定在document上,确保即使移出容器也能正确处理
+    document.addEventListener('mousemove', handleMouseMove)
+    document.addEventListener('mouseup', handleMouseUp)
+
+    // 鼠标离开容器事件
+    container.addEventListener('mouseleave', handleMouseLeave)
+
+    // 阻止默认的图片拖拽等行为
+    container.addEventListener('dragstart', (e) => e.preventDefault())
+  }
+})
+
+// 组件销毁时清理事件监听器
+onUnmounted(() => {
+  if (navScrollContainer.value && !('ontouchstart' in window)) {
+    const container = navScrollContainer.value
+
+    container.removeEventListener('mousedown', handleMouseDown)
+    container.removeEventListener('mouseleave', handleMouseLeave)
+    container.removeEventListener('dragstart', (e) => e.preventDefault())
+
+    // 移除document上的事件监听
+    document.removeEventListener('mousemove', handleMouseMove)
+    document.removeEventListener('mouseup', handleMouseUp)
+  }
+
+  if (contentSection.value) {
+    contentSection.value.removeEventListener('scroll', handleScroll)
+  }
 })
 </script>
 <style>
@@ -184,17 +317,17 @@ onMounted(async () => {
 
 .search-container-collect .search-input {
   border-radius: 20px;
-  border-color: #5B472E;
+  border-color: #5b472e;
 }
 
 .vir-input {
   display: none;
   position: relative;
   border-radius: 20px;
-  border: 1px solid #5B472E;
+  border: 1px solid #5b472e;
   height: 45px;
   align-items: center;
-  color: #5B472E;
+  color: #5b472e;
   padding: 0 15px;
 }
 
@@ -245,11 +378,27 @@ onMounted(async () => {
   -webkit-overflow-scrolling: touch;
   scrollbar-width: none;
   /* Firefox */
+  user-select: none; /* 防止拖拽时选中文本 */
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  cursor: grab; /* 默认显示可拖拽的鼠标样式 */
 
   &::-webkit-scrollbar {
     display: none;
     /* Chrome, Safari, Edge */
   }
+
+  /* 拖拽时的样式 */
+  &.dragging {
+    cursor: grabbing !important;
+    user-select: none; /* 拖拽时防止选中文本 */
+  }
+
+  /* 移动设备不显示拖拽鼠标样式 */
+  @media (hover: none) and (pointer: coarse) {
+    cursor: default;
+  }
 }
 
 :deep(.category-menu) {
@@ -274,17 +423,17 @@ onMounted(async () => {
 
       .category-text {
         display: inline-flex;
-        border-bottom: 1px solid #F3B200;
+        border-bottom: 1px solid #f3b200;
       }
     }
 
     &:hover {
-      color: #B1967B;
+      color: #b1967b;
       background-color: transparent;
     }
 
     &:focus {
-      color: #B1967B;
+      color: #b1967b;
       background-color: transparent;
     }
 
@@ -413,4 +562,4 @@ onMounted(async () => {
     transform: rotate(360deg);
   }
 }
-</style>
+</style>

+ 37 - 22
src/views/exhibition/index.vue

@@ -2,8 +2,12 @@
   <div :class="['exhibition-container', !isFromParam ? 'home-tabar' : '']">
     <!-- 轮播图部分 -->
     <div class="carousel-section">
-      <div style="position: relative;" @click="goToDetail(item.exhibitId)">
-        <img src="https://sit-kelamayi.4dage.com/mini/wxImg/zhanlan.png" alt="展览图片" class="carousel-img" />
+      <div style="position: relative" @click="goToDetail(item.exhibitId)">
+        <img
+          src="https://klmybwg.4dage.com//mini/wxImg/zhanlan.png"
+          alt="展览图片"
+          class="carousel-img"
+        />
         <div class="online-exhibition" @click.stop="goToOnlineExhibition(item)">
           <img class="online-icon" src="@/assets/exhibition/online-kz.png" alt="线上观展" />
           <span class="online-text">线上观展</span>
@@ -25,11 +29,17 @@
 
     <!-- 展览列表 -->
     <div class="exhibition-list" ref="listContainer" @scroll="handleScroll">
-      <div class="exhibition-item" v-for="item in exhibitionList" :key="item.exhibitId"
-        @click="goToDetail(item.exhibitId)">
-        <img :src="getFieldValue(item, 'img')" alt="展览" class="exhibition-img">
+      <div
+        class="exhibition-item"
+        v-for="item in exhibitionList"
+        :key="item.exhibitId"
+        @click="goToDetail(item.exhibitId)"
+      >
+        <img :src="getFieldValue(item, 'img')" alt="展览" class="exhibition-img" />
         <div class="exhibition-info">
-          <h4 class="exhibition-title">{{ getFieldValue(item, 'title') || '记忆与传承的艺术史' }}</h4>
+          <h4 class="exhibition-title">
+            {{ getFieldValue(item, 'title') || '记忆与传承的艺术史' }}
+          </h4>
         </div>
       </div>
 
@@ -87,7 +97,7 @@ const getCarouselData = async () => {
     const params = {
       pageNum: 1,
       pageSize: 5,
-      type: 0
+      type: 0,
     }
 
     // 预览模式下添加status参数
@@ -114,7 +124,7 @@ const getExhibitionList = async (isLoadMore = false) => {
     const params = {
       pageNum: isLoadMore ? currentPage.value : 1,
       pageSize: pageSize.value,
-      type: selectedType.value
+      type: selectedType.value,
     }
 
     // 预览模式下添加status参数
@@ -136,10 +146,6 @@ const getExhibitionList = async (isLoadMore = false) => {
 
       // 判断是否还有更多数据
       hasMore.value = response.records.length === pageSize.value
-
-      if (isLoadMore) {
-        currentPage.value++
-      }
     }
   } catch (error) {
     console.error('获取展览列表失败:', error)
@@ -168,7 +174,16 @@ const handleScroll = async () => {
 
   // 当滚动到底部附近时加载更多
   if (scrollTop + clientHeight >= scrollHeight - 50) {
-    await getExhibitionList(true)
+    // 先递增页码
+    currentPage.value++
+
+    try {
+      await getExhibitionList(true)
+    } catch (error) {
+      // 如果请求失败,回退页码
+      currentPage.value--
+      console.error('加载更多失败:', error)
+    }
   }
 }
 
@@ -177,7 +192,7 @@ const goToDetail = (id) => {
   const query = {
     id: id,
     type: 'exhibition',
-    isFromPage: 'exhibition'
+    isFromPage: 'exhibition',
   }
 
   // 如果当前页面有preview=1参数,跳转时也要带上
@@ -187,15 +202,15 @@ const goToDetail = (id) => {
 
   router.push({
     path: '/allDetailsShow',
-    query: query
+    query: query,
   })
 }
 const goToOnlineExhibition = () => {
-  let url;
+  let url
   if (isPreviewMode.value) {
-    url = 'https://www.4dmodel.com/SuperTwoCustom/KLMYscene/?m=SG-alDn3FU4jQ8'
+    url = 'https://klmybwg.4dage.com/KLMYScene/index.html?m=SG-alDn3FU4jQ8'
   } else {
-    url = 'https://www.4dmodel.com/SuperTwoCustom/KLMYscene/?m=SG-alDn3FU4jQ8'
+    url = 'https://klmybwg.4dage.com/KLMYScene/index.html?m=SG-alDn3FU4jQ8'
   }
   if (url) {
     window.open(url, '_blank')
@@ -326,7 +341,7 @@ onMounted(async () => {
 
     span {
       font-size: 16px;
-      color: #B1967B;
+      color: #b1967b;
     }
   }
 }
@@ -372,7 +387,7 @@ onMounted(async () => {
       opacity: 0.8;
       position: absolute;
       bottom: 0;
-      background: #B1967B;
+      background: #b1967b;
 
       .exhibition-title {
         font-size: 16px;
@@ -391,7 +406,7 @@ onMounted(async () => {
   .loading-more {
     text-align: center;
     padding: 20px;
-    color: #B1967B;
+    color: #b1967b;
     font-size: 14px;
   }
 
@@ -403,4 +418,4 @@ onMounted(async () => {
     font-size: 14px;
   }
 }
-</style>
+</style>

+ 6 - 6
src/views/indexPage/components/activePeople.vue

@@ -164,11 +164,11 @@ const isFormValid = computed(() => {
   if (visitors.value.length === 0) return false
   return visitors.value.every(
     (visitor) =>
-      visitor.name &&
-      visitor.phone &&
-      visitor.idNumber &&
-      !visitor.nameError &&
-      !visitor.phoneError &&
+    visitor.name &&
+    visitor.phone &&
+    visitor.idNumber &&
+    !visitor.nameError &&
+    !visitor.phoneError &&
       !visitor.idNumberError,
   )
 })
@@ -291,7 +291,7 @@ const closeSuccessModal = () => {
       query: { preview: '1' },
     })
   } else {
-    router.push('/indexPage')
+  router.push('/indexPage')
   }
 }
 

+ 6 - 6
src/views/indexPage/components/visitPeople.vue

@@ -164,11 +164,11 @@ const isFormValid = computed(() => {
   if (visitors.value.length === 0) return false
   return visitors.value.every(
     (visitor) =>
-      visitor.name &&
-      visitor.phone &&
-      visitor.idNumber &&
-      !visitor.nameError &&
-      !visitor.phoneError &&
+    visitor.name &&
+    visitor.phone &&
+    visitor.idNumber &&
+    !visitor.nameError &&
+    !visitor.phoneError &&
       !visitor.idNumberError,
   )
 })
@@ -291,7 +291,7 @@ const closeSuccessModal = () => {
       query: { preview: '1' },
     })
   } else {
-    router.push('/indexPage')
+  router.push('/indexPage')
   }
 }
 

+ 4 - 4
src/views/user/index.vue

@@ -16,7 +16,7 @@
       <div class="user-zhanwei">
         <img
           class="zhanwei-img"
-          src="https://sit-kelamayi.4dage.com/mini/wxImg/img_03.png"
+          src="https://klmybwg.4dage.com//mini/wxImg/img_03.png"
           alt="占位图"
         />
       </div>
@@ -50,7 +50,7 @@ export default {
 <style lang="scss" scoped>
 .user-container {
   height: 100vh;
-  background: url('https://sit-kelamayi.4dage.com/mini/wxImg/user-bg.png') no-repeat;
+  background: url('https://klmybwg.4dage.com//mini/wxImg/user-bg.png') no-repeat;
   background-size: cover;
   display: flex;
   flex-direction: column;
@@ -127,7 +127,7 @@ export default {
 }
 
 .btn-reserve {
-  background: url('https://sit-kelamayi.4dage.com/mini/wxImg/preview-btn.png');
+  background: url('https://klmybwg.4dage.com//mini/wxImg/preview-btn.png');
   width: 100%;
   height: 65px;
   border-radius: 5px;
@@ -146,7 +146,7 @@ export default {
   align-items: center;
   width: 100%;
   height: 65px;
-  background: url('https://sit-kelamayi.4dage.com/mini/wxImg/btn_02.png');
+  background: url('https://klmybwg.4dage.com//mini/wxImg/btn_02.png');
   background-size: 100% auto;
   border-radius: 5px;
   border: 1px solid #94765a;