Browse Source

修改车位

loemkie 2 weeks ago
parent
commit
8606a763ba

+ 56 - 34
src/main/java/com/qmrb/system/service/impl/ContractPlaceNumberRelServiceImpl.java

@@ -14,11 +14,9 @@ import com.qmrb.system.mapper.BarnRecordMapper;
 import com.qmrb.system.mapper.ContractPlaceNumberRelMapper;
 import com.qmrb.system.pojo.entity.*;
 import com.qmrb.system.pojo.form.ContractPlaceNumberRelForm;
-import com.qmrb.system.pojo.form.VirtualParkingSlotForm;
 import com.qmrb.system.pojo.query.ContractPlaceNumberRelQuery;
 import com.qmrb.system.pojo.vo.ContractPlaceNumberRelVO;
 import com.qmrb.system.service.*;
-import groovy.time.BaseDuration;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -30,7 +28,6 @@ import org.springframework.stereotype.Service;
 import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
-import java.time.temporal.ChronoUnit;
 import java.util.*;
 
 /**
@@ -216,7 +213,7 @@ public class ContractPlaceNumberRelServiceImpl extends ServiceImpl<ContractPlace
         }
         
         virtualParkingSlot.setStatus("1");//占用
-        virtualParkingSlot.setSlotType(StrUtil.equals("1",form.getCarType())? "small" : "large");
+        virtualParkingSlot.setSlotType(StrUtil.equals("1",form.getCarType())? "large" : "small");
         virtualParkingSlot.setCurrentPlateNumber(form.getPlateNumber());
         virtualParkingSlot.setLastOccupiedTime(form.getStartTime());
         virtualParkingSlot.setLastReleasedTime(form.getEndTime());
@@ -387,43 +384,68 @@ public class ContractPlaceNumberRelServiceImpl extends ServiceImpl<ContractPlace
 
         LocalDateTime endDateTime = LocalDateTimeUtil.beginOfDay(currentDate).plusDays(1).withHour(14).withMinute(0).withSecond(0);
         Date endTime = Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant());//隔天14:00:00
-        // // 获取有效期包含当天的车牌登记记录
-        // List<ContractPlaceNumberRel> contractPlaceNumberRels = this.list(
-        //         new LambdaQueryWrapper<ContractPlaceNumberRel>()
-        //                 .eq(ContractPlaceNumberRel::getContractId, contractId)
-        //                 .ge(ContractPlaceNumberRel::getEndTime, startTime)
-        //                 .le(ContractPlaceNumberRel::getStartTime, endOfDay)
-        // );
+        
         // 获取当天创建的或有效期包含当天的车牌登记记录
         List<ContractPlaceNumberRel> contractPlaceNumberRels = baseMapper.getCurrentPlaceNumberRel(
-                contractId,startTime,endOfDay
+                contractId, startTime, endOfDay
         );
         
-        // 当天车位已初始化
-        if(CollectionUtil.isNotEmpty(contractPlaceNumberRels) && contractPlaceNumberRels.size() == list.size()){
-            return null;
-        }
-        ArrayList<String> virtualSlotMumbers = new ArrayList<>();
-        List<ContractPlaceNumberRel> currentDayContractPlaceNumberRels = new ArrayList<>();
-        if(CollectionUtil.isNotEmpty(contractPlaceNumberRels)){
-            contractPlaceNumberRels.forEach(iter->{
-                virtualSlotMumbers.add(iter.getVirtualSlotNumber());
-            });
+        // 创建一个Map,键为虚拟槽号,值为对应的关系记录
+        Map<String, ContractPlaceNumberRel> existingRelMap = new HashMap<>();
+        if(CollectionUtil.isNotEmpty(contractPlaceNumberRels)) {
+            for(ContractPlaceNumberRel rel : contractPlaceNumberRels) {
+                existingRelMap.put(rel.getVirtualSlotNumber(), rel);
+            }
         }
         
-        list.stream().forEach(iter->{
-            if(!virtualSlotMumbers.contains(iter.getVirtualSlotNumber())){
-                ContractPlaceNumberRel contractPlaceNumberRel = new ContractPlaceNumberRel();
-                contractPlaceNumberRel.setVirtualSlotNumber(iter.getVirtualSlotNumber());
-                contractPlaceNumberRel.setStartTime(startTime);
-                contractPlaceNumberRel.setEndTime(endTime);
-                contractPlaceNumberRel.setContractId(contractId);
-                contractPlaceNumberRel.setCarType(StrUtil.equals(iter.getSlotType(),"large") ? "1":"2");
-                currentDayContractPlaceNumberRels.add(contractPlaceNumberRel);
+        // 需要创建或更新的记录列表
+        List<ContractPlaceNumberRel> newOrUpdatedRels = new ArrayList<>();
+        List<ContractPlaceNumberRel> needUpdateRels = new ArrayList<>();
+        
+        // 遍历所有虚拟车位
+        for(VirtualParkingSlot slot : list) {
+            String expectedCarType = StrUtil.equals(slot.getSlotType(), "large") ? "1" : "2";
+            ContractPlaceNumberRel existingRel = existingRelMap.get(slot.getVirtualSlotNumber());
+            
+            // 处理几种情况:
+            // 1. 不存在该车位的记录,需要创建
+            // 2. 存在记录但车位类型变化且车位是空闲的,需要更新
+            // 3. 存在记录且车位类型一致或车位已占用,不处理
+            
+            if(existingRel == null) {
+                // 车位没有对应记录,创建新记录
+                ContractPlaceNumberRel newRel = new ContractPlaceNumberRel();
+                newRel.setVirtualSlotNumber(slot.getVirtualSlotNumber());
+                newRel.setStartTime(startTime);
+                newRel.setEndTime(endTime);
+                newRel.setContractId(contractId);
+                newRel.setCarType(StrUtil.equals(slot.getSlotType(), "large") ? "1" : "2");
+                newOrUpdatedRels.add(newRel);
+            } else if(StrUtil.equals(slot.getStatus(), "0") && !StrUtil.equals(existingRel.getCarType(), expectedCarType)) {
+                // 车位空闲且类型不匹配,需要更新类型
+                log.info("车位类型变更:车位号 {} 从 {} 变为 {}", 
+                    slot.getVirtualSlotNumber(), 
+                    existingRel.getCarType(), 
+                    expectedCarType);
+                
+                existingRel.setCarType(expectedCarType);
+                needUpdateRels.add(existingRel);
             }
-        });
-        this.saveBatch(currentDayContractPlaceNumberRels);
-        return currentDayContractPlaceNumberRels;
+            // 车位已占用或类型一致,不做处理
+        }
+        
+        // 保存新记录和更新已有记录
+        if(CollectionUtil.isNotEmpty(newOrUpdatedRels)) {
+            this.saveBatch(newOrUpdatedRels);
+        }
+        
+        if(CollectionUtil.isNotEmpty(needUpdateRels)) {
+            this.updateBatchById(needUpdateRels);
+        }
+        
+        // 合并返回所有更新和创建的记录
+        newOrUpdatedRels.addAll(needUpdateRels);
+        return newOrUpdatedRels.isEmpty() ? null : newOrUpdatedRels;
     }
 
 }

+ 54 - 29
src/main/java/com/qmrb/system/service/impl/VirtualParkingSlotServiceImpl.java

@@ -1,38 +1,38 @@
 package com.qmrb.system.service.impl;
 
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.*;
-import java.util.stream.Collectors;
-
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
-import com.alibaba.fastjson.JSON;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmrb.system.common.result.Result;
+import com.qmrb.system.converter.VirtualParkingSlotConverter;
 import com.qmrb.system.framework.security.util.SecurityUtils;
+import com.qmrb.system.mapper.VirtualParkingSlotMapper;
 import com.qmrb.system.pojo.entity.Contract;
 import com.qmrb.system.pojo.entity.ContractPlaceNumberRel;
-import com.qmrb.system.service.IContractPlaceNumberRelHisService;
-import com.qmrb.system.utils.DateUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.qmrb.system.converter.VirtualParkingSlotConverter;
 import com.qmrb.system.pojo.entity.VirtualParkingSlot;
 import com.qmrb.system.pojo.form.VirtualParkingSlotForm;
-import com.qmrb.system.pojo.vo.VirtualParkingSlotVO;
 import com.qmrb.system.pojo.query.VirtualParkingSlotQuery;
-import com.qmrb.system.mapper.VirtualParkingSlotMapper;
+import com.qmrb.system.pojo.vo.VirtualParkingSlotVO;
+import com.qmrb.system.service.IContractPlaceNumberRelHisService;
 import com.qmrb.system.service.IVirtualParkingSlotService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmrb.system.utils.DateUtils;
+import jakarta.validation.Valid;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.core.lang.Assert;
-import jakarta.validation.Valid;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -101,6 +101,30 @@ public class VirtualParkingSlotServiceImpl extends ServiceImpl<VirtualParkingSlo
 				.ne(VirtualParkingSlot::getStatus,"2").orderByAsc(VirtualParkingSlot::getId));
 		if(CollectionUtil.isNotEmpty(list)){
 			List<VirtualParkingSlot> allVirtuals = this.list(new LambdaQueryWrapper<VirtualParkingSlot>().eq(VirtualParkingSlot::getContractId, contract.getId()).orderByAsc(VirtualParkingSlot::getId));
+			
+			// 检查已占用的车位数量
+			List<VirtualParkingSlot> occupiedSlots = list.stream()
+				.filter(slot -> StrUtil.equals(slot.getStatus(), "1"))
+				.collect(Collectors.toList());
+				
+			// 检查大型和小型车位的已占用数量
+			long occupiedLargeCount = occupiedSlots.stream()
+				.filter(slot -> StrUtil.equals(slot.getSlotType(), "large"))
+				.count();
+			long occupiedSmallCount = occupiedSlots.stream()
+				.filter(slot -> StrUtil.equals(slot.getSlotType(), "small"))
+				.count();
+				
+			int largeSlotNum = contract.getMaxParkingLotNum() - contract.getSmallParkingLotNum();
+			
+			// 检查新配置的车位数是否能满足已占用的车位
+			if (occupiedLargeCount > largeSlotNum || occupiedSmallCount > contract.getSmallParkingLotNum()) {
+				log.warn("合同车位修改失败: 大型车已占用{}个,配置{}个; 小型车已占用{}个,配置{}个", 
+					occupiedLargeCount, largeSlotNum, occupiedSmallCount, contract.getSmallParkingLotNum());
+				// 如果当前占用的车位超出了新配置的车位数,则不允许修改
+				return;
+			}
+			
 			// 若包租协议得最大车位数小于虚拟车位数,则停用超出部分得虚拟车位
 			if(contract.getMaxParkingLotNum() < list.size()){
 				List<VirtualParkingSlot> outVirtuals = list.subList(contract.getMaxParkingLotNum(), list.size());
@@ -167,11 +191,13 @@ public class VirtualParkingSlotServiceImpl extends ServiceImpl<VirtualParkingSlo
 			list = new ArrayList<>();
 			// Integer index = 1;
 			Long index = lastOne != null ? lastOne.getId() + 1 : 1L; 
-			for(int i = contract.getMaxParkingLotNum(); i > 0;i--){
+			// 计算大型车位数量
+			int largeSlotNum = contract.getMaxParkingLotNum() - contract.getSmallParkingLotNum();
+			for(int i = 0; i < contract.getMaxParkingLotNum(); i++){
 				VirtualParkingSlot virtualParkingSlot = new VirtualParkingSlot();
 				virtualParkingSlot.setContractId(contract.getId());
 				virtualParkingSlot.setVirtualSlotNumber("A"+index);
-				if(i >= contract.getSmallParkingLotNum()){
+				if(i < largeSlotNum){
 					virtualParkingSlot.setSlotType("large");
 				}else{
 					virtualParkingSlot.setSlotType("small");
@@ -187,15 +213,14 @@ public class VirtualParkingSlotServiceImpl extends ServiceImpl<VirtualParkingSlo
 	public void updateSlotType(List<VirtualParkingSlot> list,Contract contract){
 		for (int i = 0; i < list.size(); i++) {
 			// 更新非停用得
-			if(!StrUtil.equals(list.get(0).getStatus(),"2")){
-				if(i < contract.getSmallParkingLotNum()){
-					list.get(i).setSlotType("small");
-				}else{
+			if(!StrUtil.equals(list.get(i).getStatus(),"2")){
+				if(i < contract.getMaxParkingLotNum() - contract.getSmallParkingLotNum()){
 					list.get(i).setSlotType("large");
+				}else{
+					list.get(i).setSlotType("small");
 				}
 			}
 		}
-		
 	}
 	/**更新
 	 * */
@@ -247,7 +272,7 @@ public class VirtualParkingSlotServiceImpl extends ServiceImpl<VirtualParkingSlo
 			Assert.isTrue(CollectionUtil.isNotEmpty(freeVirtualParkingSlots),"无可用车位");
 			virtualParkingSlot = freeVirtualParkingSlots.get(0);
 			virtualParkingSlot.setStatus("1");//占用
-			virtualParkingSlot.setSlotType(StrUtil.equals("1",contractPlaceNumberRel.getCarType())? "small" : "large");
+			virtualParkingSlot.setSlotType(StrUtil.equals("1",contractPlaceNumberRel.getCarType())? "large" : "small");
 			virtualParkingSlot.setCurrentPlateNumber(contractPlaceNumberRel.getPlateNumber());
 			virtualParkingSlot.setLastOccupiedTime(contractPlaceNumberRel.getStartTime());
 			virtualParkingSlot.setLastReleasedTime(contractPlaceNumberRel.getEndTime());
@@ -352,7 +377,7 @@ public class VirtualParkingSlotServiceImpl extends ServiceImpl<VirtualParkingSlo
 		log.info("定时释放虚拟车位数:" + releasedList.size() +  LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
 		releasedList = releasedList.stream().map(iter->{
 			iter.setCurrentPlateNumber(null);
-			iter.setSlotType("small");
+			// 不改变车位类型,保持原有的大小类型
 			iter.setStatus("0");
 			return iter;
 		}).collect(Collectors.toList());