CmsGoodsDonSpecServiceImpl.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. package com.cyksj.service.mange.goods;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.collection.CollUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  6. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7. import com.cyksj.common.exception.BusinessRuntimeException;
  8. import com.cyksj.common.util.Jsons;
  9. import com.cyksj.mapper.GoodsDonMapper;
  10. import com.cyksj.mapper.GoodsDonSkuMapper;
  11. import com.cyksj.mapper.GoodsDonSpecMapper;
  12. import com.cyksj.model.entity.GoodsDon;
  13. import com.cyksj.model.entity.GoodsDonSku;
  14. import com.cyksj.model.entity.GoodsDonSpec;
  15. import com.cyksj.model.manage.request.ReqGoodsSkuInsert;
  16. import com.cyksj.model.manage.request.ReqGoodsSkuSpec;
  17. import com.cyksj.model.manage.request.ReqGoodsSpecSingle;
  18. import com.cyksj.model.request.CombinationSkuReq;
  19. import com.cyksj.service.mange.CmsGoodsDonSpecService;
  20. import com.fasterxml.jackson.databind.JavaType;
  21. import lombok.RequiredArgsConstructor;
  22. import lombok.extern.slf4j.Slf4j;
  23. import org.apache.commons.lang3.StringUtils;
  24. import org.springframework.stereotype.Service;
  25. import org.springframework.transaction.annotation.Transactional;
  26. import java.math.BigDecimal;
  27. import java.util.*;
  28. import java.util.concurrent.ConcurrentHashMap;
  29. import java.util.concurrent.atomic.AtomicBoolean;
  30. import java.util.stream.Collectors;
  31. /**
  32. * @author chan
  33. * @date 2022/9/27 5:19 PM
  34. */
  35. @Slf4j
  36. @Service
  37. @RequiredArgsConstructor
  38. public class CmsGoodsDonSpecServiceImpl extends ServiceImpl<GoodsDonSpecMapper, GoodsDonSpec> implements CmsGoodsDonSpecService {
  39. private final GoodsDonMapper goodsDonMapper;
  40. private final GoodsDonSkuMapper goodsDonSkuMapper;
  41. @Override
  42. @Transactional(rollbackFor = Throwable.class)
  43. public void insertOrUpdateSkuSpec(ReqGoodsSkuInsert insert, Boolean isUpdate) throws Exception {
  44. GoodsDon goods = goodsDonMapper.selectById(insert.getGoodsId());
  45. if (null == goods) {
  46. throw new RuntimeException("找不到商品spu.");
  47. }
  48. GoodsDonSpec loveSpec = this.getOne(Wrappers.lambdaQuery(GoodsDonSpec.class).eq(GoodsDonSpec::getGoodsId, insert.getGoodsId()));
  49. Map<String, List<ReqGoodsSkuSpec>> dbSpecMap = null;
  50. Map<Integer, ReqGoodsSkuSpec.Node> dbNodeMap = null;
  51. if (null != loveSpec) {
  52. insert.setId(loveSpec.getId());
  53. String specsJson = loveSpec.getSpecsJson();
  54. dbSpecMap = Jsons.parseList(specsJson, ReqGoodsSkuSpec.class).stream().collect(Collectors.groupingBy(ReqGoodsSkuSpec::getKey));
  55. }
  56. if (isUpdate && loveSpec == null) {
  57. throw BusinessRuntimeException.getInstance("所更新的平台id:{0}属性不存在", insert.getGoodsId());
  58. }
  59. List<ReqGoodsSkuSpec> specs = insert.getSpecs();
  60. if (null == specs || specs.isEmpty()) {
  61. throw new RuntimeException("缺少商品总规格.");
  62. }
  63. // 属性最大id
  64. Integer maxId = 0;
  65. // 统计总属性数
  66. Integer total = 0;
  67. // 判断id是否有重复
  68. Map<Integer, ReqGoodsSpecSingle> map = null;
  69. // 规格数量
  70. int specNumber = specs.size();
  71. dbNodeMap = checkUpdateGoodsSpec(goods.getId(), dbSpecMap, dbNodeMap, specs);
  72. for (ReqGoodsSkuSpec spec : specs) {
  73. if (StringUtils.isBlank(spec.getKey())) {
  74. throw new RuntimeException("存在空白规格名.");
  75. }
  76. List<ReqGoodsSkuSpec.Node> values = spec.getValues();
  77. if (null == values || values.isEmpty()) {
  78. throw new RuntimeException("规格[" + spec.getKey() + "]中缺少属性.");
  79. }
  80. total += values.size();
  81. for (ReqGoodsSkuSpec.Node e : values) {
  82. if (null == e.getId() || e.getId() < 0) {
  83. e.setId(maxId + 1);
  84. }
  85. if (StringUtils.isBlank(e.getValue())) {
  86. throw new RuntimeException("规格[" + spec.getKey() + "]中存在空白属性.");
  87. }
  88. if (e.getId() > maxId) {
  89. maxId = e.getId();
  90. }
  91. //新增时 实物价格要填入
  92. if (goods.getType() == 2 && insert.getId() == null && (e.getPrice() == null || e.getPrice().compareTo(BigDecimal.ZERO) < 0)) {
  93. throw BusinessRuntimeException.getInstance("实物规格:{0}对应价格请输入", e.getValue());
  94. }
  95. if (null == map) {
  96. map = new HashMap<>(16);
  97. }
  98. String benefitsList = e.getBenefitsList();
  99. if (StrUtil.isNotBlank(benefitsList)) {
  100. Set<GoodsDonSku> benefitsSkuIds = Jsons.parseSet(benefitsList, GoodsDonSku.class);
  101. e.setBenefitsList(Jsons.toJson(benefitsSkuIds));
  102. }
  103. syncSpecNodeSku(goods.getId(), dbNodeMap, e);
  104. ReqGoodsSpecSingle single = new ReqGoodsSpecSingle();
  105. single.setId(e.getId());
  106. single.setKey(spec.getKey());
  107. single.setName(e.getValue());
  108. map.put(e.getId(), single);
  109. }
  110. }
  111. if (map.size() != total) {
  112. throw new RuntimeException("规格中存在重复id.");
  113. }
  114. GoodsDonSpec spec = new GoodsDonSpec();
  115. spec.setId(insert.getId());
  116. spec.setGoodsId(insert.getGoodsId());
  117. spec.setMaxId(maxId);
  118. spec.setSpecsJson(Jsons.toJson(specs));
  119. if (goods.getType() == 2) {
  120. List<ReqGoodsSkuSpec> specJsonList = Jsons.parseList(spec.getSpecsJson(), ReqGoodsSkuSpec.class);
  121. for (ReqGoodsSkuSpec skuSpec : specJsonList) {
  122. if ("套餐".equals(skuSpec.getKey())) {
  123. BigDecimal benefitsPrice = null;
  124. for (ReqGoodsSkuSpec.Node value : skuSpec.getValues()) {
  125. String benefitsList = value.getBenefitsList();
  126. if (StrUtil.isEmpty(benefitsList)) {
  127. value.setBenefitsPrice(null);
  128. return;
  129. }
  130. List<GoodsDonSku> goodsDonSkus = Jsons.parseList(benefitsList, GoodsDonSku.class);
  131. if (CollUtil.isEmpty(goodsDonSkus)) {
  132. value.setBenefitsPrice(null);
  133. }
  134. List<Long> skuIds = goodsDonSkus.stream().map(GoodsDonSku::getId).collect(Collectors.toList());
  135. benefitsPrice = goodsDonSkuMapper.sumMoneyBySkuId(skuIds);
  136. value.setBenefitsPrice(benefitsPrice);
  137. }
  138. spec.setSpecsJson(Jsons.toJson(specJsonList));
  139. break;
  140. }
  141. }
  142. }
  143. spec.setSpecNumber(specNumber);
  144. spec.setSpecMapping(Jsons.toJson(map));
  145. if (insert.getId() != null) {
  146. this.updateById(spec);
  147. return;
  148. }
  149. this.save(spec);
  150. }
  151. @Override
  152. public void skuAppend(ReqGoodsSkuInsert insert, GoodsDon goods) throws Exception {
  153. GoodsDonSpec loveSpec = this.getOne(Wrappers.lambdaQuery(GoodsDonSpec.class).eq(GoodsDonSpec::getGoodsId, insert.getGoodsId()));
  154. if (null == loveSpec) {
  155. throw new RuntimeException("该商品未设置总规格, 请设置总规格.");
  156. }
  157. List<ReqGoodsSkuInsert.Sku> skus = insert.getSkus();
  158. if (null == skus || skus.isEmpty()) {
  159. throw new RuntimeException("参数错误.");
  160. }
  161. int specNumber = loveSpec.getSpecNumber();
  162. JavaType type = Jsons.javaType().constructMapType(HashMap.class, Integer.class, ReqGoodsSpecSingle.class);
  163. Map<Integer, ReqGoodsSpecSingle> map = Jsons.parseObject(loveSpec.getSpecMapping(), type);
  164. StringBuilder builder = new StringBuilder();
  165. List<ReqGoodsSpecSingle> specList = null;
  166. GoodsDonSku goodsDonSku = null;
  167. // 判断属性是否属于同一个key
  168. Set<String> set = null;
  169. for (ReqGoodsSkuInsert.Sku sku : insert.getSkus()) {
  170. // 跳过空值的sku
  171. // 解析sku的规格属性
  172. final String specIds = sku.getSpecIds();
  173. if (StringUtils.isBlank(specIds)) {
  174. throw new RuntimeException("请选择商品的规格.");
  175. }
  176. int[] ids = Jsons.parseObject(specIds, int[].class);
  177. // if (ids.length != specNumber) {
  178. // throw new RuntimeException("sku规格数量 与 总规格数量 不一致.");
  179. // }
  180. // init
  181. builder.delete(0, builder.length());
  182. if (null == specList) {
  183. specList = new ArrayList<>(specNumber);
  184. } else {
  185. specList.clear();
  186. }
  187. if (null == set) {
  188. int capacity = (specNumber + 1) * 4 / 3 + 1;
  189. set = new HashSet<>(capacity);
  190. } else {
  191. set.clear();
  192. }
  193. for (int id : ids) {
  194. ReqGoodsSpecSingle single = map.get(id);
  195. if (null == single) {
  196. throw new RuntimeException("总规格属性id中 不存在 sku中的id.");
  197. }
  198. builder.append(single.getName()).append(';');
  199. specList.add(single);
  200. set.add(single.getKey());
  201. }
  202. // if (set.size() != specNumber) {
  203. // throw new RuntimeException("sku中存在多个属性属于同一个规格.");
  204. // }
  205. String specVal = builder.toString();
  206. String specJson = Jsons.toJson(specList);
  207. if (null == goodsDonSku) {
  208. goodsDonSku = new GoodsDonSku();
  209. goodsDonSku.setGoodsId(insert.getGoodsId());
  210. }
  211. BeanUtil.copyProperties(sku, goodsDonSku);
  212. String specIdsStr = Jsons.toJson(ids);
  213. //升序
  214. Arrays.sort(ids);
  215. String dupSpecIds = Jsons.toJson(ids);
  216. GoodsDonSku specIds_exists = goodsDonSkuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class)
  217. .and(qr -> qr.eq(GoodsDonSku::getDupSpecIds, dupSpecIds).or().eq(GoodsDonSku::getSpecIds, specIdsStr))
  218. .eq(GoodsDonSku::getGoodsId, goods.getId())
  219. .last("limit 1"));
  220. if (specIds_exists != null) {
  221. log.info("库中存在相同二级分类的规格,spec_ids:{}", dupSpecIds);
  222. continue;
  223. }
  224. goodsDonSku.setSpecIds(specIdsStr);
  225. goodsDonSku.setDupSpecIds(dupSpecIds);
  226. goodsDonSku.setSpecVal(specVal);
  227. goodsDonSku.setSpecJson(specJson);
  228. String benefitsList = goodsDonSku.getBenefitsList();
  229. if (StrUtil.isNotBlank(benefitsList)) {
  230. Set<GoodsDonSku> benefitsSkuIds = Jsons.parseSet(benefitsList, GoodsDonSku.class);
  231. goodsDonSku.setIsBenefits(true);
  232. goodsDonSku.setBenefitsList(Jsons.toJson(benefitsSkuIds));
  233. }
  234. if (goods.getType() == 1) {
  235. if (sku.getMonths() != null && sku.getMonths() > 0 && sku.getDays() != null && sku.getDays() > 0)
  236. throw BusinessRuntimeException.getInstance("续费天数和续费月数不能同时存在");
  237. if (sku.getMonths() == null && sku.getDays() == null)
  238. throw BusinessRuntimeException.getInstance("请输入对应续费时间");
  239. }
  240. goodsDonSkuMapper.insert(goodsDonSku);
  241. }
  242. }
  243. @Override
  244. public void combinationSku(Long goodsId, List<CombinationSkuReq> combinations) throws Exception {
  245. GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
  246. if (goodsDon == null) throw BusinessRuntimeException.getInstance("平台不存在");
  247. if (goodsDon.getType() != 2) {
  248. throw BusinessRuntimeException.getInstance("暂只支持实物规格");
  249. }
  250. GoodsDonSpec loveSpec = this.getOne(Wrappers.lambdaQuery(GoodsDonSpec.class).eq(GoodsDonSpec::getGoodsId, goodsId));
  251. if (null == loveSpec) {
  252. throw new RuntimeException("该商品未设置总规格, 请设置总规格.");
  253. }
  254. String specsJson = loveSpec.getSpecsJson();
  255. List<ReqGoodsSkuSpec> specsList = Jsons.parseList(specsJson, ReqGoodsSkuSpec.class);
  256. Map<String, List<ReqGoodsSkuSpec>> specValueMap = specsList.stream().collect(Collectors.groupingBy(ReqGoodsSkuSpec::getKey));
  257. if (combinations.isEmpty()) {
  258. throw BusinessRuntimeException.getInstance("请选择对应的规格组合");
  259. }
  260. List<ReqGoodsSkuInsert.Sku> skus = new LinkedList<>();
  261. ReqGoodsSkuInsert reqGoodsSkuInsert = new ReqGoodsSkuInsert();
  262. reqGoodsSkuInsert.setGoodsId(goodsId);
  263. List<List<Integer>> specIdLists = new LinkedList<>();
  264. CombinationSkuReq request = combinations.get(0);
  265. List<ReqGoodsSkuSpec> reqGoodsSkuSpecs = specValueMap.get(request.getKey());
  266. if (reqGoodsSkuSpecs == null) {
  267. throw BusinessRuntimeException.getInstance("传入的总规格属性:{0}不存在", request.getKey());
  268. }
  269. Map<Integer, List<ReqGoodsSkuSpec.Node>> nodeIdMap = reqGoodsSkuSpecs.get(0).getValues().stream().collect(Collectors.groupingBy(ReqGoodsSkuSpec.Node::getId));
  270. if (CollUtil.isNotEmpty(request.getValues())) {
  271. unifiedHandleCombinationSku(combinations, request.getValues(), specValueMap, nodeIdMap, specIdLists, skus);
  272. } else {
  273. ReqGoodsSkuSpec reqGoodsSkuSpec = reqGoodsSkuSpecs.get(0);
  274. unifiedHandleCombinationSku(combinations,reqGoodsSkuSpec.getValues(),specValueMap, nodeIdMap,specIdLists,skus);
  275. }
  276. reqGoodsSkuInsert.setSkus(skus);
  277. skuAppend(reqGoodsSkuInsert, goodsDon);
  278. }
  279. public void unifiedHandleCombinationSku(List<CombinationSkuReq> combinations, List<ReqGoodsSkuSpec.Node> values, Map<String, List<ReqGoodsSkuSpec>> specValueMap, Map<Integer, List<ReqGoodsSkuSpec.Node>> nodeIdMap, List<List<Integer>> specIdLists, List<ReqGoodsSkuInsert.Sku> skus) throws Exception {
  280. for (ReqGoodsSkuSpec.Node node_value : values) {
  281. ReqGoodsSkuInsert.Sku sku = new ReqGoodsSkuInsert.Sku();
  282. sku.setPrice(BigDecimal.ZERO);
  283. List<Integer> specIds = new LinkedList<>();
  284. unifiedHandleSecondCombinationSku(node_value, nodeIdMap, sku, specIds);
  285. recurCombinationSku(combinations, combinations.size(), 1, 1, specIds, specIdLists, sku, specValueMap, skus);
  286. }
  287. }
  288. public void unifiedHandleSecondCombinationSku(ReqGoodsSkuSpec.Node temp_node, Map<Integer, List<ReqGoodsSkuSpec.Node>> nodeIdMap, ReqGoodsSkuInsert.Sku sku, List<Integer> specIds) {
  289. List<ReqGoodsSkuSpec.Node> nodes = nodeIdMap.get(temp_node.getId());
  290. if (CollUtil.isEmpty(nodes)) {
  291. throw BusinessRuntimeException.getInstance("{0}规格不存在", temp_node.getValue());
  292. }
  293. ReqGoodsSkuSpec.Node node = nodes.get(0);
  294. BigDecimal price = node.getPrice();
  295. if (price == null && node.getValue().contains("无")) {
  296. price = BigDecimal.ZERO;
  297. }
  298. if (price == null) {
  299. throw BusinessRuntimeException.getInstance("该实物子规格:{0}未配置价格", node.getValue());
  300. }
  301. sku.setPrice(sku.getPrice().add(price));
  302. specIds.add(temp_node.getId());
  303. if (StrUtil.isNotEmpty(node.getBenefitsList())) {
  304. sku.setIsBenefits(true);
  305. sku.setBenefitsList(node.getBenefitsList());
  306. }
  307. }
  308. /**
  309. * @param combinations 传入的组合数据
  310. * @param total 总共需要组合的大小
  311. * @param has 已有组合数大小
  312. * @param start 下一个组合数组下表
  313. * @param specIds 组合规格ids
  314. * @param sku 待插入库中的sku
  315. * @param specValueMap 总规格库中对应values
  316. */
  317. private void recurCombinationSku(List<CombinationSkuReq> combinations, Integer total, Integer has, Integer start, List<Integer> specIds, List<List<Integer>> specIdLists, ReqGoodsSkuInsert.Sku sku, Map<String, List<ReqGoodsSkuSpec>> specValueMap, List<ReqGoodsSkuInsert.Sku> skus) throws Exception {
  318. if (has == total) {
  319. if (specIdLists.contains(specIds)) {
  320. return;
  321. }
  322. sku.setSpecIds(Jsons.toJson(specIds));
  323. skus.add(sku);
  324. return;
  325. }
  326. CombinationSkuReq request = combinations.get(start);
  327. List<ReqGoodsSkuSpec> reqGoodsSkuSpecs = specValueMap.get(request.getKey());
  328. if (reqGoodsSkuSpecs == null) {
  329. throw BusinessRuntimeException.getInstance("总规格属性{0}不存在", request.getKey());
  330. }
  331. ReqGoodsSkuSpec reqGoodsSkuSpec = reqGoodsSkuSpecs.get(0);
  332. Map<Integer, List<ReqGoodsSkuSpec.Node>> nodeIdMap = reqGoodsSkuSpec.getValues().stream().collect(Collectors.groupingBy(ReqGoodsSkuSpec.Node::getId));
  333. if (CollUtil.isNotEmpty(request.getValues())) {
  334. createNewSkuAndRecurCombination(combinations, request.getValues(), nodeIdMap, has, start, specIds, specIdLists, sku, specValueMap, skus);
  335. return;
  336. }
  337. createNewSkuAndRecurCombination(combinations, reqGoodsSkuSpec.getValues(), nodeIdMap, has, start, specIds, specIdLists, sku, specValueMap, skus);
  338. }
  339. /**
  340. * 新的规格 递归
  341. */
  342. public void createNewSkuAndRecurCombination(List<CombinationSkuReq> combinations, List<ReqGoodsSkuSpec.Node> values, Map<Integer, List<ReqGoodsSkuSpec.Node>> nodeIdMap, Integer has, Integer start, List<Integer> specIds, List<List<Integer>> specIdLists, ReqGoodsSkuInsert.Sku sku, Map<String, List<ReqGoodsSkuSpec>> specValueMap, List<ReqGoodsSkuInsert.Sku> skus) throws Exception {
  343. for (ReqGoodsSkuSpec.Node node_value : values) {
  344. BigDecimal last_price = sku.getPrice();
  345. unifiedHandleSecondCombinationSku(node_value, nodeIdMap, sku, specIds);
  346. recurCombinationSku(combinations, combinations.size(), has + 1, start + 1, specIds, specIdLists, sku, specValueMap, skus);
  347. specIds.remove(node_value.getId());
  348. sku = new ReqGoodsSkuInsert.Sku();
  349. sku.setPrice(last_price);
  350. }
  351. }
  352. /**
  353. * 更新删除总属性 一级分类 校验
  354. */
  355. public Map<Integer, ReqGoodsSkuSpec.Node> checkUpdateGoodsSpec(Long goodsId, Map<String, List<ReqGoodsSkuSpec>> dbSpecMap, Map<Integer, ReqGoodsSkuSpec.Node> dbNodeMap, List<ReqGoodsSkuSpec> specs) {
  356. if (CollUtil.isNotEmpty(dbSpecMap)) {
  357. Map<String, List<ReqGoodsSkuSpec>> updateSpecMap = specs.stream().collect(Collectors.groupingBy(ReqGoodsSkuSpec::getKey));
  358. dbNodeMap = new ConcurrentHashMap<>();
  359. for (String key : dbSpecMap.keySet()) {
  360. List<ReqGoodsSkuSpec> reqGoodsSkuSpecs = updateSpecMap.get(key);
  361. if (CollUtil.isNotEmpty(reqGoodsSkuSpecs)) {
  362. ReqGoodsSkuSpec reqGoodsSkuSpec = reqGoodsSkuSpecs.get(0);
  363. if (CollUtil.isEmpty(reqGoodsSkuSpec.getValues())) {
  364. //删除整个一级分类key
  365. String specFirstKey = reqGoodsSkuSpec.getKey();
  366. GoodsDonSku sku = goodsDonSkuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class)
  367. .eq(GoodsDonSku::getGoodsId, goodsId)
  368. .like(GoodsDonSku::getSpecJson, specFirstKey).last("limit 1"));
  369. if (sku != null) {
  370. throw BusinessRuntimeException.getInstance("删除总规格分类,存在使用该总规格分类的规格");
  371. }
  372. } else {
  373. Map<Integer, List<ReqGoodsSkuSpec.Node>> updateSecondMap = reqGoodsSkuSpec.getValues().stream().filter(node -> node.getId() != null).collect(Collectors.groupingBy(ReqGoodsSkuSpec.Node::getId));
  374. ReqGoodsSkuSpec dbReqGoodsSkuSpec = dbSpecMap.get(key).get(0);
  375. for (ReqGoodsSkuSpec.Node dbSecondValue : dbReqGoodsSkuSpec.getValues()) {
  376. if (updateSecondMap.get(dbSecondValue.getId()) == null) {
  377. GoodsDonSku sku = goodsDonSkuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class)
  378. .eq(GoodsDonSku::getGoodsId, goodsId)
  379. .like(GoodsDonSku::getSpecVal, dbSecondValue.getValue()).last("limit 1"));
  380. if (sku != null) {
  381. throw BusinessRuntimeException.getInstance("删除总规格分类,存在使用该总规格分类的规格");
  382. }
  383. }
  384. dbNodeMap.put(dbSecondValue.getId(), dbSecondValue);
  385. }
  386. }
  387. }
  388. //去除总规格分类时
  389. //校验是否已引用该属性规格
  390. if (CollUtil.isEmpty(reqGoodsSkuSpecs)) {
  391. ReqGoodsSkuSpec dbReqGoodsSkuSpec = dbSpecMap.get(key).get(0);
  392. //删除整个一级分类key
  393. String specFirstKey = dbReqGoodsSkuSpec.getKey();
  394. GoodsDonSku sku = goodsDonSkuMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSku.class)
  395. .eq(GoodsDonSku::getGoodsId, goodsId)
  396. .like(GoodsDonSku::getSpecJson, specFirstKey).last("limit 1"));
  397. if (sku != null) {
  398. throw BusinessRuntimeException.getInstance("删除总规格分类,存在使用该总规格分类的规格");
  399. }
  400. }
  401. }
  402. return dbNodeMap;
  403. }
  404. return null;
  405. }
  406. /**
  407. * 更新二级分类标题价格等 同步库中sku
  408. */
  409. public void syncSpecNodeSku(Long goodsId, Map<Integer, ReqGoodsSkuSpec.Node> dbNodeMap, ReqGoodsSkuSpec.Node e) {
  410. if (CollUtil.isNotEmpty(dbNodeMap)) {
  411. ReqGoodsSkuSpec.Node dbNode = dbNodeMap.get(e.getId());
  412. if (dbNode == null) {
  413. return;
  414. }
  415. AtomicBoolean isUpdateTitle = new AtomicBoolean(false);
  416. AtomicBoolean isUpdatePrice = new AtomicBoolean(false);
  417. AtomicBoolean isUpdateBenefits = new AtomicBoolean(false);
  418. if (!StrUtil.equals(dbNode.getValue(), e.getValue())) {
  419. isUpdateTitle.set(true);
  420. }
  421. if (e.getPrice() == null) {
  422. e.setPrice(BigDecimal.ZERO);
  423. }
  424. if (dbNode.getPrice() != null && e.getPrice().compareTo(dbNode.getPrice()) != 0) {
  425. isUpdatePrice.set(true);
  426. }
  427. if (!StrUtil.equals(dbNode.getBenefitsList(), e.getBenefitsList())) {
  428. isUpdateBenefits.set(true);
  429. }
  430. if (isUpdateTitle.get() || isUpdatePrice.get() || isUpdateBenefits.get()) {
  431. List<GoodsDonSku> goodsDonSkus = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
  432. .eq(GoodsDonSku::getGoodsId, goodsId));
  433. goodsDonSkus.forEach(sku -> {
  434. try {
  435. List<Integer> specIdsList = Jsons.parseList(sku.getSpecIds(), Integer.class);
  436. if (specIdsList.contains(dbNode.getId())) {
  437. if (isUpdateTitle.get()) {
  438. sku.setSpecJson(sku.getSpecJson().replaceAll(dbNode.getValue(), e.getValue()));
  439. sku.setSpecVal(sku.getSpecVal().replaceAll(dbNode.getValue(), e.getValue()));
  440. }
  441. if (isUpdatePrice.get()) {
  442. sku.setPrice(sku.getPrice().subtract(dbNode.getPrice()).add(e.getPrice()));
  443. }
  444. if (isUpdateBenefits.get()) {
  445. if (StrUtil.isEmpty(e.getBenefitsList())) {
  446. sku.setBenefitsList(StrUtil.EMPTY);
  447. } else {
  448. try {
  449. sku.setBenefitsList(e.getBenefitsList());
  450. } catch (Exception exception) {
  451. }
  452. }
  453. }
  454. goodsDonSkuMapper.updateById(sku);
  455. }
  456. } catch (Exception exception) {
  457. }
  458. });
  459. }
  460. }
  461. }
  462. }