Explorar o código

fix(DimensionWeightPicker): 修复拖动时按比例分配算法,首维度多分配问题

Xiaogang Liao hai 2 meses
pai
achega
f04e4bad3a
Modificáronse 1 ficheiros con 23 adicións e 40 borrados
  1. 23 40
      cfc-web/src/components/DimensionWeightPicker.vue

+ 23 - 40
cfc-web/src/components/DimensionWeightPicker.vue

@@ -91,60 +91,43 @@ export default {
   },
   methods: {
     onWeightChange(changedCode) {
-      // 1. Clamp the changed dimension
       const changed = this.dimensions.find(function(d) { return d.code === changedCode })
       if (changed) {
         changed.currentValue = Math.max(0, Math.min(100, changed.currentValue))
       }
       var remaining = 100 - this.sum
-      if (remaining === 0) {
+      if (Math.abs(remaining) < 0.01) {
         this.emitValue()
         return
       }
       var others = this.dimensions.filter(function(d) { return d.code !== changedCode })
       if (remaining > 0) {
-        // 需要把剩余分配到其他维度
-        var otherTotal = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
-        if (otherTotal === 0) {
-          // 所有其他维度为 0,平分剩余
-          var rest = remaining
-          others.forEach(function(d, i) {
-            d.currentValue = (i === others.length - 1) ? rest : Math.floor(remaining / others.length)
-            if (i < others.length - 1) rest = remaining - d.currentValue
-          })
-        } else {
-          var distSum = 0
-          others.forEach(function(d, i) {
-            if (i === others.length - 1) {
-              d.currentValue = Math.max(0, remaining - distSum)
-            } else {
-              var share = Math.max(0, Math.round((d.currentValue / otherTotal) * remaining))
-              d.currentValue = share
-              distSum += share
-            }
-          })
+        var othersTotal = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
+        var exactVals = []
+        for (var i = 0; i < others.length; i++) {
+          exactVals.push(othersTotal > 0 ? ((others[i].currentValue || 0) / othersTotal) * remaining : remaining / others.length)
+        }
+        var distributed = 0
+        for (var j = 0; j < others.length - 1; j++) {
+          var rounded = Math.round(exactVals[j])
+          others[j].currentValue = Math.max(0, rounded)
+          distributed += rounded
         }
+        others[others.length - 1].currentValue = Math.max(0, Math.round(remaining - distributed))
       } else {
-        // 超过 100,需要从其他维度扣除
         var excess = -remaining
-        var otherTotal2 = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
-        if (otherTotal2 > 0) {
-          var cutSum = 0
-          others.forEach(function(d, i) {
-            if (i === others.length - 1) {
-              d.currentValue = Math.max(0, (d.currentValue || 0) - (excess - cutSum))
-            } else {
-              var cut = Math.min(d.currentValue || 0, Math.round((d.currentValue / otherTotal2) * excess))
-              d.currentValue = Math.max(0, (d.currentValue || 0) - cut)
-              cutSum += cut
-            }
-          })
+        var othersTotal2 = others.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
+        var exactCuts = []
+        for (var k = 0; k < others.length; k++) {
+          exactCuts.push(othersTotal2 > 0 ? ((others[k].currentValue || 0) / othersTotal2) * excess : excess / others.length)
         }
-      }
-      // 最后修正浮点误差
-      var finalSum = this.dimensions.reduce(function(s, d) { return s + (d.currentValue || 0) }, 0)
-      if (finalSum !== 100 && others.length > 0) {
-        others[0].currentValue += 100 - finalSum
+        var cutSum = 0
+        for (var m = 0; m < others.length - 1; m++) {
+          var cutRounded = Math.round(exactCuts[m])
+          others[m].currentValue = Math.max(0, (others[m].currentValue || 0) - cutRounded)
+          cutSum += cutRounded
+        }
+        others[others.length - 1].currentValue = Math.max(0, (others[others.length - 1].currentValue || 0) - Math.round(excess - cutSum))
       }
       this.emitValue()
     },