Files
junhong_cmp_fiber/internal/model/dto/shop_dto.go
break 5ed6b39deb
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
feat(收口): 补齐 8 月迭代缺口并同步 Spec 与证据链
- 新增六对成对迁移 000232–000237:H5 弹窗类型、退款结算标识与申请人备注、优先轮询事实字段与两个新终态、通道阈值命中留痕、手机号最近解绑人、提现资格校验留痕
- 退款:原因必填与申请人备注、来源支付与渠道流水冻结、线下处理流水号补录审计、按订单查询可选退款方式、企微审批材料补齐且新增字段缺失映射即明确失败
- 优先轮询:人工关闭、有效期到期独立周期任务、失败与过期人工重触发、事实字段与异常重试查询、资产解析端点只读投影
- 通道阈值:命中事实同事务留痕与命中记录查询;员工账单:列表筛选与详情投影;商户池:列表投影与统计周期语义;H5:弹窗类型与类别排序
- 手机号:有效关联数量与最近解绑人、短信验证码失败次数限制;导出:佣金明细十五列与报表序号列
- 时间筛选:三处新增筛选纳入统一严格解析契约,员工账单产生时间参数改名
- 同步 12 份主 Spec 需求、两端点与异步任务证据链,门禁 context-health 与 OpenSpec 校验通过
2026-09-18 15:34:29 +08:00

199 lines
14 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 dto
import "github.com/bytedance/sonic"
type ShopListRequest struct {
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
ShopName string `json:"shop_name" query:"shop_name" validate:"omitempty,max=100" maxLength:"100" description:"店铺名称模糊查询"`
ShopCode string `json:"shop_code" query:"shop_code" validate:"omitempty,max=50" maxLength:"50" description:"店铺编号精确查询"`
ContactPhone string `json:"contact_phone" query:"contact_phone" validate:"omitempty,len=11,numeric,ascii" minLength:"11" maxLength:"11" pattern:"^[0-9]{11}$" description:"联系电话精确查询11位 ASCII 数字;空值不启用筛选;与其他条件按 AND 组合)"`
BusinessOwnerAccountID *uint `json:"business_owner_account_id" query:"business_owner_account_id" validate:"omitempty,min=1" minimum:"1" description:"平台业务员账号ID精确筛选"`
ParentID *uint `json:"parent_id" query:"parent_id" validate:"omitempty,min=1" minimum:"1" description:"上级店铺ID"`
Level *int `json:"level" query:"level" validate:"omitempty,min=1,max=7" minimum:"1" maximum:"7" description:"店铺层级 (1-7级)"`
Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1" description:"状态 (0:禁用, 1:启用)"`
BusinessUserGroupID *uint `json:"business_user_group_id" query:"business_user_group_id" validate:"omitempty,min=1" minimum:"1" description:"按业务用户组筛选,只匹配店铺当前负责人所属组;停用组同样可被筛出并携带已停用标记"`
BusinessLine *string `json:"business_line" query:"business_line" validate:"omitempty,oneof=standard smart other" enum:"standard,smart,other" description:"按负责人所属业务用户组的业务线筛选 (standard:标品, smart:智能产品, other:其他)"`
Ungrouped *bool `json:"ungrouped" query:"ungrouped" description:"按未分组筛选true 只返回无负责人或负责人无成员关系的店铺;负责人属于停用组的店铺不计入未分组"`
}
type CreateShopRequest struct {
ShopName string `json:"shop_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"店铺名称"`
ShopCode string `json:"shop_code" validate:"required,min=1,max=50" required:"true" minLength:"1" maxLength:"50" description:"店铺编号"`
ParentID *uint `json:"parent_id" validate:"omitempty,min=1" minimum:"1" description:"上级店铺ID一级店铺可不填"`
BusinessOwnerAccountID *uint `json:"business_owner_account_id" nullable:"true" description:"平台业务员账号ID缺失时继承上级null 表示空归属"`
BusinessOwnerAccountIDSet bool `json:"-"`
ContactName string `json:"contact_name" validate:"omitempty,max=50" maxLength:"50" description:"联系人姓名"`
ContactPhone string `json:"contact_phone" validate:"omitempty,len=11" minLength:"11" maxLength:"11" description:"联系人电话"`
Province string `json:"province" validate:"omitempty,max=50" maxLength:"50" description:"省份"`
City string `json:"city" validate:"omitempty,max=50" maxLength:"50" description:"城市"`
District string `json:"district" validate:"omitempty,max=50" maxLength:"50" description:"区县"`
Address string `json:"address" validate:"omitempty,max=255" maxLength:"255" description:"详细地址"`
DefaultRoleID uint `json:"default_role_id" validate:"required,min=1" required:"true" minimum:"1" description:"店铺默认角色ID必须是客户角色"`
InitPassword string `json:"init_password" validate:"required,min=8,max=32" required:"true" minLength:"8" maxLength:"32" description:"初始账号密码"`
InitUsername string `json:"init_username" validate:"required,min=3,max=50" required:"true" minLength:"3" maxLength:"50" description:"初始账号用户名"`
InitPhone string `json:"init_phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"初始账号手机号"`
}
// UnmarshalJSON 解析创建店铺请求并保留业务员字段“缺失”和“显式 null”的差异。
func (r *CreateShopRequest) UnmarshalJSON(data []byte) error {
type plain CreateShopRequest
var decoded plain
if err := sonic.Unmarshal(data, &decoded); err != nil {
return err
}
var fields map[string]any
if err := sonic.Unmarshal(data, &fields); err != nil {
return err
}
decoded.BusinessOwnerAccountIDSet = false
if _, exists := fields["business_owner_account_id"]; exists {
decoded.BusinessOwnerAccountIDSet = true
}
*r = CreateShopRequest(decoded)
return nil
}
type UpdateShopRequest struct {
ShopName string `json:"shop_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"店铺名称"`
BusinessOwnerAccountID *uint `json:"business_owner_account_id" nullable:"true" description:"平台业务员账号ID缺失时保持不变null 表示清空"`
BusinessOwnerAccountIDSet bool `json:"-"`
ContactName string `json:"contact_name" validate:"omitempty,max=50" maxLength:"50" description:"联系人姓名"`
ContactPhone string `json:"contact_phone" validate:"omitempty,len=11" minLength:"11" maxLength:"11" description:"联系人电话"`
Province string `json:"province" validate:"omitempty,max=50" maxLength:"50" description:"省份"`
City string `json:"city" validate:"omitempty,max=50" maxLength:"50" description:"城市"`
District string `json:"district" validate:"omitempty,max=50" maxLength:"50" description:"区县"`
Address string `json:"address" validate:"omitempty,max=255" maxLength:"255" description:"详细地址"`
Status int `json:"status" validate:"oneof=0 1" required:"true" description:"状态 (0:禁用, 1:启用)"`
ClientLoginDisabled *bool `json:"client_login_disabled" description:"是否禁止该店铺资产发起新的 C 端登录;不传保持不变"`
}
// UnmarshalJSON 解析更新店铺请求并保留业务员字段“缺失”和“显式 null”的差异。
func (r *UpdateShopRequest) UnmarshalJSON(data []byte) error {
type plain UpdateShopRequest
var decoded plain
if err := sonic.Unmarshal(data, &decoded); err != nil {
return err
}
var fields map[string]any
if err := sonic.Unmarshal(data, &fields); err != nil {
return err
}
decoded.BusinessOwnerAccountIDSet = false
if _, exists := fields["business_owner_account_id"]; exists {
decoded.BusinessOwnerAccountIDSet = true
}
*r = UpdateShopRequest(decoded)
return nil
}
// ShopResponse 店铺响应
type ShopResponse struct {
ID uint `json:"id" description:"店铺ID"`
ShopName string `json:"shop_name" description:"店铺名称"`
ShopCode string `json:"shop_code" description:"店铺编号"`
// DistributionCode 是创建时生成的全局唯一随机分销码,创建后不可修改。
// 该字段为只读;它是该店铺作为上级被扫码注册的唯一入口标识,二维码只编码该码。
DistributionCode string `json:"distribution_code" description:"分销码(全局唯一、创建后不可修改的只读随机码;该店铺作为上级被扫码注册的唯一入口标识)"`
ParentID *uint `json:"parent_id,omitempty" description:"上级店铺ID"`
ParentShopName string `json:"parent_shop_name,omitempty" description:"上级店铺名称"`
BusinessOwnerAccountID *uint `json:"business_owner_account_id" description:"平台业务员账号IDnull 表示未归属"`
BusinessOwnerUsername string `json:"business_owner_username" description:"平台业务员账号名"`
BusinessOwnerPhoneSummary string `json:"business_owner_phone_summary" description:"平台业务员手机号摘要(前三后四)"`
BusinessOwnerAvailable bool `json:"business_owner_available" description:"平台业务员当前是否可用于通知接收"`
// 店铺负责人业务用户组由当前负责人实时推导,店铺不保存组字段。
BusinessUserGroupID *uint `json:"business_user_group_id" description:"负责人当前所属业务用户组IDnull 表示未分组"`
BusinessUserGroupCode string `json:"business_user_group_code" description:"业务用户组稳定编码"`
BusinessUserGroupName string `json:"business_user_group_name" description:"业务用户组名称"`
BusinessUserGroupEnabled bool `json:"business_user_group_enabled" description:"业务用户组是否启用false 且组ID非空表示负责人属于已停用组"`
BusinessUserGroupBusinessLine string `json:"business_user_group_business_line" description:"业务用户组所属业务线 (standard:标品, smart:智能产品, other:其他),空字符串表示未设置"`
Level int `json:"level" description:"店铺层级 (1-7级)"`
ContactName string `json:"contact_name" description:"联系人姓名"`
ContactPhone string `json:"contact_phone" description:"联系人电话"`
Province string `json:"province" description:"省份"`
City string `json:"city" description:"城市"`
District string `json:"district" description:"区县"`
Address string `json:"address" description:"详细地址"`
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
StatusName string `json:"status_name" description:"状态名称(中文)"`
ClientLoginDisabled bool `json:"client_login_disabled" description:"是否禁止该店铺资产发起新的 C 端登录"`
// 直接下级代理数量为只读投影:未删除且上级店铺为该店铺的店铺数,无下级返回 0。
DownstreamAgentCount int64 `json:"downstream_agent_count" description:"直接下级代理数量(未删除且上级店铺标识等于该店铺的店铺数),无下级返回 0"`
CreatedAt string `json:"created_at" description:"创建时间"`
UpdatedAt string `json:"updated_at" description:"更新时间"`
}
// ShopPageResult 店铺分页响应
type ShopPageResult struct {
Items []ShopResponse `json:"items" description:"店铺列表"`
Total int64 `json:"total" description:"总记录数"`
Page int `json:"page" description:"当前页码"`
Size int `json:"size" description:"每页数量"`
}
// UpdateShopParams 更新店铺聚合参数 (用于文档生成)
type UpdateShopParams struct {
IDReq
UpdateShopRequest
}
// ShopCascadeRequest 店铺联级查询请求
type ShopCascadeRequest struct {
ShopName string `json:"shop_name" query:"shop_name" validate:"omitempty,max=100" maxLength:"100" description:"店铺名称(模糊查询)"`
ParentID *uint `json:"parent_id" query:"parent_id" validate:"omitempty,min=1" minimum:"1" description:"上级店铺ID不传则查询顶级店铺"`
ExcludeSelf bool `json:"exclude_self" query:"exclude_self" description:"是否排除当前账号自身店铺默认false"`
}
// ShopCascadeItem 联级查询结果项
type ShopCascadeItem struct {
ID uint `json:"id" description:"店铺ID"`
ShopName string `json:"shop_name" description:"店铺名称"`
HasChildren bool `json:"has_children" description:"是否有下级店铺"`
}
// ShopBusinessOwnerCandidateRequest 是平台业务员候选分页查询。
type ShopBusinessOwnerCandidateRequest struct {
Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=50" maxLength:"50" description:"用户名或手机号关键词"`
Page int `json:"page" query:"page" validate:"omitempty,min=1,max=10000" minimum:"1" maximum:"10000" description:"页码,默认 1"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量,默认 20最大 100"`
}
// ShopBusinessOwnerCandidate 是平台业务员候选最小投影。
type ShopBusinessOwnerCandidate struct {
ID uint `json:"id" description:"平台业务员账号ID"`
Username string `json:"username" description:"平台业务员账号名"`
PhoneSummary string `json:"phone_summary" description:"手机号摘要(前三后四)"`
}
// ShopBusinessOwnerCandidatePageResult 是平台业务员候选分页结果。
type ShopBusinessOwnerCandidatePageResult struct {
Items []ShopBusinessOwnerCandidate `json:"items" description:"候选账号列表"`
Total int64 `json:"total" description:"总数量"`
Page int `json:"page" description:"当前页码"`
Size int `json:"size" description:"每页数量"`
}
// UpdateShopCreditLimitRequest 调整既有店铺实际信用额度请求。
type UpdateShopCreditLimitRequest struct {
CreditEnabled *bool `json:"credit_enabled" validate:"required" required:"true" description:"是否启用实际信用额度"`
CreditLimit *int64 `json:"credit_limit" validate:"required,min=0" required:"true" minimum:"0" description:"实际信用额度关闭时必须为0"`
}
// UpdateShopCreditLimitParams 调整既有店铺实际信用额度参数。
type UpdateShopCreditLimitParams struct {
IDReq
UpdateShopCreditLimitRequest
}
// ShopCreditLimitResponse 店铺实际信用额度调整响应。
type ShopCreditLimitResponse struct {
ShopID uint `json:"shop_id" description:"店铺ID"`
WalletID uint `json:"wallet_id" description:"代理主钱包ID"`
Balance int64 `json:"balance" description:"账面余额(分)"`
FrozenBalance int64 `json:"frozen_balance" description:"冻结金额(分)"`
CreditEnabled bool `json:"credit_enabled" description:"是否启用实际信用额度"`
CreditLimit int64 `json:"credit_limit" description:"实际信用额度(分)"`
AvailableBalance int64 `json:"available_balance" description:"总可用金额(分)"`
Version int `json:"version" description:"更新后的主钱包版本"`
}