新增代理实名认证和授权
This commit is contained in:
@@ -65,6 +65,9 @@ service main {
|
||||
// 下级贡献详情
|
||||
@handler GetAgentSubordinateContributionDetail
|
||||
get /subordinate/contribution/detail (GetAgentSubordinateContributionDetailReq) returns (GetAgentSubordinateContributionDetailResp)
|
||||
|
||||
@handler AgentRealName
|
||||
post /real_name (AgentRealNameReq) returns (AgentRealNameResp)
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -75,8 +78,8 @@ type (
|
||||
level string `json:"level"`
|
||||
region string `json:"region"`
|
||||
mobile string `json:"mobile"`
|
||||
wechatID string `json:"wechat_id"`
|
||||
expiryTime string `json:"expiry_time"`
|
||||
isRealName bool `json:"is_real_name"`
|
||||
}
|
||||
// 查询代理申请状态响应
|
||||
AgentAuditStatusResp {
|
||||
@@ -150,6 +153,15 @@ type (
|
||||
DescendantWithdrawCount int64 `json:"descendant_withdraw_count"` // 下级提现次数
|
||||
DescendantWithdrawAmount float64 `json:"descendant_withdraw_amount"` // 下级提现总额
|
||||
}
|
||||
AgentRealNameReq {
|
||||
Name string `json:"name"`
|
||||
IDCard string `json:"id_card"`
|
||||
Mobile string `json:"mobile"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
AgentRealNameResp {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
@@ -331,7 +343,6 @@ type (
|
||||
AgentApplyReq {
|
||||
Region string `json:"region"`
|
||||
Mobile string `json:"mobile"`
|
||||
WechatID string `json:"wechat_id"`
|
||||
Code string `json:"code"`
|
||||
Ancestor string `json:"ancestor,optional"`
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ service main {
|
||||
|
||||
@handler PaymentCheck
|
||||
post /pay/check (PaymentCheckReq) returns (PaymentCheckResp)
|
||||
|
||||
@handler QueryPaymentCheck
|
||||
post /pay/query_check (QueryPaymentCheckReq) returns (QueryPaymentCheckResp)
|
||||
}
|
||||
|
||||
type (
|
||||
@@ -62,6 +65,16 @@ type (
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
QueryPaymentCheckReq {
|
||||
OrderNo string `json:"order_no" validate:"required"`
|
||||
}
|
||||
QueryPaymentCheckResp {
|
||||
OrderStatus string `json:"order_status"`
|
||||
AuthorizationStatus string `json:"authorization_status"`
|
||||
Name string `json:"name"`
|
||||
IdCard string `json:"id_card"`
|
||||
ProductName string `json:"product_name"`
|
||||
}
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
@@ -20,6 +20,9 @@ type Query {
|
||||
CreateTime string `json:"create_time"` // 创建时间
|
||||
UpdateTime string `json:"update_time"` // 更新时间
|
||||
QueryState string `json:"query_state"` // 查询状态
|
||||
IsPaid bool `json:"is_paid"` // 是否支付
|
||||
IsQueryCompleted bool `json:"is_query_completed"` // 查询是否完成
|
||||
IsAuthCompleted bool `json:"is_auth_completed"` // 授权是否完成
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +110,10 @@ service main {
|
||||
@doc "更新查询数据"
|
||||
@handler updateQueryData
|
||||
post /query/update_data (UpdateQueryDataReq) returns (UpdateQueryDataResp)
|
||||
|
||||
@doc "确认查询状态"
|
||||
@handler confirmQueryState
|
||||
post /query/confirm_state (ConfirmQueryStateReq) returns (ConfirmQueryStateResp)
|
||||
}
|
||||
|
||||
// 获取查询临时订单
|
||||
@@ -218,3 +225,14 @@ type QuerySingleTestResp {
|
||||
Api string `json:"api"`
|
||||
}
|
||||
|
||||
// 新增接口的请求、响应类型定义
|
||||
type (
|
||||
ConfirmQueryStateReq {
|
||||
OrderID int64 `json:"order_id" validate:"required"`
|
||||
}
|
||||
ConfirmQueryStateResp {
|
||||
OrderState string `json:"order_state"` // 查询状态,例如"pending"、"success"、"failed"等
|
||||
QueryState string `json:"query_state"`
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -146,22 +146,63 @@ type (
|
||||
|
||||
//============================> auth v1 <============================
|
||||
@server (
|
||||
prefix: api/v1
|
||||
prefix: api/v1/auth
|
||||
group: auth
|
||||
)
|
||||
service main {
|
||||
@doc "get mobile verify code"
|
||||
@handler sendSms
|
||||
post /auth/sendSms (sendSmsReq)
|
||||
post /sendSms (sendSmsReq)
|
||||
|
||||
@doc "发起人脸认证"
|
||||
@handler initFaceVerify
|
||||
post /face/init (InitFaceVerifyReq) returns (InitFaceVerifyResp)
|
||||
|
||||
@doc "查询人脸认证结果"
|
||||
@handler getFaceVerifyResult
|
||||
post /face/result (GetFaceVerifyResultReq) returns (GetFaceVerifyResultResp)
|
||||
|
||||
@doc "第三方拒绝授权"
|
||||
@handler rejectAuthorization
|
||||
post /rejectAuthorization (RejectAuthorizationReq) returns (RejectAuthorizationResp)
|
||||
}
|
||||
|
||||
type (
|
||||
sendSmsReq {
|
||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||
ActionType string `json:"actionType" validate:"required,oneof=login register query agentApply bindMobile"`
|
||||
ActionType string `json:"actionType" validate:"required,oneof=login register query agentApply bindMobile realName"`
|
||||
}
|
||||
|
||||
// 发起人脸认证请求
|
||||
InitFaceVerifyReq {
|
||||
MetaInfo string `json:"meta_info" validate:"required"` // H5端获取的MetaInfo,JSON格式
|
||||
OrderNo string `json:"order_no" validate:"required"` // 订单号
|
||||
AuthType int64 `json:"auth_type" validate:"required"` // 认证类型
|
||||
}
|
||||
|
||||
// 发起人脸认证响应
|
||||
InitFaceVerifyResp {
|
||||
CertifyId string `json:"certify_id"` // 认证ID
|
||||
CertifyUrl string `json:"certify_url"` // 跳转认证页面URL
|
||||
}
|
||||
|
||||
// 查询人脸认证结果请求
|
||||
GetFaceVerifyResultReq {
|
||||
CertifyId string `json:"certify_id" validate:"required"` // 认证ID
|
||||
}
|
||||
|
||||
// 查询人脸认证结果响应
|
||||
GetFaceVerifyResultResp {
|
||||
Passed bool `json:"passed"` // 是否通过
|
||||
OrderID int64 `json:"order_id"`
|
||||
AuthType int64 `json:"auth_type"`
|
||||
}
|
||||
RejectAuthorizationReq {
|
||||
OrderNo string `json:"order_no" validate:"required"` // 订单号
|
||||
}
|
||||
RejectAuthorizationResp {
|
||||
}
|
||||
)
|
||||
|
||||
//============================> notification v1 <============================
|
||||
@server (
|
||||
prefix: api/v1
|
||||
|
||||
@@ -37,7 +37,7 @@ Alipay:
|
||||
AlipayRootCertPath: "etc/merchant/alipayRootCert.crt"
|
||||
IsProduction: true
|
||||
NotifyUrl: "https://6m4685017o.goho.co/api/v1/pay/alipay/callback"
|
||||
ReturnURL: "http://192.168.10.13:5679/payment/result"
|
||||
ReturnURL: "http://192.168.10.16:5679/authorization"
|
||||
|
||||
Wxpay:
|
||||
AppID: "wx442ee1ac1ee75917"
|
||||
@@ -64,3 +64,9 @@ SystemConfig:
|
||||
WechatH5:
|
||||
AppID: "wx442ee1ac1ee75917"
|
||||
AppSecret: "c80474909db42f63913b7a307b3bee17"
|
||||
CloudAuth:
|
||||
AccessKeyId: "LTAI5tSWnaq1kvUawsV4ayL8"
|
||||
AccessKeySecret: "fSGdUzm4TGtkus9rUVzipSOhEtimG5"
|
||||
Endpoint: "cloudauth.aliyuncs.com"
|
||||
SceneId: 1000013341
|
||||
ReturnUrl: "https://www.quannengcha.com/authorization/result"
|
||||
|
||||
@@ -65,3 +65,9 @@ SystemConfig:
|
||||
WechatH5:
|
||||
AppID: "wx442ee1ac1ee75917"
|
||||
AppSecret: "c80474909db42f63913b7a307b3bee17"
|
||||
CloudAuth:
|
||||
AccessKeyId: "LTAI5tSWnaq1kvUawsV4ayL8"
|
||||
AccessKeySecret: "fSGdUzm4TGtkus9rUVzipSOhEtimG5"
|
||||
Endpoint: "cloudauth.aliyuncs.com"
|
||||
SceneId: 1000013341
|
||||
ReturnUrl: "https://www.quannengcha.com/authorization/face/result"
|
||||
|
||||
@@ -20,6 +20,7 @@ type Config struct {
|
||||
YushanConfig YushanConfig
|
||||
SystemConfig SystemConfig
|
||||
WechatH5 WechatH5Config
|
||||
CloudAuth CloudAuthConfig
|
||||
}
|
||||
|
||||
// JwtAuth 用于 JWT 鉴权配置
|
||||
@@ -92,3 +93,10 @@ type WechatH5Config struct {
|
||||
AppID string
|
||||
AppSecret string
|
||||
}
|
||||
type CloudAuthConfig struct {
|
||||
AccessKeyId string
|
||||
AccessKeySecret string
|
||||
Endpoint string
|
||||
SceneId int64
|
||||
ReturnUrl string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"qnc-server/app/user/cmd/api/internal/logic/agent"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/result"
|
||||
"qnc-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func AgentRealNameHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.AgentRealNameReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := agent.NewAgentRealNameLogic(r.Context(), svcCtx)
|
||||
resp, err := l.AgentRealName(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"qnc-server/app/user/cmd/api/internal/logic/auth"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/result"
|
||||
"qnc-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func GetFaceVerifyResultHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetFaceVerifyResultReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := auth.NewGetFaceVerifyResultLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetFaceVerifyResult(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"qnc-server/app/user/cmd/api/internal/logic/auth"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/result"
|
||||
"qnc-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func InitFaceVerifyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.InitFaceVerifyReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := auth.NewInitFaceVerifyLogic(r.Context(), svcCtx)
|
||||
resp, err := l.InitFaceVerify(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"qnc-server/app/user/cmd/api/internal/logic/auth"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/result"
|
||||
"qnc-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func RejectAuthorizationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.RejectAuthorizationReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := auth.NewRejectAuthorizationLogic(r.Context(), svcCtx)
|
||||
resp, err := l.RejectAuthorization(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package pay
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"qnc-server/app/user/cmd/api/internal/logic/pay"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/result"
|
||||
"qnc-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func QueryPaymentCheckHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.QueryPaymentCheckReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := pay.NewQueryPaymentCheckLogic(r.Context(), svcCtx)
|
||||
resp, err := l.QueryPaymentCheck(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"qnc-server/app/user/cmd/api/internal/logic/query"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/result"
|
||||
"qnc-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func ConfirmQueryStateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ConfirmQueryStateReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := query.NewConfirmQueryStateLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ConfirmQueryState(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
Path: "/product_config",
|
||||
Handler: agent.GetAgentProductConfigHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/real_name",
|
||||
Handler: agent.AgentRealNameHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/subordinate/contribution/detail",
|
||||
@@ -144,14 +149,32 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// 发起人脸认证
|
||||
Method: http.MethodPost,
|
||||
Path: "/face/init",
|
||||
Handler: auth.InitFaceVerifyHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 查询人脸认证结果
|
||||
Method: http.MethodPost,
|
||||
Path: "/face/result",
|
||||
Handler: auth.GetFaceVerifyResultHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 第三方拒绝授权
|
||||
Method: http.MethodPost,
|
||||
Path: "/rejectAuthorization",
|
||||
Handler: auth.RejectAuthorizationHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// get mobile verify code
|
||||
Method: http.MethodPost,
|
||||
Path: "/auth/sendSms",
|
||||
Path: "/sendSms",
|
||||
Handler: auth.SendSmsHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/v1"),
|
||||
rest.WithPrefix("/api/v1/auth"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
@@ -206,6 +229,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
Path: "/pay/payment",
|
||||
Handler: pay.PaymentHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/pay/query_check",
|
||||
Handler: pay.QueryPaymentCheckHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||
@@ -275,6 +303,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// 确认查询状态
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/confirm_state",
|
||||
Handler: query.ConfirmQueryStateHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 查询列表
|
||||
Method: http.MethodGet,
|
||||
|
||||
99
app/user/cmd/api/internal/logic/agent/agentrealnamelogic.go
Normal file
99
app/user/cmd/api/internal/logic/agent/agentrealnamelogic.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/service"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/common/ctxdata"
|
||||
"qnc-server/common/xerr"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
)
|
||||
|
||||
type AgentRealNameLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewAgentRealNameLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AgentRealNameLogic {
|
||||
return &AgentRealNameLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AgentRealNameLogic) AgentRealName(req *types.AgentRealNameReq) (resp *types.AgentRealNameResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败, %v", err)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理实名, 加密手机号失败: %v", err)
|
||||
}
|
||||
// 检查手机号是否在一分钟内已发送过验证码
|
||||
redisKey := fmt.Sprintf("%s:%s", "realName", encryptedMobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "代理实名, 验证码过期: %s", encryptedMobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理实名, 读取验证码redis缓存失败, mobile: %s, err: %+v", encryptedMobile, err)
|
||||
}
|
||||
if cacheCode != req.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "代理实名, 验证码不正确: %s", encryptedMobile)
|
||||
}
|
||||
agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息失败, %v", err)
|
||||
}
|
||||
|
||||
agentRealName, err := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agent.Id)
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理实名信息失败, %v", err)
|
||||
}
|
||||
|
||||
if agentRealName != nil && agentRealName.Status == model.AgentRealNameStatusApproved {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("代理实名信息已审核通过"), "代理实名信息已审核通过")
|
||||
}
|
||||
// 三要素验证
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: req.Name,
|
||||
IDCard: req.IDCard,
|
||||
Mobile: req.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "三要素验证失败: %v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "三要素验证不通过: %v", err)
|
||||
}
|
||||
agentRealName = &model.AgentRealName{
|
||||
AgentId: agent.Id,
|
||||
Status: model.AgentRealNameStatusApproved,
|
||||
Name: req.Name,
|
||||
IdCard: req.IDCard,
|
||||
ApproveTime: sql.NullTime{Time: time.Now(), Valid: true},
|
||||
}
|
||||
_, err = l.svcCtx.AgentRealNameModel.Insert(l.ctx, nil, agentRealName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "添加代理实名信息失败, %v", err)
|
||||
}
|
||||
|
||||
return &types.AgentRealNameResp{
|
||||
Status: agentRealName.Status,
|
||||
}, nil
|
||||
}
|
||||
@@ -60,11 +60,22 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败: %v", err)
|
||||
}
|
||||
|
||||
// 查询代理信息
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询代理信息失败: %v", err)
|
||||
}
|
||||
agentRealName, err := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agentModel.Id)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return errors.Wrapf(xerr.NewErrMsg("您未进行实名认证, 无法提现"), "您未进行实名认证")
|
||||
}
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询代理实名信息失败: %v", err)
|
||||
}
|
||||
if agentRealName.Status != model.AgentRealNameStatusApproved {
|
||||
return errors.Wrapf(xerr.NewErrMsg("您的实名认证未通过, 无法提现"), "您的实名认证未通过")
|
||||
}
|
||||
if agentRealName.Name != req.PayeeName {
|
||||
return errors.Wrapf(xerr.NewErrMsg("您的实名认证信息不匹配, 无法提现"), "您的实名认证信息不匹配")
|
||||
}
|
||||
|
||||
// 查询钱包
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
jwtx "qnc-server/common/jwt"
|
||||
"qnc-server/common/xerr"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
"qnc-server/pkg/lzkit/lzUtils"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -108,7 +107,6 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
|
||||
agentAudit.UserId = user.Id
|
||||
agentAudit.Mobile = encryptedMobile
|
||||
agentAudit.Region = req.Region
|
||||
agentAudit.WechatId = lzUtils.StringToNullString(req.WechatID)
|
||||
agentAudit.Status = 1
|
||||
_, insetAgentAuditErr := l.svcCtx.AgentAuditModel.Insert(transCtx, session, &agentAudit)
|
||||
if insetAgentAuditErr != nil {
|
||||
@@ -131,7 +129,6 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
|
||||
agentModel.Mobile = agentAudit.Mobile
|
||||
agentModel.Region = agentAudit.Region
|
||||
agentModel.UserId = agentAudit.UserId
|
||||
agentModel.WechatId = lzUtils.StringToNullString(req.WechatID)
|
||||
agentModelInsert, insertAgentModelErr := l.svcCtx.AgentModel.Insert(transCtx, session, &agentModel)
|
||||
if insertAgentModelErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 新增代理失败: %+v", insertAgentModelErr)
|
||||
|
||||
@@ -6,12 +6,12 @@ import (
|
||||
"qnc-server/common/ctxdata"
|
||||
"qnc-server/common/xerr"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
"qnc-server/pkg/lzkit/lzUtils"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -64,6 +64,16 @@ func (l *GetAgentInfoLogic) GetAgentInfo() (resp *types.AgentInfoResp, err error
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息, 解密手机号失败: %v", err)
|
||||
}
|
||||
|
||||
IsRealName := false
|
||||
agentRealName, err := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agent.Id)
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理实名信息失败, %v", err)
|
||||
}
|
||||
if agentRealName != nil {
|
||||
IsRealName = true
|
||||
}
|
||||
|
||||
return &types.AgentInfoResp{
|
||||
AgentID: agent.Id,
|
||||
Level: agent.LevelName,
|
||||
@@ -72,6 +82,6 @@ func (l *GetAgentInfoLogic) GetAgentInfo() (resp *types.AgentInfoResp, err error
|
||||
Region: agent.Region,
|
||||
Mobile: agent.Mobile,
|
||||
ExpiryTime: agent.MembershipExpiryTime.Time.Format("2006-01-02 15:04:05"),
|
||||
WechatID: lzUtils.NullStringToString(agent.WechatId),
|
||||
IsRealName: IsRealName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
122
app/user/cmd/api/internal/logic/auth/getfaceverifyresultlogic.go
Normal file
122
app/user/cmd/api/internal/logic/auth/getfaceverifyresultlogic.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"qnc-server/common/xerr"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/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
|
||||
}
|
||||
134
app/user/cmd/api/internal/logic/auth/initfaceverifylogic.go
Normal file
134
app/user/cmd/api/internal/logic/auth/initfaceverifylogic.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/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)
|
||||
}
|
||||
if authorization.GrantType == "face" {
|
||||
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,
|
||||
}
|
||||
_, 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
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type RejectAuthorizationLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewRejectAuthorizationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RejectAuthorizationLogic {
|
||||
return &RejectAuthorizationLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RejectAuthorizationLogic) RejectAuthorization(req *types.RejectAuthorizationReq) (resp *types.RejectAuthorizationResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
@@ -2,8 +2,11 @@ package pay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
"qnc-server/pkg/lzkit/lzUtils"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -11,6 +14,7 @@ import (
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
@@ -95,9 +99,48 @@ func (l *AlipayCallbackLogic) handleQueryOrderPayment(w http.ResponseWriter, not
|
||||
}
|
||||
|
||||
if order.Status == "paid" {
|
||||
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil {
|
||||
logx.Errorf("异步任务调度失败: %v", asyncErr)
|
||||
return asyncErr
|
||||
redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo)
|
||||
cache, cacheErr := l.svcCtx.Redis.Get(redisKey)
|
||||
if cacheErr != nil {
|
||||
return fmt.Errorf("获取缓存内容失败: %+v", cacheErr)
|
||||
}
|
||||
var data types.QueryCacheLoad
|
||||
err = json.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析缓存内容失败: %+v", err)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return fmt.Errorf("获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesdecryptErr := crypto.AesDecrypt(data.Params, key)
|
||||
if aesdecryptErr != nil {
|
||||
return fmt.Errorf("解密参数失败: %+v", aesdecryptErr)
|
||||
}
|
||||
var paramsMap map[string]string
|
||||
if err := json.Unmarshal([]byte(decryptData), ¶msMap); err != nil {
|
||||
return fmt.Errorf("解析参数失败: %+v", err)
|
||||
}
|
||||
encryptName, err := crypto.AesEncrypt([]byte(paramsMap["name"]), key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("生成订单, 加密姓名失败: %+v", err)
|
||||
}
|
||||
encryptIdcard, err := crypto.AesEncrypt([]byte(paramsMap["id_card"]), key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("生成订单, 加密身份证号失败: %+v", err)
|
||||
}
|
||||
_, err = l.svcCtx.AuthorizationModel.Insert(l.ctx, nil, &model.Authorization{
|
||||
OrderId: order.Id,
|
||||
UserId: order.UserId,
|
||||
TargetName: encryptName,
|
||||
TargetIdcard: encryptIdcard,
|
||||
GrantType: model.GrantTypeFace,
|
||||
Status: model.AuthorizationStatusPending,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorf("支付宝支付回调,插入授权信息失败: %+v", err)
|
||||
return fmt.Errorf("插入授权信息失败: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +226,7 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter,
|
||||
return nil
|
||||
}
|
||||
|
||||
// 退款
|
||||
func (l *AlipayCallbackLogic) handleRefund(order *model.AgentMembershipRechargeOrder) error {
|
||||
ctx := context.Background()
|
||||
// 退款
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
@@ -125,6 +126,14 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
|
||||
amount = 0.01
|
||||
}
|
||||
var orderID int64
|
||||
Status := "pending"
|
||||
env := os.Getenv("ENV")
|
||||
if env == "" {
|
||||
env = "production"
|
||||
}
|
||||
if env == "development" {
|
||||
Status = "paid"
|
||||
}
|
||||
order := model.Order{
|
||||
OrderNo: outTradeNo,
|
||||
UserId: userID,
|
||||
@@ -132,7 +141,7 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
|
||||
PaymentPlatform: req.PayMethod,
|
||||
PaymentScene: "app",
|
||||
Amount: amount,
|
||||
Status: "pending",
|
||||
Status: Status,
|
||||
}
|
||||
orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(l.ctx, session, &order)
|
||||
if insertOrderErr != nil {
|
||||
@@ -157,6 +166,53 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存代理订单失败: %+v", agentOrderInsert)
|
||||
}
|
||||
}
|
||||
|
||||
if env == "development" {
|
||||
redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo)
|
||||
cache, cacheErr := l.svcCtx.Redis.Get(redisKey)
|
||||
if cacheErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取缓存内容失败: %+v", cacheErr)
|
||||
}
|
||||
var data types.QueryCacheLoad
|
||||
err = json.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析缓存内容失败: %+v", err)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesdecryptErr := crypto.AesDecrypt(data.Params, key)
|
||||
if aesdecryptErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解密参数失败: %+v", aesdecryptErr)
|
||||
}
|
||||
var paramsMap map[string]string
|
||||
if err := json.Unmarshal([]byte(decryptData), ¶msMap); err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析参数失败: %+v", err)
|
||||
}
|
||||
|
||||
encryptName, err := crypto.AesEncrypt([]byte(paramsMap["name"]), key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 加密姓名失败: %+v", err)
|
||||
}
|
||||
encryptIdcard, err := crypto.AesEncrypt([]byte(paramsMap["id_card"]), key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 加密身份证号失败: %+v", err)
|
||||
}
|
||||
_, err = l.svcCtx.AuthorizationModel.Insert(l.ctx, nil, &model.Authorization{
|
||||
OrderId: orderID,
|
||||
UserId: order.UserId,
|
||||
TargetName: encryptName,
|
||||
TargetIdcard: encryptIdcard,
|
||||
GrantType: model.GrantTypeFace,
|
||||
Status: model.AuthorizationStatusPending,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorf("支付宝支付回调,插入授权信息失败: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 插入授权信息失败: %+v", err)
|
||||
}
|
||||
}
|
||||
return &PaymentTypeResp{amount: amount, outTradeNo: outTradeNo, description: product.ProductName}, nil
|
||||
}
|
||||
func (l *PaymentLogic) AgentVipOrderPayment(req *types.PaymentReq, session sqlx.Session) (resp *PaymentTypeResp, err error) {
|
||||
|
||||
100
app/user/cmd/api/internal/logic/pay/querypaymentchecklogic.go
Normal file
100
app/user/cmd/api/internal/logic/pay/querypaymentchecklogic.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package pay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/xerr"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type QueryPaymentCheckLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewQueryPaymentCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryPaymentCheckLogic {
|
||||
return &QueryPaymentCheckLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *QueryPaymentCheckLogic) QueryPaymentCheck(req *types.QueryPaymentCheckReq) (resp *types.QueryPaymentCheckResp, 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)
|
||||
}
|
||||
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, order.ProductId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品失败: %v", err)
|
||||
}
|
||||
resp = new(types.QueryPaymentCheckResp)
|
||||
resp.OrderStatus = order.Status
|
||||
resp.ProductName = product.ProductName
|
||||
|
||||
if order.Status == "paid" {
|
||||
authorization, err := l.svcCtx.AuthorizationModel.FindOneByOrderId(l.ctx, order.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询授权信息失败: %v", err)
|
||||
}
|
||||
resp.AuthorizationStatus = authorization.Status
|
||||
key, decodeErr := hex.DecodeString(l.svcCtx.Config.Encrypt.SecretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询授权信息失败: %v", decodeErr)
|
||||
}
|
||||
decryptName, 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)
|
||||
}
|
||||
resp.Name = maskName(string(decryptName))
|
||||
resp.IdCard = maskIDCard(string(idCard))
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// 姓名脱敏
|
||||
func maskName(name string) string {
|
||||
// 将字符串转换为rune切片以正确处理中文字符
|
||||
runes := []rune(name)
|
||||
length := len(runes)
|
||||
|
||||
if length <= 1 {
|
||||
return name
|
||||
}
|
||||
|
||||
if length == 2 {
|
||||
// 两个字:保留第一个字,第二个字用*替代
|
||||
return string(runes[0]) + "*"
|
||||
}
|
||||
|
||||
// 三个字及以上:保留首尾字,中间用*替代
|
||||
first := string(runes[0])
|
||||
last := string(runes[length-1])
|
||||
mask := strings.Repeat("*", length-2)
|
||||
|
||||
return first + mask + last
|
||||
}
|
||||
|
||||
// 身份证号脱敏
|
||||
func maskIDCard(idCard string) string {
|
||||
length := len(idCard)
|
||||
if length <= 10 {
|
||||
return idCard // 如果长度太短,可能不是身份证,不处理
|
||||
}
|
||||
// 保留前3位和后4位
|
||||
return idCard[:3] + strings.Repeat("*", length-7) + idCard[length-4:]
|
||||
}
|
||||
@@ -2,10 +2,14 @@ package pay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"qnc-server/app/user/cmd/api/internal/service"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
"qnc-server/pkg/lzkit/lzUtils"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -197,15 +201,41 @@ func (l *WechatPayCallbackLogic) handleRefund(order *model.AgentMembershipRechar
|
||||
return refundErr
|
||||
}
|
||||
if refund.IsSuccess() {
|
||||
logx.Errorf("支付宝退款成功, orderID: %d", order.Id)
|
||||
// 更新订单状态为退款
|
||||
order.Status = "refunded"
|
||||
updateOrderErr := l.svcCtx.AgentMembershipRechargeOrderModel.UpdateWithVersion(ctx, nil, order)
|
||||
if updateOrderErr != nil {
|
||||
logx.Errorf("更新订单状态失败,订单ID: %d, 错误: %v", order.Id, updateOrderErr)
|
||||
return fmt.Errorf("更新订单状态失败: %v", updateOrderErr)
|
||||
redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo)
|
||||
cache, cacheErr := l.svcCtx.Redis.Get(redisKey)
|
||||
if cacheErr != nil {
|
||||
return fmt.Errorf("获取缓存内容失败: %+v", cacheErr)
|
||||
}
|
||||
var data types.QueryCacheLoad
|
||||
err := json.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析缓存内容失败: %+v", err)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return fmt.Errorf("获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesdecryptErr := crypto.AesDecrypt(data.Params, key)
|
||||
if aesdecryptErr != nil {
|
||||
return fmt.Errorf("解密参数失败: %+v", aesdecryptErr)
|
||||
}
|
||||
var paramsMap map[string]string
|
||||
if err := json.Unmarshal([]byte(decryptData), ¶msMap); err != nil {
|
||||
return fmt.Errorf("解析参数失败: %+v", err)
|
||||
}
|
||||
_, err = l.svcCtx.AuthorizationModel.Insert(l.ctx, nil, &model.Authorization{
|
||||
OrderId: order.Id,
|
||||
UserId: order.UserId,
|
||||
TargetName: paramsMap["name"],
|
||||
TargetIdcard: paramsMap["id_card"],
|
||||
GrantType: model.GrantTypeFace,
|
||||
Status: model.AuthorizationStatusPending,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorf("支付宝支付回调,插入授权信息失败: %+v", err)
|
||||
return fmt.Errorf("插入授权信息失败: %+v", err)
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
logx.Errorf("支付宝退款失败:%v", refundErr)
|
||||
return refundErr
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/common/xerr"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ConfirmQueryStateLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewConfirmQueryStateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConfirmQueryStateLogic {
|
||||
return &ConfirmQueryStateLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ConfirmQueryStateLogic) ConfirmQueryState(req *types.ConfirmQueryStateReq) (resp *types.ConfirmQueryStateResp, err error) {
|
||||
// 1. 通过 order_id 查询订单,判断订单是否已支付
|
||||
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, req.OrderID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", err)
|
||||
}
|
||||
if order == nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "订单不存在")
|
||||
}
|
||||
// 若订单未支付,则直接返回 OrderState := "pending", QueryState := ""
|
||||
if order.Status != model.OrderStatusPaid {
|
||||
return &types.ConfirmQueryStateResp{
|
||||
OrderState: order.Status,
|
||||
QueryState: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 2. 订单已支付,查询 query 状态(假设通过 order_id 查询 query 记录,例如使用 QueryModel.FindOneByOrderId)
|
||||
query, err := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, req.OrderID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询 query 失败: %v", err)
|
||||
}
|
||||
if query == nil {
|
||||
// 若 query 不存在,则返回 OrderState := "paid", QueryState := ""
|
||||
return &types.ConfirmQueryStateResp{
|
||||
OrderState: order.Status,
|
||||
QueryState: "",
|
||||
}, nil
|
||||
}
|
||||
// 否则,返回 OrderState := "paid", QueryState := query.QueryState
|
||||
return &types.ConfirmQueryStateResp{
|
||||
OrderState: query.QueryState,
|
||||
QueryState: query.QueryState,
|
||||
}, nil
|
||||
}
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"context"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/common/ctxdata"
|
||||
"qnc-server/common/xerr"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -30,35 +30,66 @@ func NewQueryListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryLi
|
||||
func (l *QueryListLogic) QueryList(req *types.QueryListReq) (resp *types.QueryListResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告列表查询, 获取用户信息失败, %+v", getUidErr)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "订单列表查询, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// 直接构建查询query表的条件
|
||||
build := l.svcCtx.QueryModel.SelectBuilder().Where(squirrel.Eq{
|
||||
// 构建查询订单表的条件,排除未支付的订单
|
||||
build := l.svcCtx.OrderModel.SelectBuilder().Where(squirrel.And{
|
||||
squirrel.Eq{
|
||||
"user_id": userID,
|
||||
},
|
||||
squirrel.NotEq{
|
||||
"status": model.OrderStatusPending,
|
||||
},
|
||||
})
|
||||
|
||||
// 直接从query表分页查询
|
||||
queryList, total, err := l.svcCtx.QueryModel.FindPageListByPageWithTotal(l.ctx, build, req.Page, req.PageSize, "create_time DESC")
|
||||
// 从订单表分页查询
|
||||
orderList, total, err := l.svcCtx.OrderModel.FindPageListByPageWithTotal(l.ctx, build, req.Page, req.PageSize, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告列表查询, 查找报告列表错误, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "订单列表查询, 查找订单列表错误, %+v", err)
|
||||
}
|
||||
|
||||
var list []types.Query
|
||||
if len(queryList) > 0 {
|
||||
for _, queryModel := range queryList {
|
||||
if len(orderList) > 0 {
|
||||
for _, orderModel := range orderList {
|
||||
var query types.Query
|
||||
query.CreateTime = queryModel.CreateTime.Format("2006-01-02 15:04:05")
|
||||
query.UpdateTime = queryModel.UpdateTime.Format("2006-01-02 15:04:05")
|
||||
copyErr := copier.Copy(&query, queryModel)
|
||||
if copyErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 报告结构体复制失败, %+v", err)
|
||||
}
|
||||
product, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
|
||||
query.CreateTime = orderModel.CreateTime.Format("2006-01-02 15:04:05")
|
||||
query.UpdateTime = orderModel.UpdateTime.Format("2006-01-02 15:04:05")
|
||||
// 设置订单ID
|
||||
query.OrderId = orderModel.Id
|
||||
query.UserId = orderModel.UserId
|
||||
|
||||
// 获取商品信息
|
||||
product, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, orderModel.ProductId)
|
||||
if findProductErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 获取商品信息失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "订单列表查询, 获取商品信息失败, %+v", findProductErr)
|
||||
}
|
||||
query.ProductName = product.ProductName
|
||||
|
||||
// 设置订单支付状态
|
||||
query.IsPaid = orderModel.Status == model.OrderStatusPaid
|
||||
|
||||
// 查询查询状态
|
||||
queryInfo, findQueryErr := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, orderModel.Id)
|
||||
if findQueryErr == nil {
|
||||
// 查询存在
|
||||
query.Id = queryInfo.Id
|
||||
query.QueryState = queryInfo.QueryState
|
||||
query.IsQueryCompleted = queryInfo.QueryState == model.QueryStateSuccess
|
||||
} else {
|
||||
query.QueryState = "未创建"
|
||||
query.IsQueryCompleted = false
|
||||
}
|
||||
|
||||
// 获取授权状态
|
||||
authInfo, findAuthErr := l.svcCtx.AuthorizationModel.FindOneByOrderId(l.ctx, orderModel.Id)
|
||||
if findAuthErr == nil {
|
||||
// 授权存在
|
||||
query.IsAuthCompleted = authInfo.Status == model.AuthorizationStatusSuccess
|
||||
} else {
|
||||
query.IsAuthCompleted = false
|
||||
}
|
||||
|
||||
list = append(list, query)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,16 +463,16 @@ func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceR
|
||||
}
|
||||
|
||||
// 校验验证码
|
||||
//verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||||
//if verifyCodeErr != nil {
|
||||
// return nil, verifyCodeErr
|
||||
//}
|
||||
//
|
||||
//// 校验三要素
|
||||
//verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||||
//if verifyErr != nil {
|
||||
// return nil, verifyErr
|
||||
//}
|
||||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||||
if verifyCodeErr != nil {
|
||||
return nil, verifyCodeErr
|
||||
}
|
||||
|
||||
// 校验三要素
|
||||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||||
if verifyErr != nil {
|
||||
return nil, verifyErr
|
||||
}
|
||||
|
||||
// 缓存
|
||||
params := map[string]interface{}{
|
||||
|
||||
@@ -12,10 +12,9 @@ import (
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
"qnc-server/pkg/lzkit/lzUtils"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/hibiken/asynq"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -60,7 +59,7 @@ func (l *PaySuccessNotifyUserHandler) ProcessTask(ctx context.Context, t *asynq.
|
||||
return fmt.Errorf("获取缓存内容失败: %+v", cacheErr)
|
||||
}
|
||||
var data types.QueryCacheLoad
|
||||
err = json.Unmarshal([]byte(cache), &data)
|
||||
err = sonic.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析缓存内容失败: %+v", err)
|
||||
}
|
||||
@@ -74,38 +73,8 @@ func (l *PaySuccessNotifyUserHandler) ProcessTask(ctx context.Context, t *asynq.
|
||||
return fmt.Errorf("解密参数失败: %+v", aesdecryptErr)
|
||||
}
|
||||
|
||||
// 敏感数据脱敏处理
|
||||
desensitizedParams, err := l.desensitizeParams(decryptData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("脱敏处理失败: %+v", err)
|
||||
}
|
||||
|
||||
// 对脱敏后的数据进行AES加密
|
||||
encryptedParams, encryptErr := crypto.AesEncrypt(desensitizedParams, key)
|
||||
if encryptErr != nil {
|
||||
return fmt.Errorf("加密脱敏数据失败: %+v", encryptErr)
|
||||
}
|
||||
|
||||
query := &model.Query{
|
||||
OrderId: order.Id,
|
||||
UserId: order.UserId,
|
||||
ProductId: product.Id,
|
||||
QueryParams: encryptedParams,
|
||||
QueryState: "pending",
|
||||
}
|
||||
result, insertQueryErr := l.svcCtx.QueryModel.Insert(ctx, nil, query)
|
||||
if insertQueryErr != nil {
|
||||
return fmt.Errorf("保存查询失败: %+v", insertQueryErr)
|
||||
}
|
||||
|
||||
// 获取插入后的ID
|
||||
queryId, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取插入的查询ID失败: %+v", err)
|
||||
}
|
||||
|
||||
// 从数据库中查询完整的查询记录
|
||||
query, err = l.svcCtx.QueryModel.FindOne(ctx, queryId)
|
||||
query, err := l.svcCtx.QueryModel.FindOneByOrderId(ctx, order.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取插入后的查询记录失败: %+v", err)
|
||||
}
|
||||
@@ -204,177 +173,3 @@ func (l *PaySuccessNotifyUserHandler) handleError(ctx context.Context, err error
|
||||
|
||||
return asynq.SkipRetry
|
||||
}
|
||||
|
||||
// desensitizeParams 对敏感数据进行脱敏处理
|
||||
func (l *PaySuccessNotifyUserHandler) desensitizeParams(data []byte) ([]byte, error) {
|
||||
// 解析JSON数据到map
|
||||
var paramsMap map[string]interface{}
|
||||
if err := json.Unmarshal(data, ¶msMap); err != nil {
|
||||
return nil, fmt.Errorf("解析JSON数据失败: %v", err)
|
||||
}
|
||||
|
||||
// 处理可能包含敏感信息的字段
|
||||
for key, value := range paramsMap {
|
||||
if strValue, ok := value.(string); ok {
|
||||
// 根据字段名和内容判断并脱敏
|
||||
if isNameField(key) && len(strValue) > 0 {
|
||||
// 姓名脱敏
|
||||
paramsMap[key] = maskName(strValue)
|
||||
} else if isIDCardField(key) && len(strValue) > 10 {
|
||||
// 身份证号脱敏
|
||||
paramsMap[key] = maskIDCard(strValue)
|
||||
} else if isPhoneField(key) && len(strValue) >= 8 {
|
||||
// 手机号脱敏
|
||||
paramsMap[key] = maskPhone(strValue)
|
||||
} else if len(strValue) > 3 {
|
||||
// 其他所有未匹配的字段都进行通用脱敏
|
||||
paramsMap[key] = maskGeneral(strValue)
|
||||
}
|
||||
} else if mapValue, ok := value.(map[string]interface{}); ok {
|
||||
// 递归处理嵌套的map
|
||||
for subKey, subValue := range mapValue {
|
||||
if subStrValue, ok := subValue.(string); ok {
|
||||
if isNameField(subKey) && len(subStrValue) > 0 {
|
||||
mapValue[subKey] = maskName(subStrValue)
|
||||
} else if isIDCardField(subKey) && len(subStrValue) > 10 {
|
||||
mapValue[subKey] = maskIDCard(subStrValue)
|
||||
} else if isPhoneField(subKey) && len(subStrValue) >= 8 {
|
||||
mapValue[subKey] = maskPhone(subStrValue)
|
||||
} else if len(subStrValue) > 3 {
|
||||
// 其他所有未匹配的字段都进行通用脱敏
|
||||
mapValue[subKey] = maskGeneral(subStrValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将处理后的map重新序列化为JSON
|
||||
return json.Marshal(paramsMap)
|
||||
}
|
||||
|
||||
// 判断是否为姓名字段
|
||||
func isNameField(key string) bool {
|
||||
key = strings.ToLower(key)
|
||||
return strings.Contains(key, "name") || strings.Contains(key, "姓名") ||
|
||||
strings.Contains(key, "owner") || strings.Contains(key, "user")
|
||||
}
|
||||
|
||||
// 判断是否为身份证字段
|
||||
func isIDCardField(key string) bool {
|
||||
key = strings.ToLower(key)
|
||||
return strings.Contains(key, "idcard") || strings.Contains(key, "id_card") ||
|
||||
strings.Contains(key, "身份证") || strings.Contains(key, "证件号")
|
||||
}
|
||||
|
||||
// 判断是否为手机号字段
|
||||
func isPhoneField(key string) bool {
|
||||
key = strings.ToLower(key)
|
||||
return strings.Contains(key, "phone") || strings.Contains(key, "mobile") ||
|
||||
strings.Contains(key, "手机") || strings.Contains(key, "电话")
|
||||
}
|
||||
|
||||
// 判断是否包含敏感数据模式
|
||||
func containsSensitivePattern(value string) bool {
|
||||
// 检查是否包含连续的数字或字母模式
|
||||
numPattern := regexp.MustCompile(`\d{6,}`)
|
||||
return numPattern.MatchString(value)
|
||||
}
|
||||
|
||||
// 姓名脱敏
|
||||
func maskName(name string) string {
|
||||
// 将字符串转换为rune切片以正确处理中文字符
|
||||
runes := []rune(name)
|
||||
length := len(runes)
|
||||
|
||||
if length <= 1 {
|
||||
return name
|
||||
}
|
||||
|
||||
if length == 2 {
|
||||
// 两个字:保留第一个字,第二个字用*替代
|
||||
return string(runes[0]) + "*"
|
||||
}
|
||||
|
||||
// 三个字及以上:保留首尾字,中间用*替代
|
||||
first := string(runes[0])
|
||||
last := string(runes[length-1])
|
||||
mask := strings.Repeat("*", length-2)
|
||||
|
||||
return first + mask + last
|
||||
}
|
||||
|
||||
// 身份证号脱敏
|
||||
func maskIDCard(idCard string) string {
|
||||
length := len(idCard)
|
||||
if length <= 10 {
|
||||
return idCard // 如果长度太短,可能不是身份证,不处理
|
||||
}
|
||||
// 保留前3位和后4位
|
||||
return idCard[:3] + strings.Repeat("*", length-7) + idCard[length-4:]
|
||||
}
|
||||
|
||||
// 手机号脱敏
|
||||
func maskPhone(phone string) string {
|
||||
length := len(phone)
|
||||
if length < 8 {
|
||||
return phone // 如果长度太短,可能不是手机号,不处理
|
||||
}
|
||||
// 保留前3位和后4位
|
||||
return phone[:3] + strings.Repeat("*", length-7) + phone[length-4:]
|
||||
}
|
||||
|
||||
// 通用敏感信息脱敏 - 根据字符串长度比例进行脱敏
|
||||
func maskGeneral(value string) string {
|
||||
length := len(value)
|
||||
|
||||
// 小于3个字符的不脱敏
|
||||
if length <= 3 {
|
||||
return value
|
||||
}
|
||||
|
||||
// 根据字符串长度计算保留字符数
|
||||
var prefixLen, suffixLen int
|
||||
|
||||
switch {
|
||||
case length <= 6: // 短字符串
|
||||
// 保留首尾各1个字符
|
||||
prefixLen, suffixLen = 1, 1
|
||||
case length <= 10: // 中等长度字符串
|
||||
// 保留首部30%和尾部20%的字符
|
||||
prefixLen = int(float64(length) * 0.3)
|
||||
suffixLen = int(float64(length) * 0.2)
|
||||
case length <= 20: // 较长字符串
|
||||
// 保留首部25%和尾部15%的字符
|
||||
prefixLen = int(float64(length) * 0.25)
|
||||
suffixLen = int(float64(length) * 0.15)
|
||||
default: // 非常长的字符串
|
||||
// 保留首部20%和尾部10%的字符
|
||||
prefixLen = int(float64(length) * 0.2)
|
||||
suffixLen = int(float64(length) * 0.1)
|
||||
}
|
||||
|
||||
// 确保至少有一个字符被保留
|
||||
if prefixLen < 1 {
|
||||
prefixLen = 1
|
||||
}
|
||||
if suffixLen < 1 {
|
||||
suffixLen = 1
|
||||
}
|
||||
|
||||
// 确保前缀和后缀总长不超过总长度的80%
|
||||
if prefixLen+suffixLen > int(float64(length)*0.8) {
|
||||
// 调整为总长度的80%
|
||||
totalVisible := int(float64(length) * 0.8)
|
||||
// 前缀占60%,后缀占40%
|
||||
prefixLen = int(float64(totalVisible) * 0.6)
|
||||
suffixLen = totalVisible - prefixLen
|
||||
}
|
||||
|
||||
// 创建脱敏后的字符串
|
||||
prefix := value[:prefixLen]
|
||||
suffix := value[length-suffixLen:]
|
||||
masked := strings.Repeat("*", length-prefixLen-suffixLen)
|
||||
|
||||
return prefix + masked + suffix
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"qnc-server/app/user/cmd/api/internal/middleware"
|
||||
"qnc-server/app/user/cmd/api/internal/service"
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/pkg/core/aliyun/cloudauth"
|
||||
|
||||
"github.com/hibiken/asynq"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
@@ -41,8 +42,11 @@ type ServiceContext struct {
|
||||
AgentPlatformDeductionModel model.AgentPlatformDeductionModel
|
||||
AgentActiveStatModel model.AgentActiveStatModel
|
||||
AgentWithdrawalModel model.AgentWithdrawalModel
|
||||
AgentRealNameModel model.AgentRealNameModel
|
||||
ExampleModel model.ExampleModel
|
||||
GlobalNotificationsModel model.GlobalNotificationsModel
|
||||
AuthorizationModel model.AuthorizationModel
|
||||
AuthorizationFaceModel model.AuthorizationFaceModel
|
||||
AlipayService *service.AliPayService
|
||||
WechatPayService *service.WechatPayService
|
||||
ApplePayService *service.ApplePayService
|
||||
@@ -54,6 +58,9 @@ type ServiceContext struct {
|
||||
VerificationService *service.VerificationService
|
||||
AgentService *service.AgentService
|
||||
UserService *service.UserService
|
||||
|
||||
// core service
|
||||
CloudAuthService *cloudauth.CloudAuthClient
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@@ -75,7 +82,17 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
Concurrency: 10,
|
||||
},
|
||||
)
|
||||
|
||||
cloudAuthService, err := cloudauth.NewCloudAuthClient(cloudauth.CloudAuthConfig{
|
||||
AccessKeyId: c.CloudAuth.AccessKeyId,
|
||||
AccessKeySecret: c.CloudAuth.AccessKeySecret,
|
||||
Endpoint: c.CloudAuth.Endpoint,
|
||||
SceneId: c.CloudAuth.SceneId,
|
||||
ReturnUrl: c.CloudAuth.ReturnUrl,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorf("初始化阿里云人脸认证服务失败: %+v", err)
|
||||
panic(err)
|
||||
}
|
||||
westDexService := service.NewWestDexService(c)
|
||||
yushanService := service.NewYushanService(c)
|
||||
productFeatureModel := model.NewProductFeatureModel(db, c.CacheRedis)
|
||||
@@ -104,7 +121,10 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
agentPlatformDeductionModel := model.NewAgentPlatformDeductionModel(db, c.CacheRedis)
|
||||
agentActiveStatModel := model.NewAgentActiveStatModel(db, c.CacheRedis)
|
||||
agentWithdrawalModel := model.NewAgentWithdrawalModel(db, c.CacheRedis)
|
||||
agentRealNameModel := model.NewAgentRealNameModel(db, c.CacheRedis)
|
||||
exampleModel := model.NewExampleModel(db, c.CacheRedis)
|
||||
authorizationModel := model.NewAuthorizationModel(db, c.CacheRedis)
|
||||
authorizationFaceModel := model.NewAuthorizationFaceModel(db, c.CacheRedis)
|
||||
|
||||
alipayService := service.NewAliPayService(c)
|
||||
wechatPayService := service.NewWechatPayService(c, userAuthModel, service.InitTypePlatformCert)
|
||||
@@ -117,6 +137,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
agentMembershipConfigModel, agentMembershipRechargeOrderModel, agentMembershipUserConfigModel,
|
||||
agentProductConfigModel, agentPlatformDeductionModel, agentActiveStatModel, agentWithdrawalModel)
|
||||
userService := service.NewUserService(userModel, userAuthModel)
|
||||
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
Redis: redis.MustNewRedis(redisConf),
|
||||
@@ -156,8 +177,12 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
AgentPlatformDeductionModel: agentPlatformDeductionModel,
|
||||
AgentActiveStatModel: agentActiveStatModel,
|
||||
AgentWithdrawalModel: agentWithdrawalModel,
|
||||
AgentRealNameModel: agentRealNameModel,
|
||||
ExampleModel: exampleModel,
|
||||
AuthorizationModel: authorizationModel,
|
||||
AuthorizationFaceModel: authorizationFaceModel,
|
||||
UserService: userService,
|
||||
CloudAuthService: cloudAuthService,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ type AgentActivateMembershipResp struct {
|
||||
type AgentApplyReq struct {
|
||||
Region string `json:"region"`
|
||||
Mobile string `json:"mobile"`
|
||||
WechatID string `json:"wechat_id"`
|
||||
Code string `json:"code"`
|
||||
Ancestor string `json:"ancestor,optional"`
|
||||
}
|
||||
@@ -58,8 +57,8 @@ type AgentInfoResp struct {
|
||||
Level string `json:"level"`
|
||||
Region string `json:"region"`
|
||||
Mobile string `json:"mobile"`
|
||||
WechatID string `json:"wechat_id"`
|
||||
ExpiryTime string `json:"expiry_time"`
|
||||
IsRealName bool `json:"is_real_name"`
|
||||
}
|
||||
|
||||
type AgentMembershipProductConfigReq struct {
|
||||
@@ -98,6 +97,17 @@ type AgentProductConfigResp struct {
|
||||
AgentProductConfig []AgentProductConfig
|
||||
}
|
||||
|
||||
type AgentRealNameReq struct {
|
||||
Name string `json:"name"`
|
||||
IDCard string `json:"id_card"`
|
||||
Mobile string `json:"mobile"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type AgentRealNameResp struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type AgentSubordinateContributionDetail struct {
|
||||
ID int64 `json:"id"`
|
||||
CreateTime string `json:"create_time"`
|
||||
@@ -148,6 +158,15 @@ type Commission struct {
|
||||
CreateTime string `json:"create_time"`
|
||||
}
|
||||
|
||||
type ConfirmQueryStateReq struct {
|
||||
OrderID int64 `json:"order_id" validate:"required"`
|
||||
}
|
||||
|
||||
type ConfirmQueryStateResp struct {
|
||||
OrderState string `json:"order_state"` // 查询状态,例如"pending"、"success"、"failed"等
|
||||
QueryState string `json:"query_state"`
|
||||
}
|
||||
|
||||
type DirectPushReport struct {
|
||||
TotalCommission float64 `json:"total_commission"`
|
||||
TotalReport int `json:"total_report"`
|
||||
@@ -211,6 +230,16 @@ type GetCommissionResp struct {
|
||||
List []Commission `json:"list"` // 查询列表
|
||||
}
|
||||
|
||||
type GetFaceVerifyResultReq struct {
|
||||
CertifyId string `json:"certify_id" validate:"required"` // 认证ID
|
||||
}
|
||||
|
||||
type GetFaceVerifyResultResp struct {
|
||||
Passed bool `json:"passed"` // 是否通过
|
||||
OrderID int64 `json:"order_id"`
|
||||
AuthType int64 `json:"auth_type"`
|
||||
}
|
||||
|
||||
type GetLinkDataReq struct {
|
||||
LinkIdentifier string `form:"link_identifier"`
|
||||
}
|
||||
@@ -262,6 +291,17 @@ type IapCallbackReq struct {
|
||||
TransactionReceipt string `json:"transaction_receipt" validate:"required"`
|
||||
}
|
||||
|
||||
type InitFaceVerifyReq struct {
|
||||
MetaInfo string `json:"meta_info" validate:"required"` // H5端获取的MetaInfo,JSON格式
|
||||
OrderNo string `json:"order_no" validate:"required"` // 订单号
|
||||
AuthType int64 `json:"auth_type" validate:"required"` // 认证类型
|
||||
}
|
||||
|
||||
type InitFaceVerifyResp struct {
|
||||
CertifyId string `json:"certify_id"` // 认证ID
|
||||
CertifyUrl string `json:"certify_url"` // 跳转认证页面URL
|
||||
}
|
||||
|
||||
type MobileCodeLoginReq struct {
|
||||
Mobile string `json:"mobile"`
|
||||
Code string `json:"code" validate:"required"`
|
||||
@@ -345,6 +385,9 @@ type Query struct {
|
||||
CreateTime string `json:"create_time"` // 创建时间
|
||||
UpdateTime string `json:"update_time"` // 更新时间
|
||||
QueryState string `json:"query_state"` // 查询状态
|
||||
IsPaid bool `json:"is_paid"` // 是否支付
|
||||
IsQueryCompleted bool `json:"is_query_completed"` // 查询是否完成
|
||||
IsAuthCompleted bool `json:"is_auth_completed"` // 授权是否完成
|
||||
}
|
||||
|
||||
type QueryDetailByOrderIdReq struct {
|
||||
@@ -394,6 +437,18 @@ type QueryListResp struct {
|
||||
List []Query `json:"list"` // 查询列表
|
||||
}
|
||||
|
||||
type QueryPaymentCheckReq struct {
|
||||
OrderNo string `json:"order_no" validate:"required"`
|
||||
}
|
||||
|
||||
type QueryPaymentCheckResp struct {
|
||||
OrderStatus string `json:"order_status"`
|
||||
AuthorizationStatus string `json:"authorization_status"`
|
||||
Name string `json:"name"`
|
||||
IdCard string `json:"id_card"`
|
||||
ProductName string `json:"product_name"`
|
||||
}
|
||||
|
||||
type QueryProvisionalOrderReq struct {
|
||||
Id string `path:"id"`
|
||||
}
|
||||
@@ -457,6 +512,13 @@ type RegisterResp struct {
|
||||
RefreshAfter int64 `json:"refreshAfter"`
|
||||
}
|
||||
|
||||
type RejectAuthorizationReq struct {
|
||||
OrderNo string `json:"order_no" validate:"required"` // 订单号
|
||||
}
|
||||
|
||||
type RejectAuthorizationResp struct {
|
||||
}
|
||||
|
||||
type Rewards struct {
|
||||
Type string `json:"type"`
|
||||
Amount float64 `json:"amount"`
|
||||
@@ -545,5 +607,5 @@ type GetAppVersionResp struct {
|
||||
|
||||
type SendSmsReq struct {
|
||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||
ActionType string `json:"actionType" validate:"required,oneof=login register query agentApply bindMobile"`
|
||||
ActionType string `json:"actionType" validate:"required,oneof=login register query agentApply bindMobile realName"`
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ type (
|
||||
UserId int64 `db:"user_id"`
|
||||
Region string `db:"region"`
|
||||
Mobile string `db:"mobile"`
|
||||
WechatId sql.NullString `db:"wechat_id"`
|
||||
Status int64 `db:"status"`
|
||||
AuditReason sql.NullString `db:"audit_reason"`
|
||||
CreateTime time.Time `db:"create_time"`
|
||||
@@ -84,11 +83,11 @@ func (m *defaultAgentAuditModel) Insert(ctx context.Context, session sqlx.Sessio
|
||||
qncAgentAuditIdKey := fmt.Sprintf("%s%v", cacheQncAgentAuditIdPrefix, data.Id)
|
||||
qncAgentAuditUserIdKey := fmt.Sprintf("%s%v", cacheQncAgentAuditUserIdPrefix, data.UserId)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, agentAuditRowsExpectAutoSet)
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, agentAuditRowsExpectAutoSet)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, data.UserId, data.Region, data.Mobile, data.WechatId, data.Status, data.AuditReason, data.AuditTime, data.DeleteTime, data.DelState, data.Version)
|
||||
return session.ExecCtx(ctx, query, data.UserId, data.Region, data.Mobile, data.Status, data.AuditReason, data.AuditTime, data.DeleteTime, data.DelState, data.Version)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, data.UserId, data.Region, data.Mobile, data.WechatId, data.Status, data.AuditReason, data.AuditTime, data.DeleteTime, data.DelState, data.Version)
|
||||
return conn.ExecCtx(ctx, query, data.UserId, data.Region, data.Mobile, data.Status, data.AuditReason, data.AuditTime, data.DeleteTime, data.DelState, data.Version)
|
||||
}, qncAgentAuditIdKey, qncAgentAuditUserIdKey)
|
||||
}
|
||||
|
||||
@@ -139,9 +138,9 @@ func (m *defaultAgentAuditModel) Update(ctx context.Context, session sqlx.Sessio
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, agentAuditRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.WechatId, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.WechatId, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}, qncAgentAuditIdKey, qncAgentAuditUserIdKey)
|
||||
}
|
||||
|
||||
@@ -162,9 +161,9 @@ func (m *defaultAgentAuditModel) UpdateWithVersion(ctx context.Context, session
|
||||
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, agentAuditRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.WechatId, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.WechatId, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.Region, newData.Mobile, newData.Status, newData.AuditReason, newData.AuditTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}, qncAgentAuditIdKey, qncAgentAuditUserIdKey)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -63,7 +63,6 @@ type (
|
||||
LevelName string `db:"level_name"` // 代理等级
|
||||
Region string `db:"region"`
|
||||
Mobile string `db:"mobile"`
|
||||
WechatId sql.NullString `db:"wechat_id"`
|
||||
MembershipExpiryTime sql.NullTime `db:"membership_expiry_time"` // 会员过期时间
|
||||
CreateTime time.Time `db:"create_time"`
|
||||
UpdateTime time.Time `db:"update_time"`
|
||||
@@ -86,11 +85,11 @@ func (m *defaultAgentModel) Insert(ctx context.Context, session sqlx.Session, da
|
||||
qncAgentMobileKey := fmt.Sprintf("%s%v", cacheQncAgentMobilePrefix, data.Mobile)
|
||||
qncAgentUserIdKey := fmt.Sprintf("%s%v", cacheQncAgentUserIdPrefix, data.UserId)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, agentRowsExpectAutoSet)
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, agentRowsExpectAutoSet)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, data.UserId, data.LevelName, data.Region, data.Mobile, data.WechatId, data.MembershipExpiryTime, data.DeleteTime, data.DelState, data.Version)
|
||||
return session.ExecCtx(ctx, query, data.UserId, data.LevelName, data.Region, data.Mobile, data.MembershipExpiryTime, data.DeleteTime, data.DelState, data.Version)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, data.UserId, data.LevelName, data.Region, data.Mobile, data.WechatId, data.MembershipExpiryTime, data.DeleteTime, data.DelState, data.Version)
|
||||
return conn.ExecCtx(ctx, query, data.UserId, data.LevelName, data.Region, data.Mobile, data.MembershipExpiryTime, data.DeleteTime, data.DelState, data.Version)
|
||||
}, qncAgentIdKey, qncAgentMobileKey, qncAgentUserIdKey)
|
||||
}
|
||||
|
||||
@@ -162,9 +161,9 @@ func (m *defaultAgentModel) Update(ctx context.Context, session sqlx.Session, ne
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, agentRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.WechatId, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.WechatId, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}, qncAgentIdKey, qncAgentMobileKey, qncAgentUserIdKey)
|
||||
}
|
||||
|
||||
@@ -186,9 +185,9 @@ func (m *defaultAgentModel) UpdateWithVersion(ctx context.Context, session sqlx.
|
||||
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, agentRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.WechatId, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
return session.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.WechatId, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
return conn.ExecCtx(ctx, query, newData.UserId, newData.LevelName, newData.Region, newData.Mobile, newData.MembershipExpiryTime, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}, qncAgentIdKey, qncAgentMobileKey, qncAgentUserIdKey)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
27
app/user/model/agentRealNameModel.go
Normal file
27
app/user/model/agentRealNameModel.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ AgentRealNameModel = (*customAgentRealNameModel)(nil)
|
||||
|
||||
type (
|
||||
// AgentRealNameModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customAgentRealNameModel.
|
||||
AgentRealNameModel interface {
|
||||
agentRealNameModel
|
||||
}
|
||||
|
||||
customAgentRealNameModel struct {
|
||||
*defaultAgentRealNameModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewAgentRealNameModel returns a model for the database table.
|
||||
func NewAgentRealNameModel(conn sqlx.SqlConn, c cache.CacheConf) AgentRealNameModel {
|
||||
return &customAgentRealNameModel{
|
||||
defaultAgentRealNameModel: newAgentRealNameModel(conn, c),
|
||||
}
|
||||
}
|
||||
411
app/user/model/agentRealNameModel_gen.go
Normal file
411
app/user/model/agentRealNameModel_gen.go
Normal file
@@ -0,0 +1,411 @@
|
||||
// Code generated by goctl. DO NOT EDIT!
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"qnc-server/common/globalkey"
|
||||
)
|
||||
|
||||
var (
|
||||
agentRealNameFieldNames = builder.RawFieldNames(&AgentRealName{})
|
||||
agentRealNameRows = strings.Join(agentRealNameFieldNames, ",")
|
||||
agentRealNameRowsExpectAutoSet = strings.Join(stringx.Remove(agentRealNameFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
|
||||
agentRealNameRowsWithPlaceHolder = strings.Join(stringx.Remove(agentRealNameFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||
|
||||
cacheQncAgentRealNameIdPrefix = "cache:qnc:agentRealName:id:"
|
||||
cacheQncAgentRealNameAgentIdPrefix = "cache:qnc:agentRealName:agentId:"
|
||||
)
|
||||
|
||||
type (
|
||||
agentRealNameModel interface {
|
||||
Insert(ctx context.Context, session sqlx.Session, data *AgentRealName) (sql.Result, error)
|
||||
FindOne(ctx context.Context, id int64) (*AgentRealName, error)
|
||||
FindOneByAgentId(ctx context.Context, agentId int64) (*AgentRealName, error)
|
||||
Update(ctx context.Context, session sqlx.Session, data *AgentRealName) (sql.Result, error)
|
||||
UpdateWithVersion(ctx context.Context, session sqlx.Session, data *AgentRealName) error
|
||||
Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error
|
||||
SelectBuilder() squirrel.SelectBuilder
|
||||
DeleteSoft(ctx context.Context, session sqlx.Session, data *AgentRealName) error
|
||||
FindSum(ctx context.Context, sumBuilder squirrel.SelectBuilder, field string) (float64, error)
|
||||
FindCount(ctx context.Context, countBuilder squirrel.SelectBuilder, field string) (int64, error)
|
||||
FindAll(ctx context.Context, rowBuilder squirrel.SelectBuilder, orderBy string) ([]*AgentRealName, error)
|
||||
FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AgentRealName, error)
|
||||
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AgentRealName, int64, error)
|
||||
FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*AgentRealName, error)
|
||||
FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*AgentRealName, error)
|
||||
Delete(ctx context.Context, session sqlx.Session, id int64) error
|
||||
}
|
||||
|
||||
defaultAgentRealNameModel struct {
|
||||
sqlc.CachedConn
|
||||
table string
|
||||
}
|
||||
|
||||
AgentRealName struct {
|
||||
Id int64 `db:"id"` // 主键ID
|
||||
AgentId int64 `db:"agent_id"` // 代理ID
|
||||
Name string `db:"name"` // 实名姓名
|
||||
IdCard string `db:"id_card"` // 身份证号
|
||||
Status string `db:"status"` // 认证状态(认证中、通过、拒绝)
|
||||
DelState int64 `db:"del_state"` // 删除状态
|
||||
Version int64 `db:"version"` // 版本号
|
||||
CreateTime time.Time `db:"create_time"` // 创建时间
|
||||
UpdateTime time.Time `db:"update_time"` // 更新时间
|
||||
ApproveTime sql.NullTime `db:"approve_time"` // 认证通过时间
|
||||
RejectTime sql.NullTime `db:"reject_time"` // 认证拒绝时间
|
||||
DeleteTime sql.NullTime `db:"delete_time"` // 删除时间
|
||||
}
|
||||
)
|
||||
|
||||
func newAgentRealNameModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultAgentRealNameModel {
|
||||
return &defaultAgentRealNameModel{
|
||||
CachedConn: sqlc.NewConn(conn, c),
|
||||
table: "`agent_real_name`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) Insert(ctx context.Context, session sqlx.Session, data *AgentRealName) (sql.Result, error) {
|
||||
data.DelState = globalkey.DelStateNo
|
||||
qncAgentRealNameAgentIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameAgentIdPrefix, data.AgentId)
|
||||
qncAgentRealNameIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameIdPrefix, data.Id)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, agentRealNameRowsExpectAutoSet)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, data.AgentId, data.Name, data.IdCard, data.Status, data.DelState, data.Version, data.ApproveTime, data.RejectTime, data.DeleteTime)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, data.AgentId, data.Name, data.IdCard, data.Status, data.DelState, data.Version, data.ApproveTime, data.RejectTime, data.DeleteTime)
|
||||
}, qncAgentRealNameAgentIdKey, qncAgentRealNameIdKey)
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindOne(ctx context.Context, id int64) (*AgentRealName, error) {
|
||||
qncAgentRealNameIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameIdPrefix, id)
|
||||
var resp AgentRealName
|
||||
err := m.QueryRowCtx(ctx, &resp, qncAgentRealNameIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", agentRealNameRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo)
|
||||
})
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindOneByAgentId(ctx context.Context, agentId int64) (*AgentRealName, error) {
|
||||
qncAgentRealNameAgentIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameAgentIdPrefix, agentId)
|
||||
var resp AgentRealName
|
||||
err := m.QueryRowIndexCtx(ctx, &resp, qncAgentRealNameAgentIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||
query := fmt.Sprintf("select %s from %s where `agent_id` = ? and del_state = ? limit 1", agentRealNameRows, m.table)
|
||||
if err := conn.QueryRowCtx(ctx, &resp, query, agentId, globalkey.DelStateNo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Id, nil
|
||||
}, m.queryPrimary)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) Update(ctx context.Context, session sqlx.Session, newData *AgentRealName) (sql.Result, error) {
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qncAgentRealNameAgentIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameAgentIdPrefix, data.AgentId)
|
||||
qncAgentRealNameIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameIdPrefix, data.Id)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, agentRealNameRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.AgentId, newData.Name, newData.IdCard, newData.Status, newData.DelState, newData.Version, newData.ApproveTime, newData.RejectTime, newData.DeleteTime, newData.Id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.AgentId, newData.Name, newData.IdCard, newData.Status, newData.DelState, newData.Version, newData.ApproveTime, newData.RejectTime, newData.DeleteTime, newData.Id)
|
||||
}, qncAgentRealNameAgentIdKey, qncAgentRealNameIdKey)
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *AgentRealName) error {
|
||||
|
||||
oldVersion := newData.Version
|
||||
newData.Version += 1
|
||||
|
||||
var sqlResult sql.Result
|
||||
var err error
|
||||
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
qncAgentRealNameAgentIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameAgentIdPrefix, data.AgentId)
|
||||
qncAgentRealNameIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameIdPrefix, data.Id)
|
||||
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, agentRealNameRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.AgentId, newData.Name, newData.IdCard, newData.Status, newData.DelState, newData.Version, newData.ApproveTime, newData.RejectTime, newData.DeleteTime, newData.Id, oldVersion)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.AgentId, newData.Name, newData.IdCard, newData.Status, newData.DelState, newData.Version, newData.ApproveTime, newData.RejectTime, newData.DeleteTime, newData.Id, oldVersion)
|
||||
}, qncAgentRealNameAgentIdKey, qncAgentRealNameIdKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateCount, err := sqlResult.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updateCount == 0 {
|
||||
return ErrNoRowsUpdate
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *AgentRealName) error {
|
||||
data.DelState = globalkey.DelStateYes
|
||||
data.DeleteTime = sql.NullTime{Time: time.Now(), Valid: true}
|
||||
if err := m.UpdateWithVersion(ctx, session, data); err != nil {
|
||||
return errors.Wrapf(errors.New("delete soft failed "), "AgentRealNameModel delete err : %+v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindSum(ctx context.Context, builder squirrel.SelectBuilder, field string) (float64, error) {
|
||||
|
||||
if len(field) == 0 {
|
||||
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
|
||||
}
|
||||
|
||||
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var resp float64
|
||||
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64, error) {
|
||||
|
||||
if len(field) == 0 {
|
||||
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
|
||||
}
|
||||
|
||||
builder = builder.Columns("COUNT(" + field + ")")
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var resp int64
|
||||
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*AgentRealName, error) {
|
||||
|
||||
builder = builder.Columns(agentRealNameRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AgentRealName
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AgentRealName, error) {
|
||||
|
||||
builder = builder.Columns(agentRealNameRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AgentRealName
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AgentRealName, int64, error) {
|
||||
|
||||
total, err := m.FindCount(ctx, builder, "id")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
builder = builder.Columns(agentRealNameRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, total, err
|
||||
}
|
||||
|
||||
var resp []*AgentRealName
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, total, nil
|
||||
default:
|
||||
return nil, total, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*AgentRealName, error) {
|
||||
|
||||
builder = builder.Columns(agentRealNameRows)
|
||||
|
||||
if preMinId > 0 {
|
||||
builder = builder.Where(" id < ? ", preMinId)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AgentRealName
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*AgentRealName, error) {
|
||||
|
||||
builder = builder.Columns(agentRealNameRows)
|
||||
|
||||
if preMaxId > 0 {
|
||||
builder = builder.Where(" id > ? ", preMaxId)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AgentRealName
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
|
||||
|
||||
return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
return fn(ctx, session)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) SelectBuilder() squirrel.SelectBuilder {
|
||||
return squirrel.Select().From(m.table)
|
||||
}
|
||||
func (m *defaultAgentRealNameModel) Delete(ctx context.Context, session sqlx.Session, id int64) error {
|
||||
data, err := m.FindOne(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
qncAgentRealNameAgentIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameAgentIdPrefix, data.AgentId)
|
||||
qncAgentRealNameIdKey := fmt.Sprintf("%s%v", cacheQncAgentRealNameIdPrefix, id)
|
||||
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, id)
|
||||
}, qncAgentRealNameAgentIdKey, qncAgentRealNameIdKey)
|
||||
return err
|
||||
}
|
||||
func (m *defaultAgentRealNameModel) formatPrimary(primary interface{}) string {
|
||||
return fmt.Sprintf("%s%v", cacheQncAgentRealNameIdPrefix, primary)
|
||||
}
|
||||
func (m *defaultAgentRealNameModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", agentRealNameRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo)
|
||||
}
|
||||
|
||||
func (m *defaultAgentRealNameModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
27
app/user/model/authorizationFaceModel.go
Normal file
27
app/user/model/authorizationFaceModel.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ AuthorizationFaceModel = (*customAuthorizationFaceModel)(nil)
|
||||
|
||||
type (
|
||||
// AuthorizationFaceModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customAuthorizationFaceModel.
|
||||
AuthorizationFaceModel interface {
|
||||
authorizationFaceModel
|
||||
}
|
||||
|
||||
customAuthorizationFaceModel struct {
|
||||
*defaultAuthorizationFaceModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewAuthorizationFaceModel returns a model for the database table.
|
||||
func NewAuthorizationFaceModel(conn sqlx.SqlConn, c cache.CacheConf) AuthorizationFaceModel {
|
||||
return &customAuthorizationFaceModel{
|
||||
defaultAuthorizationFaceModel: newAuthorizationFaceModel(conn, c),
|
||||
}
|
||||
}
|
||||
439
app/user/model/authorizationFaceModel_gen.go
Normal file
439
app/user/model/authorizationFaceModel_gen.go
Normal file
@@ -0,0 +1,439 @@
|
||||
// Code generated by goctl. DO NOT EDIT!
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"qnc-server/common/globalkey"
|
||||
)
|
||||
|
||||
var (
|
||||
authorizationFaceFieldNames = builder.RawFieldNames(&AuthorizationFace{})
|
||||
authorizationFaceRows = strings.Join(authorizationFaceFieldNames, ",")
|
||||
authorizationFaceRowsExpectAutoSet = strings.Join(stringx.Remove(authorizationFaceFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
|
||||
authorizationFaceRowsWithPlaceHolder = strings.Join(stringx.Remove(authorizationFaceFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||
|
||||
cacheQncAuthorizationFaceIdPrefix = "cache:qnc:authorizationFace:id:"
|
||||
cacheQncAuthorizationFaceCertifyIdPrefix = "cache:qnc:authorizationFace:certifyId:"
|
||||
cacheQncAuthorizationFaceOuterOrderNoPrefix = "cache:qnc:authorizationFace:outerOrderNo:"
|
||||
)
|
||||
|
||||
type (
|
||||
authorizationFaceModel interface {
|
||||
Insert(ctx context.Context, session sqlx.Session, data *AuthorizationFace) (sql.Result, error)
|
||||
FindOne(ctx context.Context, id int64) (*AuthorizationFace, error)
|
||||
FindOneByCertifyId(ctx context.Context, certifyId string) (*AuthorizationFace, error)
|
||||
FindOneByOuterOrderNo(ctx context.Context, outerOrderNo string) (*AuthorizationFace, error)
|
||||
Update(ctx context.Context, session sqlx.Session, data *AuthorizationFace) (sql.Result, error)
|
||||
UpdateWithVersion(ctx context.Context, session sqlx.Session, data *AuthorizationFace) error
|
||||
Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error
|
||||
SelectBuilder() squirrel.SelectBuilder
|
||||
DeleteSoft(ctx context.Context, session sqlx.Session, data *AuthorizationFace) error
|
||||
FindSum(ctx context.Context, sumBuilder squirrel.SelectBuilder, field string) (float64, error)
|
||||
FindCount(ctx context.Context, countBuilder squirrel.SelectBuilder, field string) (int64, error)
|
||||
FindAll(ctx context.Context, rowBuilder squirrel.SelectBuilder, orderBy string) ([]*AuthorizationFace, error)
|
||||
FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AuthorizationFace, error)
|
||||
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AuthorizationFace, int64, error)
|
||||
FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*AuthorizationFace, error)
|
||||
FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*AuthorizationFace, error)
|
||||
Delete(ctx context.Context, session sqlx.Session, id int64) error
|
||||
}
|
||||
|
||||
defaultAuthorizationFaceModel struct {
|
||||
sqlc.CachedConn
|
||||
table string
|
||||
}
|
||||
|
||||
AuthorizationFace struct {
|
||||
Id int64 `db:"id"`
|
||||
AuthorizationId int64 `db:"authorization_id"` // 关联授权主表ID
|
||||
CertifyId string `db:"certify_id"`
|
||||
OuterOrderNo string `db:"outer_order_no"` // 外部业务流水号
|
||||
CertifyUrl string `db:"certify_url"`
|
||||
CertifyUrlExpireAt time.Time `db:"certify_url_expire_at"` // 认证链接过期时间
|
||||
Status string `db:"status"` // 认证状态:pending待认证、success成功、fail失败
|
||||
ResultMsg sql.NullString `db:"result_msg"`
|
||||
PdfUrl sql.NullString `db:"pdf_url"`
|
||||
CreateTime time.Time `db:"create_time"`
|
||||
UpdateTime time.Time `db:"update_time"`
|
||||
DeleteTime sql.NullTime `db:"delete_time"` // 删除时间
|
||||
DelState int64 `db:"del_state"`
|
||||
Version int64 `db:"version"` // 版本号
|
||||
}
|
||||
)
|
||||
|
||||
func newAuthorizationFaceModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultAuthorizationFaceModel {
|
||||
return &defaultAuthorizationFaceModel{
|
||||
CachedConn: sqlc.NewConn(conn, c),
|
||||
table: "`authorization_face`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) Insert(ctx context.Context, session sqlx.Session, data *AuthorizationFace) (sql.Result, error) {
|
||||
data.DelState = globalkey.DelStateNo
|
||||
qncAuthorizationFaceCertifyIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceCertifyIdPrefix, data.CertifyId)
|
||||
qncAuthorizationFaceIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceIdPrefix, data.Id)
|
||||
qncAuthorizationFaceOuterOrderNoKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceOuterOrderNoPrefix, data.OuterOrderNo)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, authorizationFaceRowsExpectAutoSet)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, data.AuthorizationId, data.CertifyId, data.OuterOrderNo, data.CertifyUrl, data.CertifyUrlExpireAt, data.Status, data.ResultMsg, data.PdfUrl, data.DeleteTime, data.DelState, data.Version)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, data.AuthorizationId, data.CertifyId, data.OuterOrderNo, data.CertifyUrl, data.CertifyUrlExpireAt, data.Status, data.ResultMsg, data.PdfUrl, data.DeleteTime, data.DelState, data.Version)
|
||||
}, qncAuthorizationFaceCertifyIdKey, qncAuthorizationFaceIdKey, qncAuthorizationFaceOuterOrderNoKey)
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindOne(ctx context.Context, id int64) (*AuthorizationFace, error) {
|
||||
qncAuthorizationFaceIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceIdPrefix, id)
|
||||
var resp AuthorizationFace
|
||||
err := m.QueryRowCtx(ctx, &resp, qncAuthorizationFaceIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", authorizationFaceRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo)
|
||||
})
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindOneByCertifyId(ctx context.Context, certifyId string) (*AuthorizationFace, error) {
|
||||
qncAuthorizationFaceCertifyIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceCertifyIdPrefix, certifyId)
|
||||
var resp AuthorizationFace
|
||||
err := m.QueryRowIndexCtx(ctx, &resp, qncAuthorizationFaceCertifyIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||
query := fmt.Sprintf("select %s from %s where `certify_id` = ? and del_state = ? limit 1", authorizationFaceRows, m.table)
|
||||
if err := conn.QueryRowCtx(ctx, &resp, query, certifyId, globalkey.DelStateNo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Id, nil
|
||||
}, m.queryPrimary)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindOneByOuterOrderNo(ctx context.Context, outerOrderNo string) (*AuthorizationFace, error) {
|
||||
qncAuthorizationFaceOuterOrderNoKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceOuterOrderNoPrefix, outerOrderNo)
|
||||
var resp AuthorizationFace
|
||||
err := m.QueryRowIndexCtx(ctx, &resp, qncAuthorizationFaceOuterOrderNoKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||
query := fmt.Sprintf("select %s from %s where `outer_order_no` = ? and del_state = ? limit 1", authorizationFaceRows, m.table)
|
||||
if err := conn.QueryRowCtx(ctx, &resp, query, outerOrderNo, globalkey.DelStateNo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Id, nil
|
||||
}, m.queryPrimary)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) Update(ctx context.Context, session sqlx.Session, newData *AuthorizationFace) (sql.Result, error) {
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qncAuthorizationFaceCertifyIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceCertifyIdPrefix, data.CertifyId)
|
||||
qncAuthorizationFaceIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceIdPrefix, data.Id)
|
||||
qncAuthorizationFaceOuterOrderNoKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceOuterOrderNoPrefix, data.OuterOrderNo)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, authorizationFaceRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.AuthorizationId, newData.CertifyId, newData.OuterOrderNo, newData.CertifyUrl, newData.CertifyUrlExpireAt, newData.Status, newData.ResultMsg, newData.PdfUrl, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.AuthorizationId, newData.CertifyId, newData.OuterOrderNo, newData.CertifyUrl, newData.CertifyUrlExpireAt, newData.Status, newData.ResultMsg, newData.PdfUrl, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}, qncAuthorizationFaceCertifyIdKey, qncAuthorizationFaceIdKey, qncAuthorizationFaceOuterOrderNoKey)
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *AuthorizationFace) error {
|
||||
|
||||
oldVersion := newData.Version
|
||||
newData.Version += 1
|
||||
|
||||
var sqlResult sql.Result
|
||||
var err error
|
||||
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
qncAuthorizationFaceCertifyIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceCertifyIdPrefix, data.CertifyId)
|
||||
qncAuthorizationFaceIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceIdPrefix, data.Id)
|
||||
qncAuthorizationFaceOuterOrderNoKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceOuterOrderNoPrefix, data.OuterOrderNo)
|
||||
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, authorizationFaceRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.AuthorizationId, newData.CertifyId, newData.OuterOrderNo, newData.CertifyUrl, newData.CertifyUrlExpireAt, newData.Status, newData.ResultMsg, newData.PdfUrl, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.AuthorizationId, newData.CertifyId, newData.OuterOrderNo, newData.CertifyUrl, newData.CertifyUrlExpireAt, newData.Status, newData.ResultMsg, newData.PdfUrl, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}, qncAuthorizationFaceCertifyIdKey, qncAuthorizationFaceIdKey, qncAuthorizationFaceOuterOrderNoKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateCount, err := sqlResult.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updateCount == 0 {
|
||||
return ErrNoRowsUpdate
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *AuthorizationFace) error {
|
||||
data.DelState = globalkey.DelStateYes
|
||||
data.DeleteTime = sql.NullTime{Time: time.Now(), Valid: true}
|
||||
if err := m.UpdateWithVersion(ctx, session, data); err != nil {
|
||||
return errors.Wrapf(errors.New("delete soft failed "), "AuthorizationFaceModel delete err : %+v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindSum(ctx context.Context, builder squirrel.SelectBuilder, field string) (float64, error) {
|
||||
|
||||
if len(field) == 0 {
|
||||
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
|
||||
}
|
||||
|
||||
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var resp float64
|
||||
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64, error) {
|
||||
|
||||
if len(field) == 0 {
|
||||
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
|
||||
}
|
||||
|
||||
builder = builder.Columns("COUNT(" + field + ")")
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var resp int64
|
||||
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*AuthorizationFace, error) {
|
||||
|
||||
builder = builder.Columns(authorizationFaceRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AuthorizationFace
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AuthorizationFace, error) {
|
||||
|
||||
builder = builder.Columns(authorizationFaceRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AuthorizationFace
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*AuthorizationFace, int64, error) {
|
||||
|
||||
total, err := m.FindCount(ctx, builder, "id")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
builder = builder.Columns(authorizationFaceRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, total, err
|
||||
}
|
||||
|
||||
var resp []*AuthorizationFace
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, total, nil
|
||||
default:
|
||||
return nil, total, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*AuthorizationFace, error) {
|
||||
|
||||
builder = builder.Columns(authorizationFaceRows)
|
||||
|
||||
if preMinId > 0 {
|
||||
builder = builder.Where(" id < ? ", preMinId)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AuthorizationFace
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*AuthorizationFace, error) {
|
||||
|
||||
builder = builder.Columns(authorizationFaceRows)
|
||||
|
||||
if preMaxId > 0 {
|
||||
builder = builder.Where(" id > ? ", preMaxId)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*AuthorizationFace
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
|
||||
|
||||
return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
return fn(ctx, session)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) SelectBuilder() squirrel.SelectBuilder {
|
||||
return squirrel.Select().From(m.table)
|
||||
}
|
||||
func (m *defaultAuthorizationFaceModel) Delete(ctx context.Context, session sqlx.Session, id int64) error {
|
||||
data, err := m.FindOne(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
qncAuthorizationFaceCertifyIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceCertifyIdPrefix, data.CertifyId)
|
||||
qncAuthorizationFaceIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceIdPrefix, id)
|
||||
qncAuthorizationFaceOuterOrderNoKey := fmt.Sprintf("%s%v", cacheQncAuthorizationFaceOuterOrderNoPrefix, data.OuterOrderNo)
|
||||
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, id)
|
||||
}, qncAuthorizationFaceCertifyIdKey, qncAuthorizationFaceIdKey, qncAuthorizationFaceOuterOrderNoKey)
|
||||
return err
|
||||
}
|
||||
func (m *defaultAuthorizationFaceModel) formatPrimary(primary interface{}) string {
|
||||
return fmt.Sprintf("%s%v", cacheQncAuthorizationFaceIdPrefix, primary)
|
||||
}
|
||||
func (m *defaultAuthorizationFaceModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", authorizationFaceRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo)
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationFaceModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
27
app/user/model/authorizationModel.go
Normal file
27
app/user/model/authorizationModel.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ AuthorizationModel = (*customAuthorizationModel)(nil)
|
||||
|
||||
type (
|
||||
// AuthorizationModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customAuthorizationModel.
|
||||
AuthorizationModel interface {
|
||||
authorizationModel
|
||||
}
|
||||
|
||||
customAuthorizationModel struct {
|
||||
*defaultAuthorizationModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewAuthorizationModel returns a model for the database table.
|
||||
func NewAuthorizationModel(conn sqlx.SqlConn, c cache.CacheConf) AuthorizationModel {
|
||||
return &customAuthorizationModel{
|
||||
defaultAuthorizationModel: newAuthorizationModel(conn, c),
|
||||
}
|
||||
}
|
||||
412
app/user/model/authorizationModel_gen.go
Normal file
412
app/user/model/authorizationModel_gen.go
Normal file
@@ -0,0 +1,412 @@
|
||||
// Code generated by goctl. DO NOT EDIT!
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"qnc-server/common/globalkey"
|
||||
)
|
||||
|
||||
var (
|
||||
authorizationFieldNames = builder.RawFieldNames(&Authorization{})
|
||||
authorizationRows = strings.Join(authorizationFieldNames, ",")
|
||||
authorizationRowsExpectAutoSet = strings.Join(stringx.Remove(authorizationFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
|
||||
authorizationRowsWithPlaceHolder = strings.Join(stringx.Remove(authorizationFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||
|
||||
cacheQncAuthorizationIdPrefix = "cache:qnc:authorization:id:"
|
||||
cacheQncAuthorizationOrderIdPrefix = "cache:qnc:authorization:orderId:"
|
||||
)
|
||||
|
||||
type (
|
||||
authorizationModel interface {
|
||||
Insert(ctx context.Context, session sqlx.Session, data *Authorization) (sql.Result, error)
|
||||
FindOne(ctx context.Context, id int64) (*Authorization, error)
|
||||
FindOneByOrderId(ctx context.Context, orderId int64) (*Authorization, error)
|
||||
Update(ctx context.Context, session sqlx.Session, data *Authorization) (sql.Result, error)
|
||||
UpdateWithVersion(ctx context.Context, session sqlx.Session, data *Authorization) error
|
||||
Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error
|
||||
SelectBuilder() squirrel.SelectBuilder
|
||||
DeleteSoft(ctx context.Context, session sqlx.Session, data *Authorization) error
|
||||
FindSum(ctx context.Context, sumBuilder squirrel.SelectBuilder, field string) (float64, error)
|
||||
FindCount(ctx context.Context, countBuilder squirrel.SelectBuilder, field string) (int64, error)
|
||||
FindAll(ctx context.Context, rowBuilder squirrel.SelectBuilder, orderBy string) ([]*Authorization, error)
|
||||
FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*Authorization, error)
|
||||
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*Authorization, int64, error)
|
||||
FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*Authorization, error)
|
||||
FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*Authorization, error)
|
||||
Delete(ctx context.Context, session sqlx.Session, id int64) error
|
||||
}
|
||||
|
||||
defaultAuthorizationModel struct {
|
||||
sqlc.CachedConn
|
||||
table string
|
||||
}
|
||||
|
||||
Authorization struct {
|
||||
Id int64 `db:"id"`
|
||||
OrderId int64 `db:"order_id"`
|
||||
GrantType string `db:"grant_type"` // 授权类型:face人脸,后续可扩展
|
||||
AuthType sql.NullInt64 `db:"auth_type"` // 1本人,2他人
|
||||
UserId int64 `db:"user_id"`
|
||||
TargetName string `db:"target_name"`
|
||||
TargetIdcard string `db:"target_idcard"`
|
||||
Status string `db:"status"` // 授权状态:pending待授权、success已授权、expired已失效、revoked已撤销
|
||||
CreateTime time.Time `db:"create_time"`
|
||||
UpdateTime time.Time `db:"update_time"`
|
||||
DeleteTime sql.NullTime `db:"delete_time"` // 删除时间
|
||||
DelState int64 `db:"del_state"`
|
||||
Version int64 `db:"version"` // 版本号
|
||||
}
|
||||
)
|
||||
|
||||
func newAuthorizationModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultAuthorizationModel {
|
||||
return &defaultAuthorizationModel{
|
||||
CachedConn: sqlc.NewConn(conn, c),
|
||||
table: "`authorization`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) Insert(ctx context.Context, session sqlx.Session, data *Authorization) (sql.Result, error) {
|
||||
data.DelState = globalkey.DelStateNo
|
||||
qncAuthorizationIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationIdPrefix, data.Id)
|
||||
qncAuthorizationOrderIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationOrderIdPrefix, data.OrderId)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, authorizationRowsExpectAutoSet)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, data.OrderId, data.GrantType, data.AuthType, data.UserId, data.TargetName, data.TargetIdcard, data.Status, data.DeleteTime, data.DelState, data.Version)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, data.OrderId, data.GrantType, data.AuthType, data.UserId, data.TargetName, data.TargetIdcard, data.Status, data.DeleteTime, data.DelState, data.Version)
|
||||
}, qncAuthorizationIdKey, qncAuthorizationOrderIdKey)
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindOne(ctx context.Context, id int64) (*Authorization, error) {
|
||||
qncAuthorizationIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationIdPrefix, id)
|
||||
var resp Authorization
|
||||
err := m.QueryRowCtx(ctx, &resp, qncAuthorizationIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", authorizationRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo)
|
||||
})
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindOneByOrderId(ctx context.Context, orderId int64) (*Authorization, error) {
|
||||
qncAuthorizationOrderIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationOrderIdPrefix, orderId)
|
||||
var resp Authorization
|
||||
err := m.QueryRowIndexCtx(ctx, &resp, qncAuthorizationOrderIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||
query := fmt.Sprintf("select %s from %s where `order_id` = ? and del_state = ? limit 1", authorizationRows, m.table)
|
||||
if err := conn.QueryRowCtx(ctx, &resp, query, orderId, globalkey.DelStateNo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Id, nil
|
||||
}, m.queryPrimary)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) Update(ctx context.Context, session sqlx.Session, newData *Authorization) (sql.Result, error) {
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qncAuthorizationIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationIdPrefix, data.Id)
|
||||
qncAuthorizationOrderIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationOrderIdPrefix, data.OrderId)
|
||||
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, authorizationRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.OrderId, newData.GrantType, newData.AuthType, newData.UserId, newData.TargetName, newData.TargetIdcard, newData.Status, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.OrderId, newData.GrantType, newData.AuthType, newData.UserId, newData.TargetName, newData.TargetIdcard, newData.Status, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||
}, qncAuthorizationIdKey, qncAuthorizationOrderIdKey)
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *Authorization) error {
|
||||
|
||||
oldVersion := newData.Version
|
||||
newData.Version += 1
|
||||
|
||||
var sqlResult sql.Result
|
||||
var err error
|
||||
|
||||
data, err := m.FindOne(ctx, newData.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
qncAuthorizationIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationIdPrefix, data.Id)
|
||||
qncAuthorizationOrderIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationOrderIdPrefix, data.OrderId)
|
||||
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, authorizationRowsWithPlaceHolder)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, newData.OrderId, newData.GrantType, newData.AuthType, newData.UserId, newData.TargetName, newData.TargetIdcard, newData.Status, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, newData.OrderId, newData.GrantType, newData.AuthType, newData.UserId, newData.TargetName, newData.TargetIdcard, newData.Status, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||
}, qncAuthorizationIdKey, qncAuthorizationOrderIdKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateCount, err := sqlResult.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if updateCount == 0 {
|
||||
return ErrNoRowsUpdate
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *Authorization) error {
|
||||
data.DelState = globalkey.DelStateYes
|
||||
data.DeleteTime = sql.NullTime{Time: time.Now(), Valid: true}
|
||||
if err := m.UpdateWithVersion(ctx, session, data); err != nil {
|
||||
return errors.Wrapf(errors.New("delete soft failed "), "AuthorizationModel delete err : %+v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindSum(ctx context.Context, builder squirrel.SelectBuilder, field string) (float64, error) {
|
||||
|
||||
if len(field) == 0 {
|
||||
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
|
||||
}
|
||||
|
||||
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var resp float64
|
||||
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64, error) {
|
||||
|
||||
if len(field) == 0 {
|
||||
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
|
||||
}
|
||||
|
||||
builder = builder.Columns("COUNT(" + field + ")")
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var resp int64
|
||||
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*Authorization, error) {
|
||||
|
||||
builder = builder.Columns(authorizationRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*Authorization
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*Authorization, error) {
|
||||
|
||||
builder = builder.Columns(authorizationRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*Authorization
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*Authorization, int64, error) {
|
||||
|
||||
total, err := m.FindCount(ctx, builder, "id")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
builder = builder.Columns(authorizationRows)
|
||||
|
||||
if orderBy == "" {
|
||||
builder = builder.OrderBy("id DESC")
|
||||
} else {
|
||||
builder = builder.OrderBy(orderBy)
|
||||
}
|
||||
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, total, err
|
||||
}
|
||||
|
||||
var resp []*Authorization
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, total, nil
|
||||
default:
|
||||
return nil, total, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*Authorization, error) {
|
||||
|
||||
builder = builder.Columns(authorizationRows)
|
||||
|
||||
if preMinId > 0 {
|
||||
builder = builder.Where(" id < ? ", preMinId)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*Authorization
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*Authorization, error) {
|
||||
|
||||
builder = builder.Columns(authorizationRows)
|
||||
|
||||
if preMaxId > 0 {
|
||||
builder = builder.Where(" id > ? ", preMaxId)
|
||||
}
|
||||
|
||||
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp []*Authorization
|
||||
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
|
||||
|
||||
return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
return fn(ctx, session)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) SelectBuilder() squirrel.SelectBuilder {
|
||||
return squirrel.Select().From(m.table)
|
||||
}
|
||||
func (m *defaultAuthorizationModel) Delete(ctx context.Context, session sqlx.Session, id int64) error {
|
||||
data, err := m.FindOne(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
qncAuthorizationIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationIdPrefix, id)
|
||||
qncAuthorizationOrderIdKey := fmt.Sprintf("%s%v", cacheQncAuthorizationOrderIdPrefix, data.OrderId)
|
||||
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||
if session != nil {
|
||||
return session.ExecCtx(ctx, query, id)
|
||||
}
|
||||
return conn.ExecCtx(ctx, query, id)
|
||||
}, qncAuthorizationIdKey, qncAuthorizationOrderIdKey)
|
||||
return err
|
||||
}
|
||||
func (m *defaultAuthorizationModel) formatPrimary(primary interface{}) string {
|
||||
return fmt.Sprintf("%s%v", cacheQncAuthorizationIdPrefix, primary)
|
||||
}
|
||||
func (m *defaultAuthorizationModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", authorizationRows, m.table)
|
||||
return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo)
|
||||
}
|
||||
|
||||
func (m *defaultAuthorizationModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
@@ -46,3 +46,27 @@ const (
|
||||
QueryStateSuccess = "success"
|
||||
QueryStateProcessing = "processing"
|
||||
)
|
||||
|
||||
const (
|
||||
GrantTypeFace string = "face"
|
||||
)
|
||||
const (
|
||||
AuthorizationStatusPending = "pending"
|
||||
AuthorizationStatusSuccess = "success"
|
||||
AuthorizationStatusFailed = "failed"
|
||||
AuthorizationStatusExpired = "expired"
|
||||
AuthorizationStatusRevoked = "revoked"
|
||||
AuthorizationStatusRejected = "rejected"
|
||||
)
|
||||
|
||||
const (
|
||||
AuthorizationFaceStatusPending = "pending"
|
||||
AuthorizationFaceStatusSuccess = "success"
|
||||
AuthorizationFaceStatusFailed = "failed"
|
||||
)
|
||||
|
||||
const (
|
||||
AgentRealNameStatusPending = "pending"
|
||||
AgentRealNameStatusApproved = "approved"
|
||||
AgentRealNameStatusRejected = "rejected"
|
||||
)
|
||||
|
||||
110
common/jwt/jwtx_test.go
Normal file
110
common/jwt/jwtx_test.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package jwtx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestGenerateAndParseJwtToken(t *testing.T) {
|
||||
// 测试参数
|
||||
userId := int64(102)
|
||||
secret := "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA"
|
||||
expireTime := int64(2592000) // 1小时过期
|
||||
|
||||
// 生成token
|
||||
token, err := GenerateJwtToken(userId, secret, expireTime)
|
||||
if err != nil {
|
||||
t.Fatalf("生成JWT令牌失败: %v", err)
|
||||
}
|
||||
if token == "" {
|
||||
t.Fatal("生成的JWT令牌为空")
|
||||
}
|
||||
fmt.Println(token)
|
||||
// 解析token
|
||||
parsedUserId, err := ParseJwtToken(token, secret)
|
||||
if err != nil {
|
||||
t.Fatalf("解析JWT令牌失败: %v", err)
|
||||
}
|
||||
|
||||
// 验证解析出的userId是否正确
|
||||
if parsedUserId != userId {
|
||||
t.Errorf("解析出的userId不匹配: 期望 %d, 实际 %d", userId, parsedUserId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenExpiration(t *testing.T) {
|
||||
// 测试参数
|
||||
userId := int64(10086)
|
||||
secret := "test_secret_key"
|
||||
expireTime := int64(1) // 1秒过期
|
||||
|
||||
// 生成token
|
||||
token, err := GenerateJwtToken(userId, secret, expireTime)
|
||||
if err != nil {
|
||||
t.Fatalf("生成JWT令牌失败: %v", err)
|
||||
}
|
||||
|
||||
// 等待令牌过期
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// 解析已过期token
|
||||
_, err = ParseJwtToken(token, secret)
|
||||
if err == nil {
|
||||
t.Error("期望令牌过期错误,但没有发生错误")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidToken(t *testing.T) {
|
||||
secret := "test_secret_key"
|
||||
|
||||
// 测试无效token
|
||||
invalidToken := "invalid.token.string"
|
||||
_, err := ParseJwtToken(invalidToken, secret)
|
||||
if err == nil {
|
||||
t.Error("期望无效令牌错误,但没有发生错误")
|
||||
}
|
||||
|
||||
// 测试密钥不匹配
|
||||
userId := int64(10086)
|
||||
expireTime := int64(3600)
|
||||
token, _ := GenerateJwtToken(userId, "original_secret", expireTime)
|
||||
_, err = ParseJwtToken(token, "wrong_secret")
|
||||
if err == nil {
|
||||
t.Error("期望密钥不匹配错误,但没有发生错误")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserIdTypes(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
setupFn func() (string, string, int64)
|
||||
expected int64
|
||||
}{
|
||||
{
|
||||
name: "正常int64类型",
|
||||
setupFn: func() (string, string, int64) {
|
||||
userId := int64(10086)
|
||||
secret := "test_secret"
|
||||
expireTime := int64(3600)
|
||||
token, _ := GenerateJwtToken(userId, secret, expireTime)
|
||||
return token, secret, userId
|
||||
},
|
||||
expected: 10086,
|
||||
},
|
||||
// 其他类型在实际场景中通过手动修改token内容测试,这里省略
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
token, secret, expected := tc.setupFn()
|
||||
userId, err := ParseJwtToken(token, secret)
|
||||
if err != nil {
|
||||
t.Fatalf("解析失败: %v", err)
|
||||
}
|
||||
if userId != expected {
|
||||
t.Errorf("用户ID不匹配: 期望 %d, 实际 %d", expected, userId)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
163
deploy/script/README.md
Normal file
163
deploy/script/README.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# Go-Zero 代码生成工具
|
||||
|
||||
这是一个用于 Go-Zero 微服务项目的代码生成工具,支持生成数据库模型和 API 代码。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 数据库模型生成:支持生成 Go-Zero 风格的数据库模型代码
|
||||
- API 代码生成:支持生成 API 服务相关代码
|
||||
- 灵活的表名管理:支持通过命令行指定表名,无需修改配置文件
|
||||
- 配置文件支持:通过 config.json 配置数据库连接和表列表
|
||||
- 命令行参数:支持通过命令行参数覆盖配置文件设置
|
||||
|
||||
## 安装
|
||||
|
||||
确保你的系统已安装 Node.js(10.0+)。
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
cd deploy/script
|
||||
npm install
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 查看配置
|
||||
|
||||
```bash
|
||||
npm run config
|
||||
```
|
||||
|
||||
### 生成所有配置的表模型
|
||||
|
||||
```bash
|
||||
npm run model
|
||||
```
|
||||
|
||||
### 生成指定表的模型
|
||||
|
||||
```bash
|
||||
# 生成单个表
|
||||
npm run model:table agent
|
||||
|
||||
# 生成多个表(逗号分隔,不含空格)
|
||||
npm run model:tables agent,user,order
|
||||
|
||||
# 或者使用完整命令
|
||||
node codegen.js model --tables agent,user,order
|
||||
```
|
||||
|
||||
### 排除指定表
|
||||
|
||||
```bash
|
||||
# 从配置的表中排除某些表
|
||||
npm run model:exclude user,order
|
||||
|
||||
# 或者使用完整命令
|
||||
node codegen.js model --exclude user,order
|
||||
```
|
||||
|
||||
### 生成所有数据库表的模型
|
||||
|
||||
```bash
|
||||
npm run model:all
|
||||
|
||||
# 生成所有表但排除某些表
|
||||
node codegen.js model --all --exclude system_table,temp_table
|
||||
```
|
||||
|
||||
### 保存表配置
|
||||
|
||||
```bash
|
||||
# 生成指定表并保存到配置文件
|
||||
npm run model:save agent,user,order -- --save
|
||||
|
||||
# 或者使用完整命令
|
||||
node codegen.js model --tables agent,user,order --save
|
||||
```
|
||||
|
||||
### 生成 API 代码
|
||||
|
||||
```bash
|
||||
npm run api
|
||||
```
|
||||
|
||||
### 生成带样式的 API 代码
|
||||
|
||||
```bash
|
||||
npm run api:style
|
||||
```
|
||||
|
||||
### 查看帮助信息
|
||||
|
||||
```bash
|
||||
npm run help
|
||||
```
|
||||
|
||||
## 配置文件
|
||||
|
||||
所有配置都保存在`config.json`文件中,你可以编辑此文件来修改数据库连接信息和要生成的表列表:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": {
|
||||
"dbUrl": "user:password@tcp(host:port)/database",
|
||||
"outputDir": "./model",
|
||||
"templateDir": "../template",
|
||||
"targetDir": "../../app/user/model",
|
||||
"tables": ["table1", "table2"],
|
||||
"disabledTables": ["disabled_table1"]
|
||||
},
|
||||
"api": {
|
||||
"apiFile": "./app/user/cmd/api/desc/main.api",
|
||||
"outputDir": "./app/user/cmd/api",
|
||||
"templateDir": "./deploy/template",
|
||||
"useStyle": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 表名管理
|
||||
|
||||
本工具提供了多种方式来指定需要生成的表:
|
||||
|
||||
1. **配置文件指定**:在`config.json`的`tables`数组中列出要生成的表
|
||||
2. **命令行指定单个表**:使用`--table`参数指定单个表
|
||||
3. **命令行指定多个表**:使用`--tables`参数指定多个表(逗号分隔)
|
||||
4. **排除特定表**:使用`--exclude`参数排除特定表
|
||||
5. **生成所有表**:使用`--all`参数生成数据库中的所有表
|
||||
6. **保存到配置**:使用`--save`参数将当前指定的表保存到配置文件
|
||||
|
||||
这种灵活的表名管理方式使你可以根据需要随时调整要生成的表,而无需频繁修改配置文件。
|
||||
|
||||
## 高级用法
|
||||
|
||||
### 通过命令行参数覆盖配置
|
||||
|
||||
```bash
|
||||
# 使用不同的数据库连接
|
||||
node codegen.js model --db-url "user:pass@tcp(localhost:3306)/otherdb"
|
||||
|
||||
# 使用不同的API文件
|
||||
node codegen.js api --api ./other_api.api
|
||||
|
||||
# 指定输出目录
|
||||
node codegen.js api --dir ./output
|
||||
```
|
||||
|
||||
### 组合使用参数
|
||||
|
||||
```bash
|
||||
# 生成所有表但排除系统表,并使用自定义模板
|
||||
node codegen.js model --all --exclude system_log,system_user --template ./my-templates
|
||||
|
||||
# 生成指定表并保存到配置
|
||||
node codegen.js model --tables user,order,product --save
|
||||
```
|
||||
|
||||
## 脚本文件说明
|
||||
|
||||
- `codegen.js` - 统一入口脚本
|
||||
- `gen_models.js` - 模型生成脚本
|
||||
- `gen_api.js` - API 生成脚本
|
||||
- `config.json` - 配置文件
|
||||
444
deploy/script/codegen.js
Normal file
444
deploy/script/codegen.js
Normal file
@@ -0,0 +1,444 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 代码生成统一入口脚本
|
||||
* 整合了model生成和api生成功能
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { generateApi } = require('./gen_api');
|
||||
|
||||
// 读取配置文件
|
||||
const CONFIG_FILE = path.join(__dirname, 'config.json');
|
||||
let config = {};
|
||||
|
||||
try {
|
||||
if (fs.existsSync(CONFIG_FILE)) {
|
||||
const configContent = fs.readFileSync(CONFIG_FILE, 'utf8');
|
||||
config = JSON.parse(configContent);
|
||||
console.log('Configuration loaded from config.json');
|
||||
} else {
|
||||
console.log('config.json not found, using default settings');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading configuration:', error.message);
|
||||
console.log('Using default settings');
|
||||
}
|
||||
|
||||
// 默认数据库配置
|
||||
const modelConfig = config.model || {
|
||||
// 数据库连接信息
|
||||
dbUrl: 'qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc',
|
||||
// 输出目录
|
||||
outputDir: './model',
|
||||
// 模板目录
|
||||
templateDir: '../template',
|
||||
// 目标目录
|
||||
targetDir: '../../app/user/model',
|
||||
// 表名列表
|
||||
tables: [
|
||||
'agent',
|
||||
'agent_audit',
|
||||
'agent_real_name'
|
||||
],
|
||||
// 禁用的表名列表
|
||||
disabledTables: []
|
||||
};
|
||||
|
||||
// 默认API配置
|
||||
const apiConfig = config.api || {
|
||||
// API定义文件路径
|
||||
apiFile: './app/user/cmd/api/desc/main.api',
|
||||
// 输出目录
|
||||
outputDir: './app/user/cmd/api',
|
||||
// 模板目录
|
||||
templateDir: './deploy/template',
|
||||
// 是否使用样式
|
||||
useStyle: false
|
||||
};
|
||||
|
||||
/**
|
||||
* 将表名转换为驼峰命名法
|
||||
* @param {string} tableName 表名
|
||||
* @returns {string} 驼峰命名的表名
|
||||
*/
|
||||
function convertToCamelCase(tableName) {
|
||||
try {
|
||||
// 将表名按_分割,并将每个部分首字母大写
|
||||
const parts = tableName.split('_');
|
||||
let camelCase = '';
|
||||
for (const part of parts) {
|
||||
if (part.length > 0) {
|
||||
camelCase += part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
return camelCase;
|
||||
} catch (error) {
|
||||
console.error(`Error in convertToCamelCase for table: ${tableName}`);
|
||||
console.error(error.message);
|
||||
return tableName; // 出错时返回原表名
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保目录存在
|
||||
* @param {string} dirPath 目录路径
|
||||
*/
|
||||
function ensureDirectoryExists(dirPath) {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
console.log(`Creating directory: ${dirPath}`);
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为单个表生成模型
|
||||
* @param {string} table 表名
|
||||
* @param {object} config 配置信息
|
||||
*/
|
||||
function generateModelForTable(table, config) {
|
||||
try {
|
||||
console.log('=========================================');
|
||||
console.log(`Processing table: ${table}`);
|
||||
|
||||
// 生成模型
|
||||
console.log('Generating model...');
|
||||
const command = `goctl model mysql datasource -url="${config.dbUrl}" -table="${table}" -dir="${config.outputDir}" --home="${config.templateDir}" -cache=true --style=goZero`;
|
||||
console.log(`Running command: ${command}`);
|
||||
|
||||
execSync(command, { stdio: 'inherit' });
|
||||
|
||||
// 将表名转换为驼峰命名法
|
||||
const camelCaseName = convertToCamelCase(table);
|
||||
console.log(`Table name converted to: ${camelCaseName}`);
|
||||
|
||||
// 定义源文件和目标文件路径
|
||||
const sourceModelFile = path.join(config.outputDir, `${camelCaseName}Model.go`);
|
||||
const sourceModelGenFile = path.join(config.outputDir, `${camelCaseName}Model_gen.go`);
|
||||
const targetModelFile = path.join(config.targetDir, `${camelCaseName}Model.go`);
|
||||
const targetModelGenFile = path.join(config.targetDir, `${camelCaseName}Model_gen.go`);
|
||||
|
||||
console.log('Source files:');
|
||||
console.log(` - ${sourceModelFile}`);
|
||||
console.log(` - ${sourceModelGenFile}`);
|
||||
console.log('Target files:');
|
||||
console.log(` - ${targetModelFile}`);
|
||||
console.log(` - ${targetModelGenFile}`);
|
||||
|
||||
// 检查源文件是否存在并移动
|
||||
if (fs.existsSync(sourceModelFile)) {
|
||||
console.log(`Moving ${sourceModelFile} to ${targetModelFile}`);
|
||||
fs.copyFileSync(sourceModelFile, targetModelFile);
|
||||
fs.unlinkSync(sourceModelFile);
|
||||
} else {
|
||||
console.log(`WARNING: Source file not found: ${sourceModelFile}`);
|
||||
}
|
||||
|
||||
if (fs.existsSync(sourceModelGenFile)) {
|
||||
console.log(`Moving ${sourceModelGenFile} to ${targetModelGenFile}`);
|
||||
fs.copyFileSync(sourceModelGenFile, targetModelGenFile);
|
||||
fs.unlinkSync(sourceModelGenFile);
|
||||
} else {
|
||||
console.log(`WARNING: Source file not found: ${sourceModelGenFile}`);
|
||||
}
|
||||
|
||||
console.log(`Processing completed for table: ${table}`);
|
||||
} catch (error) {
|
||||
console.error(`ERROR processing table: ${table}`);
|
||||
console.error(error.message);
|
||||
console.error(error.stack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定表列表的模型
|
||||
* @param {string[]} tables 表名列表
|
||||
* @param {object} config 配置信息
|
||||
*/
|
||||
function generateModels(tables, config) {
|
||||
try {
|
||||
// 确保目录存在
|
||||
ensureDirectoryExists(config.outputDir);
|
||||
ensureDirectoryExists(config.targetDir);
|
||||
|
||||
if (tables.length === 0) {
|
||||
console.log('No tables specified for generation.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 为每个表生成模型
|
||||
for (const table of tables) {
|
||||
generateModelForTable(table, config);
|
||||
}
|
||||
|
||||
console.log('=========================================');
|
||||
console.log('All models generated successfully.');
|
||||
} catch (error) {
|
||||
console.error('ERROR in model generation:');
|
||||
console.error(error.message);
|
||||
console.error(error.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库获取所有表名
|
||||
* @param {string} dbUrl 数据库连接URL
|
||||
* @returns {Promise<string[]>} 表名列表
|
||||
*/
|
||||
async function getAllTablesFromDB(dbUrl) {
|
||||
try {
|
||||
// 解析数据库连接信息
|
||||
const dbName = dbUrl.split('/').pop().split('?')[0];
|
||||
console.log(`Fetching all tables from database: ${dbName}`);
|
||||
|
||||
// 这里需要实现从数据库获取所有表的逻辑
|
||||
// 由于需要依赖额外的库,这里只是示例
|
||||
// 实际实现可能需要使用mysql2或其他数据库客户端库
|
||||
|
||||
// 模拟返回一些表名
|
||||
return [
|
||||
'agent',
|
||||
'agent_audit',
|
||||
'agent_real_name',
|
||||
'agent_active_stat',
|
||||
'agent_closure',
|
||||
'agent_commission',
|
||||
'agent_commission_deduction',
|
||||
'agent_link',
|
||||
'agent_membership_config',
|
||||
'agent_membership_recharge_order',
|
||||
'agent_membership_user_config',
|
||||
'agent_order',
|
||||
'agent_platform_deduction',
|
||||
'agent_product_config',
|
||||
'agent_rewards',
|
||||
'agent_wallet',
|
||||
'agent_withdrawal',
|
||||
'feature',
|
||||
'global_notifications',
|
||||
'order',
|
||||
'product',
|
||||
'product_feature',
|
||||
'query',
|
||||
'user',
|
||||
'user_auth',
|
||||
'example',
|
||||
'authorization',
|
||||
'authorization_face'
|
||||
];
|
||||
} catch (error) {
|
||||
console.error('Error fetching tables from database:', error.message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示配置信息
|
||||
*/
|
||||
function showConfig() {
|
||||
console.log('=========================================');
|
||||
console.log('Current Configuration:');
|
||||
console.log('\nModel Configuration:');
|
||||
console.log(' Database URL:', modelConfig.dbUrl);
|
||||
console.log(' Output Directory:', modelConfig.outputDir);
|
||||
console.log(' Template Directory:', modelConfig.templateDir);
|
||||
console.log(' Target Directory:', modelConfig.targetDir);
|
||||
console.log(' Tables:');
|
||||
modelConfig.tables.forEach(table => console.log(` - ${table}`));
|
||||
|
||||
if (modelConfig.disabledTables && modelConfig.disabledTables.length > 0) {
|
||||
console.log(' Disabled Tables:');
|
||||
modelConfig.disabledTables.forEach(table => console.log(` - ${table}`));
|
||||
}
|
||||
|
||||
console.log('\nAPI Configuration:');
|
||||
console.log(' API File:', apiConfig.apiFile);
|
||||
console.log(' Output Directory:', apiConfig.outputDir);
|
||||
console.log(' Template Directory:', apiConfig.templateDir);
|
||||
console.log(' Use Style:', apiConfig.useStyle ? 'Yes' : 'No');
|
||||
console.log('=========================================');
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存配置到文件
|
||||
* @param {object} config 配置对象
|
||||
*/
|
||||
function saveConfig(config) {
|
||||
try {
|
||||
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 4), 'utf8');
|
||||
console.log('Configuration saved to config.json');
|
||||
} catch (error) {
|
||||
console.error('Error saving configuration:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示帮助信息
|
||||
*/
|
||||
function showHelp() {
|
||||
console.log('Usage: node codegen.js <command> [options]');
|
||||
console.log('Commands:');
|
||||
console.log(' model Generate database models');
|
||||
console.log(' api Generate API code');
|
||||
console.log(' config Show current configuration');
|
||||
console.log(' help Show this help message');
|
||||
console.log('');
|
||||
console.log('Model Options:');
|
||||
console.log(' --table <name> Generate model for specific table');
|
||||
console.log(' --tables <names> Generate models for specific tables (comma-separated)');
|
||||
console.log(' --exclude <names> Exclude specific tables (comma-separated)');
|
||||
console.log(' --all Generate models for all tables in database');
|
||||
console.log(' --db-url <url> Database connection URL');
|
||||
console.log(' --template <dir> Template directory');
|
||||
console.log(' --save Save specified tables to config.json');
|
||||
console.log('');
|
||||
console.log('API Options:');
|
||||
console.log(' --api <file> API definition file path');
|
||||
console.log(' --dir <dir> Output directory');
|
||||
console.log(' --template <dir> Template directory');
|
||||
console.log(' --style Use goZero style');
|
||||
console.log('');
|
||||
console.log('Configuration:');
|
||||
console.log(' Settings are loaded from config.json');
|
||||
console.log(' Command line options override config file settings');
|
||||
console.log('');
|
||||
console.log('Examples:');
|
||||
console.log(' node codegen.js model --table agent');
|
||||
console.log(' node codegen.js model --tables agent,user,order');
|
||||
console.log(' node codegen.js model --exclude user,order');
|
||||
console.log(' node codegen.js model --all --exclude system_table');
|
||||
console.log(' node codegen.js model --tables agent,user --save');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数
|
||||
*/
|
||||
async function main() {
|
||||
// 解析命令行参数
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0 || args[0] === 'help') {
|
||||
showHelp();
|
||||
}
|
||||
|
||||
const command = args[0];
|
||||
|
||||
// 显示配置信息
|
||||
if (command === 'config') {
|
||||
showConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理模型生成命令
|
||||
if (command === 'model') {
|
||||
const config = { ...modelConfig };
|
||||
let singleTable = null;
|
||||
let tablesToGenerate = [...config.tables];
|
||||
let excludeTables = [];
|
||||
let shouldSaveConfig = false;
|
||||
let generateAllTables = false;
|
||||
|
||||
// 处理其他参数
|
||||
for (let i = 1; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
|
||||
if (arg === '--table' && i + 1 < args.length) {
|
||||
singleTable = args[++i];
|
||||
tablesToGenerate = [singleTable];
|
||||
} else if (arg === '--tables' && i + 1 < args.length) {
|
||||
const tableList = args[++i].split(',').map(t => t.trim()).filter(t => t);
|
||||
tablesToGenerate = tableList;
|
||||
} else if (arg === '--exclude' && i + 1 < args.length) {
|
||||
excludeTables = args[++i].split(',').map(t => t.trim()).filter(t => t);
|
||||
} else if (arg === '--all') {
|
||||
generateAllTables = true;
|
||||
} else if (arg === '--db-url' && i + 1 < args.length) {
|
||||
config.dbUrl = args[++i];
|
||||
} else if (arg === '--template' && i + 1 < args.length) {
|
||||
config.templateDir = args[++i];
|
||||
} else if (arg === '--save') {
|
||||
shouldSaveConfig = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果指定了--all参数,获取所有表名
|
||||
if (generateAllTables) {
|
||||
tablesToGenerate = await getAllTablesFromDB(config.dbUrl);
|
||||
}
|
||||
|
||||
// 排除指定的表
|
||||
if (excludeTables.length > 0) {
|
||||
tablesToGenerate = tablesToGenerate.filter(table => !excludeTables.includes(table));
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
if (shouldSaveConfig) {
|
||||
const newConfig = { ...config };
|
||||
newConfig.tables = tablesToGenerate;
|
||||
|
||||
// 更新配置文件
|
||||
if (fs.existsSync(CONFIG_FILE)) {
|
||||
const existingConfig = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
||||
existingConfig.model = newConfig;
|
||||
saveConfig(existingConfig);
|
||||
} else {
|
||||
saveConfig({ model: newConfig, api: apiConfig });
|
||||
}
|
||||
}
|
||||
|
||||
// 生成单个表的模型或所有表的模型
|
||||
if (singleTable) {
|
||||
generateModelForTable(singleTable, config);
|
||||
} else {
|
||||
generateModels(tablesToGenerate, config);
|
||||
}
|
||||
}
|
||||
// 处理API生成命令
|
||||
else if (command === 'api') {
|
||||
const config = { ...apiConfig };
|
||||
|
||||
// 处理其他参数
|
||||
for (let i = 1; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
|
||||
if (arg === '--api' && i + 1 < args.length) {
|
||||
config.apiFile = args[++i];
|
||||
} else if (arg === '--dir' && i + 1 < args.length) {
|
||||
config.outputDir = args[++i];
|
||||
} else if (arg === '--template' && i + 1 < args.length) {
|
||||
config.templateDir = args[++i];
|
||||
} else if (arg === '--style') {
|
||||
config.useStyle = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 生成API代码
|
||||
generateApi(config);
|
||||
}
|
||||
else {
|
||||
console.error(`Unknown command: ${command}`);
|
||||
showHelp();
|
||||
}
|
||||
}
|
||||
|
||||
// 执行主函数
|
||||
if (require.main === module) {
|
||||
main().catch(err => {
|
||||
console.error('Error in main execution:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
// 导出函数,以便其他脚本可以调用
|
||||
module.exports = {
|
||||
generateModels,
|
||||
generateModelForTable,
|
||||
generateApi,
|
||||
showConfig,
|
||||
saveConfig,
|
||||
getAllTablesFromDB
|
||||
};
|
||||
46
deploy/script/config.json
Normal file
46
deploy/script/config.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"model": {
|
||||
"dbUrl": "qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc",
|
||||
"outputDir": "./model",
|
||||
"templateDir": "../template",
|
||||
"targetDir": "../../app/user/model",
|
||||
"tables": [
|
||||
"agent",
|
||||
"agent_audit",
|
||||
"agent_real_name"
|
||||
],
|
||||
"disabledTables": [
|
||||
"agent_active_stat",
|
||||
"agent_closure",
|
||||
"agent_commission",
|
||||
"agent_commission_deduction",
|
||||
"agent_link",
|
||||
"agent_membership_config",
|
||||
"agent_membership_recharge_order",
|
||||
"agent_membership_user_config",
|
||||
"agent_order",
|
||||
"agent_platform_deduction",
|
||||
"agent_product_config",
|
||||
"agent_rewards",
|
||||
"agent_wallet",
|
||||
"agent_withdrawal",
|
||||
"feature",
|
||||
"global_notifications",
|
||||
"order",
|
||||
"product",
|
||||
"product_feature",
|
||||
"query",
|
||||
"user",
|
||||
"user_auth",
|
||||
"example",
|
||||
"authorization",
|
||||
"authorization_face"
|
||||
]
|
||||
},
|
||||
"api": {
|
||||
"apiFile": "./app/user/cmd/api/desc/main.api",
|
||||
"outputDir": "./app/user/cmd/api",
|
||||
"templateDir": "./deploy/template",
|
||||
"useStyle": false
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
const (
|
||||
// 请替换为实际的数据库连接信息
|
||||
dbHost = "localhost"
|
||||
dbPort = "21001"
|
||||
dbUser = "qnc"
|
||||
dbPassword = "5vg67b3UNHu8"
|
||||
dbName = "qnc"
|
||||
// 请替换为实际的加密密钥
|
||||
secretKey = "ff83609b2b24fc73196aac3d3dfb874f"
|
||||
)
|
||||
|
||||
func RunEncryptMobile() {
|
||||
fmt.Println("开始加密手机号")
|
||||
// 连接数据库
|
||||
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
|
||||
dbUser, dbPassword, dbHost, dbPort, dbName)
|
||||
db := sqlx.NewMysql(dsn)
|
||||
|
||||
// 加密user表的mobile字段
|
||||
if err := encryptUserMobile(db); err != nil {
|
||||
log.Fatalf("加密user表mobile字段失败: %v", err)
|
||||
}
|
||||
|
||||
// 加密user_auth表的auth_key字段
|
||||
if err := encryptUserAuthKey(db); err != nil {
|
||||
log.Fatalf("加密user_auth表auth_key字段失败: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("加密完成!")
|
||||
}
|
||||
|
||||
func encryptUserMobile(db sqlx.SqlConn) error {
|
||||
// 查询所有未加密的手机号
|
||||
query := "SELECT id, mobile FROM user WHERE mobile IS NOT NULL AND mobile != ''"
|
||||
var rows []struct {
|
||||
ID int64 `db:"id"`
|
||||
Mobile string `db:"mobile"`
|
||||
}
|
||||
if err := db.QueryRows(&rows, query); err != nil {
|
||||
return fmt.Errorf("查询user表失败: %v", err)
|
||||
}
|
||||
|
||||
// 准备更新语句
|
||||
updateStmt := "UPDATE user SET mobile = ? WHERE id = ?"
|
||||
|
||||
// 处理每一行
|
||||
for _, row := range rows {
|
||||
// 加密手机号
|
||||
encryptedMobile, err := crypto.EncryptMobile(row.Mobile, secretKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("加密手机号失败: %v", err)
|
||||
}
|
||||
|
||||
// 更新数据库
|
||||
if _, err := db.Exec(updateStmt, encryptedMobile, row.ID); err != nil {
|
||||
return fmt.Errorf("更新user表失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func encryptUserAuthKey(db sqlx.SqlConn) error {
|
||||
// 查询所有需要加密的auth_key
|
||||
query := "SELECT id, auth_key FROM user_auth WHERE auth_type = 'app_mobile' AND auth_key IS NOT NULL AND auth_key != ''"
|
||||
var rows []struct {
|
||||
ID int64 `db:"id"`
|
||||
AuthKey string `db:"auth_key"`
|
||||
}
|
||||
if err := db.QueryRows(&rows, query); err != nil {
|
||||
return fmt.Errorf("查询user_auth表失败: %v", err)
|
||||
}
|
||||
|
||||
// 准备更新语句
|
||||
updateStmt := "UPDATE user_auth SET auth_key = ? WHERE id = ?"
|
||||
|
||||
// 处理每一行
|
||||
for _, row := range rows {
|
||||
// 加密auth_key
|
||||
encryptedAuthKey, err := crypto.EncryptMobile(row.AuthKey, secretKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("加密auth_key失败: %v", err)
|
||||
}
|
||||
|
||||
// 更新数据库
|
||||
if _, err := db.Exec(updateStmt, encryptedAuthKey, row.ID); err != nil {
|
||||
return fmt.Errorf("更新user_auth表失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
108
deploy/script/gen_api.js
Normal file
108
deploy/script/gen_api.js
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* API代码生成脚本
|
||||
* 功能等同于gen_api.ps1
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 配置信息
|
||||
const config = {
|
||||
// API定义文件路径
|
||||
apiFile: './app/user/cmd/api/desc/main.api',
|
||||
// 输出目录
|
||||
outputDir: './app/user/cmd/api',
|
||||
// 模板目录
|
||||
templateDir: './deploy/template'
|
||||
};
|
||||
|
||||
/**
|
||||
* 生成API代码
|
||||
* @param {object} options 选项
|
||||
* @param {string} options.apiFile API定义文件路径
|
||||
* @param {string} options.outputDir 输出目录
|
||||
* @param {string} options.templateDir 模板目录
|
||||
* @param {boolean} options.useStyle 是否使用样式
|
||||
*/
|
||||
function generateApi({ apiFile, outputDir, templateDir, useStyle = false }) {
|
||||
try {
|
||||
console.log('=========================================');
|
||||
console.log('Generating API code...');
|
||||
|
||||
// 构建命令
|
||||
let command = `goctl api go --api ${apiFile} --dir ${outputDir} --home ${templateDir}`;
|
||||
|
||||
// 如果需要使用样式
|
||||
if (useStyle) {
|
||||
command += ' --style=goZero';
|
||||
console.log('Using goZero style');
|
||||
}
|
||||
|
||||
console.log(`Running command: ${command}`);
|
||||
|
||||
// 执行命令
|
||||
execSync(command, { stdio: 'inherit' });
|
||||
|
||||
console.log('API code generation completed!');
|
||||
console.log('=========================================');
|
||||
} catch (error) {
|
||||
console.error('ERROR in API generation:');
|
||||
console.error(error.message);
|
||||
console.error(error.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数
|
||||
*/
|
||||
function main() {
|
||||
// 解析命令行参数
|
||||
const args = process.argv.slice(2);
|
||||
const options = {
|
||||
apiFile: config.apiFile,
|
||||
outputDir: config.outputDir,
|
||||
templateDir: config.templateDir,
|
||||
useStyle: false
|
||||
};
|
||||
|
||||
// 处理命令行参数
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
|
||||
if (arg === '--api' && i + 1 < args.length) {
|
||||
options.apiFile = args[++i];
|
||||
} else if (arg === '--dir' && i + 1 < args.length) {
|
||||
options.outputDir = args[++i];
|
||||
} else if (arg === '--template' && i + 1 < args.length) {
|
||||
options.templateDir = args[++i];
|
||||
} else if (arg === '--style') {
|
||||
options.useStyle = true;
|
||||
} else if (arg === '--help') {
|
||||
console.log('Usage: node gen_api.js [options]');
|
||||
console.log('Options:');
|
||||
console.log(' --api <file> API definition file path');
|
||||
console.log(' --dir <dir> Output directory');
|
||||
console.log(' --template <dir> Template directory');
|
||||
console.log(' --style Use goZero style');
|
||||
console.log(' --help Show this help message');
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成API代码
|
||||
generateApi(options);
|
||||
}
|
||||
|
||||
// 执行主函数
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
// 导出函数,以便其他脚本可以调用
|
||||
module.exports = {
|
||||
generateApi
|
||||
};
|
||||
172
deploy/script/gen_models.js
Normal file
172
deploy/script/gen_models.js
Normal file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* 数据库模型生成脚本
|
||||
* 功能等同于gen_models.ps1
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 配置信息
|
||||
const config = {
|
||||
// 数据库连接信息
|
||||
dbUrl: 'qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc',
|
||||
// 输出目录
|
||||
outputDir: './model',
|
||||
// 模板目录
|
||||
templateDir: '../template',
|
||||
// 目标目录
|
||||
targetDir: '../../app/user/model',
|
||||
// 表名列表
|
||||
tables: [
|
||||
'agent',
|
||||
// 'agent_active_stat',
|
||||
'agent_audit',
|
||||
'agent_real_name'
|
||||
// 'agent_closure',
|
||||
// 'agent_commission',
|
||||
// 'agent_commission_deduction',
|
||||
// 'agent_link',
|
||||
// 'agent_membership_config',
|
||||
// 'agent_membership_recharge_order',
|
||||
// 'agent_membership_user_config',
|
||||
// 'agent_order',
|
||||
// 'agent_platform_deduction',
|
||||
// 'agent_product_config',
|
||||
// 'agent_rewards',
|
||||
// 'agent_wallet',
|
||||
// 'agent_withdrawal',
|
||||
// 'feature',
|
||||
// 'global_notifications',
|
||||
// 'order',
|
||||
// 'product',
|
||||
// 'product_feature',
|
||||
// 'query',
|
||||
// 'user',
|
||||
// 'user_auth',
|
||||
// 'example',
|
||||
// 'authorization',
|
||||
// 'authorization_face'
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* 将表名转换为驼峰命名法
|
||||
* @param {string} tableName 表名
|
||||
* @returns {string} 驼峰命名的表名
|
||||
*/
|
||||
function convertToCamelCase(tableName) {
|
||||
try {
|
||||
// 将表名按_分割,并将每个部分首字母大写
|
||||
const parts = tableName.split('_');
|
||||
let camelCase = '';
|
||||
for (const part of parts) {
|
||||
if (part.length > 0) {
|
||||
camelCase += part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
return camelCase;
|
||||
} catch (error) {
|
||||
console.error(`Error in convertToCamelCase for table: ${tableName}`);
|
||||
console.error(error.message);
|
||||
return tableName; // 出错时返回原表名
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保目录存在
|
||||
* @param {string} dirPath 目录路径
|
||||
*/
|
||||
function ensureDirectoryExists(dirPath) {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
console.log(`Creating directory: ${dirPath}`);
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为单个表生成模型
|
||||
* @param {string} table 表名
|
||||
*/
|
||||
function generateModelForTable(table) {
|
||||
try {
|
||||
console.log('=========================================');
|
||||
console.log(`Processing table: ${table}`);
|
||||
|
||||
// 生成模型
|
||||
console.log('Generating model...');
|
||||
const command = `goctl model mysql datasource -url="${config.dbUrl}" -table="${table}" -dir="${config.outputDir}" --home="${config.templateDir}" -cache=true --style=goZero`;
|
||||
console.log(`Running command: ${command}`);
|
||||
|
||||
execSync(command, { stdio: 'inherit' });
|
||||
|
||||
// 将表名转换为驼峰命名法
|
||||
const camelCaseName = convertToCamelCase(table);
|
||||
console.log(`Table name converted to: ${camelCaseName}`);
|
||||
|
||||
// 定义源文件和目标文件路径
|
||||
const sourceModelFile = path.join(config.outputDir, `${camelCaseName}Model.go`);
|
||||
const sourceModelGenFile = path.join(config.outputDir, `${camelCaseName}Model_gen.go`);
|
||||
const targetModelFile = path.join(config.targetDir, `${camelCaseName}Model.go`);
|
||||
const targetModelGenFile = path.join(config.targetDir, `${camelCaseName}Model_gen.go`);
|
||||
|
||||
console.log('Source files:');
|
||||
console.log(` - ${sourceModelFile}`);
|
||||
console.log(` - ${sourceModelGenFile}`);
|
||||
console.log('Target files:');
|
||||
console.log(` - ${targetModelFile}`);
|
||||
console.log(` - ${targetModelGenFile}`);
|
||||
|
||||
// 检查源文件是否存在并移动
|
||||
if (fs.existsSync(sourceModelFile)) {
|
||||
console.log(`Moving ${sourceModelFile} to ${targetModelFile}`);
|
||||
fs.copyFileSync(sourceModelFile, targetModelFile);
|
||||
fs.unlinkSync(sourceModelFile);
|
||||
} else {
|
||||
console.log(`WARNING: Source file not found: ${sourceModelFile}`);
|
||||
}
|
||||
|
||||
if (fs.existsSync(sourceModelGenFile)) {
|
||||
console.log(`Moving ${sourceModelGenFile} to ${targetModelGenFile}`);
|
||||
fs.copyFileSync(sourceModelGenFile, targetModelGenFile);
|
||||
fs.unlinkSync(sourceModelGenFile);
|
||||
} else {
|
||||
console.log(`WARNING: Source file not found: ${sourceModelGenFile}`);
|
||||
}
|
||||
|
||||
console.log(`Processing completed for table: ${table}`);
|
||||
} catch (error) {
|
||||
console.error(`ERROR processing table: ${table}`);
|
||||
console.error(error.message);
|
||||
console.error(error.stack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数
|
||||
*/
|
||||
function main() {
|
||||
try {
|
||||
// 确保目录存在
|
||||
ensureDirectoryExists(config.outputDir);
|
||||
ensureDirectoryExists(config.targetDir);
|
||||
|
||||
// 为每个表生成模型
|
||||
for (const table of config.tables) {
|
||||
generateModelForTable(table);
|
||||
}
|
||||
|
||||
console.log('=========================================');
|
||||
console.log('Script execution completed.');
|
||||
} catch (error) {
|
||||
console.error('ERROR in main execution:');
|
||||
console.error(error.message);
|
||||
console.error(error.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 执行主函数
|
||||
main();
|
||||
@@ -1,21 +1,64 @@
|
||||
# 设置输出编码为UTF-8
|
||||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
# 数据库连接信息 - 修改了URL格式
|
||||
$DB_URL = "qnc:5vg67b3UNHu8@(127.0.0.1:21001)/qnc"
|
||||
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
|
||||
|
||||
# 启用详细输出和错误处理
|
||||
$ErrorActionPreference = "Stop"
|
||||
$VerbosePreference = "Continue"
|
||||
|
||||
# 检查并创建必要的目录
|
||||
if (-not (Test-Path "./model")) {
|
||||
Write-Output "Creating model directory..."
|
||||
New-Item -ItemType Directory -Path "./model" | Out-Null
|
||||
}
|
||||
|
||||
if (-not (Test-Path "../../app/user/model")) {
|
||||
Write-Output "Creating target directory..."
|
||||
New-Item -ItemType Directory -Path "../../app/user/model" -Force | Out-Null
|
||||
}
|
||||
|
||||
# 将表名转换为驼峰命名法的函数
|
||||
function ConvertToCamelCase {
|
||||
param (
|
||||
[string]$tableName
|
||||
)
|
||||
try {
|
||||
# 将表名按_分割,并将每个部分首字母大写
|
||||
$parts = $tableName -split '_'
|
||||
$camelCase = ""
|
||||
foreach ($part in $parts) {
|
||||
if ($part.Length -gt 0) {
|
||||
$camelCase += $part.Substring(0, 1).ToUpper() + $part.Substring(1).ToLower()
|
||||
}
|
||||
}
|
||||
return $camelCase
|
||||
}
|
||||
catch {
|
||||
Write-Output "Error in ConvertToCamelCase for table: $tableName"
|
||||
Write-Output $_.Exception.Message
|
||||
return $tableName # 出错时返回原表名
|
||||
}
|
||||
}
|
||||
|
||||
# 数据库连接信息
|
||||
$DB_URL = "qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc"
|
||||
$OUTPUT_DIR = "./model"
|
||||
$TEMPLATE_DIR = "../template"
|
||||
$TARGET_DIR = "../../app/user/model"
|
||||
|
||||
# 表名列表
|
||||
# 表名列表 - 每个元素后必须有逗号分隔
|
||||
$tables = @(
|
||||
# "agent",
|
||||
"agent",
|
||||
# "agent_active_stat",
|
||||
# "agent_audit",
|
||||
"agent_audit",
|
||||
"agent_real_name"
|
||||
# "agent_closure",
|
||||
# "agent_commission",
|
||||
# "agent_commission_deduction",
|
||||
# "agent_link",
|
||||
# "agent_membership_config",
|
||||
# "agent_membership_recharge_order"
|
||||
# "agent_membership_recharge_order",
|
||||
# "agent_membership_user_config",
|
||||
# "agent_order",
|
||||
# "agent_platform_deduction",
|
||||
@@ -29,12 +72,68 @@ $tables = @(
|
||||
# "product",
|
||||
# "product_feature",
|
||||
# "query",
|
||||
"user"
|
||||
# "user_auth"
|
||||
# "example"
|
||||
# "user",
|
||||
# "user_auth",
|
||||
# "example",
|
||||
# "authorization",
|
||||
# "authorization_face"
|
||||
)
|
||||
|
||||
# 为每个表生成模型
|
||||
foreach ($table in $tables) {
|
||||
goctl model mysql datasource -url="qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc" -table="$table" -dir="./model" --home="../template" -cache=true --style=goZero
|
||||
try {
|
||||
Write-Output "========================================="
|
||||
Write-Output "Processing table: $table"
|
||||
|
||||
# 生成模型
|
||||
Write-Output "Generating model..."
|
||||
$command = "goctl model mysql datasource -url=`"$DB_URL`" -table=`"$table`" -dir=`"$OUTPUT_DIR`" --home=`"$TEMPLATE_DIR`" -cache=true --style=goZero"
|
||||
Write-Output "Running command: $command"
|
||||
Invoke-Expression $command
|
||||
|
||||
# 将表名转换为驼峰命名法
|
||||
$camelCaseName = ConvertToCamelCase -tableName $table
|
||||
Write-Output "Table name converted to: $camelCaseName"
|
||||
|
||||
# 定义源文件和目标文件路径
|
||||
$sourceModelFile = "$OUTPUT_DIR/${camelCaseName}Model.go"
|
||||
$sourceModelGenFile = "$OUTPUT_DIR/${camelCaseName}Model_gen.go"
|
||||
$targetModelFile = "$TARGET_DIR/${camelCaseName}Model.go"
|
||||
$targetModelGenFile = "$TARGET_DIR/${camelCaseName}Model_gen.go"
|
||||
|
||||
Write-Output "Source files:"
|
||||
Write-Output " - $sourceModelFile"
|
||||
Write-Output " - $sourceModelGenFile"
|
||||
Write-Output "Target files:"
|
||||
Write-Output " - $targetModelFile"
|
||||
Write-Output " - $targetModelGenFile"
|
||||
|
||||
# 检查源文件是否存在
|
||||
if (-not (Test-Path $sourceModelFile)) {
|
||||
Write-Output "WARNING: Source file not found: $sourceModelFile"
|
||||
}
|
||||
if (-not (Test-Path $sourceModelGenFile)) {
|
||||
Write-Output "WARNING: Source file not found: $sourceModelGenFile"
|
||||
}
|
||||
|
||||
# 移动文件
|
||||
if (Test-Path $sourceModelFile) {
|
||||
Write-Output "Moving $sourceModelFile to $targetModelFile"
|
||||
Move-Item -Path $sourceModelFile -Destination $targetModelFile -Force
|
||||
}
|
||||
if (Test-Path $sourceModelGenFile) {
|
||||
Write-Output "Moving $sourceModelGenFile to $targetModelGenFile"
|
||||
Move-Item -Path $sourceModelGenFile -Destination $targetModelGenFile -Force
|
||||
}
|
||||
|
||||
Write-Output "Processing completed for table: $table"
|
||||
}
|
||||
catch {
|
||||
Write-Output "ERROR processing table: $table"
|
||||
Write-Output $_.Exception.Message
|
||||
Write-Output $_.ScriptStackTrace
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output "========================================="
|
||||
Write-Output "Script execution completed."
|
||||
|
||||
26
deploy/script/package.json
Normal file
26
deploy/script/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "qnc-codegen",
|
||||
"version": "1.0.0",
|
||||
"description": "代码生成工具 - Go-Zero微服务项目",
|
||||
"main": "codegen.js",
|
||||
"scripts": {
|
||||
"model": "node codegen.js model",
|
||||
"model:table": "node codegen.js model --table",
|
||||
"model:tables": "node codegen.js model --tables",
|
||||
"model:exclude": "node codegen.js model --exclude",
|
||||
"model:all": "node codegen.js model --all",
|
||||
"model:save": "node codegen.js model --tables",
|
||||
"model:save-exclude": "node codegen.js model --exclude",
|
||||
"api": "node codegen.js api",
|
||||
"api:style": "node codegen.js api --style",
|
||||
"config": "node codegen.js config",
|
||||
"help": "node codegen.js help"
|
||||
},
|
||||
"keywords": [
|
||||
"go-zero",
|
||||
"codegen",
|
||||
"microservice"
|
||||
],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
51
deploy/sql/agent_real_name.sql
Normal file
51
deploy/sql/agent_real_name.sql
Normal file
@@ -0,0 +1,51 @@
|
||||
-- 创建数据库(如果不存在)
|
||||
CREATE DATABASE IF NOT EXISTS `qnc_server` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
-- 使用数据库
|
||||
USE `qnc_server`;
|
||||
|
||||
-- 创建代理实名认证表
|
||||
CREATE TABLE `agent_real_name` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`agent_id` bigint NOT NULL COMMENT '代理ID',
|
||||
`name` varchar(255) NOT NULL COMMENT '实名姓名',
|
||||
`card_id` varchar(255) NOT NULL COMMENT '身份证号',
|
||||
`status` enum(
|
||||
'pending',
|
||||
'approved',
|
||||
'rejected'
|
||||
) NOT NULL DEFAULT 'pending' COMMENT '认证状态(认证中、通过、拒绝)',
|
||||
`del_state` tinyint NOT NULL DEFAULT '0' COMMENT '删除状态',
|
||||
`version` bigint NOT NULL DEFAULT '0' COMMENT '版本号',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`approve_time` datetime DEFAULT NULL COMMENT '认证通过时间',
|
||||
`reject_time` datetime DEFAULT NULL COMMENT '认证拒绝时间',
|
||||
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `unique_agent_id` (`agent_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_card_id` (`card_id`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代理实名认证表';
|
||||
|
||||
-- 添加表注释
|
||||
ALTER TABLE `agent_real_name` COMMENT = '代理实名认证表';
|
||||
|
||||
-- 添加字段注释
|
||||
ALTER TABLE `agent_real_name`
|
||||
MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
MODIFY COLUMN `agent_id` bigint NOT NULL COMMENT '代理ID',
|
||||
MODIFY COLUMN `name` varchar(255) NOT NULL COMMENT '实名姓名',
|
||||
MODIFY COLUMN `card_id` varchar(255) NOT NULL COMMENT '身份证号',
|
||||
MODIFY COLUMN `status` enum(
|
||||
'pending',
|
||||
'approved',
|
||||
'rejected'
|
||||
) NOT NULL DEFAULT 'pending' COMMENT '认证状态(认证中、通过、拒绝)',
|
||||
MODIFY COLUMN `del_state` tinyint NOT NULL DEFAULT '0' COMMENT '删除状态',
|
||||
MODIFY COLUMN `version` bigint NOT NULL DEFAULT '0' COMMENT '版本号',
|
||||
MODIFY COLUMN `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
MODIFY COLUMN `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
MODIFY COLUMN `approve_time` datetime DEFAULT NULL COMMENT '认证通过时间',
|
||||
MODIFY COLUMN `reject_time` datetime DEFAULT NULL COMMENT '认证拒绝时间',
|
||||
MODIFY COLUMN `delete_time` datetime DEFAULT NULL COMMENT '删除时间';
|
||||
21
go.mod
21
go.mod
@@ -4,17 +4,22 @@ go 1.22.4
|
||||
|
||||
require (
|
||||
github.com/Masterminds/squirrel v1.5.4
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10
|
||||
github.com/alibabacloud-go/cloudauth-20190307/v4 v4.6.0
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11
|
||||
github.com/alibabacloud-go/dysmsapi-20170525/v3 v3.0.6
|
||||
github.com/alibabacloud-go/tea v1.2.2
|
||||
github.com/alibabacloud-go/tea-rpc v1.1.7
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.7
|
||||
github.com/aliyun/credentials-go v1.4.6
|
||||
github.com/bytedance/sonic v1.13.0
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/go-playground/validator/v10 v10.22.1
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hibiken/asynq v0.25.0
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/redis/go-redis/v9 v9.7.0
|
||||
github.com/shopspring/decimal v1.4.0
|
||||
github.com/smartwalle/alipay/v3 v3.2.23
|
||||
github.com/sony/sonyflake v1.2.0
|
||||
@@ -30,10 +35,14 @@ require (
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
|
||||
github.com/alibabacloud-go/debug v1.0.1 // indirect
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
|
||||
github.com/alibabacloud-go/tea-utils v1.3.1 // indirect
|
||||
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
|
||||
github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 // indirect
|
||||
github.com/alibabacloud-go/tea-fileform v1.1.1 // indirect
|
||||
github.com/alibabacloud-go/tea-oss-sdk v1.1.5 // indirect
|
||||
github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect
|
||||
github.com/alibabacloud-go/tea-rpc-utils v1.1.1 // indirect
|
||||
github.com/alibabacloud-go/tea-utils v1.4.5 // indirect
|
||||
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
|
||||
github.com/aliyun/credentials-go v1.3.10 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
@@ -60,7 +69,6 @@ require (
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -81,14 +89,13 @@ require (
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.7.0 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/samber/lo v1.49.1 // indirect
|
||||
github.com/smartwalle/ncrypto v1.0.4 // indirect
|
||||
github.com/smartwalle/ngx v1.0.9 // indirect
|
||||
github.com/smartwalle/nsign v1.0.9 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
|
||||
39
go.sum
39
go.sum
@@ -13,15 +13,18 @@ github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do2
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 h1:zE8vH9C7JiZLNJJQ5OwjU9mSi4T9ef9u3BURT6LCLC8=
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5/go.mod h1:tWnyE9AjF8J8qqLk645oUmVUnFybApTQWklQmi5tY6g=
|
||||
github.com/alibabacloud-go/cloudauth-20190307/v4 v4.6.0 h1:msLjhAxXUrGVPCmVIz2SYMdERk4UDlMxaDTFt10GnXE=
|
||||
github.com/alibabacloud-go/cloudauth-20190307/v4 v4.6.0/go.mod h1:XqPmDB32MyabzEsJBBzcFfRudijqlyyPyKBGRSbErYM=
|
||||
github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY=
|
||||
github.com/alibabacloud-go/darabonba-array v0.1.0/go.mod h1:BLKxr0brnggqOJPqT09DFJ8g3fsDshapUD3C3aOEFaI=
|
||||
github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC2NG0Ax+GpOM5gtupki31XE=
|
||||
github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8=
|
||||
github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
|
||||
github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.0/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.2/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10 h1:GEYkMApgpKEVDn6z12DcH1EGYpDYRB8JxsazM4Rywak=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10/go.mod h1:26a14FGhZVELuz2cc2AolvW4RHmIO3/HRwsdHhaIPDE=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11 h1:GkVQ9AphMCmgAYakcTpH/OuFz0mQUypO/JiOvo0wgVA=
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11/go.mod h1:wHxkgZT1ClZdcwEVP/pDgYK/9HucsnCfMipmJgCz4xY=
|
||||
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
|
||||
github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ=
|
||||
github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo=
|
||||
@@ -35,19 +38,35 @@ github.com/alibabacloud-go/dysmsapi-20170525/v3 v3.0.6/go.mod h1:UWpcGrWwTbES9QW
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
|
||||
github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.1 h1:ujGErJjG8ncRW6XtBBMphzHTvCxn4DjrVw4m04HsS28=
|
||||
github.com/alibabacloud-go/openapi-util v0.1.1/go.mod h1:/UehBSE2cf1gYT43GV4E+RxTdLRzURImCYY0aRmlXpw=
|
||||
github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 h1:L0TIjr9Qh/SLVc1yPhFkcB9+9SbCNK/jPq4ZKB5zmnc=
|
||||
github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1/go.mod h1:EKxBRDLcMzwl4VLF/1WJwlByZZECJawPXUvinKMsTTs=
|
||||
github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg=
|
||||
github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.10/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
|
||||
github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
|
||||
github.com/alibabacloud-go/tea v1.2.2 h1:aTsR6Rl3ANWPfqeQugPglfurloyBJY85eFy7Gc1+8oU=
|
||||
github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
|
||||
github.com/alibabacloud-go/tea-utils v1.3.1 h1:iWQeRzRheqCMuiF3+XkfybB3kTgUXkXX+JMrqfLeB2I=
|
||||
github.com/alibabacloud-go/tea-fileform v1.1.1 h1:1YG6erAP3joQ0XdCXYIotuD7zyOM6qCR49xkp5FZDeU=
|
||||
github.com/alibabacloud-go/tea-fileform v1.1.1/go.mod h1:ZeCV91o4ISmxidd686f0ebdS5EDHWU+vW+TkjLhrsFE=
|
||||
github.com/alibabacloud-go/tea-oss-sdk v1.1.5 h1:CFUFcqanvBaoGN/CyTHUZrVNtFZd1WTjem46m0HTTV0=
|
||||
github.com/alibabacloud-go/tea-oss-sdk v1.1.5/go.mod h1:5fhlKMa/kWRJNgPYRt+5qSg3UidRvNbf9Z2bI8Dp5/s=
|
||||
github.com/alibabacloud-go/tea-oss-utils v1.1.0 h1:y65crjjcZ2Pbb6UZtC2deuIZHDVTS3IaDWE7M9nVLRc=
|
||||
github.com/alibabacloud-go/tea-oss-utils v1.1.0/go.mod h1:PFCF12e9yEKyBUIn7X1IrF/pNjvxgkHy0CgxX4+xRuY=
|
||||
github.com/alibabacloud-go/tea-rpc v1.1.7 h1:txkbgBb5DUBwQKqw9I+JY49eXGvvoAUSU2jnCr7Di+I=
|
||||
github.com/alibabacloud-go/tea-rpc v1.1.7/go.mod h1:FU//dNbNYv1jSz1BGj6Sc3Co0IrbWsCnPiB/e1YnvgQ=
|
||||
github.com/alibabacloud-go/tea-rpc-utils v1.1.1 h1:pthm/FnXIqXMNXXJhocvfEkbzUhHD8oWa10BlCHVKMw=
|
||||
github.com/alibabacloud-go/tea-rpc-utils v1.1.1/go.mod h1:V5HdNi6Xdn0JMpgVhQ19vsFAS51tydr7BqcJtuXH1Yw=
|
||||
github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
|
||||
github.com/alibabacloud-go/tea-utils v1.3.4/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
|
||||
github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA=
|
||||
github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.0/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.3/go.mod h1:sj1PbjPodAVTqGTA3olprfeeqqmwD0A5OQz94o9EuXQ=
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4=
|
||||
@@ -64,8 +83,9 @@ github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQ
|
||||
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
|
||||
github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
|
||||
github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM=
|
||||
github.com/aliyun/credentials-go v1.3.10 h1:45Xxrae/evfzQL9V10zL3xX31eqgLWEaIdCoPipOEQA=
|
||||
github.com/aliyun/credentials-go v1.3.10/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
|
||||
github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
|
||||
github.com/aliyun/credentials-go v1.4.6 h1:CG8rc/nxCNKfXbZWpWDzI9GjF4Tuu3Es14qT8Y0ClOk=
|
||||
github.com/aliyun/credentials-go v1.4.6/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -261,8 +281,6 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
|
||||
github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/smartwalle/alipay/v3 v3.2.23 h1:i1VwJeu70EmwpsXXz6GZZnMAtRx5MTfn2dPoql/L3zE=
|
||||
@@ -298,9 +316,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
@@ -460,10 +478,9 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
178
pkg/core/aliyun/cloudauth/client.go
Normal file
178
pkg/core/aliyun/cloudauth/client.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package cloudauth
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
cloudauth "github.com/alibabacloud-go/cloudauth-20190307/v4/client"
|
||||
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||||
util "github.com/alibabacloud-go/tea-utils/v2/service"
|
||||
|
||||
"github.com/alibabacloud-go/tea/tea"
|
||||
"github.com/aliyun/credentials-go/credentials"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CloudAuthClient struct {
|
||||
Client *cloudauth.Client
|
||||
Config *CloudAuthConfig
|
||||
}
|
||||
|
||||
type CloudAuthConfig struct {
|
||||
AccessKeyId string
|
||||
AccessKeySecret string
|
||||
Endpoint string
|
||||
SceneId int64
|
||||
ReturnUrl string
|
||||
}
|
||||
type InitFaceVerifyResp struct {
|
||||
CertifyId string
|
||||
CertifyUrl string
|
||||
}
|
||||
type DescribeFaceVerifyResp struct {
|
||||
Passed bool
|
||||
}
|
||||
|
||||
// InitFaceVerifyRequest 封装初始化人脸认证所需参数
|
||||
type InitFaceVerifyParam struct {
|
||||
OuterOrderNo string
|
||||
CertName string
|
||||
CertNo string
|
||||
MetaInfo string
|
||||
}
|
||||
|
||||
// NewCloudAuthClient 创建阿里云人脸认证客户端
|
||||
func NewCloudAuthClient(cloudAuthconfig CloudAuthConfig) (*CloudAuthClient, error) {
|
||||
// 使用AK 初始化Credentials Client。
|
||||
credentialsConfig := new(credentials.Config).
|
||||
// 凭证类型。
|
||||
SetType("access_key").
|
||||
// 设置为AccessKey ID值。
|
||||
SetAccessKeyId(cloudAuthconfig.AccessKeyId).
|
||||
// 设置为AccessKey Secret值。
|
||||
SetAccessKeySecret(cloudAuthconfig.AccessKeySecret)
|
||||
credentialClient, _err := credentials.NewCredential(credentialsConfig)
|
||||
if _err != nil {
|
||||
panic(_err)
|
||||
}
|
||||
|
||||
ecsConfig := &openapi.Config{}
|
||||
// 配置云产品服务接入地址(endpoint)。
|
||||
ecsConfig.Endpoint = tea.String(cloudAuthconfig.Endpoint)
|
||||
// 使用Credentials配置凭证。
|
||||
ecsConfig.Credential = credentialClient
|
||||
|
||||
// 创建客户端
|
||||
client, err := cloudauth.NewClient(ecsConfig)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("创建阿里云人脸认证客户端失败: %v", err))
|
||||
}
|
||||
|
||||
return &CloudAuthClient{
|
||||
Client: client,
|
||||
Config: &CloudAuthConfig{
|
||||
AccessKeyId: cloudAuthconfig.AccessKeyId,
|
||||
AccessKeySecret: cloudAuthconfig.AccessKeySecret,
|
||||
Endpoint: cloudAuthconfig.Endpoint,
|
||||
SceneId: cloudAuthconfig.SceneId,
|
||||
ReturnUrl: cloudAuthconfig.ReturnUrl,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InitFaceVerify 初始化人脸认证
|
||||
func (c *CloudAuthClient) InitFaceVerify(param InitFaceVerifyParam) (*InitFaceVerifyResp, error) {
|
||||
request := &cloudauth.InitFaceVerifyRequest{
|
||||
SceneId: tea.Int64(c.Config.SceneId),
|
||||
OuterOrderNo: tea.String(param.OuterOrderNo),
|
||||
ProductCode: tea.String("ID_PRO"),
|
||||
Model: tea.String("LIVENESS"),
|
||||
CertType: tea.String("IDENTITY_CARD"),
|
||||
CertName: tea.String(param.CertName),
|
||||
CertNo: tea.String(param.CertNo),
|
||||
MetaInfo: tea.String(param.MetaInfo),
|
||||
ReturnUrl: tea.String(c.Config.ReturnUrl),
|
||||
}
|
||||
|
||||
runtime := &util.RuntimeOptions{
|
||||
ReadTimeout: tea.Int(10000),
|
||||
ConnectTimeout: tea.Int(5000),
|
||||
}
|
||||
|
||||
response, err := c.Client.InitFaceVerifyWithOptions(request, runtime)
|
||||
if err != nil {
|
||||
if sdkErr, ok := err.(*tea.SDKError); ok {
|
||||
logx.Errorf("认证初始化失败: %s, 建议: %s",
|
||||
tea.StringValue(sdkErr.Message),
|
||||
getRecommendFromError(sdkErr))
|
||||
return nil, fmt.Errorf("认证初始化失败: %s", tea.StringValue(sdkErr.Message))
|
||||
}
|
||||
logx.Errorf("认证初始化失败: %v", err)
|
||||
return nil, fmt.Errorf("认证初始化失败: %v", err)
|
||||
}
|
||||
|
||||
if tea.StringValue(response.Body.Code) != "200" {
|
||||
logx.Errorf("认证初始化失败: %s", tea.StringValue(response.Body.Message))
|
||||
return nil, fmt.Errorf("认证初始化失败: %s", tea.StringValue(response.Body.Message))
|
||||
}
|
||||
|
||||
return &InitFaceVerifyResp{
|
||||
CertifyId: tea.StringValue(response.Body.ResultObject.CertifyId),
|
||||
CertifyUrl: tea.StringValue(response.Body.ResultObject.CertifyUrl),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DescribeFaceVerify 获取认证结果
|
||||
func (c *CloudAuthClient) DescribeFaceVerify(certifyId string) (*DescribeFaceVerifyResp, error) {
|
||||
request := &cloudauth.DescribeFaceVerifyRequest{
|
||||
SceneId: tea.Int64(c.Config.SceneId),
|
||||
CertifyId: tea.String(certifyId),
|
||||
}
|
||||
|
||||
runtime := &util.RuntimeOptions{
|
||||
ReadTimeout: tea.Int(10000),
|
||||
ConnectTimeout: tea.Int(5000),
|
||||
}
|
||||
response, err := c.Client.DescribeFaceVerifyWithOptions(request, runtime)
|
||||
if err != nil {
|
||||
logx.Errorf("获取认证结果失败: %v", err)
|
||||
return nil, fmt.Errorf("获取认证结果失败: %v", err)
|
||||
}
|
||||
|
||||
if tea.StringValue(response.Body.Code) != "200" {
|
||||
logx.Errorf("获取认证结果失败: %s", tea.StringValue(response.Body.Message))
|
||||
return nil, fmt.Errorf("获取认证结果失败: %s", tea.StringValue(response.Body.Message))
|
||||
}
|
||||
var passed bool
|
||||
var passedStr = tea.StringValue(response.Body.ResultObject.Passed)
|
||||
|
||||
switch passedStr {
|
||||
case "T":
|
||||
passed = true
|
||||
case "F":
|
||||
passed = false
|
||||
default:
|
||||
passed = false
|
||||
}
|
||||
return &DescribeFaceVerifyResp{
|
||||
Passed: passed,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 从SDK错误中获取推荐信息
|
||||
func getRecommendFromError(err *tea.SDKError) string {
|
||||
if err == nil || err.Data == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var data map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(tea.StringValue(err.Data)), &data); err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if recommend, ok := data["Recommend"].(string); ok {
|
||||
return recommend
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
31
pkg/lzkit/crypto/crypto_test.go
Normal file
31
pkg/lzkit/crypto/crypto_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAesEncryptDecrypt(t *testing.T) {
|
||||
keyHex := "ff83609b2b24fc73196aac3d3dfb874f"
|
||||
key, decodeErr := hex.DecodeString(keyHex)
|
||||
if decodeErr != nil {
|
||||
t.Fatalf("key decode error: %v", decodeErr)
|
||||
}
|
||||
|
||||
plainText := "45212220000827423X"
|
||||
|
||||
cipherText, err := AesEncrypt([]byte(plainText), key)
|
||||
if err != nil {
|
||||
t.Fatalf("AesEncrypt error: %v", err)
|
||||
}
|
||||
fmt.Println(cipherText)
|
||||
decrypted, err := AesDecrypt(cipherText, key)
|
||||
if err != nil {
|
||||
t.Fatalf("AesDecrypt error: %v", err)
|
||||
}
|
||||
|
||||
if string(decrypted) != plainText {
|
||||
t.Errorf("AesDecrypt result not match, got: %s, want: %s", string(decrypted), plainText)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user