七月迭代短暂完结,还有很多后端的关键东西没有弄,这是一版赶时间做的东西
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
This commit is contained in:
@@ -4,7 +4,9 @@ package account
|
||||
|
||||
import (
|
||||
"context"
|
||||
stdErrors "errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
@@ -13,6 +15,7 @@ import (
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -31,12 +34,18 @@ type Service struct {
|
||||
shopStore ShopStoreInterface
|
||||
enterpriseStore middleware.EnterpriseStoreInterface
|
||||
auditService AuditServiceInterface
|
||||
wecomMembers WeComMemberFinder
|
||||
}
|
||||
|
||||
type AuditServiceInterface interface {
|
||||
LogOperation(ctx context.Context, log *model.AccountOperationLog)
|
||||
}
|
||||
|
||||
// WeComMemberFinder 定义账号绑定时校验应用可见成员的边界。
|
||||
type WeComMemberFinder interface {
|
||||
GetVisible(ctx context.Context, applicationID uint, userID string) (*model.WeComMember, error)
|
||||
}
|
||||
|
||||
// New 创建账号服务
|
||||
func New(
|
||||
accountStore *postgres.AccountStore,
|
||||
@@ -58,6 +67,11 @@ func New(
|
||||
}
|
||||
}
|
||||
|
||||
// SetWeComMemberFinder 注入企业微信应用可见成员查询边界。
|
||||
func (s *Service) SetWeComMemberFinder(finder WeComMemberFinder) {
|
||||
s.wecomMembers = finder
|
||||
}
|
||||
|
||||
// Create 创建账号
|
||||
func (s *Service) Create(ctx context.Context, req *dto.CreateAccountRequest) (*model.Account, error) {
|
||||
currentUserID := middleware.GetUserIDFromContext(ctx)
|
||||
@@ -180,7 +194,7 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateAccountRequest) (*m
|
||||
}
|
||||
|
||||
// Get 获取账号
|
||||
func (s *Service) Get(ctx context.Context, id uint) (*model.Account, error) {
|
||||
func (s *Service) Get(ctx context.Context, id uint) (*dto.AccountResponse, error) {
|
||||
account, err := s.accountStore.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
@@ -188,7 +202,66 @@ func (s *Service) Get(ctx context.Context, id uint) (*model.Account, error) {
|
||||
}
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "获取账号失败")
|
||||
}
|
||||
return account, nil
|
||||
accounts := []*model.Account{account}
|
||||
return s.toAccountResponse(account, s.loadShopNames(ctx, accounts), s.loadEnterpriseNames(ctx, accounts)), nil
|
||||
}
|
||||
|
||||
// BindWeCom 将系统账号绑定到管理员明确选择的企微应用可见成员。
|
||||
func (s *Service) BindWeCom(ctx context.Context, accountID uint, request dto.BindAccountWeComRequest) (*dto.AccountResponse, error) {
|
||||
operatorID := middleware.GetUserIDFromContext(ctx)
|
||||
operatorType := middleware.GetUserTypeFromContext(ctx)
|
||||
if operatorID == 0 {
|
||||
return nil, errors.New(errors.CodeUnauthorized)
|
||||
}
|
||||
if operatorType != constants.UserTypeSuperAdmin && operatorType != constants.UserTypePlatform {
|
||||
return nil, errors.New(errors.CodeForbidden)
|
||||
}
|
||||
if s.wecomMembers == nil || request.ApplicationID == 0 || strings.TrimSpace(request.UserID) == "" {
|
||||
return nil, errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
account, err := s.accountStore.GetByID(ctx, accountID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
|
||||
}
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询待绑定账号失败")
|
||||
}
|
||||
member, err := s.wecomMembers.GetVisible(ctx, request.ApplicationID, request.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
beforeData := model.JSONB{
|
||||
"wecom_corp_id": account.WeComCorpID, "wecom_userid": account.WeComUserID,
|
||||
"wecom_name": account.WeComName,
|
||||
}
|
||||
if err := s.accountStore.BindWeCom(ctx, accountID, member.CorpID, member.UserID, member.Name, operatorID); err != nil {
|
||||
var pgErr *pgconn.PgError
|
||||
if stdErrors.As(err, &pgErr) && pgErr.Code == "23505" {
|
||||
return nil, errors.New(errors.CodeConflict, "该企业微信成员已绑定其他系统账号")
|
||||
}
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "绑定企业微信成员失败")
|
||||
}
|
||||
account.WeComCorpID = member.CorpID
|
||||
account.WeComUserID = member.UserID
|
||||
account.WeComName = member.Name
|
||||
account.Updater = operatorID
|
||||
if s.auditService != nil {
|
||||
operatorName := ""
|
||||
if operator, getErr := s.accountStore.GetByID(ctx, operatorID); getErr == nil {
|
||||
operatorName = operator.Username
|
||||
}
|
||||
s.auditService.LogOperation(ctx, &model.AccountOperationLog{
|
||||
OperatorID: operatorID, OperatorType: operatorType, OperatorName: operatorName,
|
||||
TargetAccountID: &account.ID, TargetUsername: &account.Username, TargetUserType: &account.UserType,
|
||||
OperationType: "bind_wecom", OperationDesc: fmt.Sprintf("绑定账号企业微信成员: %s", account.Username),
|
||||
BeforeData: beforeData, AfterData: model.JSONB{
|
||||
"wecom_corp_id": member.CorpID, "wecom_userid": member.UserID, "wecom_name": member.Name,
|
||||
}, RequestID: middleware.GetRequestIDFromContext(ctx), IPAddress: middleware.GetIPFromContext(ctx),
|
||||
UserAgent: middleware.GetUserAgentFromContext(ctx),
|
||||
})
|
||||
}
|
||||
accounts := []*model.Account{account}
|
||||
return s.toAccountResponse(account, s.loadShopNames(ctx, accounts), s.loadEnterpriseNames(ctx, accounts)), nil
|
||||
}
|
||||
|
||||
// Update 更新账号
|
||||
@@ -796,6 +869,10 @@ func (s *Service) toAccountResponse(acc *model.Account, shopMap map[uint]string,
|
||||
UserType: acc.UserType,
|
||||
ShopID: acc.ShopID,
|
||||
EnterpriseID: acc.EnterpriseID,
|
||||
WeComCorpID: acc.WeComCorpID,
|
||||
WeComUserID: acc.WeComUserID,
|
||||
WeComName: acc.WeComName,
|
||||
WeComBound: acc.WeComCorpID != "" && acc.WeComUserID != "",
|
||||
Status: acc.Status,
|
||||
StatusName: constants.GetStatusName(acc.Status),
|
||||
Creator: acc.Creator,
|
||||
|
||||
Reference in New Issue
Block a user