refactor: 删除旧套餐系列分配和套餐分配 Service

业务逻辑已全部迁移至 shop_series_grant/service.go,旧 Service 层完整删除。底层 Store(shop_series_allocation_store、shop_package_allocation_store)保留,仍被佣金计算、订单服务和 Grant Service 使用。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-03-04 11:35:56 +08:00
parent 163d01dae5
commit beed9d25e0
2 changed files with 0 additions and 785 deletions

View File

@@ -1,432 +0,0 @@
package shop_package_allocation
import (
"context"
"time"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"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"
"gorm.io/gorm"
)
type Service struct {
packageAllocationStore *postgres.ShopPackageAllocationStore
seriesAllocationStore *postgres.ShopSeriesAllocationStore
priceHistoryStore *postgres.ShopPackageAllocationPriceHistoryStore
shopStore *postgres.ShopStore
packageStore *postgres.PackageStore
packageSeriesStore *postgres.PackageSeriesStore
}
func New(
packageAllocationStore *postgres.ShopPackageAllocationStore,
seriesAllocationStore *postgres.ShopSeriesAllocationStore,
priceHistoryStore *postgres.ShopPackageAllocationPriceHistoryStore,
shopStore *postgres.ShopStore,
packageStore *postgres.PackageStore,
packageSeriesStore *postgres.PackageSeriesStore,
) *Service {
return &Service{
packageAllocationStore: packageAllocationStore,
seriesAllocationStore: seriesAllocationStore,
priceHistoryStore: priceHistoryStore,
shopStore: shopStore,
packageStore: packageStore,
packageSeriesStore: packageSeriesStore,
}
}
func (s *Service) Create(ctx context.Context, req *dto.CreateShopPackageAllocationRequest) (*dto.ShopPackageAllocationResponse, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
}
userType := middleware.GetUserTypeFromContext(ctx)
allocatorShopID := middleware.GetShopIDFromContext(ctx)
if userType == constants.UserTypeAgent && allocatorShopID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "当前用户不属于任何店铺")
}
targetShop, err := s.shopStore.GetByID(ctx, req.ShopID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "目标店铺不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取店铺失败")
}
if userType == constants.UserTypeAgent {
if targetShop.ParentID == nil || *targetShop.ParentID != allocatorShopID {
return nil, errors.New(errors.CodeForbidden, "只能为直属下级分配套餐")
}
}
pkg, err := s.packageStore.GetByID(ctx, req.PackageID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "套餐不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
}
existing, _ := s.packageAllocationStore.GetByShopAndPackage(ctx, req.ShopID, req.PackageID)
if existing != nil {
return nil, errors.New(errors.CodeConflict, "该店铺已有此套餐的分配配置")
}
seriesAllocation, err := s.seriesAllocationStore.GetByShopAndSeries(ctx, req.ShopID, pkg.SeriesID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeInvalidParam, "请先分配该套餐所属的系列")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取系列分配失败")
}
allocation := &model.ShopPackageAllocation{
ShopID: req.ShopID,
PackageID: req.PackageID,
AllocatorShopID: allocatorShopID,
CostPrice: req.CostPrice,
SeriesAllocationID: &seriesAllocation.ID,
Status: constants.StatusEnabled,
}
allocation.Creator = currentUserID
if err := s.packageAllocationStore.Create(ctx, allocation); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "创建分配失败")
}
return s.buildResponse(ctx, allocation, targetShop.ShopName, pkg.PackageName, pkg.PackageCode)
}
func (s *Service) Get(ctx context.Context, id uint) (*dto.ShopPackageAllocationResponse, error) {
allocation, err := s.packageAllocationStore.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
pkg, _ := s.packageStore.GetByIDUnscoped(ctx, allocation.PackageID)
shopName := ""
packageName := ""
packageCode := ""
if shop != nil {
shopName = shop.ShopName
}
if pkg != nil {
packageName = pkg.PackageName
packageCode = pkg.PackageCode
}
return s.buildResponse(ctx, allocation, shopName, packageName, packageCode)
}
func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopPackageAllocationRequest) (*dto.ShopPackageAllocationResponse, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
}
allocation, err := s.packageAllocationStore.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
if req.CostPrice != nil {
allocation.CostPrice = *req.CostPrice
}
allocation.Updater = currentUserID
if err := s.packageAllocationStore.Update(ctx, allocation); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "更新分配失败")
}
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
pkg, _ := s.packageStore.GetByIDUnscoped(ctx, allocation.PackageID)
shopName := ""
packageName := ""
packageCode := ""
if shop != nil {
shopName = shop.ShopName
}
if pkg != nil {
packageName = pkg.PackageName
packageCode = pkg.PackageCode
}
return s.buildResponse(ctx, allocation, shopName, packageName, packageCode)
}
func (s *Service) Delete(ctx context.Context, id uint) error {
_, err := s.packageAllocationStore.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return errors.New(errors.CodeNotFound, "分配记录不存在")
}
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
if err := s.packageAllocationStore.Delete(ctx, id); err != nil {
return errors.Wrap(errors.CodeInternalError, err, "删除分配失败")
}
return nil
}
func (s *Service) List(ctx context.Context, req *dto.ShopPackageAllocationListRequest) ([]*dto.ShopPackageAllocationResponse, int64, error) {
opts := &store.QueryOptions{
Page: req.Page,
PageSize: req.PageSize,
OrderBy: "id DESC",
}
if opts.Page == 0 {
opts.Page = 1
}
if opts.PageSize == 0 {
opts.PageSize = constants.DefaultPageSize
}
filters := make(map[string]interface{})
if req.ShopID != nil {
filters["shop_id"] = *req.ShopID
}
if req.PackageID != nil {
filters["package_id"] = *req.PackageID
}
if req.SeriesAllocationID != nil {
filters["series_allocation_id"] = *req.SeriesAllocationID
}
if req.AllocatorShopID != nil {
filters["allocator_shop_id"] = *req.AllocatorShopID
}
if req.Status != nil {
filters["status"] = *req.Status
}
allocations, total, err := s.packageAllocationStore.List(ctx, opts, filters)
if err != nil {
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询分配列表失败")
}
responses := make([]*dto.ShopPackageAllocationResponse, len(allocations))
for i, a := range allocations {
shop, _ := s.shopStore.GetByID(ctx, a.ShopID)
pkg, _ := s.packageStore.GetByIDUnscoped(ctx, a.PackageID)
shopName := ""
packageName := ""
packageCode := ""
if shop != nil {
shopName = shop.ShopName
}
if pkg != nil {
packageName = pkg.PackageName
packageCode = pkg.PackageCode
}
resp, _ := s.buildResponse(ctx, a, shopName, packageName, packageCode)
responses[i] = resp
}
return responses, total, nil
}
func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return errors.New(errors.CodeUnauthorized, "未授权访问")
}
// 任务 3.2:所有者校验 —— 代理只能修改自己创建的分配记录的 status
// 使用系统级查询(不带数据权限过滤),再做业务层权限判断以返回正确的 403
allocation, err := s.packageAllocationStore.GetByIDForSystem(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return errors.New(errors.CodeNotFound, "分配记录不存在")
}
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
userType := middleware.GetUserTypeFromContext(ctx)
if userType == constants.UserTypeAgent {
callerShopID := middleware.GetShopIDFromContext(ctx)
// 代理用户只能修改自己作为 allocator 的记录
if allocation.AllocatorShopID != callerShopID {
return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
}
}
if err := s.packageAllocationStore.UpdateStatus(ctx, id, status, currentUserID); err != nil {
return errors.Wrap(errors.CodeInternalError, err, "更新状态失败")
}
return nil
}
// UpdateShelfStatus 更新分配记录的上下架状态
// 代理独立控制自己客户侧套餐可见性,不影响平台全局状态
func (s *Service) UpdateShelfStatus(ctx context.Context, allocationID uint, shelfStatus int) error {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return errors.New(errors.CodeUnauthorized, "未授权访问")
}
allocation, err := s.packageAllocationStore.GetByID(ctx, allocationID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return errors.New(errors.CodeNotFound, "分配记录不存在")
}
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
// 上架时检查套餐全局状态:禁用的套餐不允许上架
if shelfStatus == constants.ShelfStatusOn {
pkg, err := s.packageStore.GetByID(ctx, allocation.PackageID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return errors.New(errors.CodeNotFound, "套餐不存在")
}
return errors.Wrap(errors.CodeInternalError, err, "获取套餐失败")
}
if pkg.Status == constants.StatusDisabled {
return errors.New(errors.CodeInvalidStatus, "套餐已禁用,无法上架")
}
}
if err := s.packageAllocationStore.UpdateShelfStatus(ctx, allocationID, shelfStatus, currentUserID); err != nil {
return errors.Wrap(errors.CodeInternalError, err, "更新上下架状态失败")
}
return nil
}
func (s *Service) buildResponse(ctx context.Context, a *model.ShopPackageAllocation, shopName, packageName, packageCode string) (*dto.ShopPackageAllocationResponse, error) {
var seriesID uint
seriesName := ""
pkg, _ := s.packageStore.GetByIDUnscoped(ctx, a.PackageID)
if pkg != nil {
seriesID = pkg.SeriesID
series, _ := s.packageSeriesStore.GetByIDUnscoped(ctx, pkg.SeriesID)
if series != nil {
seriesName = series.SeriesName
}
}
allocatorShopName := ""
if a.AllocatorShopID > 0 {
allocatorShop, _ := s.shopStore.GetByID(ctx, a.AllocatorShopID)
if allocatorShop != nil {
allocatorShopName = allocatorShop.ShopName
}
} else {
allocatorShopName = "平台"
}
return &dto.ShopPackageAllocationResponse{
ID: a.ID,
ShopID: a.ShopID,
ShopName: shopName,
PackageID: a.PackageID,
PackageName: packageName,
PackageCode: packageCode,
SeriesID: seriesID,
SeriesName: seriesName,
SeriesAllocationID: a.SeriesAllocationID,
AllocatorShopID: a.AllocatorShopID,
AllocatorShopName: allocatorShopName,
CostPrice: a.CostPrice,
Status: a.Status,
ShelfStatus: a.ShelfStatus,
CreatedAt: a.CreatedAt.Format(time.RFC3339),
UpdatedAt: a.UpdatedAt.Format(time.RFC3339),
}, nil
}
func (s *Service) UpdateCostPrice(ctx context.Context, id uint, newCostPrice int64, changeReason string) (*dto.ShopPackageAllocationResponse, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
}
allocation, err := s.packageAllocationStore.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
if allocation.CostPrice == newCostPrice {
return nil, errors.New(errors.CodeInvalidParam, "新成本价与当前成本价相同")
}
oldCostPrice := allocation.CostPrice
now := time.Now()
priceHistory := &model.ShopPackageAllocationPriceHistory{
AllocationID: allocation.ID,
OldCostPrice: oldCostPrice,
NewCostPrice: newCostPrice,
ChangeReason: changeReason,
ChangedBy: currentUserID,
EffectiveFrom: now,
}
if err := s.priceHistoryStore.Create(ctx, priceHistory); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "创建价格历史记录失败")
}
allocation.CostPrice = newCostPrice
allocation.Updater = currentUserID
if err := s.packageAllocationStore.Update(ctx, allocation); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "更新成本价失败")
}
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
pkg, _ := s.packageStore.GetByIDUnscoped(ctx, allocation.PackageID)
shopName := ""
packageName := ""
packageCode := ""
if shop != nil {
shopName = shop.ShopName
}
if pkg != nil {
packageName = pkg.PackageName
packageCode = pkg.PackageCode
}
return s.buildResponse(ctx, allocation, shopName, packageName, packageCode)
}
func (s *Service) GetPriceHistory(ctx context.Context, allocationID uint) ([]*model.ShopPackageAllocationPriceHistory, error) {
_, err := s.packageAllocationStore.GetByID(ctx, allocationID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
history, err := s.priceHistoryStore.ListByAllocation(ctx, allocationID)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "获取价格历史失败")
}
return history, nil
}

View File

@@ -1,353 +0,0 @@
package shop_series_allocation
import (
"context"
"time"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"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"
"gorm.io/gorm"
)
type Service struct {
seriesAllocationStore *postgres.ShopSeriesAllocationStore
packageAllocationStore *postgres.ShopPackageAllocationStore
shopStore *postgres.ShopStore
packageSeriesStore *postgres.PackageSeriesStore
}
func New(
seriesAllocationStore *postgres.ShopSeriesAllocationStore,
packageAllocationStore *postgres.ShopPackageAllocationStore,
shopStore *postgres.ShopStore,
packageSeriesStore *postgres.PackageSeriesStore,
) *Service {
return &Service{
seriesAllocationStore: seriesAllocationStore,
packageAllocationStore: packageAllocationStore,
shopStore: shopStore,
packageSeriesStore: packageSeriesStore,
}
}
func (s *Service) Create(ctx context.Context, req *dto.CreateShopSeriesAllocationRequest) (*dto.ShopSeriesAllocationResponse, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
}
userType := middleware.GetUserTypeFromContext(ctx)
allocatorShopID := middleware.GetShopIDFromContext(ctx)
if userType == constants.UserTypeAgent && allocatorShopID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "当前用户不属于任何店铺")
}
targetShop, err := s.shopStore.GetByID(ctx, req.ShopID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "目标店铺不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取店铺失败")
}
if userType == constants.UserTypeAgent {
if targetShop.ParentID == nil || *targetShop.ParentID != allocatorShopID {
return nil, errors.New(errors.CodeForbidden, "只能为直属下级分配套餐系列")
}
}
series, err := s.packageSeriesStore.GetByID(ctx, req.SeriesID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
}
// 检查是否已存在分配
exists, err := s.seriesAllocationStore.ExistsByShopAndSeries(ctx, req.ShopID, req.SeriesID)
if err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "检查分配记录失败")
}
if exists {
return nil, errors.New(errors.CodeConflict, "该店铺已分配此套餐系列")
}
// 代理用户:检查自己是否有该系列的分配权限,且金额不能超过上级给的上限
// 平台用户:无上限限制,可自由设定金额
if userType == constants.UserTypeAgent {
allocatorAllocation, err := s.seriesAllocationStore.GetByShopAndSeries(ctx, allocatorShopID, req.SeriesID)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeForbidden, "您没有该套餐系列的分配权限")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配权限失败")
}
if req.OneTimeCommissionAmount > allocatorAllocation.OneTimeCommissionAmount {
return nil, errors.New(errors.CodeInvalidParam, "一次性佣金金额不能超过您的分配上限")
}
}
allocation := &model.ShopSeriesAllocation{
ShopID: req.ShopID,
SeriesID: req.SeriesID,
AllocatorShopID: allocatorShopID,
OneTimeCommissionAmount: req.OneTimeCommissionAmount,
EnableOneTimeCommission: false,
OneTimeCommissionTrigger: "",
OneTimeCommissionThreshold: 0,
EnableForceRecharge: false,
ForceRechargeAmount: 0,
ForceRechargeTriggerType: 2,
Status: constants.StatusEnabled,
}
if req.EnableOneTimeCommission != nil {
allocation.EnableOneTimeCommission = *req.EnableOneTimeCommission
}
if req.OneTimeCommissionTrigger != "" {
allocation.OneTimeCommissionTrigger = req.OneTimeCommissionTrigger
}
if req.OneTimeCommissionThreshold != nil {
allocation.OneTimeCommissionThreshold = *req.OneTimeCommissionThreshold
}
if req.EnableForceRecharge != nil {
allocation.EnableForceRecharge = *req.EnableForceRecharge
}
if req.ForceRechargeAmount != nil {
allocation.ForceRechargeAmount = *req.ForceRechargeAmount
}
if req.ForceRechargeTriggerType != nil {
allocation.ForceRechargeTriggerType = *req.ForceRechargeTriggerType
}
allocation.Creator = currentUserID
if err := s.seriesAllocationStore.Create(ctx, allocation); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "创建分配失败")
}
return s.buildResponse(ctx, allocation, targetShop.ShopName, series.SeriesName, series.SeriesCode)
}
func (s *Service) Get(ctx context.Context, id uint) (*dto.ShopSeriesAllocationResponse, error) {
allocation, err := s.seriesAllocationStore.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
series, _ := s.packageSeriesStore.GetByID(ctx, allocation.SeriesID)
shopName := ""
seriesName := ""
seriesCode := ""
if shop != nil {
shopName = shop.ShopName
}
if series != nil {
seriesName = series.SeriesName
seriesCode = series.SeriesCode
}
return s.buildResponse(ctx, allocation, shopName, seriesName, seriesCode)
}
func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdateShopSeriesAllocationRequest) (*dto.ShopSeriesAllocationResponse, error) {
currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
}
userType := middleware.GetUserTypeFromContext(ctx)
allocatorShopID := middleware.GetShopIDFromContext(ctx)
allocation, err := s.seriesAllocationStore.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, errors.New(errors.CodeNotFound, "分配记录不存在")
}
return nil, errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
if req.OneTimeCommissionAmount != nil {
newAmount := *req.OneTimeCommissionAmount
if userType == constants.UserTypeAgent {
allocatorAllocation, err := s.seriesAllocationStore.GetByShopAndSeries(ctx, allocatorShopID, allocation.SeriesID)
if err == nil && allocatorAllocation != nil {
if newAmount > allocatorAllocation.OneTimeCommissionAmount {
return nil, errors.New(errors.CodeInvalidParam, "一次性佣金金额不能超过您的分配上限")
}
}
}
allocation.OneTimeCommissionAmount = newAmount
}
if req.EnableOneTimeCommission != nil {
allocation.EnableOneTimeCommission = *req.EnableOneTimeCommission
}
if req.OneTimeCommissionTrigger != nil {
allocation.OneTimeCommissionTrigger = *req.OneTimeCommissionTrigger
}
if req.OneTimeCommissionThreshold != nil {
allocation.OneTimeCommissionThreshold = *req.OneTimeCommissionThreshold
}
if req.EnableForceRecharge != nil {
allocation.EnableForceRecharge = *req.EnableForceRecharge
}
if req.ForceRechargeAmount != nil {
allocation.ForceRechargeAmount = *req.ForceRechargeAmount
}
if req.ForceRechargeTriggerType != nil {
allocation.ForceRechargeTriggerType = *req.ForceRechargeTriggerType
}
if req.Status != nil {
allocation.Status = *req.Status
}
allocation.Updater = currentUserID
if err := s.seriesAllocationStore.Update(ctx, allocation); err != nil {
return nil, errors.Wrap(errors.CodeInternalError, err, "更新分配失败")
}
shop, _ := s.shopStore.GetByID(ctx, allocation.ShopID)
series, _ := s.packageSeriesStore.GetByID(ctx, allocation.SeriesID)
shopName := ""
seriesName := ""
seriesCode := ""
if shop != nil {
shopName = shop.ShopName
}
if series != nil {
seriesName = series.SeriesName
seriesCode = series.SeriesCode
}
return s.buildResponse(ctx, allocation, shopName, seriesName, seriesCode)
}
func (s *Service) Delete(ctx context.Context, id uint) error {
_, err := s.seriesAllocationStore.GetByID(ctx, id)
if err != nil {
if err == gorm.ErrRecordNotFound {
return errors.New(errors.CodeNotFound, "分配记录不存在")
}
return errors.Wrap(errors.CodeInternalError, err, "获取分配记录失败")
}
count, err := s.packageAllocationStore.CountBySeriesAllocationID(ctx, id)
if err != nil {
return errors.Wrap(errors.CodeInternalError, err, "检查关联套餐分配失败")
}
if count > 0 {
return errors.New(errors.CodeInvalidParam, "存在关联的套餐分配,无法删除")
}
if err := s.seriesAllocationStore.Delete(ctx, id); err != nil {
return errors.Wrap(errors.CodeInternalError, err, "删除分配失败")
}
return nil
}
func (s *Service) List(ctx context.Context, req *dto.ShopSeriesAllocationListRequest) ([]*dto.ShopSeriesAllocationResponse, int64, error) {
opts := &store.QueryOptions{
Page: req.Page,
PageSize: req.PageSize,
OrderBy: "id DESC",
}
if opts.Page == 0 {
opts.Page = 1
}
if opts.PageSize == 0 {
opts.PageSize = constants.DefaultPageSize
}
filters := make(map[string]interface{})
if req.ShopID != nil {
filters["shop_id"] = *req.ShopID
}
if req.SeriesID != nil {
filters["series_id"] = *req.SeriesID
}
if req.AllocatorShopID != nil {
filters["allocator_shop_id"] = *req.AllocatorShopID
}
if req.Status != nil {
filters["status"] = *req.Status
}
allocations, total, err := s.seriesAllocationStore.List(ctx, opts, filters)
if err != nil {
return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询分配列表失败")
}
responses := make([]*dto.ShopSeriesAllocationResponse, len(allocations))
for i, a := range allocations {
shop, _ := s.shopStore.GetByID(ctx, a.ShopID)
series, _ := s.packageSeriesStore.GetByID(ctx, a.SeriesID)
shopName := ""
seriesName := ""
seriesCode := ""
if shop != nil {
shopName = shop.ShopName
}
if series != nil {
seriesName = series.SeriesName
seriesCode = series.SeriesCode
}
resp, _ := s.buildResponse(ctx, a, shopName, seriesName, seriesCode)
responses[i] = resp
}
return responses, total, nil
}
func (s *Service) buildResponse(ctx context.Context, a *model.ShopSeriesAllocation, shopName, seriesName, seriesCode string) (*dto.ShopSeriesAllocationResponse, error) {
allocatorShopName := ""
if a.AllocatorShopID > 0 {
allocatorShop, _ := s.shopStore.GetByID(ctx, a.AllocatorShopID)
if allocatorShop != nil {
allocatorShopName = allocatorShop.ShopName
}
} else {
allocatorShopName = "平台"
}
return &dto.ShopSeriesAllocationResponse{
ID: a.ID,
ShopID: a.ShopID,
ShopName: shopName,
SeriesID: a.SeriesID,
SeriesName: seriesName,
SeriesCode: seriesCode,
AllocatorShopID: a.AllocatorShopID,
AllocatorShopName: allocatorShopName,
OneTimeCommissionAmount: a.OneTimeCommissionAmount,
EnableOneTimeCommission: a.EnableOneTimeCommission,
OneTimeCommissionTrigger: a.OneTimeCommissionTrigger,
OneTimeCommissionThreshold: a.OneTimeCommissionThreshold,
EnableForceRecharge: a.EnableForceRecharge,
ForceRechargeAmount: a.ForceRechargeAmount,
ForceRechargeTriggerType: a.ForceRechargeTriggerType,
Status: a.Status,
CreatedAt: a.CreatedAt.Format(time.RFC3339),
UpdatedAt: a.UpdatedAt.Format(time.RFC3339),
}, nil
}
func (s *Service) GetByShopAndSeries(ctx context.Context, shopID, seriesID uint) (*model.ShopSeriesAllocation, error) {
return s.seriesAllocationStore.GetByShopAndSeries(ctx, shopID, seriesID)
}