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:"备注"` 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:"每页数量"` } // SetBusinessUserGroupMembersRequest 批量设置平台用户业务用户组归属请求。 // 设置直接替换每个账号的原归属;任一账号不是启用平台用户或目标组未启用时整批不修改。 type SetBusinessUserGroupMembersRequest struct { AccountIDs []uint `json:"account_ids" validate:"required,min=1,dive,min=1" required:"true" description:"平台用户账号ID列表,至少一个;每个账号必须是启用平台用户"` } // ClearBusinessUserGroupMembersRequest 批量清空平台用户业务用户组归属请求。 type ClearBusinessUserGroupMembersRequest struct { AccountIDs []uint `json:"account_ids" validate:"required,min=1,dive,min=1" required:"true" description:"平台用户账号ID列表,至少一个;每个账号必须是启用平台用户"` } // BusinessUserGroupMemberRequest 业务用户组成员维护路径参数。 type BusinessUserGroupMemberRequest struct { ID uint `path:"id" 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 } // ClearBusinessUserGroupMembersParams 清空平台用户分组归属请求(用于 DELETE 显式请求体)。 type ClearBusinessUserGroupMembersParams struct { ClearBusinessUserGroupMembersRequest } // BusinessUserGroupMembersResult 成员维护结果。 type BusinessUserGroupMembersResult struct { GroupID uint `json:"group_id" description:"目标业务用户组ID;清空操作为 0"` AccountIDs []uint `json:"account_ids" description:"本次成功维护归属的平台用户账号ID列表"` } // BatchUpdateShopBusinessOwnerRequest 勾选店铺批量设置或清空负责人请求。 // 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:"逐行结果明细;任务级失败时为空数组"` }