qnc-server-tob/app/main/api/internal/logic/auth/initfaceverifylogic.go
2025-06-09 12:34:52 +08:00

137 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package auth
import (
"context"
"database/sql"
"encoding/hex"
"math/rand"
"strconv"
"time"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/app/main/model"
"qnc-server/common/xerr"
"qnc-server/pkg/core/aliyun/cloudauth"
"qnc-server/pkg/lzkit/crypto"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type InitFaceVerifyLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewInitFaceVerifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InitFaceVerifyLogic {
return &InitFaceVerifyLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
// 生成带前缀的随机OuterOrderNo阿里云人脸验证单号
func genOuterOrderNo() string {
prefix := "FACE_"
timestamp := time.Now().UnixNano()
randNum := rand.Intn(1000000)
return prefix + strconv.FormatInt(timestamp, 10) + strconv.Itoa(randNum)
}
func (l *InitFaceVerifyLogic) InitFaceVerify(req *types.InitFaceVerifyReq) (resp *types.InitFaceVerifyResp, err error) {
order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", err)
}
if order.Status != "paid" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "订单未支付")
}
authorization, err := l.svcCtx.AuthorizationModel.FindOneByOrderId(l.ctx, order.Id)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询授权信息失败: %v", err)
}
if authorization.Status != "pending" {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "授权信息状态不正确")
}
key, decodeErr := hex.DecodeString(l.svcCtx.Config.Encrypt.SecretKey)
if decodeErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询授权信息失败: %v", decodeErr)
}
authorizationFaceBuilder := l.svcCtx.AuthorizationFaceModel.SelectBuilder().
Where("authorization_id = ? AND status = ? AND certify_id != '' AND certify_url != ''",
authorization.Id, model.AuthorizationStatusPending).
OrderBy("create_time DESC").
Limit(1)
existingFaces, err := l.svcCtx.AuthorizationFaceModel.FindAll(l.ctx, authorizationFaceBuilder, "")
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询人脸认证记录失败: %v", err)
}
if len(existingFaces) > 0 {
// 如果存在记录,直接返回最新的认证信息
return &types.InitFaceVerifyResp{
CertifyId: existingFaces[0].CertifyId,
CertifyUrl: existingFaces[0].CertifyUrl,
}, nil
}
outerOrderNo := genOuterOrderNo()
name, err := crypto.AesDecrypt(authorization.TargetName, key)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解密姓名失败: %v", err)
}
idCard, err := crypto.AesDecrypt(authorization.TargetIdcard, key)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解密身份证号失败: %v", err)
}
initFaceVerifyResp, err := l.svcCtx.CloudAuthService.InitFaceVerify(cloudauth.InitFaceVerifyParam{
OuterOrderNo: outerOrderNo,
CertName: string(name),
CertNo: string(idCard),
MetaInfo: req.MetaInfo,
})
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化人脸认证失败: %v", err)
}
err = l.svcCtx.AuthorizationModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
authorization.AuthType = sql.NullInt64{
Int64: req.AuthType,
Valid: true,
}
authorization.GrantType = sql.NullString{
String: model.AuthorizationGrantTypeFace,
Valid: true,
}
_, err = l.svcCtx.AuthorizationModel.Update(l.ctx, session, authorization)
if err != nil {
return err
}
authorizationFace := &model.AuthorizationFace{
AuthorizationId: authorization.Id,
CertifyId: initFaceVerifyResp.CertifyId,
CertifyUrl: initFaceVerifyResp.CertifyUrl,
Status: model.AuthorizationStatusPending,
CertifyUrlExpireAt: time.Now().Add(time.Minute * 30),
OuterOrderNo: outerOrderNo,
}
_, err = l.svcCtx.AuthorizationFaceModel.Insert(l.ctx, session, authorizationFace)
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "更新授权信息失败: %v", err)
}
return &types.InitFaceVerifyResp{
CertifyId: initFaceVerifyResp.CertifyId,
CertifyUrl: initFaceVerifyResp.CertifyUrl,
}, nil
}