| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- package vehicle
- import (
- "errors"
- "server/dao"
- "server/global"
- "server/model/vehicle/request"
- "time"
- )
- type vehicleService struct{}
- func NewVehicleService() *vehicleService {
- return &vehicleService{}
- }
- // CreateVehicle 创建车辆信息
- func (s *vehicleService) CreateVehicle(req request.VehicleCreate) error {
- // 检查车牌号是否已存在
- var existingVehicle dao.Vehicle
- result := global.GVA_DB.Where("plate_number = ?", req.PlateNumber).First(&existingVehicle)
- if result.RowsAffected > 0 {
- return errors.New("车牌号已存在")
- }
- // 处理临时车辆的情况
- var ownerId *uint
- if req.OwnerId > 0 {
- ownerId = &req.OwnerId
- }
- vehicle := dao.Vehicle{
- PlateNumber: req.PlateNumber,
- VehicleType: req.VehicleType,
- VehicleBrand: req.VehicleBrand,
- VehicleColor: req.VehicleColor,
- OwnerId: ownerId,
- }
- return global.GVA_DB.Create(&vehicle).Error
- }
- // UpdateVehicle 更新车辆信息
- func (s *vehicleService) UpdateVehicle(req request.VehicleUpdate) error {
- var vehicle dao.Vehicle
- result := global.GVA_DB.First(&vehicle, req.ID)
- if result.RowsAffected == 0 {
- return errors.New("车辆不存在")
- }
- // 检查车牌号是否被其他车辆使用
- var existingVehicle dao.Vehicle
- result = global.GVA_DB.Where("plate_number = ? AND id != ?", req.PlateNumber, req.ID).First(&existingVehicle)
- if result.RowsAffected > 0 {
- return errors.New("车牌号已被其他车辆使用")
- }
- // 处理临时车辆的情况
- var ownerId *uint
- if req.OwnerId > 0 {
- ownerId = &req.OwnerId
- } else {
- ownerId = nil
- }
- vehicle.PlateNumber = req.PlateNumber
- vehicle.VehicleType = req.VehicleType
- vehicle.VehicleBrand = req.VehicleBrand
- vehicle.VehicleColor = req.VehicleColor
- vehicle.OwnerId = ownerId
- return global.GVA_DB.Save(&vehicle).Error
- }
- // GetVehicleByID 根据ID获取车辆信息
- func (s *vehicleService) GetVehicleByID(id uint) (dao.Vehicle, error) {
- var vehicle dao.Vehicle
- result := global.GVA_DB.First(&vehicle, id)
- if result.RowsAffected == 0 {
- return dao.Vehicle{}, errors.New("车辆不存在")
- }
- return vehicle, nil
- }
- // GetVehicleByPlateNumber 根据车牌号获取车辆信息
- func (s *vehicleService) GetVehicleByPlateNumber(plateNumber, RFIDTag string) (dao.Vehicle, error) {
- var vehicle dao.Vehicle
- result := global.GVA_DB.Where("plate_number = ? or rfid_tag = ?", plateNumber, RFIDTag).First(&vehicle)
- if result.RowsAffected == 0 {
- return dao.Vehicle{}, errors.New("车辆不存在")
- }
- return vehicle, nil
- }
- // ListVehicles 获取车辆列表
- func (s *vehicleService) ListVehicles(req request.VehicleQuery) (int64, []dao.Vehicle, error) {
- var vehicles []dao.Vehicle
- var total int64
- query := global.GVA_DB.Model(&dao.Vehicle{})
- if req.PlateNumber != "" {
- query = query.Where("plate_number LIKE ?", "%"+req.PlateNumber+"%")
- }
- if req.VehicleType != "" {
- query = query.Where("vehicle_type = ?", req.VehicleType)
- }
- if req.OwnerId > 0 {
- query = query.Where("owner_id = ?", req.OwnerId)
- }
- // 计算总数
- query.Count(&total)
- // 分页查询
- offset := (req.Page - 1) * req.PageSize
- result := query.Offset(offset).Limit(req.PageSize).Find(&vehicles)
- if result.Error != nil {
- return 0, nil, result.Error
- }
- return total, vehicles, nil
- }
- // DeleteVehicle 删除车辆
- func (s *vehicleService) DeleteVehicle(id uint) error {
- result := global.GVA_DB.Delete(&dao.Vehicle{}, id)
- if result.RowsAffected == 0 {
- return errors.New("车辆不存在")
- }
- return result.Error
- }
- // VehicleEntry 车辆入场
- func (s *vehicleService) VehicleEntry(req request.VehicleEntry) (request.VehicleEntryResponse, error) {
- // 检查车辆是否存在
- vehicle, err := s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
- if err != nil {
- // 如果车辆不存在,创建新车辆
- createReq := request.VehicleCreate{
- PlateNumber: req.PlateNumber,
- VehicleType: "普通车辆", // 默认类型
- OwnerId: 0, // 默认无车主
- }
- err = s.CreateVehicle(createReq)
- if err != nil {
- return request.VehicleEntryResponse{}, err
- }
- vehicle, _ = s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
- }
- // 检查是否有未出场的记录
- var existingRecord dao.VehicleRecord
- result := global.GVA_DB.Where("plate_number = ? AND exit_time IS NULL", req.PlateNumber).First(&existingRecord)
- if result.RowsAffected > 0 {
- return request.VehicleEntryResponse{}, errors.New("车辆已入场,未出场")
- }
- // 创建入场记录
- entryTime := time.Now()
- record := dao.VehicleRecord{
- PlateNumber: req.PlateNumber,
- EntryTime: entryTime,
- ParkingLotID: req.ParkingLotID,
- ParkingSpaceID: req.ParkingSpaceID,
- EntryImage: req.EntryImage,
- PaymentStatus: "unpaid",
- }
- err = global.GVA_DB.Create(&record).Error
- if err != nil {
- return request.VehicleEntryResponse{}, err
- }
- // 更新车辆最近入场时间
- vehicle.LastEntryTime = entryTime
- global.GVA_DB.Save(&vehicle)
- response := request.VehicleEntryResponse{
- Success: true,
- Message: "车辆入场成功",
- }
- response.Data.PlateNumber = req.PlateNumber
- response.Data.EntryTime = entryTime.Unix()
- response.Data.ParkingLotID = req.ParkingLotID
- response.Data.ParkingSpaceID = req.ParkingSpaceID
- return response, nil
- }
- // VehicleExit 车辆出场
- func (s *vehicleService) VehicleExit(req request.VehicleExit) (request.VehicleExitResponse, error) {
- // 检查是否有未出场的记录
- var record dao.VehicleRecord
- result := global.GVA_DB.Where("plate_number = ? AND exit_time IS NULL", req.PlateNumber).First(&record)
- if result.RowsAffected == 0 {
- return request.VehicleExitResponse{}, errors.New("车辆未入场")
- }
- // 获取车辆信息
- vehicle, err := s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
- if err != nil {
- return request.VehicleExitResponse{}, err
- }
- // 计算费用
- exitTime := time.Now()
- stayTime := int64(exitTime.Sub(record.EntryTime).Minutes()) // 转换为分钟
- fee := s.calculateFee(vehicle, stayTime)
- // 更新出场记录
- record.ExitTime = exitTime
- record.StayTime = stayTime
- record.Fee = fee
- record.ExitImage = req.ExitImage
- record.PaymentStatus = "paid" // 假设出场时已支付
- err = global.GVA_DB.Save(&record).Error
- if err != nil {
- return request.VehicleExitResponse{}, err
- }
- // 更新车辆信息
- vehicle.LastExitTime = exitTime
- vehicle.TotalStayTime += stayTime
- vehicle.TotalFee += fee
- global.GVA_DB.Save(&vehicle)
- response := request.VehicleExitResponse{
- Success: true,
- Message: "车辆出场成功",
- }
- response.Data.PlateNumber = req.PlateNumber
- response.Data.EntryTime = record.EntryTime.Unix()
- response.Data.ExitTime = exitTime.Unix()
- response.Data.StayTime = stayTime
- response.Data.Fee = fee
- response.Data.PaymentStatus = record.PaymentStatus
- return response, nil
- }
- // calculateFee 计算停车费用
- func (s *vehicleService) calculateFee(vehicle dao.Vehicle, stayTime int64) float64 {
- // 获取收费配置
- var feeConfig dao.FeeConfig
- result := global.GVA_DB.Where("vehicle_type = ?", vehicle.VehicleType).First(&feeConfig)
- if result.RowsAffected == 0 {
- // 使用默认收费标准
- return float64(stayTime) * 0.1 // 默认0.1元/分钟
- }
- // 检查是否是VIP且免费
- isVIP := false
- if vehicle.OwnerId != nil {
- var owner dao.Owner
- ownerResult := global.GVA_DB.First(&owner, *vehicle.OwnerId)
- if ownerResult.RowsAffected > 0 {
- // 检查是否是VIP且未过期
- isVIP = owner.IsVip && time.Now().Before(owner.VipExpireTime)
- }
- }
- if isVIP && feeConfig.IsVIPFree {
- return 0
- }
- // 计算费用
- fee := feeConfig.StartFee
- if stayTime > int64(feeConfig.StartTime) {
- extraTime := stayTime - int64(feeConfig.StartTime)
- extraUnits := extraTime / int64(feeConfig.UnitTime)
- if extraTime%int64(feeConfig.UnitTime) > 0 {
- extraUnits++
- }
- fee += float64(extraUnits) * feeConfig.UnitFee
- }
- // 检查每日最高费用
- if fee > feeConfig.DailyMaxFee {
- fee = feeConfig.DailyMaxFee
- }
- // 应用VIP折扣
- if isVIP {
- fee *= feeConfig.VIPDiscount
- }
- return fee
- }
|