service.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package service
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. "wails-app/internal/dao"
  7. "wails-app/internal/global"
  8. "wails-app/internal/modules/monthly/repository"
  9. paymentSvc "wails-app/internal/modules/payment/service"
  10. )
  11. type MonthlyCardService struct {
  12. repo *repository.MonthlyCardRepository
  13. }
  14. func NewMonthlyCardService() *MonthlyCardService {
  15. return &MonthlyCardService{repo: &repository.MonthlyCardRepository{}}
  16. }
  17. func cardDays(cardType string) int {
  18. switch cardType {
  19. case "month":
  20. return 30
  21. case "quarter":
  22. return 90
  23. case "year":
  24. return 365
  25. default:
  26. return 30
  27. }
  28. }
  29. // Create 办理月卡:创建 monthly_card + shortlist 白名单 + payment_record
  30. func (s *MonthlyCardService) Create(vehicleID uint, cardType string, fee float64, operatorID uint, remark string) (*dao.MonthlyCard, error) {
  31. existing, _ := s.repo.GetByVehicleID(vehicleID)
  32. if existing != nil {
  33. return nil, errors.New("该车辆已有有效月卡,请先退卡或等过期后续费")
  34. }
  35. var vehicle dao.Vehicle
  36. if err := global.GVA_DB.First(&vehicle, vehicleID).Error; err != nil {
  37. return nil, errors.New("车辆不存在")
  38. }
  39. now := time.Now()
  40. endDate := now.AddDate(0, 0, cardDays(cardType))
  41. card := &dao.MonthlyCard{
  42. VehicleID: vehicleID, CardType: cardType,
  43. StartDate: now, EndDate: endDate,
  44. Fee: fee, PaymentStatus: "paid", OperatorID: operatorID, Remark: remark,
  45. }
  46. if err := s.repo.Create(card); err != nil {
  47. return nil, fmt.Errorf("创建月卡失败: %w", err)
  48. }
  49. // 写入白名单
  50. shortlist := dao.Shortlist{
  51. VehicleId: int(vehicleID),
  52. ListType: "白名单",
  53. ExpirationTime: &endDate,
  54. }
  55. global.GVA_DB.Create(&shortlist)
  56. // 创建 payment_record
  57. payRecord := dao.PaymentRecord{
  58. RecordID: 0, PaymentMethod: paymentSvc.PaymentCash,
  59. Amount: fee, PaidAmount: fee, ChangeAmount: 0,
  60. OperatorID: operatorID, PaidAt: now,
  61. Remark: fmt.Sprintf("包月卡办理(%s)", cardType),
  62. }
  63. global.GVA_DB.Create(&payRecord)
  64. return card, nil
  65. }
  66. // Renew 续费:延长到期日 + 更新 shortlist
  67. func (s *MonthlyCardService) Renew(cardID uint, cardType string, fee float64, operatorID uint) error {
  68. var card dao.MonthlyCard
  69. if err := global.GVA_DB.First(&card, cardID).Error; err != nil {
  70. return errors.New("月卡记录不存在")
  71. }
  72. if card.PaymentStatus != "paid" {
  73. return errors.New("月卡已退卡,无法续费")
  74. }
  75. newEnd := card.EndDate.AddDate(0, 0, cardDays(cardType))
  76. card.EndDate = newEnd
  77. card.Fee += fee
  78. global.GVA_DB.Save(&card)
  79. // 更新 shortlist 到期日
  80. global.GVA_DB.Model(&dao.Shortlist{}).Where("vehicle_id = ? AND list_type = ?", card.VehicleID, "白名单").
  81. Update("expiration_time", newEnd)
  82. // 创建 payment_record
  83. now := time.Now()
  84. payRecord := dao.PaymentRecord{
  85. RecordID: 0, PaymentMethod: paymentSvc.PaymentCash,
  86. Amount: fee, PaidAmount: fee, ChangeAmount: 0,
  87. OperatorID: operatorID, PaidAt: now,
  88. Remark: fmt.Sprintf("包月卡续费(%s)", cardType),
  89. }
  90. global.GVA_DB.Create(&payRecord)
  91. return nil
  92. }
  93. // Refund 退卡:标记 refunded + 移除 shortlist
  94. func (s *MonthlyCardService) Refund(cardID uint) error {
  95. var card dao.MonthlyCard
  96. if err := global.GVA_DB.First(&card, cardID).Error; err != nil {
  97. return errors.New("月卡记录不存在")
  98. }
  99. card.PaymentStatus = "refunded"
  100. global.GVA_DB.Save(&card)
  101. // 移除白名单
  102. global.GVA_DB.Where("vehicle_id = ? AND list_type = ?", card.VehicleID, "白名单").Unscoped().Delete(&dao.Shortlist{})
  103. return nil
  104. }
  105. func (s *MonthlyCardService) List(q repository.MonthlyCardQuery) ([]repository.MonthlyCardResult, int64, error) {
  106. return s.repo.List(q)
  107. }