Browse Source

fix(apps): 优化导航拖拽与无价商品询价入口

- 将首页导航排序限制在序号和图标手柄,避免编辑及开关操作被拖拽抢占
- 统一商城无价格商品的加购入口跳转详情页,支持未登录用户查看并询价
shizhongqi 12 hours ago
parent
commit
934a7dde54

+ 33 - 41
hdApp/src/admin/homePageConfig/navGrid.vue

@@ -13,7 +13,7 @@
       </tui-list-cell>
       </tui-list-cell>
     </view>
     </view>
 
 
-    <view class="tip-bar">支持上下拖拽调整展示顺序</view>
+    <view class="tip-bar">按住序号或图标可上下拖拽调整展示顺序</view>
 
 
     <view class="list-wrap">
     <view class="list-wrap">
       <block v-if="form.list.length">
       <block v-if="form.list.length">
@@ -30,38 +30,39 @@
             transition: isDragging ? 'none' : 'transform 0.25s ease',
             transition: isDragging ? 'none' : 'transform 0.25s ease',
             zIndex: draggedIndex === index ? 999 : 1
             zIndex: draggedIndex === index ? 999 : 1
           }"
           }"
-          :data-index="index"
-          @touchstart="dragStart"
-          @touchmove.stop.prevent="dragMove"
-          @touchend="dragEnd"
         >
         >
-          <view class="list-num">{{ index + 1 }}</view>
-          <view class="item-icon">
-            <image
-              v-if="isPresetIcon(item.icon)"
-              class="icon-img"
-              :src="presetIconFullUrl(item.icon)"
-              mode="aspectFill"
-            />
-            <image v-else class="icon-img" :src="iconFullUrl(item.icon)" mode="aspectFill" />
+          <!--
+            拖拽手柄:仅序号+图标可发起排序。
+            触摸事件绑在手柄上而不是整行,避免标题点击、编辑、开关被拖拽抢走。
+            touchmove 仍绑在手柄即可:按下后手指移出手柄,后续 move/end 仍回落到起始节点。
+          -->
+          <view
+            class="drag-handle"
+            :data-index="index"
+            @touchstart="dragStart"
+            @touchmove.stop.prevent="dragMove"
+            @touchend="dragEnd"
+          >
+            <view class="list-num">{{ index + 1 }}</view>
+            <view class="item-icon">
+              <image
+                v-if="isPresetIcon(item.icon)"
+                class="icon-img"
+                :src="presetIconFullUrl(item.icon)"
+                mode="aspectFill"
+              />
+              <image v-else class="icon-img" :src="iconFullUrl(item.icon)" mode="aspectFill" />
+            </view>
           </view>
           </view>
           <!-- 小程序 data-event-opts 不能可靠序列化对象参数,改为传 index -->
           <!-- 小程序 data-event-opts 不能可靠序列化对象参数,改为传 index -->
           <view class="list-main" @click.stop="goEditByIndex(index)">
           <view class="list-main" @click.stop="goEditByIndex(index)">
             <view class="list-title">{{ item.name || '未命名' }}</view>
             <view class="list-title">{{ item.name || '未命名' }}</view>
           </view>
           </view>
-          <view class="list-edit" @click.stop="goEditByIndex(index)" data-drag-ignore="true">
+          <view class="list-edit" @click.stop="goEditByIndex(index)">
             编辑
             编辑
           </view>
           </view>
-          <!--
-            注意:这里不能用 @touchstart.stop 之类的 catch 写法拦截触摸事件。
-            微信小程序里 catch 会在原生手势层面“吃掉”触摸,导致内置 <switch>
-            自身的滑动/点击手势也收不到事件,表现为开关完全点不动;编辑按钮同理点不了。
-            所以改为:不拦截事件冒泡,而是给操作区域打上 data-drag-ignore 标记,
-            在 dragStart 里识别到该标记后直接放弃进入拖拽,把触摸交还给按钮/switch 自己处理。
-          -->
-          <view class="list-switch" data-drag-ignore="true">
+          <view class="list-switch">
             <switch
             <switch
-              data-drag-ignore="true"
               :checked="item.enabled == 1"
               :checked="item.enabled == 1"
               color="#09C567"
               color="#09C567"
               @change="toggleItemEnabledByIndex(index, $event)"
               @change="toggleItemEnabledByIndex(index, $event)"
@@ -311,21 +312,6 @@ export default {
           this.saving = false
           this.saving = false
         })
         })
     },
     },
-    /**
-     * 判断触摸目标是否位于标记了 data-drag-ignore 的区域(如编辑按钮、开关)。
-     * 小程序端 e.target 是精简对象,只能直接读 dataset;
-     * H5/App 端是真实 DOM 节点,兼容用 closest 向上查找,防止触摸到 switch 内部子节点时漏判。
-     */
-    isDragIgnoreTarget(target) {
-      if (!target) return false
-      if (target.dataset && (target.dataset.dragIgnore === 'true' || target.dataset.dragIgnore === true)) {
-        return true
-      }
-      if (typeof target.closest === 'function') {
-        return !!target.closest('[data-drag-ignore="true"]')
-      }
-      return false
-    },
     transformStyle(index) {
     transformStyle(index) {
       if (!this.isDragging || this.draggedIndex < 0) {
       if (!this.isDragging || this.draggedIndex < 0) {
         return 'translateY(0upx)'
         return 'translateY(0upx)'
@@ -346,10 +332,11 @@ export default {
       }
       }
       return 'translateY(0upx)'
       return 'translateY(0upx)'
     },
     },
+    /**
+     * 从序号/图标手柄按下后进入拖拽;currentTarget 是手柄节点,用其 data-index 定位行。
+     */
     dragStart(e) {
     dragStart(e) {
       if (this.isDragging) return
       if (this.isDragging) return
-      // 触摸起点落在编辑/开关区域时不进入拖拽,避免抢占按钮点击和 switch 自身手势
-      if (this.isDragIgnoreTarget(e.target)) return
       const index = parseInt(e.currentTarget.dataset.index, 10)
       const index = parseInt(e.currentTarget.dataset.index, 10)
       if (isNaN(index) || index < 0 || index >= this.form.list.length) {
       if (isNaN(index) || index < 0 || index >= this.form.list.length) {
         return
         return
@@ -509,6 +496,11 @@ export default {
   position: relative;
   position: relative;
 }
 }
 
 
+.drag-handle {
+  @include disFlex(center, flex-start);
+  flex-shrink: 0;
+}
+
 .list-num {
 .list-num {
   width: 48upx;
   width: 48upx;
   height: 48upx;
   height: 48upx;

+ 7 - 6
mallApp/src/components/home/goodsSection.vue

@@ -162,8 +162,8 @@ export default {
       this.pageTo({ url: `/pages/goods/detail?id=${g.id}&account=${this.account}&hdId=${this.hdId}` })
       this.pageTo({ url: `/pages/goods/detail?id=${g.id}&account=${this.account}&hdId=${this.hdId}` })
     },
     },
     /**
     /**
-     * 单规格直接加购,多规格(goodsStyle=1)跳转详情选规格;无价格商品拦截并提示询价
-     * 未登录:仅拦截「直接加购」,多规格仍可进详情;由父页弹 wangCg
+     * 单规格直接加购,多规格(goodsStyle=1)跳转详情选规格;无价格商品同样进详情询价
+     * 未登录:仅拦截「直接加购」,多规格/无价格仍可进详情;由父页弹 wangCg
      */
      */
     handleCartClick(g) {
     handleCartClick(g) {
       if (!g || !g.id) return
       if (!g || !g.id) return
@@ -171,12 +171,13 @@ export default {
         this.goDetail(g)
         this.goDetail(g)
         return
         return
       }
       }
-      if (!this.isLoggedIn) {
-        this.$emit('require-login')
+      // 无价格商品无法加购,进详情让用户向商家咨询(浏览不强制登录)
+      if (this.isNoPrice(g)) {
+        this.goDetail(g)
         return
         return
       }
       }
-      if (this.isNoPrice(g)) {
-        this.$msg('请向商家咨询价格')
+      if (!this.isLoggedIn) {
+        this.$emit('require-login')
         return
         return
       }
       }
       if (!(Number(g.price) > 0)) {
       if (!(Number(g.price) > 0)) {

+ 3 - 1
mallApp/src/pages/goods/list.vue

@@ -585,6 +585,7 @@ export default {
     },
     },
     /**
     /**
      * 列表加购:单规格直接加入购物车;多规格(goodsStyle=1)跳转详情选规格后再加购
      * 列表加购:单规格直接加入购物车;多规格(goodsStyle=1)跳转详情选规格后再加购
+     * 无价格商品无法加购,改为进入详情页向商家咨询
      * @param {Object} item 列表商品行(含 goodsStyle / specEnabled / price)
      * @param {Object} item 列表商品行(含 goodsStyle / specEnabled / price)
      */
      */
     handleCartClick(item) {
     handleCartClick(item) {
@@ -594,8 +595,9 @@ export default {
         this.goDetail(item)
         this.goDetail(item)
         return
         return
       }
       }
+      // 无价格商品无法加购,进详情让用户向商家咨询
       if (this.isNoPrice(item)) {
       if (this.isNoPrice(item)) {
-        this.$msg('请向商家咨询价格')
+        this.goDetail(item)
         return
         return
       }
       }
       if (!(Number(item.price) > 0)) {
       if (!(Number(item.price) > 0)) {

+ 3 - 1
mallApp/src/pages/goods/section-list.vue

@@ -228,6 +228,7 @@ export default {
     },
     },
     /**
     /**
      * 列表加购:单规格直接加入购物车;多规格(goodsStyle=1)跳转详情选规格后再加购
      * 列表加购:单规格直接加入购物车;多规格(goodsStyle=1)跳转详情选规格后再加购
+     * 无价格商品无法加购,改为进入详情页向商家咨询
      * @param {Object} item 列表商品行(含 goodsStyle / specEnabled / price)
      * @param {Object} item 列表商品行(含 goodsStyle / specEnabled / price)
      */
      */
     handleCartClick(item) {
     handleCartClick(item) {
@@ -237,8 +238,9 @@ export default {
         this.goDetail(item)
         this.goDetail(item)
         return
         return
       }
       }
+      // 无价格商品无法加购,进详情让用户向商家咨询
       if (this.isNoPrice(item)) {
       if (this.isNoPrice(item)) {
-        this.$msg('请向商家咨询价格')
+        this.goDetail(item)
         return
         return
       }
       }
       if (!(Number(item.price) > 0)) {
       if (!(Number(item.price) > 0)) {

+ 5 - 4
mallApp/src/pages/home/shop-category.vue

@@ -887,7 +887,7 @@ export default {
         }
         }
       })
       })
     },
     },
-    /** 花束加购:单规格直接加入购物车,多规格(goodsStyle=1)跳转详情选规格 */
+    /** 花束加购:单规格直接加入购物车,多规格(goodsStyle=1)跳转详情选规格;无价格商品进详情询价 */
     handleBouquetAddToCart(item) {
     handleBouquetAddToCart(item) {
       if (!item || !item.id) {
       if (!item || !item.id) {
         return
         return
@@ -897,11 +897,12 @@ export default {
         this.toBouquetDetail(item)
         this.toBouquetDetail(item)
         return
         return
       }
       }
-      if (!this.requireLogin()) {
+      // 无价格商品无法加购,进详情让用户向商家咨询(浏览不强制登录)
+      if (Number(item.priceType) === 0) {
+        this.toBouquetDetail(item)
         return
         return
       }
       }
-      if (Number(item.priceType) === 0) {
-        this.$msg('请向商家咨询价格')
+      if (!this.requireLogin()) {
         return
         return
       }
       }
       if (Number(item.priceType) !== 1 || !(Number(item.price) > 0)) {
       if (Number(item.priceType) !== 1 || !(Number(item.price) > 0)) {