package auth import ( "context" "fmt" "qnc-server/common/xerr" "github.com/bytedance/sonic" "github.com/pkg/errors" "qnc-server/app/main/api/internal/svc" "qnc-server/app/main/api/internal/types" "qnc-server/app/main/model" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/sqlx" ) type GetFaceVerifyResultLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetFaceVerifyResultLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFaceVerifyResultLogic { return &GetFaceVerifyResultLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *GetFaceVerifyResultLogic) GetFaceVerifyResult(req *types.GetFaceVerifyResultReq) (resp *types.GetFaceVerifyResultResp, err error) { // 1. 查询认证明细 face, err := l.svcCtx.AuthorizationFaceModel.FindOneByCertifyId(l.ctx, req.CertifyId) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询认证明细失败: %v", err) } if face == nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询认证明细为空") } // 2. 查询主授权(如后续需要可用) auth, err := l.svcCtx.AuthorizationModel.FindOne(l.ctx, face.AuthorizationId) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询授权主表失败: %v", err) } // 3. 判断人脸认证明细和主授权状态,若均已是"success",则直接返回通过 if (face.Status == model.AuthorizationFaceStatusSuccess) && (auth.Status == model.AuthorizationStatusSuccess) { return &types.GetFaceVerifyResultResp{ OrderID: auth.OrderId, Passed: true, }, nil } // 4. 调用阿里云接口查询认证结果 describeResp, err := l.svcCtx.CloudAuthService.DescribeFaceVerify(req.CertifyId) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "校验人脸识别结果失败: %v", err) } // 5. 判断认证状态并更新(使用事务) if describeResp.Passed { // 使用事务更新状态 err = l.svcCtx.AuthorizationModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error { order, err := l.svcCtx.OrderModel.FindOne(ctx, auth.OrderId) if err != nil { return errors.Wrapf(err, "查询订单失败") } redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo) cache, cacheErr := l.svcCtx.Redis.GetCtx(ctx, redisKey) if cacheErr != nil { return fmt.Errorf("获取缓存内容失败: %+v", cacheErr) } var data types.QueryCacheLoad err = sonic.Unmarshal([]byte(cache), &data) if err != nil { return fmt.Errorf("解析缓存内容失败: %+v", err) } // 插入新queryModel query := &model.Query{ OrderId: auth.OrderId, UserId: auth.UserId, ProductId: order.ProductId, QueryParams: data.Params, QueryState: "pending", } _, insertQueryErr := l.svcCtx.QueryModel.Insert(ctx, session, query) if insertQueryErr != nil { return errors.Wrapf(insertQueryErr, "保存查询失败") } // 更新主授权状态 auth.Status = model.AuthorizationStatusSuccess _, err = l.svcCtx.AuthorizationModel.Update(ctx, session, auth) if err != nil { return errors.Wrapf(err, "更新授权状态失败") } // 更新人脸认证明细状态 face.Status = model.AuthorizationFaceStatusSuccess _, err = l.svcCtx.AuthorizationFaceModel.Update(ctx, session, face) if err != nil { return errors.Wrapf(err, "更新人脸认证状态失败") } if asyncErr := l.svcCtx.AsynqService.SendQueryTask(auth.OrderId); asyncErr != nil { logx.Errorf("异步任务调度失败: %v", asyncErr) return asyncErr } return nil }) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新认证状态失败: %v", err) } } // 6. 返回resp(resp.Passed := describeResp.Passed)和err(如有) resp = &types.GetFaceVerifyResultResp{ OrderID: auth.OrderId, Passed: describeResp.Passed, AuthType: auth.AuthType.Int64, } return resp, nil }