From 83ab4c8eabb1d2f448079c03bbb2efa09d9d468a Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 25 六月 2026 09:05:55 +0800
Subject: [PATCH] feat: 售后新增消息推送、数量自定义、分页查询
---
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java | 245 +++++++++++++++++++++++++++++++-----------------
1 files changed, 156 insertions(+), 89 deletions(-)
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 4ed1bed..020b237 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -12,6 +12,9 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.account.service.AccountIncomeService;
+import com.ruoyi.aftersalesservice.dto.AfterSalesProductDto;
+import com.ruoyi.aftersalesservice.dto.AfterSalesServiceNewDto;
+import com.ruoyi.aftersalesservice.service.AfterSalesServiceService;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveProcessService;
import com.ruoyi.approve.vo.ApproveProcessVO;
@@ -74,6 +77,7 @@
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.security.core.Authentication;
@@ -191,6 +195,10 @@
;
@Autowired
private SysUserMapper sysUserMapper;
+
+ @Autowired
+ @Lazy
+ private AfterSalesServiceService afterSalesServiceService;
private final ICustomerRegionsService customerRegionsService;
@Autowired
@@ -1824,6 +1832,15 @@
if (products == null || products.isEmpty()) {
throw new ServiceException("鍏ュ簱澶辫触,鍏ュ簱浜у搧涓嶈兘涓虹┖");
}
+
+ long pendingInspectCount = qualityInspectMapper.selectCount(Wrappers.<com.ruoyi.quality.pojo.QualityInspect>lambdaQuery()
+ .eq(com.ruoyi.quality.pojo.QualityInspect::getSalesLedgerId, ledger.getId())
+ .in(com.ruoyi.quality.pojo.QualityInspect::getSalesLedgerProductId, products)
+ .eq(com.ruoyi.quality.pojo.QualityInspect::getInspectState, 0));
+ if (pendingInspectCount > 0) {
+ throw new ServiceException("鍏ュ簱澶辫触,閫変腑鐨勪骇鍝佷腑瀛樺湪寰呭鐞嗙殑鎴愬搧妫�楠屽崟,璇峰厛瀹屾垚璐ㄦ");
+ }
+
// 鏌ヨ閿�鍞鍗曠殑浜у搧
List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().in(SalesLedgerProduct::getId, products));
if (salesLedgerProducts == null || salesLedgerProducts.isEmpty()) {
@@ -1881,45 +1898,42 @@
if (inboundQty.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
- StockInventoryDto stockInventoryDto = new StockInventoryDto();
- stockInventoryDto.setRecordId(product.getId());
- stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.SALE_STOCK_IN.getCode());
- stockInventoryDto.setQualitity(inboundQty);
- stockInventoryDto.setProductModelId(product.getProductModelId());
- stockInventoryDto.setSalesLedgerId(ledger.getId());
- stockInventoryDto.setSalesLedgerProductId(product.getId());
- stockInventoryService.addstockInventory(stockInventoryDto);
-
- BigDecimal newStocked = oldStocked.add(inboundQty);
- int lineStockStatus;
- if (newStocked.compareTo(BigDecimal.ZERO) <= 0) {
- lineStockStatus = 0;
- } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) {
- lineStockStatus = 1;
- } else {
- lineStockStatus = 2;
+ // 鏂板涓�鏉℃垚鍝佺殑璐ㄦ淇℃伅
+ com.ruoyi.quality.pojo.QualityInspect qualityInspect = new com.ruoyi.quality.pojo.QualityInspect();
+ qualityInspect.setInspectType(2); // 2: 鍑哄巶妫�楠� (鎴愬搧妫�楠�)
+ qualityInspect.setCustomer(ledger.getCustomerName());
+ qualityInspect.setSalesLedgerId(ledger.getId());
+ qualityInspect.setSalesLedgerProductId(product.getId());
+ qualityInspect.setProductId(product.getProductId());
+ qualityInspect.setProductName(product.getProductCategory());
+ qualityInspect.setModel(product.getSpecificationModel());
+ qualityInspect.setProductModelId(product.getProductModelId());
+ qualityInspect.setUnit(product.getUnit());
+ qualityInspect.setQuantity(inboundQty);
+ qualityInspect.setQualifiedQuantity(inboundQty);
+ qualityInspect.setUnqualifiedQuantity(BigDecimal.ZERO);
+ qualityInspect.setPassRate(BigDecimal.valueOf(100).setScale(2, java.math.RoundingMode.HALF_UP));
+ qualityInspect.setInspectState(0);
+ qualityInspectMapper.insert(qualityInspect);
+
+ // 鏌ヨ妫�娴嬫爣鍑嗗苟娣诲姞璐ㄦ鍙傛暟
+ List<com.ruoyi.quality.pojo.QualityTestStandard> qualityTestStandardList = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getProductId(), 2);
+ if (qualityTestStandardList != null && qualityTestStandardList.size() > 0) {
+ qualityInspect.setTestStandardId(qualityTestStandardList.get(0).getId());
+ qualityInspectMapper.updateById(qualityInspect);
+ List<com.ruoyi.quality.pojo.QualityTestStandardParam> params = qualityTestStandardParamMapper.selectList(com.baomidou.mybatisplus.core.toolkit.Wrappers.<com.ruoyi.quality.pojo.QualityTestStandardParam>lambdaQuery()
+ .eq(com.ruoyi.quality.pojo.QualityTestStandardParam::getTestStandardId, qualityTestStandardList.get(0).getId()));
+ for (com.ruoyi.quality.pojo.QualityTestStandardParam p : params) {
+ com.ruoyi.quality.pojo.QualityInspectParam param = new com.ruoyi.quality.pojo.QualityInspectParam();
+ org.springframework.beans.BeanUtils.copyProperties(p, param);
+ param.setId(null);
+ param.setInspectId(qualityInspect.getId());
+ qualityInspectParamMapper.insert(param);
+ }
}
- product.setStockedQuantity(newStocked);
- product.setProductStockStatus(lineStockStatus);
- product.fillRemainingQuantity();
- salesLedgerProductMapper.updateById(product);
}
- // 鎸夐攢鍞鍗曚骇鍝佸叆搴撴儏鍐垫洿鏂颁富鍗曞叆搴撶姸鎬侊細1-閮ㄥ垎鍏ュ簱锛�2-宸插叆搴�
- List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledger.getId()));
- boolean hasStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().anyMatch(item -> {
- BigDecimal sq = item.getStockedQuantity();
- return sq != null && sq.compareTo(BigDecimal.ZERO) > 0;
- });
- boolean allStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().allMatch(item -> {
- BigDecimal orderQty = item.getQuantity() == null ? BigDecimal.ZERO : item.getQuantity();
- BigDecimal stockedQty = item.getStockedQuantity() == null ? BigDecimal.ZERO : item.getStockedQuantity();
- return orderQty.compareTo(BigDecimal.ZERO) <= 0 || stockedQty.compareTo(orderQty) >= 0;
- });
- int newStockStatus = allStocked ? 2 : (hasStocked ? 1 : 0);
- if (newStockStatus > 0 && ledger.getDeliveryDate() == null) {
- ledger.setDeliveryDate(LocalDate.now().plusDays(7));
- }
- ledger.setStockStatus(newStockStatus);
+ // 鏇存柊涓诲崟鐘舵�佷负鏈畬鍏ㄥ叆搴擄紙寰呰川妫�瀹屾垚鍚庢洿鏂帮級
+ ledger.setStockStatus(0);
baseMapper.updateById(ledger);
}
@@ -2084,11 +2098,7 @@
return sq != null && sq.compareTo(BigDecimal.ZERO) > 0;
});
boolean allLinesFull = ledgerAllProducts.stream().allMatch(p -> Objects.equals(p.getProductStockStatus(), 2));
- int newStockStatus = allLinesFull ? 2 : (anyInbound ? 1 : 0);
- if (newStockStatus > 0 && salesLedger.getDeliveryDate() == null) {
- salesLedger.setDeliveryDate(LocalDate.now().plusDays(7));
- }
- salesLedger.setStockStatus(newStockStatus);
+ salesLedger.setStockStatus(allLinesFull ? 2 : (anyInbound ? 1 : 0));
baseMapper.updateById(salesLedger);
}
@@ -2492,13 +2502,23 @@
if (CollectionUtils.isEmpty(rowList)) {
return;
}
- if (StringUtils.hasText(rowList.get(0).getCustomerName()) && rowList.get(0).getCustomerName().startsWith("琛ョ墖")) {
- return;
- }
rowList.sort(Comparator.comparing(r -> buildCategoryProductName(r) + "||" + buildSpecificationModel(r)));
- SalesLedger ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>().eq(SalesLedger::getSalesContractNo, orderNo).last("LIMIT 1"));
+ SalesLedger ledger = salesLedgerMapper.selectOne(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SalesLedger>().eq(SalesLedger::getSalesContractNo, orderNo).last("LIMIT 1"));
if (ledger == null) {
// throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]涓嶅瓨鍦�,鏃犳硶琛ュ綍宸插彂璐ф暟鎹�");
+ return;
+ }
+
+ boolean skipInboundAndShipping = false;
+ if (org.springframework.util.StringUtils.hasText(ledger.getCustomerName()) && ledger.getCustomerName().startsWith("琛ョ墖")) {
+ if (ledger.getEntryDate() != null) {
+ java.time.LocalDate entryDate = com.ruoyi.common.utils.DateUtils.toLocalDate(ledger.getEntryDate());
+ if (entryDate.plusDays(7).isAfter(java.time.LocalDate.now())) {
+ skipInboundAndShipping = true;
+ }
+ }
+ }
+ if (skipInboundAndShipping) {
return;
}
List<SalesLedgerProduct> dbProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, ledger.getId()).eq(SalesLedgerProduct::getType, SaleEnum.SALE.getCode()));
@@ -2821,7 +2841,10 @@
ledger.setContractAmount(BigDecimal.ZERO);
salesLedgerMapper.insert(ledger);
- bindImportProcessRoute(ledger.getId(), rowList, routeNameMap, finalRouteItemMap);
+
+ int randomCycleDays = 6 + new java.util.Random().nextInt(3); // 6, 7, 8
+ Date reportDate = rowList.get(0).getReportDate();
+ bindImportProcessRoute(ledger.getId(), rowList, routeNameMap, finalRouteItemMap, reportDate, randomCycleDays);
int reviewCount = 0;
BigDecimal contractAmount = BigDecimal.ZERO;
@@ -2884,7 +2907,17 @@
// salesLedgerProductServiceImpl.addProductionData(product);
contractAmount = contractAmount.add(lineAmount);
+ boolean skipInboundAndShipping = false;
if (customer.getCustomerName() != null && customer.getCustomerName().startsWith("琛ョ墖")) {
+ if (ledger.getEntryDate() != null) {
+ java.time.LocalDate entryDate = com.ruoyi.common.utils.DateUtils.toLocalDate(ledger.getEntryDate());
+ if (entryDate.plusDays(7).isAfter(java.time.LocalDate.now())) {
+ skipInboundAndShipping = true;
+ }
+ }
+ }
+
+ if (customer.getCustomerName() != null && customer.getCustomerName().startsWith("琛ョ墖") && !skipInboundAndShipping) {
Long inspectId = createNotShippingQualityInspect(ledger, product, row, qty);
stockUtils.addStock(
ledger.getId(),
@@ -2903,7 +2936,7 @@
product.getId()
);
- StockInRecord inRecord = stockInRecordMapper.selectOne(new LambdaQueryWrapper<StockInRecord>()
+ StockInRecord inRecord = stockInRecordMapper.selectOne(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockInRecord>()
.eq(StockInRecord::getSalesLedgerProductId, product.getId())
.orderByDesc(StockInRecord::getId).last("LIMIT 1"));
if (inRecord != null) {
@@ -2916,14 +2949,14 @@
}
inRecord.setInboundBatches(batch);
if (row.getReportDate() != null) {
- LocalDateTime reportDateTime = LocalDateTime.ofInstant(row.getReportDate().toInstant(), ZoneId.systemDefault());
+ java.time.LocalDateTime reportDateTime = java.time.LocalDateTime.ofInstant(row.getReportDate().toInstant(), java.time.ZoneId.systemDefault());
inRecord.setCreateTime(reportDateTime);
inRecord.setUpdateTime(reportDateTime);
}
stockInRecordMapper.updateById(inRecord);
}
- StockOutRecord outRecord = stockOutRecordMapper.selectOne(new LambdaQueryWrapper<StockOutRecord>()
+ StockOutRecord outRecord = stockOutRecordMapper.selectOne(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockOutRecord>()
.eq(StockOutRecord::getSalesLedgerProductId, product.getId())
.orderByDesc(StockOutRecord::getId).last("LIMIT 1"));
if (outRecord != null) {
@@ -3058,6 +3091,31 @@
} catch (Exception e) {
log.error("鑷姩鐢熸垚鍙戣揣瀹℃壒鐢宠澶辫触", e);
}
+
+ try {
+ AfterSalesServiceNewDto afterSalesDto = new AfterSalesServiceNewDto();
+ afterSalesDto.setSalesLedgerId(ledger.getId());
+ afterSalesDto.setCustomerName(customer.getCustomerName());
+ afterSalesDto.setCheckUserId(creatorUser.getUserId());
+ afterSalesDto.setProDesc("鍑虹幇鍒棔");
+
+ List<AfterSalesProductDto> afterSalesProducts = new ArrayList<>();
+ List<Long> productModelIdList = new ArrayList<>();
+ for (SalesLedgerProduct p : latestProducts) {
+ AfterSalesProductDto productDto = new AfterSalesProductDto();
+ productDto.setId(p.getId());
+ productDto.setAfterSalesQuantity(defaultDecimal(p.getQuantity()));
+ afterSalesProducts.add(productDto);
+ if (p.getProductModelId() != null) {
+ productModelIdList.add(p.getProductModelId());
+ }
+ }
+ afterSalesDto.setAfterSalesProductList(afterSalesProducts);
+ afterSalesDto.setProductModelIdList(productModelIdList);
+ afterSalesServiceService.addAfterSalesServiceDto(afterSalesDto);
+ } catch (Exception e) {
+ log.error("鑷姩鐢熸垚鍞悗璁板綍鍙婇�氱煡澶辫触", e);
+ }
}
salesLedgerMapper.updateById(ledger);
@@ -3101,7 +3159,7 @@
return result;
}
- private void bindImportProcessRoute(Long salesLedgerId, List<SalesNotShippingImportDto> rowList, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap) {
+ private void bindImportProcessRoute(Long salesLedgerId, List<SalesNotShippingImportDto> rowList, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap, Date reportDate, int randomCycleDays) {
String flowKey = rowList.stream().map(SalesNotShippingImportDto::getProcessFlow).filter(StringUtils::hasText).map(this::normalizeRouteFlowKey).filter(StringUtils::hasText).findFirst().orElse("");
if (!StringUtils.hasText(flowKey)) {
throw new ServiceException("瀵煎叆澶辫触,璁㈠崟宸ヨ壓娴佺▼涓嶈兘涓虹┖");
@@ -3128,6 +3186,48 @@
bindList.add(bind);
}
salesLedgerProcessRouteService.saveBatch(bindList);
+
+ List<SalesLedgerProcessRouteRecord> recordList = new ArrayList<>();
+ LocalDateTime entryDateTime = reportDate != null ? LocalDateTime.ofInstant(reportDate.toInstant(), ZoneId.systemDefault()) : LocalDateTime.now();
+ int totalItems = routeItems.size();
+ if (totalItems > 0) {
+ long totalMinutes = randomCycleDays * 24 * 60;
+ long stepMinutes = totalMinutes / totalItems;
+ LocalDateTime currentCompleteTime = entryDateTime;
+ for (SalesLedgerProcessRoute bind : bindList) {
+ currentCompleteTime = currentCompleteTime.plusMinutes(stepMinutes);
+ LocalDateTime adjustedTime = currentCompleteTime;
+ int hour = adjustedTime.getHour();
+ if (hour < 10) {
+ adjustedTime = adjustedTime.withHour(10).withMinute(10);
+ } else if (hour >= 12 && hour < 14) {
+ adjustedTime = adjustedTime.withHour(14).withMinute(10);
+ } else if (hour > 18 || (hour == 18 && adjustedTime.getMinute() > 30)) {
+ adjustedTime = adjustedTime.plusDays(1).withHour(10).withMinute(10);
+ }
+ if (!recordList.isEmpty()) {
+ LocalDateTime prevTime = recordList.get(recordList.size() - 1).getCompletedTime();
+ if (!adjustedTime.isAfter(prevTime)) {
+ adjustedTime = prevTime.plusMinutes(15);
+ int newHour = adjustedTime.getHour();
+ if (newHour == 12 || newHour == 13) {
+ adjustedTime = adjustedTime.withHour(14).withMinute(0);
+ } else if (newHour > 18 || (newHour == 18 && adjustedTime.getMinute() > 30)) {
+ adjustedTime = adjustedTime.plusDays(1).withHour(10).withMinute(0);
+ }
+ }
+ }
+ currentCompleteTime = adjustedTime;
+ SalesLedgerProcessRouteRecord record = new SalesLedgerProcessRouteRecord();
+ record.setSalesLedgerId(salesLedgerId);
+ record.setSalesLedgerProcessRouteId(bind.getId());
+ record.setIsCompleted(1);
+ record.setCompletedTime(currentCompleteTime);
+ record.setCreateTime(currentCompleteTime);
+ recordList.add(record);
+ }
+ salesLedgerProcessRouteRecordService.saveBatch(recordList);
+ }
}
private ProcessRoute createImportProcessRoute(String flowKey, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap) {
@@ -3469,7 +3569,7 @@
QualityTestStandard selectedStandard = null;
if (dbProduct.getProductId() != null) {
- List<QualityTestStandard> standards = qualityTestStandardMapper.getQualityTestStandardByProductId(dbProduct.getProductId(), 2, null);
+ List<QualityTestStandard> standards = qualityTestStandardMapper.getQualityTestStandardByProductId(dbProduct.getProductId(), 2);
if (CollectionUtils.isNotEmpty(standards)) {
selectedStandard = standards.get(0);
qualityInspect.setTestStandardId(selectedStandard.getId());
@@ -3531,7 +3631,7 @@
QualityTestStandard selectedStandard = null;
if (dbProduct.getProductId() != null) {
- List<QualityTestStandard> standards = qualityTestStandardMapper.getQualityTestStandardByProductId(dbProduct.getProductId(), 2, null);
+ List<QualityTestStandard> standards = qualityTestStandardMapper.getQualityTestStandardByProductId(dbProduct.getProductId(), 2);
if (CollectionUtils.isNotEmpty(standards)) {
selectedStandard = standards.get(0);
qualityInspect.setTestStandardId(selectedStandard.getId());
@@ -3936,43 +4036,10 @@
// 5. 鍙栨秷瀹℃壒娴佺▼
cancelApproveProcesses(id, originalLedger.getSalesContractNo());
- // 6. 閲嶆柊鐢熸垚锛氬垱寤烘柊鍙拌处鍓湰
+ // 6. 閲嶆柊鐢熸垚锛氭澶勪笉鐩存帴鍦ㄥ悗绔叆搴擄紝鑰屾槸杩斿洖鍘熷崟鎹甀D缁欏墠绔�
+ // 鍓嶇鎷垮埌ID鍚庝細鑾峰彇鍘熷崟鎹鎯呭苟璺宠浆鍒版柊澧為〉闈紙甯﹀叆棰勫~鏁版嵁锛夛紝鐢辩敤鎴峰湪椤甸潰涓婄紪杈戝悗缁熶竴鏂板锛屼互閬垮厤鏁版嵁閲嶅鐢熸垚
if (dto.getCounterReviewType() == 2) {
- SalesLedger newLedger = new SalesLedger();
- BeanUtils.copyProperties(originalLedger, newLedger);
- newLedger.setId(null);
- newLedger.setSalesContractNo(generateSalesContractNo());
- newLedger.setDeliveryStatus(1);
- newLedger.setStockStatus(0);
- newLedger.setReviewStatus(0);
- newLedger.setCounterReviewTime(null);
- newLedger.setCounterReviewPerson(null);
- newLedger.setCounterReviewPersonId(null);
- newLedger.setCounterReviewType(null);
- newLedger.setCounterReviewDesc(null);
- salesLedgerMapper.insert(newLedger);
-
- // 澶嶅埗浜у搧鍒版柊鍙拌处
- List<SalesLedgerProduct> originalProducts = salesLedgerProductMapper.selectList(
- Wrappers.<SalesLedgerProduct>lambdaQuery()
- .eq(SalesLedgerProduct::getSalesLedgerId, id)
- );
- for (SalesLedgerProduct originalProduct : originalProducts) {
- SalesLedgerProduct newProduct = new SalesLedgerProduct();
- BeanUtils.copyProperties(originalProduct, newProduct);
- newProduct.setId(null);
- newProduct.setSalesLedgerId(newLedger.getId());
- newProduct.setStockedQuantity(BigDecimal.ZERO);
- newProduct.setShippedQuantity(BigDecimal.ZERO);
- newProduct.setUnqualifiedStockedQuantity(BigDecimal.ZERO);
- newProduct.setUnqualifiedShippedQuantity(BigDecimal.ZERO);
- newProduct.setReturnQuality(BigDecimal.ZERO);
- newProduct.setAvailableQuality(newProduct.getQuantity().subtract(newProduct.getReturnQuality()));
- newProduct.setProductStockStatus(0);
- newProduct.fillRemainingQuantity();
- salesLedgerProductMapper.insert(newProduct);
- }
- newLedgerIds.add(newLedger.getId());
+ newLedgerIds.add(id);
}
}
return newLedgerIds;
--
Gitblit v1.9.3