All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m42s
273 lines
18 KiB
Go
273 lines
18 KiB
Go
package dto
|
||
|
||
import "github.com/bytedance/sonic"
|
||
|
||
// 业务用户组 DTO。
|
||
// 枚举说明:enabled 与 business_line 取值必须与 pkg/constants 的
|
||
// StatusDisabled/StatusEnabled 与 BusinessLineStandard/BusinessLineSmart/BusinessLineOther 保持一致。
|
||
|
||
// CreateBusinessUserGroupRequest 创建业务用户组请求。
|
||
type CreateBusinessUserGroupRequest struct {
|
||
Code string `json:"code" validate:"required,min=1,max=64" required:"true" minLength:"1" maxLength:"64" description:"业务用户组稳定编码,1-64 字符,未删除组内唯一,创建后不可修改"`
|
||
Name string `json:"name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"业务用户组名称,1-100 字符"`
|
||
BusinessLine string `json:"business_line" validate:"omitempty,oneof=standard smart other" enum:"standard,smart,other" description:"所属业务线 (standard:标品, smart:智能产品, other:其他),留空表示不设置"`
|
||
Sort *int64 `json:"sort" validate:"omitempty,min=0" minimum:"0" description:"排序值,非负整数,默认 0"`
|
||
Enabled *bool `json:"enabled" description:"是否启用,默认启用;停用后不得新增成员,也不得作为批量目标"`
|
||
Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注,最多 500 字符"`
|
||
}
|
||
|
||
// UpdateBusinessUserGroupRequest 更新业务用户组请求。
|
||
// 仅传入的字段被修改;稳定编码永不允许修改,本请求不提供该字段。
|
||
// business_line 传显式空字符串表示清空业务线。
|
||
type UpdateBusinessUserGroupRequest struct {
|
||
Name *string `json:"name" validate:"omitempty,min=1,max=100" minLength:"1" maxLength:"100" description:"业务用户组名称,1-100 字符"`
|
||
BusinessLine *string `json:"business_line" enum:"standard,smart,other" description:"所属业务线 (standard:标品, smart:智能产品, other:其他);字段缺失不修改,传空字符串清空;取值白名单在服务层校验"`
|
||
Sort *int64 `json:"sort" validate:"omitempty,min=0" minimum:"0" description:"排序值,非负整数"`
|
||
Enabled *bool `json:"enabled" description:"是否启用;停用后不得新增成员,已有成员关系保留并显示已停用"`
|
||
Remark *string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注,最多 500 字符"`
|
||
}
|
||
|
||
// BusinessUserGroupListRequest 查询业务用户组列表请求。
|
||
type BusinessUserGroupListRequest struct {
|
||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码,默认 1"`
|
||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量,默认 20,最大 100"`
|
||
Enabled *bool `json:"enabled" query:"enabled" description:"按启用状态过滤;不传返回全部"`
|
||
Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=100" maxLength:"100" description:"按稳定编码或名称模糊搜索,最多 100 字符"`
|
||
BusinessLine *string `json:"business_line" query:"business_line" validate:"omitempty,oneof=standard smart other" enum:"standard,smart,other" description:"按所属业务线过滤 (standard:标品, smart:智能产品, other:其他)"`
|
||
}
|
||
|
||
// BusinessUserGroupResponse 业务用户组响应。
|
||
type BusinessUserGroupResponse struct {
|
||
ID uint `json:"id" description:"业务用户组ID"`
|
||
Code string `json:"code" description:"业务用户组稳定编码,创建后不可修改"`
|
||
Name string `json:"name" description:"业务用户组名称"`
|
||
BusinessLine string `json:"business_line" description:"所属业务线 (standard:标品, smart:智能产品, other:其他),空字符串表示未设置"`
|
||
BusinessLineName string `json:"business_line_name" description:"所属业务线中文名称,未设置时为空字符串"`
|
||
Sort int64 `json:"sort" description:"排序值"`
|
||
Enabled bool `json:"enabled" description:"是否启用;停用后不得新增成员,也不得作为批量目标"`
|
||
Remark string `json:"remark" description:"备注"`
|
||
MemberCount int64 `json:"member_count" description:"当前保留成员关系数量,包含禁用或已删除账号"`
|
||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||
}
|
||
|
||
// BusinessUserGroupPageResult 业务用户组分页响应。
|
||
type BusinessUserGroupPageResult struct {
|
||
Items []*BusinessUserGroupResponse `json:"items" description:"业务用户组列表"`
|
||
Total int64 `json:"total" description:"总记录数"`
|
||
Page int `json:"page" description:"当前页码"`
|
||
Size int `json:"size" description:"每页数量"`
|
||
}
|
||
|
||
// BusinessUserGroupMemberListRequest 业务用户组成员分页查询请求。
|
||
type BusinessUserGroupMemberListRequest struct {
|
||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码,默认 1"`
|
||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量,默认 20,最大 100"`
|
||
Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=100" maxLength:"100" description:"按用户名或手机号模糊搜索,最多 100 字符"`
|
||
AccountStatus string `json:"account_status" query:"account_status" validate:"omitempty,oneof=enabled disabled deleted" enum:"enabled,disabled,deleted" description:"账号状态筛选 (enabled:启用, disabled:禁用, deleted:已删除)"`
|
||
}
|
||
|
||
// BusinessUserGroupMemberListParams 业务用户组成员分页查询路径与查询参数。
|
||
type BusinessUserGroupMemberListParams struct {
|
||
BusinessUserGroupMemberRequest
|
||
BusinessUserGroupMemberListRequest
|
||
}
|
||
|
||
// BusinessUserGroupMemberResponse 业务用户组成员响应。
|
||
type BusinessUserGroupMemberResponse struct {
|
||
AccountID uint `json:"account_id" description:"平台用户账号ID"`
|
||
Username string `json:"username" description:"平台用户用户名"`
|
||
Phone string `json:"phone" description:"脱敏手机号,仅保留前3位和后4位"`
|
||
Enabled bool `json:"enabled" description:"账号是否启用"`
|
||
StatusName string `json:"status_name" description:"账号启停状态名称"`
|
||
Deleted bool `json:"deleted" description:"账号是否已软删除"`
|
||
MemberCreatedAt string `json:"member_created_at" description:"成员关系创建时间"`
|
||
CurrentGroupID uint `json:"current_group_id" description:"当前业务用户组ID"`
|
||
CurrentGroupCode string `json:"current_group_code" description:"当前业务用户组稳定编码"`
|
||
CurrentGroupName string `json:"current_group_name" description:"当前业务用户组名称"`
|
||
CurrentGroupEnabled bool `json:"current_group_enabled" description:"当前业务用户组是否启用"`
|
||
}
|
||
|
||
// BusinessUserGroupMemberPageResult 业务用户组成员分页响应。
|
||
type BusinessUserGroupMemberPageResult struct {
|
||
Items []*BusinessUserGroupMemberResponse `json:"items" description:"成员列表"`
|
||
Total int64 `json:"total" description:"总记录数"`
|
||
Page int `json:"page" description:"当前页码"`
|
||
Size int `json:"size" description:"每页数量"`
|
||
}
|
||
|
||
// BusinessUserGroupMemberCandidateRequest 业务用户组成员候选分页查询请求。
|
||
type BusinessUserGroupMemberCandidateRequest struct {
|
||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码,默认 1"`
|
||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量,默认 20,最大 100"`
|
||
Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=100" maxLength:"100" description:"按用户名或脱敏手机号模糊搜索,最多 100 字符"`
|
||
GroupFilter string `json:"group_filter" query:"group_filter" validate:"omitempty,oneof=all ungrouped current other" enum:"all,ungrouped,current,other" description:"归属筛选 (all:全部, ungrouped:未分组, current:当前组, other:其他组)"`
|
||
}
|
||
|
||
// BusinessUserGroupMemberCandidateParams 业务用户组成员候选路径与查询参数。
|
||
type BusinessUserGroupMemberCandidateParams struct {
|
||
BusinessUserGroupMemberRequest
|
||
BusinessUserGroupMemberCandidateRequest
|
||
}
|
||
|
||
// BusinessUserGroupMemberCandidateResponse 业务用户组成员候选响应。
|
||
type BusinessUserGroupMemberCandidateResponse struct {
|
||
AccountID uint `json:"account_id" description:"平台用户账号ID"`
|
||
Username string `json:"username" description:"平台用户用户名"`
|
||
Phone string `json:"phone" description:"脱敏手机号,仅保留前3位和后4位"`
|
||
CurrentGroupID *uint `json:"current_group_id" description:"当前业务用户组ID,未分组时为空"`
|
||
CurrentGroupCode string `json:"current_group_code" description:"当前业务用户组稳定编码"`
|
||
CurrentGroupName string `json:"current_group_name" description:"当前业务用户组名称"`
|
||
CurrentGroupEnabled bool `json:"current_group_enabled" description:"当前业务用户组是否启用"`
|
||
Action string `json:"action" enum:"add,already_member,move" description:"稳定操作提示 (add:新增, already_member:已在目标组, move:迁入)"`
|
||
CanAdd bool `json:"can_add" description:"当前目标组是否允许新增成员"`
|
||
}
|
||
|
||
// BusinessUserGroupMemberCandidatePageResult 业务用户组成员候选分页响应。
|
||
type BusinessUserGroupMemberCandidatePageResult struct {
|
||
Items []*BusinessUserGroupMemberCandidateResponse `json:"items" description:"成员候选列表"`
|
||
Total int64 `json:"total" description:"总记录数"`
|
||
Page int `json:"page" description:"当前页码"`
|
||
Size int `json:"size" description:"每页数量"`
|
||
}
|
||
|
||
// AddBusinessUserGroupMembersRequest 增量增加业务用户组成员请求。
|
||
// account_ids 去重后必须非空,且全部是启用且未删除的平台用户账号。
|
||
type AddBusinessUserGroupMembersRequest struct {
|
||
AccountIDs []uint `json:"account_ids" validate:"required,min=1,dive,min=1" required:"true" description:"平台用户账号ID列表,去重后至少一个;全部必须是启用且未删除的平台用户"`
|
||
}
|
||
|
||
// RemoveBusinessUserGroupMembersRequest 组作用域增量移除成员请求。
|
||
type RemoveBusinessUserGroupMembersRequest struct {
|
||
AccountIDs []uint `json:"account_ids" validate:"required,min=1,dive,min=1" required:"true" description:"当前业务用户组成员账号ID列表,去重后至少一个;任一不属于目标组时整批拒绝"`
|
||
}
|
||
|
||
// BusinessUserGroupMemberRequest 业务用户组成员维护路径参数。
|
||
type BusinessUserGroupMemberRequest struct {
|
||
ID uint `json:"-" path:"id" validate:"required,min=1" required:"true" description:"业务用户组ID"`
|
||
}
|
||
|
||
// BusinessUserGroupDeleteRequest 业务用户组删除二次确认请求。
|
||
type BusinessUserGroupDeleteRequest struct {
|
||
Confirm bool `json:"confirm" validate:"required" required:"true" description:"确认删除,必须为 true;仅无成员的用户组可删除,有成员时只能停用或先移走成员"`
|
||
}
|
||
|
||
// BusinessUserGroupUpdateParams 更新业务用户组参数(路径参数 + 请求体,用于文档生成)。
|
||
type BusinessUserGroupUpdateParams struct {
|
||
IDReq
|
||
UpdateBusinessUserGroupRequest
|
||
}
|
||
|
||
// BusinessUserGroupDeleteParams 删除业务用户组参数(路径参数 + 二次确认,用于文档生成)。
|
||
type BusinessUserGroupDeleteParams struct {
|
||
IDReq
|
||
BusinessUserGroupDeleteRequest
|
||
}
|
||
|
||
// BusinessUserGroupMemberMutationResult 成员增量维护结果。
|
||
type BusinessUserGroupMemberMutationResult struct {
|
||
GroupID uint `json:"group_id" description:"目标业务用户组ID"`
|
||
AccountIDs []uint `json:"account_ids" description:"本次请求去重后的账号ID列表"`
|
||
RequestedCount int `json:"requested_count" description:"本次请求账号数"`
|
||
AddedCount int `json:"added_count" description:"实际新增成员数"`
|
||
AddedAccountIDs []uint `json:"added_account_ids" description:"实际新增成员账号ID集合"`
|
||
MovedCount int `json:"moved_count" description:"从其他组迁入的成员数"`
|
||
MovedAccountIDs []uint `json:"moved_account_ids" description:"从其他组迁入的成员账号ID集合"`
|
||
UnchangedCount int `json:"unchanged_count" description:"已在目标组而未变化的成员数"`
|
||
UnchangedAccountIDs []uint `json:"unchanged_account_ids" description:"已在目标组而未变化的成员账号ID集合"`
|
||
RemovedCount int `json:"removed_count" description:"实际移除成员数"`
|
||
RemovedAccountIDs []uint `json:"removed_account_ids" description:"实际移除成员账号ID集合"`
|
||
}
|
||
|
||
// business_owner_account_id 缺失时请求非法;显式 null 表示清空负责人。
|
||
type BatchUpdateShopBusinessOwnerRequest struct {
|
||
ShopIDs []uint `json:"shop_ids" validate:"required,min=1,max=500,dive,min=1" required:"true" minItems:"1" maxItems:"500" description:"店铺ID列表,至少一个且去重,最多 500 个"`
|
||
BusinessOwnerAccountID *uint `json:"business_owner_account_id" nullable:"true" description:"目标平台业务员账号ID;显式 null 表示清空负责人"`
|
||
BusinessOwnerAccountIDSet bool `json:"-"`
|
||
}
|
||
|
||
// UnmarshalJSON 解析批量交接请求并保留负责人字段「缺失」和「显式 null」的差异。
|
||
func (r *BatchUpdateShopBusinessOwnerRequest) UnmarshalJSON(data []byte) error {
|
||
type plain BatchUpdateShopBusinessOwnerRequest
|
||
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 = BatchUpdateShopBusinessOwnerRequest(decoded)
|
||
return nil
|
||
}
|
||
|
||
// BatchUpdateShopBusinessOwnerResult 勾选店铺批量交接结果。
|
||
type BatchUpdateShopBusinessOwnerResult struct {
|
||
BatchKey string `json:"batch_key" description:"批次标识,可用于审计关联时间线"`
|
||
ShopCount int `json:"shop_count" description:"本次成功变更的店铺数量"`
|
||
Cleared bool `json:"cleared" description:"本次是否为清空负责人操作"`
|
||
BusinessOwnerAccountID *uint `json:"business_owner_account_id" description:"目标平台业务员账号ID;清空时为 null"`
|
||
}
|
||
|
||
// CreateShopBusinessOwnerImportRequest 创建店铺负责人 CSV 导入任务请求。
|
||
type CreateShopBusinessOwnerImportRequest struct {
|
||
FileKey string `json:"file_key" validate:"required,min=1,max=500" required:"true" minLength:"1" maxLength:"500" description:"CSV 对象存储 Key,必须以 shop-imports/ 开头且扩展名为 .csv(通过 POST /api/admin/storage/upload-url 获取)"`
|
||
}
|
||
|
||
// ListShopBusinessOwnerImportRequest 查询店铺负责人导入任务列表请求。
|
||
type ListShopBusinessOwnerImportRequest struct {
|
||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码,默认 1"`
|
||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量,默认 20,最大 100"`
|
||
Status *int `json:"status" query:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:失败)"`
|
||
}
|
||
|
||
// GetShopBusinessOwnerImportRequest 店铺负责人导入任务详情路径参数。
|
||
type GetShopBusinessOwnerImportRequest struct {
|
||
ID uint `path:"id" required:"true" description:"导入任务ID"`
|
||
}
|
||
|
||
// ShopBusinessOwnerImportTaskResponse 店铺负责人导入任务响应。
|
||
type ShopBusinessOwnerImportTaskResponse struct {
|
||
ID uint `json:"id" description:"导入任务ID"`
|
||
TaskNo string `json:"task_no" description:"导入任务编号"`
|
||
FileName string `json:"file_name" description:"上传的源 CSV 文件名"`
|
||
Status int `json:"status" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:失败)"`
|
||
StatusName string `json:"status_name" description:"任务状态中文名称"`
|
||
TotalCount int `json:"total_count" description:"数据行总数;任务级失败时为 0"`
|
||
SuccessCount int `json:"success_count" description:"成功行数"`
|
||
FailCount int `json:"fail_count" description:"失败行数"`
|
||
ErrorMessage string `json:"error_message" description:"任务级失败原因;与行级失败原因分开记录"`
|
||
CreatorName string `json:"creator_name" description:"任务创建人名称快照"`
|
||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||
StartedAt string `json:"started_at" description:"开始处理时间"`
|
||
CompletedAt string `json:"completed_at" description:"完成时间"`
|
||
}
|
||
|
||
// ShopBusinessOwnerImportTaskPageResult 店铺负责人导入任务分页响应。
|
||
type ShopBusinessOwnerImportTaskPageResult struct {
|
||
Items []*ShopBusinessOwnerImportTaskResponse `json:"items" description:"导入任务列表"`
|
||
Total int64 `json:"total" description:"总记录数"`
|
||
Page int `json:"page" description:"当前页码"`
|
||
Size int `json:"size" description:"每页数量"`
|
||
}
|
||
|
||
// ShopBusinessOwnerImportItemResponse 店铺负责人导入逐行结果。
|
||
type ShopBusinessOwnerImportItemResponse struct {
|
||
Line int `json:"line" description:"行号,自数据首行起计(表头不计入)"`
|
||
ShopCode string `json:"shop_code" description:"店铺编码"`
|
||
OperationType string `json:"operation_type" description:"操作类型 (换绑/清空)"`
|
||
Status int `json:"status" description:"行状态 (3:成功, 4:失败)"`
|
||
StatusName string `json:"status_name" description:"行状态中文名称"`
|
||
Reason string `json:"reason" description:"失败原因;成功行为空"`
|
||
}
|
||
|
||
// ShopBusinessOwnerImportTaskDetailResponse 店铺负责人导入任务详情响应。
|
||
type ShopBusinessOwnerImportTaskDetailResponse struct {
|
||
ShopBusinessOwnerImportTaskResponse
|
||
Items []ShopBusinessOwnerImportItemResponse `json:"items" description:"逐行结果明细;任务级失败时为空数组"`
|
||
}
|