Pārlūkot izejas kodu

优化货权转移计算业务,全部替换为BigDecimal类计算

dw 1 nedēļu atpakaļ
vecāks
revīzija
d5b18f1844

+ 71
- 39
src/main/java/com/th/demo/service/impl/ware/ChangeServiceImpl.java Parādīt failu

@@ -30,6 +30,10 @@ import org.springframework.stereotype.Service;
30 30
 import org.springframework.transaction.annotation.Transactional;
31 31
 import org.springframework.util.StringUtils;
32 32
 
33
+import java.math.BigDecimal;
34
+import java.text.SimpleDateFormat;
35
+import java.time.LocalDateTime;
36
+import java.time.format.DateTimeFormatter;
33 37
 import java.util.Collections;
34 38
 import java.util.Date;
35 39
 import java.util.List;
@@ -56,11 +60,12 @@ public class ChangeServiceImpl implements ChangeService {
56 60
 
57 61
     /**
58 62
      * 货权转移
59
-     * 解决:货权转移后Cargo重量不减少、中途return不扣重量、空指针、事务部分提交BUG
63
+     * 修复:浮点数精度问题、重复更新问题、逻辑校验问题
60 64
      */
61 65
     @Transactional(rollbackFor = Exception.class)
62 66
     @Override
63 67
     public String changeCustomer(String json, String customer, String address, String userId, String belongId) throws Exception {
68
+
64 69
         // 1. 基础参数非空校验
65 70
         if (!StringUtils.hasText(json) || !StringUtils.hasText(customer) || !StringUtils.hasText(userId) || !StringUtils.hasText(belongId)) {
66 71
             throw new Exception("传入参数不能为空");
@@ -93,52 +98,79 @@ public class ChangeServiceImpl implements ChangeService {
93 98
             throw new Exception("原货主不存在");
94 99
         }
95 100
 
96
-        // 4. 查询货权配置记录
101
+        // 4. 校验新旧货主不能相同
102
+        if (oldCustomer.getId().equals(newCustomer.getId())) {
103
+            throw new Exception("新旧货主不能相同");
104
+        }
105
+
106
+        // 5. 查询货权配置记录
97 107
         Cargo cargo = cargoMapper.selectByByFkAndCustomer(oldCustomer.getId(), newCustomer.getId(), belongId);
98
-        double sumWeight = 0;
108
+
109
+        // 使用BigDecimal处理重量
110
+        BigDecimal availableWeight = BigDecimal.ZERO;
111
+        BigDecimal sumWeightBD = BigDecimal.ZERO;
112
+
99 113
         if (cargo != null) {
100
-            sumWeight = cargo.getSumWeight();
101
-            // 货权可用重量为0直接拦截
102
-            if (sumWeight <= 0) {
114
+            sumWeightBD = BigDecimal.valueOf(cargo.getSumWeight());
115
+            availableWeight = sumWeightBD;
116
+            // 货权可用重量为0直接拦截(使用精度比较)
117
+            if (availableWeight.compareTo(BigDecimal.ZERO) <= 0) {
103 118
                 throw new Exception("货权信息已维护,可用转移重量为0");
104 119
             }
105 120
         }
106 121
 
107
-        double useWeight = 0;// 已累计使用转移重量
108
-        int num = 0;// 数据库受影响行数 初始化
109
-        String recordType;
122
+        // 6. 计算需要转移的总重量
123
+        BigDecimal needTotalWeight = BigDecimal.ZERO;
124
+        for (Store store : storeList) {
125
+            if (store != null && store.getWeight() > 0) {
126
+                needTotalWeight = needTotalWeight.add(BigDecimal.valueOf(store.getWeight()));
127
+            }
128
+        }
129
+
130
+        // 7. 总重量校验(提前校验,避免处理一半才失败)
131
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
132
+        System.out.println("时间"+sdf.format(new Date()));
133
+        System.out.println("可用重量"+availableWeight.stripTrailingZeros().toPlainString());
134
+        System.out .println("需要总重量"+needTotalWeight.stripTrailingZeros().toPlainString());
135
+        if (cargo != null && availableWeight.compareTo(needTotalWeight) < 0) {
136
+            throw new Exception(String.format("货权转移重量不足。可用: %s, 转移重量: %s",
137
+                    availableWeight.stripTrailingZeros().toPlainString(),
138
+                    needTotalWeight.stripTrailingZeros().toPlainString()));
139
+        }
140
+        // 8. 循环逐条处理库存转移
141
+        BigDecimal usedWeight = BigDecimal.ZERO;
142
+        int affectedRows = 0;
110 143
 
111
-        // 5. 循环逐条处理库存转移
112 144
         for (Store store : storeList) {
113 145
             if (store == null || store.getWeight() <= 0) {
114 146
                 continue;
115 147
             }
116
-            double currentWeight = store.getWeight();
117 148
 
118
-            // 重量不足校验
119
-            if (sumWeight > 0 && (sumWeight - useWeight - currentWeight) < 0) {
120
-                throw new Exception("货权转移重量不足");
121
-            }
149
+            BigDecimal currentWeight = BigDecimal.valueOf(store.getWeight());
122 150
 
123
-            // 判断记录类型
151
+            // 9. 判断记录类型(如果新货主名跟库存老货主名一样,则记录类型为0)
152
+            String recordType;
124 153
             if (newCustomer.getName().equals(store.getCustomer().getName())) {
125 154
                 recordType = "0";
126 155
             } else {
127 156
                 recordType = "1";
128 157
                 // 插入账户明细
129 158
                 AccountDetail accountDetail = getAccountDetail(store, userId, belongId);
130
-                num += accountDetailMapper.insert(accountDetail);
159
+                affectedRows += accountDetailMapper.insert(accountDetail);
131 160
             }
132 161
 
133
-            // 插入变更记录
162
+            // 10. 插入变更记录
134 163
             ChangeRecord changeRecord = getChangeRecord(recordType, store, newCustomer, address, userId, belongId);
135
-            num += changeRecordMapper.insert(changeRecord);
164
+            affectedRows += changeRecordMapper.insert(changeRecord);
165
+
166
+            // 11. 保存老货主ID
167
+            String oldCustomerId = store.getCustomer().getId();
136 168
 
137
-            // 修改库存归属
169
+            // 12. 修改库存归属
138 170
             store.setCustomer(newCustomer);
139
-            store.setFkComponyId(oldCustomer.getId());
171
+            store.setFkComponyId(oldCustomerId);
140 172
 
141
-            // 地址处理
173
+            // 13. 地址处理
142 174
             if (StringUtils.hasText(address)) {
143 175
                 if ("0".equals(address)) {
144 176
                     store.setReceiveAddress("");
@@ -147,41 +179,41 @@ public class ChangeServiceImpl implements ChangeService {
147 179
                 }
148 180
             }
149 181
 
150
-            // 更新库存
151
-            num += storeMapper.updateByPrimaryKey(store);
152
-            num += storeMapper.updateFkById(store);
182
+            // 14. 更新库存(合并为一次更新)
183
+            affectedRows += storeMapper.updateByPrimaryKey(store);
153 184
 
154
-            // 累加已使用重量
155
-            useWeight += currentWeight;
185
+            // 15. 累加已使用重量
186
+            usedWeight = usedWeight.add(currentWeight);
156 187
 
157
-            // ========== 关键修复:逐条实时扣减货权重量,不放到循环外 ==========
188
+            // 16. 逐条实时扣减货权重量(使用BigDecimal保证精度)
158 189
             if (cargo != null) {
159
-                cargo.setSumWeight(cargo.getSumWeight() - currentWeight);
160
-                cargo.setUseWeight(cargo.getUseWeight() + currentWeight);
161
-                // 立即更新数据库,每处理一条扣一条,避免中途中断完全不扣
162
-                num += cargoMapper.updateByPrimaryKey(cargo);
190
+                BigDecimal newSumWeight = BigDecimal.valueOf(cargo.getSumWeight()).subtract(currentWeight);
191
+                BigDecimal newUseWeight = BigDecimal.valueOf(cargo.getUseWeight()).add(currentWeight);
192
+                cargo.setSumWeight(newSumWeight.doubleValue());
193
+                cargo.setUseWeight(newUseWeight.doubleValue());
194
+                affectedRows += cargoMapper.updateByPrimaryKey(cargo);
163 195
             }
164 196
         }
165 197
 
166
-        // 6. 批量处理完后 插入货权变更记录
167
-        if (cargo != null && useWeight > 0) {
198
+        // 17. 批量处理完后插入货权变更记录
199
+        if (cargo != null && usedWeight.compareTo(BigDecimal.ZERO) > 0) {
168 200
             CargoChangeRecord cargoChangeRecord = new CargoChangeRecord();
169 201
             cargoChangeRecord.setUperCustomer(cargo.getUperCustomer());
170 202
             cargoChangeRecord.setCustomer(cargo.getCustomer());
171 203
             cargoChangeRecord.setChangeFrom("货权转移");
172
-            cargoChangeRecord.setWeight(useWeight);
204
+            cargoChangeRecord.setWeight(usedWeight.doubleValue());
173 205
             cargoChangeRecord.setSubStr("减少");
174 206
             cargoChangeRecord.setModifyTime(new Date());
175 207
             cargoChangeRecord.setModifyUser(new SysUser(userId));
176
-//            cargoChangeRecord.setCancelFlag("0");
177
-            num += cargoChangeRecordMapper.insert(cargoChangeRecord);
208
+            affectedRows += cargoChangeRecordMapper.insert(cargoChangeRecord);
178 209
         }
179 210
 
180
-        // 7. 返回结果
181
-        return Tools.moreThanZeroResultJSON(num);
211
+        // 18. 返回结果
212
+        return Tools.moreThanZeroResultJSON(affectedRows);
182 213
     }
183 214
 
184 215
 
216
+
185 217
     private ChangeRecord getChangeRecord(String recordType, Store store, Customer customer, String receiveAddress, String userId, String belongId) {
186 218
         ChangeRecord record = new ChangeRecord();
187 219
         record.setRecordType(recordType);

Notiek ielāde…
Atcelt
Saglabāt