Files
junhong_cmp_fiber/internal/handler/app/agent_distribution.go
break 6333f4ad13
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m57s
fix(代理分销注册): 校验手机号/用户名/店铺编号唯一性并支持驳回后重注册
- 提交写事务内先取事务级 advisory lock,再校验既有未删除账号/店铺与其它待审批申请:
  手机号 1014、用户名 1013、店铺编号 1031、待审批占用 1007,冲突不落库且不消费短信验证码
- 已驳回(含通过后撤销)与已通过的终态记录不阻塞重新注册,形成新记录与新审批实例
- 并发同关键字段提交串行裁决,同一关键字段至多一条待审批记录
- 审批通过建店建号前复检关键字段,冲突返回可定位错误并整体回滚,不再以裸数据库错误收场
- 归档 Change fix-agent-distribution-registration-duplicate-guard 并同步主 Spec

验证:junhong_cmp_test + Redis DB 6 受控脚手架 37 项通过 / 0 项失败(含 6 路并发仅 1 条落库、
审批冲突回滚与无冲突建店回归),清理后 fixture 残留 0;gofmt/go build/go vet 全绿;
openspec validate --all 35 项通过、doctor healthy、context-health 通过
2026-09-17 19:02:14 +08:00

72 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package app
import (
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
distributionapp "github.com/break/junhong_cmp_fiber/internal/application/distributionwithdrawal"
distributiondomain "github.com/break/junhong_cmp_fiber/internal/domain/distribution"
"github.com/break/junhong_cmp_fiber/internal/handler/validation"
"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/response"
)
// AgentDistributionHandler 代理分销扫码注册公开 Handler。
type AgentDistributionHandler struct {
service *distributionapp.RegistrationService
validator *validator.Validate
}
// NewAgentDistributionHandler 创建代理分销扫码注册公开 Handler。
func NewAgentDistributionHandler(
service *distributionapp.RegistrationService,
validate *validator.Validate,
) *AgentDistributionHandler {
return &AgentDistributionHandler{service: service, validator: validate}
}
// RegisterAgentDistribution 提交代理扫码注册
// POST /api/c/v1/agent-distribution-registrations
// 无需认证、JWT、角色或权限只创建待审批注册记录不返回任何账号凭证。
// 分销码无效、上级店铺停用、上级店铺缺少启用的主账号、短信验证码无效分别返回各自提示且不落库;
// 手机号、用户名或店铺编号与既有账号/店铺冲突时返回对应已存在错误,与其它待审批申请冲突时返回资源冲突;
// 短信验证码在注册记录落库成功后消费,落库前的失败(含关键字段冲突)不消耗验证码。
func (h *AgentDistributionHandler) RegisterAgentDistribution(c *fiber.Ctx) error {
if h.service == nil {
return errors.New(errors.CodeServiceUnavailable, "代理分销注册能力尚未配置")
}
var req dto.CreateAgentDistributionRegistrationReq
if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
}
if h.validator == nil {
return errors.New(errors.CodeInternalError, "代理分销注册校验器未配置")
}
if err := h.validator.Struct(&req); err != nil {
return errors.New(errors.CodeInvalidParam, validation.Message("注册参数不合法", &req, err))
}
result, err := h.service.Register(c.UserContext(), distributiondomain.RegistrationInput{
DistributionCode: req.DistributionCode,
Phone: req.Phone,
Username: req.Username,
Password: req.Password,
ShopName: req.ShopName,
ShopCode: req.ShopCode,
ContactName: req.ContactName,
Province: req.Province,
City: req.City,
District: req.District,
Address: req.Address,
}, req.Code)
if err != nil {
return err
}
return response.Success(c, &dto.CreateAgentDistributionRegistrationResp{
ID: result.RegistrationID,
Status: result.Status,
StatusName: constants.GetAgentDistributionRegistrationStatusName(result.Status),
})
}