vehicle.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package vehicle
  2. import (
  3. "errors"
  4. "fmt"
  5. "server/dao"
  6. "server/global"
  7. "server/model/vehicle/request"
  8. "time"
  9. )
  10. type VehicleService struct{}
  11. // CreateVehicle 创建车辆信息
  12. func (s *VehicleService) CreateVehicle(req request.VehicleCreate) error {
  13. // 检查车牌号是否已存在
  14. var existingVehicle dao.Vehicle
  15. result := global.GVA_DB.Where("plate_number = ? OR rfid_tag = ?", req.PlateNumber, req.RFIDTag).First(&existingVehicle)
  16. if result.RowsAffected > 0 {
  17. return errors.New("车牌号已存在")
  18. }
  19. // 处理临时车辆的情况
  20. var ownerId *uint
  21. if req.OwnerId > 0 {
  22. ownerId = &req.OwnerId
  23. }
  24. vehicle := dao.Vehicle{
  25. PlateNumber: req.PlateNumber,
  26. VehicleType: req.VehicleType,
  27. VehicleBrand: req.VehicleBrand,
  28. VehicleColor: req.VehicleColor,
  29. OwnerId: ownerId,
  30. }
  31. return global.GVA_DB.Create(&vehicle).Error
  32. }
  33. // UpdateVehicle 更新车辆信息
  34. func (s *VehicleService) UpdateVehicle(req request.VehicleUpdate) error {
  35. var vehicle dao.Vehicle
  36. result := global.GVA_DB.First(&vehicle, req.ID)
  37. if result.RowsAffected == 0 {
  38. return errors.New("车辆不存在")
  39. }
  40. // 检查车牌号是否被其他车辆使用
  41. var existingVehicle dao.Vehicle
  42. result = global.GVA_DB.Where("(plate_number = ? OR rfid_tag = ?) AND id != ?", req.PlateNumber, req.RFIDTag, req.ID).First(&existingVehicle)
  43. fmt.Println("result", result.RowsAffected)
  44. if result.RowsAffected > 0 {
  45. return errors.New("车牌号已被其他车辆使用")
  46. }
  47. // 处理临时车辆的情况
  48. var ownerId *uint
  49. if req.OwnerId > 0 {
  50. ownerId = &req.OwnerId
  51. } else {
  52. ownerId = nil
  53. }
  54. err := global.GVA_DB.Model(&vehicle).Updates(map[string]interface{}{
  55. "plate_number": req.PlateNumber,
  56. "rfid_tag": req.RFIDTag,
  57. "vehicle_type": req.VehicleType,
  58. "vehicle_brand": req.VehicleBrand,
  59. "vehicle_color": req.VehicleColor,
  60. "owner_id": ownerId,
  61. }).Error
  62. return err
  63. }
  64. // GetVehicleByID 根据ID获取车辆信息
  65. func (s *VehicleService) GetVehicleByID(id uint) (dao.Vehicle, error) {
  66. var vehicle dao.Vehicle
  67. result := global.GVA_DB.First(&vehicle, id)
  68. if result.RowsAffected == 0 {
  69. return dao.Vehicle{}, errors.New("车辆不存在")
  70. }
  71. return vehicle, nil
  72. }
  73. // GetVehicleByPlateNumber 根据车牌号获取车辆信息
  74. func (s *VehicleService) GetVehicleByPlateNumber(plateNumber, RFIDTag string) (dao.Vehicle, error) {
  75. var vehicle dao.Vehicle
  76. result := global.GVA_DB.Where("plate_number = ? or rfid_tag = ?", plateNumber, RFIDTag).First(&vehicle)
  77. if result.RowsAffected == 0 {
  78. return dao.Vehicle{}, errors.New("车辆不存在")
  79. }
  80. return vehicle, nil
  81. }
  82. // ListVehicles 获取车辆列表
  83. func (s *VehicleService) ListVehicles(req request.VehicleQuery) (int64, []dao.Vehicle, error) {
  84. var vehicles []dao.Vehicle
  85. var total int64
  86. query := global.GVA_DB.Model(&dao.Vehicle{})
  87. if req.PlateNumber != "" {
  88. query = query.Where("plate_number LIKE ?", "%"+req.PlateNumber+"%")
  89. }
  90. if req.VehicleType != "" {
  91. query = query.Where("vehicle_type = ?", req.VehicleType)
  92. }
  93. if req.OwnerId > 0 {
  94. query = query.Where("owner_id = ?", req.OwnerId)
  95. }
  96. // 计算总数
  97. query.Count(&total)
  98. // 分页查询
  99. offset := (req.Page - 1) * req.PageSize
  100. result := query.Offset(offset).Limit(req.PageSize).Find(&vehicles)
  101. if result.Error != nil {
  102. return 0, nil, result.Error
  103. }
  104. return total, vehicles, nil
  105. }
  106. // DeleteVehicle 删除车辆
  107. func (s *VehicleService) DeleteVehicle(id uint) error {
  108. result := global.GVA_DB.Delete(&dao.Vehicle{}, id)
  109. if result.RowsAffected == 0 {
  110. return errors.New("车辆不存在")
  111. }
  112. return result.Error
  113. }
  114. // VehicleEntry 车辆入场
  115. func (s *VehicleService) VehicleEntry(req request.VehicleEntry) (request.VehicleEntryResponse, error) {
  116. // 检查车辆是否存在
  117. vehicle, err := s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
  118. if err != nil {
  119. // 如果车辆不存在,创建新车辆
  120. createReq := request.VehicleCreate{
  121. PlateNumber: req.PlateNumber,
  122. VehicleType: "临时车", // 默认类型
  123. OwnerId: 0, // 默认无车主
  124. }
  125. err = s.CreateVehicle(createReq)
  126. if err != nil {
  127. return request.VehicleEntryResponse{}, err
  128. }
  129. vehicle, _ = s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
  130. }
  131. // 检查是否有未出场的记录
  132. var existingRecord dao.VehicleRecord
  133. result := global.GVA_DB.Where("(plate_number = ? OR rfid_tag = ?) AND exit_time IS NULL", req.PlateNumber, req.RFIDTag).First(&existingRecord)
  134. if result.RowsAffected > 0 {
  135. return request.VehicleEntryResponse{}, errors.New("车辆已入场,未出场")
  136. }
  137. // 创建入场记录
  138. entryTime := time.Now()
  139. record := dao.VehicleRecord{
  140. PlateNumber: req.PlateNumber,
  141. RFIDTag: req.RFIDTag,
  142. EntryTime: entryTime,
  143. ParkingLotID: req.ParkingLotID,
  144. ParkingSpaceID: req.ParkingSpaceID,
  145. EntryImage: req.EntryImage,
  146. PaymentStatus: "unpaid",
  147. }
  148. err = global.GVA_DB.Create(&record).Error
  149. if err != nil {
  150. return request.VehicleEntryResponse{}, err
  151. }
  152. // 更新车辆最近入场时间
  153. vehicle.LastEntryTime = &entryTime
  154. global.GVA_DB.Save(&vehicle)
  155. response := request.VehicleEntryResponse{
  156. Success: true,
  157. Message: "车辆入场成功",
  158. }
  159. response.Data.PlateNumber = req.PlateNumber
  160. response.Data.EntryTime = entryTime.Unix()
  161. response.Data.ParkingLotID = req.ParkingLotID
  162. response.Data.ParkingSpaceID = req.ParkingSpaceID
  163. return response, nil
  164. }
  165. // VehicleExit 车辆出场
  166. func (s *VehicleService) VehicleExit(req request.VehicleExit) (request.VehicleExitResponse, error) {
  167. // 检查是否有未出场的记录
  168. var record dao.VehicleRecord
  169. result := global.GVA_DB.Where("(plate_number = ? OR rfid_tag = ?) AND exit_time IS NULL", req.PlateNumber, req.RFIDTag).First(&record)
  170. if result.RowsAffected == 0 {
  171. return request.VehicleExitResponse{}, errors.New("车辆未入场")
  172. }
  173. // 获取车辆信息
  174. vehicle, err := s.GetVehicleByPlateNumber(req.PlateNumber, req.RFIDTag)
  175. if err != nil {
  176. return request.VehicleExitResponse{}, err
  177. }
  178. // 计算费用
  179. exitTime := time.Now()
  180. stayTime := int64(exitTime.Sub(record.EntryTime).Minutes()) // 转换为分钟
  181. fee := s.calculateFee(vehicle, stayTime)
  182. // 更新出场记录
  183. record.ExitTime = exitTime
  184. record.StayTime = stayTime
  185. record.Fee = fee
  186. record.ExitImage = req.ExitImage
  187. record.PaymentStatus = "paid" // 假设出场时已支付
  188. err = global.GVA_DB.Save(&record).Error
  189. if err != nil {
  190. return request.VehicleExitResponse{}, err
  191. }
  192. // 更新车辆信息
  193. vehicle.LastExitTime = &exitTime
  194. vehicle.TotalStayTime += stayTime
  195. vehicle.TotalFee += fee
  196. global.GVA_DB.Save(&vehicle)
  197. response := request.VehicleExitResponse{
  198. Success: true,
  199. Message: "车辆出场成功",
  200. }
  201. response.Data.PlateNumber = req.PlateNumber
  202. response.Data.EntryTime = record.EntryTime.Unix()
  203. response.Data.ExitTime = exitTime.Unix()
  204. response.Data.StayTime = stayTime
  205. response.Data.Fee = fee
  206. response.Data.PaymentStatus = record.PaymentStatus
  207. return response, nil
  208. }
  209. // calculateFee 计算停车费用
  210. func (s *VehicleService) calculateFee(vehicle dao.Vehicle, stayTime int64) float64 {
  211. // 获取收费配置
  212. var feeConfig dao.FeeConfig
  213. result := global.GVA_DB.Where("vehicle_type = ?", vehicle.VehicleType).First(&feeConfig)
  214. if result.RowsAffected == 0 {
  215. // 使用默认收费标准
  216. return float64(stayTime) * 0.1 // 默认0.1元/分钟
  217. }
  218. // 检查是否是VIP且免费
  219. isVIP := false
  220. if vehicle.OwnerId != nil {
  221. var owner dao.Owner
  222. ownerResult := global.GVA_DB.First(&owner, *vehicle.OwnerId)
  223. if ownerResult.RowsAffected > 0 {
  224. // 检查是否是VIP且未过期
  225. isVIP = owner.IsVip && time.Now().Before(owner.VipExpireTime)
  226. }
  227. }
  228. if isVIP && feeConfig.IsVIPFree {
  229. return 0
  230. }
  231. // 计算费用
  232. fee := feeConfig.StartFee
  233. if stayTime > int64(feeConfig.StartTime) {
  234. extraTime := stayTime - int64(feeConfig.StartTime)
  235. extraUnits := extraTime / int64(feeConfig.UnitTime)
  236. if extraTime%int64(feeConfig.UnitTime) > 0 {
  237. extraUnits++
  238. }
  239. fee += float64(extraUnits) * feeConfig.UnitFee
  240. }
  241. // 检查每日最高费用
  242. if fee > feeConfig.DailyMaxFee {
  243. fee = feeConfig.DailyMaxFee
  244. }
  245. // 应用VIP折扣
  246. if isVIP {
  247. fee *= feeConfig.VIPDiscount
  248. }
  249. return fee
  250. }