| 
					
				 | 
			
			
				@@ -7,10 +7,14 @@ import java.time.ZoneId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import java.util.stream.Collectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.qmrb.parking.fee.ParkingFeeCalculator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.qmrb.system.mapper.BarnRecordMapper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.qmrb.system.mapper.OrderMapper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.qmrb.system.pojo.entity.BarnRecord; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.qmrb.system.pojo.entity.CarParkStoredCard; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import com.qmrb.system.service.IBarnRecordService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.qmrb.system.pojo.entity.Order; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.qmrb.system.service.ICarParkStoredCardService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.qmrb.system.service.OrderService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.beans.factory.annotation.Autowired; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -49,7 +53,10 @@ public class CarParkChargingRulesServiceImpl extends ServiceImpl<CarParkCharging 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	private ICarParkStoredCardService parkStoredCardService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	@Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	private IBarnRecordService barnRecordService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	private BarnRecordMapper barnRecordMapper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	@Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	private OrderMapper orderMapper; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/**分页查询 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -116,33 +123,80 @@ public class CarParkChargingRulesServiceImpl extends ServiceImpl<CarParkCharging 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	@Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	public BigDecimal calcuExpenses(Long recordId, Long userId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	public BigDecimal calcuExpenses(Long recordId, String carNumber) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// 查询当前用户是否有月卡 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		List<CarParkStoredCard> list = parkStoredCardService.list(new LambdaQueryWrapper<CarParkStoredCard>().eq(CarParkStoredCard::getUserId, userId).ge(CarParkStoredCard::getEndTime, LocalDateTime.now())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		BarnRecord barnRecord = barnRecordService.getById(recordId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		List<CarParkStoredCard> list = parkStoredCardService.list(new LambdaQueryWrapper<CarParkStoredCard>().eq(CarParkStoredCard::getPlateNumber, carNumber) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				.eq(CarParkStoredCard::getStatus,1).ge(CarParkStoredCard::getEndTime, LocalDateTime.now())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		BarnRecord barnRecord = barnRecordMapper.selectById(recordId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		Assert.isTrue(barnRecord != null, "计费时停车记录不存在,id为"+recordId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 根据停车场id获取到计费规则 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		List<CarParkChargingRules> parkChargingRules = this.list(new LambdaQueryWrapper<CarParkChargingRules>().eq(CarParkChargingRules::getCarParkId, barnRecord.getCarParkId())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Assert.isTrue(CollectionUtil.isNotEmpty(parkChargingRules), "计费规则不存在,停车场id为"+barnRecord.getCarParkId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		CarParkChargingRules carParkChargingRules = parkChargingRules.get(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 获取所有订单 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		List<Order> orderList = orderMapper.selectList(new LambdaQueryWrapper<Order>().eq(Order::getGoodId, recordId)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 示例计费规则 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ParkingFeeCalculator.FeeRule feeRule = new ParkingFeeCalculator.FeeRule(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		feeRule.freeDurationMinutes = carParkChargingRules.getFreeTime();//免费时长 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		feeRule.firstCycleFee = carParkChargingRules.getFirstFee() != null ? carParkChargingRules.getFirstFee().doubleValue() : 0;//首周期计费金额 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		feeRule.firstCycleDurationMinutes = carParkChargingRules.getFirstCycle();//首周期计费时长 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		feeRule.cycleDurationMinutes = carParkChargingRules.getBillingCycle();//计费周期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		feeRule.cycleFee = carParkChargingRules.getFee()!= null ? carParkChargingRules.getFee().doubleValue() : 0;//每周期计费金额 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		feeRule.dailyCapFee = carParkChargingRules.getFeeUpperLimit()!= null ? carParkChargingRules.getFeeUpperLimit().doubleValue() : 0;//24小时封顶费用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		feeRule.gracePeriodMinutes = carParkChargingRules.getOutInterval();// 离场时长宽容度(分钟) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 将 Date 转换为 Instant 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Instant instant = barnRecord.getInTime().toInstant(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 将 Instant 转换为 LocalDateTime(假设使用系统默认时区) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		LocalDateTime inDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 示例停车记录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ParkingFeeCalculator.ParkingRecord parkingRecord = new ParkingFeeCalculator.ParkingRecord(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		parkingRecord.entryTime = inDateTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		parkingRecord.exitTime = LocalDateTime.now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		parkingRecord.paidAmount = barnRecord.getReceivedAmount()!= null ? barnRecord.getReceivedAmount().doubleValue() : 0;;//已支付金额 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if(CollectionUtil.isNotEmpty(orderList)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			ArrayList<ParkingFeeCalculator.PaymentRecord> paymentRecords = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			for (Order order : orderList) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ParkingFeeCalculator.PaymentRecord record = new ParkingFeeCalculator.PaymentRecord(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				Instant payTimeInstant = order.getPayTime().toInstant();; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				record.paymentTime = payTimeInstant.atZone(ZoneId.systemDefault()).toLocalDateTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				record.amount = order.getAmountsPayable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				paymentRecords.add(record); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			parkingRecord.paymentRecords = paymentRecords; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		double fee = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		if(CollectionUtil.isNotEmpty(list)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			CarParkStoredCard parkStoredCard = list.get(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// 将 Date 转换为 Instant 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			Instant instant = barnRecord.getInTime().toInstant(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// 将 Instant 转换为 LocalDateTime(假设使用系统默认时区) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			LocalDateTime inDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(parkStoredCard.getStartTime().isAfter(inDateTime) && parkStoredCard.getEndTime().isBefore(LocalDateTime.now())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				//入库时间在月卡开始日前,出库时间在结束日前 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} else if(parkStoredCard.getStartTime().isAfter(inDateTime) && parkStoredCard.getEndTime().isAfter(LocalDateTime.now())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				//入库时间在月卡开始日前,出库时间在结束日内 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} else if (parkStoredCard.getStartTime().isBefore(inDateTime) && parkStoredCard.getEndTime().isBefore(LocalDateTime.now())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				//入库时间在月卡开始日后,出库时间在结束日前 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} else if(parkStoredCard.getStartTime().isBefore(inDateTime) && parkStoredCard.getEndTime().isAfter(LocalDateTime.now())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				//入库时间在月卡开始日后,出库时间在结束日后 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			parkingRecord.monthlyCardExpiryTime = parkStoredCard.getEndTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 计算费用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			fee = ParkingFeeCalculator.calculateParkingFee(parkingRecord, feeRule, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// if(parkStoredCard.getStartTime().isAfter(inDateTime) && parkStoredCard.getEndTime().isBefore(LocalDateTime.now())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 	//入库时间在月卡开始日前,出库时间在结束日前  不会出现 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// } else if(parkStoredCard.getStartTime().isAfter(inDateTime) && parkStoredCard.getEndTime().isAfter(LocalDateTime.now())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 	//入库时间在月卡开始日前,出库时间在结束日后  不会出现 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// } else if (parkStoredCard.getStartTime().isBefore(inDateTime) && parkStoredCard.getEndTime().isBefore(LocalDateTime.now())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 	//入库时间在月卡开始日后,出库时间在结束日前 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 	return BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// } else if(parkStoredCard.getStartTime().isBefore(inDateTime) && parkStoredCard.getEndTime().isAfter(LocalDateTime.now())){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 	//入库时间在月卡开始日后,出库时间在结束日后 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			//直接计算费用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			fee = ParkingFeeCalculator.calculateParkingFee(parkingRecord, feeRule, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return new BigDecimal(fee); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |