Files
junhong_cmp_fiber/internal/application/shop/update.go
2026-07-24 16:07:18 +08:00

109 lines
3.7 KiB
Go

package shop
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/middleware"
)
// UpdateService 收口店铺资料与业务员归属的简单写事务脚本。
type UpdateService struct {
db *gorm.DB
}
// NewUpdateService 创建店铺更新事务脚本。
func NewUpdateService(db *gorm.DB) *UpdateService {
return &UpdateService{db: db}
}
// Update 更新单个店铺;业务员归属变化不会传播到其他店铺。
func (s *UpdateService) Update(ctx context.Context, shopID uint, request *dto.UpdateShopRequest) (*dto.ShopResponse, error) {
if shopID == 0 {
return nil, errors.New(errors.CodeInvalidParam)
}
userType := middleware.GetUserTypeFromContext(ctx)
if userType == constants.UserTypeEnterprise {
return nil, errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
}
if err := middleware.CanManageShop(ctx, shopID); err != nil {
return nil, errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
}
if userType == constants.UserTypeAgent && request.BusinessOwnerAccountIDSet {
return nil, errors.New(errors.CodeForbidden, "无权限设置店铺业务员")
}
if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform && userType != constants.UserTypeAgent {
return nil, errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
}
operatorID := middleware.GetUserIDFromContext(ctx)
if operatorID == 0 {
return nil, errors.New(errors.CodeUnauthorized)
}
var response *dto.ShopResponse
err := s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var shop model.Shop
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&shop, shopID).Error; err != nil {
return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
}
if request.BusinessOwnerAccountIDSet {
ownerID, err := validateUpdatedBusinessOwner(tx, request.BusinessOwnerAccountID)
if err != nil {
return err
}
shop.BusinessOwnerAccountID = ownerID
}
shop.ShopName = request.ShopName
shop.ContactName = request.ContactName
shop.ContactPhone = request.ContactPhone
shop.Province = request.Province
shop.City = request.City
shop.District = request.District
shop.Address = request.Address
shop.Status = request.Status
shop.Updater = operatorID
if err := tx.Save(&shop).Error; err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "更新店铺失败")
}
parentName := ""
if shop.ParentID != nil {
var parent model.Shop
if err := tx.Select("shop_name").First(&parent, *shop.ParentID).Error; err == nil {
parentName = parent.ShopName
}
}
response = newShopResponse(&shop, parentName)
if err := fillBusinessOwnerResponse(tx, &shop, response); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return response, nil
}
func validateUpdatedBusinessOwner(tx *gorm.DB, requestedID *uint) (*uint, error) {
if requestedID == nil {
return nil, nil
}
if *requestedID == 0 {
return nil, errors.New(errors.CodeInvalidParam, "业务员账号无效")
}
var account model.Account
if err := tx.Clauses(clause.Locking{Strength: "SHARE"}).
Where("id = ? AND user_type = ? AND status = ?", *requestedID, constants.UserTypePlatform, constants.StatusEnabled).
First(&account).Error; err != nil {
return nil, errors.New(errors.CodeInvalidParam, "业务员账号无效或不可用")
}
ownerID := account.ID
return &ownerID, nil
}