package parking import ( "errors" "wails-app/internal/dao" "wails-app/internal/global" "wails-app/internal/model/parking/request" "gorm.io/gorm" ) type parkingLotService struct{} func NewParkingLotService() *parkingLotService { return &parkingLotService{} } // CreateParkingLot 创建停车区域 func (s *parkingLotService) CreateParkingLot(req request.ParkingLotCreate) error { // 检查区域编码是否已存在 var existingLot dao.ParkingLot result := global.GVA_DB.Where("lot_code = ?", req.LotCode).First(&existingLot) if result.RowsAffected > 0 { return errors.New("区域编码已存在") } return global.GVA_DB.Transaction(func(tx *gorm.DB) error { lot := dao.ParkingLot{ LotCode: req.LotCode, LotName: req.LotName, Capacity: req.Capacity, Occupied: 0, Available: req.Capacity, Description: req.Description, } if err := tx.Create(&lot).Error; err != nil { return err } // 显式更新布尔值,确保 false 不会被 GORM 的数据库默认值覆盖。 return tx.Model(&lot).Updates(map[string]interface{}{ "allow_temporary_when_full": req.AllowTemporaryWhenFull, "allow_monthly_when_full": req.AllowMonthlyWhenFull, "allow_vip_when_full": req.AllowVIPWhenFull, }).Error }) } // UpdateParkingLot 更新停车区域 func (s *parkingLotService) UpdateParkingLot(req request.ParkingLotUpdate) error { return global.GVA_DB.Transaction(func(tx *gorm.DB) error { var lot dao.ParkingLot if err := tx.First(&lot, req.ID).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return errors.New("停车区域不存在") } return err } var duplicateCount int64 if err := tx.Model(&dao.ParkingLot{}). Where("lot_code = ? AND id != ?", req.LotCode, req.ID). Count(&duplicateCount).Error; err != nil { return err } if duplicateCount > 0 { return errors.New("区域编码已被其他区域使用") } var occupied int64 if err := tx.Model(&dao.VehicleRecord{}). Where("parking_lot_id = ? AND exit_time IS NULL", req.ID). Count(&occupied).Error; err != nil { return err } if int64(req.Capacity) < occupied { return errors.New("停车场容量不能小于当前在场车辆数") } return tx.Model(&lot).Updates(map[string]interface{}{ "lot_code": req.LotCode, "lot_name": req.LotName, "capacity": req.Capacity, "occupied": occupied, "available": int64(req.Capacity) - occupied, "allow_temporary_when_full": req.AllowTemporaryWhenFull, "allow_monthly_when_full": req.AllowMonthlyWhenFull, "allow_vip_when_full": req.AllowVIPWhenFull, "description": req.Description, }).Error }) } // GetParkingLotByID 根据ID获取停车区域 func (s *parkingLotService) GetParkingLotByID(id uint) (dao.ParkingLot, error) { var lot dao.ParkingLot result := global.GVA_DB.First(&lot, id) if result.RowsAffected == 0 { return dao.ParkingLot{}, errors.New("停车区域不存在") } return lot, nil } // GetParkingLotByCode 根据编码获取停车区域 func (s *parkingLotService) GetParkingLotByCode(code string) (dao.ParkingLot, error) { var lot dao.ParkingLot result := global.GVA_DB.Where("lot_code = ?", code).First(&lot) if result.RowsAffected == 0 { return dao.ParkingLot{}, errors.New("停车区域不存在") } return lot, nil } func (s *parkingLotService) QueryAllParkingLots() ([]dao.ParkingLot, error) { var parkingLots []dao.ParkingLot err := global.GVA_DB.Find(&parkingLots).Error if err != nil { return parkingLots, err } return parkingLots, nil } // ListParkingLots 获取停车区域列表 func (s *parkingLotService) ListParkingLots(req request.ParkingLotQuery) (int64, []dao.ParkingLot, error) { var lots []dao.ParkingLot var total int64 query := global.GVA_DB.Model(&dao.ParkingLot{}) if req.LotCode != "" { query = query.Where("lot_code LIKE ?", "%"+req.LotCode+"%") } if req.LotId > 0 { query = query.Where("id = ?", req.LotId) } if req.LotName != "" { query = query.Where("lot_name LIKE ?", "%"+req.LotName+"%") } // 计算总数 query.Count(&total) // 分页查询 offset := (req.Page - 1) * req.PageSize result := query.Offset(offset).Limit(req.PageSize).Preload("Booths").Preload("Channels").Preload("UHFReaders").Find(&lots) if result.Error != nil { return 0, nil, result.Error } return total, lots, nil } // DeleteParkingLot 删除停车区域 func (s *parkingLotService) DeleteParkingLot(id uint) error { return global.GVA_DB.Transaction(func(tx *gorm.DB) error { var lot dao.ParkingLot if err := tx.First(&lot, id).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return errors.New("停车区域不存在") } return err } var activeSessions int64 if err := tx.Model(&dao.VehicleRecord{}). Where("parking_lot_id = ? AND exit_time IS NULL", id). Count(&activeSessions).Error; err != nil { return err } if activeSessions > 0 { return errors.New("停车场仍有在场车辆,不能删除") } return tx.Delete(&lot).Error }) }