update.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright 2019 getensh.com. All rights reserved.
  2. // Use of this source code is governed by getensh.com.
  3. package vehicle
  4. import (
  5. "context"
  6. "encoding/json"
  7. "fmt"
  8. "gorm.io/gorm"
  9. "property-garden/errors"
  10. "property-garden/impl/v1/park_space"
  11. dbmodel "property-garden/model"
  12. pb_v1 "property-garden/pb/v1"
  13. "property-garden/utils"
  14. "time"
  15. "git.getensh.com/common/gopkgs/database"
  16. "git.getensh.com/common/gopkgs/logger"
  17. "go.uber.org/zap"
  18. "google.golang.org/grpc/status"
  19. )
  20. func checkVehicleUpdateParam(req *pb_v1.VehicleUpdateRequest) error {
  21. if req.SpaceId == 0 {
  22. //req.BindType = BindTypeNormal
  23. }
  24. switch {
  25. case req.GardenId == 0:
  26. return status.Error(10003, "小区不能为空")
  27. case req.PlateNo == "":
  28. return status.Error(10003, "车牌号不能为空")
  29. case req.Displacement < 1:
  30. //return status.Error(10003, "排量不能为空")
  31. case req.DisplacementUnit == "":
  32. //return status.Error(10003, "排量单位不能为空")
  33. case req.Seat < 1:
  34. //return status.Error(10003, "座位数不能为空")
  35. case req.BindType < 1:
  36. return status.Error(10003, "绑定类型不能为空")
  37. case req.SpaceId > 0 && req.BindType == BindTypeNormal:
  38. return status.Error(10003, "绑定类型错误")
  39. case req.Id == 0:
  40. return status.Error(10003, "id不能为空")
  41. case req.HouseholdUid == 0:
  42. return status.Error(10003, "未绑定住户")
  43. case req.BindType == BindTypeSell && req.SpaceId == 0:
  44. return status.Error(10003, "出售类型请绑定车位")
  45. case req.BindType == BindTypeRent && req.SpaceId == 0:
  46. return status.Error(10003, "出租类型请绑定车位")
  47. }
  48. return nil
  49. }
  50. func checkSpace(req *pb_v1.VehicleUpdateRequest, oldVehicle *dbmodel.TVehicle, targetSpace *dbmodel.TParkSpace, dbname string) error {
  51. // 目标车位已绑定车辆
  52. if targetSpace.VehicleId > 0 && req.SpaceId != oldVehicle.SpaceId {
  53. return status.Error(10003, "车位已绑定车辆")
  54. }
  55. // 目标车位未出售,车辆绑定类型不能为出售
  56. if req.BindType == BindTypeSell && targetSpace.HouseId == 0 {
  57. return status.Error(10003, "出售类型请先在车位配置中绑定房屋")
  58. }
  59. if targetSpace.HouseId > 0 {
  60. // 目标车位已出售,不能绑定出租类型
  61. if req.BindType != BindTypeSell {
  62. return status.Error(10003, "车位已出售,不能出租")
  63. }
  64. householdHasThisHouse, err := checkHouseholdHouse(req.HouseholdUid, targetSpace.HouseId, dbname)
  65. if err != nil {
  66. return err
  67. }
  68. // 目标车位已出售,车辆业主没有入驻车位所绑定的房屋
  69. if !householdHasThisHouse {
  70. return status.Error(10003, "车位已绑定房屋,该用户没有入驻该房屋")
  71. }
  72. }
  73. return nil
  74. }
  75. func VehicleUpdate(ctx context.Context, req *pb_v1.VehicleUpdateRequest) (reply *pb_v1.VehicleUpdateReply, err error) {
  76. reply = &pb_v1.VehicleUpdateReply{}
  77. // 捕获各个task中的异常并返回给调用者
  78. defer func() {
  79. if r := recover(); r != nil {
  80. err = fmt.Errorf("%+v", r)
  81. e := &status.Status{}
  82. if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
  83. logger.Error("err",
  84. zap.String("system_err", err.Error()),
  85. zap.Stack("stacktrace"))
  86. }
  87. }
  88. }()
  89. // 参数检查
  90. err = checkVehicleUpdateParam(req)
  91. if err != nil {
  92. return nil, err
  93. }
  94. dbname := utils.GetGardenDbName(req.GardenId)
  95. // 获取旧数据
  96. old := dbmodel.NewVehicle(dbname)
  97. where := map[string]interface{}{
  98. "id": req.Id,
  99. }
  100. err = old.Find(database.DB(), where)
  101. if err != nil && err != gorm.ErrRecordNotFound {
  102. return nil, errors.DataBaseError
  103. }
  104. if old.ID == 0 {
  105. return nil, errors.ErrRecordNotFound
  106. }
  107. reply.Origin = &pb_v1.VehicleUpdateRequest{
  108. GardenId: req.GardenId,
  109. Id: req.Id,
  110. PlateNo: old.PlateNo,
  111. VehicleType: old.VehicleType,
  112. Vin: old.Vin,
  113. EngineNo: old.EngineNo,
  114. Brand: old.Brand,
  115. Color: old.Color,
  116. SpaceId: old.SpaceId,
  117. HouseholdUid: old.HouseholdUid,
  118. BindType: old.BindType,
  119. Displacement: old.Displacement,
  120. DisplacementUnit: old.DisplacementUnit,
  121. Seat: old.Seat,
  122. }
  123. now := time.Now()
  124. bindType := req.BindType
  125. space := dbmodel.NewParkSpace(dbname)
  126. parkId := old.ParkId
  127. // 绑定新车位,判断合法性
  128. if req.SpaceId > 0 && req.SpaceId != old.SpaceId || req.HouseholdUid != old.HouseholdUid {
  129. where := map[string]interface{}{
  130. "id": req.SpaceId,
  131. }
  132. err = space.Find(database.DB(), where)
  133. if err != nil && err != gorm.ErrRecordNotFound {
  134. return nil, errors.DataBaseError
  135. }
  136. if space.ID == 0 {
  137. return nil, status.Error(10003, "车位不存在")
  138. }
  139. if err = checkSpace(req, old, space, dbname); err != nil {
  140. return nil, err
  141. }
  142. parkId = space.ParkId
  143. }
  144. if req.SpaceId == 0 {
  145. bindType = BindTypeNormal
  146. }
  147. // 更新数据
  148. veh := dbmodel.NewVehicle(dbname)
  149. where = map[string]interface{}{
  150. "id": req.Id,
  151. }
  152. values := map[string]interface{}{
  153. "plate_no": req.PlateNo,
  154. "vehicle_type": req.VehicleType,
  155. "vin": req.Vin,
  156. "engine_no": req.EngineNo,
  157. "brand": req.Brand,
  158. "color": req.Color,
  159. "space_id": req.SpaceId,
  160. "park_id": parkId,
  161. "household_uid": req.HouseholdUid,
  162. "bind_type": bindType,
  163. "displacement": req.Displacement,
  164. "displacement_unit": req.DisplacementUnit,
  165. "seat": req.Seat,
  166. "updated_at": now,
  167. }
  168. db := database.DB().Begin()
  169. defer func() {
  170. if err != nil {
  171. db.Rollback()
  172. }
  173. }()
  174. err = veh.Update(db, where, values)
  175. if err != nil {
  176. return nil, errors.DataBaseError
  177. }
  178. // 更新新车位数据
  179. if space.ParkId > 0 && space.VehicleId != req.Id {
  180. where := map[string]interface{}{
  181. "id": req.SpaceId,
  182. }
  183. values := map[string]interface{}{
  184. "vehicle_id": req.Id,
  185. }
  186. if bindType == BindTypeSell || bindType == BindTypeRent {
  187. values["status"] = bindType
  188. values["bind_status"] = park_space.SpaceBindStatusBind
  189. }
  190. err = space.Update(db, where, values)
  191. if err != nil {
  192. return nil, errors.DataBaseError
  193. }
  194. }
  195. // 更新旧车位数据
  196. if old.SpaceId > 0 && old.SpaceId != req.SpaceId {
  197. oldSpace := dbmodel.NewParkSpace(dbname)
  198. where := map[string]interface{}{
  199. "id": old.SpaceId,
  200. }
  201. err = oldSpace.Find(db, where)
  202. if err != nil && err != gorm.ErrRecordNotFound {
  203. return nil, errors.DataBaseError
  204. }
  205. if oldSpace.ID == 0 {
  206. db.Commit()
  207. return reply, nil
  208. }
  209. values := map[string]interface{}{
  210. "vehicle_id": 0,
  211. }
  212. if oldSpace.HouseId == 0 {
  213. values["status"] = park_space.SpaceStatusEmpty
  214. values["bind_status"] = park_space.SpaceBindStatusEmpty
  215. }
  216. err = oldSpace.Update(db, where, values)
  217. if err != nil {
  218. return nil, errors.DataBaseError
  219. }
  220. }
  221. db.Commit()
  222. return reply, nil
  223. }