Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 1h43m42s
- 迁移 000221:新增 tb_business_user_group、tb_business_user_group_member、tb_shop_business_owner_import_task,成员一账号一行由部分唯一索引保证,店铺所属组按当前负责人实时推导,不回填历史分组。 - 用户组 CRUD、成员改组/清空归属、店铺批量交接(原子失败不部分写入)。 - 店铺负责人 CSV 导入任务:逐行独立事务、逐行明细、任务级与行级失败分离。 - 读侧推导与筛选:未分组、业务线、停用组可筛出并带停用标记。 - 补齐操作审计动作与资源、openapi 清单、发布门禁巡检表清单。 - 归档 add-shop-salesperson-groups 变更并同步 openspec/specs/business-user-group,补齐 AUG26-003 验证证据链。
232 lines
7.5 KiB
Go
232 lines
7.5 KiB
Go
package admin
|
|
|
|
import (
|
|
"github.com/go-playground/validator/v10"
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
businessusergroupApp "github.com/break/junhong_cmp_fiber/internal/application/businessusergroup"
|
|
shopApp "github.com/break/junhong_cmp_fiber/internal/application/shop"
|
|
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
|
businessusergroupQuery "github.com/break/junhong_cmp_fiber/internal/query/businessusergroup"
|
|
"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/break/junhong_cmp_fiber/pkg/response"
|
|
)
|
|
|
|
// BusinessUserGroupHandler 业务用户组与店铺负责人批量交接处理器。
|
|
type BusinessUserGroupHandler struct {
|
|
service *businessusergroupApp.Service
|
|
query *businessusergroupQuery.Query
|
|
batchService *shopApp.BatchBusinessOwnerService
|
|
validator *validator.Validate
|
|
}
|
|
|
|
// NewBusinessUserGroupHandler 创建业务用户组处理器。
|
|
func NewBusinessUserGroupHandler(service *businessusergroupApp.Service, validator *validator.Validate) *BusinessUserGroupHandler {
|
|
return &BusinessUserGroupHandler{service: service, validator: validator}
|
|
}
|
|
|
|
// SetQuery 注入业务用户组读取投影。
|
|
func (h *BusinessUserGroupHandler) SetQuery(query *businessusergroupQuery.Query) {
|
|
h.query = query
|
|
}
|
|
|
|
// SetBatchService 注入店铺负责人批量交接事务脚本。
|
|
func (h *BusinessUserGroupHandler) SetBatchService(service *shopApp.BatchBusinessOwnerService) {
|
|
h.batchService = service
|
|
}
|
|
|
|
// Create 创建业务用户组。
|
|
// POST /api/admin/business-user-groups
|
|
func (h *BusinessUserGroupHandler) Create(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
var request dto.CreateBusinessUserGroupRequest
|
|
if err := c.BodyParser(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
|
}
|
|
if err := h.validate(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam)
|
|
}
|
|
result, err := h.service.Create(c.UserContext(), &request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return response.Success(c, result)
|
|
}
|
|
|
|
// List 查询业务用户组列表。
|
|
// GET /api/admin/business-user-groups
|
|
func (h *BusinessUserGroupHandler) List(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
var request dto.BusinessUserGroupListRequest
|
|
if err := c.QueryParser(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
|
}
|
|
if err := h.validate(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam)
|
|
}
|
|
if h.query == nil {
|
|
return errors.New(errors.CodeInternalError, "业务用户组查询尚未配置")
|
|
}
|
|
result, err := h.query.List(c.UserContext(), request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size)
|
|
}
|
|
|
|
// Detail 查询业务用户组详情。
|
|
// GET /api/admin/business-user-groups/:id
|
|
func (h *BusinessUserGroupHandler) Detail(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
id, err := pathID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if h.query == nil {
|
|
return errors.New(errors.CodeInternalError, "业务用户组查询尚未配置")
|
|
}
|
|
result, err := h.query.Detail(c.UserContext(), id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return response.Success(c, result)
|
|
}
|
|
|
|
// Update 更新业务用户组的名称、业务线、排序、启停与备注;编码不可修改。
|
|
// PUT /api/admin/business-user-groups/:id
|
|
func (h *BusinessUserGroupHandler) Update(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
id, err := pathID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var request dto.UpdateBusinessUserGroupRequest
|
|
if err := c.BodyParser(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
|
}
|
|
if err := h.validate(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam)
|
|
}
|
|
result, err := h.service.Update(c.UserContext(), id, &request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return response.Success(c, result)
|
|
}
|
|
|
|
// Delete 二次确认删除无成员的业务用户组。
|
|
// DELETE /api/admin/business-user-groups/:id
|
|
func (h *BusinessUserGroupHandler) Delete(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
id, err := pathID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var request dto.BusinessUserGroupDeleteRequest
|
|
if err := c.BodyParser(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
|
}
|
|
if !request.Confirm {
|
|
return errors.New(errors.CodeInvalidParam, "删除业务用户组必须二次确认")
|
|
}
|
|
if err := h.service.Delete(c.UserContext(), id); err != nil {
|
|
return err
|
|
}
|
|
return response.Success(c, nil)
|
|
}
|
|
|
|
// SetMembers 批量设置平台用户的业务用户组归属,直接替换原归属。
|
|
// PUT /api/admin/business-user-groups/:id/members
|
|
func (h *BusinessUserGroupHandler) SetMembers(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
id, err := pathID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var request dto.SetBusinessUserGroupMembersRequest
|
|
if err := c.BodyParser(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
|
}
|
|
if err := h.validate(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam)
|
|
}
|
|
result, err := h.service.SetMembers(c.UserContext(), id, &request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return response.Success(c, result)
|
|
}
|
|
|
|
// ClearMembers 批量清空平台用户的业务用户组归属。
|
|
// DELETE /api/admin/business-user-groups/members
|
|
func (h *BusinessUserGroupHandler) ClearMembers(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
var request dto.ClearBusinessUserGroupMembersRequest
|
|
if err := c.BodyParser(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
|
}
|
|
if err := h.validate(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam)
|
|
}
|
|
result, err := h.service.ClearMembers(c.UserContext(), &request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return response.Success(c, result)
|
|
}
|
|
|
|
// BatchUpdateShopBusinessOwner 勾选店铺批量设置或清空平台业务员负责人。
|
|
// PUT /api/admin/shops/business-owner/batch
|
|
func (h *BusinessUserGroupHandler) BatchUpdateShopBusinessOwner(c *fiber.Ctx) error {
|
|
if err := requirePlatformManagement(c); err != nil {
|
|
return err
|
|
}
|
|
var request dto.BatchUpdateShopBusinessOwnerRequest
|
|
if err := c.BodyParser(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
|
}
|
|
if err := h.validate(&request); err != nil {
|
|
return errors.New(errors.CodeInvalidParam)
|
|
}
|
|
if h.batchService == nil {
|
|
return errors.New(errors.CodeInternalError, "店铺负责人批量交接服务尚未配置")
|
|
}
|
|
result, err := h.batchService.Execute(c.UserContext(), &request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return response.Success(c, result)
|
|
}
|
|
|
|
func (h *BusinessUserGroupHandler) validate(request any) error {
|
|
if h.validator == nil {
|
|
return errors.New(errors.CodeInternalError)
|
|
}
|
|
return h.validator.Struct(request)
|
|
}
|
|
|
|
// requirePlatformManagement 校验调用者仅限超级管理员与平台账号,代理与企业统一返回 403。
|
|
func requirePlatformManagement(c *fiber.Ctx) error {
|
|
userType := middleware.GetUserTypeFromContext(c.UserContext())
|
|
if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform {
|
|
return errors.New(errors.CodeForbidden, constants.PlatformManagementForbiddenMessage)
|
|
}
|
|
return nil
|
|
}
|