f
This commit is contained in:
@@ -44,11 +44,13 @@ service main {
|
||||
type (
|
||||
// 列表请求
|
||||
AdminGetUserListReq {
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
Username string `form:"username,optional"` // 用户名
|
||||
RealName string `form:"real_name,optional"` // 真实姓名
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
Username string `form:"username,optional"` // 用户名
|
||||
RealName string `form:"real_name,optional"` // 真实姓名
|
||||
StartTime string `form:"startTime,optional"` // 创建时间开始(yyyy-MM-dd HH:mm:ss)
|
||||
EndTime string `form:"endTime,optional"` // 创建时间结束(yyyy-MM-dd HH:mm:ss)
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
}
|
||||
|
||||
// 列表响应
|
||||
|
||||
@@ -36,11 +36,16 @@ service main {
|
||||
type (
|
||||
// 列表请求
|
||||
GetRoleListReq {
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
Name string `form:"name,optional"` // 角色名称
|
||||
Code string `form:"code,optional"` // 角色编码
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
RoleName string `form:"role_name,optional"` // 角色名称(前端字段)
|
||||
Name string `form:"name,optional"` // 角色名称(兼容字段)
|
||||
RoleCode string `form:"role_code,optional"` // 角色编码(前端字段)
|
||||
Code string `form:"code,optional"` // 角色编码(兼容字段)
|
||||
Description string `form:"description,optional"` // 角色描述
|
||||
StartTime string `form:"startTime,optional"` // 创建时间开始(yyyy-MM-dd HH:mm:ss)
|
||||
EndTime string `form:"endTime,optional"` // 创建时间结束(yyyy-MM-dd HH:mm:ss)
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
}
|
||||
|
||||
// 列表响应
|
||||
|
||||
@@ -54,6 +54,8 @@ type (
|
||||
// 代理服务基本类型定义
|
||||
type AgentProductConfig {
|
||||
ProductID int64 `json:"product_id"`
|
||||
ProductName string `json:"product_name"`
|
||||
ProductEn string `json:"product_en"`
|
||||
CostPrice float64 `json:"cost_price"`
|
||||
PriceRangeMin float64 `json:"price_range_min"`
|
||||
PriceRangeMax float64 `json:"price_range_max"`
|
||||
|
||||
@@ -141,9 +141,9 @@ service main {
|
||||
|
||||
type (
|
||||
sendSmsReq {
|
||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||
CaptchaVerifyParam string `json:"captchaVerifyParam"`
|
||||
ActionType string `json:"actionType,optional" validate:"oneof=login register query agentApply realName bindMobile"`
|
||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||
CaptchaVerifyParam string `json:"captchaVerifyParam,optional,omitempty"`
|
||||
ActionType string `json:"actionType,optional" validate:"oneof=login register query agentApply realName bindMobile"`
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -68,8 +68,6 @@ WechatH5:
|
||||
WechatMini:
|
||||
AppID: "xxxx" # 小程序的AppID
|
||||
AppSecret: "xxxx" # 小程序的AppSecret
|
||||
TycAppID: "xxxx"
|
||||
TycAppSecret: "xxxx"
|
||||
Query:
|
||||
ShareLinkExpire: 604800 # 7天 = 7 * 24 * 60 * 60 = 604800秒
|
||||
AdminConfig:
|
||||
|
||||
@@ -2,6 +2,7 @@ package admin_notification
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bdrp-server/app/main/api/internal/svc"
|
||||
@@ -32,7 +33,10 @@ func (l *AdminGetNotificationListLogic) AdminGetNotificationList(req *types.Admi
|
||||
builder = builder.Where("title LIKE ?", "%"+*req.Title+"%")
|
||||
}
|
||||
if req.NotificationPage != nil {
|
||||
builder = builder.Where("notification_page = ?", *req.NotificationPage)
|
||||
s := strings.TrimSpace(*req.NotificationPage)
|
||||
if s != "" {
|
||||
builder = builder.Where("notification_page LIKE ?", "%"+s+"%")
|
||||
}
|
||||
}
|
||||
if req.Status != nil {
|
||||
builder = builder.Where("status = ?", *req.Status)
|
||||
|
||||
@@ -3,6 +3,7 @@ package admin_notification
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bdrp-server/app/main/api/internal/svc"
|
||||
@@ -32,13 +33,30 @@ func (l *AdminUpdateNotificationLogic) AdminUpdateNotification(req *types.AdminU
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查找通知失败, err: %v, id: %d", err, req.Id)
|
||||
}
|
||||
// 空字符串表示「无日期」(如每天展示),须写 NULL;不能写零时间,否则 MySQL 会报 Incorrect date value
|
||||
if req.StartDate != nil {
|
||||
startDate, _ := time.Parse("2006-01-02", *req.StartDate)
|
||||
notification.StartDate = sql.NullTime{Time: startDate, Valid: true}
|
||||
s := strings.TrimSpace(*req.StartDate)
|
||||
if s == "" {
|
||||
notification.StartDate = sql.NullTime{Valid: false}
|
||||
} else {
|
||||
startDate, err := time.Parse("2006-01-02", s)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.REUQEST_PARAM_ERROR), "start_date 格式错误: %v", err)
|
||||
}
|
||||
notification.StartDate = sql.NullTime{Time: startDate, Valid: true}
|
||||
}
|
||||
}
|
||||
if req.EndDate != nil {
|
||||
endDate, _ := time.Parse("2006-01-02", *req.EndDate)
|
||||
notification.EndDate = sql.NullTime{Time: endDate, Valid: true}
|
||||
s := strings.TrimSpace(*req.EndDate)
|
||||
if s == "" {
|
||||
notification.EndDate = sql.NullTime{Valid: false}
|
||||
} else {
|
||||
endDate, err := time.Parse("2006-01-02", s)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.REUQEST_PARAM_ERROR), "end_date 格式错误: %v", err)
|
||||
}
|
||||
notification.EndDate = sql.NullTime{Time: endDate, Valid: true}
|
||||
}
|
||||
}
|
||||
if req.Title != nil {
|
||||
notification.Title = *req.Title
|
||||
|
||||
@@ -2,12 +2,15 @@ package admin_role
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"bdrp-server/app/main/api/internal/svc"
|
||||
"bdrp-server/app/main/api/internal/types"
|
||||
"bdrp-server/app/main/model"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/samber/lo"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/mr"
|
||||
@@ -34,15 +37,7 @@ func (l *GetRoleListLogic) GetRoleList(req *types.GetRoleListReq) (resp *types.G
|
||||
|
||||
// 构建查询条件
|
||||
builder := l.svcCtx.AdminRoleModel.SelectBuilder()
|
||||
if len(req.Name) > 0 {
|
||||
builder = builder.Where("role_name LIKE ?", "%"+req.Name+"%")
|
||||
}
|
||||
if len(req.Code) > 0 {
|
||||
builder = builder.Where("role_code LIKE ?", "%"+req.Code+"%")
|
||||
}
|
||||
if req.Status != -1 {
|
||||
builder = builder.Where("status = ?", req.Status)
|
||||
}
|
||||
builder = applyRoleListFilters(builder, req)
|
||||
|
||||
// 设置分页
|
||||
offset := (req.Page - 1) * req.PageSize
|
||||
@@ -73,15 +68,7 @@ func (l *GetRoleListLogic) GetRoleList(req *types.GetRoleListReq) (resp *types.G
|
||||
mutex.Unlock()
|
||||
} else if taskType == 2 {
|
||||
countBuilder := l.svcCtx.AdminRoleModel.SelectBuilder()
|
||||
if len(req.Name) > 0 {
|
||||
countBuilder = countBuilder.Where("role_name LIKE ?", "%"+req.Name+"%")
|
||||
}
|
||||
if len(req.Code) > 0 {
|
||||
countBuilder = countBuilder.Where("role_code LIKE ?", "%"+req.Code+"%")
|
||||
}
|
||||
if req.Status != -1 {
|
||||
countBuilder = countBuilder.Where("status = ?", req.Status)
|
||||
}
|
||||
countBuilder = applyRoleListFilters(countBuilder, req)
|
||||
|
||||
count, err := l.svcCtx.AdminRoleModel.FindCount(l.ctx, countBuilder, "id")
|
||||
if err != nil {
|
||||
@@ -146,3 +133,56 @@ func (l *GetRoleListLogic) GetRoleList(req *types.GetRoleListReq) (resp *types.G
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func applyRoleListFilters(builder squirrel.SelectBuilder, req *types.GetRoleListReq) squirrel.SelectBuilder {
|
||||
roleName := strings.TrimSpace(req.RoleName)
|
||||
if roleName == "" {
|
||||
roleName = strings.TrimSpace(req.Name)
|
||||
}
|
||||
if roleName != "" {
|
||||
builder = builder.Where("role_name LIKE ?", "%"+roleName+"%")
|
||||
}
|
||||
|
||||
roleCode := strings.TrimSpace(req.RoleCode)
|
||||
if roleCode == "" {
|
||||
roleCode = strings.TrimSpace(req.Code)
|
||||
}
|
||||
if roleCode != "" {
|
||||
builder = builder.Where("role_code LIKE ?", "%"+roleCode+"%")
|
||||
}
|
||||
|
||||
description := strings.TrimSpace(req.Description)
|
||||
if description != "" {
|
||||
builder = builder.Where("description LIKE ?", "%"+description+"%")
|
||||
}
|
||||
|
||||
if req.Status != -1 {
|
||||
builder = builder.Where("status = ?", req.Status)
|
||||
}
|
||||
|
||||
if startTime, ok := parseRoleListTime(req.StartTime, false); ok {
|
||||
builder = builder.Where("create_time >= ?", startTime)
|
||||
}
|
||||
if endTime, ok := parseRoleListTime(req.EndTime, true); ok {
|
||||
builder = builder.Where("create_time <= ?", endTime)
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
func parseRoleListTime(raw string, isEnd bool) (time.Time, bool) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
for _, layout := range []string{"2006-01-02 15:04:05", "2006-01-02", time.RFC3339} {
|
||||
if t, err := time.Parse(layout, raw); err == nil {
|
||||
if layout == "2006-01-02" && isEnd {
|
||||
t = t.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
|
||||
}
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package admin_user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"bdrp-server/app/main/api/internal/svc"
|
||||
"bdrp-server/app/main/api/internal/types"
|
||||
"bdrp-server/app/main/model"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/samber/lo"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/mr"
|
||||
@@ -36,15 +39,7 @@ func (l *AdminGetUserListLogic) AdminGetUserList(req *types.AdminGetUserListReq)
|
||||
// 构建查询条件
|
||||
builder := l.svcCtx.AdminUserModel.SelectBuilder().
|
||||
Where("del_state = ?", 0)
|
||||
if len(req.Username) > 0 {
|
||||
builder = builder.Where("username LIKE ?", "%"+req.Username+"%")
|
||||
}
|
||||
if len(req.RealName) > 0 {
|
||||
builder = builder.Where("real_name LIKE ?", "%"+req.RealName+"%")
|
||||
}
|
||||
if req.Status != -1 {
|
||||
builder = builder.Where("status = ?", req.Status)
|
||||
}
|
||||
builder = applyAdminUserListFilters(builder, req)
|
||||
|
||||
// 设置分页
|
||||
offset := (req.Page - 1) * req.PageSize
|
||||
@@ -76,15 +71,7 @@ func (l *AdminGetUserListLogic) AdminGetUserList(req *types.AdminGetUserListReq)
|
||||
} else if taskType == 2 {
|
||||
countBuilder := l.svcCtx.AdminUserModel.SelectBuilder().
|
||||
Where("del_state = ?", 0)
|
||||
if len(req.Username) > 0 {
|
||||
countBuilder = countBuilder.Where("username LIKE ?", "%"+req.Username+"%")
|
||||
}
|
||||
if len(req.RealName) > 0 {
|
||||
countBuilder = countBuilder.Where("real_name LIKE ?", "%"+req.RealName+"%")
|
||||
}
|
||||
if req.Status != -1 {
|
||||
countBuilder = countBuilder.Where("status = ?", req.Status)
|
||||
}
|
||||
countBuilder = applyAdminUserListFilters(countBuilder, req)
|
||||
|
||||
count, err := l.svcCtx.AdminUserModel.FindCount(l.ctx, countBuilder, "id")
|
||||
if err != nil {
|
||||
@@ -147,3 +134,38 @@ func (l *AdminGetUserListLogic) AdminGetUserList(req *types.AdminGetUserListReq)
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func applyAdminUserListFilters(builder squirrel.SelectBuilder, req *types.AdminGetUserListReq) squirrel.SelectBuilder {
|
||||
if username := strings.TrimSpace(req.Username); username != "" {
|
||||
builder = builder.Where("username LIKE ?", "%"+username+"%")
|
||||
}
|
||||
if realName := strings.TrimSpace(req.RealName); realName != "" {
|
||||
builder = builder.Where("real_name LIKE ?", "%"+realName+"%")
|
||||
}
|
||||
if req.Status != -1 {
|
||||
builder = builder.Where("status = ?", req.Status)
|
||||
}
|
||||
if startTime, ok := parseAdminUserListTime(req.StartTime, false); ok {
|
||||
builder = builder.Where("create_time >= ?", startTime)
|
||||
}
|
||||
if endTime, ok := parseAdminUserListTime(req.EndTime, true); ok {
|
||||
builder = builder.Where("create_time <= ?", endTime)
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
func parseAdminUserListTime(raw string, isEnd bool) (time.Time, bool) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return time.Time{}, false
|
||||
}
|
||||
for _, layout := range []string{"2006-01-02 15:04:05", "2006-01-02", time.RFC3339} {
|
||||
if t, err := time.Parse(layout, raw); err == nil {
|
||||
if layout == "2006-01-02" && isEnd {
|
||||
t = t.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
|
||||
}
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
@@ -67,6 +67,13 @@ func (l *GetAgentProductConfigLogic) GetAgentProductConfig() (resp *types.AgentP
|
||||
// 将 item 转换为推广项目配置模型
|
||||
config := item.(*model.AgentProductConfig)
|
||||
var agentProductConfig types.AgentProductConfig
|
||||
productModel, findProductErr := l.svcCtx.ProductModel.FindOne(l.ctx, config.ProductId)
|
||||
if findProductErr != nil {
|
||||
cancel(findProductErr)
|
||||
return
|
||||
}
|
||||
agentProductConfig.ProductName = productModel.ProductName
|
||||
agentProductConfig.ProductEn = productModel.ProductEn
|
||||
// 配置平台成本价和定价成本
|
||||
agentProductConfigModel, findAgentProductConfigErr := l.svcCtx.AgentProductConfigModel.FindOneByProductId(l.ctx, config.ProductId)
|
||||
if findAgentProductConfigErr != nil {
|
||||
|
||||
@@ -37,17 +37,16 @@ func NewSendSmsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendSmsLo
|
||||
|
||||
func (l *SendSmsLogic) SendSms(req *types.SendSmsReq) error {
|
||||
cfg := l.svcCtx.Config.Captcha
|
||||
// captcha 开关:关闭后直接跳过图形验证码校验
|
||||
if !cfg.Enable {
|
||||
return nil
|
||||
}
|
||||
if err := captcha.VerifyWithRequest(captcha.Config{
|
||||
AccessKeyID: cfg.AccessKeyID,
|
||||
AccessKeySecret: cfg.AccessKeySecret,
|
||||
EndpointURL: cfg.EndpointURL,
|
||||
SceneID: cfg.SceneID,
|
||||
}, req.CaptchaVerifyParam, l.ctx); err != nil {
|
||||
return err
|
||||
// captcha 开关:仅控制是否做图形校验;关闭时不校验,短信照常发送
|
||||
if cfg.Enable {
|
||||
if err := captcha.VerifyWithRequest(captcha.Config{
|
||||
AccessKeyID: cfg.AccessKeyID,
|
||||
AccessKeySecret: cfg.AccessKeySecret,
|
||||
EndpointURL: cfg.EndpointURL,
|
||||
SceneID: cfg.SceneID,
|
||||
}, req.CaptchaVerifyParam, l.ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 默认action类型:当未传入时,默认为login,便于小程序环境兼容
|
||||
action := req.ActionType
|
||||
|
||||
@@ -2,14 +2,15 @@ package notification
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bdrp-server/common/xerr"
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
"bdrp-server/common/xerr"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"bdrp-server/app/main/api/internal/svc"
|
||||
"bdrp-server/app/main/api/internal/types"
|
||||
"bdrp-server/app/main/model"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -36,22 +37,42 @@ func (l *GetNotificationsLogic) GetNotifications() (resp *types.GetNotifications
|
||||
todayStart := now.Format("2006-01-02") + " 00:00:00"
|
||||
todayEnd := now.Format("2006-01-02") + " 23:59:59"
|
||||
|
||||
// 构建查询条件
|
||||
// 构建查询条件(与后台管理一致:status 1=启用 0=禁用;库中为整型,不能用字符串 "active")
|
||||
builder := l.svcCtx.GlobalNotificationsModel.SelectBuilder().
|
||||
Where("status = ?", "active").
|
||||
Where("status = ?", 1).
|
||||
Where("(start_date IS NULL OR start_date <= ?)", todayEnd). // start_date 是 NULL 或者小于等于今天结束时间
|
||||
Where("(end_date IS NULL OR end_date >= ?)", todayStart) // end_date 是 NULL 或者大于等于今天开始时间
|
||||
Where("(end_date IS NULL OR end_date >= ?)", todayStart) // end_date 是 NULL 或者大于等于今天开始时间
|
||||
|
||||
notificationsModelList, findErr := l.svcCtx.GlobalNotificationsModel.FindAll(l.ctx, builder, "")
|
||||
if findErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "全局通知, 查找通知失败, err:%+v", findErr)
|
||||
}
|
||||
|
||||
var notifications []types.Notification
|
||||
copyErr := copier.Copy(¬ifications, ¬ificationsModelList)
|
||||
if copyErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "全局通知, 复制结构体失败, err:%+v", copyErr)
|
||||
}
|
||||
notifications := toPublicNotifications(notificationsModelList)
|
||||
|
||||
return &types.GetNotificationsResp{Notifications: notifications}, nil
|
||||
return &types.GetNotificationsResp{
|
||||
Notifications: notifications,
|
||||
Total: int64(len(notifications)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toPublicNotifications(list []*model.GlobalNotifications) []types.Notification {
|
||||
out := make([]types.Notification, 0, len(list))
|
||||
for _, m := range list {
|
||||
n := types.Notification{
|
||||
Title: m.Title,
|
||||
Content: m.Content,
|
||||
NotificationPage: m.NotificationPage,
|
||||
StartTime: m.StartTime,
|
||||
EndTime: m.EndTime,
|
||||
}
|
||||
if m.StartDate.Valid {
|
||||
n.StartDate = m.StartDate.Time.Format("2006-01-02")
|
||||
}
|
||||
if m.EndDate.Valid {
|
||||
n.EndDate = m.EndDate.Time.Format("2006-01-02")
|
||||
}
|
||||
out = append(out, n)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -73,6 +73,9 @@ func (l *BindMobileLogic) BindMobile(req *types.BindMobileReq) (resp *types.Bind
|
||||
if claims.UserType == model.UserTypeTemp {
|
||||
userTemp, err := l.svcCtx.UserTempModel.FindOne(l.ctx, claims.UserId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.USER_TEMP_INVALID), "绑定手机号, 临时用户不存在: %d", claims.UserId)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "绑定手机号, 读取临时用户失败: %v", err)
|
||||
}
|
||||
userAuth, err := l.svcCtx.UserAuthModel.FindOneByUserIdAuthType(l.ctx, user.Id, userTemp.AuthType)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bdrp-server/app/main/api/internal/svc"
|
||||
"bdrp-server/app/main/api/internal/types"
|
||||
"bdrp-server/app/main/model"
|
||||
"bdrp-server/common/ctxdata"
|
||||
"bdrp-server/common/xerr"
|
||||
"bdrp-server/pkg/lzkit/crypto"
|
||||
"context"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
@@ -38,6 +38,15 @@ func (l *DetailLogic) Detail() (resp *types.UserInfoResp, err error) {
|
||||
userID := claims.UserId
|
||||
userType := claims.UserType
|
||||
if userType != model.UserTypeNormal {
|
||||
if userType == model.UserTypeTemp {
|
||||
_, err = l.svcCtx.UserTempModel.FindOne(l.ctx, userID)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.USER_TEMP_INVALID), "用户信息, 临时用户不存在, %v", err)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户信息, 查询临时用户失败, %v", err)
|
||||
}
|
||||
}
|
||||
return &types.UserInfoResp{
|
||||
UserInfo: types.User{
|
||||
Id: userID,
|
||||
|
||||
@@ -37,7 +37,10 @@ func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error)
|
||||
if claims.UserType == model.UserTypeTemp {
|
||||
_, err := l.svcCtx.UserTempModel.FindOne(l.ctx, claims.UserId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.USER_TEMP_INVALID), "用户信息, 临时用户不存在, %v", err)
|
||||
}
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户信息, 查询临时用户失败, %v", err)
|
||||
}
|
||||
} else {
|
||||
user, err := l.svcCtx.UserModel.FindOne(l.ctx, claims.UserId)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bdrp-server/app/main/model"
|
||||
"bdrp-server/common/xerr"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -104,6 +104,8 @@ func (l *WxH5AuthLogic) WxH5Auth(req *types.WXH5AuthReq) (resp *types.WXH5AuthRe
|
||||
type AccessTokenResp struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
Openid string `json:"openid"`
|
||||
ErrCode int `json:"errcode,omitempty"`
|
||||
ErrMsg string `json:"errmsg,omitempty"`
|
||||
}
|
||||
|
||||
// GetAccessToken 通过code获取access_token
|
||||
@@ -112,26 +114,46 @@ func (l *WxH5AuthLogic) GetAccessToken(code string) (*AccessTokenResp, error) {
|
||||
appSecret := l.svcCtx.Config.WechatH5.AppSecret
|
||||
|
||||
url := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", appID, appSecret, code)
|
||||
const (
|
||||
maxRetryTimes = 3
|
||||
httpTimeout = 5 * time.Second
|
||||
retryDelay = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
client := &http.Client{Timeout: httpTimeout}
|
||||
var lastErr error
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for attempt := 1; attempt <= maxRetryTimes; attempt++ {
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
} else {
|
||||
body, readErr := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if readErr != nil {
|
||||
lastErr = readErr
|
||||
} else {
|
||||
var accessTokenResp AccessTokenResp
|
||||
if unmarshalErr := json.Unmarshal(body, &accessTokenResp); unmarshalErr != nil {
|
||||
lastErr = unmarshalErr
|
||||
} else {
|
||||
if accessTokenResp.ErrCode != 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
|
||||
"微信接口返回错误: errcode=%d, errmsg=%s",
|
||||
accessTokenResp.ErrCode, accessTokenResp.ErrMsg)
|
||||
}
|
||||
if accessTokenResp.AccessToken == "" || accessTokenResp.Openid == "" {
|
||||
return nil, errors.New("微信接口返回数据不完整")
|
||||
}
|
||||
return &accessTokenResp, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if attempt < maxRetryTimes {
|
||||
time.Sleep(time.Duration(attempt) * retryDelay)
|
||||
}
|
||||
}
|
||||
|
||||
var accessTokenResp AccessTokenResp
|
||||
if err = json.Unmarshal(body, &accessTokenResp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if accessTokenResp.AccessToken == "" || accessTokenResp.Openid == "" {
|
||||
return nil, errors.New("accessTokenResp.AccessToken为空")
|
||||
}
|
||||
|
||||
return &accessTokenResp, nil
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "请求微信access_token接口失败(重试%d次): %v", maxRetryTimes, lastErr)
|
||||
}
|
||||
|
||||
@@ -119,36 +119,52 @@ func (l *WxMiniAuthLogic) GetSessionKey(code string) (*SessionKeyResp, error) {
|
||||
|
||||
url := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
|
||||
appID, appSecret, code)
|
||||
const (
|
||||
maxRetryTimes = 3
|
||||
httpTimeout = 5 * time.Second
|
||||
retryDelay = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取session_key失败: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
client := &http.Client{Timeout: httpTimeout}
|
||||
var lastErr error
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "读取响应失败: %v", err)
|
||||
for attempt := 1; attempt <= maxRetryTimes; attempt++ {
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
} else {
|
||||
body, readErr := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if readErr != nil {
|
||||
lastErr = readErr
|
||||
} else {
|
||||
var sessionKeyResp SessionKeyResp
|
||||
if unmarshalErr := json.Unmarshal(body, &sessionKeyResp); unmarshalErr != nil {
|
||||
lastErr = unmarshalErr
|
||||
} else {
|
||||
// 检查微信返回的错误码
|
||||
if sessionKeyResp.ErrCode != 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
|
||||
"微信接口返回错误: errcode=%d, errmsg=%s",
|
||||
sessionKeyResp.ErrCode, sessionKeyResp.ErrMsg)
|
||||
}
|
||||
|
||||
// 验证必要字段
|
||||
if sessionKeyResp.Openid == "" || sessionKeyResp.SessionKey == "" {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
|
||||
"微信接口返回数据不完整: openid=%s, session_key=%s",
|
||||
sessionKeyResp.Openid, sessionKeyResp.SessionKey)
|
||||
}
|
||||
|
||||
return &sessionKeyResp, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if attempt < maxRetryTimes {
|
||||
time.Sleep(time.Duration(attempt) * retryDelay)
|
||||
}
|
||||
}
|
||||
|
||||
var sessionKeyResp SessionKeyResp
|
||||
if err = json.Unmarshal(body, &sessionKeyResp); err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解析响应失败: %v", err)
|
||||
}
|
||||
|
||||
// 检查微信返回的错误码
|
||||
if sessionKeyResp.ErrCode != 0 {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
|
||||
"微信接口返回错误: errcode=%d, errmsg=%s",
|
||||
sessionKeyResp.ErrCode, sessionKeyResp.ErrMsg)
|
||||
}
|
||||
|
||||
// 验证必要字段
|
||||
if sessionKeyResp.Openid == "" || sessionKeyResp.SessionKey == "" {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR),
|
||||
"微信接口返回数据不完整: openid=%s, session_key=%s",
|
||||
sessionKeyResp.Openid, sessionKeyResp.SessionKey)
|
||||
}
|
||||
|
||||
return &sessionKeyResp, nil
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "请求微信session_key接口失败(重试%d次): %v", maxRetryTimes, lastErr)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bdrp-server/app/main/api/internal/config"
|
||||
"bdrp-server/app/main/model"
|
||||
"bdrp-server/common/ctxdata"
|
||||
jwtx "bdrp-server/common/jwt"
|
||||
"bdrp-server/common/xerr"
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -210,6 +210,9 @@ func (s *UserService) TempUserBindUser(ctx context.Context, session sqlx.Session
|
||||
// 使用事务上下文查询临时用户
|
||||
userTemp, err := s.userTempModel.FindOne(ctx, claims.UserId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.USER_TEMP_INVALID), "临时用户不存在, userId: %d", claims.UserId)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -236,6 +239,9 @@ func (s *UserService) TempUserBindUser(ctx context.Context, session sqlx.Session
|
||||
// 重新获取最新的userTemp数据,确保版本号是最新的
|
||||
latestUserTemp, err := s.userTempModel.FindOne(ctx, claims.UserId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.USER_TEMP_INVALID), "临时用户不存在, userId: %d", claims.UserId)
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = s.userTempModel.DeleteSoft(ctx, session, latestUserTemp)
|
||||
@@ -261,6 +267,9 @@ func (s *UserService) TempUserBindUser(ctx context.Context, session sqlx.Session
|
||||
// 重新获取最新的userTemp数据,确保版本号是最新的
|
||||
latestUserTemp, err := s.userTempModel.FindOne(ctx, claims.UserId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.USER_TEMP_INVALID), "临时用户不存在, userId: %d", claims.UserId)
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = s.userTempModel.DeleteSoft(ctx, session, latestUserTemp)
|
||||
|
||||
@@ -728,11 +728,13 @@ type AdminGetUserDetailResp struct {
|
||||
}
|
||||
|
||||
type AdminGetUserListReq struct {
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
Username string `form:"username,optional"` // 用户名
|
||||
RealName string `form:"real_name,optional"` // 真实姓名
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
Username string `form:"username,optional"` // 用户名
|
||||
RealName string `form:"real_name,optional"` // 真实姓名
|
||||
StartTime string `form:"startTime,optional"` // 创建时间开始(yyyy-MM-dd HH:mm:ss)
|
||||
EndTime string `form:"endTime,optional"` // 创建时间结束(yyyy-MM-dd HH:mm:ss)
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
}
|
||||
|
||||
type AdminGetUserListResp struct {
|
||||
@@ -1199,6 +1201,8 @@ type AgentPlatformDeductionListItem struct {
|
||||
|
||||
type AgentProductConfig struct {
|
||||
ProductID int64 `json:"product_id"`
|
||||
ProductName string `json:"product_name"`
|
||||
ProductEn string `json:"product_en"`
|
||||
CostPrice float64 `json:"cost_price"`
|
||||
PriceRangeMin float64 `json:"price_range_min"`
|
||||
PriceRangeMax float64 `json:"price_range_max"`
|
||||
@@ -1678,11 +1682,16 @@ type GetRoleDetailResp struct {
|
||||
}
|
||||
|
||||
type GetRoleListReq struct {
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
Name string `form:"name,optional"` // 角色名称
|
||||
Code string `form:"code,optional"` // 角色编码
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
Page int64 `form:"page,default=1"` // 页码
|
||||
PageSize int64 `form:"pageSize,default=20"` // 每页数量
|
||||
RoleName string `form:"role_name,optional"` // 角色名称(前端字段)
|
||||
Name string `form:"name,optional"` // 角色名称(兼容字段)
|
||||
RoleCode string `form:"role_code,optional"` // 角色编码(前端字段)
|
||||
Code string `form:"code,optional"` // 角色编码(兼容字段)
|
||||
Description string `form:"description,optional"` // 角色描述
|
||||
StartTime string `form:"startTime,optional"` // 创建时间开始(yyyy-MM-dd HH:mm:ss)
|
||||
EndTime string `form:"endTime,optional"` // 创建时间结束(yyyy-MM-dd HH:mm:ss)
|
||||
Status int64 `form:"status,optional,default=-1"` // 状态:0-禁用,1-启用
|
||||
}
|
||||
|
||||
type GetRoleListResp struct {
|
||||
@@ -2221,6 +2230,6 @@ type GetAppVersionResp struct {
|
||||
|
||||
type SendSmsReq struct {
|
||||
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||
CaptchaVerifyParam string `json:"captchaVerifyParam"`
|
||||
ActionType string `json:"actionType" validate:"omitempty,oneof=login register query agentApply realName bindMobile"`
|
||||
CaptchaVerifyParam string `json:"captchaVerifyParam,optional,omitempty"`
|
||||
ActionType string `json:"actionType,optional" validate:"oneof=login register query agentApply realName bindMobile"`
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ const CUSTOM_ERROR uint32 = 100008
|
||||
const USER_NOT_FOUND uint32 = 100009
|
||||
const USER_NEED_BIND_MOBILE uint32 = 100010
|
||||
const USER_DISABLED uint32 = 100011 // 账号已被封禁
|
||||
const USER_TEMP_INVALID uint32 = 100012
|
||||
|
||||
const LOGIN_FAILED uint32 = 200001
|
||||
const LOGIC_QUERY_WAIT uint32 = 200002
|
||||
|
||||
@@ -14,6 +14,7 @@ func init() {
|
||||
message[USER_NOT_FOUND] = "用户不存在"
|
||||
message[USER_NEED_BIND_MOBILE] = "请先绑定手机号"
|
||||
message[USER_DISABLED] = "账号已被封禁"
|
||||
message[USER_TEMP_INVALID] = "用户状态异常"
|
||||
}
|
||||
|
||||
func MapErrMsg(errcode uint32) string {
|
||||
|
||||
Reference in New Issue
Block a user