Browse Source

导入销售预测

bai 3 weeks ago
parent
commit
71b7e2a8d1

+ 47 - 53
blade-service/blade-factory/src/main/java/org/springblade/factory/api/controller/SalesForecastSummaryController.java

@@ -208,20 +208,20 @@ public class SalesForecastSummaryController {
 
 
 	@PostMapping("/importForecastData/{id}")
-	@ApiOperation(value = "导入销售预测数据(覆盖同年同月数据)")
+	@ApiOperation(value = "导入销售预测数据(不删除原有数据)")
 	public R<List<PcBladeSalesForecastSummary>> importForecastData(@PathVariable("id") Long id, @RequestParam("file") MultipartFile file) {
 
+		// 1. 基础参数校验
 		if (id == null) {
 			return R.fail("预测ID不能为空");
 		}
 
 		PcBladeSalesForecastMain pcBladeDealerForecast = forecastMainService.getById(id);
-
 		if (pcBladeDealerForecast == null) {
 			return R.fail("预测主数据不存在");
 		}
 
-		// 1. 校验文件
+		// 2. 文件校验
 		if (file.isEmpty()) {
 			return R.fail("导入文件不能为空");
 		}
@@ -230,15 +230,14 @@ public class SalesForecastSummaryController {
 			return R.fail("仅支持.xlsx格式的Excel文件导入");
 		}
 
-		// 2. 从主表获取年月(用于删除同年同月数据)
+		// 3. 从主表获取年月
 		Integer forecastYear = pcBladeDealerForecast.getYear();
 		Integer forecastMonth = pcBladeDealerForecast.getMonth();
-
 		if (forecastYear == null || forecastMonth == null) {
 			return R.fail("预测主数据的年月不能为空");
 		}
 
-		// 获取当前登录用户ID
+		// 4. 用户信息校验
 		Long userId = AuthUtil.getUserId();
 		if (userId == null) {
 			return R.fail("用户未登录");
@@ -249,25 +248,28 @@ public class SalesForecastSummaryController {
 		}
 
 		try {
-			// 3. 删除同年同月已有数据(先删后导,覆盖逻辑)
-			LambdaQueryWrapper<PcBladeSalesForecastSummary> deleteWrapper = new LambdaQueryWrapper<>();
-			deleteWrapper.eq(PcBladeSalesForecastSummary::getYear, forecastYear)
-				.eq(PcBladeSalesForecastSummary::getMonth, forecastMonth)
-				.eq(PcBladeSalesForecastSummary::getCustomerId, user.getData().getCustomerId())
-				.eq(PcBladeSalesForecastSummary::getForecastMainId, id);
-			forecastService.deletePcBladeSalesForecastSummaryByIds(deleteWrapper);
-
-			// 4. 定义列表存储导入数据(使用线程安全的列表)
-			List<PcBladeSalesForecastSummary> saveList = Collections.synchronizedList(new ArrayList<>());
-
-			// ========== 修复核心问题:使用同步读取方式,确保数据能被捕获 ==========
-			// 方式1:使用同步读取(推荐,适合中小文件)
+			// ========== 移除删除数据的逻辑 ==========
+			// 不再执行删除forecast_main_id = id的同年同月数据
+
+			// 5. 定义列表存储导入数据(无需线程安全,同步读取无并发)
+			List<PcBladeSalesForecastSummary> saveList = new ArrayList<>();
+
+			// 6. 同步读取Excel数据
 			List<SalesForecastImportDTO> dtoList = EasyExcel.read(file.getInputStream())
 				.head(SalesForecastImportDTO.class)
 				.sheet()
-				.doReadSync(); // 同步读取,直接返回所有数据
+				.doReadSync();
+
+			// 7. 提前查询经销商信息(避免循环内重复查询,提升性能)
+			QueryWrapper<ViewCustomerSel> customerQueryWrapper = new QueryWrapper<>();
+			customerQueryWrapper.eq("customer_id", user.getData().getCustomerId());
+			List<ViewCustomerSel> customerList = zcrmViewCustomerSelService.list(customerQueryWrapper);
+			if (customerList.isEmpty()) {
+				return R.fail("经销商数据不存在");
+			}
+			ViewCustomerSel customerInfo = customerList.get(0);
 
-			// 5. 遍历解析的数据,转换为入库实体
+			// 8. 遍历解析的数据,转换为入库实体
 			for (SalesForecastImportDTO dto : dtoList) {
 				// 跳过空行(防止Excel空行导致无效数据)
 				if (dto.getItemCode() == null && dto.getItemName() == null && dto.getForecastQuantity() == null) {
@@ -276,37 +278,22 @@ public class SalesForecastSummaryController {
 
 				PcBladeSalesForecastSummary summary = new PcBladeSalesForecastSummary();
 
-				// 基础字段(使用主表的年月)
+				// 基础字段赋值
 				summary.setYear(forecastYear);
 				summary.setMonth(forecastMonth);
 				summary.setForecastMainId(id); // 关联主预测表的ID
 
-				QueryWrapper<ViewCustomerSel> queryWrapper = new QueryWrapper<>();
-				queryWrapper.eq("customer_id", user.getData().getCustomerId());
-				List<ViewCustomerSel> customerList = zcrmViewCustomerSelService.list(queryWrapper);
-				if (customerList.isEmpty()) {
-					return R.fail("数据不存在");
-				}
-				ViewCustomerSel customer1 = customerList.get(0);
-
-				// 经销商信息(从当前登录用户获取)
-				summary.setCustomerCode(customer1.getCustomerCode());
-				// 补充经销商名称/ID(根据你的业务逻辑查询)
-				ViewCustomerSel customer = zcrmViewCustomerSelService.getOne(
-					new LambdaQueryWrapper<ViewCustomerSel>().eq(ViewCustomerSel::getCustomerId, userId)
-				);
-				if (customer != null) {
-					summary.setCustomerId(customer.getId());
-					summary.setCustomerName(customer.getCustomerName()); // 注意字段名和你的实体一致
-				}
-
-				// Excel导入字段映射(处理空值)
-				summary.setItemCode(dto.getItemCode() == null ? "" : dto.getItemCode().trim());       // 物料号
-				summary.setItemName(dto.getItemName() == null ? "" : dto.getItemName().trim());       // 物料名称
-				summary.setBrandName(dto.getBrandName() == null ? "" : dto.getBrandName().trim());     // 品牌名
-				summary.setSpecs(dto.getSpecs() == null ? "" : dto.getSpecs().trim());                 // 规格
-				summary.setPattern(dto.getPattern() == null ? "" : dto.getPattern().trim());           // 花纹
-				// 预测数量(空值默认0,避免数据库报错)
+				// 经销商信息赋值(统一使用提前查询的经销商信息)
+				summary.setCustomerId(customerInfo.getId());
+				summary.setCustomerCode(customerInfo.getCustomerCode());
+				summary.setCustomerName(customerInfo.getCustomerName());
+
+				// Excel导入字段映射(处理空值和首尾空格)
+				summary.setItemCode(dto.getItemCode() == null ? "" : dto.getItemCode().trim());
+				summary.setItemName(dto.getItemName() == null ? "" : dto.getItemName().trim());
+				summary.setBrandName(dto.getBrandName() == null ? "" : dto.getBrandName().trim());
+				summary.setSpecs(dto.getSpecs() == null ? "" : dto.getSpecs().trim());
+				summary.setPattern(dto.getPattern() == null ? "" : dto.getPattern().trim());
 				summary.setForecastQuantity(dto.getForecastQuantity() == null ? BigDecimal.ZERO : dto.getForecastQuantity());
 
 				// 补充物料ID/品牌ID(关联库存表查询)
@@ -317,7 +304,7 @@ public class SalesForecastSummaryController {
 					if (stock != null) {
 						summary.setItemId(stock.getItemId());
 						summary.setBrandId(stock.getItemId());
-						summary.setBrandCode(stock.getItemCode()); // 若有品牌编码字段可调整
+						summary.setBrandCode(stock.getItemCode());
 					}
 				}
 
@@ -326,15 +313,22 @@ public class SalesForecastSummaryController {
 				saveList.add(summary);
 			}
 
-			// 6. 批量保存数据
+			// 9. 批量保存数据(仅当有有效数据时保存)
 			if (!saveList.isEmpty()) {
-				forecastService.saveBatch(saveList);
+				boolean saveSuccess = forecastService.saveBatch(saveList);
+				if (!saveSuccess) {
+					return R.fail("数据保存失败");
+				}
 			}
 
-			QueryWrapper<PcBladeSalesForecastSummary> queryWrapper = new QueryWrapper<>();
-			queryWrapper.eq("forecast_main_id", id);
+			// 10. 查询该forecast_main_id下的所有汇总明细数据并返回
+			LambdaQueryWrapper<PcBladeSalesForecastSummary> queryWrapper = new LambdaQueryWrapper<>();
+			queryWrapper.eq(PcBladeSalesForecastSummary::getForecastMainId, id);
+			// 可选:按物料号排序,返回数据更规整
+			queryWrapper.orderByAsc(PcBladeSalesForecastSummary::getItemCode);
 
 			List<PcBladeSalesForecastSummary> lists = forecastService.list(queryWrapper);
+
 			return R.data(lists);
 		} catch (Exception e) {
 			e.printStackTrace();