vehicle.go 7.8 KB

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