Răsfoiți Sursa

✨ feat(goods-spec-selector): 优化商品规格选择器的用户体验和状态管理

- 为规格选项添加过渡动画,提升视觉体验
- 重构 useEffect 依赖项,分离数据加载逻辑与状态同步逻辑
- 新增独立的 useEffect 监听 currentSpec 变化以更新选中状态,避免数据重新加载
- 新增独立的 useEffect 监听 currentQuantity 变化以更新数量状态
- 移除确认操作后自动关闭模态框的逻辑,避免视觉闪烁,允许用户继续操作
- 调整初始化逻辑,确保数量和选中状态仅在数据加载时正确设置

🐛 fix(goods-detail): 修复规格确认后的状态处理逻辑

- 移除在库存不足时过早重置 pendingAction 和关闭模态框的操作,确保错误提示后用户仍可调整选择
- 将模态框关闭和动作重置逻辑统一移至所有业务分支处理完毕后,确保流程一致性

🔧 chore(claude): 更新本地设置文件权限

- 在 Claude 本地设置文件的技能允许列表中新增 `Bash(pnpm eslint:*)` 命令权限
yourname 3 săptămâni în urmă
părinte
comite
a700b4c44e

+ 2 - 1
.claude/settings.local.json

@@ -94,7 +94,8 @@
       "Skill(BMad:tasks:execute-checklist)",
       "Skill(BMad:tasks:execute-checklist:*)",
       "Skill(BMad:tasks:apply-qa-fixes)",
-      "Skill(BMad:tasks:apply-qa-fixes:*)"
+      "Skill(BMad:tasks:apply-qa-fixes:*)",
+      "Bash(pnpm eslint:*)"
     ],
     "deny": [],
     "ask": []

+ 1 - 0
mini/src/components/goods-spec-selector/index.css

@@ -114,6 +114,7 @@
   border: 1rpx solid #e8e8e8;
   border-radius: 8rpx;
   background: #f8f8f8;
+  transition: all 0.3s ease;
 }
 
 .spec-option.selected {

+ 28 - 10
mini/src/components/goods-spec-selector/index.tsx

@@ -82,13 +82,16 @@ export function GoodsSpecSelector({
             }))
             setSpecOptions(childGoodsAsSpecs)
 
-            // 如果有当前选中的规格,设置选中状态
+            // 如果有当前选中的规格,设置选中状态(只在数据加载时初始化)
             if (currentSpec) {
               const foundSpec = childGoodsAsSpecs.find(spec => spec.name === currentSpec)
               if (foundSpec) {
                 setSelectedSpec(foundSpec)
               }
             }
+
+            // 初始化数量为当前数量(只在数据加载时初始化)
+            setQuantity(currentQuantity)
           } else {
             // 尝试解析响应体获取具体错误消息
             let errorMsg = `获取子商品列表失败: ${response.status}`
@@ -119,7 +122,27 @@ export function GoodsSpecSelector({
       // 如果不可见或parentGoodsId无效,清空规格选项
       setIsLoading(false)
     }
-  }, [visible, parentGoodsId, currentSpec])
+  }, [visible, parentGoodsId])
+
+  // 监听currentSpec变化,更新选中状态(不重新加载数据)
+  useEffect(() => {
+    if (visible && specOptions.length > 0 && currentSpec) {
+      const foundSpec = specOptions.find(spec => spec.name === currentSpec)
+      if (foundSpec) {
+        setSelectedSpec(foundSpec)
+      } else {
+        // 如果找不到对应的规格,清空选中状态
+        setSelectedSpec(null)
+      }
+    }
+  }, [visible, currentSpec, specOptions])
+
+  // 监听currentQuantity变化,更新数量状态(不重新加载数据)
+  useEffect(() => {
+    if (visible) {
+      setQuantity(currentQuantity)
+    }
+  }, [visible, currentQuantity])
 
   const handleSpecSelect = (spec: SpecOption) => {
     setSelectedSpec(spec)
@@ -150,13 +173,6 @@ export function GoodsSpecSelector({
     validatePriceCalculation()
   }, [selectedSpec, quantity])
 
-  // 监听 currentQuantity 变化,同步更新 quantity 状态
-  useEffect(() => {
-    if (visible) {
-      setQuantity(currentQuantity)
-    }
-  }, [visible, currentQuantity])
-
   // 模态窗口显示/隐藏时控制页面滚动
   useEffect(() => {
     if (visible) {
@@ -168,6 +184,7 @@ export function GoodsSpecSelector({
     }
   }, [visible])
 
+
   // 获取最大可购买数量
   const getMaxQuantity = () => {
     if (!selectedSpec) return 999
@@ -282,7 +299,8 @@ export function GoodsSpecSelector({
       return
     }
     onConfirm(selectedSpec, quantity, actionType)
-    onClose()
+    // 不重置选中状态和数量,避免视觉闪烁
+    // 用户可以继续选择其他规格,或者再次添加相同规格
   }
 
   if (!visible) return null

+ 1 - 7
mini/src/pages/goods-detail/index.tsx

@@ -209,6 +209,7 @@ export default function GoodsDetailPage() {
   // 规格选择确认
   const handleSpecConfirm = (spec: SelectedSpec | null, qty: number, actionType?: 'add-to-cart' | 'buy-now') => {
     if (spec) {
+      // 更新选中的规格和数量(用于页面显示)
       setSelectedSpec(spec)
       setQuantity(qty)
 
@@ -230,8 +231,6 @@ export default function GoodsDetailPage() {
               title: '库存不足',
               icon: 'none'
             })
-            setPendingAction(undefined)
-            setShowSpecModal(false)
             return
           }
 
@@ -265,8 +264,6 @@ export default function GoodsDetailPage() {
               title: '库存不足',
               icon: 'none'
             })
-            setPendingAction(undefined)
-            setShowSpecModal(false)
             return
           }
 
@@ -291,9 +288,6 @@ export default function GoodsDetailPage() {
         }
       }
     }
-
-    setPendingAction(undefined)
-    setShowSpecModal(false)
   }