|
@@ -0,0 +1,128 @@
|
|
|
|
|
+package service
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "errors"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "time"
|
|
|
|
|
+ "wails-app/internal/dao"
|
|
|
|
|
+ "wails-app/internal/global"
|
|
|
|
|
+ "wails-app/internal/modules/monthly/repository"
|
|
|
|
|
+ paymentSvc "wails-app/internal/modules/payment/service"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+type MonthlyCardService struct {
|
|
|
|
|
+ repo *repository.MonthlyCardRepository
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func NewMonthlyCardService() *MonthlyCardService {
|
|
|
|
|
+ return &MonthlyCardService{repo: &repository.MonthlyCardRepository{}}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func cardDays(cardType string) int {
|
|
|
|
|
+ switch cardType {
|
|
|
|
|
+ case "month":
|
|
|
|
|
+ return 30
|
|
|
|
|
+ case "quarter":
|
|
|
|
|
+ return 90
|
|
|
|
|
+ case "year":
|
|
|
|
|
+ return 365
|
|
|
|
|
+ default:
|
|
|
|
|
+ return 30
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Create 办理月卡:创建 monthly_card + shortlist 白名单 + payment_record
|
|
|
|
|
+func (s *MonthlyCardService) Create(vehicleID uint, cardType string, fee float64, operatorID uint, remark string) (*dao.MonthlyCard, error) {
|
|
|
|
|
+ existing, _ := s.repo.GetByVehicleID(vehicleID)
|
|
|
|
|
+ if existing != nil {
|
|
|
|
|
+ return nil, errors.New("该车辆已有有效月卡,请先退卡或等过期后续费")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var vehicle dao.Vehicle
|
|
|
|
|
+ if err := global.GVA_DB.First(&vehicle, vehicleID).Error; err != nil {
|
|
|
|
|
+ return nil, errors.New("车辆不存在")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ now := time.Now()
|
|
|
|
|
+ endDate := now.AddDate(0, 0, cardDays(cardType))
|
|
|
|
|
+
|
|
|
|
|
+ card := &dao.MonthlyCard{
|
|
|
|
|
+ VehicleID: vehicleID, CardType: cardType,
|
|
|
|
|
+ StartDate: now, EndDate: endDate,
|
|
|
|
|
+ Fee: fee, PaymentStatus: "paid", OperatorID: operatorID, Remark: remark,
|
|
|
|
|
+ }
|
|
|
|
|
+ if err := s.repo.Create(card); err != nil {
|
|
|
|
|
+ return nil, fmt.Errorf("创建月卡失败: %w", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 写入白名单
|
|
|
|
|
+ shortlist := dao.Shortlist{
|
|
|
|
|
+ VehicleId: int(vehicleID),
|
|
|
|
|
+ ListType: "白名单",
|
|
|
|
|
+ ExpirationTime: &endDate,
|
|
|
|
|
+ }
|
|
|
|
|
+ global.GVA_DB.Create(&shortlist)
|
|
|
|
|
+
|
|
|
|
|
+ // 创建 payment_record
|
|
|
|
|
+ payRecord := dao.PaymentRecord{
|
|
|
|
|
+ RecordID: 0, PaymentMethod: paymentSvc.PaymentCash,
|
|
|
|
|
+ Amount: fee, PaidAmount: fee, ChangeAmount: 0,
|
|
|
|
|
+ OperatorID: operatorID, PaidAt: now,
|
|
|
|
|
+ Remark: fmt.Sprintf("包月卡办理(%s)", cardType),
|
|
|
|
|
+ }
|
|
|
|
|
+ global.GVA_DB.Create(&payRecord)
|
|
|
|
|
+
|
|
|
|
|
+ return card, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Renew 续费:延长到期日 + 更新 shortlist
|
|
|
|
|
+func (s *MonthlyCardService) Renew(cardID uint, cardType string, fee float64, operatorID uint) error {
|
|
|
|
|
+ var card dao.MonthlyCard
|
|
|
|
|
+ if err := global.GVA_DB.First(&card, cardID).Error; err != nil {
|
|
|
|
|
+ return errors.New("月卡记录不存在")
|
|
|
|
|
+ }
|
|
|
|
|
+ if card.PaymentStatus != "paid" {
|
|
|
|
|
+ return errors.New("月卡已退卡,无法续费")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ newEnd := card.EndDate.AddDate(0, 0, cardDays(cardType))
|
|
|
|
|
+ card.EndDate = newEnd
|
|
|
|
|
+ card.Fee += fee
|
|
|
|
|
+ global.GVA_DB.Save(&card)
|
|
|
|
|
+
|
|
|
|
|
+ // 更新 shortlist 到期日
|
|
|
|
|
+ global.GVA_DB.Model(&dao.Shortlist{}).Where("vehicle_id = ? AND list_type = ?", card.VehicleID, "白名单").
|
|
|
|
|
+ Update("expiration_time", newEnd)
|
|
|
|
|
+
|
|
|
|
|
+ // 创建 payment_record
|
|
|
|
|
+ now := time.Now()
|
|
|
|
|
+ payRecord := dao.PaymentRecord{
|
|
|
|
|
+ RecordID: 0, PaymentMethod: paymentSvc.PaymentCash,
|
|
|
|
|
+ Amount: fee, PaidAmount: fee, ChangeAmount: 0,
|
|
|
|
|
+ OperatorID: operatorID, PaidAt: now,
|
|
|
|
|
+ Remark: fmt.Sprintf("包月卡续费(%s)", cardType),
|
|
|
|
|
+ }
|
|
|
|
|
+ global.GVA_DB.Create(&payRecord)
|
|
|
|
|
+
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Refund 退卡:标记 refunded + 移除 shortlist
|
|
|
|
|
+func (s *MonthlyCardService) Refund(cardID uint) error {
|
|
|
|
|
+ var card dao.MonthlyCard
|
|
|
|
|
+ if err := global.GVA_DB.First(&card, cardID).Error; err != nil {
|
|
|
|
|
+ return errors.New("月卡记录不存在")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ card.PaymentStatus = "refunded"
|
|
|
|
|
+ global.GVA_DB.Save(&card)
|
|
|
|
|
+
|
|
|
|
|
+ // 移除白名单
|
|
|
|
|
+ global.GVA_DB.Where("vehicle_id = ? AND list_type = ?", card.VehicleID, "白名单").Unscoped().Delete(&dao.Shortlist{})
|
|
|
|
|
+
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (s *MonthlyCardService) List(q repository.MonthlyCardQuery) ([]repository.MonthlyCardResult, int64, error) {
|
|
|
|
|
+ return s.repo.List(q)
|
|
|
|
|
+}
|