手机号适配双端
This commit is contained in:
parent
a738c711de
commit
301a80447d
@ -35,7 +35,6 @@ type ProductConfig {
|
|||||||
PriceRangeMin float64 `json:"price_range_min"`
|
PriceRangeMin float64 `json:"price_range_min"`
|
||||||
PriceRangeMax float64 `json:"price_range_max"`
|
PriceRangeMax float64 `json:"price_range_max"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@server (
|
@server (
|
||||||
prefix: api/v1/agent
|
prefix: api/v1/agent
|
||||||
group: agent
|
group: agent
|
||||||
@ -46,6 +45,16 @@ service main {
|
|||||||
@handler GetAgentInfo
|
@handler GetAgentInfo
|
||||||
get /info returns (AgentInfoResp)
|
get /info returns (AgentInfoResp)
|
||||||
|
|
||||||
|
@handler GetAgentRevenueInfo
|
||||||
|
get /revenue (GetAgentRevenueInfoReq) returns (GetAgentRevenueInfoResp)
|
||||||
|
}
|
||||||
|
@server (
|
||||||
|
prefix: api/v1/agent
|
||||||
|
group: agent
|
||||||
|
jwt: JwtAuth
|
||||||
|
middleware: UserAuthInterceptor
|
||||||
|
)
|
||||||
|
service main {
|
||||||
// 查询代理申请状态
|
// 查询代理申请状态
|
||||||
@handler GetAgentAuditStatus
|
@handler GetAgentAuditStatus
|
||||||
get /audit/status returns (AgentAuditStatusResp)
|
get /audit/status returns (AgentAuditStatusResp)
|
||||||
@ -169,6 +178,8 @@ type (
|
|||||||
prefix: api/v1/agent
|
prefix: api/v1/agent
|
||||||
group: agent
|
group: agent
|
||||||
jwt: JwtAuth
|
jwt: JwtAuth
|
||||||
|
middleware: UserAuthInterceptor
|
||||||
|
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
@handler GetAgentMembershipProductConfig
|
@handler GetAgentMembershipProductConfig
|
||||||
@ -204,11 +215,10 @@ type (
|
|||||||
prefix: api/v1/agent
|
prefix: api/v1/agent
|
||||||
group: agent
|
group: agent
|
||||||
jwt: JwtAuth
|
jwt: JwtAuth
|
||||||
|
middleware: UserAuthInterceptor
|
||||||
|
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
@handler GetAgentRevenueInfo
|
|
||||||
get /revenue (GetAgentRevenueInfoReq) returns (GetAgentRevenueInfoResp)
|
|
||||||
|
|
||||||
@handler GetAgentCommission
|
@handler GetAgentCommission
|
||||||
get /commission (GetCommissionReq) returns (GetCommissionResp)
|
get /commission (GetCommissionReq) returns (GetCommissionResp)
|
||||||
|
|
||||||
@ -327,6 +337,8 @@ type (
|
|||||||
@server (
|
@server (
|
||||||
prefix: api/v1/agent
|
prefix: api/v1/agent
|
||||||
group: agent
|
group: agent
|
||||||
|
middleware: AuthInterceptor
|
||||||
|
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
// 提交代理申请
|
// 提交代理申请
|
||||||
|
@ -30,7 +30,8 @@ service main {
|
|||||||
prefix: api/v1
|
prefix: api/v1
|
||||||
group: pay
|
group: pay
|
||||||
jwt: JwtAuth
|
jwt: JwtAuth
|
||||||
middleware: SourceInterceptor
|
middleware: UserAuthInterceptor
|
||||||
|
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
// 支付
|
// 支付
|
||||||
|
@ -26,6 +26,8 @@ type Product {
|
|||||||
prefix: api/v1/product
|
prefix: api/v1/product
|
||||||
group: product
|
group: product
|
||||||
jwt: JwtAuth
|
jwt: JwtAuth
|
||||||
|
middleware: UserAuthInterceptor
|
||||||
|
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
@handler GetProductByID
|
@handler GetProductByID
|
||||||
|
@ -70,6 +70,8 @@ type (
|
|||||||
prefix: api/v1
|
prefix: api/v1
|
||||||
group: query
|
group: query
|
||||||
jwt: JwtAuth
|
jwt: JwtAuth
|
||||||
|
middleware: UserAuthInterceptor
|
||||||
|
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
@doc "query service"
|
@doc "query service"
|
||||||
@ -81,6 +83,8 @@ service main {
|
|||||||
prefix: api/v1
|
prefix: api/v1
|
||||||
group: query
|
group: query
|
||||||
jwt: JwtAuth
|
jwt: JwtAuth
|
||||||
|
middleware: UserAuthInterceptor
|
||||||
|
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
@doc "获取查询临时订单"
|
@doc "获取查询临时订单"
|
||||||
|
@ -14,6 +14,7 @@ type User {
|
|||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
Mobile string `json:"mobile"`
|
Mobile string `json:"mobile"`
|
||||||
NickName string `json:"nickName"`
|
NickName string `json:"nickName"`
|
||||||
|
UserType int64 `json:"userType"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//no need login
|
//no need login
|
||||||
@ -22,22 +23,10 @@ type User {
|
|||||||
group: user
|
group: user
|
||||||
)
|
)
|
||||||
service main {
|
service main {
|
||||||
@doc "register"
|
|
||||||
@handler register
|
|
||||||
post /user/register (RegisterReq) returns (RegisterResp)
|
|
||||||
|
|
||||||
@doc "mobile login"
|
|
||||||
@handler mobileLogin
|
|
||||||
post /user/mobileLogin (MobileLoginReq) returns (MobileLoginResp)
|
|
||||||
|
|
||||||
@doc "mobile code login"
|
@doc "mobile code login"
|
||||||
@handler mobileCodeLogin
|
@handler mobileCodeLogin
|
||||||
post /user/mobileCodeLogin (MobileCodeLoginReq) returns (MobileCodeLoginResp)
|
post /user/mobileCodeLogin (MobileCodeLoginReq) returns (MobileCodeLoginResp)
|
||||||
|
|
||||||
@doc "agent mobile code login"
|
|
||||||
@handler agentMobileCodeLogin
|
|
||||||
post /user/agent_mobile_code_login (MobileCodeLoginReq) returns (MobileCodeLoginResp)
|
|
||||||
|
|
||||||
@doc "wechat mini auth"
|
@doc "wechat mini auth"
|
||||||
@handler wxMiniAuth
|
@handler wxMiniAuth
|
||||||
post /user/wxMiniAuth (WXMiniAuthReq) returns (WXMiniAuthResp)
|
post /user/wxMiniAuth (WXMiniAuthReq) returns (WXMiniAuthResp)
|
||||||
@ -47,31 +36,6 @@ service main {
|
|||||||
post /user/wxh5Auth (WXH5AuthReq) returns (WXH5AuthResp)
|
post /user/wxh5Auth (WXH5AuthReq) returns (WXH5AuthResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
|
||||||
RegisterReq {
|
|
||||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
|
||||||
Password string `json:"password" validate:"required,min=11,max=11,password"`
|
|
||||||
Code string `json:"code" validate:"required"`
|
|
||||||
}
|
|
||||||
RegisterResp {
|
|
||||||
AccessToken string `json:"accessToken"`
|
|
||||||
AccessExpire int64 `json:"accessExpire"`
|
|
||||||
RefreshAfter int64 `json:"refreshAfter"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
MobileLoginReq {
|
|
||||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
|
||||||
Password string `json:"password" validate:"required"`
|
|
||||||
}
|
|
||||||
MobileLoginResp {
|
|
||||||
AccessToken string `json:"accessToken"`
|
|
||||||
AccessExpire int64 `json:"accessExpire"`
|
|
||||||
RefreshAfter int64 `json:"refreshAfter"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
MobileCodeLoginReq {
|
MobileCodeLoginReq {
|
||||||
Mobile string `json:"mobile"`
|
Mobile string `json:"mobile"`
|
||||||
@ -107,6 +71,16 @@ type (
|
|||||||
RefreshAfter int64 `json:"refreshAfter"`
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@server (
|
||||||
|
prefix: api/v1
|
||||||
|
group: user
|
||||||
|
middleware: AuthInterceptor
|
||||||
|
)
|
||||||
|
service main {
|
||||||
|
@doc "绑定手机号"
|
||||||
|
@handler bindMobile
|
||||||
|
post /user/bindMobile (BindMobileReq) returns (BindMobileResp)
|
||||||
|
}
|
||||||
|
|
||||||
//need login
|
//need login
|
||||||
@server (
|
@server (
|
||||||
@ -125,10 +99,6 @@ service main {
|
|||||||
|
|
||||||
@handler cancelOut
|
@handler cancelOut
|
||||||
post /user/cancelOut
|
post /user/cancelOut
|
||||||
|
|
||||||
@doc "绑定手机号"
|
|
||||||
@handler bindMobile
|
|
||||||
post /user/bindMobile (BindMobileReq) returns (BindMobileResp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -141,6 +111,9 @@ type (
|
|||||||
Code string `json:"code" validate:"required"`
|
Code string `json:"code" validate:"required"`
|
||||||
}
|
}
|
||||||
BindMobileResp {
|
BindMobileResp {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -515,6 +515,25 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/info",
|
||||||
|
Handler: agent.GetAgentInfoHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/revenue",
|
||||||
|
Handler: agent.GetAgentRevenueInfoHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
|
rest.WithPrefix("/api/v1/agent"),
|
||||||
|
)
|
||||||
|
|
||||||
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.UserAuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
@ -526,11 +545,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/generating_link",
|
Path: "/generating_link",
|
||||||
Handler: agent.GeneratingLinkHandler(serverCtx),
|
Handler: agent.GeneratingLinkHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/info",
|
|
||||||
Handler: agent.GetAgentInfoHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/product_config",
|
Path: "/product_config",
|
||||||
@ -551,12 +565,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/subordinate/list",
|
Path: "/subordinate/list",
|
||||||
Handler: agent.GetAgentSubordinateListHandler(serverCtx),
|
Handler: agent.GetAgentSubordinateListHandler(serverCtx),
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
|
),
|
||||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
rest.WithPrefix("/api/v1/agent"),
|
rest.WithPrefix("/api/v1/agent"),
|
||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.UserAuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
@ -568,12 +585,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/membership/user_config",
|
Path: "/membership/user_config",
|
||||||
Handler: agent.GetAgentMembershipProductConfigHandler(serverCtx),
|
Handler: agent.GetAgentMembershipProductConfigHandler(serverCtx),
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
|
),
|
||||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
rest.WithPrefix("/api/v1/agent"),
|
rest.WithPrefix("/api/v1/agent"),
|
||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.UserAuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
@ -585,11 +605,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/membership/activate",
|
Path: "/membership/activate",
|
||||||
Handler: agent.ActivateAgentMembershipHandler(serverCtx),
|
Handler: agent.ActivateAgentMembershipHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/revenue",
|
|
||||||
Handler: agent.GetAgentRevenueInfoHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/rewards",
|
Path: "/rewards",
|
||||||
@ -605,12 +620,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/withdrawal",
|
Path: "/withdrawal",
|
||||||
Handler: agent.AgentWithdrawalHandler(serverCtx),
|
Handler: agent.AgentWithdrawalHandler(serverCtx),
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
|
),
|
||||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
rest.WithPrefix("/api/v1/agent"),
|
rest.WithPrefix("/api/v1/agent"),
|
||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
@ -622,7 +640,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/link",
|
Path: "/link",
|
||||||
Handler: agent.GetLinkDataHandler(serverCtx),
|
Handler: agent.GetLinkDataHandler(serverCtx),
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
|
),
|
||||||
rest.WithPrefix("/api/v1/agent"),
|
rest.WithPrefix("/api/v1/agent"),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -690,7 +709,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
rest.WithMiddlewares(
|
rest.WithMiddlewares(
|
||||||
[]rest.Middleware{serverCtx.SourceInterceptor},
|
[]rest.Middleware{serverCtx.UserAuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
@ -714,6 +733,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.UserAuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
@ -725,7 +746,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/en/:product_en",
|
Path: "/en/:product_en",
|
||||||
Handler: product.GetProductByEnHandler(serverCtx),
|
Handler: product.GetProductByEnHandler(serverCtx),
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
|
),
|
||||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
rest.WithPrefix("/api/v1/product"),
|
rest.WithPrefix("/api/v1/product"),
|
||||||
)
|
)
|
||||||
@ -762,6 +784,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.UserAuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
// query service
|
// query service
|
||||||
@ -769,12 +793,15 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/query/service/:product",
|
Path: "/query/service/:product",
|
||||||
Handler: query.QueryServiceHandler(serverCtx),
|
Handler: query.QueryServiceHandler(serverCtx),
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
|
),
|
||||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
rest.WithPrefix("/api/v1"),
|
rest.WithPrefix("/api/v1"),
|
||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.UserAuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
// 生成分享链接
|
// 生成分享链接
|
||||||
@ -818,7 +845,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/query/update_data",
|
Path: "/query/update_data",
|
||||||
Handler: query.UpdateQueryDataHandler(serverCtx),
|
Handler: query.UpdateQueryDataHandler(serverCtx),
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
|
),
|
||||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
rest.WithPrefix("/api/v1"),
|
rest.WithPrefix("/api/v1"),
|
||||||
)
|
)
|
||||||
@ -848,30 +876,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
|
||||||
// agent mobile code login
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/user/agent_mobile_code_login",
|
|
||||||
Handler: user.AgentMobileCodeLoginHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
// mobile code login
|
// mobile code login
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/user/mobileCodeLogin",
|
Path: "/user/mobileCodeLogin",
|
||||||
Handler: user.MobileCodeLoginHandler(serverCtx),
|
Handler: user.MobileCodeLoginHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
// mobile login
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/user/mobileLogin",
|
|
||||||
Handler: user.MobileLoginHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// register
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/user/register",
|
|
||||||
Handler: user.RegisterHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
// wechat mini auth
|
// wechat mini auth
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
@ -889,6 +899,8 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
|
rest.WithMiddlewares(
|
||||||
|
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
// 绑定手机号
|
// 绑定手机号
|
||||||
@ -896,6 +908,13 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/user/bindMobile",
|
Path: "/user/bindMobile",
|
||||||
Handler: user.BindMobileHandler(serverCtx),
|
Handler: user.BindMobileHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
}...,
|
||||||
|
),
|
||||||
|
rest.WithPrefix("/api/v1"),
|
||||||
|
)
|
||||||
|
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/user/cancelOut",
|
Path: "/user/cancelOut",
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"tydata-server/app/main/api/internal/logic/user"
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
|
||||||
"tydata-server/app/main/api/internal/types"
|
|
||||||
"tydata-server/common/result"
|
|
||||||
"tydata-server/pkg/lzkit/validator"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AgentMobileCodeLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var req types.MobileCodeLoginReq
|
|
||||||
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 := user.NewAgentMobileCodeLoginLogic(r.Context(), svcCtx)
|
|
||||||
resp, err := l.AgentMobileCodeLogin(&req)
|
|
||||||
result.HttpResult(r, w, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"tydata-server/app/main/api/internal/logic/user"
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
|
||||||
"tydata-server/app/main/api/internal/types"
|
|
||||||
"tydata-server/common/result"
|
|
||||||
"tydata-server/pkg/lzkit/validator"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
|
||||||
)
|
|
||||||
|
|
||||||
func MobileLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var req types.MobileLoginReq
|
|
||||||
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 := user.NewMobileLoginLogic(r.Context(), svcCtx)
|
|
||||||
resp, err := l.MobileLogin(&req)
|
|
||||||
result.HttpResult(r, w, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"tydata-server/app/main/api/internal/logic/user"
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
|
||||||
"tydata-server/app/main/api/internal/types"
|
|
||||||
"tydata-server/common/result"
|
|
||||||
"tydata-server/pkg/lzkit/validator"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
|
||||||
)
|
|
||||||
|
|
||||||
func RegisterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var req types.RegisterReq
|
|
||||||
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 := user.NewRegisterLogic(r.Context(), svcCtx)
|
|
||||||
resp, err := l.Register(&req)
|
|
||||||
result.HttpResult(r, w, resp, err)
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
"tydata-server/app/main/api/internal/svc"
|
||||||
"tydata-server/app/main/api/internal/types"
|
"tydata-server/app/main/api/internal/types"
|
||||||
|
"tydata-server/app/main/model"
|
||||||
jwtx "tydata-server/common/jwt"
|
jwtx "tydata-server/common/jwt"
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
"tydata-server/pkg/lzkit/crypto"
|
||||||
@ -71,7 +72,14 @@ func (l *AdminLoginLogic) AdminLogin(req *types.AdminLoginReq) (resp *types.Admi
|
|||||||
// 5. 生成token
|
// 5. 生成token
|
||||||
refreshToken := l.svcCtx.Config.JwtAuth.RefreshAfter
|
refreshToken := l.svcCtx.Config.JwtAuth.RefreshAfter
|
||||||
expiresAt := l.svcCtx.Config.JwtAuth.AccessExpire
|
expiresAt := l.svcCtx.Config.JwtAuth.AccessExpire
|
||||||
token, err := jwtx.GenerateJwtToken(user.Id, l.svcCtx.Config.JwtAuth.AccessSecret, expiresAt)
|
claims := jwtx.JwtClaims{
|
||||||
|
UserId: user.Id,
|
||||||
|
AgentId: 0,
|
||||||
|
Platform: model.PlatformAdmin,
|
||||||
|
UserType: model.UserTypeAdmin,
|
||||||
|
IsAgent: model.AgentStatusNo,
|
||||||
|
}
|
||||||
|
token, err := jwtx.GenerateJwtToken(claims, l.svcCtx.Config.JwtAuth.AccessSecret, expiresAt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("生成token失败"), "用户登录, 生成token失败, 用户名: %s", req.Username)
|
return nil, errors.Wrapf(xerr.NewErrMsg("生成token失败"), "用户登录, 生成token失败, 用户名: %s", req.Username)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
"tydata-server/app/main/model"
|
"tydata-server/app/main/model"
|
||||||
jwtx "tydata-server/common/jwt"
|
"tydata-server/common/ctxdata"
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
"tydata-server/pkg/lzkit/crypto"
|
||||||
|
|
||||||
@ -35,6 +35,10 @@ func NewApplyForAgentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *App
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *types.AgentApplyResp, err error) {
|
func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *types.AgentApplyResp, err error) {
|
||||||
|
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||||||
|
if err != nil && !errors.Is(err, ctxdata.ErrNoInCtx) {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, %v", err)
|
||||||
|
}
|
||||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||||
encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey)
|
encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -63,29 +67,20 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
|
|||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 读取数据库获取用户失败, mobile: %s, err: %+v", encryptedMobile, err)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 读取数据库获取用户失败, mobile: %s, err: %+v", encryptedMobile, err)
|
||||||
}
|
}
|
||||||
if user == nil {
|
if user == nil {
|
||||||
user = &model.User{Mobile: sql.NullString{String: encryptedMobile, Valid: true}}
|
userID, err = l.svcCtx.UserService.RegisterUser(l.ctx, encryptedMobile)
|
||||||
// if len(main.Nickname) == 0 {
|
if err != nil {
|
||||||
// main.Nickname = encryptedMobile
|
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 注册用户失败: %+v", err)
|
||||||
// }
|
|
||||||
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(transCtx, session, user)
|
|
||||||
if userInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 数据库插入新用户失败, mobile%s, err: %+v", encryptedMobile, userInsertErr)
|
|
||||||
}
|
}
|
||||||
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
} else {
|
||||||
if lastInsertIdErr != nil {
|
if claims != nil && claims.UserType == model.UserTypeTemp {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 获取新用户ID失败, err:%+v, main:%+v", lastInsertIdErr, user)
|
// 临时用户,转为正式用户
|
||||||
}
|
err = l.svcCtx.UserService.TempUserBindUser(l.ctx, session, user.Id)
|
||||||
user.Id = lastId
|
if err != nil {
|
||||||
userID = lastId
|
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 注册用户失败: %+v", err)
|
||||||
userAuth := new(model.UserAuth)
|
|
||||||
userAuth.UserId = lastId
|
|
||||||
userAuth.AuthKey = encryptedMobile
|
|
||||||
userAuth.AuthType = model.UserAuthTypeAgentDirect
|
|
||||||
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(transCtx, session, userAuth); userAuthInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 数据库插入用户认证失败, err:%+v", userAuthInsertErr)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
userID = user.Id
|
userID = user.Id
|
||||||
|
}
|
||||||
|
|
||||||
// 使用SelectBuilder构建查询,查找符合user_id的记录并按创建时间降序排序获取最新一条
|
// 使用SelectBuilder构建查询,查找符合user_id的记录并按创建时间降序排序获取最新一条
|
||||||
builder := l.svcCtx.AgentAuditModel.SelectBuilder().Where("user_id = ?", user.Id).OrderBy("create_time DESC").Limit(1)
|
builder := l.svcCtx.AgentAuditModel.SelectBuilder().Where("user_id = ?", user.Id).OrderBy("create_time DESC").Limit(1)
|
||||||
@ -113,23 +108,12 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
|
|||||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 保存代理审核信息失败: %v", insetAgentAuditErr)
|
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 保存代理审核信息失败: %v", insetAgentAuditErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
//agentAuditID, _ := agentAuditInsert.LastInsertId()
|
|
||||||
//agentAuditRow, findAgentAuditModelErr := l.svcCtx.AgentAuditModel.FindOne(l.ctx, agentAuditID)
|
|
||||||
//if findAgentAuditModelErr != nil {
|
|
||||||
// return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 查找代理审核信息失败: %v", insetAgentAuditErr)
|
|
||||||
//}
|
|
||||||
//agentAuditRow.Status = 1
|
|
||||||
//updateAgentAuditErr := l.svcCtx.AgentAuditModel.UpdateWithVersion(transCtx, session, agentAuditRow)
|
|
||||||
//if updateAgentAuditErr != nil {
|
|
||||||
// return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 通过代理审核失败: %+v", updateAgentAuditErr)
|
|
||||||
//}
|
|
||||||
|
|
||||||
// 新增代理
|
// 新增代理
|
||||||
var agentModel model.Agent
|
var agentModel model.Agent
|
||||||
agentModel.Mobile = agentAudit.Mobile
|
agentModel.Mobile = agentAudit.Mobile
|
||||||
agentModel.Region = agentAudit.Region
|
agentModel.Region = agentAudit.Region
|
||||||
agentModel.LevelName = model.AgentLeveNameNormal
|
|
||||||
agentModel.UserId = agentAudit.UserId
|
agentModel.UserId = agentAudit.UserId
|
||||||
|
agentModel.LevelName = model.AgentLeveNameNormal
|
||||||
agentModelInsert, insertAgentModelErr := l.svcCtx.AgentModel.Insert(transCtx, session, &agentModel)
|
agentModelInsert, insertAgentModelErr := l.svcCtx.AgentModel.Insert(transCtx, session, &agentModel)
|
||||||
if insertAgentModelErr != nil {
|
if insertAgentModelErr != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 新增代理失败: %+v", insertAgentModelErr)
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 新增代理失败: %+v", insertAgentModelErr)
|
||||||
@ -169,9 +153,9 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
|
|||||||
if transErr != nil {
|
if transErr != nil {
|
||||||
return nil, transErr
|
return nil, transErr
|
||||||
}
|
}
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理申请, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前时间戳
|
// 获取当前时间戳
|
||||||
|
@ -31,9 +31,31 @@ func NewGetAgentRevenueInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *GetAgentRevenueInfoLogic) GetAgentRevenueInfo(req *types.GetAgentRevenueInfoReq) (resp *types.GetAgentRevenueInfoResp, err error) {
|
func (l *GetAgentRevenueInfoLogic) GetAgentRevenueInfo(req *types.GetAgentRevenueInfoReq) (resp *types.GetAgentRevenueInfoResp, err error) {
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理奖励, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息, %v", err)
|
||||||
|
}
|
||||||
|
userID := claims.UserId
|
||||||
|
userType := claims.UserType
|
||||||
|
if userType == model.UserTypeTemp {
|
||||||
|
return &types.GetAgentRevenueInfoResp{
|
||||||
|
Balance: 0,
|
||||||
|
TotalEarnings: 0,
|
||||||
|
FrozenBalance: 0,
|
||||||
|
DirectPush: types.DirectPushReport{
|
||||||
|
TotalCommission: 0,
|
||||||
|
TotalReport: 0,
|
||||||
|
Today: types.TimeRangeReport{},
|
||||||
|
Last7D: types.TimeRangeReport{},
|
||||||
|
Last30D: types.TimeRangeReport{},
|
||||||
|
},
|
||||||
|
ActiveReward: types.ActiveReward{
|
||||||
|
TotalReward: 0,
|
||||||
|
Today: types.ActiveRewardData{},
|
||||||
|
Last7D: types.ActiveRewardData{},
|
||||||
|
Last30D: types.ActiveRewardData{},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"tydata-server/app/main/api/internal/service"
|
"tydata-server/app/main/api/internal/service"
|
||||||
"tydata-server/common/ctxdata"
|
"tydata-server/common/ctxdata"
|
||||||
jwtx "tydata-server/common/jwt"
|
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
"tydata-server/pkg/lzkit/crypto"
|
||||||
"tydata-server/pkg/lzkit/validator"
|
"tydata-server/pkg/lzkit/validator"
|
||||||
@ -125,8 +124,8 @@ func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*t
|
|||||||
if cacheDataErr != nil {
|
if cacheDataErr != nil {
|
||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,8 +185,8 @@ func (l *QueryServiceLogic) ProcessHomeServiceLogic(req *types.QueryServiceReq)
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,8 +246,8 @@ func (l *QueryServiceLogic) ProcessRiskAssessmentLogic(req *types.QueryServiceRe
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,8 +306,8 @@ func (l *QueryServiceLogic) ProcessCompanyInfoLogic(req *types.QueryServiceReq)
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,8 +367,8 @@ func (l *QueryServiceLogic) ProcessRentalInfoLogic(req *types.QueryServiceReq) (
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,8 +428,8 @@ func (l *QueryServiceLogic) ProcessPreLoanBackgroundCheckLogic(req *types.QueryS
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,8 +488,8 @@ func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceR
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1393,30 +1392,32 @@ func (l *QueryServiceLogic) CacheData(params map[string]interface{}, Product str
|
|||||||
// 3. 其他情况返回未登录错误
|
// 3. 其他情况返回未登录错误
|
||||||
func (l *QueryServiceLogic) GetOrCreateUser() (int64, error) {
|
func (l *QueryServiceLogic) GetOrCreateUser() (int64, error) {
|
||||||
// 尝试获取用户ID
|
// 尝试获取用户ID
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
return userID, nil // 已有用户ID,直接返回
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果不是未登录错误,说明是其他错误,直接返回
|
|
||||||
if !ctxdata.IsNoUserIdError(err) {
|
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
userID := claims.UserId
|
||||||
|
return userID, nil
|
||||||
|
|
||||||
// 检查是否是代理查询或APP请求
|
// // 如果不是未登录错误,说明是其他错误,直接返回
|
||||||
isAgentQuery := false
|
// if !ctxdata.IsNoUserIdError(err) {
|
||||||
if agentID, ok := l.ctx.Value("agentIdentifier").(string); ok && agentID != "" {
|
// return 0, err
|
||||||
isAgentQuery = true
|
// }
|
||||||
}
|
|
||||||
if app, ok := l.ctx.Value("app").(bool); ok && app {
|
|
||||||
isAgentQuery = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果不是代理查询或APP请求,返回未登录错误
|
// // 检查是否是代理查询或APP请求
|
||||||
if !isAgentQuery {
|
// isAgentQuery := false
|
||||||
return 0, ctxdata.ErrNoUserIdInCtx
|
// if agentID, ok := l.ctx.Value("agentIdentifier").(string); ok && agentID != "" {
|
||||||
}
|
// isAgentQuery = true
|
||||||
|
// }
|
||||||
|
// if app, ok := l.ctx.Value("app").(bool); ok && app {
|
||||||
|
// isAgentQuery = true
|
||||||
|
// }
|
||||||
|
|
||||||
// 创建新用户
|
// // 如果不是代理查询或APP请求,返回未登录错误
|
||||||
return l.svcCtx.UserService.RegisterUUIDUser(l.ctx)
|
// if !isAgentQuery {
|
||||||
|
// return 0, ctxdata.ErrNoUserIdInCtx
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 创建新用户
|
||||||
|
// return l.svcCtx.UserService.RegisterUUIDUser(l.ctx)
|
||||||
}
|
}
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
|
||||||
"tydata-server/app/main/api/internal/types"
|
|
||||||
"tydata-server/app/main/model"
|
|
||||||
jwtx "tydata-server/common/jwt"
|
|
||||||
"tydata-server/common/xerr"
|
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AgentMobileCodeLoginLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAgentMobileCodeLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AgentMobileCodeLoginLogic {
|
|
||||||
return &AgentMobileCodeLoginLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *AgentMobileCodeLoginLogic) AgentMobileCodeLogin(req *types.MobileCodeLoginReq) (resp *types.MobileCodeLoginResp, err error) {
|
|
||||||
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", "query", encryptedMobile)
|
|
||||||
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, redis.Nil) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "手机登录, 验证码过期")
|
|
||||||
}
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取验证码redis缓存失败, err: %+v", err)
|
|
||||||
}
|
|
||||||
if cacheCode != req.Code {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "手机登录, 验证码不正确")
|
|
||||||
}
|
|
||||||
|
|
||||||
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
|
|
||||||
if findUserErr != nil && findUserErr != model.ErrNotFound {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile: %s, err: %+v", encryptedMobile, err)
|
|
||||||
}
|
|
||||||
if user == nil {
|
|
||||||
user = &model.User{Mobile: sql.NullString{String: encryptedMobile, Valid: true}}
|
|
||||||
// if len(main.Nickname) == 0 {
|
|
||||||
// main.Nickname = ""
|
|
||||||
// }
|
|
||||||
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
||||||
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(ctx, session, user)
|
|
||||||
if userInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入新用户失败, mobile%s, err: %+v", encryptedMobile, err)
|
|
||||||
}
|
|
||||||
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
|
||||||
if lastInsertIdErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 获取新用户ID失败, err:%+v, main:%+v", lastInsertIdErr, user)
|
|
||||||
}
|
|
||||||
user.Id = lastId
|
|
||||||
|
|
||||||
userAuth := new(model.UserAuth)
|
|
||||||
userAuth.UserId = lastId
|
|
||||||
userAuth.AuthKey = encryptedMobile
|
|
||||||
userAuth.AuthType = model.UserAuthTypeH5Mobile
|
|
||||||
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(ctx, session, userAuth); userAuthInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入用户认证失败, err:%+v", userAuthInsertErr)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); transErr != nil {
|
|
||||||
return nil, transErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(user.Id, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
|
||||||
if generaErr != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", user.Id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前时间戳
|
|
||||||
now := time.Now().Unix()
|
|
||||||
return &types.MobileCodeLoginResp{
|
|
||||||
AccessToken: token,
|
|
||||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
|
||||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
"tydata-server/app/main/api/internal/svc"
|
||||||
"tydata-server/app/main/api/internal/types"
|
"tydata-server/app/main/api/internal/types"
|
||||||
@ -15,7 +16,6 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BindMobileLogic struct {
|
type BindMobileLogic struct {
|
||||||
@ -33,22 +33,15 @@ func NewBindMobileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BindMo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *BindMobileLogic) BindMobile(req *types.BindMobileReq) (resp *types.BindMobileResp, err error) {
|
func (l *BindMobileLogic) BindMobile(req *types.BindMobileReq) (resp *types.BindMobileResp, err error) {
|
||||||
userID, getUserIdErr := ctxdata.GetUidFromCtx(l.ctx)
|
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||||||
if getUserIdErr != nil {
|
if err != nil && !errors.Is(err, ctxdata.ErrNoInCtx) {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, %v", getUserIdErr)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, %v", err)
|
||||||
}
|
}
|
||||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||||
encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey)
|
encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, 加密手机号失败: %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, 加密手机号失败: %v", err)
|
||||||
}
|
}
|
||||||
user, err := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
|
|
||||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "绑定手机号, %v", err)
|
|
||||||
}
|
|
||||||
if user != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("该手机号已绑定"), "绑定手机号, %v", err)
|
|
||||||
}
|
|
||||||
// 检查手机号是否在一分钟内已发送过验证码
|
// 检查手机号是否在一分钟内已发送过验证码
|
||||||
redisKey := fmt.Sprintf("%s:%s", "bindMobile", encryptedMobile)
|
redisKey := fmt.Sprintf("%s:%s", "bindMobile", encryptedMobile)
|
||||||
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
|
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
|
||||||
@ -61,44 +54,38 @@ func (l *BindMobileLogic) BindMobile(req *types.BindMobileReq) (resp *types.Bind
|
|||||||
if cacheCode != req.Code {
|
if cacheCode != req.Code {
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "手机登录, 验证码不正确: %s", encryptedMobile)
|
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "手机登录, 验证码不正确: %s", encryptedMobile)
|
||||||
}
|
}
|
||||||
|
var userID int64
|
||||||
userModel, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
|
user, err := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "绑定手机号, %v", err)
|
|
||||||
}
|
|
||||||
if userModel.Mobile.Valid && userModel.Mobile.String != "" {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("账号已绑定手机号,无法再次绑定"), "绑定手机号, %v", err)
|
|
||||||
}
|
|
||||||
userAuthModel, err := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, userID, model.UserAuthTypeH5Mobile)
|
|
||||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "绑定手机号, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "绑定手机号, %v", err)
|
||||||
}
|
}
|
||||||
if userAuthModel != nil {
|
if user != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("账号已绑定手机号,无法再次绑定"), "绑定手机号, %v", err)
|
// 进行平台绑定
|
||||||
|
if claims != nil {
|
||||||
|
if claims.UserType == model.UserTypeTemp {
|
||||||
|
err = l.svcCtx.UserService.TempUserBindUser(l.ctx, nil, user.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, 临时用户绑定用户失败: %+v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userID = user.Id
|
||||||
|
} else {
|
||||||
|
// 创建账号,并绑定手机号
|
||||||
|
userID, err = l.svcCtx.UserService.RegisterUser(l.ctx, encryptedMobile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, 注册用户失败: %+v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var userAuth model.UserAuth
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
userAuth.UserId = userID
|
|
||||||
userAuth.AuthType = model.UserAuthTypeH5Mobile
|
|
||||||
userAuth.AuthKey = encryptedMobile
|
|
||||||
transErr := l.svcCtx.UserAuthModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
||||||
_, err = l.svcCtx.UserAuthModel.Insert(ctx, session, &userAuth)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "绑定手机号, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, 生成token失败: %+v", err)
|
||||||
}
|
}
|
||||||
userModel.Mobile = sql.NullString{
|
now := time.Now().Unix()
|
||||||
String: encryptedMobile,
|
return &types.BindMobileResp{
|
||||||
Valid: true,
|
AccessToken: token,
|
||||||
}
|
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
_, err = l.svcCtx.UserModel.Update(l.ctx, session, userModel)
|
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||||
if err != nil {
|
}, nil
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "绑定手机号, %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if transErr != nil {
|
|
||||||
return nil, transErr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.BindMobileResp{}, nil
|
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,23 @@ func NewDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DetailLogi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *DetailLogic) Detail() (resp *types.UserInfoResp, err error) {
|
func (l *DetailLogic) Detail() (resp *types.UserInfoResp, err error) {
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userID := claims.UserId
|
||||||
|
userType := claims.UserType
|
||||||
|
if userType == model.UserTypeTemp {
|
||||||
|
return &types.UserInfoResp{
|
||||||
|
UserInfo: types.User{
|
||||||
|
Id: userID,
|
||||||
|
UserType: userType,
|
||||||
|
Mobile: "",
|
||||||
|
NickName: "",
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
|
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, model.ErrNotFound) {
|
if errors.Is(err, model.ErrNotFound) {
|
||||||
@ -46,12 +59,15 @@ func (l *DetailLogic) Detail() (resp *types.UserInfoResp, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 用户信息结构体复制失败, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 用户信息结构体复制失败, %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Mobile.Valid {
|
if user.Mobile.Valid {
|
||||||
userInfo.Mobile, err = crypto.DecryptMobile(user.Mobile.String, l.svcCtx.Config.Encrypt.SecretKey)
|
userInfo.Mobile, err = crypto.DecryptMobile(user.Mobile.String, l.svcCtx.Config.Encrypt.SecretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 解密手机号失败, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, 解密手机号失败, %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
userInfo.UserType = claims.UserType
|
||||||
|
|
||||||
return &types.UserInfoResp{
|
return &types.UserInfoResp{
|
||||||
UserInfo: userInfo,
|
UserInfo: userInfo,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
"tydata-server/common/ctxdata"
|
"tydata-server/common/ctxdata"
|
||||||
jwtx "tydata-server/common/jwt"
|
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -32,11 +31,11 @@ func NewGetTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetToken
|
|||||||
func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error) {
|
func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error) {
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg(""), "用户信息, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
||||||
}
|
}
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if generaErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "更新token, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
||||||
}
|
}
|
||||||
// 获取当前时间戳
|
// 获取当前时间戳
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
|
@ -8,13 +8,11 @@ import (
|
|||||||
"tydata-server/app/main/api/internal/svc"
|
"tydata-server/app/main/api/internal/svc"
|
||||||
"tydata-server/app/main/api/internal/types"
|
"tydata-server/app/main/api/internal/types"
|
||||||
"tydata-server/app/main/model"
|
"tydata-server/app/main/model"
|
||||||
jwtx "tydata-server/common/jwt"
|
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
"tydata-server/pkg/lzkit/crypto"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
@ -53,42 +51,22 @@ func (l *MobileCodeLoginLogic) MobileCodeLogin(req *types.MobileCodeLoginReq) (r
|
|||||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "手机登录, 验证码不正确: %s", encryptedMobile)
|
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "手机登录, 验证码不正确: %s", encryptedMobile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var userID int64
|
||||||
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
|
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
|
||||||
if findUserErr != nil && findUserErr != model.ErrNotFound {
|
if findUserErr != nil && findUserErr != model.ErrNotFound {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile: %s, err: %+v", encryptedMobile, err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile: %s, err: %+v", encryptedMobile, err)
|
||||||
}
|
}
|
||||||
if user == nil {
|
if user == nil {
|
||||||
user = &model.User{Mobile: sql.NullString{String: encryptedMobile, Valid: true}}
|
userID, err = l.svcCtx.UserService.RegisterUser(l.ctx, encryptedMobile)
|
||||||
// if len(main.Nickname) == 0 {
|
if err != nil {
|
||||||
// main.Nickname = encryptedMobile
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 注册用户失败: %+v", err)
|
||||||
// }
|
|
||||||
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
||||||
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(ctx, session, user)
|
|
||||||
if userInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入新用户失败, mobile%s, err: %+v", encryptedMobile, err)
|
|
||||||
}
|
}
|
||||||
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
} else {
|
||||||
if lastInsertIdErr != nil {
|
userID = user.Id
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 获取新用户ID失败, err:%+v, main:%+v", lastInsertIdErr, user)
|
|
||||||
}
|
}
|
||||||
user.Id = lastId
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
|
if err != nil {
|
||||||
userAuth := new(model.UserAuth)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", userID)
|
||||||
userAuth.UserId = lastId
|
|
||||||
userAuth.AuthKey = encryptedMobile
|
|
||||||
userAuth.AuthType = model.UserAuthTypeAppMobile
|
|
||||||
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(ctx, session, userAuth); userAuthInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入用户认证失败, err:%+v", userAuthInsertErr)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); transErr != nil {
|
|
||||||
return nil, transErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(user.Id, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
|
||||||
if generaErr != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", user.Id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前时间戳
|
// 获取当前时间戳
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"time"
|
|
||||||
"tydata-server/app/main/model"
|
|
||||||
jwtx "tydata-server/common/jwt"
|
|
||||||
"tydata-server/common/tool"
|
|
||||||
"tydata-server/common/xerr"
|
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
|
||||||
"tydata-server/pkg/lzkit/lzUtils"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
|
||||||
"tydata-server/app/main/api/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MobileLoginLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMobileLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MobileLoginLogic {
|
|
||||||
return &MobileLoginLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *MobileLoginLogic) MobileLogin(req *types.MobileLoginReq) (resp *types.MobileCodeLoginResp, err error) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
|
|
||||||
if findUserErr != nil && findUserErr != model.ErrNotFound {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile%s, err: %+v", encryptedMobile, err)
|
|
||||||
}
|
|
||||||
if user == nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("手机号码未注册"), "手机登录, 手机号未注册:%s", encryptedMobile)
|
|
||||||
}
|
|
||||||
if !(tool.Md5ByString(req.Password) == lzUtils.NullStringToString(user.Password)) {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("密码不正确"), "手机登录, 密码匹配不正确%s", encryptedMobile)
|
|
||||||
}
|
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(user.Id, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
|
||||||
if generaErr != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", user.Id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前时间戳
|
|
||||||
now := time.Now().Unix()
|
|
||||||
return &types.MobileCodeLoginResp{
|
|
||||||
AccessToken: token,
|
|
||||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
|
||||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
package user
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
|
||||||
"tydata-server/app/main/api/internal/types"
|
|
||||||
"tydata-server/app/main/model"
|
|
||||||
jwtx "tydata-server/common/jwt"
|
|
||||||
"tydata-server/common/tool"
|
|
||||||
"tydata-server/common/xerr"
|
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
|
||||||
"tydata-server/pkg/lzkit/lzUtils"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RegisterLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
|
|
||||||
return &RegisterLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.RegisterResp, err error) {
|
|
||||||
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", "register", 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)
|
|
||||||
}
|
|
||||||
hasUser, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true})
|
|
||||||
if findUserErr != nil && findUserErr != model.ErrNotFound {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 读取数据库获取用户失败, mobile%s, err: %+v", encryptedMobile, err)
|
|
||||||
}
|
|
||||||
if hasUser != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrMsg("该手机号码已注册"), "手机注册, 手机号码已注册, mobile:%s", encryptedMobile)
|
|
||||||
}
|
|
||||||
var userId int64
|
|
||||||
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
||||||
user := new(model.User)
|
|
||||||
user.Mobile = sql.NullString{String: encryptedMobile, Valid: true}
|
|
||||||
// if len(main.Nickname) == 0 {
|
|
||||||
// main.Nickname = encryptedMobile
|
|
||||||
// }
|
|
||||||
if len(req.Password) > 0 {
|
|
||||||
user.Password = lzUtils.StringToNullString(tool.Md5ByString(req.Password))
|
|
||||||
}
|
|
||||||
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(ctx, session, user)
|
|
||||||
if userInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入新用户失败, mobile%s, err: %+v", encryptedMobile, err)
|
|
||||||
}
|
|
||||||
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
|
||||||
if lastInsertIdErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 获取新用户ID失败, err:%+v, main:%+v", lastInsertIdErr, user)
|
|
||||||
}
|
|
||||||
userId = lastId
|
|
||||||
|
|
||||||
userAuth := new(model.UserAuth)
|
|
||||||
userAuth.UserId = lastId
|
|
||||||
userAuth.AuthKey = encryptedMobile
|
|
||||||
userAuth.AuthType = model.UserAuthTypeAppMobile
|
|
||||||
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(ctx, session, userAuth); userAuthInsertErr != nil {
|
|
||||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 数据库插入用户认证失败, err:%+v", userAuthInsertErr)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); transErr != nil {
|
|
||||||
return nil, transErr
|
|
||||||
}
|
|
||||||
|
|
||||||
token, generaErr := jwtx.GenerateJwtToken(userId, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
|
||||||
if generaErr != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机注册, 生成jwt token失败, userid: %d, err:%+v", userId, generaErr)
|
|
||||||
}
|
|
||||||
// 获取当前时间戳
|
|
||||||
now := time.Now().Unix()
|
|
||||||
return &types.RegisterResp{
|
|
||||||
AccessToken: token,
|
|
||||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
|
||||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -8,11 +8,9 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
"tydata-server/app/main/model"
|
"tydata-server/app/main/model"
|
||||||
jwtx "tydata-server/common/jwt"
|
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
||||||
|
|
||||||
"tydata-server/app/main/api/internal/svc"
|
"tydata-server/app/main/api/internal/svc"
|
||||||
"tydata-server/app/main/api/internal/types"
|
"tydata-server/app/main/api/internal/types"
|
||||||
@ -40,60 +38,51 @@ func (l *WxH5AuthLogic) WxH5Auth(req *types.WXH5AuthReq) (resp *types.WXH5AuthRe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取access_token失败: %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取access_token失败: %v", err)
|
||||||
}
|
}
|
||||||
if accessTokenResp.AccessToken == "" || accessTokenResp.Openid == "" {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取access_token为空: %v", accessTokenResp)
|
|
||||||
}
|
|
||||||
// Step 2: 查找用户授权信息
|
// Step 2: 查找用户授权信息
|
||||||
userAuth, findErr := l.svcCtx.UserAuthModel.FindOneByAuthTypeAuthKey(l.ctx, model.UserAuthTypeWxh5, accessTokenResp.Openid)
|
userAuth, findErr := l.svcCtx.UserAuthModel.FindOneByAuthTypeAuthKey(l.ctx, model.UserAuthTypeWxh5OpenID, accessTokenResp.Openid)
|
||||||
if findErr != nil && !errors.Is(findErr, model.ErrNotFound) {
|
if findErr != nil && !errors.Is(findErr, model.ErrNotFound) {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询用户授权失败,findErr: %v", findErr)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户授权失败: %v", findErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: 查找或创建用户
|
// Step 3: 处理用户信息
|
||||||
var user *model.User
|
var userID int64
|
||||||
if userAuth != nil {
|
if userAuth != nil {
|
||||||
// 授权信息存在,查找用户
|
// 已存在用户,直接登录
|
||||||
userModel, findUserErr := l.svcCtx.UserModel.FindOne(l.ctx, userAuth.UserId)
|
userID = userAuth.UserId
|
||||||
if findUserErr != nil {
|
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询用户失败,userId: %v", findUserErr)
|
|
||||||
}
|
|
||||||
user = userModel
|
|
||||||
} else {
|
} else {
|
||||||
// 授权信息不存在,创建新用户
|
// 检查临时用户表
|
||||||
user = &model.User{}
|
userTemp, err := l.svcCtx.UserTempModel.FindOneByAuthTypeAuthKey(l.ctx, model.UserAuthTypeWxh5OpenID, accessTokenResp.Openid)
|
||||||
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(context context.Context, session sqlx.Session) error {
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||||
// 插入数据库
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询用户临时信息失败: %v", err)
|
||||||
insertResult, insertErr := l.svcCtx.UserModel.Insert(l.ctx, session, user)
|
|
||||||
if insertErr != nil {
|
|
||||||
return errors.Wrapf(insertErr, "创建新用户失败,openid: %s", accessTokenResp.Openid)
|
|
||||||
}
|
}
|
||||||
// 获取插入后生成的 main.Id
|
|
||||||
lastInsertId, lastInsertIdErr := insertResult.LastInsertId()
|
if userTemp == nil {
|
||||||
if lastInsertIdErr != nil {
|
// 创建临时用户记录
|
||||||
return errors.Wrapf(lastInsertIdErr, "获取新用户ID失败,openid: %s", accessTokenResp.Openid)
|
userTemp = &model.UserTemp{
|
||||||
}
|
AuthType: model.UserAuthTypeWxh5OpenID,
|
||||||
user.Id = lastInsertId
|
|
||||||
// 创建用户授权信息
|
|
||||||
userAuth = &model.UserAuth{
|
|
||||||
UserId: user.Id,
|
|
||||||
AuthKey: accessTokenResp.Openid,
|
AuthKey: accessTokenResp.Openid,
|
||||||
AuthType: model.UserAuthTypeWxh5, // 微信小程序
|
|
||||||
}
|
}
|
||||||
if _, insertUserAuthErr := l.svcCtx.UserAuthModel.Insert(l.ctx, session, userAuth); insertUserAuthErr != nil {
|
result, err := l.svcCtx.UserTempModel.Insert(l.ctx, nil, userTemp)
|
||||||
return errors.Wrapf(insertUserAuthErr, "创建用户授权失败,openid: %s", accessTokenResp.Openid)
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建临时用户信息失败: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
userID, err = result.LastInsertId()
|
||||||
}); transErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建新用户事务失败: %v", transErr)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取新创建的临时用户ID失败: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
userID = userTemp.Id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: 生成JWT Token
|
// Step 4: 生成JWT Token
|
||||||
token, genErr := jwtx.GenerateJwtToken(user.Id, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
||||||
if genErr != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成JWT token失败: %v", genErr)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成JWT token失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 5: 返回登录结果
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
return &types.WXH5AuthResp{
|
return &types.WXH5AuthResp{
|
||||||
AccessToken: token,
|
AccessToken: token,
|
||||||
@ -130,9 +119,9 @@ func (l *WxH5AuthLogic) GetAccessToken(code string) (*AccessTokenResp, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//if accessTokenResp.AccessToken == "" {
|
if accessTokenResp.AccessToken == "" || accessTokenResp.Openid == "" {
|
||||||
// return nil, errors.New("accessTokenResp.AccessToken为空")
|
return nil, errors.New("accessTokenResp.AccessToken为空")
|
||||||
//}
|
}
|
||||||
|
|
||||||
return &accessTokenResp, nil
|
return &accessTokenResp, nil
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,9 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"tydata-server/app/main/api/internal/config"
|
"tydata-server/app/main/api/internal/config"
|
||||||
"tydata-server/common/ctxdata"
|
|
||||||
jwtx "tydata-server/common/jwt"
|
jwtx "tydata-server/common/jwt"
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
|
|
||||||
@ -42,17 +39,14 @@ func (m *AuthInterceptorMiddleware) Handle(next http.HandlerFunc) http.HandlerFu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析JWT令牌
|
// 解析JWT令牌
|
||||||
userId, err := jwtx.ParseJwtToken(authHeader, m.Config.JwtAuth.AccessSecret)
|
claims, err := jwtx.ParseJwtToken(authHeader, m.Config.JwtAuth.AccessSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// JWT解析失败,返回401错误
|
// JWT解析失败,返回401错误
|
||||||
httpx.Error(w, errors.Wrapf(xerr.NewErrCode(ErrCodeUnauthorized), "token解析失败: %v", err))
|
httpx.Error(w, errors.Wrapf(xerr.NewErrCode(ErrCodeUnauthorized), "token解析失败: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将用户ID转换为json.Number类型后添加到请求上下文
|
ctx := context.WithValue(r.Context(), jwtx.ExtraKey, claims)
|
||||||
userIdStr := fmt.Sprintf("%d", userId)
|
|
||||||
userIdJsonNum := json.Number(userIdStr)
|
|
||||||
ctx := context.WithValue(r.Context(), ctxdata.CtxKeyJwtUserId, userIdJsonNum)
|
|
||||||
|
|
||||||
// 使用新的上下文继续处理请求
|
// 使用新的上下文继续处理请求
|
||||||
next(w, r.WithContext(ctx))
|
next(w, r.WithContext(ctx))
|
||||||
|
@ -6,28 +6,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BrandKey = "X-Brand"
|
|
||||||
PlatformKey = "X-Platform"
|
PlatformKey = "X-Platform"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SourceInterceptorMiddleware struct {
|
func GlobalSourceInterceptor(next http.HandlerFunc) http.HandlerFunc {
|
||||||
}
|
|
||||||
|
|
||||||
func NewSourceInterceptorMiddleware() *SourceInterceptorMiddleware {
|
|
||||||
return &SourceInterceptorMiddleware{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *SourceInterceptorMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// 获取请求头 X-Brand 和 X-Platform 的值
|
// 获取请求头 X-Platform 的值
|
||||||
brand := r.Header.Get(BrandKey)
|
|
||||||
platform := r.Header.Get(PlatformKey)
|
platform := r.Header.Get(PlatformKey)
|
||||||
|
|
||||||
// 将值放入新的 context 中
|
// 将值放入新的 context 中
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
if brand != "" {
|
|
||||||
ctx = context.WithValue(ctx, "brand", brand)
|
|
||||||
}
|
|
||||||
if platform != "" {
|
if platform != "" {
|
||||||
ctx = context.WithValue(ctx, "platform", platform)
|
ctx = context.WithValue(ctx, "platform", platform)
|
||||||
}
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"tydata-server/app/main/model"
|
||||||
|
"tydata-server/common/ctxdata"
|
||||||
|
"tydata-server/common/xerr"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserAuthInterceptorMiddleware struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserAuthInterceptorMiddleware() *UserAuthInterceptorMiddleware {
|
||||||
|
return &UserAuthInterceptorMiddleware{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *UserAuthInterceptorMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
claims, err := ctxdata.GetClaimsFromCtx(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
httpx.Error(w, errors.Wrapf(xerr.NewErrCode(ErrCodeUnauthorized), "token解析失败: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if claims.UserType == model.UserTypeTemp {
|
||||||
|
httpx.Error(w, errors.Wrapf(xerr.NewErrCode(xerr.USER_NEED_BIND_MOBILE), "token解析失败: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
next(w, r)
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
"tydata-server/app/main/api/internal/config"
|
"tydata-server/app/main/api/internal/config"
|
||||||
|
"tydata-server/app/main/model"
|
||||||
"tydata-server/pkg/lzkit/lzUtils"
|
"tydata-server/pkg/lzkit/lzUtils"
|
||||||
|
|
||||||
"github.com/smartwalle/alipay/v3"
|
"github.com/smartwalle/alipay/v3"
|
||||||
@ -104,10 +105,10 @@ func (a *AliPayService) CreateAlipayOrder(ctx context.Context, amount float64, s
|
|||||||
return "", fmt.Errorf("无的支付平台: %s", platform)
|
return "", fmt.Errorf("无的支付平台: %s", platform)
|
||||||
}
|
}
|
||||||
switch platform {
|
switch platform {
|
||||||
case "app":
|
case model.PlatformApp:
|
||||||
// 调用App支付的创建方法
|
// 调用App支付的创建方法
|
||||||
return a.CreateAlipayAppOrder(amount, subject, outTradeNo)
|
return a.CreateAlipayAppOrder(amount, subject, outTradeNo)
|
||||||
case "h5":
|
case model.PlatformH5:
|
||||||
// 调用H5支付的创建方法,并传入 returnUrl
|
// 调用H5支付的创建方法,并传入 returnUrl
|
||||||
return a.CreateAlipayH5Order(amount, subject, outTradeNo)
|
return a.CreateAlipayH5Order(amount, subject, outTradeNo)
|
||||||
default:
|
default:
|
||||||
|
@ -2,22 +2,34 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"tydata-server/app/main/api/internal/config"
|
||||||
"tydata-server/app/main/model"
|
"tydata-server/app/main/model"
|
||||||
|
"tydata-server/common/ctxdata"
|
||||||
|
jwtx "tydata-server/common/jwt"
|
||||||
|
"tydata-server/common/xerr"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserService struct {
|
type UserService struct {
|
||||||
|
Config *config.Config
|
||||||
userModel model.UserModel
|
userModel model.UserModel
|
||||||
userAuthModel model.UserAuthModel
|
userAuthModel model.UserAuthModel
|
||||||
|
userTempModel model.UserTempModel
|
||||||
|
agentModel model.AgentModel
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUserService 创建UserService实例
|
// NewUserService 创建UserService实例
|
||||||
func NewUserService(userModel model.UserModel, userAuthModel model.UserAuthModel) *UserService {
|
func NewUserService(config *config.Config, userModel model.UserModel, userAuthModel model.UserAuthModel, userTempModel model.UserTempModel, agentModel model.AgentModel) *UserService {
|
||||||
return &UserService{
|
return &UserService{
|
||||||
|
Config: config,
|
||||||
userModel: userModel,
|
userModel: userModel,
|
||||||
userAuthModel: userAuthModel,
|
userAuthModel: userAuthModel,
|
||||||
|
userTempModel: userTempModel,
|
||||||
|
agentModel: agentModel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,3 +75,217 @@ func (s *UserService) RegisterUUIDUser(ctx context.Context) (int64, error) {
|
|||||||
|
|
||||||
return userId, nil
|
return userId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generalUserToken 生成用户token
|
||||||
|
func (s *UserService) GeneralUserToken(ctx context.Context, userID int64) (string, error) {
|
||||||
|
platform, err := ctxdata.GetPlatformFromCtx(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var isAgent int64
|
||||||
|
var agentID int64
|
||||||
|
var userType int64
|
||||||
|
user, err := s.userModel.FindOne(ctx, userID)
|
||||||
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if user != nil {
|
||||||
|
userID = user.Id
|
||||||
|
userType = model.UserTypeNormal
|
||||||
|
agent, err := s.agentModel.FindOneByUserId(ctx, userID)
|
||||||
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if agent != nil {
|
||||||
|
agentID = agent.Id
|
||||||
|
isAgent = model.AgentStatusYes
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
userTemp, err := s.userTempModel.FindOne(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if userTemp != nil {
|
||||||
|
userID = userTemp.Id
|
||||||
|
userType = model.UserTypeTemp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token, generaErr := jwtx.GenerateJwtToken(jwtx.JwtClaims{
|
||||||
|
UserId: userID,
|
||||||
|
AgentId: agentID,
|
||||||
|
Platform: platform,
|
||||||
|
UserType: userType,
|
||||||
|
IsAgent: isAgent,
|
||||||
|
}, s.Config.JwtAuth.AccessSecret, s.Config.JwtAuth.AccessExpire)
|
||||||
|
if generaErr != nil {
|
||||||
|
return "", errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "更新token, 生成token失败 : %d", userID)
|
||||||
|
}
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUser 注册用户,返回用户ID
|
||||||
|
// 传入手机号,自动注册,如果ctx存在临时用户则临时用户转为正式用户
|
||||||
|
func (s *UserService) RegisterUser(ctx context.Context, mobile string) (int64, error) {
|
||||||
|
claims, err := ctxdata.GetClaimsFromCtx(ctx)
|
||||||
|
if err != nil && !errors.Is(err, ctxdata.ErrNoInCtx) {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
user, err := s.userModel.FindOneByMobile(ctx, sql.NullString{String: mobile, Valid: true})
|
||||||
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if user != nil {
|
||||||
|
return 0, errors.New("用户已注册")
|
||||||
|
}
|
||||||
|
// 普通注册
|
||||||
|
if claims == nil {
|
||||||
|
var userId int64
|
||||||
|
err = s.userModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
|
user := &model.User{
|
||||||
|
Mobile: sql.NullString{String: mobile, Valid: true},
|
||||||
|
}
|
||||||
|
result, err := s.userModel.Insert(ctx, session, user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
userId, err = result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.userAuthModel.Insert(ctx, session, &model.UserAuth{
|
||||||
|
UserId: userId,
|
||||||
|
AuthType: model.UserAuthTypeMobile,
|
||||||
|
AuthKey: mobile,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return userId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 双重判断是否已经注册
|
||||||
|
if claims.UserType == model.UserTypeNormal {
|
||||||
|
return 0, errors.New("用户已注册")
|
||||||
|
}
|
||||||
|
var userId int64
|
||||||
|
// 临时转正式注册
|
||||||
|
err = s.userModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
|
user := &model.User{
|
||||||
|
Mobile: sql.NullString{String: mobile, Valid: true},
|
||||||
|
}
|
||||||
|
result, err := s.userModel.Insert(ctx, session, user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
userId, err = result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = s.userAuthModel.Insert(ctx, session, &model.UserAuth{
|
||||||
|
UserId: userId,
|
||||||
|
AuthType: model.UserAuthTypeMobile,
|
||||||
|
AuthKey: mobile,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = s.TempUserBindUser(ctx, session, userId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return userId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TempUserBindUser 临时用户绑定用户
|
||||||
|
func (s *UserService) TempUserBindUser(ctx context.Context, session sqlx.Session, normalUserID int64) error {
|
||||||
|
claims, err := ctxdata.GetClaimsFromCtx(ctx)
|
||||||
|
if err != nil && !errors.Is(err, ctxdata.ErrNoInCtx) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if claims == nil || claims.UserType != model.UserTypeTemp {
|
||||||
|
return errors.New("无临时用户")
|
||||||
|
}
|
||||||
|
|
||||||
|
userTemp, err := s.userTempModel.FindOne(ctx, claims.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userAuth, err := s.userAuthModel.FindOneByAuthTypeAuthKey(ctx, userTemp.AuthType, userTemp.AuthKey)
|
||||||
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if userAuth != nil {
|
||||||
|
return errors.New("临时用户已注册")
|
||||||
|
}
|
||||||
|
|
||||||
|
if session == nil {
|
||||||
|
err := s.userAuthModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
|
_, err = s.userAuthModel.Insert(ctx, session, &model.UserAuth{
|
||||||
|
UserId: normalUserID,
|
||||||
|
AuthType: userTemp.AuthType,
|
||||||
|
AuthKey: userTemp.AuthKey,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = s.userTempModel.DeleteSoft(ctx, session, userTemp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
_, err = s.userAuthModel.Insert(ctx, session, &model.UserAuth{
|
||||||
|
UserId: normalUserID,
|
||||||
|
AuthType: userTemp.AuthType,
|
||||||
|
AuthKey: userTemp.AuthKey,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = s.userTempModel.DeleteSoft(ctx, session, userTemp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// _bak_RegisterUUIDUser 注册UUID用户,返回用户ID
|
||||||
|
func (s *UserService) _bak_RegisterUUIDUser(ctx context.Context) error {
|
||||||
|
// 生成UUID
|
||||||
|
uuidStr, err := s.GenerateUUIDUserId(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.userTempModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
|
// 创建用户临时记录
|
||||||
|
userTemp := &model.UserTemp{
|
||||||
|
AuthType: model.UserAuthTypeUUID,
|
||||||
|
AuthKey: uuidStr,
|
||||||
|
}
|
||||||
|
_, err := s.userTempModel.Insert(ctx, session, userTemp)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -219,12 +219,12 @@ func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
switch platform {
|
switch platform {
|
||||||
case "mp-weixin":
|
case model.PlatformWxMini:
|
||||||
userID, getUidErr := ctxdata.GetUidFromCtx(ctx)
|
userID, getUidErr := ctxdata.GetUidFromCtx(ctx)
|
||||||
if getUidErr != nil {
|
if getUidErr != nil {
|
||||||
return "", getUidErr
|
return "", getUidErr
|
||||||
}
|
}
|
||||||
userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxMini)
|
userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxMiniOpenID)
|
||||||
if findAuthModelErr != nil {
|
if findAuthModelErr != nil {
|
||||||
return "", findAuthModelErr
|
return "", findAuthModelErr
|
||||||
}
|
}
|
||||||
@ -232,12 +232,12 @@ func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
case "h5-weixin":
|
case model.PlatformWxH5:
|
||||||
userID, getUidErr := ctxdata.GetUidFromCtx(ctx)
|
userID, getUidErr := ctxdata.GetUidFromCtx(ctx)
|
||||||
if getUidErr != nil {
|
if getUidErr != nil {
|
||||||
return "", getUidErr
|
return "", getUidErr
|
||||||
}
|
}
|
||||||
userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxh5)
|
userAuthModel, findAuthModelErr := w.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWxh5OpenID)
|
||||||
if findAuthModelErr != nil {
|
if findAuthModelErr != nil {
|
||||||
return "", findAuthModelErr
|
return "", findAuthModelErr
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
case "app":
|
case model.PlatformApp:
|
||||||
// 如果是 APP 平台,调用 APP 支付订单创建
|
// 如果是 APP 平台,调用 APP 支付订单创建
|
||||||
prepayData, err = w.CreateWechatAppOrder(ctx, amount, description, outTradeNo)
|
prepayData, err = w.CreateWechatAppOrder(ctx, amount, description, outTradeNo)
|
||||||
default:
|
default:
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"github.com/hibiken/asynq"
|
"github.com/hibiken/asynq"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
|
||||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
"github.com/zeromicro/go-zero/rest"
|
"github.com/zeromicro/go-zero/rest"
|
||||||
@ -20,12 +19,13 @@ type ServiceContext struct {
|
|||||||
Redis *redis.Redis
|
Redis *redis.Redis
|
||||||
|
|
||||||
// 中间件
|
// 中间件
|
||||||
SourceInterceptor rest.Middleware
|
|
||||||
AuthInterceptor rest.Middleware
|
AuthInterceptor rest.Middleware
|
||||||
|
UserAuthInterceptor rest.Middleware
|
||||||
|
|
||||||
// 用户相关模型
|
// 用户相关模型
|
||||||
UserModel model.UserModel
|
UserModel model.UserModel
|
||||||
UserAuthModel model.UserAuthModel
|
UserAuthModel model.UserAuthModel
|
||||||
|
UserTempModel model.UserTempModel
|
||||||
|
|
||||||
// 产品相关模型
|
// 产品相关模型
|
||||||
ProductModel model.ProductModel
|
ProductModel model.ProductModel
|
||||||
@ -94,185 +94,98 @@ type ServiceContext struct {
|
|||||||
AdminPromotionLinkStatsService *service.AdminPromotionLinkStatsService
|
AdminPromotionLinkStatsService *service.AdminPromotionLinkStatsService
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户相关模型初始化
|
// NewServiceContext 创建服务上下文
|
||||||
type userModels struct {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
UserModel model.UserModel
|
// ============================== 基础设施初始化 ==============================
|
||||||
UserAuthModel model.UserAuthModel
|
db := sqlx.NewMysql(c.DataSource)
|
||||||
}
|
cacheConf := c.CacheRedis
|
||||||
|
|
||||||
func initUserModels(db sqlx.SqlConn, redis cache.CacheConf) userModels {
|
// 初始化Redis客户端
|
||||||
return userModels{
|
redisConf := redis.RedisConf{
|
||||||
UserModel: model.NewUserModel(db, redis),
|
Host: cacheConf[0].Host,
|
||||||
UserAuthModel: model.NewUserAuthModel(db, redis),
|
Pass: cacheConf[0].Pass,
|
||||||
|
Type: cacheConf[0].Type,
|
||||||
}
|
}
|
||||||
}
|
redisClient := redis.MustNewRedis(redisConf)
|
||||||
|
|
||||||
// 产品相关模型初始化
|
// ============================== 用户相关模型 ==============================
|
||||||
type productModels struct {
|
userModel := model.NewUserModel(db, cacheConf)
|
||||||
ProductModel model.ProductModel
|
userAuthModel := model.NewUserAuthModel(db, cacheConf)
|
||||||
FeatureModel model.FeatureModel
|
userTempModel := model.NewUserTempModel(db, cacheConf)
|
||||||
ProductFeatureModel model.ProductFeatureModel
|
|
||||||
}
|
|
||||||
|
|
||||||
func initProductModels(db sqlx.SqlConn, redis cache.CacheConf) productModels {
|
// ============================== 产品相关模型 ==============================
|
||||||
return productModels{
|
productModel := model.NewProductModel(db, cacheConf)
|
||||||
ProductModel: model.NewProductModel(db, redis),
|
featureModel := model.NewFeatureModel(db, cacheConf)
|
||||||
FeatureModel: model.NewFeatureModel(db, redis),
|
productFeatureModel := model.NewProductFeatureModel(db, cacheConf)
|
||||||
ProductFeatureModel: model.NewProductFeatureModel(db, redis),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 订单相关模型初始化
|
// ============================== 订单相关模型 ==============================
|
||||||
type orderModels struct {
|
orderModel := model.NewOrderModel(db, cacheConf)
|
||||||
OrderModel model.OrderModel
|
queryModel := model.NewQueryModel(db, cacheConf)
|
||||||
QueryModel model.QueryModel
|
orderRefundModel := model.NewOrderRefundModel(db, cacheConf)
|
||||||
OrderRefundModel model.OrderRefundModel
|
queryCleanupLogModel := model.NewQueryCleanupLogModel(db, cacheConf)
|
||||||
QueryCleanupLogModel model.QueryCleanupLogModel
|
queryCleanupDetailModel := model.NewQueryCleanupDetailModel(db, cacheConf)
|
||||||
QueryCleanupDetailModel model.QueryCleanupDetailModel
|
queryCleanupConfigModel := model.NewQueryCleanupConfigModel(db, cacheConf)
|
||||||
QueryCleanupConfigModel model.QueryCleanupConfigModel
|
|
||||||
}
|
|
||||||
|
|
||||||
func initOrderModels(db sqlx.SqlConn, redis cache.CacheConf) orderModels {
|
// ============================== 代理相关模型 ==============================
|
||||||
return orderModels{
|
agentModel := model.NewAgentModel(db, cacheConf)
|
||||||
OrderModel: model.NewOrderModel(db, redis),
|
agentAuditModel := model.NewAgentAuditModel(db, cacheConf)
|
||||||
QueryModel: model.NewQueryModel(db, redis),
|
agentClosureModel := model.NewAgentClosureModel(db, cacheConf)
|
||||||
OrderRefundModel: model.NewOrderRefundModel(db, redis),
|
agentCommissionModel := model.NewAgentCommissionModel(db, cacheConf)
|
||||||
QueryCleanupLogModel: model.NewQueryCleanupLogModel(db, redis),
|
agentCommissionDeductionModel := model.NewAgentCommissionDeductionModel(db, cacheConf)
|
||||||
QueryCleanupDetailModel: model.NewQueryCleanupDetailModel(db, redis),
|
agentWalletModel := model.NewAgentWalletModel(db, cacheConf)
|
||||||
QueryCleanupConfigModel: model.NewQueryCleanupConfigModel(db, redis),
|
agentLinkModel := model.NewAgentLinkModel(db, cacheConf)
|
||||||
}
|
agentOrderModel := model.NewAgentOrderModel(db, cacheConf)
|
||||||
}
|
agentRewardsModel := model.NewAgentRewardsModel(db, cacheConf)
|
||||||
|
agentMembershipConfigModel := model.NewAgentMembershipConfigModel(db, cacheConf)
|
||||||
|
agentMembershipRechargeOrderModel := model.NewAgentMembershipRechargeOrderModel(db, cacheConf)
|
||||||
|
agentMembershipUserConfigModel := model.NewAgentMembershipUserConfigModel(db, cacheConf)
|
||||||
|
agentProductConfigModel := model.NewAgentProductConfigModel(db, cacheConf)
|
||||||
|
agentPlatformDeductionModel := model.NewAgentPlatformDeductionModel(db, cacheConf)
|
||||||
|
agentActiveStatModel := model.NewAgentActiveStatModel(db, cacheConf)
|
||||||
|
agentWithdrawalModel := model.NewAgentWithdrawalModel(db, cacheConf)
|
||||||
|
agentRealNameModel := model.NewAgentRealNameModel(db, cacheConf)
|
||||||
|
|
||||||
// 代理相关模型初始化
|
// ============================== 管理后台相关模型 ==============================
|
||||||
type agentModels struct {
|
adminApiModel := model.NewAdminApiModel(db, cacheConf)
|
||||||
AgentModel model.AgentModel
|
adminMenuModel := model.NewAdminMenuModel(db, cacheConf)
|
||||||
AgentAuditModel model.AgentAuditModel
|
adminRoleModel := model.NewAdminRoleModel(db, cacheConf)
|
||||||
AgentClosureModel model.AgentClosureModel
|
adminRoleApiModel := model.NewAdminRoleApiModel(db, cacheConf)
|
||||||
AgentCommissionModel model.AgentCommissionModel
|
adminRoleMenuModel := model.NewAdminRoleMenuModel(db, cacheConf)
|
||||||
AgentCommissionDeductionModel model.AgentCommissionDeductionModel
|
adminUserModel := model.NewAdminUserModel(db, cacheConf)
|
||||||
AgentWalletModel model.AgentWalletModel
|
adminUserRoleModel := model.NewAdminUserRoleModel(db, cacheConf)
|
||||||
AgentLinkModel model.AgentLinkModel
|
adminDictDataModel := model.NewAdminDictDataModel(db, cacheConf)
|
||||||
AgentOrderModel model.AgentOrderModel
|
adminDictTypeModel := model.NewAdminDictTypeModel(db, cacheConf)
|
||||||
AgentRewardsModel model.AgentRewardsModel
|
adminPromotionLinkModel := model.NewAdminPromotionLinkModel(db, cacheConf)
|
||||||
AgentMembershipConfigModel model.AgentMembershipConfigModel
|
adminPromotionLinkStatsTotalModel := model.NewAdminPromotionLinkStatsTotalModel(db, cacheConf)
|
||||||
AgentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel
|
adminPromotionLinkStatsHistoryModel := model.NewAdminPromotionLinkStatsHistoryModel(db, cacheConf)
|
||||||
AgentMembershipUserConfigModel model.AgentMembershipUserConfigModel
|
adminPromotionOrderModel := model.NewAdminPromotionOrderModel(db, cacheConf)
|
||||||
AgentProductConfigModel model.AgentProductConfigModel
|
|
||||||
AgentPlatformDeductionModel model.AgentPlatformDeductionModel
|
|
||||||
AgentActiveStatModel model.AgentActiveStatModel
|
|
||||||
AgentWithdrawalModel model.AgentWithdrawalModel
|
|
||||||
AgentRealNameModel model.AgentRealNameModel
|
|
||||||
}
|
|
||||||
|
|
||||||
func initAgentModels(db sqlx.SqlConn, redis cache.CacheConf) agentModels {
|
// ============================== 其他模型 ==============================
|
||||||
return agentModels{
|
exampleModel := model.NewExampleModel(db, cacheConf)
|
||||||
AgentModel: model.NewAgentModel(db, redis),
|
globalNotificationsModel := model.NewGlobalNotificationsModel(db, cacheConf)
|
||||||
AgentAuditModel: model.NewAgentAuditModel(db, redis),
|
|
||||||
AgentClosureModel: model.NewAgentClosureModel(db, redis),
|
|
||||||
AgentCommissionModel: model.NewAgentCommissionModel(db, redis),
|
|
||||||
AgentCommissionDeductionModel: model.NewAgentCommissionDeductionModel(db, redis),
|
|
||||||
AgentWalletModel: model.NewAgentWalletModel(db, redis),
|
|
||||||
AgentLinkModel: model.NewAgentLinkModel(db, redis),
|
|
||||||
AgentOrderModel: model.NewAgentOrderModel(db, redis),
|
|
||||||
AgentRewardsModel: model.NewAgentRewardsModel(db, redis),
|
|
||||||
AgentMembershipConfigModel: model.NewAgentMembershipConfigModel(db, redis),
|
|
||||||
AgentMembershipRechargeOrderModel: model.NewAgentMembershipRechargeOrderModel(db, redis),
|
|
||||||
AgentMembershipUserConfigModel: model.NewAgentMembershipUserConfigModel(db, redis),
|
|
||||||
AgentProductConfigModel: model.NewAgentProductConfigModel(db, redis),
|
|
||||||
AgentPlatformDeductionModel: model.NewAgentPlatformDeductionModel(db, redis),
|
|
||||||
AgentActiveStatModel: model.NewAgentActiveStatModel(db, redis),
|
|
||||||
AgentWithdrawalModel: model.NewAgentWithdrawalModel(db, redis),
|
|
||||||
AgentRealNameModel: model.NewAgentRealNameModel(db, redis),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 管理后台相关模型初始化
|
// ============================== 第三方服务初始化 ==============================
|
||||||
type adminModels struct {
|
westDexService := service.NewWestDexService(c)
|
||||||
AdminApiModel model.AdminApiModel
|
yushanService := service.NewYushanService(c)
|
||||||
AdminMenuModel model.AdminMenuModel
|
|
||||||
AdminRoleModel model.AdminRoleModel
|
|
||||||
AdminRoleApiModel model.AdminRoleApiModel
|
|
||||||
AdminRoleMenuModel model.AdminRoleMenuModel
|
|
||||||
AdminUserModel model.AdminUserModel
|
|
||||||
AdminUserRoleModel model.AdminUserRoleModel
|
|
||||||
AdminDictDataModel model.AdminDictDataModel
|
|
||||||
AdminDictTypeModel model.AdminDictTypeModel
|
|
||||||
AdminPromotionLinkModel model.AdminPromotionLinkModel
|
|
||||||
AdminPromotionLinkStatsTotalModel model.AdminPromotionLinkStatsTotalModel
|
|
||||||
AdminPromotionLinkStatsHistoryModel model.AdminPromotionLinkStatsHistoryModel
|
|
||||||
AdminPromotionOrderModel model.AdminPromotionOrderModel
|
|
||||||
}
|
|
||||||
|
|
||||||
func initAdminModels(db sqlx.SqlConn, redis cache.CacheConf) adminModels {
|
|
||||||
return adminModels{
|
|
||||||
AdminApiModel: model.NewAdminApiModel(db, redis),
|
|
||||||
AdminMenuModel: model.NewAdminMenuModel(db, redis),
|
|
||||||
AdminRoleModel: model.NewAdminRoleModel(db, redis),
|
|
||||||
AdminRoleApiModel: model.NewAdminRoleApiModel(db, redis),
|
|
||||||
AdminRoleMenuModel: model.NewAdminRoleMenuModel(db, redis),
|
|
||||||
AdminUserModel: model.NewAdminUserModel(db, redis),
|
|
||||||
AdminUserRoleModel: model.NewAdminUserRoleModel(db, redis),
|
|
||||||
AdminDictDataModel: model.NewAdminDictDataModel(db, redis),
|
|
||||||
AdminDictTypeModel: model.NewAdminDictTypeModel(db, redis),
|
|
||||||
AdminPromotionLinkModel: model.NewAdminPromotionLinkModel(db, redis),
|
|
||||||
AdminPromotionLinkStatsTotalModel: model.NewAdminPromotionLinkStatsTotalModel(db, redis),
|
|
||||||
AdminPromotionLinkStatsHistoryModel: model.NewAdminPromotionLinkStatsHistoryModel(db, redis),
|
|
||||||
AdminPromotionOrderModel: model.NewAdminPromotionOrderModel(db, redis),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其他模型初始化
|
|
||||||
type otherModels struct {
|
|
||||||
ExampleModel model.ExampleModel
|
|
||||||
GlobalNotificationsModel model.GlobalNotificationsModel
|
|
||||||
}
|
|
||||||
|
|
||||||
func initOtherModels(db sqlx.SqlConn, redis cache.CacheConf) otherModels {
|
|
||||||
return otherModels{
|
|
||||||
ExampleModel: model.NewExampleModel(db, redis),
|
|
||||||
GlobalNotificationsModel: model.NewGlobalNotificationsModel(db, redis),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 服务初始化
|
|
||||||
type services struct {
|
|
||||||
AlipayService *service.AliPayService
|
|
||||||
WechatPayService *service.WechatPayService
|
|
||||||
ApplePayService *service.ApplePayService
|
|
||||||
WestDexService *service.WestDexService
|
|
||||||
YushanService *service.YushanService
|
|
||||||
ApiRequestService *service.ApiRequestService
|
|
||||||
AsynqServer *asynq.Server
|
|
||||||
AsynqService *service.AsynqService
|
|
||||||
VerificationService *service.VerificationService
|
|
||||||
AgentService *service.AgentService
|
|
||||||
UserService *service.UserService
|
|
||||||
DictService *service.DictService
|
|
||||||
AdminPromotionLinkStatsService *service.AdminPromotionLinkStatsService
|
|
||||||
}
|
|
||||||
|
|
||||||
func initServices(c config.Config, userAuthModel model.UserAuthModel, westDexService *service.WestDexService,
|
|
||||||
yushanService *service.YushanService, featureModel model.FeatureModel,
|
|
||||||
productFeatureModel model.ProductFeatureModel, agentModels agentModels,
|
|
||||||
userModels userModels, adminModels adminModels) services {
|
|
||||||
|
|
||||||
|
// ============================== 业务服务初始化 ==============================
|
||||||
alipayService := service.NewAliPayService(c)
|
alipayService := service.NewAliPayService(c)
|
||||||
wechatPayService := service.NewWechatPayService(c, userAuthModel, service.InitTypeWxPayPubKey)
|
wechatPayService := service.NewWechatPayService(c, userAuthModel, service.InitTypeWxPayPubKey)
|
||||||
applePayService := service.NewApplePayService(c)
|
applePayService := service.NewApplePayService(c)
|
||||||
apiRequestService := service.NewApiRequestService(c, westDexService, yushanService, featureModel, productFeatureModel)
|
apiRequestService := service.NewApiRequestService(c, westDexService, yushanService, featureModel, productFeatureModel)
|
||||||
verificationService := service.NewVerificationService(c, westDexService, apiRequestService)
|
verificationService := service.NewVerificationService(c, westDexService, apiRequestService)
|
||||||
asynqService := service.NewAsynqService(c)
|
asynqService := service.NewAsynqService(c)
|
||||||
agentService := service.NewAgentService(c, agentModels.AgentModel, agentModels.AgentAuditModel,
|
agentService := service.NewAgentService(c, agentModel, agentAuditModel, agentClosureModel,
|
||||||
agentModels.AgentClosureModel, agentModels.AgentCommissionModel,
|
agentCommissionModel, agentCommissionDeductionModel, agentWalletModel, agentLinkModel,
|
||||||
agentModels.AgentCommissionDeductionModel, agentModels.AgentWalletModel,
|
agentOrderModel, agentRewardsModel, agentMembershipConfigModel, agentMembershipRechargeOrderModel,
|
||||||
agentModels.AgentLinkModel, agentModels.AgentOrderModel, agentModels.AgentRewardsModel,
|
agentMembershipUserConfigModel, agentProductConfigModel, agentPlatformDeductionModel,
|
||||||
agentModels.AgentMembershipConfigModel, agentModels.AgentMembershipRechargeOrderModel,
|
agentActiveStatModel, agentWithdrawalModel)
|
||||||
agentModels.AgentMembershipUserConfigModel, agentModels.AgentProductConfigModel,
|
userService := service.NewUserService(&c, userModel, userAuthModel, userTempModel, agentModel)
|
||||||
agentModels.AgentPlatformDeductionModel, agentModels.AgentActiveStatModel,
|
dictService := service.NewDictService(adminDictTypeModel, adminDictDataModel)
|
||||||
agentModels.AgentWithdrawalModel)
|
adminPromotionLinkStatsService := service.NewAdminPromotionLinkStatsService(adminPromotionLinkModel,
|
||||||
userService := service.NewUserService(userModels.UserModel, userModels.UserAuthModel)
|
adminPromotionLinkStatsTotalModel, adminPromotionLinkStatsHistoryModel)
|
||||||
dictService := service.NewDictService(adminModels.AdminDictTypeModel, adminModels.AdminDictDataModel)
|
|
||||||
AdminPromotionLinkStatsService := service.NewAdminPromotionLinkStatsService(adminModels.AdminPromotionLinkModel, adminModels.AdminPromotionLinkStatsTotalModel, adminModels.AdminPromotionLinkStatsHistoryModel)
|
// ============================== 异步任务服务 ==============================
|
||||||
asynqServer := asynq.NewServer(
|
asynqServer := asynq.NewServer(
|
||||||
asynq.RedisClientOpt{Addr: c.CacheRedis[0].Host, Password: c.CacheRedis[0].Pass},
|
asynq.RedisClientOpt{Addr: c.CacheRedis[0].Host, Password: c.CacheRedis[0].Pass},
|
||||||
asynq.Config{
|
asynq.Config{
|
||||||
@ -284,7 +197,70 @@ wechatPayService := service.NewWechatPayService(c, userAuthModel, service.InitTy
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return services{
|
// ============================== 返回服务上下文 ==============================
|
||||||
|
return &ServiceContext{
|
||||||
|
Config: c,
|
||||||
|
Redis: redisClient,
|
||||||
|
AuthInterceptor: middleware.NewAuthInterceptorMiddleware(c).Handle,
|
||||||
|
UserAuthInterceptor: middleware.NewUserAuthInterceptorMiddleware().Handle,
|
||||||
|
|
||||||
|
// 用户相关模型
|
||||||
|
UserModel: userModel,
|
||||||
|
UserAuthModel: userAuthModel,
|
||||||
|
UserTempModel: userTempModel,
|
||||||
|
|
||||||
|
// 产品相关模型
|
||||||
|
ProductModel: productModel,
|
||||||
|
FeatureModel: featureModel,
|
||||||
|
ProductFeatureModel: productFeatureModel,
|
||||||
|
|
||||||
|
// 订单相关模型
|
||||||
|
OrderModel: orderModel,
|
||||||
|
QueryModel: queryModel,
|
||||||
|
OrderRefundModel: orderRefundModel,
|
||||||
|
QueryCleanupLogModel: queryCleanupLogModel,
|
||||||
|
QueryCleanupDetailModel: queryCleanupDetailModel,
|
||||||
|
QueryCleanupConfigModel: queryCleanupConfigModel,
|
||||||
|
|
||||||
|
// 代理相关模型
|
||||||
|
AgentModel: agentModel,
|
||||||
|
AgentAuditModel: agentAuditModel,
|
||||||
|
AgentClosureModel: agentClosureModel,
|
||||||
|
AgentCommissionModel: agentCommissionModel,
|
||||||
|
AgentCommissionDeductionModel: agentCommissionDeductionModel,
|
||||||
|
AgentWalletModel: agentWalletModel,
|
||||||
|
AgentLinkModel: agentLinkModel,
|
||||||
|
AgentOrderModel: agentOrderModel,
|
||||||
|
AgentRewardsModel: agentRewardsModel,
|
||||||
|
AgentMembershipConfigModel: agentMembershipConfigModel,
|
||||||
|
AgentMembershipRechargeOrderModel: agentMembershipRechargeOrderModel,
|
||||||
|
AgentMembershipUserConfigModel: agentMembershipUserConfigModel,
|
||||||
|
AgentProductConfigModel: agentProductConfigModel,
|
||||||
|
AgentPlatformDeductionModel: agentPlatformDeductionModel,
|
||||||
|
AgentActiveStatModel: agentActiveStatModel,
|
||||||
|
AgentWithdrawalModel: agentWithdrawalModel,
|
||||||
|
AgentRealNameModel: agentRealNameModel,
|
||||||
|
|
||||||
|
// 管理后台相关模型
|
||||||
|
AdminApiModel: adminApiModel,
|
||||||
|
AdminMenuModel: adminMenuModel,
|
||||||
|
AdminRoleModel: adminRoleModel,
|
||||||
|
AdminRoleApiModel: adminRoleApiModel,
|
||||||
|
AdminRoleMenuModel: adminRoleMenuModel,
|
||||||
|
AdminUserModel: adminUserModel,
|
||||||
|
AdminUserRoleModel: adminUserRoleModel,
|
||||||
|
AdminDictDataModel: adminDictDataModel,
|
||||||
|
AdminDictTypeModel: adminDictTypeModel,
|
||||||
|
AdminPromotionLinkModel: adminPromotionLinkModel,
|
||||||
|
AdminPromotionLinkStatsTotalModel: adminPromotionLinkStatsTotalModel,
|
||||||
|
AdminPromotionLinkStatsHistoryModel: adminPromotionLinkStatsHistoryModel,
|
||||||
|
AdminPromotionOrderModel: adminPromotionOrderModel,
|
||||||
|
|
||||||
|
// 其他模型
|
||||||
|
ExampleModel: exampleModel,
|
||||||
|
GlobalNotificationsModel: globalNotificationsModel,
|
||||||
|
|
||||||
|
// 服务
|
||||||
AlipayService: alipayService,
|
AlipayService: alipayService,
|
||||||
WechatPayService: wechatPayService,
|
WechatPayService: wechatPayService,
|
||||||
ApplePayService: applePayService,
|
ApplePayService: applePayService,
|
||||||
@ -297,115 +273,7 @@ wechatPayService := service.NewWechatPayService(c, userAuthModel, service.InitTy
|
|||||||
AgentService: agentService,
|
AgentService: agentService,
|
||||||
UserService: userService,
|
UserService: userService,
|
||||||
DictService: dictService,
|
DictService: dictService,
|
||||||
AdminPromotionLinkStatsService: AdminPromotionLinkStatsService,
|
AdminPromotionLinkStatsService: adminPromotionLinkStatsService,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewServiceContext 创建服务上下文
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
|
||||||
db := sqlx.NewMysql(c.DataSource)
|
|
||||||
|
|
||||||
// 使用配置中的CacheRedis配置
|
|
||||||
cacheConf := c.CacheRedis
|
|
||||||
|
|
||||||
// 初始化Redis客户端(用于异步任务等)
|
|
||||||
redisConf := redis.RedisConf{
|
|
||||||
Host: cacheConf[0].Host,
|
|
||||||
Pass: cacheConf[0].Pass,
|
|
||||||
Type: cacheConf[0].Type,
|
|
||||||
}
|
|
||||||
redisClient := redis.MustNewRedis(redisConf)
|
|
||||||
|
|
||||||
// 初始化各个模块的模型
|
|
||||||
userModels := initUserModels(db, cacheConf)
|
|
||||||
productModels := initProductModels(db, cacheConf)
|
|
||||||
orderModels := initOrderModels(db, cacheConf)
|
|
||||||
agentModels := initAgentModels(db, cacheConf)
|
|
||||||
adminModels := initAdminModels(db, cacheConf)
|
|
||||||
otherModels := initOtherModels(db, cacheConf)
|
|
||||||
|
|
||||||
// 初始化第三方服务
|
|
||||||
westDexService := service.NewWestDexService(c)
|
|
||||||
yushanService := service.NewYushanService(c)
|
|
||||||
|
|
||||||
// 初始化所有服务
|
|
||||||
services := initServices(c, userModels.UserAuthModel, westDexService, yushanService,
|
|
||||||
productModels.FeatureModel, productModels.ProductFeatureModel, agentModels, userModels, adminModels)
|
|
||||||
|
|
||||||
return &ServiceContext{
|
|
||||||
Config: c,
|
|
||||||
Redis: redisClient,
|
|
||||||
SourceInterceptor: middleware.NewSourceInterceptorMiddleware().Handle,
|
|
||||||
AuthInterceptor: middleware.NewAuthInterceptorMiddleware(c).Handle,
|
|
||||||
|
|
||||||
// 用户相关模型
|
|
||||||
UserModel: userModels.UserModel,
|
|
||||||
UserAuthModel: userModels.UserAuthModel,
|
|
||||||
|
|
||||||
// 产品相关模型
|
|
||||||
ProductModel: productModels.ProductModel,
|
|
||||||
FeatureModel: productModels.FeatureModel,
|
|
||||||
ProductFeatureModel: productModels.ProductFeatureModel,
|
|
||||||
|
|
||||||
// 订单相关模型
|
|
||||||
OrderModel: orderModels.OrderModel,
|
|
||||||
QueryModel: orderModels.QueryModel,
|
|
||||||
OrderRefundModel: orderModels.OrderRefundModel,
|
|
||||||
QueryCleanupLogModel: orderModels.QueryCleanupLogModel,
|
|
||||||
QueryCleanupDetailModel: orderModels.QueryCleanupDetailModel,
|
|
||||||
QueryCleanupConfigModel: orderModels.QueryCleanupConfigModel,
|
|
||||||
// 代理相关模型
|
|
||||||
AgentModel: agentModels.AgentModel,
|
|
||||||
AgentAuditModel: agentModels.AgentAuditModel,
|
|
||||||
AgentClosureModel: agentModels.AgentClosureModel,
|
|
||||||
AgentCommissionModel: agentModels.AgentCommissionModel,
|
|
||||||
AgentCommissionDeductionModel: agentModels.AgentCommissionDeductionModel,
|
|
||||||
AgentWalletModel: agentModels.AgentWalletModel,
|
|
||||||
AgentLinkModel: agentModels.AgentLinkModel,
|
|
||||||
AgentOrderModel: agentModels.AgentOrderModel,
|
|
||||||
AgentRewardsModel: agentModels.AgentRewardsModel,
|
|
||||||
AgentMembershipConfigModel: agentModels.AgentMembershipConfigModel,
|
|
||||||
AgentMembershipRechargeOrderModel: agentModels.AgentMembershipRechargeOrderModel,
|
|
||||||
AgentMembershipUserConfigModel: agentModels.AgentMembershipUserConfigModel,
|
|
||||||
AgentProductConfigModel: agentModels.AgentProductConfigModel,
|
|
||||||
AgentPlatformDeductionModel: agentModels.AgentPlatformDeductionModel,
|
|
||||||
AgentActiveStatModel: agentModels.AgentActiveStatModel,
|
|
||||||
AgentWithdrawalModel: agentModels.AgentWithdrawalModel,
|
|
||||||
AgentRealNameModel: agentModels.AgentRealNameModel,
|
|
||||||
|
|
||||||
// 管理后台相关模型
|
|
||||||
AdminApiModel: adminModels.AdminApiModel,
|
|
||||||
AdminMenuModel: adminModels.AdminMenuModel,
|
|
||||||
AdminRoleModel: adminModels.AdminRoleModel,
|
|
||||||
AdminRoleApiModel: adminModels.AdminRoleApiModel,
|
|
||||||
AdminRoleMenuModel: adminModels.AdminRoleMenuModel,
|
|
||||||
AdminUserModel: adminModels.AdminUserModel,
|
|
||||||
AdminUserRoleModel: adminModels.AdminUserRoleModel,
|
|
||||||
AdminDictDataModel: adminModels.AdminDictDataModel,
|
|
||||||
AdminDictTypeModel: adminModels.AdminDictTypeModel,
|
|
||||||
AdminPromotionLinkModel: adminModels.AdminPromotionLinkModel,
|
|
||||||
AdminPromotionLinkStatsTotalModel: adminModels.AdminPromotionLinkStatsTotalModel,
|
|
||||||
AdminPromotionLinkStatsHistoryModel: adminModels.AdminPromotionLinkStatsHistoryModel,
|
|
||||||
AdminPromotionOrderModel: adminModels.AdminPromotionOrderModel,
|
|
||||||
|
|
||||||
// 其他模型
|
|
||||||
ExampleModel: otherModels.ExampleModel,
|
|
||||||
GlobalNotificationsModel: otherModels.GlobalNotificationsModel,
|
|
||||||
|
|
||||||
// 服务
|
|
||||||
AlipayService: services.AlipayService,
|
|
||||||
WechatPayService: services.WechatPayService,
|
|
||||||
ApplePayService: services.ApplePayService,
|
|
||||||
WestDexService: services.WestDexService,
|
|
||||||
YushanService: services.YushanService,
|
|
||||||
ApiRequestService: services.ApiRequestService,
|
|
||||||
AsynqServer: services.AsynqServer,
|
|
||||||
AsynqService: services.AsynqService,
|
|
||||||
VerificationService: services.VerificationService,
|
|
||||||
AgentService: services.AgentService,
|
|
||||||
UserService: services.UserService,
|
|
||||||
DictService: services.DictService,
|
|
||||||
AdminPromotionLinkStatsService: services.AdminPromotionLinkStatsService,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,6 +962,9 @@ type BindMobileReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BindMobileResp struct {
|
type BindMobileResp struct {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Commission struct {
|
type Commission struct {
|
||||||
@ -1293,17 +1296,6 @@ type MobileCodeLoginResp struct {
|
|||||||
RefreshAfter int64 `json:"refreshAfter"`
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MobileLoginReq struct {
|
|
||||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
|
||||||
Password string `json:"password" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MobileLoginResp struct {
|
|
||||||
AccessToken string `json:"accessToken"`
|
|
||||||
AccessExpire int64 `json:"accessExpire"`
|
|
||||||
RefreshAfter int64 `json:"refreshAfter"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
Title string `json:"title"` // 通知标题
|
Title string `json:"title"` // 通知标题
|
||||||
Content string `json:"content"` // 通知内容 (富文本)
|
Content string `json:"content"` // 通知内容 (富文本)
|
||||||
@ -1596,18 +1588,6 @@ type RecordLinkClickResp struct {
|
|||||||
Success bool `json:"success"` // 是否成功
|
Success bool `json:"success"` // 是否成功
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegisterReq struct {
|
|
||||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
|
||||||
Password string `json:"password" validate:"required,min=11,max=11,password"`
|
|
||||||
Code string `json:"code" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegisterResp struct {
|
|
||||||
AccessToken string `json:"accessToken"`
|
|
||||||
AccessExpire int64 `json:"accessExpire"`
|
|
||||||
RefreshAfter int64 `json:"refreshAfter"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rewards struct {
|
type Rewards struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Amount float64 `json:"amount"`
|
Amount float64 `json:"amount"`
|
||||||
@ -1692,6 +1672,7 @@ type User struct {
|
|||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
Mobile string `json:"mobile"`
|
Mobile string `json:"mobile"`
|
||||||
NickName string `json:"nickName"`
|
NickName string `json:"nickName"`
|
||||||
|
UserType int64 `json:"userType"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserInfoResp struct {
|
type UserInfoResp struct {
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"tydata-server/app/main/api/internal/config"
|
"tydata-server/app/main/api/internal/config"
|
||||||
"tydata-server/app/main/api/internal/handler"
|
"tydata-server/app/main/api/internal/handler"
|
||||||
|
"tydata-server/app/main/api/internal/middleware"
|
||||||
"tydata-server/app/main/api/internal/queue"
|
"tydata-server/app/main/api/internal/queue"
|
||||||
"tydata-server/app/main/api/internal/svc"
|
"tydata-server/app/main/api/internal/svc"
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ func main() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
|
server.Use(middleware.GlobalSourceInterceptor)
|
||||||
defer server.Stop()
|
defer server.Stop()
|
||||||
|
|
||||||
handler.RegisterHandlers(server, svcContext)
|
handler.RegisterHandlers(server, svcContext)
|
||||||
|
27
app/main/model/userTempModel.go
Normal file
27
app/main/model/userTempModel.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 _ UserTempModel = (*customUserTempModel)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// UserTempModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customUserTempModel.
|
||||||
|
UserTempModel interface {
|
||||||
|
userTempModel
|
||||||
|
}
|
||||||
|
|
||||||
|
customUserTempModel struct {
|
||||||
|
*defaultUserTempModel
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewUserTempModel returns a model for the database table.
|
||||||
|
func NewUserTempModel(conn sqlx.SqlConn, c cache.CacheConf) UserTempModel {
|
||||||
|
return &customUserTempModel{
|
||||||
|
defaultUserTempModel: newUserTempModel(conn, c),
|
||||||
|
}
|
||||||
|
}
|
407
app/main/model/userTempModel_gen.go
Normal file
407
app/main/model/userTempModel_gen.go
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
// 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"
|
||||||
|
"tydata-server/common/globalkey"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
userTempFieldNames = builder.RawFieldNames(&UserTemp{})
|
||||||
|
userTempRows = strings.Join(userTempFieldNames, ",")
|
||||||
|
userTempRowsExpectAutoSet = strings.Join(stringx.Remove(userTempFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
|
||||||
|
userTempRowsWithPlaceHolder = strings.Join(stringx.Remove(userTempFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||||
|
|
||||||
|
cacheTydataUserTempIdPrefix = "cache:tydata:userTemp:id:"
|
||||||
|
cacheTydataUserTempAuthTypeAuthKeyPrefix = "cache:tydata:userTemp:authType:authKey:"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
userTempModel interface {
|
||||||
|
Insert(ctx context.Context, session sqlx.Session, data *UserTemp) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id int64) (*UserTemp, error)
|
||||||
|
FindOneByAuthTypeAuthKey(ctx context.Context, authType string, authKey string) (*UserTemp, error)
|
||||||
|
Update(ctx context.Context, session sqlx.Session, data *UserTemp) (sql.Result, error)
|
||||||
|
UpdateWithVersion(ctx context.Context, session sqlx.Session, data *UserTemp) 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 *UserTemp) 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) ([]*UserTemp, error)
|
||||||
|
FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserTemp, error)
|
||||||
|
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserTemp, int64, error)
|
||||||
|
FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*UserTemp, error)
|
||||||
|
FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*UserTemp, error)
|
||||||
|
Delete(ctx context.Context, session sqlx.Session, id int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultUserTempModel struct {
|
||||||
|
sqlc.CachedConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
UserTemp struct {
|
||||||
|
Id int64 `db:"id"`
|
||||||
|
AuthKey string `db:"auth_key"` // 平台唯一id
|
||||||
|
AuthType string `db:"auth_type"` // 平台类型
|
||||||
|
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 newUserTempModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultUserTempModel {
|
||||||
|
return &defaultUserTempModel{
|
||||||
|
CachedConn: sqlc.NewConn(conn, c),
|
||||||
|
table: "`user_temp`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) Insert(ctx context.Context, session sqlx.Session, data *UserTemp) (sql.Result, error) {
|
||||||
|
data.DelState = globalkey.DelStateNo
|
||||||
|
tydataUserTempAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheTydataUserTempAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
tydataUserTempIdKey := fmt.Sprintf("%s%v", cacheTydataUserTempIdPrefix, 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, userTempRowsExpectAutoSet)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, data.AuthKey, data.AuthType, data.DeleteTime, data.DelState, data.Version)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, data.AuthKey, data.AuthType, data.DeleteTime, data.DelState, data.Version)
|
||||||
|
}, tydataUserTempAuthTypeAuthKeyKey, tydataUserTempIdKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) FindOne(ctx context.Context, id int64) (*UserTemp, error) {
|
||||||
|
tydataUserTempIdKey := fmt.Sprintf("%s%v", cacheTydataUserTempIdPrefix, id)
|
||||||
|
var resp UserTemp
|
||||||
|
err := m.QueryRowCtx(ctx, &resp, tydataUserTempIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", userTempRows, 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 *defaultUserTempModel) FindOneByAuthTypeAuthKey(ctx context.Context, authType string, authKey string) (*UserTemp, error) {
|
||||||
|
tydataUserTempAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheTydataUserTempAuthTypeAuthKeyPrefix, authType, authKey)
|
||||||
|
var resp UserTemp
|
||||||
|
err := m.QueryRowIndexCtx(ctx, &resp, tydataUserTempAuthTypeAuthKeyKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `auth_type` = ? and `auth_key` = ? and del_state = ? limit 1", userTempRows, m.table)
|
||||||
|
if err := conn.QueryRowCtx(ctx, &resp, query, authType, authKey, 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 *defaultUserTempModel) Update(ctx context.Context, session sqlx.Session, newData *UserTemp) (sql.Result, error) {
|
||||||
|
data, err := m.FindOne(ctx, newData.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tydataUserTempAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheTydataUserTempAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
tydataUserTempIdKey := fmt.Sprintf("%s%v", cacheTydataUserTempIdPrefix, 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, userTempRowsWithPlaceHolder)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, newData.AuthKey, newData.AuthType, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, newData.AuthKey, newData.AuthType, newData.DeleteTime, newData.DelState, newData.Version, newData.Id)
|
||||||
|
}, tydataUserTempAuthTypeAuthKeyKey, tydataUserTempIdKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *UserTemp) 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
|
||||||
|
}
|
||||||
|
tydataUserTempAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheTydataUserTempAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
tydataUserTempIdKey := fmt.Sprintf("%s%v", cacheTydataUserTempIdPrefix, 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, userTempRowsWithPlaceHolder)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, newData.AuthKey, newData.AuthType, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, newData.AuthKey, newData.AuthType, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion)
|
||||||
|
}, tydataUserTempAuthTypeAuthKeyKey, tydataUserTempIdKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updateCount, err := sqlResult.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if updateCount == 0 {
|
||||||
|
return ErrNoRowsUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *UserTemp) 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 "), "UserTempModel delete err : %+v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) 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 *defaultUserTempModel) 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 *defaultUserTempModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*UserTemp, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userTempRows)
|
||||||
|
|
||||||
|
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 []*UserTemp
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserTemp, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userTempRows)
|
||||||
|
|
||||||
|
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 []*UserTemp
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserTemp, int64, error) {
|
||||||
|
|
||||||
|
total, err := m.FindCount(ctx, builder, "id")
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns(userTempRows)
|
||||||
|
|
||||||
|
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 []*UserTemp
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, total, nil
|
||||||
|
default:
|
||||||
|
return nil, total, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*UserTemp, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userTempRows)
|
||||||
|
|
||||||
|
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 []*UserTemp
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*UserTemp, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userTempRows)
|
||||||
|
|
||||||
|
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 []*UserTemp
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) 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 *defaultUserTempModel) SelectBuilder() squirrel.SelectBuilder {
|
||||||
|
return squirrel.Select().From(m.table)
|
||||||
|
}
|
||||||
|
func (m *defaultUserTempModel) Delete(ctx context.Context, session sqlx.Session, id int64) error {
|
||||||
|
data, err := m.FindOne(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tydataUserTempAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheTydataUserTempAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
tydataUserTempIdKey := fmt.Sprintf("%s%v", cacheTydataUserTempIdPrefix, 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)
|
||||||
|
}, tydataUserTempAuthTypeAuthKeyKey, tydataUserTempIdKey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func (m *defaultUserTempModel) formatPrimary(primary interface{}) string {
|
||||||
|
return fmt.Sprintf("%s%v", cacheTydataUserTempIdPrefix, primary)
|
||||||
|
}
|
||||||
|
func (m *defaultUserTempModel) 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", userTempRows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserTempModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
@ -9,15 +9,20 @@ import (
|
|||||||
var ErrNotFound = sqlx.ErrNotFound
|
var ErrNotFound = sqlx.ErrNotFound
|
||||||
var ErrNoRowsUpdate = errors.New("update db no rows change")
|
var ErrNoRowsUpdate = errors.New("update db no rows change")
|
||||||
|
|
||||||
var UserAuthTypeAppMobile string = "app_mobile" //平台内部
|
// 平台
|
||||||
var UserAuthTypeAppWechat string = "app_wechat" //微信小程序
|
var PlatformWxMini string = "wxmini"
|
||||||
var UserAuthTypeH5Mobile string = "h5_mobile"
|
var PlatformWxH5 string = "wxh5"
|
||||||
var UserAuthTypeWxMini string = "wx_mini"
|
var PlatformApp string = "app"
|
||||||
var UserAuthTypeWxh5 string = "wx_h5"
|
var PlatformH5 string = "h5"
|
||||||
var UserAuthTypeAgentDirect string = "agent_direct"
|
var PlatformAdmin string = "admin"
|
||||||
var UserAuthTypeAgentPromote string = "agent_promote"
|
|
||||||
|
// 用户授权类型
|
||||||
|
var UserAuthTypeMobile string = "mobile"
|
||||||
|
var UserAuthTypeWxMiniOpenID string = "wxmini_openid"
|
||||||
|
var UserAuthTypeWxh5OpenID string = "wxh5_openid"
|
||||||
var UserAuthTypeUUID string = "uuid"
|
var UserAuthTypeUUID string = "uuid"
|
||||||
|
|
||||||
|
// 代理扣除类型
|
||||||
var AgentDeductionTypeCost string = "cost"
|
var AgentDeductionTypeCost string = "cost"
|
||||||
var AgentDeductionTypePricing string = "pricing"
|
var AgentDeductionTypePricing string = "pricing"
|
||||||
|
|
||||||
@ -78,3 +83,16 @@ const (
|
|||||||
AgentRealNameStatusApproved = "approved"
|
AgentRealNameStatusApproved = "approved"
|
||||||
AgentRealNameStatusRejected = "rejected"
|
AgentRealNameStatusRejected = "rejected"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 用户身份类型
|
||||||
|
const (
|
||||||
|
UserTypeTemp = 0 // 临时用户
|
||||||
|
UserTypeNormal = 1 // 正式用户
|
||||||
|
UserTypeAdmin = 2 // 管理员
|
||||||
|
)
|
||||||
|
|
||||||
|
// 代理状态
|
||||||
|
const (
|
||||||
|
AgentStatusNo = 0 // 非代理
|
||||||
|
AgentStatusYes = 1 // 是代理
|
||||||
|
)
|
||||||
|
@ -5,13 +5,15 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"tydata-server/app/main/model"
|
||||||
|
jwtx "tydata-server/common/jwt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CtxKeyJwtUserId = "userId"
|
const CtxKeyJwtUserId = "userId"
|
||||||
|
|
||||||
// 定义错误类型
|
// 定义错误类型
|
||||||
var (
|
var (
|
||||||
ErrNoUserIdInCtx = errors.New("上下文中没有用户ID") // 未登录
|
ErrNoInCtx = errors.New("上下文中没有相关数据")
|
||||||
ErrInvalidUserId = errors.New("用户ID格式无效") // 数据异常
|
ErrInvalidUserId = errors.New("用户ID格式无效") // 数据异常
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,7 +22,11 @@ func GetUidFromCtx(ctx context.Context) (int64, error) {
|
|||||||
// 尝试从上下文中获取 jwtUserId
|
// 尝试从上下文中获取 jwtUserId
|
||||||
value := ctx.Value(CtxKeyJwtUserId)
|
value := ctx.Value(CtxKeyJwtUserId)
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return 0, ErrNoUserIdInCtx
|
claims, err := GetClaimsFromCtx(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return claims.UserId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据值的类型进行不同处理
|
// 根据值的类型进行不同处理
|
||||||
@ -47,12 +53,52 @@ func GetUidFromCtx(ctx context.Context) (int64, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetClaimsFromCtx(ctx context.Context) (*jwtx.JwtClaims, error) {
|
||||||
|
value := ctx.Value(jwtx.ExtraKey)
|
||||||
|
if value == nil {
|
||||||
|
return nil, ErrNoInCtx
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首先尝试直接断言为 *jwtx.JwtClaims
|
||||||
|
if claims, ok := value.(*jwtx.JwtClaims); ok {
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果直接断言失败,尝试从 map[string]interface{} 中解析
|
||||||
|
if claimsMap, ok := value.(map[string]interface{}); ok {
|
||||||
|
return jwtx.MapToJwtClaims(claimsMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, ErrNoInCtx
|
||||||
|
}
|
||||||
|
|
||||||
// IsNoUserIdError 判断是否是未登录错误
|
// IsNoUserIdError 判断是否是未登录错误
|
||||||
func IsNoUserIdError(err error) bool {
|
func IsNoUserIdError(err error) bool {
|
||||||
return errors.Is(err, ErrNoUserIdInCtx)
|
return errors.Is(err, ErrNoInCtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInvalidUserIdError 判断是否是用户ID格式错误
|
// IsInvalidUserIdError 判断是否是用户ID格式错误
|
||||||
func IsInvalidUserIdError(err error) bool {
|
func IsInvalidUserIdError(err error) bool {
|
||||||
return errors.Is(err, ErrInvalidUserId)
|
return errors.Is(err, ErrInvalidUserId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPlatformFromCtx 从 context 中获取平台
|
||||||
|
func GetPlatformFromCtx(ctx context.Context) (string, error) {
|
||||||
|
platform, platformOk := ctx.Value("platform").(string)
|
||||||
|
if !platformOk {
|
||||||
|
return "", fmt.Errorf("平台不存在: %s", platform)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch platform {
|
||||||
|
case model.PlatformWxMini:
|
||||||
|
return model.PlatformWxMini, nil
|
||||||
|
case model.PlatformWxH5:
|
||||||
|
return model.PlatformWxH5, nil
|
||||||
|
case model.PlatformApp:
|
||||||
|
return model.PlatformApp, nil
|
||||||
|
case model.PlatformH5:
|
||||||
|
return model.PlatformH5, nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("不支持的支付平台: %s", platform)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,179 +0,0 @@
|
|||||||
package ctxdata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetUidFromCtx(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
ctxSetup func() context.Context
|
|
||||||
wantUid int64
|
|
||||||
wantError error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "正常情况_有效用户ID_json.Number",
|
|
||||||
ctxSetup: func() context.Context {
|
|
||||||
return context.WithValue(context.Background(), CtxKeyJwtUserId, json.Number("12345"))
|
|
||||||
},
|
|
||||||
wantUid: 12345,
|
|
||||||
wantError: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "正常情况_有效用户ID_int64",
|
|
||||||
ctxSetup: func() context.Context {
|
|
||||||
return context.WithValue(context.Background(), CtxKeyJwtUserId, int64(12345))
|
|
||||||
},
|
|
||||||
wantUid: 12345,
|
|
||||||
wantError: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "正常情况_有效用户ID_int",
|
|
||||||
ctxSetup: func() context.Context {
|
|
||||||
return context.WithValue(context.Background(), CtxKeyJwtUserId, 12345)
|
|
||||||
},
|
|
||||||
wantUid: 12345,
|
|
||||||
wantError: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "正常情况_有效用户ID_float64",
|
|
||||||
ctxSetup: func() context.Context {
|
|
||||||
return context.WithValue(context.Background(), CtxKeyJwtUserId, float64(12345))
|
|
||||||
},
|
|
||||||
wantUid: 12345,
|
|
||||||
wantError: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "异常情况_上下文中无用户ID",
|
|
||||||
ctxSetup: func() context.Context {
|
|
||||||
return context.Background()
|
|
||||||
},
|
|
||||||
wantUid: 0,
|
|
||||||
wantError: ErrNoUserIdInCtx,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "异常情况_用户ID类型错误",
|
|
||||||
ctxSetup: func() context.Context {
|
|
||||||
return context.WithValue(context.Background(), CtxKeyJwtUserId, "非数字类型")
|
|
||||||
},
|
|
||||||
wantUid: 0,
|
|
||||||
wantError: ErrInvalidUserId,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "异常情况_用户ID无法转换为int64",
|
|
||||||
ctxSetup: func() context.Context {
|
|
||||||
return context.WithValue(context.Background(), CtxKeyJwtUserId, json.Number("非数字内容"))
|
|
||||||
},
|
|
||||||
wantUid: 0,
|
|
||||||
wantError: ErrInvalidUserId,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
ctx := tt.ctxSetup()
|
|
||||||
gotUid, gotErr := GetUidFromCtx(ctx)
|
|
||||||
|
|
||||||
// 检查返回的用户ID
|
|
||||||
if gotUid != tt.wantUid {
|
|
||||||
t.Errorf("GetUidFromCtx() 返回用户ID = %v, 期望值 %v", gotUid, tt.wantUid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查错误类型
|
|
||||||
if tt.wantError == nil && gotErr != nil {
|
|
||||||
t.Errorf("GetUidFromCtx() 返回意外错误 = %v", gotErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if tt.wantError != nil && !errors.Is(gotErr, tt.wantError) {
|
|
||||||
t.Errorf("GetUidFromCtx() 错误类型 = %v, 期望错误类型 %v", gotErr, tt.wantError)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsNoUserIdError(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
err error
|
|
||||||
expected bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "是未登录错误",
|
|
||||||
err: ErrNoUserIdInCtx,
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "包装的未登录错误",
|
|
||||||
err: errors.New("外层错误: " + ErrNoUserIdInCtx.Error()),
|
|
||||||
expected: false, // 直接字符串拼接不会保留错误链
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "使用fmt.Errorf包装的未登录错误",
|
|
||||||
err: errors.New("外层错误"),
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "非未登录错误",
|
|
||||||
err: ErrInvalidUserId,
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "nil错误",
|
|
||||||
err: nil,
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := IsNoUserIdError(tt.err); got != tt.expected {
|
|
||||||
t.Errorf("IsNoUserIdError() = %v, 期望值 %v", got, tt.expected)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsInvalidUserIdError(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
err error
|
|
||||||
expected bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "是无效用户ID错误",
|
|
||||||
err: ErrInvalidUserId,
|
|
||||||
expected: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "包装的无效用户ID错误",
|
|
||||||
err: errors.New("外层错误: " + ErrInvalidUserId.Error()),
|
|
||||||
expected: false, // 直接字符串拼接不会保留错误链
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "使用fmt.Errorf包装的无效用户ID错误",
|
|
||||||
err: errors.New("外层错误"),
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "非无效用户ID错误",
|
|
||||||
err: ErrNoUserIdInCtx,
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "nil错误",
|
|
||||||
err: nil,
|
|
||||||
expected: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := IsInvalidUserIdError(tt.err); got != tt.expected {
|
|
||||||
t.Errorf("IsInvalidUserIdError() = %v, 期望值 %v", got, tt.expected)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +1,94 @@
|
|||||||
package jwtx
|
package jwtx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/golang-jwt/jwt/v4"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Token 生成逻辑的函数,接收 userId、过期时间和密钥,返回生成的 token
|
const ExtraKey = "extra"
|
||||||
func GenerateJwtToken(userId int64, secret string, expireTime int64) (string, error) {
|
|
||||||
// 获取当前时间戳
|
type JwtClaims struct {
|
||||||
now := time.Now().Unix()
|
UserId int64 `json:"userId"`
|
||||||
// 定义 JWT Claims
|
AgentId int64 `json:"agentId"`
|
||||||
claims := jwt.MapClaims{
|
Platform string `json:"platform"`
|
||||||
"exp": now + expireTime, // token 过期时间
|
// 用户身份类型:0-临时用户,1-正式用户
|
||||||
"iat": now, // 签发时间
|
UserType int64 `json:"userType"`
|
||||||
"userId": userId, // 用户ID
|
// 是否代理:0-否,1-是
|
||||||
|
IsAgent int64 `json:"isAgent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MapToJwtClaims 将 map[string]interface{} 转换为 JwtClaims 结构体
|
||||||
|
func MapToJwtClaims(claimsMap map[string]interface{}) (*JwtClaims, error) {
|
||||||
|
// 使用JSON序列化/反序列化的方式自动转换
|
||||||
|
jsonData, err := json.Marshal(claimsMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("序列化claims失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新的 JWT token
|
var claims JwtClaims
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
if err := json.Unmarshal(jsonData, &claims); err != nil {
|
||||||
|
return nil, errors.New("反序列化claims失败")
|
||||||
|
}
|
||||||
|
|
||||||
// 使用密钥对 token 签名
|
return &claims, nil
|
||||||
signedToken, err := token.SignedString([]byte(secret))
|
}
|
||||||
|
|
||||||
|
// GenerateJwtToken 生成JWT token
|
||||||
|
func GenerateJwtToken(claims JwtClaims, secret string, expire int64) (string, error) {
|
||||||
|
now := time.Now().Unix()
|
||||||
|
|
||||||
|
// 将 claims 结构体转换为 map[string]interface{}
|
||||||
|
claimsBytes, err := json.Marshal(claims)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return signedToken, nil
|
var claimsMap map[string]interface{}
|
||||||
|
if err := json.Unmarshal(claimsBytes, &claimsMap); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
jwtClaims := jwt.MapClaims{
|
||||||
|
"exp": now + expire,
|
||||||
|
"iat": now,
|
||||||
|
"userId": claims.UserId,
|
||||||
|
ExtraKey: claimsMap,
|
||||||
|
}
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims)
|
||||||
|
return token.SignedString([]byte(secret))
|
||||||
}
|
}
|
||||||
func ParseJwtToken(tokenStr string, secret string) (int64, error) {
|
|
||||||
|
func ParseJwtToken(tokenStr string, secret string) (*JwtClaims, error) {
|
||||||
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
|
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
|
||||||
return []byte(secret), nil
|
return []byte(secret), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil || !token.Valid {
|
if err != nil || !token.Valid {
|
||||||
return 0, errors.New("invalid JWT")
|
return nil, errors.New("invalid JWT")
|
||||||
}
|
}
|
||||||
|
|
||||||
claims, ok := token.Claims.(jwt.MapClaims)
|
claims, ok := token.Claims.(jwt.MapClaims)
|
||||||
if !ok || !token.Valid {
|
if !ok || !token.Valid {
|
||||||
return 0, errors.New("invalid JWT claims")
|
return nil, errors.New("invalid JWT claims")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从 claims 中提取 userId
|
extraInfo, exists := claims[ExtraKey]
|
||||||
userIdRaw, ok := claims["userId"]
|
if !exists {
|
||||||
if !ok {
|
return nil, errors.New("extra not found in JWT")
|
||||||
return 0, errors.New("userId not found in JWT")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理不同类型的 userId,确保它被转换为 int64
|
// 尝试直接断言为 JwtClaims 结构体
|
||||||
switch userId := userIdRaw.(type) {
|
if jwtClaims, ok := extraInfo.(JwtClaims); ok {
|
||||||
case float64:
|
return &jwtClaims, nil
|
||||||
return int64(userId), nil
|
|
||||||
case int64:
|
|
||||||
return userId, nil
|
|
||||||
case string:
|
|
||||||
// 如果 userId 是字符串,可以尝试将其转换为 int64
|
|
||||||
parsedId, err := strconv.ParseInt(userId, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.New("invalid userId in JWT")
|
|
||||||
}
|
}
|
||||||
return parsedId, nil
|
|
||||||
default:
|
// 尝试从 map[string]interface{} 中解析
|
||||||
return 0, errors.New("unsupported userId type in JWT")
|
if claimsMap, ok := extraInfo.(map[string]interface{}); ok {
|
||||||
|
return MapToJwtClaims(claimsMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("unsupported extra type in JWT")
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ const DB_UPDATE_AFFECTED_ZERO_ERROR uint32 = 100006
|
|||||||
const PARAM_VERIFICATION_ERROR uint32 = 100007
|
const PARAM_VERIFICATION_ERROR uint32 = 100007
|
||||||
const CUSTOM_ERROR uint32 = 100008
|
const CUSTOM_ERROR uint32 = 100008
|
||||||
const USER_NOT_FOUND uint32 = 100009
|
const USER_NOT_FOUND uint32 = 100009
|
||||||
|
const USER_NEED_BIND_MOBILE uint32 = 100010
|
||||||
|
|
||||||
const LOGIN_FAILED uint32 = 200001
|
const LOGIN_FAILED uint32 = 200001
|
||||||
const LOGIC_QUERY_WAIT uint32 = 200002
|
const LOGIC_QUERY_WAIT uint32 = 200002
|
||||||
|
@ -33,9 +33,10 @@ $tables = @(
|
|||||||
# "query",
|
# "query",
|
||||||
# "query_cleanup_log"
|
# "query_cleanup_log"
|
||||||
# "query_cleanup_detail"
|
# "query_cleanup_detail"
|
||||||
"query_cleanup_config"
|
# "query_cleanup_config"
|
||||||
# "user"
|
# "user"
|
||||||
# "user_auth"
|
# "user_auth"
|
||||||
|
"user_temp"
|
||||||
# "example"
|
# "example"
|
||||||
# "admin_user"
|
# "admin_user"
|
||||||
# "admin_user_role"
|
# "admin_user_role"
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
func TestAesEcbMobileEncryption(t *testing.T) {
|
func TestAesEcbMobileEncryption(t *testing.T) {
|
||||||
// 测试手机号加密
|
// 测试手机号加密
|
||||||
mobile := "13280082033 "
|
mobile := "17776203797 "
|
||||||
key := []byte("ff83609b2b24fc73196aac3d3dfb874f") // 16字节AES-128密钥
|
key := []byte("ff83609b2b24fc73196aac3d3dfb874f") // 16字节AES-128密钥
|
||||||
|
|
||||||
keyStr := hex.EncodeToString(key)
|
keyStr := hex.EncodeToString(key)
|
||||||
@ -19,7 +19,7 @@ func TestAesEcbMobileEncryption(t *testing.T) {
|
|||||||
t.Fatalf("手机号加密失败: %v", err)
|
t.Fatalf("手机号加密失败: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("encrypted: %s\n", encrypted)
|
fmt.Printf("encrypted: %s\n", encrypted)
|
||||||
jmStr := "oEpLcrIpDPN63rOlESXTDg=="
|
jmStr := "m9EEeW9ZBBJmi1hx1k1uIQ=="
|
||||||
// 测试解密
|
// 测试解密
|
||||||
decrypted, err := DecryptMobile(jmStr, keyStr)
|
decrypted, err := DecryptMobile(jmStr, keyStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user