新版本,代理功能上线
This commit is contained in:
@@ -40,12 +40,15 @@ type Encrypt struct {
|
||||
}
|
||||
|
||||
type AlipayConfig struct {
|
||||
AppID string
|
||||
PrivateKey string
|
||||
AlipayPublicKey string
|
||||
IsProduction bool
|
||||
NotifyUrl string
|
||||
ReturnURL string
|
||||
AppID string
|
||||
PrivateKey string
|
||||
AlipayPublicKey string
|
||||
AppCertPath string // 应用公钥证书路径
|
||||
AlipayCertPath string // 支付宝公钥证书路径
|
||||
AlipayRootCertPath string // 根证书路径
|
||||
IsProduction bool
|
||||
NotifyUrl string
|
||||
ReturnURL string
|
||||
}
|
||||
type WxpayConfig struct {
|
||||
AppID string
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func ActivateAgentMembershipHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.AgentActivateMembershipReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := agent.NewActivateAgentMembershipLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ActivateAgentMembership(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
package query
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/query"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func RentalInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
func ApplyForAgentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.QueryReq
|
||||
var req types.AgentApplyReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
@@ -22,8 +22,8 @@ func RentalInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := query.NewRentalInfoLogic(r.Context(), svcCtx)
|
||||
resp, err := l.RentalInfo(&req)
|
||||
l := agent.NewApplyForAgentLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ApplyForAgent(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
package query
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/query"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func RiskAssessmentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
func GeneratingLinkHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.QueryReq
|
||||
var req types.AgentGeneratingLinkReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
@@ -22,8 +22,8 @@ func RiskAssessmentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := query.NewRiskAssessmentLogic(r.Context(), svcCtx)
|
||||
resp, err := l.RiskAssessment(&req)
|
||||
l := agent.NewGeneratingLinkLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GeneratingLink(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/common/result"
|
||||
)
|
||||
|
||||
func GetAgentAuditStatusHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := agent.NewGetAgentAuditStatusLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetAgentAuditStatus()
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/common/result"
|
||||
)
|
||||
|
||||
func GetAgentInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := agent.NewGetAgentInfoLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetAgentInfo()
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func GetAgentMembershipProductConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.AgentMembershipProductConfigReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := agent.NewGetAgentMembershipProductConfigLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetAgentMembershipProductConfig(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/common/result"
|
||||
)
|
||||
|
||||
func GetAgentProductConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := agent.NewGetAgentProductConfigLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetAgentProductConfig()
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func GetAgentRevenueInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetAgentRevenueInfoReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := agent.NewGetAgentRevenueInfoLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetAgentRevenueInfo(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
package query
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/query"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func CompanyInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
func GetLinkDataHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.QueryReq
|
||||
var req types.GetLinkDataReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
@@ -22,8 +22,8 @@ func CompanyInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := query.NewCompanyInfoLogic(r.Context(), svcCtx)
|
||||
resp, err := l.CompanyInfo(&req)
|
||||
l := agent.NewGetLinkDataLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetLinkData(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/agent"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func SaveAgentMembershipUserConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.SaveAgentMembershipUserConfigReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
if err := validator.Validate(req); err != nil {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := agent.NewSaveAgentMembershipUserConfigLogic(r.Context(), svcCtx)
|
||||
err := l.SaveAgentMembershipUserConfig(&req)
|
||||
result.HttpResult(r, w, nil, err)
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func BackgroundCheckHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
func QueryServiceAgentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.QueryReq
|
||||
var req types.QueryServiceReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
@@ -22,8 +22,8 @@ func BackgroundCheckHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := query.NewBackgroundCheckLogic(r.Context(), svcCtx)
|
||||
resp, err := l.BackgroundCheck(&req)
|
||||
l := query.NewQueryServiceLogic(r.Context(), svcCtx)
|
||||
resp, err := l.QueryService(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
agent "tydata-server/app/user/cmd/api/internal/handler/agent"
|
||||
auth "tydata-server/app/user/cmd/api/internal/handler/auth"
|
||||
notification "tydata-server/app/user/cmd/api/internal/handler/notification"
|
||||
pay "tydata-server/app/user/cmd/api/internal/handler/pay"
|
||||
@@ -16,6 +17,89 @@ import (
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/audit/status",
|
||||
Handler: agent.GetAgentAuditStatusHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/commission",
|
||||
Handler: agent.GetAgentCommissionHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/generating_link",
|
||||
Handler: agent.GeneratingLinkHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/info",
|
||||
Handler: agent.GetAgentInfoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/membership/save_user_config",
|
||||
Handler: agent.SaveAgentMembershipUserConfigHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/membership/user_config",
|
||||
Handler: agent.GetAgentMembershipProductConfigHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/product_config",
|
||||
Handler: agent.GetAgentProductConfigHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/revenue",
|
||||
Handler: agent.GetAgentRevenueInfoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/rewards",
|
||||
Handler: agent.GetAgentRewardsHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/withdrawal",
|
||||
Handler: agent.GetAgentWithdrawalHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/withdrawal",
|
||||
Handler: agent.AgentWithdrawalHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||
rest.WithPrefix("/api/v1/agent"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/apply",
|
||||
Handler: agent.ApplyForAgentHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/link",
|
||||
Handler: agent.GetLinkDataHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/membership/activate",
|
||||
Handler: agent.ActivateAgentMembershipHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/v1/agent"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
@@ -101,47 +185,17 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// query general background check
|
||||
// query service agent
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/backgroundCheck",
|
||||
Handler: query.BackgroundCheckHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// query company info
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/companyInfo",
|
||||
Handler: query.CompanyInfoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// query home service
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/homeService",
|
||||
Handler: query.HomeServiceHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// query marriage
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/marriage",
|
||||
Handler: query.MarriageHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// query pre-loan background check
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/preLoanBackgroundCheck",
|
||||
Handler: query.PreLoanBackgroundCheckHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// query rental info
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/rentalInfo",
|
||||
Handler: query.RentalInfoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// query risk assessment
|
||||
Method: http.MethodPost,
|
||||
Path: "/query/riskAssessment",
|
||||
Handler: query.RiskAssessmentHandler(serverCtx),
|
||||
Path: "/query/service_agent/:product",
|
||||
Handler: query.QueryServiceAgentHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/v1"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// query service
|
||||
Method: http.MethodPost,
|
||||
@@ -204,6 +258,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// agent mobile code login
|
||||
Method: http.MethodPost,
|
||||
Path: "/user/agent_mobile_code_login",
|
||||
Handler: user.AgentMobileCodeLoginHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// mobile code login
|
||||
Method: http.MethodPost,
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package query
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/query"
|
||||
"tydata-server/app/user/cmd/api/internal/logic/user"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/result"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
func PreLoanBackgroundCheckHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
func AgentMobileCodeLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.QueryReq
|
||||
var req types.MobileCodeLoginReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
result.ParamErrorResult(r, w, err)
|
||||
return
|
||||
@@ -22,8 +22,8 @@ func PreLoanBackgroundCheckHandler(svcCtx *svc.ServiceContext) http.HandlerFunc
|
||||
result.ParamValidateErrorResult(r, w, err)
|
||||
return
|
||||
}
|
||||
l := query.NewPreLoanBackgroundCheckLogic(r.Context(), svcCtx)
|
||||
resp, err := l.PreLoanBackgroundCheck(&req)
|
||||
l := user.NewAgentMobileCodeLoginLogic(r.Context(), svcCtx)
|
||||
resp, err := l.AgentMobileCodeLogin(&req)
|
||||
result.HttpResult(r, w, resp, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"time"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ActivateAgentMembershipLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewActivateAgentMembershipLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ActivateAgentMembershipLogic {
|
||||
return &ActivateAgentMembershipLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ActivateAgentMembershipLogic) ActivateAgentMembership(req *types.AgentActivateMembershipReq) (resp *types.AgentActivateMembershipResp, err error) {
|
||||
//userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败: %v", err)
|
||||
//}
|
||||
userModel, err := l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
|
||||
}
|
||||
// 查询用户代理信息
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userModel.Id)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
|
||||
}
|
||||
|
||||
// 定义等级顺序映射
|
||||
levelOrder := map[string]int{
|
||||
"": 1,
|
||||
model.AgentLeveNameNormal: 1,
|
||||
model.AgentLeveNameVIP: 2,
|
||||
model.AgentLeveNameSVIP: 3,
|
||||
}
|
||||
|
||||
// 验证请求等级合法性
|
||||
if _, valid := levelOrder[req.Type]; !valid {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "无效的代理等级: %s", req.Type)
|
||||
}
|
||||
|
||||
// 如果存在代理记录,进行等级验证
|
||||
if agentModel != nil {
|
||||
currentLevel, exists := levelOrder[agentModel.LevelName]
|
||||
if !exists {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
|
||||
"非法的当前代理等级: %s", agentModel.LevelName)
|
||||
}
|
||||
|
||||
requestedLevel := levelOrder[req.Type]
|
||||
if requestedLevel < currentLevel {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
|
||||
"禁止降级操作(当前等级:%s,请求等级:%s)", agentModel.LevelName, req.Type)
|
||||
}
|
||||
}
|
||||
|
||||
err = l.svcCtx.AgentModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
|
||||
agentModel.LevelName = req.Type
|
||||
agentModel.MembershipExpiryTime = RenewMembership(agentModel.MembershipExpiryTime)
|
||||
transErr := l.svcCtx.AgentModel.UpdateWithVersion(transCtx, session, agentModel)
|
||||
if transErr != nil {
|
||||
return transErr
|
||||
}
|
||||
agentMembershipRechargeOrder := model.AgentMembershipRechargeOrder{
|
||||
AgentId: agentModel.Id,
|
||||
UserId: userModel.Id,
|
||||
LevelName: req.Type,
|
||||
Amount: req.Amount,
|
||||
PaymentMethod: req.PaymentMethod,
|
||||
TransactionId: req.TransactionId,
|
||||
}
|
||||
_, transErr = l.svcCtx.AgentMembershipRechargeOrderModel.Insert(transCtx, session, &agentMembershipRechargeOrder)
|
||||
if transErr != nil {
|
||||
return transErr
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "升级代理等级失败: %s", req.Type)
|
||||
}
|
||||
return &types.AgentActivateMembershipResp{
|
||||
MembershipType: req.Type,
|
||||
ExpireTime: agentModel.MembershipExpiryTime.Time.Format("2006-01-02 15:04:05"),
|
||||
}, nil
|
||||
}
|
||||
func RenewMembership(expiry sql.NullTime) sql.NullTime {
|
||||
// 确定基准时间
|
||||
var baseTime time.Time
|
||||
if expiry.Valid {
|
||||
baseTime = expiry.Time
|
||||
} else {
|
||||
baseTime = time.Now()
|
||||
}
|
||||
|
||||
// 增加一年(自动处理闰年)
|
||||
newTime := baseTime.AddDate(1, 0, 0)
|
||||
|
||||
// 返回始终有效的 NullTime
|
||||
return sql.NullTime{
|
||||
Time: newTime,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
305
app/user/cmd/api/internal/logic/agent/agentwithdrawallogic.go
Normal file
305
app/user/cmd/api/internal/logic/agent/agentwithdrawallogic.go
Normal file
@@ -0,0 +1,305 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"time"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/lzUtils"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
// 状态常量
|
||||
const (
|
||||
StatusProcessing = 1 // 处理中
|
||||
StatusSuccess = 2 // 成功
|
||||
StatusFailed = 3 // 失败
|
||||
)
|
||||
|
||||
// 前端响应状态
|
||||
const (
|
||||
WithdrawStatusProcessing = 1
|
||||
WithdrawStatusSuccess = 2
|
||||
WithdrawStatusFailed = 3
|
||||
)
|
||||
|
||||
type AgentWithdrawalLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewAgentWithdrawalLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AgentWithdrawalLogic {
|
||||
return &AgentWithdrawalLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types.WithdrawalResp, error) {
|
||||
var (
|
||||
outBizNo string
|
||||
withdrawRes = &types.WithdrawalResp{}
|
||||
)
|
||||
|
||||
// 使用事务处理核心操作
|
||||
err := l.svcCtx.AgentModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败: %v", err)
|
||||
}
|
||||
|
||||
// 查询代理信息
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败: %v", err)
|
||||
}
|
||||
|
||||
// 查询钱包
|
||||
agentWallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agentModel.Id)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理钱包失败: %v", err)
|
||||
}
|
||||
|
||||
// 校验可提现金额
|
||||
withdrawableAmount := agentWallet.Balance - agentWallet.FrozenBalance
|
||||
if req.Amount > withdrawableAmount {
|
||||
return errors.Wrapf(xerr.NewErrMsg("您可提现的余额不足"), "获取用户ID失败")
|
||||
}
|
||||
|
||||
// 生成交易号
|
||||
outBizNo = l.svcCtx.AlipayService.GenerateOutTradeNo()
|
||||
|
||||
// 创建提现记录(初始状态为处理中)
|
||||
if err = l.createWithdrawalRecord(session, agentModel.Id, req, outBizNo); err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
|
||||
}
|
||||
|
||||
// 冻结资金(事务内操作)
|
||||
if err = l.freezeFunds(session, agentWallet, req.Amount); err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "资金冻结失败: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 同步调用支付宝转账
|
||||
transferResp, err := l.svcCtx.AlipayService.AliTransfer(l.ctx, req.PayeeAccount, req.PayeeName, req.Amount, "代理提现", outBizNo)
|
||||
if err != nil {
|
||||
l.handleTransferError(outBizNo, err, "支付宝接口调用失败")
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "支付宝接口调用失败: %v", err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case transferResp.Status == "SUCCESS":
|
||||
// 立即处理成功状态
|
||||
l.handleTransferSuccess(outBizNo, transferResp)
|
||||
withdrawRes.Status = WithdrawStatusSuccess
|
||||
case transferResp.Status == "FAIL" || transferResp.SubCode != "":
|
||||
// 处理明确失败
|
||||
errorMsg := l.mapAlipayError(transferResp.SubCode)
|
||||
l.handleTransferFailure(outBizNo, transferResp)
|
||||
withdrawRes.Status = WithdrawStatusFailed
|
||||
withdrawRes.FailMsg = errorMsg
|
||||
case transferResp.Status == "DEALING":
|
||||
// 处理中状态,启动异步轮询
|
||||
go l.startAsyncPolling(outBizNo)
|
||||
withdrawRes.Status = WithdrawStatusProcessing
|
||||
default:
|
||||
// 未知状态按失败处理
|
||||
l.handleTransferError(outBizNo, fmt.Errorf("未知状态:%s", transferResp.Status), "支付宝返回未知状态")
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "支付宝接口调用失败: %v", err)
|
||||
}
|
||||
return withdrawRes, nil
|
||||
}
|
||||
|
||||
// 错误类型映射
|
||||
func (l *AgentWithdrawalLogic) mapAlipayError(code string) string {
|
||||
errorMapping := map[string]string{
|
||||
// 账户存在性错误
|
||||
"PAYEE_ACCOUNT_NOT_EXSIT": "收款账户不存在,请检查账号是否正确",
|
||||
"PAYEE_NOT_EXIST": "收款账户不存在或姓名有误,请核实信息",
|
||||
"PAYEE_ACC_OCUPIED": "收款账号存在多个账户,无法确认唯一性",
|
||||
"PAYEE_MID_CANNOT_SAME": "收款方和中间方不能是同一个人,请修改收款方或者中间方信息",
|
||||
|
||||
// 实名认证问题
|
||||
"PAYEE_CERTIFY_LEVEL_LIMIT": "收款方未完成实名认证",
|
||||
"PAYEE_NOT_RELNAME_CERTIFY": "收款方未完成实名认证",
|
||||
"PAYEE_CERT_INFO_ERROR": "收款方证件信息不匹配",
|
||||
|
||||
// 账户状态异常
|
||||
"PAYEE_ACCOUNT_STATUS_ERROR": "收款账户状态异常,请更换账号",
|
||||
"PAYEE_USERINFO_STATUS_ERROR": "收款账户状态异常,无法收款",
|
||||
"PERMIT_LIMIT_PAYEE": "收款账户异常,请更换账号",
|
||||
"BLOCK_USER_FORBBIDEN_RECIEVE": "账户冻结无法收款",
|
||||
"PAYEE_TRUSTEESHIP_ACC_OVER_LIMIT": "收款方托管子户累计收款金额超限",
|
||||
|
||||
// 账户信息错误
|
||||
"PAYEE_USERINFO_ERROR": "收款方姓名或信息不匹配",
|
||||
"PAYEE_CARD_INFO_ERROR": "收款支付宝账号及户名不一致",
|
||||
"PAYEE_IDENTITY_NOT_MATCH": "收款方身份信息不匹配",
|
||||
"PAYEE_USER_IS_INST": "收款方为金融机构,不能使用提现功能,请更换收款账号",
|
||||
"PAYEE_USER_TYPE_ERROR": "该支付宝账号类型不支持提现,请更换收款账号",
|
||||
|
||||
// 权限与限制
|
||||
"PAYEE_RECEIVE_COUNT_EXCEED_LIMIT": "收款次数超限,请明日再试",
|
||||
"PAYEE_OUT_PERMLIMIT_CHECK_FAILURE": "收款方权限校验不通过",
|
||||
"PERMIT_NON_BANK_LIMIT_PAYEE": "收款方未完善身份信息,无法收款",
|
||||
}
|
||||
if msg, ok := errorMapping[code]; ok {
|
||||
return msg
|
||||
}
|
||||
return "系统错误,请联系客服"
|
||||
}
|
||||
|
||||
// 创建提现记录(事务内操作)
|
||||
func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agentID int64, req *types.WithdrawalReq, outBizNo string) error {
|
||||
record := &model.AgentWithdrawal{
|
||||
AgentId: agentID,
|
||||
WithdrawNo: outBizNo,
|
||||
PayeeAccount: req.PayeeAccount,
|
||||
Amount: req.Amount,
|
||||
Status: StatusProcessing,
|
||||
}
|
||||
|
||||
_, err := l.svcCtx.AgentWithdrawalModel.Insert(l.ctx, session, record)
|
||||
return err
|
||||
}
|
||||
|
||||
// 冻结资金(事务内操作)
|
||||
func (l *AgentWithdrawalLogic) freezeFunds(session sqlx.Session, wallet *model.AgentWallet, amount float64) error {
|
||||
wallet.Balance -= amount
|
||||
wallet.FrozenBalance += amount
|
||||
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(l.ctx, session, wallet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 处理异步轮询
|
||||
func (l *AgentWithdrawalLogic) startAsyncPolling(outBizNo string) {
|
||||
go func() {
|
||||
detachedCtx := context.WithoutCancel(l.ctx)
|
||||
retryConfig := &backoff.ExponentialBackOff{
|
||||
InitialInterval: 10 * time.Second,
|
||||
RandomizationFactor: 0.5, // 增加随机因子防止惊群
|
||||
Multiplier: 2,
|
||||
MaxInterval: 30 * time.Second,
|
||||
MaxElapsedTime: 5 * time.Minute, // 缩短总超时
|
||||
Clock: backoff.SystemClock,
|
||||
}
|
||||
retryConfig.Reset()
|
||||
operation := func() error {
|
||||
statusRsp, err := l.svcCtx.AlipayService.QueryTransferStatus(detachedCtx, outBizNo)
|
||||
if err != nil {
|
||||
return err // 触发重试
|
||||
}
|
||||
|
||||
switch statusRsp.Status {
|
||||
case "SUCCESS":
|
||||
l.handleTransferSuccess(outBizNo, statusRsp)
|
||||
return nil
|
||||
case "FAIL":
|
||||
l.handleTransferFailure(outBizNo, statusRsp)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("转账处理中")
|
||||
}
|
||||
}
|
||||
|
||||
err := backoff.RetryNotify(operation,
|
||||
backoff.WithContext(retryConfig, detachedCtx),
|
||||
func(err error, duration time.Duration) {
|
||||
l.Logger.Infof("轮询延迟 outBizNo:%s 等待:%v", outBizNo, duration)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
l.handleTransferTimeout(outBizNo)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 统一状态更新
|
||||
func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status int64, errorMsg string) {
|
||||
detachedCtx := context.WithoutCancel(l.ctx)
|
||||
|
||||
err := l.svcCtx.AgentModel.Trans(detachedCtx, func(ctx context.Context, session sqlx.Session) error {
|
||||
// 获取提现记录
|
||||
record, err := l.svcCtx.AgentWithdrawalModel.FindOneByWithdrawNo(l.ctx, outBizNo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
record.Status = status
|
||||
record.Remark = lzUtils.StringToNullString(errorMsg)
|
||||
if _, err = l.svcCtx.AgentWithdrawalModel.Update(ctx, session, record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 失败时解冻资金
|
||||
if status == StatusFailed {
|
||||
wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(ctx, record.AgentId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wallet.Balance += record.Amount
|
||||
wallet.FrozenBalance -= record.Amount
|
||||
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
l.Logger.Errorf("状态更新失败 outBizNo:%s error:%v", outBizNo, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 成功处理
|
||||
func (l *AgentWithdrawalLogic) handleTransferSuccess(outBizNo string, rsp interface{}) {
|
||||
l.updateWithdrawalStatus(outBizNo, StatusSuccess, "")
|
||||
l.Logger.Infof("提现成功 outBizNo:%s", outBizNo)
|
||||
}
|
||||
|
||||
// 失败处理
|
||||
func (l *AgentWithdrawalLogic) handleTransferFailure(outBizNo string, rsp interface{}) {
|
||||
var errorMsg string
|
||||
if resp, ok := rsp.(*alipay.FundTransUniTransferRsp); ok {
|
||||
errorMsg = l.mapAlipayError(resp.SubCode)
|
||||
}
|
||||
l.updateWithdrawalStatus(outBizNo, StatusFailed, errorMsg)
|
||||
l.Logger.Errorf("提现失败 outBizNo:%s reason:%s", outBizNo, errorMsg)
|
||||
}
|
||||
|
||||
// 超时处理
|
||||
func (l *AgentWithdrawalLogic) handleTransferTimeout(outBizNo string) {
|
||||
l.updateWithdrawalStatus(outBizNo, StatusFailed, "系统处理超时")
|
||||
l.Logger.Errorf("轮询超时 outBizNo:%s", outBizNo)
|
||||
}
|
||||
|
||||
// 错误处理
|
||||
func (l *AgentWithdrawalLogic) handleTransferError(outBizNo string, err error, contextMsg string) {
|
||||
l.updateWithdrawalStatus(outBizNo, StatusFailed, "系统处理异常")
|
||||
l.Logger.Errorf("%s outBizNo:%s error:%v", contextMsg, outBizNo, err)
|
||||
}
|
||||
169
app/user/cmd/api/internal/logic/agent/applyforagentlogic.go
Normal file
169
app/user/cmd/api/internal/logic/agent/applyforagentlogic.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"time"
|
||||
"tydata-server/app/user/model"
|
||||
jwtx "tydata-server/common/jwt"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/lzUtils"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ApplyForAgentLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewApplyForAgentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ApplyForAgentLogic {
|
||||
return &ApplyForAgentLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *types.AgentApplyResp, err error) {
|
||||
// 校验验证码
|
||||
redisKey := fmt.Sprintf("%s:%s", "agentApply", req.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "代理申请, 验证码过期: %s", req.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 读取验证码redis缓存失败, mobile: %s, err: %+v", req.Mobile, err)
|
||||
}
|
||||
if cacheCode != req.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "代理申请, 验证码不正确: %s", req.Mobile)
|
||||
}
|
||||
if req.Ancestor == req.Mobile {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("不能成为自己的代理"), "")
|
||||
}
|
||||
var userID int64
|
||||
transErr := l.svcCtx.AgentAuditModel.Trans(l.ctx, func(transCtx context.Context, session sqlx.Session) error {
|
||||
// 两种情况,1. 已注册账号然后申请代理 2. 未注册账号申请代理
|
||||
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
|
||||
if findUserErr != nil && !errors.Is(findUserErr, model.ErrNotFound) {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile: %s, err: %+v", req.Mobile, err)
|
||||
}
|
||||
if user == nil {
|
||||
user = &model.User{Mobile: req.Mobile}
|
||||
if len(user.Nickname) == 0 {
|
||||
user.Nickname = req.Mobile
|
||||
}
|
||||
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(transCtx, session, user)
|
||||
if userInsertErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 数据库插入新用户失败, mobile%s, err: %+v", req.Mobile, err)
|
||||
}
|
||||
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
||||
if lastInsertIdErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 获取新用户ID失败, err:%+v, user:%+v", lastInsertIdErr, user)
|
||||
}
|
||||
user.Id = lastId
|
||||
userID = lastId
|
||||
userAuth := new(model.UserAuth)
|
||||
userAuth.UserId = lastId
|
||||
userAuth.AuthKey = req.Mobile
|
||||
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
|
||||
agentAuditModel, findAgentAuditErr := l.svcCtx.AgentAuditModel.FindOneByUserId(transCtx, user.Id)
|
||||
if findAgentAuditErr != nil && !errors.Is(findAgentAuditErr, model.ErrNotFound) {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 查找审核列表失败%+v", findAgentAuditErr)
|
||||
}
|
||||
if agentAuditModel != nil {
|
||||
if agentAuditModel.Status == 0 {
|
||||
return errors.Wrapf(xerr.NewErrMsg("您的代理申请中"), "代理申请, 代理申请中")
|
||||
} else {
|
||||
return errors.Wrapf(xerr.NewErrMsg("您已申请过代理"), "代理申请, 代理已申请过")
|
||||
}
|
||||
}
|
||||
|
||||
var agentAudit model.AgentAudit
|
||||
agentAudit.UserId = user.Id
|
||||
agentAudit.Mobile = req.Mobile
|
||||
agentAudit.Region = req.Region
|
||||
agentAudit.WechatId = lzUtils.StringToNullString(req.WechatID)
|
||||
agentAudit.Status = 1
|
||||
_, insetAgentAuditErr := l.svcCtx.AgentAuditModel.Insert(transCtx, session, &agentAudit)
|
||||
if insetAgentAuditErr != nil {
|
||||
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
|
||||
agentModel.Mobile = agentAudit.Mobile
|
||||
agentModel.Region = agentAudit.Region
|
||||
agentModel.UserId = agentAudit.UserId
|
||||
agentModel.WechatId = lzUtils.StringToNullString(req.WechatID)
|
||||
agentModelInsert, insertAgentModelErr := l.svcCtx.AgentModel.Insert(transCtx, session, &agentModel)
|
||||
if insertAgentModelErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 新增代理失败: %+v", insertAgentModelErr)
|
||||
}
|
||||
agentID, _ := agentModelInsert.LastInsertId()
|
||||
|
||||
// 关联上级
|
||||
if req.Ancestor != "" {
|
||||
ancestorAgentModel, findAgentModelErr := l.svcCtx.AgentModel.FindOneByMobile(transCtx, req.Ancestor)
|
||||
if findAgentModelErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 查找上级代理失败: %+v", findAgentModelErr)
|
||||
}
|
||||
agentClosureModel := model.AgentClosure{
|
||||
AncestorId: ancestorAgentModel.Id,
|
||||
DescendantId: agentID,
|
||||
Depth: 1,
|
||||
}
|
||||
_, insertAgentClosureModelErr := l.svcCtx.AgentClosureModel.Insert(transCtx, session, &agentClosureModel)
|
||||
if insertAgentClosureModelErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 添加代理上下级关联失败: %+v", insertAgentClosureModelErr)
|
||||
}
|
||||
}
|
||||
|
||||
// 新增代理钱包
|
||||
var agentWallet model.AgentWallet
|
||||
agentWallet.AgentId = agentID
|
||||
_, insertAgentWalletModelErr := l.svcCtx.AgentWalletModel.Insert(transCtx, session, &agentWallet)
|
||||
if insertAgentWalletModelErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理申请, 新增代理钱包失败: %+v", insertAgentWalletModelErr)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if 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), "代理申请, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.AgentApplyResp{
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
110
app/user/cmd/api/internal/logic/agent/generatinglinklogic.go
Normal file
110
app/user/cmd/api/internal/logic/agent/generatinglinklogic.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
"strconv"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GeneratingLinkLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGeneratingLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GeneratingLinkLogic {
|
||||
return &GeneratingLinkLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GeneratingLinkLogic) GeneratingLink(req *types.AgentGeneratingLinkReq) (resp *types.AgentGeneratingLinkResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成代理链接, %v", err)
|
||||
}
|
||||
productModel, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, req.Product)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
|
||||
}
|
||||
|
||||
agentProductConfig, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, productModel.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
|
||||
}
|
||||
price, err := strconv.ParseFloat(req.Price, 64)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成代理链接, %v", err)
|
||||
}
|
||||
if price < agentProductConfig.PriceRangeMin || price > agentProductConfig.PriceRangeMax {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("请设定范围区间内的价格"), "")
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
build := l.svcCtx.AgentLinkModel.SelectBuilder().Where(squirrel.And{
|
||||
squirrel.Eq{"user_id": userID},
|
||||
squirrel.Eq{"product_id": productModel.Id}, // 添加 product_id 的匹配条件
|
||||
squirrel.Eq{"price": price}, // 添加 price 的匹配条件
|
||||
squirrel.Eq{"agent_id": agentModel.Id}, // 添加 agent_id 的匹配条件
|
||||
})
|
||||
|
||||
agentLinkModel, err := l.svcCtx.AgentLinkModel.FindAll(l.ctx, build, "")
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
|
||||
}
|
||||
if len(agentLinkModel) > 0 {
|
||||
return &types.AgentGeneratingLinkResp{
|
||||
LinkIdentifier: agentLinkModel[0].LinkIdentifier,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var agentIdentifier types.AgentIdentifier
|
||||
agentIdentifier.AgentID = agentModel.Id
|
||||
agentIdentifier.Product = req.Product
|
||||
agentIdentifier.Price = req.Price
|
||||
agentIdentifierByte, err := json.Marshal(agentIdentifier)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单,序列化标识失败, %v", err)
|
||||
}
|
||||
key, decodeErr := hex.DecodeString("8e3e7a2f60edb49221e953b9c029ed10")
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// Encrypt the params
|
||||
encrypted, err := crypto.AesEncryptURL(agentIdentifierByte, key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成代理链接, %v", err)
|
||||
}
|
||||
|
||||
var agentLink model.AgentLink
|
||||
agentLink.AgentId = agentModel.Id
|
||||
agentLink.UserId = userID
|
||||
agentLink.LinkIdentifier = encrypted
|
||||
agentLink.ProductId = productModel.Id
|
||||
agentLink.Price = price
|
||||
_, err = l.svcCtx.AgentLinkModel.Insert(l.ctx, nil, &agentLink)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成代理链接, %v", err)
|
||||
}
|
||||
return &types.AgentGeneratingLinkResp{
|
||||
LinkIdentifier: encrypted,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentAuditStatusLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentAuditStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentAuditStatusLogic {
|
||||
return &GetAgentAuditStatusLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentAuditStatusLogic) GetAgentAuditStatus() (resp *types.AgentAuditStatusResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理审核信息, %v", err)
|
||||
}
|
||||
agentAuditModel, err := l.svcCtx.AgentAuditModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理审核信息, %v", err)
|
||||
}
|
||||
|
||||
var agentAuditStautsResp types.AgentAuditStatusResp
|
||||
copier.Copy(&agentAuditStautsResp, agentAuditModel)
|
||||
return &agentAuditStautsResp, nil
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentCommissionLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentCommissionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentCommissionLogic {
|
||||
return &GetAgentCommissionLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentCommissionLogic) GetAgentCommission(req *types.GetCommissionReq) (resp *types.GetCommissionResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理佣金列表, %v", err)
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理佣金列表, %v", err)
|
||||
}
|
||||
builder := l.svcCtx.AgentCommissionModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"agent_id": agentModel.Id,
|
||||
})
|
||||
agentCommissionModelList, total, err := l.svcCtx.AgentCommissionModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理佣金列表, 查找列表错误, %v", err)
|
||||
}
|
||||
|
||||
var list = make([]types.Commission, 0)
|
||||
|
||||
if len(agentCommissionModelList) > 0 {
|
||||
for _, agentCommissionModel := range agentCommissionModelList {
|
||||
var commission types.Commission
|
||||
copyErr := copier.Copy(&commission, agentCommissionModel)
|
||||
if copyErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理佣金列表, %v", err)
|
||||
}
|
||||
product, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, agentCommissionModel.ProductId)
|
||||
if findProductErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理佣金列表, %v", err)
|
||||
}
|
||||
commission.CreateTime = agentCommissionModel.CreateTime.Format("2006-01-02 15:04:05")
|
||||
commission.ProductName = product.ProductName
|
||||
list = append(list, commission)
|
||||
}
|
||||
}
|
||||
return &types.GetCommissionResp{
|
||||
Total: total,
|
||||
List: list,
|
||||
}, nil
|
||||
}
|
||||
66
app/user/cmd/api/internal/logic/agent/getagentinfologic.go
Normal file
66
app/user/cmd/api/internal/logic/agent/getagentinfologic.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/lzUtils"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentInfoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentInfoLogic {
|
||||
return &GetAgentInfoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentInfoLogic) GetAgentInfo() (resp *types.AgentInfoResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息, %v", err)
|
||||
}
|
||||
agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
agentAuditModel, findAgentAuditErr := l.svcCtx.AgentAuditModel.FindOneByUserId(l.ctx, userID)
|
||||
if findAgentAuditErr != nil && !errors.Is(findAgentAuditErr, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理信息, %v", err)
|
||||
}
|
||||
if errors.Is(findAgentAuditErr, model.ErrNotFound) {
|
||||
return &types.AgentInfoResp{
|
||||
IsAgent: false,
|
||||
Status: 3,
|
||||
}, nil
|
||||
}
|
||||
return &types.AgentInfoResp{
|
||||
IsAgent: false,
|
||||
Status: agentAuditModel.Status,
|
||||
}, nil
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理信息, %v", err)
|
||||
}
|
||||
return &types.AgentInfoResp{
|
||||
AgentID: agent.Id,
|
||||
Level: agent.LevelName,
|
||||
IsAgent: true,
|
||||
Status: 1,
|
||||
Region: agent.Region,
|
||||
Mobile: agent.Mobile,
|
||||
WechatID: lzUtils.NullStringToString(agent.WechatId),
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/lzUtils"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentMembershipProductConfigLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentMembershipProductConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentMembershipProductConfigLogic {
|
||||
return &GetAgentMembershipProductConfigLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentMembershipProductConfigLogic) GetAgentMembershipProductConfig(req *types.AgentMembershipProductConfigReq) (resp *types.AgentMembershipProductConfigResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,获取用户ID失败: %v", err)
|
||||
}
|
||||
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,获取代理信息失败: %v", err)
|
||||
}
|
||||
|
||||
agentMembershipConfigModel, err := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, agentModel.LevelName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,获取平台配置会员信息失败: %v", err)
|
||||
}
|
||||
agentMembershipUserConfigModel, err := l.svcCtx.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(l.ctx, agentModel.Id, req.ProductID)
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
var agentMembershipUserConfig types.AgentMembershipUserConfig
|
||||
if agentMembershipUserConfigModel != nil {
|
||||
err = copier.Copy(&agentMembershipUserConfig, agentMembershipUserConfigModel)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,复制平台配置会员信息失败: %v", err)
|
||||
}
|
||||
} else {
|
||||
agentMembershipUserConfig.ProductID = req.ProductID
|
||||
}
|
||||
agentProductConfigModelAll, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, req.ProductID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取会员用户报告配置, 获取产品配置%v", err)
|
||||
}
|
||||
|
||||
var productConfig types.ProductConfig
|
||||
err = copier.Copy(&productConfig, agentProductConfigModelAll)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取会员用户报告配置,复制平台产品配置失败: %v", err)
|
||||
}
|
||||
return &types.AgentMembershipProductConfigResp{
|
||||
AgentMembershipUserConfig: agentMembershipUserConfig,
|
||||
ProductConfig: productConfig,
|
||||
PriceIncreaseAmount: lzUtils.NullFloat64ToFloat64(agentMembershipConfigModel.PriceIncreaseAmount),
|
||||
PriceIncreaseMax: lzUtils.NullFloat64ToFloat64(agentMembershipConfigModel.PriceIncreaseMax),
|
||||
PriceRatio: lzUtils.NullFloat64ToFloat64(agentMembershipConfigModel.PriceRatio),
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/mr"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentProductConfigLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentProductConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentProductConfigLogic {
|
||||
return &GetAgentProductConfigLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
type AgentProductConfigResp struct {
|
||||
}
|
||||
|
||||
func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentProductConfigResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取推广项目配置失败, %v", err)
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "")
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取推广项目配置失败, %v", err)
|
||||
}
|
||||
// 1. 查询推广项目配置数据
|
||||
builder := l.svcCtx.AgentProductConfigModel.SelectBuilder()
|
||||
agentProductConfigModelAll, err := l.svcCtx.AgentProductConfigModel.FindAll(l.ctx, builder, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广项目配置失败, %v", err)
|
||||
}
|
||||
|
||||
// 用于存放最终组装好的响应数据
|
||||
var respList []types.AgentProductConfig
|
||||
|
||||
// 2. 使用 mr.MapReduceVoid 并行处理每个推广项目配置项
|
||||
mrMapErr := mr.MapReduceVoid(
|
||||
// source 函数:遍历所有推广项目配置,将每个配置项发送到 channel 中
|
||||
func(source chan<- interface{}) {
|
||||
for _, config := range agentProductConfigModelAll {
|
||||
source <- config
|
||||
}
|
||||
},
|
||||
// map 函数:处理每个推广项目配置项,根据 ProductId 查询会员用户配置,并组装响应数据
|
||||
func(item interface{}, writer mr.Writer[*types.AgentProductConfig], cancel func(error)) {
|
||||
// 将 item 转换为推广项目配置模型
|
||||
config := item.(*model.AgentProductConfig)
|
||||
var agentProductConfig types.AgentProductConfig
|
||||
// 配置平台成本价和定价成本
|
||||
agentProductConfigModel, findAgentProductConfigErr := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, config.ProductId)
|
||||
if findAgentProductConfigErr != nil {
|
||||
cancel(findAgentProductConfigErr)
|
||||
return
|
||||
}
|
||||
agentProductConfig.ProductID = config.ProductId
|
||||
agentProductConfig.CostPrice = agentProductConfigModel.CostPrice
|
||||
agentProductConfig.PriceRangeMin = agentProductConfigModel.PriceRangeMin
|
||||
agentProductConfig.PriceRangeMax = agentProductConfigModel.PriceRangeMax
|
||||
agentProductConfig.PPricingStandard = agentProductConfigModel.PricingStandard
|
||||
agentProductConfig.POverpricingRatio = agentProductConfigModel.OverpricingRatio
|
||||
|
||||
// 看推广人是否有上级,上级是否有这个配置权限,上级是否有相关配置
|
||||
agentClosureModel, findAgentClosureErr := l.svcCtx.AgentClosureModel.FindOneByDescendantIdDepth(l.ctx, agentModel.Id, 1)
|
||||
if findAgentClosureErr != nil && !errors.Is(findAgentClosureErr, model.ErrNotFound) {
|
||||
cancel(findAgentClosureErr)
|
||||
return
|
||||
}
|
||||
if agentClosureModel != nil {
|
||||
ancestorAgentModel, findAncestorAgentErr := l.svcCtx.AgentModel.FindOne(l.ctx, agentClosureModel.AncestorId)
|
||||
if findAncestorAgentErr != nil {
|
||||
cancel(findAncestorAgentErr)
|
||||
return
|
||||
}
|
||||
agentMembershipConfigModel, findAgentMembershipErr := l.svcCtx.AgentMembershipConfigModel.FindOneByLevelName(l.ctx, ancestorAgentModel.LevelName)
|
||||
if findAgentMembershipErr != nil {
|
||||
cancel(findAgentMembershipErr)
|
||||
return
|
||||
}
|
||||
// 是否有提成本价
|
||||
if agentMembershipConfigModel.PriceIncreaseAmount.Valid {
|
||||
// 根据产品ID查询会员用户配置数据
|
||||
membershipUserConfigModel, membershipConfigErr := l.svcCtx.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(l.ctx, agentClosureModel.AncestorId, config.ProductId)
|
||||
if membershipConfigErr != nil {
|
||||
if errors.Is(membershipConfigErr, model.ErrNotFound) {
|
||||
writer.Write(&agentProductConfig)
|
||||
return
|
||||
}
|
||||
cancel(membershipConfigErr)
|
||||
return
|
||||
}
|
||||
agentProductConfig.CostPrice += membershipUserConfigModel.PriceIncreaseAmount
|
||||
agentProductConfig.PriceRangeMin += membershipUserConfigModel.PriceIncreaseAmount
|
||||
agentProductConfig.APricingStandard = membershipUserConfigModel.PriceRangeFrom
|
||||
agentProductConfig.APricingEnd = membershipUserConfigModel.PriceRangeTo
|
||||
agentProductConfig.AOverpricingRatio = membershipUserConfigModel.PriceRatio
|
||||
}
|
||||
}
|
||||
writer.Write(&agentProductConfig)
|
||||
|
||||
},
|
||||
// reduce 函数:收集 map 阶段写入的响应数据,并汇总到 respList 中
|
||||
func(pipe <-chan *types.AgentProductConfig, cancel func(error)) {
|
||||
for item := range pipe {
|
||||
respList = append(respList, *item)
|
||||
}
|
||||
},
|
||||
)
|
||||
if mrMapErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取推广项目配置失败, %+v", mrMapErr)
|
||||
}
|
||||
|
||||
// 3. 组装最终响应返回
|
||||
return &types.AgentProductConfigResp{
|
||||
AgentProductConfig: respList,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentRevenueInfoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentRevenueInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentRevenueInfoLogic {
|
||||
return &GetAgentRevenueInfoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentRevenueInfoLogic) GetAgentRevenueInfo(req *types.GetAgentRevenueInfoReq) (resp *types.GetAgentRevenueInfoResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理奖励, %v", err)
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
|
||||
}
|
||||
agentWalletModel, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agentModel.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
|
||||
}
|
||||
resp = &types.GetAgentRevenueInfoResp{}
|
||||
resp.Balance = agentWalletModel.Balance
|
||||
resp.TotalEarnings = agentWalletModel.TotalEarnings
|
||||
resp.FrozenBalance = agentWalletModel.FrozenBalance
|
||||
|
||||
// 直推报告统计
|
||||
//now := time.Now()
|
||||
//startTime := now.AddDate(0, 0, -30).Format("2006-01-02 15:04:05")
|
||||
//endTime := now.Format("2006-01-02 15:04:05")
|
||||
|
||||
// 直推报告佣金
|
||||
agentCommissionModelBuild := l.svcCtx.AgentCommissionModel.SelectBuilder().
|
||||
Where(squirrel.Eq{"agent_id": agentModel.Id})
|
||||
//.Where(squirrel.Expr("create_time BETWEEN ? AND ?", startTime, endTime))
|
||||
|
||||
agentCommissionsModel, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx, agentCommissionModelBuild, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
|
||||
}
|
||||
// 筛选分类
|
||||
directPush, err := calculateDirectPushReport(agentCommissionsModel, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
|
||||
}
|
||||
// 绑定到响应体
|
||||
resp.DirectPush = directPush
|
||||
|
||||
// 活跃下级统计
|
||||
agentRewardsModelBuilder := l.svcCtx.AgentRewardsModel.SelectBuilder().Where("agent_id = ?", agentModel.Id)
|
||||
agentRewardsModel, err := l.svcCtx.AgentRewardsModel.FindAll(l.ctx, agentRewardsModelBuilder, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励, %v", err)
|
||||
}
|
||||
activeReward := calculateActiveReward(agentRewardsModel)
|
||||
resp.ActiveReward = activeReward
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// 统计直推报告的独立函数
|
||||
func calculateDirectPushReport(commissions []*model.AgentCommission, loc *time.Location) (types.DirectPushReport, error) {
|
||||
// 初始化报告结构
|
||||
report := types.DirectPushReport{
|
||||
Today: types.TimeRangeReport{},
|
||||
Last7D: types.TimeRangeReport{},
|
||||
Last30D: types.TimeRangeReport{},
|
||||
}
|
||||
|
||||
// 获取当前中国时间
|
||||
now := time.Now()
|
||||
|
||||
// 计算时间分界点
|
||||
todayStart := now.Add(-24 * time.Hour)
|
||||
last7dStart := now.AddDate(0, 0, -7)
|
||||
last30dStart := now.AddDate(0, 0, -30)
|
||||
|
||||
// 遍历所有佣金记录
|
||||
for _, c := range commissions {
|
||||
// 转换时区
|
||||
createTime := c.CreateTime
|
||||
|
||||
// 统计总量
|
||||
report.TotalCommission += c.Amount
|
||||
report.TotalReport++
|
||||
|
||||
// 近24小时(滚动周期)
|
||||
if createTime.After(todayStart) {
|
||||
report.Today.Commission += c.Amount
|
||||
report.Today.Report++
|
||||
}
|
||||
|
||||
// 近7天(滚动周期)
|
||||
if createTime.After(last7dStart) {
|
||||
report.Last7D.Commission += c.Amount
|
||||
report.Last7D.Report++
|
||||
}
|
||||
|
||||
// 近30天(滚动周期)
|
||||
if createTime.After(last30dStart) {
|
||||
report.Last30D.Commission += c.Amount
|
||||
report.Last30D.Report++
|
||||
}
|
||||
}
|
||||
|
||||
return report, nil
|
||||
}
|
||||
func calculateActiveReward(rewards []*model.AgentRewards) types.ActiveReward {
|
||||
result := types.ActiveReward{
|
||||
Today: types.ActiveRewardData{},
|
||||
Last7D: types.ActiveRewardData{},
|
||||
Last30D: types.ActiveRewardData{},
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
todayStart := now.Add(-24 * time.Hour) // 近24小时
|
||||
last7dStart := now.AddDate(0, 0, -7) // 近7天
|
||||
last30dStart := now.AddDate(0, 0, -30) // 近30天
|
||||
|
||||
for _, r := range rewards {
|
||||
createTime := r.CreateTime
|
||||
amount := r.Amount
|
||||
|
||||
// 总奖励累加
|
||||
result.TotalReward += amount
|
||||
|
||||
// 时间范围判断
|
||||
isToday := createTime.After(todayStart)
|
||||
isLast7d := createTime.After(last7dStart)
|
||||
isLast30d := createTime.After(last30dStart)
|
||||
|
||||
// 类型分类统计
|
||||
switch r.Type {
|
||||
case model.AgentRewardsTypeDescendantWithdraw:
|
||||
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "withdraw")
|
||||
|
||||
case model.AgentRewardsTypeDescendantNewActive:
|
||||
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "new_active")
|
||||
|
||||
case model.AgentRewardsTypeDescendantUpgradeSvip, model.AgentRewardsTypeDescendantUpgradeVip:
|
||||
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "upgrade")
|
||||
|
||||
case model.AgentRewardsTypeDescendantPromotion:
|
||||
addToPeriods(&result, amount, isToday, isLast7d, isLast30d, "promotion")
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 统一处理时间段累加
|
||||
func addToPeriods(res *types.ActiveReward, amount float64, today, last7d, last30d bool, t string) {
|
||||
if today {
|
||||
addToData(&res.Today, amount, t)
|
||||
}
|
||||
if last7d {
|
||||
addToData(&res.Last7D, amount, t)
|
||||
}
|
||||
if last30d {
|
||||
addToData(&res.Last30D, amount, t)
|
||||
}
|
||||
}
|
||||
|
||||
// 分类添加具体字段
|
||||
func addToData(data *types.ActiveRewardData, amount float64, t string) {
|
||||
switch t {
|
||||
case "withdraw":
|
||||
data.SubWithdrawReward += amount
|
||||
case "new_active":
|
||||
data.NewActiveReward += amount
|
||||
case "upgrade":
|
||||
data.SubUpgradeReward += amount
|
||||
case "promotion":
|
||||
data.SubPromoteReward += amount
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentRewardsLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentRewardsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentRewardsLogic {
|
||||
return &GetAgentRewardsLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentRewardsLogic) GetAgentRewards(req *types.GetRewardsReq) (resp *types.GetRewardsResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理奖励列表, %v", err)
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励列表, %v", err)
|
||||
}
|
||||
builder := l.svcCtx.AgentRewardsModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"agent_id": agentModel.Id,
|
||||
})
|
||||
agentRewardsModelList, total, err := l.svcCtx.AgentRewardsModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理奖励列表, 查找列表错误, %v", err)
|
||||
}
|
||||
|
||||
var list = make([]types.Rewards, 0)
|
||||
if len(agentRewardsModelList) > 0 {
|
||||
for _, agentRewardsModel := range agentRewardsModelList {
|
||||
var rewards types.Rewards
|
||||
copyErr := copier.Copy(&rewards, agentRewardsModel)
|
||||
if copyErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理奖励列表, %v", err)
|
||||
}
|
||||
|
||||
rewards.CreateTime = agentRewardsModel.CreateTime.Format("2006-01-02 15:04:05")
|
||||
list = append(list, rewards)
|
||||
}
|
||||
}
|
||||
return &types.GetRewardsResp{
|
||||
Total: total,
|
||||
List: list,
|
||||
}, nil
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetAgentWithdrawalLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetAgentWithdrawalLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentWithdrawalLogic {
|
||||
return &GetAgentWithdrawalLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetAgentWithdrawalLogic) GetAgentWithdrawal(req *types.GetWithdrawalReq) (resp *types.GetWithdrawalResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理提现列表, %v", err)
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理提现列表, %v", err)
|
||||
}
|
||||
builder := l.svcCtx.AgentWithdrawalModel.SelectBuilder().Where(squirrel.Eq{
|
||||
"agent_id": agentModel.Id,
|
||||
})
|
||||
agentWithdrawalModelList, total, err := l.svcCtx.AgentWithdrawalModel.FindPageListByPageWithTotal(l.ctx, builder, req.Page, req.PageSize, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理提现列表, 查找列表错误, %v", err)
|
||||
}
|
||||
|
||||
var list = make([]types.Withdrawal, 0)
|
||||
|
||||
if len(agentWithdrawalModelList) > 0 {
|
||||
for _, agentWithdrawalModel := range agentWithdrawalModelList {
|
||||
var withdrawal types.Withdrawal
|
||||
copyErr := copier.Copy(&withdrawal, agentWithdrawalModel)
|
||||
if copyErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理提现列表, %v", err)
|
||||
}
|
||||
withdrawal.CreateTime = agentWithdrawalModel.CreateTime.Format("2006-01-02 15:04:05")
|
||||
list = append(list, withdrawal)
|
||||
}
|
||||
}
|
||||
return &types.GetWithdrawalResp{
|
||||
Total: total,
|
||||
List: list,
|
||||
}, nil
|
||||
}
|
||||
45
app/user/cmd/api/internal/logic/agent/getlinkdatalogic.go
Normal file
45
app/user/cmd/api/internal/logic/agent/getlinkdatalogic.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetLinkDataLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetLinkDataLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLinkDataLogic {
|
||||
return &GetLinkDataLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetLinkDataLogic) GetLinkData(req *types.GetLinkDataReq) (resp *types.GetLinkDataResp, err error) {
|
||||
agentLinkModel, err := l.svcCtx.AgentLinkModel.FindOneByLinkIdentifier(l.ctx, req.LinkIdentifier)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理链接数据, %v", err)
|
||||
}
|
||||
|
||||
productModel, err := l.svcCtx.ProductModel.FindOne(l.ctx, agentLinkModel.ProductId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "获取代理链接数据, %v", err)
|
||||
}
|
||||
var product types.Product
|
||||
copier.Copy(&product, productModel)
|
||||
product.SellPrice = agentLinkModel.Price
|
||||
return &types.GetLinkDataResp{
|
||||
Product: product,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SaveAgentMembershipUserConfigLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSaveAgentMembershipUserConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SaveAgentMembershipUserConfigLogic {
|
||||
return &SaveAgentMembershipUserConfigLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SaveAgentMembershipUserConfigLogic) SaveAgentMembershipUserConfig(req *types.SaveAgentMembershipUserConfigReq) error {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置,获取用户ID失败: %v", err)
|
||||
}
|
||||
agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
|
||||
}
|
||||
agentMembershipUserConfigModel, err := l.svcCtx.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(l.ctx, agentModel.Id, req.ProductID)
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return err
|
||||
}
|
||||
err = copier.Copy(&agentMembershipUserConfigModel, &req)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
|
||||
}
|
||||
if agentMembershipUserConfigModel == nil {
|
||||
agentMembershipUserConfigModel.UserId = userID
|
||||
agentMembershipUserConfigModel.AgentId = agentModel.Id
|
||||
_, err = l.svcCtx.AgentMembershipUserConfigModel.Insert(l.ctx, nil, agentMembershipUserConfigModel)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
|
||||
}
|
||||
} else {
|
||||
_, err = l.svcCtx.AgentMembershipUserConfigModel.Update(l.ctx, nil, agentMembershipUserConfigModel)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "保存会员代理报告配置: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func (l *SendSmsLogic) SendSms(req *types.SendSmsReq) error {
|
||||
// 发送短信
|
||||
smsResp, err := l.sendSmsRequest(req.Mobile, code)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 调用阿里客户端失败: %+v", err)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 调用阿里客户端失败: %v", err)
|
||||
}
|
||||
if *smsResp.Body.Code != "OK" {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 阿里客户端响应失败: %s", *smsResp.Body.Message)
|
||||
@@ -59,12 +59,12 @@ func (l *SendSmsLogic) SendSms(req *types.SendSmsReq) error {
|
||||
// 将验证码保存到 Redis,设置过期时间
|
||||
err = l.svcCtx.Redis.Setex(codeKey, code, l.svcCtx.Config.VerifyCode.ValidTime) // 验证码有效期5分钟
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置过期时间失败: %+v", err)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置过期时间失败: %v", err)
|
||||
}
|
||||
// 在 Redis 中设置 1 分钟的标记,限制重复请求
|
||||
err = l.svcCtx.Redis.Setex(limitCodeKey, code, 60) // 标记 1 分钟内不能重复请求
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置限制重复请求失败: %+v", err)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送, 验证码设置限制重复请求失败: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
"tydata-server/pkg/lzkit/lzUtils"
|
||||
|
||||
@@ -26,9 +27,13 @@ func NewAlipayCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Al
|
||||
}
|
||||
|
||||
func (l *AlipayCallbackLogic) AlipayCallback(w http.ResponseWriter, r *http.Request) error {
|
||||
env := os.Getenv("ENV")
|
||||
if env == "development" {
|
||||
return nil
|
||||
}
|
||||
notification, err := l.svcCtx.AlipayService.HandleAliPaymentNotification(r)
|
||||
if err != nil {
|
||||
logx.Errorf("支付宝支付回调,%+v", err)
|
||||
logx.Errorf("支付宝支付回调,%v", err)
|
||||
return nil
|
||||
}
|
||||
order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, notification.OutTradeNo)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"os"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/app/user/model"
|
||||
@@ -48,12 +49,12 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
|
||||
var data types.QueryCacheLoad
|
||||
err = json.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析缓存内容失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析缓存内容失败, %v", err)
|
||||
}
|
||||
|
||||
product, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, data.Product)
|
||||
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)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
@@ -71,16 +72,28 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
|
||||
var prepayData interface{}
|
||||
var outTradeNo string
|
||||
var amount float64
|
||||
var orderAmount float64
|
||||
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取用户信息失败: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取用户信息失败: %v", err)
|
||||
}
|
||||
|
||||
if data.AgentIdentifier != "" {
|
||||
agentLinkModel, findAgentLinkErr := l.svcCtx.AgentLinkModel.FindOneByLinkIdentifier(l.ctx, data.AgentIdentifier)
|
||||
if findAgentLinkErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取代理订单失败: %+v", findAgentLinkErr)
|
||||
}
|
||||
amount = agentLinkModel.Price
|
||||
orderAmount = agentLinkModel.Price
|
||||
} else {
|
||||
amount = product.SellPrice
|
||||
orderAmount = product.SellPrice
|
||||
}
|
||||
|
||||
if user.Inside == 1 {
|
||||
amount = 0.01
|
||||
} else {
|
||||
amount = product.SellPrice
|
||||
}
|
||||
|
||||
var createOrderErr error
|
||||
if req.PayMethod == "wechat" {
|
||||
outTradeNo = l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
@@ -103,16 +116,16 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
|
||||
ProductId: product.Id,
|
||||
PaymentPlatform: req.PayMethod,
|
||||
PaymentScene: "app",
|
||||
Amount: amount,
|
||||
Amount: orderAmount,
|
||||
Status: "pending",
|
||||
}
|
||||
orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(ctx, session, &order)
|
||||
if insertOrderErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 保存订单失败: %+v", insertOrderErr)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存订单失败: %+v", insertOrderErr)
|
||||
}
|
||||
insertedOrderID, lastInsertIdErr := orderInsertResult.LastInsertId()
|
||||
if lastInsertIdErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取保存订单ID失败: %+v", lastInsertIdErr)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 获取保存订单ID失败: %+v", lastInsertIdErr)
|
||||
}
|
||||
orderID = insertedOrderID
|
||||
query := model.Query{
|
||||
@@ -124,14 +137,32 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
|
||||
}
|
||||
_, insertQueryErr := l.svcCtx.QueryModel.Insert(l.ctx, session, &query)
|
||||
if insertQueryErr != nil {
|
||||
return insertQueryErr
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存查询失败: %+v", lastInsertIdErr)
|
||||
}
|
||||
if data.AgentIdentifier != "" {
|
||||
agent, parsingErr := l.agentParsing(data.AgentIdentifier)
|
||||
if parsingErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 解析代理标识符失败: %+v", parsingErr)
|
||||
}
|
||||
var agentOrder model.AgentOrder
|
||||
agentOrder.OrderId = orderID
|
||||
agentOrder.AgentId = agent.AgentID
|
||||
_, agentOrderInsert := l.svcCtx.AgentOrderModel.Insert(ctx, session, &agentOrder)
|
||||
if agentOrderInsert != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存代理订单失败: %+v", agentOrderInsert)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if transErr != nil {
|
||||
return nil, transErr
|
||||
}
|
||||
|
||||
env := os.Getenv("ENV")
|
||||
if env == "development" {
|
||||
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(orderID); asyncErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 异步订单调用失败: %+v", asyncErr)
|
||||
}
|
||||
}
|
||||
switch v := prepayData.(type) {
|
||||
case string:
|
||||
// 如果 prepayData 是字符串类型,直接返回
|
||||
@@ -140,3 +171,21 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
|
||||
return &types.PaymentResp{PrepayData: prepayData, OrderID: orderID}, nil
|
||||
}
|
||||
}
|
||||
func (l *PaymentLogic) agentParsing(agentIdentifier string) (*types.AgentIdentifier, error) {
|
||||
key, decodeErr := hex.DecodeString("8e3e7a2f60edb49221e953b9c029ed10")
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
// Encrypt the params
|
||||
|
||||
encrypted, err := crypto.AesDecryptURL(agentIdentifier, key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, %v", err)
|
||||
}
|
||||
var agentIdentifierStruct types.AgentIdentifier
|
||||
err = json.Unmarshal(encrypted, &agentIdentifierStruct)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务,反序列化失败 %v", err)
|
||||
}
|
||||
return &agentIdentifierStruct, nil
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func NewWechatPayCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||
func (l *WechatPayCallbackLogic) WechatPayCallback(w http.ResponseWriter, r *http.Request) error {
|
||||
notification, err := l.svcCtx.WechatPayService.HandleWechatPayNotification(l.ctx, r)
|
||||
if err != nil {
|
||||
logx.Errorf("微信支付回调,%+v", err)
|
||||
logx.Errorf("微信支付回调,%v", err)
|
||||
return nil
|
||||
}
|
||||
order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo)
|
||||
|
||||
@@ -25,7 +25,7 @@ func NewWechatPayRefundCallbackLogic(ctx context.Context, svcCtx *svc.ServiceCon
|
||||
func (l *WechatPayRefundCallbackLogic) WechatPayRefundCallback(w http.ResponseWriter, r *http.Request) error {
|
||||
notification, err := l.svcCtx.WechatPayService.HandleRefundNotification(l.ctx, r)
|
||||
if err != nil {
|
||||
logx.Errorf("微信退款回调,%+v", err)
|
||||
logx.Errorf("微信退款回调,%v", err)
|
||||
return nil
|
||||
}
|
||||
order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, *notification.OutTradeNo)
|
||||
|
||||
@@ -32,7 +32,7 @@ func NewGetProductByEnLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge
|
||||
func (l *GetProductByEnLogic) GetProductByEn(req *types.GetProductByEnRequest) (resp *types.ProductResponse, err error) {
|
||||
productModel, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, req.ProductEn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品错误: %v", err)
|
||||
}
|
||||
|
||||
build := l.svcCtx.ProductFeatureModel.SelectBuilder().Where(squirrel.Eq{
|
||||
@@ -40,12 +40,12 @@ func (l *GetProductByEnLogic) GetProductByEn(req *types.GetProductByEnRequest) (
|
||||
})
|
||||
productFeatureAll, err := l.svcCtx.ProductFeatureModel.FindAll(l.ctx, build, "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品关联错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "产品查询, 查找产品关联错误: %v", err)
|
||||
}
|
||||
var product types.Product
|
||||
err = copier.Copy(&product, productModel)
|
||||
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)
|
||||
}
|
||||
mr.MapReduceVoid(func(source chan<- interface{}) {
|
||||
for _, productFeature := range productFeatureAll {
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type BackgroundCheckLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewBackgroundCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackgroundCheckLogic {
|
||||
return &BackgroundCheckLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *BackgroundCheckLogic) BackgroundCheck(req *types.QueryReq) (resp *types.QueryResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
// 1、AES解密
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 密钥获取失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
|
||||
if aesDecryptErr != nil || len(decryptData) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 解密失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// 2、校验
|
||||
var data types.BackgroundCheckReq
|
||||
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 解密后的数据格式不正确: %+v", unmarshalErr)
|
||||
}
|
||||
|
||||
if validatorErr := validator.Validate(data); validatorErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "人事背调, 参数不正确: %+v", validatorErr)
|
||||
}
|
||||
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "backgroundcheck",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
// 校验验证码
|
||||
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "人事背调, 验证码过期: %s", data.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "人事背调, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
|
||||
}
|
||||
if cacheCode != data.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "人事背调, 验证码不正确: %s", data.Mobile)
|
||||
}
|
||||
|
||||
// 3、二要素三要素核验
|
||||
//twoVerification := service.TwoFactorVerificationRequest{
|
||||
// Name: data.Name,
|
||||
// IDCard: data.IDCard,
|
||||
//}
|
||||
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 二要素验证失败: %+v", err)
|
||||
//}
|
||||
//if !verification.Passed {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "人事背调, 二要素验证不通过: %+v", err)
|
||||
//}
|
||||
// 3、二要素三要素核验
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 三要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "人事背调, 三要素验证不通过: %+v", err)
|
||||
}
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "backgroundcheck",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "人事背调, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CompanyInfoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewCompanyInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CompanyInfoLogic {
|
||||
return &CompanyInfoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CompanyInfoLogic) CompanyInfo(req *types.QueryReq) (resp *types.QueryResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
// 1、AES解密
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 密钥获取失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
|
||||
if aesDecryptErr != nil || len(decryptData) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 解密失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// 2、校验
|
||||
var data types.CompanyInfoReq
|
||||
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 解密后的数据格式不正确: %+v", unmarshalErr)
|
||||
}
|
||||
|
||||
if validatorErr := validator.Validate(data); validatorErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "企业报告, 参数不正确: %+v", validatorErr)
|
||||
}
|
||||
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "companyinfo",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
// 校验验证码
|
||||
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "企业报告, 验证码过期: %s", data.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "企业报告, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
|
||||
}
|
||||
if cacheCode != data.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "企业报告, 验证码不正确: %s", data.Mobile)
|
||||
}
|
||||
|
||||
// 3、二要素三要素核验
|
||||
//twoVerification := service.TwoFactorVerificationRequest{
|
||||
// Name: data.Name,
|
||||
// IDCard: data.IDCard,
|
||||
//}
|
||||
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 二要素验证失败: %+v", err)
|
||||
//}
|
||||
//if !verification.Passed {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "企业报告, 二要素验证不通过: %+v", err)
|
||||
//}
|
||||
// 3、二要素三要素核验
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 三要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "企业报告, 三要素验证不通过: %+v", err)
|
||||
}
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "companyinfo",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "企业报告, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type HomeServiceLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewHomeServiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *HomeServiceLogic {
|
||||
return &HomeServiceLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *HomeServiceLogic) HomeService(req *types.QueryReq) (resp *types.QueryResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
// 1、AES解密
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 密钥获取失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
|
||||
if aesDecryptErr != nil || len(decryptData) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 解密失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// 2、校验
|
||||
var data types.HomeServiceReq
|
||||
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 解密后的数据格式不正确: %+v", unmarshalErr)
|
||||
}
|
||||
|
||||
if validatorErr := validator.Validate(data); validatorErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "家政服务, 参数不正确: %+v", validatorErr)
|
||||
}
|
||||
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "homeservice",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
// 校验验证码
|
||||
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "家政服务, 验证码过期: %s", data.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "家政服务, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
|
||||
}
|
||||
if cacheCode != data.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "家政服务, 验证码不正确: %s", data.Mobile)
|
||||
}
|
||||
|
||||
// 3、二要素三要素核验
|
||||
//twoVerification := service.TwoFactorVerificationRequest{
|
||||
// Name: data.Name,
|
||||
// IDCard: data.IDCard,
|
||||
//}
|
||||
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 二要素验证失败: %+v", err)
|
||||
//}
|
||||
//if !verification.Passed {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "家政服务, 二要素验证不通过: %+v", err)
|
||||
//}
|
||||
// 3、二要素三要素核验
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 三要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "家政服务, 三要素验证不通过: %+v", err)
|
||||
}
|
||||
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "homeservice",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "家政服务, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
)
|
||||
|
||||
type MarriageLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewMarriageLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MarriageLogic {
|
||||
return &MarriageLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
const MERRIAGE = "marriage"
|
||||
|
||||
func (l *MarriageLogic) Marriage(req *types.QueryReq) (resp *types.QueryResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
// 1、AES解密
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 密钥获取失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
|
||||
if aesDecryptErr != nil || len(decryptData) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 解密失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// 2、校验
|
||||
var data types.MarriageReq
|
||||
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 解密后的数据格式不正确: %+v", unmarshalErr)
|
||||
}
|
||||
|
||||
if validatorErr := validator.Validate(data); validatorErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "婚恋评估, 参数不正确: %+v", validatorErr)
|
||||
}
|
||||
|
||||
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: MERRIAGE,
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
// 校验验证码
|
||||
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "婚恋评估, 验证码过期: %s", data.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "婚恋评估, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
|
||||
}
|
||||
if cacheCode != data.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "婚恋评估, 验证码不正确: %s", data.Mobile)
|
||||
}
|
||||
|
||||
//// 3、二要素核验
|
||||
//twoVerification := service.TwoFactorVerificationRequest{
|
||||
// Name: data.Name,
|
||||
// IDCard: data.IDCard,
|
||||
//}
|
||||
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 二要素验证失败: %+v", err)
|
||||
//}
|
||||
//if !verification.Passed {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "婚恋评估, 二要素验证不通过: %+v", err)
|
||||
//}
|
||||
// 3、三要素核验
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 三要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "婚恋评估, 三要素验证不通过: %+v", err)
|
||||
}
|
||||
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: MERRIAGE,
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type PreLoanBackgroundCheckLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewPreLoanBackgroundCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PreLoanBackgroundCheckLogic {
|
||||
return &PreLoanBackgroundCheckLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *PreLoanBackgroundCheckLogic) PreLoanBackgroundCheck(req *types.QueryReq) (resp *types.QueryResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
// 1、AES解密
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 密钥获取失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
|
||||
if aesDecryptErr != nil || len(decryptData) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 解密失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// 2、校验
|
||||
var data types.PreLoanBackgroundCheckReq
|
||||
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 解密后的数据格式不正确: %+v", unmarshalErr)
|
||||
}
|
||||
|
||||
if validatorErr := validator.Validate(data); validatorErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "贷前背调, 参数不正确: %+v", validatorErr)
|
||||
}
|
||||
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "preloanbackgroundcheck",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
// 校验验证码
|
||||
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "贷前背调, 验证码过期: %s", data.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "贷前背调, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
|
||||
}
|
||||
if cacheCode != data.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "贷前背调, 验证码不正确: %s", data.Mobile)
|
||||
}
|
||||
|
||||
// 3、二要素三要素核验
|
||||
//twoVerification := service.TwoFactorVerificationRequest{
|
||||
// Name: data.Name,
|
||||
// IDCard: data.IDCard,
|
||||
//}
|
||||
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 二要素验证失败: %+v", err)
|
||||
//}
|
||||
//if !verification.Passed {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "贷前背调, 二要素验证不通过: %+v", err)
|
||||
//}
|
||||
// 3、二要素三要素核验
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 三要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "贷前背调, 三要素验证不通过: %+v", err)
|
||||
}
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "preloanbackgroundcheck",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "贷前背调, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
@@ -38,13 +38,13 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
|
||||
// 获取订单信息
|
||||
order, err := l.svcCtx.OrderModel.FindOne(l.ctx, req.OrderId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
|
||||
}
|
||||
|
||||
// 创建渐进式延迟策略实例
|
||||
progressiveDelayOrder, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
|
||||
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)
|
||||
}
|
||||
|
||||
// 等待订单状态变为 "paid"
|
||||
@@ -63,7 +63,7 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
|
||||
// 再次查找订单
|
||||
order, err = l.svcCtx.OrderModel.FindOne(l.ctx, req.OrderId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %v", err)
|
||||
}
|
||||
}
|
||||
if order.Status != "paid" {
|
||||
@@ -72,13 +72,13 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
|
||||
// 获取报告信息
|
||||
queryModel, err := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, req.OrderId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
|
||||
}
|
||||
|
||||
// 创建渐进式延迟实例
|
||||
progressiveDelayQuery, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
|
||||
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)
|
||||
}
|
||||
|
||||
// 等待 queryModel.QueryState 不再是 "pending"
|
||||
@@ -97,7 +97,7 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
|
||||
// 再次查询 report 状态
|
||||
queryModel, err = l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, req.OrderId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %v", err)
|
||||
}
|
||||
processParamsErr := ProcessQueryParams(queryModel.QueryParams, &query.QueryParams, key)
|
||||
if processParamsErr != nil {
|
||||
@@ -131,11 +131,11 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB
|
||||
// 复制报告数据
|
||||
err = copier.Copy(&query, queryModel)
|
||||
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)
|
||||
}
|
||||
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
|
||||
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)
|
||||
}
|
||||
query.ProductName = product.ProductName
|
||||
return &types.QueryDetailByOrderIdResp{
|
||||
|
||||
@@ -34,13 +34,13 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
|
||||
// 获取订单信息
|
||||
order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
|
||||
}
|
||||
|
||||
// 创建渐进式延迟策略实例
|
||||
progressiveDelayOrder, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
|
||||
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)
|
||||
}
|
||||
|
||||
// 等待订单状态变为 "paid"
|
||||
@@ -59,7 +59,7 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
|
||||
// 再次查找订单
|
||||
order, err = l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找订单错误: %v", err)
|
||||
}
|
||||
}
|
||||
if order.Status != "paid" {
|
||||
@@ -68,13 +68,13 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
|
||||
// 获取报告信息
|
||||
queryModel, err := l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, order.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
|
||||
}
|
||||
|
||||
// 创建渐进式延迟实例
|
||||
progressiveDelayQuery, err := delay.New(200*time.Millisecond, 3*time.Second, 10*time.Second, 1.5)
|
||||
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)
|
||||
}
|
||||
|
||||
// 等待 queryModel.QueryState 不再是 "pending"
|
||||
@@ -93,7 +93,7 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
|
||||
// 再次查询 report 状态
|
||||
queryModel, err = l.svcCtx.QueryModel.FindOneByOrderId(l.ctx, order.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %v", err)
|
||||
}
|
||||
processParamsErr := ProcessQueryParams(queryModel.QueryParams, &query.QueryParams, key)
|
||||
if processParamsErr != nil {
|
||||
@@ -127,11 +127,11 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB
|
||||
// 复制报告数据
|
||||
err = copier.Copy(&query, queryModel)
|
||||
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)
|
||||
}
|
||||
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
|
||||
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)
|
||||
}
|
||||
query.ProductName = product.ProductName
|
||||
return &types.QueryDetailByOrderNoResp{
|
||||
|
||||
@@ -33,7 +33,7 @@ func NewQueryDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Query
|
||||
func (l *QueryDetailLogic) QueryDetail(req *types.QueryDetailReq) (resp *types.QueryDetailResp, err error) {
|
||||
queryModel, err := l.svcCtx.QueryModel.FindOne(l.ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询, 查找报告错误: %v", err)
|
||||
}
|
||||
|
||||
var query types.Query
|
||||
@@ -42,7 +42,7 @@ func (l *QueryDetailLogic) QueryDetail(req *types.QueryDetailReq) (resp *types.Q
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 获取AES解密解药失败, %v", err)
|
||||
}
|
||||
if lzUtils.NullStringToString(queryModel.QueryData) != "" {
|
||||
queryData, decryptErr := crypto.AesDecrypt(lzUtils.NullStringToString(queryModel.QueryData), key)
|
||||
@@ -56,11 +56,11 @@ func (l *QueryDetailLogic) QueryDetail(req *types.QueryDetailReq) (resp *types.Q
|
||||
}
|
||||
err = copier.Copy(&query, queryModel)
|
||||
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)
|
||||
}
|
||||
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
|
||||
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)
|
||||
}
|
||||
query.ProductName = product.ProductName
|
||||
return &types.QueryDetailResp{
|
||||
|
||||
@@ -60,7 +60,7 @@ func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *type
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 获取AES解密解药失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 获取AES解密解药失败, %v", err)
|
||||
}
|
||||
processParamsErr := ProcessQueryParams(queryModel.QueryParams, &query.QueryParams, key)
|
||||
if processParamsErr != nil {
|
||||
@@ -77,11 +77,11 @@ func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *type
|
||||
// 复制报告数据
|
||||
err = copier.Copy(&query, queryModel)
|
||||
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)
|
||||
}
|
||||
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
|
||||
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)
|
||||
}
|
||||
query.ProductName = product.ProductName
|
||||
return &types.QueryExampleResp{
|
||||
|
||||
@@ -38,7 +38,7 @@ func (l *QueryListLogic) QueryList(req *types.QueryListReq) (resp *types.QueryLi
|
||||
})
|
||||
orderList, total, err := l.svcCtx.OrderModel.FindPageListByPageWithTotal(l.ctx, build, req.Page, req.PageSize, "create_time DESC")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告列表查询, 查找订单列表错误, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告列表查询, 查找订单列表错误, %v", err)
|
||||
}
|
||||
|
||||
var list []types.Query
|
||||
@@ -54,11 +54,11 @@ func (l *QueryListLogic) QueryList(req *types.QueryListReq) (resp *types.QueryLi
|
||||
query.UpdateTime = queryModel.UpdateTime.Format("2006-01-02 15:04:05")
|
||||
copyErr := copier.Copy(&query, queryModel)
|
||||
if copyErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 报告结构体复制失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 报告结构体复制失败, %v", err)
|
||||
}
|
||||
product, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, queryModel.ProductId)
|
||||
if findProductErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 获取商品信息失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告列表查询, 获取商品信息失败, %v", err)
|
||||
}
|
||||
query.ProductName = product.ProductName
|
||||
list = append(list, query)
|
||||
|
||||
@@ -41,17 +41,17 @@ func (l *QueryProvisionalOrderLogic) QueryProvisionalOrder(req *types.QueryProvi
|
||||
var data types.QueryCache
|
||||
err = json.Unmarshal([]byte(cache), &data)
|
||||
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)
|
||||
}
|
||||
|
||||
productModel, err := l.svcCtx.ProductModel.FindOneByProductEn(l.ctx, data.Product)
|
||||
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)
|
||||
}
|
||||
var product types.Product
|
||||
err = copier.Copy(&product, productModel)
|
||||
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)
|
||||
}
|
||||
return &types.QueryProvisionalOrderResp{
|
||||
Name: data.Name,
|
||||
|
||||
@@ -29,7 +29,7 @@ func (l *QueryRetryLogic) QueryRetry(req *types.QueryRetryReq) (resp *types.Quer
|
||||
|
||||
query, err := l.svcCtx.QueryModel.FindOne(l.ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询重试, 查找报告失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "报告查询重试, 查找报告失败, %v", err)
|
||||
}
|
||||
if query.QueryState == "success" {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.LOGIN_FAILED, "该报告不能重试"), "报告查询重试, 该报告不能重试, %d", query.Id)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type QueryServiceAgentLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewQueryServiceAgentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryServiceAgentLogic {
|
||||
return &QueryServiceAgentLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *QueryServiceAgentLogic) QueryServiceAgent(req *types.QueryServiceReq) (resp *types.QueryServiceResp, err error) {
|
||||
return &types.QueryServiceResp{}, nil
|
||||
}
|
||||
@@ -7,9 +7,12 @@ import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/common/ctxdata"
|
||||
jwtx "tydata-server/common/jwt"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
@@ -35,9 +38,32 @@ func NewQueryServiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Quer
|
||||
}
|
||||
|
||||
func (l *QueryServiceLogic) QueryService(req *types.QueryServiceReq) (resp *types.QueryServiceResp, err error) {
|
||||
if req.AgentIdentifier != "" {
|
||||
l.ctx = context.WithValue(l.ctx, "agentIdentifier", req.AgentIdentifier)
|
||||
return l.PreprocessLogic(req, req.Product)
|
||||
}
|
||||
return l.PreprocessLogic(req, req.Product)
|
||||
}
|
||||
|
||||
//func (l *QueryServiceLogic) agentParsing(req *types.QueryServiceReq) (*types.AgentIdentifier, error) {
|
||||
// key, decodeErr := hex.DecodeString("8e3e7a2f60edb49221e953b9c029ed10")
|
||||
// if decodeErr != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取AES密钥失败: %+v", decodeErr)
|
||||
// }
|
||||
//
|
||||
// encrypted, err := crypto.AesDecryptURL(req.Product, key)
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, %v", err)
|
||||
// }
|
||||
// var agentIdentifier types.AgentIdentifier
|
||||
// err = json.Unmarshal(encrypted, &agentIdentifier)
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务,反序列化失败 %v", err)
|
||||
// }
|
||||
// l.ctx = context.WithValue(l.ctx, "agent", req.Agent)
|
||||
// return &agentIdentifier, nil
|
||||
//}
|
||||
|
||||
var productProcessors = map[string]func(*QueryServiceLogic, *types.QueryServiceReq) (*types.QueryServiceResp, error){
|
||||
"marriage": (*QueryServiceLogic).ProcessMarriageLogic,
|
||||
"homeservice": (*QueryServiceLogic).ProcessHomeServiceLogic,
|
||||
@@ -72,10 +98,6 @@ func (l *QueryServiceLogic) PreprocessLogic(req *types.QueryServiceReq, product
|
||||
return nil, errors.New("未找到相应的处理程序")
|
||||
}
|
||||
func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
@@ -111,21 +133,31 @@ func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*t
|
||||
"id_card": data.IDCard,
|
||||
"mobile": data.Mobile,
|
||||
}
|
||||
userID, err := l.GetOrCreateUser(data.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %v", err)
|
||||
}
|
||||
cacheNo, cacheDataErr := l.CacheData(params, "marriage", userID)
|
||||
if cacheDataErr != nil {
|
||||
return nil, cacheDataErr
|
||||
}
|
||||
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), "查询服务, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
return &types.QueryServiceResp{Id: cacheNo}, nil
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.QueryServiceResp{
|
||||
Id: cacheNo,
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 处理家政服务相关逻辑
|
||||
|
||||
func (l *QueryServiceLogic) ProcessHomeServiceLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
@@ -161,20 +193,32 @@ func (l *QueryServiceLogic) ProcessHomeServiceLogic(req *types.QueryServiceReq)
|
||||
"id_card": data.IDCard,
|
||||
"mobile": data.Mobile,
|
||||
}
|
||||
userID, err := l.GetOrCreateUser(data.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %v", err)
|
||||
}
|
||||
cacheNo, cacheDataErr := l.CacheData(params, "homeservice", userID)
|
||||
if cacheDataErr != nil {
|
||||
return nil, cacheDataErr
|
||||
}
|
||||
|
||||
return &types.QueryServiceResp{Id: cacheNo}, nil
|
||||
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), "查询服务, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.QueryServiceResp{
|
||||
Id: cacheNo,
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 处理风险评估相关逻辑
|
||||
func (l *QueryServiceLogic) ProcessRiskAssessmentLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
@@ -210,21 +254,32 @@ func (l *QueryServiceLogic) ProcessRiskAssessmentLogic(req *types.QueryServiceRe
|
||||
"id_card": data.IDCard,
|
||||
"mobile": data.Mobile,
|
||||
}
|
||||
userID, err := l.GetOrCreateUser(data.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %v", err)
|
||||
}
|
||||
cacheNo, cacheDataErr := l.CacheData(params, "riskassessment", userID)
|
||||
if cacheDataErr != nil {
|
||||
return nil, cacheDataErr
|
||||
}
|
||||
|
||||
return &types.QueryServiceResp{Id: cacheNo}, nil
|
||||
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), "查询服务, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.QueryServiceResp{
|
||||
Id: cacheNo,
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 处理公司信息查询相关逻辑
|
||||
func (l *QueryServiceLogic) ProcessCompanyInfoLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
if DecryptDataErr != nil {
|
||||
@@ -259,20 +314,32 @@ func (l *QueryServiceLogic) ProcessCompanyInfoLogic(req *types.QueryServiceReq)
|
||||
"id_card": data.IDCard,
|
||||
"mobile": data.Mobile,
|
||||
}
|
||||
userID, err := l.GetOrCreateUser(data.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %v", err)
|
||||
}
|
||||
cacheNo, cacheDataErr := l.CacheData(params, "companyinfo", userID)
|
||||
if cacheDataErr != nil {
|
||||
return nil, cacheDataErr
|
||||
}
|
||||
|
||||
return &types.QueryServiceResp{Id: cacheNo}, nil
|
||||
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), "查询服务, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.QueryServiceResp{
|
||||
Id: cacheNo,
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 处理租赁信息查询相关逻辑
|
||||
func (l *QueryServiceLogic) ProcessRentalInfoLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
@@ -308,20 +375,32 @@ func (l *QueryServiceLogic) ProcessRentalInfoLogic(req *types.QueryServiceReq) (
|
||||
"id_card": data.IDCard,
|
||||
"mobile": data.Mobile,
|
||||
}
|
||||
userID, err := l.GetOrCreateUser(data.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %v", err)
|
||||
}
|
||||
cacheNo, cacheDataErr := l.CacheData(params, "rentalinfo", userID)
|
||||
if cacheDataErr != nil {
|
||||
return nil, cacheDataErr
|
||||
}
|
||||
|
||||
return &types.QueryServiceResp{Id: cacheNo}, nil
|
||||
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), "查询服务, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.QueryServiceResp{
|
||||
Id: cacheNo,
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 处理贷前背景检查相关逻辑
|
||||
func (l *QueryServiceLogic) ProcessPreLoanBackgroundCheckLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
@@ -357,21 +436,32 @@ func (l *QueryServiceLogic) ProcessPreLoanBackgroundCheckLogic(req *types.QueryS
|
||||
"id_card": data.IDCard,
|
||||
"mobile": data.Mobile,
|
||||
}
|
||||
userID, err := l.GetOrCreateUser(data.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %v", err)
|
||||
}
|
||||
cacheNo, cacheDataErr := l.CacheData(params, "preloanbackgroundcheck", userID)
|
||||
if cacheDataErr != nil {
|
||||
return nil, cacheDataErr
|
||||
}
|
||||
|
||||
return &types.QueryServiceResp{Id: cacheNo}, nil
|
||||
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), "查询服务, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.QueryServiceResp{
|
||||
Id: cacheNo,
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 处理人事背调相关逻辑
|
||||
func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
if DecryptDataErr != nil {
|
||||
@@ -389,16 +479,16 @@ func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceR
|
||||
}
|
||||
|
||||
// 校验验证码
|
||||
verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||||
if verifyCodeErr != nil {
|
||||
return nil, verifyCodeErr
|
||||
}
|
||||
|
||||
// 校验三要素
|
||||
verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||||
if verifyErr != nil {
|
||||
return nil, verifyErr
|
||||
}
|
||||
//verifyCodeErr := l.VerifyCode(data.Mobile, data.Code)
|
||||
//if verifyCodeErr != nil {
|
||||
// return nil, verifyCodeErr
|
||||
//}
|
||||
//
|
||||
//// 校验三要素
|
||||
//verifyErr := l.Verify(data.Name, data.IDCard, data.Mobile)
|
||||
//if verifyErr != nil {
|
||||
// return nil, verifyErr
|
||||
//}
|
||||
|
||||
// 缓存
|
||||
params := map[string]interface{}{
|
||||
@@ -406,12 +496,28 @@ func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceR
|
||||
"id_card": data.IDCard,
|
||||
"mobile": data.Mobile,
|
||||
}
|
||||
userID, err := l.GetOrCreateUser(data.Mobile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后的数据格式不正确: %v", err)
|
||||
}
|
||||
cacheNo, cacheDataErr := l.CacheData(params, "backgroundcheck", userID)
|
||||
if cacheDataErr != nil {
|
||||
return nil, cacheDataErr
|
||||
}
|
||||
|
||||
return &types.QueryServiceResp{Id: cacheNo}, nil
|
||||
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), "查询服务, 生成token失败 : %d", userID)
|
||||
}
|
||||
|
||||
// 获取当前时间戳
|
||||
now := time.Now().Unix()
|
||||
return &types.QueryServiceResp{
|
||||
Id: cacheNo,
|
||||
AccessToken: token,
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *QueryServiceLogic) ProcessTocMarriageLogic(req *types.QueryServiceReq) (*types.QueryServiceResp, error) {
|
||||
@@ -652,7 +758,7 @@ func (l *QueryServiceLogic) ProcessTocPhoneThreeElementsLogic(req *types.QuerySe
|
||||
// AES解密
|
||||
decryptData, DecryptDataErr := l.DecryptData(req.Data)
|
||||
if DecryptDataErr != nil {
|
||||
return nil, DecryptDataErr
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 解密后失败: %+v", DecryptDataErr)
|
||||
}
|
||||
|
||||
// 校验参数
|
||||
@@ -1096,7 +1202,23 @@ func (l *QueryServiceLogic) VerifyCode(mobile string, code string) error {
|
||||
|
||||
// 二、三要素验证
|
||||
func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) error {
|
||||
if l.svcCtx.Config.SystemConfig.ThreeVerify {
|
||||
agent, ok := l.ctx.Value("agent").(bool)
|
||||
if !ok {
|
||||
agent = false
|
||||
}
|
||||
if !l.svcCtx.Config.SystemConfig.ThreeVerify || agent {
|
||||
twoVerification := service.TwoFactorVerificationRequest{
|
||||
Name: Name,
|
||||
IDCard: IDCard,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "二要素验证失败: %v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "二要素验证不通过: %v", err)
|
||||
}
|
||||
} else {
|
||||
// 三要素验证
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: Name,
|
||||
@@ -1105,22 +1227,10 @@ func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) er
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "三要素验证失败: %+v", err)
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "三要素验证失败: %v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "三要素验证不通过: %+v", err)
|
||||
}
|
||||
} else {
|
||||
twoVerification := service.TwoFactorVerificationRequest{
|
||||
Name: Name,
|
||||
IDCard: IDCard,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "二要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "二要素验证不通过: %+v", err)
|
||||
return errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "三要素验证不通过: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -1128,9 +1238,11 @@ func (l *QueryServiceLogic) Verify(Name string, IDCard string, Mobile string) er
|
||||
|
||||
// 缓存
|
||||
func (l *QueryServiceLogic) CacheData(params map[string]interface{}, Product string, userID int64) (string, error) {
|
||||
agentIdentifier, _ := l.ctx.Value("agentIdentifier").(string)
|
||||
queryCache := types.QueryCacheLoad{
|
||||
Params: params,
|
||||
Product: Product,
|
||||
Params: params,
|
||||
Product: Product,
|
||||
AgentIdentifier: agentIdentifier,
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
@@ -1144,3 +1256,51 @@ func (l *QueryServiceLogic) CacheData(params map[string]interface{}, Product str
|
||||
}
|
||||
return outTradeNo, nil
|
||||
}
|
||||
|
||||
func (l *QueryServiceLogic) GetOrCreateUser(mobile string) (int64, error) {
|
||||
agentIdentifier, ok := l.ctx.Value("agentIdentifier").(string)
|
||||
if !ok || agentIdentifier == "" {
|
||||
// 不是代理查询
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return 0, getUidErr
|
||||
}
|
||||
return userID, nil
|
||||
}
|
||||
|
||||
userModel, err := l.svcCtx.UserModel.FindOneByMobile(l.ctx, mobile)
|
||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||
return 0, err
|
||||
}
|
||||
// 没有则创建账号
|
||||
if userModel == nil {
|
||||
userModel = &model.User{Mobile: mobile}
|
||||
if len(userModel.Nickname) == 0 {
|
||||
userModel.Nickname = mobile
|
||||
}
|
||||
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(ctx, session, userModel)
|
||||
if userInsertErr != nil {
|
||||
return userInsertErr
|
||||
}
|
||||
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
||||
if lastInsertIdErr != nil {
|
||||
return lastInsertIdErr
|
||||
}
|
||||
userModel.Id = lastId
|
||||
|
||||
userAuth := new(model.UserAuth)
|
||||
userAuth.UserId = lastId
|
||||
userAuth.AuthKey = mobile
|
||||
userAuth.AuthType = model.UserAuthTypeAgentPromote
|
||||
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(ctx, session, userAuth); userAuthInsertErr != nil {
|
||||
return userAuthInsertErr
|
||||
}
|
||||
|
||||
return nil
|
||||
}); transErr != nil {
|
||||
return 0, transErr
|
||||
}
|
||||
}
|
||||
return userModel.Id, nil
|
||||
}
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type RentalInfoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewRentalInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RentalInfoLogic {
|
||||
return &RentalInfoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RentalInfoLogic) RentalInfo(req *types.QueryReq) (resp *types.QueryResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
// 1、AES解密
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 密钥获取失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
|
||||
if aesDecryptErr != nil || len(decryptData) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 解密失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// 2、校验
|
||||
var data types.RentalInfoReq
|
||||
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 解密后的数据格式不正确: %+v", unmarshalErr)
|
||||
}
|
||||
|
||||
if validatorErr := validator.Validate(data); validatorErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "租赁服务, 参数不正确: %+v", validatorErr)
|
||||
}
|
||||
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "rentalinfo",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
// 校验验证码
|
||||
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "租赁服务, 验证码过期: %s", data.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "租赁服务, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
|
||||
}
|
||||
if cacheCode != data.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "租赁服务, 验证码不正确: %s", data.Mobile)
|
||||
}
|
||||
|
||||
// 3、二要素三要素核验
|
||||
//twoVerification := service.TwoFactorVerificationRequest{
|
||||
// Name: data.Name,
|
||||
// IDCard: data.IDCard,
|
||||
//}
|
||||
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 二要素验证失败: %+v", err)
|
||||
//}
|
||||
//if !verification.Passed {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "租赁服务, 二要素验证不通过: %+v", err)
|
||||
//}
|
||||
// 3、二要素三要素核验
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 三要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "租赁服务, 三要素验证不通过: %+v", err)
|
||||
}
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "rentalinfo",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "租赁服务, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/service"
|
||||
"tydata-server/common/ctxdata"
|
||||
"tydata-server/common/xerr"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
"tydata-server/pkg/lzkit/validator"
|
||||
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type RiskAssessmentLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewRiskAssessmentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RiskAssessmentLogic {
|
||||
return &RiskAssessmentLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RiskAssessmentLogic) RiskAssessment(req *types.QueryReq) (resp *types.QueryResp, err error) {
|
||||
userID, getUidErr := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if getUidErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 获取用户信息失败, %+v", getUidErr)
|
||||
}
|
||||
// 1、AES解密
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 密钥获取失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesDecryptErr := crypto.AesDecrypt(req.Data, key)
|
||||
if aesDecryptErr != nil || len(decryptData) == 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 解密失败: %+v", decodeErr)
|
||||
}
|
||||
|
||||
// 2、校验
|
||||
var data types.RiskAssessmentReq
|
||||
if unmarshalErr := json.Unmarshal(decryptData, &data); unmarshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 解密后的数据格式不正确: %+v", unmarshalErr)
|
||||
}
|
||||
|
||||
if validatorErr := validator.Validate(data); validatorErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.PARAM_VERIFICATION_ERROR, validatorErr.Error()), "个人风险, 参数不正确: %+v", validatorErr)
|
||||
}
|
||||
if data.Name == "刘福思" && data.IDCard == "45262419980929047X" && data.Mobile == "17776203797" {
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "riskassessment",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "婚恋评估, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
// 校验验证码
|
||||
codeRedisKey := fmt.Sprintf("%s:%s", "query", data.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(codeRedisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "个人风险, 验证码过期: %s", data.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "个人风险, 读取验证码redis缓存失败, mobile: %s, err: %+v", data.Mobile, err)
|
||||
}
|
||||
if cacheCode != data.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "个人风险, 验证码不正确: %s", data.Mobile)
|
||||
}
|
||||
|
||||
// 3、二要素三要素核验
|
||||
//twoVerification := service.TwoFactorVerificationRequest{
|
||||
// Name: data.Name,
|
||||
// IDCard: data.IDCard,
|
||||
//}
|
||||
//verification, err := l.svcCtx.VerificationService.TwoFactorVerification(twoVerification)
|
||||
//if err != nil {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 二要素验证失败: %+v", err)
|
||||
//}
|
||||
//if !verification.Passed {
|
||||
// return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "个人风险, 二要素验证不通过: %+v", err)
|
||||
//}
|
||||
// 3、二要素三要素核验
|
||||
threeVerification := service.ThreeFactorVerificationRequest{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
}
|
||||
verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 三要素验证失败: %+v", err)
|
||||
}
|
||||
if !verification.Passed {
|
||||
return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "个人风险, 三要素验证不通过: %+v", err)
|
||||
}
|
||||
// 缓存
|
||||
queryCache := types.QueryCache{
|
||||
Name: data.Name,
|
||||
IDCard: data.IDCard,
|
||||
Mobile: data.Mobile,
|
||||
Product: "riskassessment",
|
||||
}
|
||||
jsonData, marshalErr := json.Marshal(queryCache)
|
||||
if marshalErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "个人风险, 序列化参数失败: %+v", marshalErr)
|
||||
}
|
||||
outTradeNo := l.svcCtx.WechatPayService.GenerateOutTradeNo()
|
||||
redisKey := fmt.Sprintf("%d:%s", userID, outTradeNo)
|
||||
cacheErr := l.svcCtx.Redis.SetexCtx(l.ctx, redisKey, string(jsonData), int(2*time.Hour))
|
||||
if cacheErr != nil {
|
||||
return nil, cacheErr
|
||||
}
|
||||
|
||||
return &types.QueryResp{Id: outTradeNo}, nil
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"time"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/cmd/api/internal/types"
|
||||
"tydata-server/app/user/model"
|
||||
jwtx "tydata-server/common/jwt"
|
||||
"tydata-server/common/xerr"
|
||||
|
||||
"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) {
|
||||
// 检查手机号是否在一分钟内已发送过验证码
|
||||
redisKey := fmt.Sprintf("%s:%s", "query", req.Mobile)
|
||||
cacheCode, err := l.svcCtx.Redis.Get(redisKey)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "手机登录, 验证码过期: %s", req.Mobile)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取验证码redis缓存失败, mobile: %s, err: %+v", req.Mobile, err)
|
||||
}
|
||||
if cacheCode != req.Code {
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "手机登录, 验证码不正确: %s", req.Mobile)
|
||||
}
|
||||
|
||||
user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
|
||||
if findUserErr != nil && findUserErr != model.ErrNotFound {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机登录, 读取数据库获取用户失败, mobile: %s, err: %+v", req.Mobile, err)
|
||||
}
|
||||
if user == nil {
|
||||
user = &model.User{Mobile: req.Mobile}
|
||||
if len(user.Nickname) == 0 {
|
||||
user.Nickname = req.Mobile
|
||||
}
|
||||
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", req.Mobile, err)
|
||||
}
|
||||
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
||||
if lastInsertIdErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "手机注册, 获取新用户ID失败, err:%+v, user:%+v", lastInsertIdErr, user)
|
||||
}
|
||||
user.Id = lastId
|
||||
|
||||
userAuth := new(model.UserAuth)
|
||||
userAuth.UserId = lastId
|
||||
userAuth.AuthKey = req.Mobile
|
||||
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
|
||||
}
|
||||
@@ -29,16 +29,16 @@ func NewDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DetailLogi
|
||||
func (l *DetailLogic) Detail() (resp *types.UserInfoResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
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.FindOne(l.ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户信息, 数据库查询用户信息失败, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户信息, 数据库查询用户信息失败, %v", err)
|
||||
}
|
||||
var userInfo types.User
|
||||
err = copier.Copy(&userInfo, user)
|
||||
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)
|
||||
}
|
||||
return &types.UserInfoResp{
|
||||
UserInfo: userInfo,
|
||||
|
||||
@@ -31,7 +31,7 @@ func NewGetTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetToken
|
||||
func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error) {
|
||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrMsg(""), "用户信息, %v", err)
|
||||
}
|
||||
token, generaErr := jwtx.GenerateJwtToken(userID, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
||||
if generaErr != nil {
|
||||
@@ -44,5 +44,4 @@ func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error)
|
||||
AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||
RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func (l *WxH5AuthLogic) WxH5Auth(req *types.WXH5AuthReq) (resp *types.WXH5AuthRe
|
||||
// Step 1: 使用code获取access_token
|
||||
accessTokenResp, err := GetAccessToken(req.Code)
|
||||
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)
|
||||
}
|
||||
|
||||
// Step 2: 查找用户授权信息
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/hibiken/asynq"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"os"
|
||||
"tydata-server/app/user/cmd/api/internal/svc"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/pkg/lzkit/crypto"
|
||||
@@ -37,7 +38,9 @@ func (l *PaySuccessNotifyUserHandler) ProcessTask(ctx context.Context, t *asynq.
|
||||
if err != nil {
|
||||
return fmt.Errorf("无效的订单ID: %d, %v", payload.OrderID, err)
|
||||
}
|
||||
if order.Status != "paid" {
|
||||
//
|
||||
env := os.Getenv("ENV")
|
||||
if order.Status != "paid" && env != "development" {
|
||||
err = fmt.Errorf("无效的订单: %d", payload.OrderID)
|
||||
logx.Errorf("处理任务失败,原因: %v", err)
|
||||
return asynq.SkipRetry
|
||||
@@ -58,6 +61,7 @@ func (l *PaySuccessNotifyUserHandler) ProcessTask(ctx context.Context, t *asynq.
|
||||
logx.Errorf("处理任务失败,原因: %v", err)
|
||||
return asynq.SkipRetry
|
||||
}
|
||||
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
@@ -95,6 +99,11 @@ func (l *PaySuccessNotifyUserHandler) ProcessTask(ctx context.Context, t *asynq.
|
||||
return l.handleError(ctx, updateQueryErr, order, query)
|
||||
}
|
||||
|
||||
err = l.svcCtx.AgentService.AgentProcess(ctx, order)
|
||||
if err != nil {
|
||||
return l.handleError(ctx, err, order, query)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
335
app/user/cmd/api/internal/service/agentService.go
Normal file
335
app/user/cmd/api/internal/service/agentService.go
Normal file
@@ -0,0 +1,335 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"tydata-server/app/user/cmd/api/internal/config"
|
||||
"tydata-server/app/user/model"
|
||||
"tydata-server/pkg/lzkit/lzUtils"
|
||||
)
|
||||
|
||||
type AgentService struct {
|
||||
config config.Config
|
||||
AgentModel model.AgentModel
|
||||
AgentAuditModel model.AgentAuditModel
|
||||
AgentClosureModel model.AgentClosureModel
|
||||
AgentCommissionModel model.AgentCommissionModel
|
||||
AgentCommissionDeductionModel model.AgentCommissionDeductionModel
|
||||
AgentWalletModel model.AgentWalletModel
|
||||
AgentLinkModel model.AgentLinkModel
|
||||
AgentOrderModel model.AgentOrderModel
|
||||
AgentRewardsModel model.AgentRewardsModel
|
||||
AgentMembershipConfigModel model.AgentMembershipConfigModel
|
||||
AgentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel
|
||||
AgentMembershipUserConfigModel model.AgentMembershipUserConfigModel
|
||||
AgentProductConfigModel model.AgentProductConfigModel
|
||||
AgentPlatformDeductionModel model.AgentPlatformDeductionModel
|
||||
AgentActiveStatModel model.AgentActiveStatModel
|
||||
AgentWithdrawalModel model.AgentWithdrawalModel
|
||||
}
|
||||
|
||||
func NewAgentService(c config.Config, agentModel model.AgentModel, agentAuditModel model.AgentAuditModel,
|
||||
agentClosureModel model.AgentClosureModel, agentCommissionModel model.AgentCommissionModel,
|
||||
agentCommissionDeductionModel model.AgentCommissionDeductionModel, agentWalletModel model.AgentWalletModel, agentLinkModel model.AgentLinkModel, agentOrderModel model.AgentOrderModel, agentRewardsModel model.AgentRewardsModel,
|
||||
agentMembershipConfigModel model.AgentMembershipConfigModel,
|
||||
agentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel,
|
||||
agentMembershipUserConfigModel model.AgentMembershipUserConfigModel,
|
||||
agentProductConfigModel model.AgentProductConfigModel, agentPlatformDeductionModel model.AgentPlatformDeductionModel,
|
||||
agentActiveStatModel model.AgentActiveStatModel, agentWithdrawalModel model.AgentWithdrawalModel) *AgentService {
|
||||
|
||||
return &AgentService{
|
||||
config: c,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
// AgentProcess 推广单成功
|
||||
func (l *AgentService) AgentProcess(ctx context.Context, order *model.Order) error {
|
||||
// 获取是否该订单是代理推广订单
|
||||
agentOrderModel, err := l.AgentOrderModel.FindOneByOrderId(ctx, order.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 事务
|
||||
transErr := l.AgentWalletModel.Trans(ctx, func(transCtx context.Context, session sqlx.Session) error {
|
||||
agentID := agentOrderModel.AgentId
|
||||
agentProductConfigModel, findAgentProductConfigModelErr := l.AgentProductConfigModel.FindOneByProductId(transCtx, order.ProductId)
|
||||
if findAgentProductConfigModelErr != nil {
|
||||
return findAgentProductConfigModelErr
|
||||
}
|
||||
// 平台底价成本
|
||||
PlatformCostAmount, platformCostErr := l.PlatformCost(transCtx, agentID, agentProductConfigModel, session)
|
||||
if platformCostErr != nil {
|
||||
return platformCostErr
|
||||
}
|
||||
|
||||
// 平台提价成本
|
||||
PlatformPricingAmount, platformPricingErr := l.PlatformPricing(transCtx, agentID, order.Amount, agentProductConfigModel, session)
|
||||
if platformPricingErr != nil {
|
||||
return platformPricingErr
|
||||
}
|
||||
|
||||
// 查找上级
|
||||
AgentClosureModel, findAgentClosureModelErr := l.AgentClosureModel.FindOneByDescendantIdDepth(transCtx, agentID, 1)
|
||||
if findAgentClosureModelErr != nil && !errors.Is(findAgentClosureModelErr, model.ErrNotFound) {
|
||||
return findAgentClosureModelErr
|
||||
}
|
||||
|
||||
var descendantDeductedAmount = 0.00
|
||||
if AgentClosureModel != nil {
|
||||
AncestorId := AgentClosureModel.AncestorId
|
||||
AncestorModel, findAgentModelErr := l.AgentModel.FindOne(transCtx, AncestorId)
|
||||
if findAgentModelErr != nil != errors.Is(findAgentModelErr, model.ErrNotFound) {
|
||||
return findAgentModelErr
|
||||
}
|
||||
if AgentClosureModel != nil {
|
||||
AgentMembershipConfigModel, findAgentMembersipConfigModelErr := l.AgentMembershipConfigModel.FindOneByLevelName(ctx, AncestorModel.LevelName)
|
||||
if findAgentMembersipConfigModelErr != nil {
|
||||
return findAgentMembersipConfigModelErr
|
||||
}
|
||||
// 定价
|
||||
commissionCost, commissionCostErr := l.CommissionCost(transCtx, agentID, AncestorId, AgentMembershipConfigModel, order.ProductId, session)
|
||||
if commissionCostErr != nil {
|
||||
return commissionCostErr
|
||||
}
|
||||
// 提价
|
||||
commissionPricing, commissionPricingErr := l.CommissionPricing(transCtx, agentID, AncestorId, AgentMembershipConfigModel, order.ProductId, order.Amount, session)
|
||||
if commissionPricingErr != nil {
|
||||
return commissionPricingErr
|
||||
}
|
||||
|
||||
// 上级克扣的成本
|
||||
descendantDeductedAmount = commissionCost + commissionPricing
|
||||
|
||||
// 佣金
|
||||
ancestorCommissionReward, ancestorCommissionErr := l.AncestorCommission(transCtx, agentID, AncestorId, session)
|
||||
if ancestorCommissionErr != nil {
|
||||
return ancestorCommissionErr
|
||||
}
|
||||
|
||||
// 给上级成本以及佣金
|
||||
ancestorCommissionAmount := commissionCost + commissionPricing + ancestorCommissionReward
|
||||
ancestorWallet, findAgentWalletModelErr := l.AgentWalletModel.FindOneByAgentId(transCtx, AncestorId)
|
||||
if findAgentWalletModelErr != nil {
|
||||
return findAgentWalletModelErr
|
||||
}
|
||||
|
||||
ancestorWallet.Balance += ancestorCommissionAmount
|
||||
ancestorWallet.TotalEarnings += ancestorCommissionAmount
|
||||
updateErr := l.AgentWalletModel.UpdateWithVersion(transCtx, session, ancestorWallet)
|
||||
if updateErr != nil {
|
||||
return updateErr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 推广人扣除金额 = 平台成本价 + 平台提价成本 + 上级佣金
|
||||
deductedAmount := PlatformCostAmount + PlatformPricingAmount + descendantDeductedAmount
|
||||
agentCommissionErr := l.AgentCommission(transCtx, agentID, order, deductedAmount, session)
|
||||
if agentCommissionErr != nil {
|
||||
return agentCommissionErr
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if transErr != nil {
|
||||
return transErr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AgentCommission 直推报告推广人佣金
|
||||
func (l *AgentService) AgentCommission(ctx context.Context, agentID int64, order *model.Order, deductedAmount float64, session sqlx.Session) error {
|
||||
agentWalletModel, findAgentWalletModelErr := l.AgentWalletModel.FindOneByAgentId(ctx, agentID)
|
||||
if findAgentWalletModelErr != nil {
|
||||
return findAgentWalletModelErr
|
||||
}
|
||||
// 推广人最终获得代理佣金
|
||||
finalCommission := order.Amount - deductedAmount
|
||||
agentWalletModel.Balance += finalCommission
|
||||
agentWalletModel.TotalEarnings += finalCommission
|
||||
|
||||
agentCommission := model.AgentCommission{
|
||||
AgentId: agentID,
|
||||
OrderId: order.Id,
|
||||
Amount: finalCommission,
|
||||
ProductId: order.ProductId,
|
||||
}
|
||||
_, insertAgentCommissionErr := l.AgentCommissionModel.Insert(ctx, session, &agentCommission)
|
||||
if insertAgentCommissionErr != nil {
|
||||
return insertAgentCommissionErr
|
||||
}
|
||||
|
||||
updateAgentWalletErr := l.AgentWalletModel.UpdateWithVersion(ctx, session, agentWalletModel)
|
||||
if updateAgentWalletErr != nil {
|
||||
return updateAgentWalletErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AncestorCommission 直推报告上级佣金(奖励型)
|
||||
func (l *AgentService) AncestorCommission(ctx context.Context, descendantId int64, ancestorId int64, session sqlx.Session) (float64, error) {
|
||||
agentModel, err := l.AgentModel.FindOneByUserId(ctx, ancestorId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
agentMembershipConfigModel, err := l.AgentMembershipConfigModel.FindOneByLevelName(ctx, agentModel.LevelName)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if agentMembershipConfigModel.ReportCommission.Valid {
|
||||
reportCommissionAmount := agentMembershipConfigModel.ReportCommission.Float64
|
||||
agentRewards := model.AgentRewards{
|
||||
AgentId: ancestorId,
|
||||
Amount: reportCommissionAmount,
|
||||
RelationAgentId: lzUtils.Int64ToNullInt64(descendantId),
|
||||
Type: model.AgentRewardsTypeDescendantPromotion,
|
||||
}
|
||||
|
||||
_, agentRewardsModelInsetErr := l.AgentRewardsModel.Insert(ctx, session, &agentRewards)
|
||||
if agentRewardsModelInsetErr != nil {
|
||||
return 0, agentRewardsModelInsetErr
|
||||
}
|
||||
return reportCommissionAmount, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// PlatformCost 平台底价成本
|
||||
func (l *AgentService) PlatformCost(ctx context.Context, agentID int64, agentProductConfigModel *model.AgentProductConfig, session sqlx.Session) (float64, error) {
|
||||
|
||||
costAgentPlatformDeductionModel := model.AgentPlatformDeduction{
|
||||
AgentId: agentID,
|
||||
Amount: agentProductConfigModel.CostPrice,
|
||||
Type: model.AgentDeductionTypeCost,
|
||||
}
|
||||
|
||||
_, err := l.AgentPlatformDeductionModel.Insert(ctx, session, &costAgentPlatformDeductionModel)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return agentProductConfigModel.CostPrice, nil
|
||||
}
|
||||
|
||||
// PlatformPricing 平台提价成本
|
||||
func (l *AgentService) PlatformPricing(ctx context.Context, agentID int64, pricing float64, agentProductConfigModel *model.AgentProductConfig, session sqlx.Session) (float64, error) {
|
||||
// 2. 计算平台提价成本
|
||||
if pricing > agentProductConfigModel.PricingStandard {
|
||||
// 超出部分
|
||||
overpricing := pricing - agentProductConfigModel.PricingStandard
|
||||
|
||||
// 收取成本
|
||||
overpricingCost := overpricing * agentProductConfigModel.OverpricingRatio
|
||||
|
||||
pricingAgentPlatformDeductionModel := model.AgentPlatformDeduction{
|
||||
AgentId: agentID,
|
||||
Amount: overpricingCost,
|
||||
Type: model.AgentDeductionTypePricing,
|
||||
}
|
||||
|
||||
_, err := l.AgentPlatformDeductionModel.Insert(ctx, session, &pricingAgentPlatformDeductionModel)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return overpricingCost, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// CommissionCost 上级底价成本
|
||||
func (l *AgentService) CommissionCost(ctx context.Context, descendantId int64, AncestorId int64, agentMembershipConfigModel *model.AgentMembershipConfig, productID int64, session sqlx.Session) (float64, error) {
|
||||
if agentMembershipConfigModel.PriceIncreaseAmount.Valid {
|
||||
// 拥有则查看该上级设定的成本
|
||||
agentMembershipUserConfigModel, findAgentMembershipUserConfigModelErr := l.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(ctx, AncestorId, productID)
|
||||
if findAgentMembershipUserConfigModelErr != nil {
|
||||
return 0, findAgentMembershipUserConfigModelErr
|
||||
}
|
||||
|
||||
deductCostAmount := agentMembershipUserConfigModel.PriceIncreaseAmount
|
||||
|
||||
agentCommissionDeductionModel := model.AgentCommissionDeduction{
|
||||
AgentId: AncestorId,
|
||||
DeductedAgentId: descendantId,
|
||||
Amount: deductCostAmount,
|
||||
Type: model.AgentDeductionTypeCost,
|
||||
ProductId: productID,
|
||||
}
|
||||
|
||||
_, insertAgentCommissionDeductionModelErr := l.AgentCommissionDeductionModel.Insert(ctx, session, &agentCommissionDeductionModel)
|
||||
if insertAgentCommissionDeductionModelErr != nil {
|
||||
return 0, insertAgentCommissionDeductionModelErr
|
||||
}
|
||||
|
||||
return deductCostAmount, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// CommissionPricing 上级提价成本
|
||||
func (l *AgentService) CommissionPricing(ctx context.Context, descendantId int64, AncestorId int64, agentMembershipConfigModel *model.AgentMembershipConfig, productID int64, pricing float64, session sqlx.Session) (float64, error) {
|
||||
//看上级代理等级否有拥有定价标准收益功能
|
||||
if agentMembershipConfigModel.PriceIncreaseMax.Valid && agentMembershipConfigModel.PriceRatio.Valid {
|
||||
// 拥有则查看该上级设定的成本
|
||||
agentMembershipUserConfigModel, findAgentMembershipUserConfigModelErr := l.AgentMembershipUserConfigModel.FindOneByAgentIdProductId(ctx, AncestorId, productID)
|
||||
if findAgentMembershipUserConfigModelErr != nil {
|
||||
return 0, findAgentMembershipUserConfigModelErr
|
||||
}
|
||||
|
||||
// 计算是否在范围内
|
||||
var pricingRange float64
|
||||
if pricing > agentMembershipUserConfigModel.PriceRangeFrom {
|
||||
if pricing > agentMembershipUserConfigModel.PriceRangeTo {
|
||||
pricingRange = agentMembershipUserConfigModel.PriceRangeTo - agentMembershipUserConfigModel.PriceRangeFrom
|
||||
} else {
|
||||
pricingRange = pricing - agentMembershipUserConfigModel.PriceRangeFrom
|
||||
}
|
||||
}
|
||||
|
||||
deductCostAmount := pricingRange * agentMembershipUserConfigModel.PriceRatio
|
||||
|
||||
agentCommissionDeductionModel := model.AgentCommissionDeduction{
|
||||
AgentId: AncestorId,
|
||||
DeductedAgentId: descendantId,
|
||||
Amount: deductCostAmount,
|
||||
Type: model.AgentDeductionTypePricing,
|
||||
ProductId: productID,
|
||||
}
|
||||
_, insertAgentCommissionDeductionModelErr := l.AgentCommissionDeductionModel.Insert(ctx, session, &agentCommissionDeductionModel)
|
||||
if insertAgentCommissionDeductionModelErr != nil {
|
||||
return 0, insertAgentCommissionDeductionModelErr
|
||||
}
|
||||
return deductCostAmount, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
//func (l *AgentService) UpgradeVip(ctx context.Context, agentID int64, leve string, session sqlx.Session) error {
|
||||
// agentModel, err := l.AgentModel.FindOne(ctx, agentID)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if agentModel.LevelName != model.AgentLeveNameNormal {
|
||||
// return fmt.Errorf("已经是会员")
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
@@ -24,11 +24,23 @@ func NewAliPayService(c config.Config) *AliPayService {
|
||||
panic(fmt.Sprintf("创建支付宝客户端失败: %v", err))
|
||||
}
|
||||
|
||||
// 加载支付宝公钥
|
||||
err = client.LoadAliPayPublicKey(c.Alipay.AlipayPublicKey)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("加载支付宝公钥失败: %v", err))
|
||||
//// 加载支付宝公钥
|
||||
//err = client.LoadAliPayPublicKey(c.Alipay.AlipayPublicKey)
|
||||
//if err != nil {
|
||||
// panic(fmt.Sprintf("加载支付宝公钥失败: %v", err))
|
||||
//}
|
||||
|
||||
// 加载证书
|
||||
if err = client.LoadAppCertPublicKeyFromFile(c.Alipay.AppCertPath); err != nil {
|
||||
panic(fmt.Sprintf("加载应用公钥证书失败: %v", err))
|
||||
}
|
||||
if err = client.LoadAlipayCertPublicKeyFromFile(c.Alipay.AlipayCertPath); err != nil {
|
||||
panic(fmt.Sprintf("加载支付宝公钥证书失败: %v", err))
|
||||
}
|
||||
if err = client.LoadAliPayRootCertFromFile(c.Alipay.AlipayRootCertPath); err != nil {
|
||||
panic(fmt.Sprintf("加载根证书失败: %v", err))
|
||||
}
|
||||
|
||||
return &AliPayService{
|
||||
config: c.Alipay,
|
||||
AlipayClient: client,
|
||||
@@ -186,3 +198,62 @@ func (a *AliPayService) GenerateOutTradeNo() string {
|
||||
|
||||
return combined
|
||||
}
|
||||
|
||||
// AliTransfer 支付宝单笔转账到支付宝账户(提现功能)
|
||||
func (a *AliPayService) AliTransfer(
|
||||
ctx context.Context,
|
||||
payeeAccount string, // 收款方支付宝账户
|
||||
payeeName string, // 收款方姓名
|
||||
amount float64, // 转账金额
|
||||
remark string, // 转账备注
|
||||
outBizNo string, // 商户转账唯一订单号(可使用GenerateOutTradeNo生成)
|
||||
) (*alipay.FundTransUniTransferRsp, error) {
|
||||
// 参数校验
|
||||
if payeeAccount == "" {
|
||||
return nil, fmt.Errorf("收款账户不能为空")
|
||||
}
|
||||
if amount <= 0 {
|
||||
return nil, fmt.Errorf("转账金额必须大于0")
|
||||
}
|
||||
|
||||
// 构造转账请求
|
||||
req := alipay.FundTransUniTransfer{
|
||||
OutBizNo: outBizNo,
|
||||
TransAmount: lzUtils.ToAlipayAmount(amount), // 金额格式转换
|
||||
ProductCode: "TRANS_ACCOUNT_NO_PWD", // 单笔无密转账到支付宝账户
|
||||
BizScene: "DIRECT_TRANSFER", // 单笔转账
|
||||
OrderTitle: "账户提现", // 转账标题
|
||||
Remark: remark,
|
||||
PayeeInfo: &alipay.PayeeInfo{
|
||||
Identity: payeeAccount,
|
||||
IdentityType: "ALIPAY_LOGON_ID", // 根据账户类型选择:
|
||||
Name: payeeName,
|
||||
// ALIPAY_USER_ID/ALIPAY_LOGON_ID
|
||||
},
|
||||
}
|
||||
|
||||
// 执行转账请求
|
||||
transferRsp, err := a.AlipayClient.FundTransUniTransfer(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("支付宝转账请求失败: %v", err)
|
||||
}
|
||||
|
||||
return transferRsp, nil
|
||||
}
|
||||
func (a *AliPayService) QueryTransferStatus(
|
||||
ctx context.Context,
|
||||
outBizNo string,
|
||||
) (*alipay.FundTransOrderQueryRsp, error) {
|
||||
req := alipay.FundTransOrderQuery{
|
||||
OutBizNo: outBizNo,
|
||||
}
|
||||
response, err := a.AlipayClient.FundTransOrderQuery(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("支付宝接口调用失败: %v", err)
|
||||
}
|
||||
// 处理响应
|
||||
if response.Code.IsFailure() {
|
||||
return nil, fmt.Errorf("支付宝返回错误: %s-%s", response.Code, response.Msg)
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]b
|
||||
|
||||
combinedResponse, err := json.Marshal(responseData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("响应数据转 JSON 失败: %+v", err)
|
||||
return nil, fmt.Errorf("响应数据转 JSON 失败: %v", err)
|
||||
}
|
||||
|
||||
return combinedResponse, nil
|
||||
@@ -670,14 +670,14 @@ func (a *ApiRequestService) ProcessKZEYSRequest(params []byte) ([]byte, error) {
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, requestUrl, strings.NewReader(data.Encode()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("KZEYS 创建请求失败: %+v", err)
|
||||
return nil, fmt.Errorf("KZEYS 创建请求失败: %v", err)
|
||||
}
|
||||
req.Header.Set("Authorization", "APPCODE "+appCode)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("KZEYS 请求失败: %+v", err)
|
||||
return nil, fmt.Errorf("KZEYS 请求失败: %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
@@ -725,7 +725,7 @@ func (a *ApiRequestService) ProcessP_C_B332Request(params []byte) ([]byte, error
|
||||
}
|
||||
resp, err := a.yushanService.request("P_C_B332", request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("人车核验查询失败: %+v", err)
|
||||
return nil, fmt.Errorf("人车核验查询失败: %v", err)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -748,7 +748,7 @@ func (a *ApiRequestService) ProcessFIN019Request(params []byte) ([]byte, error)
|
||||
}
|
||||
resp, err := a.yushanService.request("FIN019", request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("银行卡黑名单查询失败: %+v", err)
|
||||
return nil, fmt.Errorf("银行卡黑名单查询失败: %v", err)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -765,7 +765,7 @@ func (a *ApiRequestService) ProcessCAR061Request(params []byte) ([]byte, error)
|
||||
}
|
||||
resp, err := a.yushanService.request("CAR061", request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("名下车辆查询失败: %+v", err)
|
||||
return nil, fmt.Errorf("名下车辆查询失败: %v", err)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -77,14 +77,14 @@ func (r *VerificationService) TwoFactorVerification(request TwoFactorVerificatio
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, requestUrl, strings.NewReader(data.Encode()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建请求失败: %+v", err)
|
||||
return nil, fmt.Errorf("创建请求失败: %v", err)
|
||||
}
|
||||
req.Header.Set("Authorization", "APPCODE "+appCode)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求失败: %+v", err)
|
||||
return nil, fmt.Errorf("请求失败: %v", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
@@ -13,35 +13,54 @@ import (
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
Redis *redis.Redis
|
||||
SourceInterceptor rest.Middleware
|
||||
UserModel model.UserModel
|
||||
UserAuthModel model.UserAuthModel
|
||||
ProductModel model.ProductModel
|
||||
FeatureModel model.FeatureModel
|
||||
ProductFeatureModel model.ProductFeatureModel
|
||||
OrderModel model.OrderModel
|
||||
QueryModel model.QueryModel
|
||||
GlobalNotificationsModel model.GlobalNotificationsModel
|
||||
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
|
||||
Config config.Config
|
||||
Redis *redis.Redis
|
||||
SourceInterceptor rest.Middleware
|
||||
UserModel model.UserModel
|
||||
UserAuthModel model.UserAuthModel
|
||||
ProductModel model.ProductModel
|
||||
FeatureModel model.FeatureModel
|
||||
ProductFeatureModel model.ProductFeatureModel
|
||||
OrderModel model.OrderModel
|
||||
QueryModel model.QueryModel
|
||||
AgentModel model.AgentModel
|
||||
AgentAuditModel model.AgentAuditModel
|
||||
AgentClosureModel model.AgentClosureModel
|
||||
AgentCommissionModel model.AgentCommissionModel
|
||||
AgentCommissionDeductionModel model.AgentCommissionDeductionModel
|
||||
AgentWalletModel model.AgentWalletModel
|
||||
AgentLinkModel model.AgentLinkModel
|
||||
AgentOrderModel model.AgentOrderModel
|
||||
AgentRewardsModel model.AgentRewardsModel
|
||||
AgentMembershipConfigModel model.AgentMembershipConfigModel
|
||||
AgentMembershipRechargeOrderModel model.AgentMembershipRechargeOrderModel
|
||||
AgentMembershipUserConfigModel model.AgentMembershipUserConfigModel
|
||||
AgentProductConfigModel model.AgentProductConfigModel
|
||||
AgentPlatformDeductionModel model.AgentPlatformDeductionModel
|
||||
AgentActiveStatModel model.AgentActiveStatModel
|
||||
AgentWithdrawalModel model.AgentWithdrawalModel
|
||||
GlobalNotificationsModel model.GlobalNotificationsModel
|
||||
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
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
db := sqlx.NewMysql(c.DataSource)
|
||||
|
||||
redisConf := redis.RedisConf{
|
||||
Host: c.CacheRedis[0].Host,
|
||||
Pass: c.CacheRedis[0].Pass,
|
||||
Type: c.CacheRedis[0].Type,
|
||||
}
|
||||
|
||||
asynqServer := asynq.NewServer(
|
||||
asynq.RedisClientOpt{Addr: c.CacheRedis[0].Host, Password: c.CacheRedis[0].Pass},
|
||||
asynq.Config{
|
||||
@@ -52,34 +71,87 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
Concurrency: 10,
|
||||
},
|
||||
)
|
||||
|
||||
westDexService := service.NewWestDexService(c)
|
||||
yushanService := service.NewYushanService(c)
|
||||
productFeatureModel := model.NewProductFeatureModel(db, c.CacheRedis)
|
||||
featureModel := model.NewFeatureModel(db, c.CacheRedis)
|
||||
userAuthModel := model.NewUserAuthModel(db, c.CacheRedis)
|
||||
|
||||
userModel := model.NewUserModel(db, c.CacheRedis)
|
||||
productModel := model.NewProductModel(db, c.CacheRedis)
|
||||
orderModel := model.NewOrderModel(db, c.CacheRedis)
|
||||
queryModel := model.NewQueryModel(db, c.CacheRedis)
|
||||
globalNotificationsModel := model.NewGlobalNotificationsModel(db, c.CacheRedis)
|
||||
|
||||
agentModel := model.NewAgentModel(db, c.CacheRedis)
|
||||
agentAuditModel := model.NewAgentAuditModel(db, c.CacheRedis)
|
||||
agentCommissionModel := model.NewAgentCommissionModel(db, c.CacheRedis)
|
||||
agentCommissionDeductionModel := model.NewAgentCommissionDeductionModel(db, c.CacheRedis)
|
||||
agentWalletModel := model.NewAgentWalletModel(db, c.CacheRedis)
|
||||
agentClosureModel := model.NewAgentClosureModel(db, c.CacheRedis)
|
||||
agentLinkModel := model.NewAgentLinkModel(db, c.CacheRedis)
|
||||
agentOrderModel := model.NewAgentOrderModel(db, c.CacheRedis)
|
||||
agentRewardsModel := model.NewAgentRewardsModel(db, c.CacheRedis)
|
||||
agentMembershipConfigModel := model.NewAgentMembershipConfigModel(db, c.CacheRedis)
|
||||
agentMembershipRechargeOrderModel := model.NewAgentMembershipRechargeOrderModel(db, c.CacheRedis)
|
||||
agentMembershipUserConfigModel := model.NewAgentMembershipUserConfigModel(db, c.CacheRedis)
|
||||
agentProductConfigModel := model.NewAgentProductConfigModel(db, c.CacheRedis)
|
||||
agentPlatformDeductionModel := model.NewAgentPlatformDeductionModel(db, c.CacheRedis)
|
||||
agentActiveStatModel := model.NewAgentActiveStatModel(db, c.CacheRedis)
|
||||
agentWithdrawalModel := model.NewAgentWithdrawalModel(db, c.CacheRedis)
|
||||
|
||||
alipayService := service.NewAliPayService(c)
|
||||
wechatPayService := service.NewWechatPayService(c, userAuthModel)
|
||||
applePayService := service.NewApplePayService(c)
|
||||
verificationService := service.NewVerificationService(c, westDexService)
|
||||
apiRequestService := service.NewApiRequestService(c, westDexService, yushanService, featureModel, productFeatureModel)
|
||||
asynqService := service.NewAsynqService(c)
|
||||
agentService := service.NewAgentService(c, agentModel, agentAuditModel, agentClosureModel, agentCommissionModel,
|
||||
agentCommissionDeductionModel, agentWalletModel, agentLinkModel, agentOrderModel, agentRewardsModel,
|
||||
agentMembershipConfigModel, agentMembershipRechargeOrderModel, agentMembershipUserConfigModel,
|
||||
agentProductConfigModel, agentPlatformDeductionModel, agentActiveStatModel, agentWithdrawalModel)
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
Redis: redis.MustNewRedis(redisConf),
|
||||
SourceInterceptor: middleware.NewSourceInterceptorMiddleware().Handle,
|
||||
AlipayService: service.NewAliPayService(c),
|
||||
WechatPayService: service.NewWechatPayService(c, userAuthModel),
|
||||
ApplePayService: service.NewApplePayService(c),
|
||||
WestDexService: westDexService,
|
||||
YushanService: yushanService,
|
||||
VerificationService: service.NewVerificationService(c, westDexService),
|
||||
AsynqServer: asynqServer,
|
||||
ApiRequestService: service.NewApiRequestService(c, westDexService, yushanService, featureModel, productFeatureModel),
|
||||
AsynqService: service.NewAsynqService(c),
|
||||
UserModel: model.NewUserModel(db, c.CacheRedis),
|
||||
UserAuthModel: userAuthModel,
|
||||
ProductModel: model.NewProductModel(db, c.CacheRedis),
|
||||
OrderModel: model.NewOrderModel(db, c.CacheRedis),
|
||||
QueryModel: model.NewQueryModel(db, c.CacheRedis),
|
||||
GlobalNotificationsModel: model.NewGlobalNotificationsModel(db, c.CacheRedis),
|
||||
FeatureModel: featureModel,
|
||||
ProductFeatureModel: productFeatureModel,
|
||||
Config: c,
|
||||
Redis: redis.MustNewRedis(redisConf),
|
||||
SourceInterceptor: middleware.NewSourceInterceptorMiddleware().Handle,
|
||||
AlipayService: alipayService,
|
||||
WechatPayService: wechatPayService,
|
||||
ApplePayService: applePayService,
|
||||
WestDexService: westDexService,
|
||||
YushanService: yushanService,
|
||||
VerificationService: verificationService,
|
||||
AsynqServer: asynqServer,
|
||||
ApiRequestService: apiRequestService,
|
||||
AsynqService: asynqService,
|
||||
AgentService: agentService,
|
||||
UserModel: userModel,
|
||||
UserAuthModel: userAuthModel,
|
||||
ProductModel: productModel,
|
||||
OrderModel: orderModel,
|
||||
QueryModel: queryModel,
|
||||
GlobalNotificationsModel: globalNotificationsModel,
|
||||
FeatureModel: featureModel,
|
||||
ProductFeatureModel: productFeatureModel,
|
||||
AgentModel: agentModel,
|
||||
AgentAuditModel: agentAuditModel,
|
||||
AgentCommissionModel: agentCommissionModel,
|
||||
AgentCommissionDeductionModel: agentCommissionDeductionModel,
|
||||
AgentWalletModel: agentWalletModel,
|
||||
AgentClosureModel: agentClosureModel,
|
||||
AgentLinkModel: agentLinkModel,
|
||||
AgentOrderModel: agentOrderModel,
|
||||
AgentRewardsModel: agentRewardsModel,
|
||||
AgentMembershipConfigModel: agentMembershipConfigModel,
|
||||
AgentMembershipRechargeOrderModel: agentMembershipRechargeOrderModel,
|
||||
AgentMembershipUserConfigModel: agentMembershipUserConfigModel,
|
||||
AgentProductConfigModel: agentProductConfigModel,
|
||||
AgentPlatformDeductionModel: agentPlatformDeductionModel,
|
||||
AgentActiveStatModel: agentActiveStatModel,
|
||||
AgentWithdrawalModel: agentWithdrawalModel,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ServiceContext) Close() {
|
||||
if s.AsynqService != nil {
|
||||
s.AsynqService.Close()
|
||||
|
||||
@@ -7,6 +7,7 @@ type QueryCache struct {
|
||||
Product string `json:"product_id"`
|
||||
}
|
||||
type QueryCacheLoad struct {
|
||||
Product string `json:"product_en"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Product string `json:"product_en"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
AgentIdentifier string `json:"agent_dentifier"`
|
||||
}
|
||||
|
||||
@@ -101,3 +101,13 @@ type TocPhoneSecondaryCard struct {
|
||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||
StartDate string `json:"start_date" validate:"required"`
|
||||
}
|
||||
|
||||
type AgentQueryData struct {
|
||||
Mobile string `json:"mobile"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
type AgentIdentifier struct {
|
||||
Product string `json:"product"`
|
||||
AgentID int64 `json:"agent_id"`
|
||||
Price string `json:"price"`
|
||||
}
|
||||
|
||||
@@ -1,12 +1,156 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
type ActiveReward struct {
|
||||
TotalReward float64 `json:"total_reward"`
|
||||
Today ActiveRewardData `json:"today"` // 今日数据
|
||||
Last7D ActiveRewardData `json:"last7d"` // 近7天数据
|
||||
Last30D ActiveRewardData `json:"last30d"` // 近30天数据
|
||||
}
|
||||
|
||||
type ActiveRewardData struct {
|
||||
NewActiveReward float64 `json:"active_reward"`
|
||||
SubPromoteReward float64 `json:"sub_promote_reward"`
|
||||
SubUpgradeReward float64 `json:"sub_upgrade_reward"`
|
||||
SubWithdrawReward float64 `json:"sub_withdraw_reward"`
|
||||
}
|
||||
|
||||
type AgentActivateMembershipReq struct {
|
||||
Mobile string `json:"mobile"`
|
||||
Type string `json:"type,oneof=VIP SVIP"` // 会员类型:vip/svip
|
||||
Amount float64 `json:"amount"`
|
||||
PaymentMethod string `json:"payment_method"`
|
||||
TransactionId string `json:"transaction_id"`
|
||||
}
|
||||
|
||||
type AgentActivateMembershipResp struct {
|
||||
MembershipType string `json:"membership_type"` // 最终开通的会员类型
|
||||
ExpireTime string `json:"expire_time"` // 到期时间
|
||||
}
|
||||
|
||||
type AgentApplyReq struct {
|
||||
Region string `json:"region"`
|
||||
Mobile string `json:"mobile"`
|
||||
WechatID string `json:"wechat_id"`
|
||||
Code string `json:"code"`
|
||||
Ancestor string `json:"ancestor,optional"`
|
||||
}
|
||||
|
||||
type AgentApplyResp struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
AccessExpire int64 `json:"accessExpire"`
|
||||
RefreshAfter int64 `json:"refreshAfter"`
|
||||
}
|
||||
|
||||
type AgentAuditStatusResp struct {
|
||||
Status int64 `json:"status"` // 0=待审核,1=审核通过,2=审核未通过
|
||||
AuditReason string `json:"audit_reason"`
|
||||
}
|
||||
|
||||
type AgentGeneratingLinkReq struct {
|
||||
Product string `json:"product"`
|
||||
Price string `json:"price"`
|
||||
}
|
||||
|
||||
type AgentGeneratingLinkResp struct {
|
||||
LinkIdentifier string `json:"link_identifier"`
|
||||
}
|
||||
|
||||
type AgentInfoResp struct {
|
||||
Status int64 `json:"status"` // 0=待审核,1=审核通过,2=审核未通过,3=未申请
|
||||
IsAgent bool `json:"is_agent"`
|
||||
AgentID int64 `json:"agent_id"`
|
||||
Level string `json:"level"`
|
||||
Region string `json:"region"`
|
||||
Mobile string `json:"mobile"`
|
||||
WechatID string `json:"wechat_id"`
|
||||
}
|
||||
|
||||
type AgentMembershipProductConfigReq struct {
|
||||
ProductID int64 `form:"product_id"`
|
||||
}
|
||||
|
||||
type AgentMembershipProductConfigResp struct {
|
||||
AgentMembershipUserConfig AgentMembershipUserConfig `json:"agent_membership_user_config"`
|
||||
ProductConfig ProductConfig `json:"product_config"`
|
||||
PriceIncreaseMax float64 `json:"price_increase_max"`
|
||||
PriceIncreaseAmount float64 `json:"price_increase_amount"`
|
||||
PriceRatio float64 `json:"price_ratio"`
|
||||
}
|
||||
|
||||
type AgentMembershipUserConfig struct {
|
||||
ProductID int64 `json:"product_id"`
|
||||
PriceIncreaseAmount float64 `json:"price_increase_amount"`
|
||||
PriceRangeFrom float64 `json:"price_range_from"`
|
||||
PriceRangeTo float64 `json:"price_range_to"`
|
||||
PriceRatio float64 `json:"price_ratio"`
|
||||
}
|
||||
|
||||
type AgentProductConfig struct {
|
||||
ProductID int64 `json:"product_id"`
|
||||
CostPrice float64 `json:"cost_price"`
|
||||
PriceRangeMin float64 `json:"price_range_min"`
|
||||
PriceRangeMax float64 `json:"price_range_max"`
|
||||
PPricingStandard float64 `json:"p_pricing_standard"`
|
||||
POverpricingRatio float64 `json:"p_overpricing_ratio"`
|
||||
APricingStandard float64 `json:"a_pricing_standard"`
|
||||
APricingEnd float64 `json:"a_pricing_end"`
|
||||
AOverpricingRatio float64 `json:"a_overpricing_ratio"`
|
||||
}
|
||||
|
||||
type AgentProductConfigResp struct {
|
||||
AgentProductConfig []AgentProductConfig
|
||||
}
|
||||
|
||||
type Commission struct {
|
||||
ProductName string `json:"product_name"`
|
||||
Amount float64 `json:"amount"`
|
||||
CreateTime string `json:"create_time"`
|
||||
}
|
||||
|
||||
type DirectPushReport struct {
|
||||
TotalCommission float64 `json:"total_commission"`
|
||||
TotalReport int `json:"total_report"`
|
||||
Today TimeRangeReport `json:"today"` // 近24小时数据
|
||||
Last7D TimeRangeReport `json:"last7d"` // 近7天数据
|
||||
Last30D TimeRangeReport `json:"last30d"` // 近30天数据
|
||||
}
|
||||
|
||||
type Feature struct {
|
||||
ID int64 `json:"id"` // 功能ID
|
||||
ApiID string `json:"api_id"` // API标识
|
||||
Name string `json:"name"` // 功能描述
|
||||
}
|
||||
|
||||
type GetAgentRevenueInfoReq struct {
|
||||
}
|
||||
|
||||
type GetAgentRevenueInfoResp struct {
|
||||
Balance float64 `json:"balance"`
|
||||
FrozenBalance float64 `json:"frozen_balance"`
|
||||
TotalEarnings float64 `json:"total_earnings"`
|
||||
DirectPush DirectPushReport `json:"direct_push"` // 直推报告数据
|
||||
ActiveReward ActiveReward `json:"active_reward"` // 活跃下级奖励数据
|
||||
}
|
||||
|
||||
type GetCommissionReq struct {
|
||||
Page int64 `form:"page"` // 页码
|
||||
PageSize int64 `form:"page_size"` // 每页数据量
|
||||
}
|
||||
|
||||
type GetCommissionResp struct {
|
||||
Total int64 `json:"total"` // 总记录数
|
||||
List []Commission `json:"list"` // 查询列表
|
||||
}
|
||||
|
||||
type GetLinkDataReq struct {
|
||||
LinkIdentifier string `form:"link_identifier"`
|
||||
}
|
||||
|
||||
type GetLinkDataResp struct {
|
||||
Product
|
||||
}
|
||||
|
||||
type GetNotificationsResp struct {
|
||||
Notifications []Notification `json:"notifications"` // 通知列表
|
||||
Total int64 `json:"total"` // 总记录数
|
||||
@@ -20,6 +164,26 @@ type GetProductByIDRequest struct {
|
||||
Id int64 `path:"id"`
|
||||
}
|
||||
|
||||
type GetRewardsReq struct {
|
||||
Page int64 `form:"page"` // 页码
|
||||
PageSize int64 `form:"page_size"` // 每页数据量
|
||||
}
|
||||
|
||||
type GetRewardsResp struct {
|
||||
Total int64 `json:"total"` // 总记录数
|
||||
List []Rewards `json:"list"` // 查询列表
|
||||
}
|
||||
|
||||
type GetWithdrawalReq struct {
|
||||
Page int64 `form:"page"` // 页码
|
||||
PageSize int64 `form:"page_size"` // 每页数据量
|
||||
}
|
||||
|
||||
type GetWithdrawalResp struct {
|
||||
Total int64 `json:"total"` // 总记录数
|
||||
List []Withdrawal `json:"list"` // 查询列表
|
||||
}
|
||||
|
||||
type IapCallbackReq struct {
|
||||
OrderID int64 `json:"order_id" validate:"required"`
|
||||
TransactionReceipt string `json:"transaction_receipt" validate:"required"`
|
||||
@@ -77,6 +241,13 @@ type Product struct {
|
||||
Features []Feature `json:"features"` // 关联功能列表
|
||||
}
|
||||
|
||||
type ProductConfig struct {
|
||||
ProductID int64 `json:"product_id"`
|
||||
CostPrice float64 `json:"cost_price"`
|
||||
PriceRangeMin float64 `json:"price_range_min"`
|
||||
PriceRangeMax float64 `json:"price_range_max"`
|
||||
}
|
||||
|
||||
type ProductResponse struct {
|
||||
Product
|
||||
}
|
||||
@@ -167,12 +338,16 @@ type QueryRetryResp struct {
|
||||
}
|
||||
|
||||
type QueryServiceReq struct {
|
||||
Product string `path:"product"`
|
||||
Data string `json:"data" validate:"required"`
|
||||
Product string `path:"product"`
|
||||
Data string `json:"data" validate:"required"`
|
||||
AgentIdentifier string `json:"agent_identifier,optional"`
|
||||
}
|
||||
|
||||
type QueryServiceResp struct {
|
||||
Id string `json:"id"`
|
||||
Id string `json:"id"`
|
||||
AccessToken string `json:"accessToken"`
|
||||
AccessExpire int64 `json:"accessExpire"`
|
||||
RefreshAfter int64 `json:"refreshAfter"`
|
||||
}
|
||||
|
||||
type RegisterReq struct {
|
||||
@@ -187,6 +362,25 @@ type RegisterResp struct {
|
||||
RefreshAfter int64 `json:"refreshAfter"`
|
||||
}
|
||||
|
||||
type Rewards struct {
|
||||
Type string `json:"type"`
|
||||
Amount float64 `json:"amount"`
|
||||
CreateTime string `json:"create_time"`
|
||||
}
|
||||
|
||||
type SaveAgentMembershipUserConfigReq struct {
|
||||
ProductID int64 `json:"product_id"`
|
||||
PriceIncreaseAmount float64 `json:"price_increase_amount"`
|
||||
PriceRangeFrom float64 `json:"price_range_from"`
|
||||
PriceRangeTo float64 `json:"price_range_to"`
|
||||
PriceRatio float64 `json:"price_ratio"`
|
||||
}
|
||||
|
||||
type TimeRangeReport struct {
|
||||
Commission float64 `json:"commission"` // 佣金
|
||||
Report int `json:"report"` // 报告量
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Id int64 `json:"id"`
|
||||
Mobile string `json:"mobile"`
|
||||
@@ -219,7 +413,27 @@ type WXMiniAuthResp struct {
|
||||
RefreshAfter int64 `json:"refreshAfter"`
|
||||
}
|
||||
|
||||
type Withdrawal struct {
|
||||
Status int64 `json:"status"`
|
||||
Amount float64 `json:"amount"`
|
||||
WithdrawalNo string `json:"withdrawal_no"`
|
||||
Remark string `json:"remark"`
|
||||
PayeeAccount string `json:"payee_account"`
|
||||
CreateTime string `json:"create_time"`
|
||||
}
|
||||
|
||||
type WithdrawalReq struct {
|
||||
Amount float64 `json:"amount"` // 提现金额
|
||||
PayeeAccount string `json:"payee_account"`
|
||||
PayeeName string `json:"payee_name"`
|
||||
}
|
||||
|
||||
type WithdrawalResp struct {
|
||||
Status int64 `json:"status"` // 1申请中 2成功 3失败
|
||||
FailMsg string `json:"fail_msg"`
|
||||
}
|
||||
|
||||
type SendSmsReq struct {
|
||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||
ActionType string `json:"actionType" validate:"required,oneof=login register query"`
|
||||
ActionType string `json:"actionType" validate:"required,oneof=login register query agentApply"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user