package shop import ( "context" "fmt" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/store" "github.com/break/junhong_cmp_fiber/internal/store/postgres" "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 } func New(shopStore *postgres.ShopStore, accountStore *postgres.AccountStore) *Service { return &Service{ shopStore: shopStore, accountStore: accountStore, } } func (s *Service) Create(ctx context.Context, req *model.CreateShopRequest) (*model.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 if req.ParentID != nil { parent, err := s.shopStore.GetByID(ctx, *req.ParentID) if err != nil { return nil, errors.New(errors.CodeInvalidParentID, "上级店铺不存在或无效") } 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, "初始账号手机号已存在") } 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, fmt.Errorf("创建店铺失败: %w", err) } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.InitPassword), bcrypt.DefaultCost) if err != nil { return nil, fmt.Errorf("密码哈希失败: %w", err) } account := &model.Account{ Username: req.InitUsername, Phone: req.InitPhone, Password: string(hashedPassword), UserType: constants.UserTypeAgent, ShopID: &shop.ID, Status: constants.StatusEnabled, } account.Creator = currentUserID account.Updater = currentUserID if err := s.accountStore.Create(ctx, account); err != nil { return nil, fmt.Errorf("创建初始账号失败: %w", err) } return &model.ShopResponse{ ID: shop.ID, ShopName: shop.ShopName, ShopCode: shop.ShopCode, ParentID: shop.ParentID, Level: shop.Level, ContactName: shop.ContactName, ContactPhone: shop.ContactPhone, Province: shop.Province, City: shop.City, District: shop.District, Address: shop.Address, Status: 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 *model.UpdateShopRequest) (*model.ShopResponse, error) { currentUserID := middleware.GetUserIDFromContext(ctx) if currentUserID == 0 { return nil, errors.New(errors.CodeUnauthorized, "未授权访问") } shop, err := s.shopStore.GetByID(ctx, id) if err != nil { return nil, errors.New(errors.CodeShopNotFound, "店铺不存在") } shop.ShopName = req.ShopName shop.ContactName = req.ContactName shop.ContactPhone = req.ContactPhone shop.Province = req.Province shop.City = req.City shop.District = req.District shop.Address = req.Address shop.Status = req.Status shop.Updater = currentUserID if err := s.shopStore.Update(ctx, shop); err != nil { return nil, err } return &model.ShopResponse{ ID: shop.ID, ShopName: shop.ShopName, ShopCode: shop.ShopCode, ParentID: shop.ParentID, Level: shop.Level, ContactName: shop.ContactName, ContactPhone: shop.ContactPhone, Province: shop.Province, City: shop.City, District: shop.District, Address: shop.Address, Status: shop.Status, CreatedAt: shop.CreatedAt.Format("2006-01-02 15:04:05"), UpdatedAt: shop.UpdatedAt.Format("2006-01-02 15:04:05"), }, nil } // Disable 禁用店铺 func (s *Service) Disable(ctx context.Context, id uint) error { // 获取当前用户 ID currentUserID := middleware.GetUserIDFromContext(ctx) if currentUserID == 0 { return errors.New(errors.CodeUnauthorized, "未授权访问") } // 查询店铺 shop, err := s.shopStore.GetByID(ctx, id) if err != nil { return errors.New(errors.CodeShopNotFound, "店铺不存在") } // 更新状态 shop.Status = constants.StatusDisabled shop.Updater = currentUserID return s.shopStore.Update(ctx, shop) } // Enable 启用店铺 func (s *Service) Enable(ctx context.Context, id uint) error { // 获取当前用户 ID currentUserID := middleware.GetUserIDFromContext(ctx) if currentUserID == 0 { return errors.New(errors.CodeUnauthorized, "未授权访问") } // 查询店铺 shop, err := s.shopStore.GetByID(ctx, id) if err != nil { return errors.New(errors.CodeShopNotFound, "店铺不存在") } // 更新状态 shop.Status = constants.StatusEnabled shop.Updater = currentUserID return s.shopStore.Update(ctx, shop) } // GetByID 获取店铺详情 func (s *Service) GetByID(ctx context.Context, id uint) (*model.Shop, error) { shop, err := s.shopStore.GetByID(ctx, id) if err != nil { return nil, errors.New(errors.CodeShopNotFound, "店铺不存在") } return shop, nil } func (s *Service) ListShopResponses(ctx context.Context, req *model.ShopListRequest) ([]*model.ShopResponse, int64, error) { opts := &store.QueryOptions{ Page: req.Page, PageSize: req.PageSize, OrderBy: "created_at DESC", } if opts.Page == 0 { opts.Page = 1 } if opts.PageSize == 0 { opts.PageSize = constants.DefaultPageSize } filters := make(map[string]interface{}) if req.ShopName != "" { filters["shop_name"] = req.ShopName } if req.ShopCode != "" { filters["shop_code"] = req.ShopCode } if req.ParentID != nil { filters["parent_id"] = *req.ParentID } if req.Level != nil { filters["level"] = *req.Level } if req.Status != nil { filters["status"] = *req.Status } shops, total, err := s.shopStore.List(ctx, opts, filters) if err != nil { return nil, 0, fmt.Errorf("查询店铺列表失败: %w", err) } responses := make([]*model.ShopResponse, 0, len(shops)) for _, shop := range shops { responses = append(responses, &model.ShopResponse{ ID: shop.ID, ShopName: shop.ShopName, ShopCode: shop.ShopCode, ParentID: shop.ParentID, Level: shop.Level, ContactName: shop.ContactName, ContactPhone: shop.ContactPhone, Province: shop.Province, City: shop.City, District: shop.District, Address: shop.Address, Status: shop.Status, CreatedAt: shop.CreatedAt.Format("2006-01-02 15:04:05"), UpdatedAt: shop.UpdatedAt.Format("2006-01-02 15:04:05"), }) } return responses, total, nil } func (s *Service) List(ctx context.Context, opts *store.QueryOptions, filters map[string]interface{}) ([]*model.Shop, int64, error) { return s.shopStore.List(ctx, opts, filters) } func (s *Service) Delete(ctx context.Context, id uint) error { currentUserID := middleware.GetUserIDFromContext(ctx) if currentUserID == 0 { return errors.New(errors.CodeUnauthorized, "未授权访问") } shop, err := s.shopStore.GetByID(ctx, id) if err != nil { if err == gorm.ErrRecordNotFound { return errors.New(errors.CodeShopNotFound, "店铺不存在") } return fmt.Errorf("获取店铺失败: %w", err) } accounts, err := s.accountStore.GetByShopID(ctx, shop.ID) if err != nil { return fmt.Errorf("查询店铺账号失败: %w", err) } if len(accounts) > 0 { accountIDs := make([]uint, 0, len(accounts)) for _, account := range accounts { accountIDs = append(accountIDs, account.ID) } if err := s.accountStore.BulkUpdateStatus(ctx, accountIDs, constants.StatusDisabled, currentUserID); err != nil { return fmt.Errorf("禁用店铺账号失败: %w", err) } } if err := s.shopStore.Delete(ctx, id); err != nil { return fmt.Errorf("删除店铺失败: %w", err) } return nil } // GetSubordinateShopIDs 获取下级店铺 ID 列表(包含自己) func (s *Service) GetSubordinateShopIDs(ctx context.Context, shopID uint) ([]uint, error) { return s.shopStore.GetSubordinateShopIDs(ctx, shopID) }