package api import ( "errors" "fmt" "github.com/gin-gonic/gin" "gorm.io/gorm" "io" "log" "qnc-server/config" "qnc-server/db" "qnc-server/model/model" "qnc-server/model/request" "qnc-server/model/response" "qnc-server/service" "qnc-server/utils" "strconv" "sync" ) type Car struct { } var carService service.CarService // 注册路由 func InitCar(group *gin.RouterGroup) { var c Car { carPrivateGroup := group.Group("car") carPrivateGroup.Use(JWTAuth()) carPrivateGroup.POST("insurance", c.Insurance) carPrivateGroup.POST("maintenance", c.Maintenance) carPrivateGroup.GET("get_query", c.GetQueryRecord) carPrivateGroup.POST("person_car_verify", c.PersonCarVerify) carPrivateGroup.POST("under_name", c.UnderName) carPrivateGroup.POST("insurance_info", c.InsuranceInfo) //carPrivateGroup.POST("new_energy_power", c.NewEnergyPower) carPrivateGroup.POST("vin_check_info", c.VinCheckInfo) carPrivateGroup.POST("vehicle_transfer", c.VehicleTransfer) carPrivateGroup.POST("vehicle_valuation", c.VehicleValuation) carPrivateGroup.GET("get_maintenance_history", c.QueryHistoryList) } { carPublicGroup := group.Group("car") carPublicGroup.POST("callback", c.CarCallback) } } // 出险综合查询 func (car *Car) Insurance(c *gin.Context) { var reqBody request.CarInsuranceReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) // 查找是否有 未消费 已付费 的订单 order, err := orderService.QueryConsumedOrder(userid, "chexian") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } var carInsurance model.CarInsurance reqData := map[string]interface{}{ "vin": reqBody.Vin, } plainText, err := carService.CarReqYuShan("CAR074", &reqData) if err != nil { log.Printf("YuShan request at %s error: %s", "CAR074", err.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "出险综合查询", userid, order.ID) response.FailRefund(c) return } _, err = carService.CarInsuranceDataAnalysis(string(plainText)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "出险综合查询", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "出险综合查询", userid, order.ID) } response.FailRefund(c) return } carInsurance.Resp = string(plainText) carInsurance.Vin = reqBody.Vin carInsurance.UserID = userid carInsurance.OrderID = order.ID err = db.DB.Create(&carInsurance).Error if err != nil { log.Printf("汽车出险综合记录失败:%v", err) notifyService.SendNotification("汽车查询数据保存错误,请及时处理", "出险综合查询", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWithData(gin.H{ "record_id": carInsurance.OrderID, }, c) } // 维保记录 func (car *Car) Maintenance(c *gin.Context) { var reqBody request.CarMaintenanceReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) order, err := orderService.QueryConsumedOrder(userid, "weibao") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } notifySN, _ := utils.GenerateRandomString() var carMaintenance model.CarMaintenance reqData := map[string]interface{}{ "vin": reqBody.Vin, "image": reqBody.ImageBase64, "notifyUrl": fmt.Sprintf("%s?notify_sn=%s", config.ConfigData.Car.Callback, notifySN), } plainText, err := carService.CarReqYuShan("CAR058", &reqData) if err != nil { log.Printf("YuShan request at %s error: %s", "CAR058", err.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "维保记录CAR058", userid, order.ID) response.FailRefund(c) return } data, err := carService.CarDataAnalysis(string(plainText)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "维保记录CAR058", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "维保记录CAR058", userid, order.ID) } response.FailRefund(c) return } // 检查 report 中是否存在 "orderId" orderId, exists := data.Retdata["orderId"] if !exists { log.Printf("orderId不存在") response.FailWithMessage("信息输入不匹配,无相关数据", c) return } carMaintenance.Vin = reqBody.Vin carMaintenance.UserID = userid carMaintenance.YuShanOrderID = orderId.(string) carMaintenance.OrderID = order.ID carMaintenance.Status = model.StatusPending carMaintenance.NotifySN = notifySN err = db.DB.Create(&carMaintenance).Error if err != nil { log.Printf("汽车出险综合订单记录失败:%v", err) notifyService.SendNotification("汽车查询订单保存错误,请及时处理", "维保记录", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWait(c) } func (car *Car) GetQueryRecord(c *gin.Context) { var req request.GetQueryRecordReq if err := c.ShouldBindQuery(&req); err != nil { response.FailWithMessage("Failed to read request", c) return } userid := utils.GetUserID(c) var record interface{} var err error if req.IsCase { record, err = carService.GetRecordCaseByFeature(req.Feature) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { log.Printf("无相关示例记录:%v", err) response.FailWithMessage("无相关示例记录", c) return } else { log.Printf("查询示例记录错误:%v", err) response.FailWithMessage(err.Error(), c) return } } } else { record, err = carService.GetRecordByFeature(req.Feature, req.ID, userid) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { log.Printf("无相关查车记录:%v", err) response.FailWithMessage("无相关查车记录", c) return } else { log.Printf("查询查车记录错误:%v", err) response.FailWithMessage(err.Error(), c) return } } } response.OkWithData(record, c) } // 人车核验 CAR012 // 行驶证信息核验 func (car *Car) PersonCarVerify(c *gin.Context) { var reqBody request.CarNameTypeNumberReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) // 查找是否有 未消费 已付费 的订单 order, err := orderService.QueryConsumedOrder(userid, "rencheheyan") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } var carModel model.CarPersonCarVerify reqData := map[string]interface{}{ "name": reqBody.Name, "carType": reqBody.CarType, "carNumber": reqBody.CarNumber, } plainText, err := carService.CarReqYuShan("P_C_B332", &reqData) if err != nil { log.Printf("YuShan request at %s error: %s", "P_C_B332", err.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "人车核验P_C_B332", userid, order.ID) response.FailRefund(c) return } _, err = carService.CarPersonCarVerifyDataAnalysis(string(plainText)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "人车核验P_C_B332", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "人车核验P_C_B332", userid, order.ID) } response.FailRefund(c) return } carModel.Resp = string(plainText) carModel.Name = reqBody.Name carModel.CarNumber = reqBody.CarNumber carModel.CarType = reqBody.CarType carModel.UserID = userid err = db.DB.Create(&carModel).Error if err != nil { log.Printf("人车核验保存错误:%v", err) notifyService.SendNotification("人车核验保存错误,请及时处理", "人车核验P_C_B332", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWithData(gin.H{ "record_id": carModel.OrderID, }, c) } // CAR061名下车辆 func (car *Car) UnderName(c *gin.Context) { var reqBody request.CarCardNoReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) order, err := orderService.QueryConsumedOrder(userid, "mingxiacheliang") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } var carModel model.CarUnderName reqData := map[string]interface{}{ "cardNo": reqBody.CardNo, } plainText, err := carService.CarReqYuShan("CAR061", &reqData) if err != nil { log.Printf("YuShan request at %s error: %s", "CAR061", err.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "CAR061名下车辆", userid, order.ID) response.FailRefund(c) return } _, err = carService.CarInsuranceDataAnalysis(string(plainText)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "CAR061名下车辆", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "CAR061名下车辆", userid, order.ID) } response.FailRefund(c) return } carModel.Resp = string(plainText) carModel.UserID = userid carModel.OrderID = order.ID err = db.DB.Create(&carModel).Error if err != nil { log.Printf("名下车辆查询保存错误:%v", err) notifyService.SendNotification("汽车查询数据保存错误,请及时处理", "CAR061名下车辆", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWithData(gin.H{ "record_id": carModel.OrderID, }, c) } // CAR070车辆上险信息 func (car *Car) InsuranceInfo(c *gin.Context) { var reqBody request.CarVinReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) order, err := orderService.QueryConsumedOrder(userid, "cheliangshangxian") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } var carModel model.CarInsuranceInfo reqData := map[string]interface{}{ "vin": reqBody.Vin, } var wg sync.WaitGroup var plainTextSx, plainTextWx []byte var sxErr, WxErr error wg.Add(2) go func() { defer wg.Done() plainTextSx, sxErr = carService.CarReqYuShan("CAR070", &reqData) }() go func() { defer wg.Done() plainTextWx, WxErr = carService.CarReqYuShan("CAR095", &reqData) }() wg.Wait() if sxErr != nil { log.Printf("YuShan request at %s error: %s", "CAR070", sxErr.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "CAR070", userid, order.ID) response.FailRefund(c) return } if WxErr != nil { log.Printf("YuShan request at %s error: %s", "CAR095", WxErr.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "CAR095", userid, order.ID) response.FailRefund(c) return } _, err = carService.CarInsuranceDataAnalysis(string(plainTextSx)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "CAR070", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "CAR070", userid, order.ID) } response.FailRefund(c) return } _, err = carService.CarInsuranceDataAnalysis(string(plainTextWx)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "CAR095", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "CAR095", userid, order.ID) } response.FailRefund(c) return } carModel.Resp = string(plainTextSx) carModel.FiveResp = string(plainTextWx) carModel.UserID = userid carModel.Vin = reqBody.Vin carModel.OrderID = order.ID err = db.DB.Create(&carModel).Error if err != nil { log.Printf("车辆上险信息保存错误:%v", err) notifyService.SendNotification("汽车查询数据保存错误,请及时处理", "车辆上险信息", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWithData(gin.H{ "record_id": carModel.OrderID, }, c) } // CAR079 车辆VIN码查车辆信息 func (car *Car) VinCheckInfo(c *gin.Context) { var reqBody request.CarVinReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) order, err := orderService.QueryConsumedOrder(userid, "vinchache") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } var carModel model.CarVinCheckInfo reqData := map[string]interface{}{ "vin": reqBody.Vin, } plainText, err := carService.CarReqYuShan("CAR079", &reqData) if err != nil { log.Printf("YuShan request at %s error: %s", "CAR079", err.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "车辆VIN码查车辆信息", userid, order.ID) response.FailRefund(c) return } _, err = carService.CarInsuranceDataAnalysis(string(plainText)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "车辆VIN码查车辆信息", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "车辆VIN码查车辆信息", userid, order.ID) } response.FailRefund(c) return } carModel.Resp = string(plainText) carModel.UserID = userid carModel.Vin = reqBody.Vin carModel.OrderID = order.ID err = db.DB.Create(&carModel).Error if err != nil { log.Printf("VIN查车辆信息保存错误:%v", err) notifyService.SendNotification("汽车查询数据保存错误,请及时处理", "VIN查车辆信息", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWithData(gin.H{ "record_id": carModel.OrderID, }, c) } // 车辆维保记录CAR058回调 func (car *Car) CarCallback(c *gin.Context) { // 读取请求体 encryptedData, err := io.ReadAll(c.Request.Body) if err != nil { log.Printf("CarCallback ReadAll err:%s", err.Error()) return } NotifySN := c.Query("notify_sn") apiKey := config.ConfigData.Car.ApiKey respStr, err := utils.Decrypt(string(encryptedData), []byte(apiKey)) if err != nil { log.Printf("CarCallback DecodeYushan err:%s", err.Error()) } log.Printf("%sCarCallback:%s", NotifySN, respStr) _, err = carService.CarDataAnalysis(respStr) if err != nil { if errors.Is(err, utils.ErrUnmashal) { log.Printf("CarCallback Unmashal err:%s", err.Error()) return } } maintenance, GetMaintenanceErr := carService.GetMaintenanceBySn(NotifySN) if GetMaintenanceErr != nil { log.Printf("GetMaintenanceBySn err:%s", GetMaintenanceErr.Error()) return } maintenance.Resp = respStr if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "维保记录CAR059", maintenance.UserID, maintenance.OrderID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "维保记录CAR059", maintenance.UserID, maintenance.OrderID) } maintenance.Status = model.StatusFailed } else { maintenance.Status = model.StatusSuccess } err = db.DB.Save(&maintenance).Error if err != nil { log.Printf("callback maintenance save err:%s", err.Error()) } response.Ok(c) } // 查询维保历史 func (car *Car) QueryHistoryList(c *gin.Context) { // 从查询参数中获取分页参数 pageSizeStr := c.DefaultQuery("page_size", "10") pageNumStr := c.DefaultQuery("page_num", "1") userId := utils.GetUserID(c) pageSize, err := strconv.Atoi(pageSizeStr) if err != nil { response.FailWithMessage(err.Error(), c) return } pageNum, err := strconv.Atoi(pageNumStr) if err != nil { response.FailWithMessage(err.Error(), c) return } list, err := carService.GetMaintenanceList(pageSize, pageNum, userId) if err != nil { log.Println("GetMaintenanceList:", err) response.FailWithMessage("系统错误,请稍后再试", c) return } response.OkWithData(list, c) } // CAR066 车辆过户次数 func (car *Car) VehicleTransfer(c *gin.Context) { var reqBody request.CarVinReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) order, err := orderService.QueryConsumedOrder(userid, "cheliangguohu") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } var carModel model.CarVehicleTransfer reqData := map[string]interface{}{ "vin": reqBody.Vin, } plainText, err := carService.CarReqYuShan("CAR066", &reqData) if err != nil { log.Printf("YuShan request at %s error: %s", "CAR066", err.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "车辆过户次数", userid, order.ID) response.FailRefund(c) return } _, err = carService.CarInsuranceDataAnalysis(string(plainText)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "车辆过户次数", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "车辆过户次数", userid, order.ID) } response.FailRefund(c) return } carModel.Resp = string(plainText) carModel.UserID = userid carModel.Vin = reqBody.Vin carModel.OrderID = order.ID err = db.DB.Create(&carModel).Error if err != nil { log.Printf("车辆过户次数信息保存错误:%v", err) notifyService.SendNotification("汽车查询数据保存错误,请及时处理", "车辆过户次数", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWithData(gin.H{ "record_id": carModel.OrderID, }, c) } // CAR100 车辆估值 func (car *Car) VehicleValuation(c *gin.Context) { var reqBody request.VehicleValuationReq if err := c.ShouldBindJSON(&reqBody); err != nil { response.FailWithMessage("Failed to read request body", c) return } userid := utils.GetUserID(c) order, err := orderService.QueryConsumedOrder(userid, "cheliangguzhi") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 为空就没有消费资格 response.OkNeedPay(c) return } else { log.Printf("QueryConsumedOrder err:%s", err.Error()) response.FailWithMessage("服务器错误请稍后再试", c) return } } var carModel model.CarVehicleValuation reqData := map[string]interface{}{ "vin": reqBody.Vin, "carNumber": reqBody.CarNumber, "cardNo": "", } plainText, err := carService.CarReqYuShan("CAR100", &reqData) if err != nil { log.Printf("YuShan request at %s error: %s", "CAR066", err.Error()) notifyService.SendNotification("羽山接口请求错误,请及时处理", "车辆估值", userid, order.ID) response.FailRefund(c) return } _, err = carService.CarInsuranceDataAnalysis(string(plainText)) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,请及时处理", "车辆估值", userid, order.ID) } else { notifyService.SendNotification("接口系统响应错误,请及时处理", "车辆估值", userid, order.ID) } response.FailRefund(c) return } carModel.Resp = string(plainText) carModel.UserID = userid carModel.Vin = reqBody.Vin carModel.CarNumber = reqBody.CarNumber carModel.OrderID = order.ID err = db.DB.Create(&carModel).Error if err != nil { log.Printf("车辆估值信息保存错误:%v", err) notifyService.SendNotification("汽车查询数据保存错误,请及时处理", "车辆估值", userid, order.ID) response.FailRefund(c) return } orderService.OrderConsumed(order) response.OkWithData(gin.H{ "record_id": carModel.OrderID, }, c) }