vehicle.go 7.9 KB

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