Просмотр исходного кода

feat: 拆分VehicleExit——ExitPreview费用预览+ExitConfirm确认出场支付

Co-Authored-By: Claude <noreply@anthropic.com>
lq 1 месяц назад
Родитель
Сommit
47a1745714

+ 7 - 0
internal/model/vehicle/request/vehicle.go

@@ -89,3 +89,10 @@ type VehicleRecordRequest struct {
 	Page        int    `form:"page,default=1" json:"page"`
 	PageSize    int    `form:"page_size,default=10" json:"page_size"`
 }
+
+type ExitConfirmRequest struct {
+	PlateNumber   string  `json:"plate_number"`
+	RFIDTag       string  `json:"rfid_tag"`
+	PaymentMethod string  `json:"payment_method"`
+	PaidAmount    float64 `json:"paid_amount"`
+}

+ 19 - 0
internal/model/vehicle/response/vehicle.go

@@ -28,3 +28,22 @@ type FeeConfigList struct {
 	Total int64           `json:"total"`
 	List  []dao.FeeConfig `json:"list"`
 }
+
+type ExitPreviewResponse struct {
+	PlateNumber string  `json:"plate_number"`
+	EntryTime   int64   `json:"entry_time"`
+	StayTime    int64   `json:"stay_time"`
+	Fee         float64 `json:"fee"`
+	VehicleType string  `json:"vehicle_type"`
+	IsTemp      bool    `json:"is_temp"`
+}
+
+type ExitConfirmResponse struct {
+	PlateNumber   string  `json:"plate_number"`
+	EntryTime     int64   `json:"entry_time"`
+	ExitTime      int64   `json:"exit_time"`
+	StayTime      int64   `json:"stay_time"`
+	Fee           float64 `json:"fee"`
+	ChangeAmount  float64 `json:"change_amount"`
+	PaymentMethod string  `json:"payment_method"`
+}

+ 94 - 0
internal/service/vehicle/vehicle.go

@@ -7,6 +7,8 @@ import (
 	"wails-app/internal/dao"
 	"wails-app/internal/global"
 	"wails-app/internal/model/vehicle/request"
+	vehicleResponse "wails-app/internal/model/vehicle/response"
+	paymentService "wails-app/internal/modules/payment/service"
 )
 
 type VehicleService struct{}
@@ -275,6 +277,98 @@ func (s *VehicleService) VehicleExit(req request.VehicleExit) (request.VehicleEx
 	return response, nil
 }
 
+// ExitPreview 费用预览(不修改数据库,仅查询+计算费用)
+func (s *VehicleService) ExitPreview(req request.VehicleEntry) (vehicleResponse.ExitPreviewResponse, error) {
+	var record dao.VehicleRecord
+	err := global.GVA_DB.Where("(plate_number = ? OR rfid_tag = ?) AND exit_time IS NULL",
+		req.PlateNumber, req.RFIDTag).First(&record).Error
+	if err != nil {
+		return vehicleResponse.ExitPreviewResponse{}, errors.New("车辆未入场或已出场")
+	}
+
+	vehicle, err := s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
+	if err != nil {
+		return vehicleResponse.ExitPreviewResponse{}, err
+	}
+
+	now := time.Now()
+	stayTime := int64(now.Sub(record.EntryTime).Minutes())
+	if stayTime < 0 {
+		stayTime = 0
+	}
+	fee := s.calculateFee(&vehicle, stayTime)
+
+	typeName := ""
+	isTemp := false
+	if vehicle.VehicleType != nil {
+		typeName = vehicle.VehicleType.Name
+		isTemp = vehicle.VehicleType.IsSystem
+	}
+
+	return vehicleResponse.ExitPreviewResponse{
+		PlateNumber: vehicle.PlateNumber,
+		EntryTime:   record.EntryTime.Unix(),
+		StayTime:    stayTime,
+		Fee:         fee,
+		VehicleType: typeName,
+		IsTemp:      isTemp,
+	}, nil
+}
+
+// ExitConfirm 确认出场 + 支付(更新车辆记录 + 创建支付记录)
+func (s *VehicleService) ExitConfirm(req request.ExitConfirmRequest, operatorID uint) (vehicleResponse.ExitConfirmResponse, error) {
+	var record dao.VehicleRecord
+	err := global.GVA_DB.Where("(plate_number = ? OR rfid_tag = ?) AND exit_time IS NULL",
+		req.PlateNumber, req.RFIDTag).First(&record).Error
+	if err != nil {
+		return vehicleResponse.ExitConfirmResponse{}, errors.New("车辆未入场或已出场")
+	}
+
+	vehicle, err := s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
+	if err != nil {
+		return vehicleResponse.ExitConfirmResponse{}, err
+	}
+
+	exitTime := time.Now()
+	stayTime := int64(exitTime.Sub(record.EntryTime).Minutes())
+	if stayTime < 0 {
+		stayTime = 0
+	}
+	fee := s.calculateFee(&vehicle, stayTime)
+
+	record.ExitTime = &exitTime
+	record.StayTime = stayTime
+	record.Fee = fee
+	record.PaymentMethod = req.PaymentMethod
+	global.GVA_DB.Save(&record)
+
+	vehicle.LastExitTime = &exitTime
+	vehicle.TotalStayTime += stayTime
+	vehicle.TotalFee += fee
+	global.GVA_DB.Save(&vehicle)
+
+	paymentSvc := paymentService.NewPaymentService()
+	pr, err := paymentSvc.ProcessPayment(record.ID, req.PaymentMethod, fee, req.PaidAmount, operatorID)
+	if err != nil {
+		return vehicleResponse.ExitConfirmResponse{}, err
+	}
+
+	changeAmount := 0.0
+	if pr != nil {
+		changeAmount = pr.ChangeAmount
+	}
+
+	return vehicleResponse.ExitConfirmResponse{
+		PlateNumber:   vehicle.PlateNumber,
+		EntryTime:     record.EntryTime.Unix(),
+		ExitTime:      exitTime.Unix(),
+		StayTime:      stayTime,
+		Fee:           fee,
+		ChangeAmount:  changeAmount,
+		PaymentMethod: req.PaymentMethod,
+	}, nil
+}
+
 // calculateFee 计算停车费用
 func (s *VehicleService) calculateFee(vehicle *dao.Vehicle, stayTime int64) float64 {
 	// 1. 根据车辆类型ID获取收费配置(唯一)