vehicle.go 7.8 KB

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