Просмотр исходного кода

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

dw 1 неделю назад
Родитель
Сommit
d5b18f1844
1 измененных файлов: 71 добавлений и 39 удалений
  1. 71
    39
      src/main/java/com/th/demo/service/impl/ware/ChangeServiceImpl.java

+ 71
- 39
src/main/java/com/th/demo/service/impl/ware/ChangeServiceImpl.java Просмотреть файл

30
 import org.springframework.transaction.annotation.Transactional;
30
 import org.springframework.transaction.annotation.Transactional;
31
 import org.springframework.util.StringUtils;
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
 import java.util.Collections;
37
 import java.util.Collections;
34
 import java.util.Date;
38
 import java.util.Date;
35
 import java.util.List;
39
 import java.util.List;
56
 
60
 
57
     /**
61
     /**
58
      * 货权转移
62
      * 货权转移
59
-     * 解决:货权转移后Cargo重量不减少、中途return不扣重量、空指针、事务部分提交BUG
63
+     * 修复:浮点数精度问题、重复更新问题、逻辑校验问题
60
      */
64
      */
61
     @Transactional(rollbackFor = Exception.class)
65
     @Transactional(rollbackFor = Exception.class)
62
     @Override
66
     @Override
63
     public String changeCustomer(String json, String customer, String address, String userId, String belongId) throws Exception {
67
     public String changeCustomer(String json, String customer, String address, String userId, String belongId) throws Exception {
68
+
64
         // 1. 基础参数非空校验
69
         // 1. 基础参数非空校验
65
         if (!StringUtils.hasText(json) || !StringUtils.hasText(customer) || !StringUtils.hasText(userId) || !StringUtils.hasText(belongId)) {
70
         if (!StringUtils.hasText(json) || !StringUtils.hasText(customer) || !StringUtils.hasText(userId) || !StringUtils.hasText(belongId)) {
66
             throw new Exception("传入参数不能为空");
71
             throw new Exception("传入参数不能为空");
93
             throw new Exception("原货主不存在");
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
         Cargo cargo = cargoMapper.selectByByFkAndCustomer(oldCustomer.getId(), newCustomer.getId(), belongId);
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
         if (cargo != null) {
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
                 throw new Exception("货权信息已维护,可用转移重量为0");
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
         for (Store store : storeList) {
144
         for (Store store : storeList) {
113
             if (store == null || store.getWeight() <= 0) {
145
             if (store == null || store.getWeight() <= 0) {
114
                 continue;
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
             if (newCustomer.getName().equals(store.getCustomer().getName())) {
153
             if (newCustomer.getName().equals(store.getCustomer().getName())) {
125
                 recordType = "0";
154
                 recordType = "0";
126
             } else {
155
             } else {
127
                 recordType = "1";
156
                 recordType = "1";
128
                 // 插入账户明细
157
                 // 插入账户明细
129
                 AccountDetail accountDetail = getAccountDetail(store, userId, belongId);
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
             ChangeRecord changeRecord = getChangeRecord(recordType, store, newCustomer, address, userId, belongId);
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
             store.setCustomer(newCustomer);
170
             store.setCustomer(newCustomer);
139
-            store.setFkComponyId(oldCustomer.getId());
171
+            store.setFkComponyId(oldCustomerId);
140
 
172
 
141
-            // 地址处理
173
+            // 13. 地址处理
142
             if (StringUtils.hasText(address)) {
174
             if (StringUtils.hasText(address)) {
143
                 if ("0".equals(address)) {
175
                 if ("0".equals(address)) {
144
                     store.setReceiveAddress("");
176
                     store.setReceiveAddress("");
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
             if (cargo != null) {
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
             CargoChangeRecord cargoChangeRecord = new CargoChangeRecord();
200
             CargoChangeRecord cargoChangeRecord = new CargoChangeRecord();
169
             cargoChangeRecord.setUperCustomer(cargo.getUperCustomer());
201
             cargoChangeRecord.setUperCustomer(cargo.getUperCustomer());
170
             cargoChangeRecord.setCustomer(cargo.getCustomer());
202
             cargoChangeRecord.setCustomer(cargo.getCustomer());
171
             cargoChangeRecord.setChangeFrom("货权转移");
203
             cargoChangeRecord.setChangeFrom("货权转移");
172
-            cargoChangeRecord.setWeight(useWeight);
204
+            cargoChangeRecord.setWeight(usedWeight.doubleValue());
173
             cargoChangeRecord.setSubStr("减少");
205
             cargoChangeRecord.setSubStr("减少");
174
             cargoChangeRecord.setModifyTime(new Date());
206
             cargoChangeRecord.setModifyTime(new Date());
175
             cargoChangeRecord.setModifyUser(new SysUser(userId));
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
     private ChangeRecord getChangeRecord(String recordType, Store store, Customer customer, String receiveAddress, String userId, String belongId) {
217
     private ChangeRecord getChangeRecord(String recordType, Store store, Customer customer, String receiveAddress, String userId, String belongId) {
186
         ChangeRecord record = new ChangeRecord();
218
         ChangeRecord record = new ChangeRecord();
187
         record.setRecordType(recordType);
219
         record.setRecordType(recordType);

Загрузка…
Отмена
Сохранить