package api import ( "encoding/json" "errors" "github.com/gin-gonic/gin" "github.com/tidwall/gjson" "net/http" "qnc-server/config" "github.com/redis/go-redis/v9" "gorm.io/gorm" "log" "qnc-server/db" "qnc-server/model/model" "qnc-server/model/request" "qnc-server/model/response" "qnc-server/service" "qnc-server/utils" ) type SingleQuery struct { } var singleQueryService service.SingleQueryService var notifyService service.Notify var requestService service.RequestService // 注册路由 func InitSingleQuery(group *gin.RouterGroup) { var s SingleQuery singQueryPrivate := group.Group("single") singQueryPrivate.Use(JWTAuth()) singQueryPrivate.POST("bc_evaluate_marriage", NotifyMiddleware(), s.EvaluateMarriageQuery) singQueryPrivate.GET("get_merriage_record", s.GetMerriageRecord) } func (s *SingleQuery) EvaluateMarriageQuery(c *gin.Context) { ctx := c.Request.Context() var reqBody request.EvaluateMarriageReq if err := c.ShouldBindJSON(&reqBody); err != nil { log.Printf("请求参数错误%v\n", err) response.FailWithMessage("Failed to read request body", c) return } if config.ConfigData.Setting.Sign { if reqBody.SignImage == "" { response.FailWithMessage("Failed to read request body", c) return } } if len(reqBody.Mobile) != 11 { response.FailWithMessage("请输入正确的手机号码", c) return } // 校验验证码 isRight, err := utils.VerifyCode(reqBody.Mobile, reqBody.VerifyCode) if err != nil { response.FailWithMessage(err.Error(), c) return } else if !isRight { response.FailWithMessage("验证码错误", c) return } if config.ConfigData.Verify.Three { // 三要素 westName, err := utils.WestDexEncrypt(reqBody.Name, "121a1e41fc1690dd6b90afbcacd80cf4") if err != nil { log.Printf("西部加密错误:%v", err) response.FailWithMessage("系统错误,请稍后再试", c) return } westIDCard, err := utils.WestDexEncrypt(reqBody.CardNo, "121a1e41fc1690dd6b90afbcacd80cf4") if err != nil { log.Printf("西部加密错误:%v", err) response.FailWithMessage("系统错误,请稍后再试", c) return } westPhone, err := utils.WestDexEncrypt(reqBody.Mobile, "121a1e41fc1690dd6b90afbcacd80cf4") if err != nil { log.Printf("西部加密错误:%v", err) response.FailWithMessage("系统错误,请稍后再试", c) return } threeElementsReq := map[string]interface{}{ "name": westName, "idNo": westIDCard, "phone": westPhone, } threeElements, err := requestService.WestDexRequest("G15BJ02", threeElementsReq) var data response.Wrapper[response.ThreeElementsResponse] err = json.Unmarshal([]byte(threeElements), &data) if err != nil { log.Printf("响应解析失败:%v", err) response.FailWithMessage("系统错误,请稍后再试", c) return } switch data.Data.Code { case 1000: case 1001: response.FailWithMessage("姓名、证件号、手机号信息不一致", c) return case 1003: response.FailWithMessage("姓名、证件号、手机号信息不一致", c) return case 1004: response.FailWithMessage("姓名不正确", c) return case 1005: response.FailWithMessage("证件号码不正确", c) return default: log.Printf("三要素检测错误%v", data.Data.Msg) response.FailWithMessage("服务器错误请稍后再试", c) return } } else { // 二要素核验 twoElementsParams := map[string]any{ "name": reqBody.Name, "idcard": reqBody.CardNo, } twoElementsRespStr, err := requestService.AliYunRequest(http.MethodPost, "https://kzidcardv1.market.alicloudapi.com/api-mall/api/id_card/check", nil, twoElementsParams) var twoElementsResp response.TwoElementsResp err = json.Unmarshal([]byte(twoElementsRespStr), &twoElementsResp) if err != nil { log.Printf("二要素解析错误:%v", err) response.FailWithMessage("系统错误,请稍后再试", c) return } if twoElementsResp.Success == false { response.FailWithMessage("请输入有效的身份证号码", c) return } if twoElementsResp.Code != 200 { response.FailWithMessage(twoElementsResp.Msg, c) return } if twoElementsResp.Data.Result == 1 { response.FailWithMessage("姓名与身份证不一致", c) return } } userid := utils.GetUserID(c) //查找是否有 未消费并且已付费 的订单 order, err := orderService.QueryConsumedOrder(userid, "evaluateMarriage") 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 } } encodeName, err := utils.WestDexEncrypt(reqBody.Name, "121a1e41fc1690dd6b90afbcacd80cf4") if err != nil { log.Printf("【婚姻查询】加密错误:%v", err) response.FailWithMessage(err.Error(), c) return } encodeID, err := utils.WestDexEncrypt(reqBody.CardNo, "121a1e41fc1690dd6b90afbcacd80cf4") if err != nil { log.Printf("【婚姻查询】加密错误:%v", err) response.FailWithMessage(err.Error(), c) return } evaluateMarriageReq := map[string]interface{}{ "nameMan": encodeName, "certNumMan": encodeID, } const maxRetryCount = 5 retryCount := 0 var plainText string for retryCount < maxRetryCount { plainText, err = requestService.WestDexRequest("G09SC02", evaluateMarriageReq) if err != nil { retryCount++ continue } marriageResult := gjson.Get(plainText, "data.0.maritalStatus") if marriageResult.Exists() { break } else { retryCount++ } } if err != nil { notifyService.SendNotification("接口系统错误,将自动退款", "婚姻查询", userid, order.ID) if order.PaymentMethod == model.PaymentMethod_ALIPAY { err := orderService.AliRefund(ctx, order) if err != nil { notifyService.SendNotification("【支付宝】接口系统错误,自动退款失败", "婚姻查询", userid, order.ID) } else { notifyService.SendNotification("【支付宝】自动退款成功", order.Product.ProductName, order.Userid, order.ID) } } else { err := orderService.WeChatRefund(order) if err != nil { notifyService.SendNotification("接口系统响应错误,自动退款失败", "婚姻查询", userid, order.ID) } } response.FailRefund(c) return } result, err := singleQueryService.MarryAnalysis(plainText) if err != nil { if errors.Is(err, utils.ErrNoRecord) { notifyService.SendNotification("用户查询数据为空,将自动退款", "婚姻查询", userid, order.ID) if order.PaymentMethod == model.PaymentMethod_ALIPAY { err := orderService.AliRefund(ctx, order) if err != nil { notifyService.SendNotification("【支付宝】用户查询数据为空,自动退款失败", "婚姻查询", userid, order.ID) } else { notifyService.SendNotification("【支付宝】自动退款成功", order.Product.ProductName, order.Userid, order.ID) } } else { err := orderService.WeChatRefund(order) if err != nil { notifyService.SendNotification("用户查询数据为空,自动退款失败", "婚姻查询", userid, order.ID) } } } else { notifyService.SendNotification("接口系统错误,将自动退款", "婚姻查询", userid, order.ID) if order.PaymentMethod == model.PaymentMethod_ALIPAY { err := orderService.AliRefund(ctx, order) if err != nil { notifyService.SendNotification("【支付宝】接口系统错误,自动退款失败", "婚姻查询", userid, order.ID) } else { notifyService.SendNotification("【支付宝】自动退款成功", order.Product.ProductName, order.Userid, order.ID) } } else { err := orderService.WeChatRefund(order) if err != nil { notifyService.SendNotification("接口系统响应错误,自动退款失败", "婚姻查询", userid, order.ID) } } } log.Printf("【婚姻查询】%s", err.Error()) response.FailRefund(c) return } var code string for _, entry := range result.Data { if entry.MaritalStatus == "" { notifyService.SendNotification("婚姻查询数据为空字段,自动退款", "婚姻查询", userid, order.ID) if order.PaymentMethod == model.PaymentMethod_ALIPAY { err := orderService.AliRefund(ctx, order) if err != nil { notifyService.SendNotification("【支付宝】婚姻查询数据为空,自动退款失败", "婚姻查询", userid, order.ID) } else { notifyService.SendNotification("【支付宝】自动退款成功", order.Product.ProductName, order.Userid, order.ID) } } else { err := orderService.WeChatRefund(order) if err != nil { notifyService.SendNotification("婚姻查询数据为空,自动退款失败", "婚姻查询", userid, order.ID) } } log.Printf("【婚姻查询】数据为空,自动退款") response.FailRefund(c) return } code = entry.MaritalStatus if code == "3" { code = "2" } } orderService.OrderConsumed(order) var query model.Query query.OrderID = order.ID query.Code, _ = utils.EncryptCode(reqBody.Mobile, "776d538f1265a814437d2e12ac10b45b85045bc208a1eb129ef301f4157aa82f") query.Userid = userid query.ProductID = order.ProductID db.DB.Create(&query) fileName, err := featureService.GenerateSignPDF(reqBody.Name, query.ID, reqBody.SignImage) query.SignFile = fileName db.DB.Save(&query) var respData = gin.H{ "card_no": utils.EncryptIDCard(reqBody.CardNo), "name": utils.EncryptName(reqBody.Name), "result": []map[string]string{ { "maritalStatus": code, }, }, } uniqueID := utils.SetCacheData(ctx, respData) response.OkWithData(gin.H{ "record_id": uniqueID, }, c) } func (s *SingleQuery) GetMerriageRecord(c *gin.Context) { ctx := c.Request.Context() var req request.GetMerriageRecordReq if err := c.ShouldBindQuery(&req); err != nil { response.FailWithMessage("Failed to read request", c) return } data, err := utils.GetCacheData(ctx, req.ID) if err != nil { if errors.Is(err, redis.Nil) { response.Ok(c) return } else { response.FailWithMessage("系统错误", c) return } } response.OkWithData(data, c) }