202 lines
4.9 KiB
Go
202 lines
4.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"platform/pkg/env"
|
|
"platform/pkg/u"
|
|
"platform/web/auth"
|
|
"platform/web/core"
|
|
g "platform/web/globals"
|
|
q "platform/web/queries"
|
|
"platform/web/services"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
jdc "github.com/jdcloud-api/jdcloud-sdk-go/core"
|
|
"github.com/jdcloud-api/jdcloud-sdk-go/services/cloudauth/apis"
|
|
jdclient "github.com/jdcloud-api/jdcloud-sdk-go/services/cloudauth/client"
|
|
)
|
|
|
|
// Identify 发起实名认证
|
|
func Identify(c *fiber.Ctx) error {
|
|
|
|
// 检查权限
|
|
authCtx, err := auth.GetAuthCtx(c).PermitUser()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
user := authCtx.User
|
|
if user.IDToken != nil && *user.IDToken != "" {
|
|
// 用户已实名认证
|
|
return c.JSON(IdentifyRes{
|
|
Identified: true,
|
|
})
|
|
}
|
|
|
|
// 解析请求参数
|
|
req := new(IdentifyReq)
|
|
if err := c.BodyParser(req); err != nil {
|
|
return err
|
|
}
|
|
|
|
// 请求活体认证
|
|
var id = services.ID.GenReadable("iden")
|
|
|
|
var credential = jdc.NewCredentials(env.IdenAccessKey, env.IdenSecretKey)
|
|
var client = jdclient.NewCloudauthClient(credential)
|
|
resp, err := client.GetAliveUrl(apis.NewGetAliveUrlRequestWithAllParams(
|
|
u.P(req.Name),
|
|
u.P(req.IdenNo),
|
|
env.IdenCallbackUrl+"?id="+id,
|
|
))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Error.Code != 0 {
|
|
var msg string
|
|
switch resp.Error.Code {
|
|
case 1007:
|
|
msg = "身份证号码格式错误"
|
|
}
|
|
return core.NewBizErr(fmt.Sprintf("活体认证失败: %s", msg))
|
|
}
|
|
|
|
// 保存认证中间状态
|
|
info := idenInfo{
|
|
Uid: user.ID,
|
|
Type: req.Type,
|
|
Name: req.Name,
|
|
IdNo: req.IdenNo,
|
|
Token: resp.Result.Token,
|
|
}
|
|
infoStr, err := json.Marshal(info)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = g.Redis.Set(c.Context(), idenKey(id), infoStr, 30*time.Minute).Err()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return c.JSON(IdentifyRes{
|
|
Identified: false,
|
|
Target: resp.Result.Url,
|
|
})
|
|
}
|
|
|
|
type IdentifyReq struct {
|
|
Type int `json:"type" validate:"required,oneof=1 2"`
|
|
Name string `json:"name" validate:"required"`
|
|
IdenNo string `json:"iden_no" validate:"required"`
|
|
}
|
|
|
|
type IdentifyRes struct {
|
|
Identified bool `json:"identified"`
|
|
Target string `json:"target"`
|
|
}
|
|
|
|
type idenResultData struct {
|
|
Success bool
|
|
Message string
|
|
}
|
|
|
|
// IdentifyCallbackNew 更新用户实名认证状态
|
|
func IdentifyCallbackNew(c *fiber.Ctx) error {
|
|
|
|
// 解析请求参数
|
|
req := new(struct {
|
|
Id string `json:"id" validate:"required"`
|
|
Success bool `json:"success" validate:"required"`
|
|
})
|
|
if err := c.QueryParser(req); err != nil {
|
|
return renderIdenResult(c, false, "解析请求参数失败")
|
|
}
|
|
|
|
// 获取 token
|
|
infoStr, err := g.Redis.GetDel(c.Context(), idenKey(req.Id)).Bytes()
|
|
if err != nil {
|
|
return renderIdenResult(c, false, "实名认证状态已失效,请重新发起认证")
|
|
}
|
|
info := idenInfo{}
|
|
if err = json.Unmarshal(infoStr, &info); err != nil {
|
|
return renderIdenResult(c, false, "解析实名认证信息失败,请重新发起认证")
|
|
}
|
|
|
|
// 获取认证结果
|
|
var credential = jdc.NewCredentials(env.IdenAccessKey, env.IdenSecretKey)
|
|
var client = jdclient.NewCloudauthClient(credential)
|
|
resp, err := client.GetAliveResult(apis.NewGetAliveResultRequestWithAllParams(
|
|
info.Token,
|
|
))
|
|
if err != nil {
|
|
return renderIdenResult(c, false, "获取实名认证结果失败,请重新发起认证")
|
|
}
|
|
if resp.Error.Code != 0 {
|
|
return renderIdenResult(c, false, fmt.Sprintf("获取实名认证结果失败:%s", resp.Error.Message))
|
|
}
|
|
if resp.Result.H5Result != "ok" || resp.Result.SmResult != "ok" || resp.Result.RxResult != "ok" {
|
|
return renderIdenResult(c, false, fmt.Sprintf("实名认证未通过:%s", resp.Result.Desc))
|
|
}
|
|
|
|
// 更新用户实名认证状态
|
|
_, err = q.User.
|
|
Where(q.User.ID.Eq(info.Uid)).
|
|
UpdateSimple(
|
|
q.User.IDType.Value(info.Type),
|
|
q.User.IDNo.Value(info.IdNo),
|
|
q.User.Name.Value(info.Name),
|
|
q.User.IDToken.Value(info.Token),
|
|
)
|
|
if err != nil {
|
|
return renderIdenResult(c, false, "保存实名认证信息失败,请联系客服处理")
|
|
}
|
|
|
|
// 返回结果页面
|
|
return renderIdenResult(c, true, "实名认证成功,请在扫码页面点击按钮完成认证")
|
|
}
|
|
|
|
func renderIdenResult(c *fiber.Ctx, success bool, message string) error {
|
|
return c.Render("views/iden-result", idenResultData{
|
|
Success: success,
|
|
Message: message,
|
|
})
|
|
}
|
|
|
|
// DebugIdentifyClear 清除用户实名认证状态(调试用)
|
|
func DebugIdentifyClear(c *fiber.Ctx) error {
|
|
phone := c.Params("phone")
|
|
if phone == "" {
|
|
return core.NewServErr("需要提供手机号")
|
|
}
|
|
|
|
_, err := q.User.
|
|
Where(
|
|
q.User.Phone.Eq(phone),
|
|
).
|
|
UpdateSimple(
|
|
q.User.IDType.Value(0),
|
|
q.User.IDNo.Value(""),
|
|
q.User.IDToken.Value(""),
|
|
)
|
|
if err != nil {
|
|
return core.NewServErr("清除实名认证失败")
|
|
}
|
|
|
|
return c.SendString("实名信息已清除")
|
|
}
|
|
|
|
func idenKey(id string) string {
|
|
return fmt.Sprintf("iden:%s", id)
|
|
}
|
|
|
|
type idenInfo struct {
|
|
Uid int32 `json:"uid"`
|
|
Type int `json:"type"`
|
|
Name string `json:"name"`
|
|
IdNo string `json:"id_no"`
|
|
Token string `json:"token"`
|
|
}
|