Browse Source

feat: 优化比例输入逻辑,增加累计金额和比例的校验,清空后续行数据

xieyong 1 tuần trước cách đây
mục cha
commit
d4666f276a
1 tập tin đã thay đổi với 51 bổ sung và 40 xóa
  1. 51 40
      src/BIZComponents/paymentCollectionPlan/Index.vue

+ 51 - 40
src/BIZComponents/paymentCollectionPlan/Index.vue

@@ -505,58 +505,69 @@
       },
       //输入比例更新金额
       async ratioInput(val, index = null) {
-        // console.log(this.discountAmount, '77777');
-        // console.log(val, '5555555');
         val = Number(val);
+        if (isNaN(val)) val = 0;
         this.discountAmount = Number(this.info.payAmount);
         try {
           if (index != null) {
-            await this.checkRatio();
-          }
-          let newval = (val / 100).toFixed(2);
-          // console.log('newval~~~', newval)
-          let price = formatPrice(this.discountAmount * newval);
-          // console.log(newval, price, index, '88888');
-          if (index != null) {
-            // console.log(newval, price, index, '999999');
+            // 计算含本次新输入值的累计比例
+            const beforeCurrent = this.form.datasource
+              .slice(0, index)
+              .reduce((sum, r) => sum + Number(r.ratio || 0), 0);
+            const totalRatioWithNew = beforeCurrent + val;
+
+            // 多期时累计比例不能超过 100%
+            if (totalRatioWithNew > 100) {
+              this.$message.error('总共比例不能超过100%');
+              this.$set(this.form.datasource[index], 'ratio', null);
+              this.$set(this.form.datasource[index], 'price', 0);
+              this.clearRowsAfter(index);
+              return;
+            }
+
+            // 计算当前行计划金额
+            let newval = (val / 100).toFixed(2);
+            let price = formatPrice(this.discountAmount * newval);
             this.$set(this.form.datasource[index], 'price', price);
+
+            // 计算累计金额(含当前行),单位换算为元(避免浮点精度问题)
+            const totalAmount =
+              this.form.datasource
+                .slice(0, index + 1)
+                .reduce(
+                  (sum, r) => sum + Math.round(Number(r.price || 0) * 100),
+                  0
+                ) / 100;
+
+            // 多期时累计金额不能超过 discountAmount,使用 0.01 容差避免精度问题
+            const discountAmt = Number(this.discountAmount);
+            if (totalAmount - discountAmt > 0.01) {
+              this.$message.error('总金额不能超过优惠后总金额');
+              this.$set(this.form.datasource[index], 'ratio', null);
+              this.$set(this.form.datasource[index], 'price', 0);
+              this.clearRowsAfter(index);
+              return;
+            }
+
+            // 累计比例达到 100% 或累计金额达到 discountAmount 时,清空后续所有行的比例与金额
+            if (totalRatioWithNew >= 100 || discountAmt - totalAmount <= 0.01) {
+              this.clearRowsAfter(index);
+            }
           } else {
+            let newval = (val / 100).toFixed(2);
+            let price = formatPrice(this.discountAmount * newval);
             return price;
           }
         } catch (error) {
           return 0;
         }
-
-        //this.$set( this.form.datasource[index], 'price',  price)
       },
-      //检验比例
-      checkRatio() {
-        return new Promise((resolve, reject) => {
-          let newData = this.form.datasource,
-            sum = 0;
-          newData.forEach((r) => {
-            if (r.ratio) {
-              sum += Number(r.ratio);
-            }
-          });
-          // console.log(sum, '3333333');
-          if (sum > 100) {
-            this.$message.error('总共比例不能超过100');
-            this.$set(
-              this.form.datasource[this.form.datasource.length - 1],
-              'ratio',
-              null
-            );
-            this.$set(
-              this.form.datasource[this.form.datasource.length - 1],
-              'price',
-              0.0
-            );
-            resolve(true);
-          } else {
-            resolve(true);
-          }
-        });
+      // 清空指定索引之后所有行的比例与金额
+      clearRowsAfter(index) {
+        for (let i = index + 1; i < this.form.datasource.length; i++) {
+          this.$set(this.form.datasource[i], 'ratio', null);
+          this.$set(this.form.datasource[i], 'price', 0);
+        }
       },
       refreshprice() {
         // 如果正在从API加载数据,则不执行刷新操作