暂存一下,防止丢失

This commit is contained in:
2026-07-24 16:07:18 +08:00
parent 5d6e23f1a5
commit a18ed8bc8d
180 changed files with 13597 additions and 1986 deletions

View File

@@ -10,17 +10,14 @@ 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"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
type Service struct {
shopStore *postgres.ShopStore
accountStore *postgres.AccountStore
shopRoleStore *postgres.ShopRoleStore
roleStore *postgres.RoleStore
accountRoleStore *postgres.AccountRoleStore
agentWalletStore *postgres.AgentWalletStore
shopStore *postgres.ShopStore
accountStore *postgres.AccountStore
shopRoleStore *postgres.ShopRoleStore
roleStore *postgres.RoleStore
}
func New(
@@ -28,177 +25,15 @@ func New(
accountStore *postgres.AccountStore,
shopRoleStore *postgres.ShopRoleStore,
roleStore *postgres.RoleStore,
accountRoleStore *postgres.AccountRoleStore,
agentWalletStore *postgres.AgentWalletStore,
) *Service {
return &Service{
shopStore: shopStore,
accountStore: accountStore,
shopRoleStore: shopRoleStore,
roleStore: roleStore,
accountRoleStore: accountRoleStore,
agentWalletStore: agentWalletStore,
shopStore: shopStore,
accountStore: accountStore,
shopRoleStore: shopRoleStore,
roleStore: roleStore,
}
}
func (s *Service) Create(ctx context.Context, req *dto.CreateShopRequest) (*dto.ShopResponse, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
}
existing, err := s.shopStore.GetByCode(ctx, req.ShopCode)
if err == nil && existing != nil {
return nil, errors.New(errors.CodeShopCodeExists, "店铺编号已存在")
}
level := 1
parentShopName := ""
if req.ParentID != nil {
parent, err := s.shopStore.GetByID(ctx, *req.ParentID)
if err != nil {
return nil, errors.New(errors.CodeInvalidParentID, "上级店铺不存在或无效")
}
parentShopName = parent.ShopName
level = parent.Level + 1
if level > constants.ShopMaxLevel {
return nil, errors.New(errors.CodeShopLevelExceeded, "店铺层级不能超过 7 级")
}
}
existingAccount, err := s.accountStore.GetByUsername(ctx, req.InitUsername)
if err == nil && existingAccount != nil {
return nil, errors.New(errors.CodeUsernameExists, "初始账号用户名已存在")
}
existingAccount, err = s.accountStore.GetByPhone(ctx, req.InitPhone)
if err == nil && existingAccount != nil {
return nil, errors.New(errors.CodePhoneExists, "初始账号手机号已存在")
}
// 验证默认角色:必须存在、是客户角色且已启用
defaultRole, err := s.roleStore.GetByID(ctx, req.DefaultRoleID)
if err != nil {
return nil, errors.New(errors.CodeNotFound, "请选择默认角色")
}
if defaultRole.RoleType != constants.RoleTypeCustomer {
return nil, errors.New(errors.CodeInvalidParam, "店铺默认角色必须是客户角色")
}
if defaultRole.Status != constants.StatusEnabled {
return nil, errors.New(errors.CodeInvalidParam, "默认角色已禁用")
}
shop := &model.Shop{
ShopName: req.ShopName,
ShopCode: req.ShopCode,
ParentID: req.ParentID,
Level: level,
ContactName: req.ContactName,
ContactPhone: req.ContactPhone,
Province: req.Province,
City: req.City,
District: req.District,
Address: req.Address,
Status: constants.ShopStatusEnabled,
}
shop.Creator = currentUserID
shop.Updater = currentUserID
if err := s.shopStore.Create(ctx, shop); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "创建店铺失败")
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.InitPassword), bcrypt.DefaultCost)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "密码哈希失败")
}
account := &model.Account{
Username: req.InitUsername,
Phone: req.InitPhone,
Password: string(hashedPassword),
UserType: constants.UserTypeAgent,
ShopID: &shop.ID,
Status: constants.StatusEnabled,
IsPrimary: true,
}
account.Creator = currentUserID
account.Updater = currentUserID
if err := s.accountStore.Create(ctx, account); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "创建初始账号失败")
}
// 为初始账号分配默认角色
accountRole := &model.AccountRole{
AccountID: account.ID,
RoleID: req.DefaultRoleID,
Status: constants.StatusEnabled,
Creator: currentUserID,
Updater: currentUserID,
}
if err := s.accountRoleStore.Create(ctx, accountRole); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "为初始账号分配角色失败")
}
// 设置店铺默认角色
shopRole := &model.ShopRole{
ShopID: shop.ID,
RoleID: req.DefaultRoleID,
Status: constants.StatusEnabled,
Creator: currentUserID,
Updater: currentUserID,
}
if err := s.shopRoleStore.BatchCreate(ctx, []*model.ShopRole{shopRole}); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "设置店铺默认角色失败")
}
// 初始化店铺代理钱包:主钱包 + 分佣钱包
// 新店铺必须有两个钱包才能参与充值和分佣体系
wallets := []*model.AgentWallet{
{
ShopID: shop.ID,
WalletType: constants.AgentWalletTypeMain,
Balance: 0,
Currency: "CNY",
Status: constants.AgentWalletStatusNormal,
ShopIDTag: shop.ID,
},
{
ShopID: shop.ID,
WalletType: constants.AgentWalletTypeCommission,
Balance: 0,
Currency: "CNY",
Status: constants.AgentWalletStatusNormal,
ShopIDTag: shop.ID,
},
}
for _, wallet := range wallets {
if err := s.agentWalletStore.Create(ctx, wallet); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "初始化店铺钱包失败")
}
}
return &dto.ShopResponse{
ID: shop.ID,
ShopName: shop.ShopName,
ShopCode: shop.ShopCode,
ParentID: shop.ParentID,
ParentShopName: parentShopName,
Level: shop.Level,
ContactName: shop.ContactName,
ContactPhone: shop.ContactPhone,
Province: shop.Province,
City: shop.City,
District: shop.District,
Address: shop.Address,
Status: shop.Status,
StatusName: constants.GetStatusName(shop.Status),
CreatedAt: shop.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: shop.UpdatedAt.Format("2006-01-02 15:04:05"),
}, nil
}
func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopRequest) (*dto.ShopResponse, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {