refactor: 重构资产实体和DTO结构类型

将gjson.Json类型替换为具体的结构体和map类型,修正DAO层链式调用,启用SKU元数据校验逻辑
This commit is contained in:
2026-03-22 20:08:32 +08:00
parent 34a1ba79b6
commit 829dc07747
36 changed files with 932 additions and 793 deletions

View File

@@ -5,6 +5,7 @@ import (
"assets/consts/stock"
"assets/model/config"
enumDto "assets/model/dto/enum"
entity "assets/model/entity/asset"
"gitea.com/red-future/common/beans"
"github.com/gogf/gf/v2/frame/g"
@@ -15,18 +16,18 @@ import (
type CreateAssetReq struct {
g.Meta `path:"/createAsset" method:"post" tags:"资产管理" summary:"创建资产" dc:"创建新的资产"`
// 基础信息
Name string `json:"name" v:"required" dc:"资产名称"`
Description string `json:"description" dc:"资产描述"`
Type consts.AssetType `json:"type" v:"required" dc:"资产类型physical实物/virtual虚拟/service服务"`
CategoryId int64 `json:"categoryId" v:"required" dc:"分类ID"`
CategoryPath string `json:"categoryPath" dc:"分类路径"`
ImageURL string `json:"imageUrl" dc:"主图URL"`
Images []string `json:"images" dc:"图片列表"`
Status consts.AssetStatusType `json:"status" dc:"状态1/0" d:"1"`
UnlimitedStock bool `json:"unlimitedStock" dc:"是否无库存限制"`
StockMode stock.StockMode `json:"stockMode" dc:"库存管理模式1-明细模式 2-批次模式" d:"2"`
OnlineTime *gtime.Time `json:"onlineTime,omitempty" dc:"上线时间格式2006-01-02 15:04:05"`
OfflineTime *gtime.Time `json:"offlineTime,omitempty" dc:"下线时间格式2006-01-02 15:04:05"`
Name string `json:"name" v:"required" dc:"资产名称"`
Description string `json:"description" dc:"资产描述"`
Type consts.AssetType `json:"type" v:"required" dc:"资产类型physical实物/virtual虚拟/service服务"`
CategoryId int64 `json:"categoryId" v:"required" dc:"分类ID"`
CategoryPath string `json:"categoryPath" dc:"分类路径"`
ImageURL string `json:"imageUrl" dc:"主图URL"`
Images []string `json:"images" dc:"图片列表"`
Status consts.AssetStatus `json:"status" dc:"状态1/0" d:"1"`
UnlimitedStock bool `json:"unlimitedStock" dc:"是否无库存限制"`
StockMode stock.StockMode `json:"stockMode" dc:"库存管理模式1-明细模式 2-批次模式" d:"2"`
OnlineTime *gtime.Time `json:"onlineTime,omitempty" dc:"上线时间格式2006-01-02 15:04:05"`
OfflineTime *gtime.Time `json:"offlineTime,omitempty" dc:"下线时间格式2006-01-02 15:04:05"`
// 类型专用配置 - 实物资产配置
PhysicalAssetConfig *config.PhysicalAssetConfig `json:"physicalAssetConfig"`
// 类型专用配置 - 服务资产配置
@@ -52,7 +53,7 @@ type ListAssetReq struct {
Type consts.AssetType `json:"type" dc:"资产类型"`
CategoryId int64 `json:"categoryId" dc:"分类ID"`
CategoryPath string `json:"categoryPath" dc:"分类路径"`
Status consts.AssetStatusType `json:"status" dc:"状态"`
Status consts.AssetStatus `json:"status" dc:"状态"`
TenantModuleType beans.TenantModuleType `json:"tenantModuleType" dc:"租户模块类型"`
Keyword string `json:"keyword" dc:"关键词搜索"`
}
@@ -64,18 +65,18 @@ type ListAssetRes struct {
}
type AssetItem struct {
Id int64 `json:"id"` // 资产ID
Name string `json:"name"` // 资产名称
Type consts.AssetType `json:"type"` // 资产类型physical实物/virtual虚拟/service服务
TypeName string `json:"typeName"` // 资产类型physical实物/virtual虚拟/service服务
CategoryId int64 `json:"categoryId"` // 分类ID
UnlimitedStock bool `json:"unlimitedStock"` // 是否无库存限制
Status consts.AssetStatusType `json:"status"` // 资产状态active启用/inactive停用
BasePrice int `json:"basePrice"` // 基础价格(分为单位)
OnlineTime *gtime.Time `json:"onlineTime,omitempty"` // 上线时间
OfflineTime *gtime.Time `json:"offlineTime,omitempty"` // 下线时间
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
Id int64 `json:"id,string"` // 资产ID
Name string `json:"name"` // 资产名称
Type consts.AssetType `json:"type"` // 资产类型physical实物/virtual虚拟/service服务
TypeName string `json:"typeName"` // 资产类型physical实物/virtual虚拟/service服务
CategoryId int64 `json:"categoryId,string"` // 分类ID
UnlimitedStock bool `json:"unlimitedStock"` // 是否无库存限制
Status consts.AssetStatus `json:"status"` // 资产状态active启用/inactive停用
BasePrice int `json:"basePrice"` // 基础价格(分为单位)
OnlineTime *gtime.Time `json:"onlineTime,omitempty"` // 上线时间
OfflineTime *gtime.Time `json:"offlineTime,omitempty"` // 下线时间
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
}
// GetAssetReq 获取资产详情请求
@@ -86,7 +87,7 @@ type GetAssetReq struct {
// GetAssetRes 获取资产详情响应
type GetAssetRes struct {
*AssetItem
*entity.Asset
CategoryName string `json:"categoryName" dc:"分类名称"`
ImgAddressPrefix string `json:"imgAddressPrefix"`
}
@@ -99,7 +100,7 @@ type GetAssetAndSkuReq struct {
// GetAssetAndSkuRes 获取资产详情响应
type GetAssetAndSkuRes struct {
*AssetItem
*entity.Asset
Skus []AssetSkuItem `json:"skus" dc:"SKU列表"`
TenantModuleType []enumDto.KeyValue `json:"tenantModuleType" dc:"租户模块类型"`
ImgAddressPrefix string `json:"imgAddressPrefix"`
@@ -108,16 +109,16 @@ type GetAssetAndSkuRes struct {
// UpdateAssetReq 更新资产请求
type UpdateAssetReq struct {
g.Meta `path:"/updateAsset" method:"put" tags:"资产管理" summary:"更新资产" dc:"更新资产信息"`
Id int64 `json:"id" v:"required" dc:"资产ID"`
Name string `json:"name" dc:"资产名称"`
Description string `json:"description" dc:"资产描述"`
Type consts.AssetType `json:"type" dc:"资产类型physical实物/virtual虚拟/service服务"`
CategoryId int64 `json:"categoryId" dc:"分类ID"`
ImageURL string `json:"imageUrl" dc:"主图URL"`
Images []string `json:"images" dc:"图片列表"`
Status consts.AssetStatusType `json:"status,omitempty" dc:"状态1/0"`
OnlineTime *gtime.Time `json:"onlineTime,omitempty" dc:"上线时间格式2006-01-02 15:04:05"`
OfflineTime *gtime.Time `json:"offlineTime,omitempty" dc:"下线时间格式2006-01-02 15:04:05"`
Id int64 `json:"id" v:"required" dc:"资产ID"`
Name string `json:"name" dc:"资产名称"`
Description string `json:"description" dc:"资产描述"`
Type consts.AssetType `json:"type" dc:"资产类型physical实物/virtual虚拟/service服务"`
CategoryId int64 `json:"categoryId" dc:"分类ID"`
ImageURL string `json:"imageUrl" dc:"主图URL"`
Images []string `json:"images" dc:"图片列表"`
Status consts.AssetStatus `json:"status,omitempty" dc:"状态1/0"`
OnlineTime *gtime.Time `json:"onlineTime,omitempty" dc:"上线时间格式2006-01-02 15:04:05"`
OfflineTime *gtime.Time `json:"offlineTime,omitempty" dc:"下线时间格式2006-01-02 15:04:05"`
// 类型专用配置 - 实物资产配置
PhysicalAssetConfig *config.PhysicalAssetConfig `json:"physicalAssetConfig"`
// 类型专用配置 - 服务资产配置
@@ -131,8 +132,8 @@ type UpdateAssetReq struct {
// UpdateAssetStatusReq 更新资产状态请求
type UpdateAssetStatusReq struct {
g.Meta `path:"/updateAssetStatus" method:"put" tags:"资产管理" summary:"更新资产状态" dc:"更新资产状态"`
Id int64 `json:"id" v:"required" dc:"资产ID"`
Status consts.AssetStatusType `json:"status" v:"required|in:1,0" dc:"状态1启用/0停用"`
Id int64 `json:"id" v:"required" dc:"资产ID"`
Status consts.AssetStatus `json:"status" v:"required|in:1,0" dc:"状态1启用/0停用"`
}
// DeleteAssetReq 删除资产请求

View File

@@ -23,7 +23,7 @@ type CreateAssetSkuReq struct {
ImageURL string `json:"imageUrl" v:"required" dc:"SKU主图"`
Price int `json:"price" v:"required|min:0" dc:"价格(分为单位)"`
Sort int `json:"sort" v:"required|min:0" dc:"排序"`
Status consts.AssetSkuStatusType `json:"status" v:"required|in:1,0" dc:"状态"`
Status consts.AssetSkuStatus `json:"status" v:"required|in:1,0" dc:"状态"`
UnlimitedStock bool `json:"unlimitedStock" v:"required" dc:"是否无库存限制"`
StockMode stock.StockMode `json:"stockMode" dc:"库存管理模式:1-明细模式 2-批次模式"`
CategoryId int64 `json:"categoryId" dc:"分类ID"`
@@ -49,7 +49,7 @@ type UpdateAssetSkuReq struct {
Price int `json:"price" dc:"价格(分为单位)"`
Sort int `json:"sort" dc:"排序"`
Stock int `json:"stock" dc:"库存数量"`
Status consts.AssetSkuStatusType `json:"status" dc:"状态"`
Status consts.AssetSkuStatus `json:"status" dc:"状态"`
}
// DeleteAssetSkuReq 删除SKU请求
@@ -86,13 +86,13 @@ type GetAssetSkuRes struct {
type ListAssetSkuReq struct {
g.Meta `path:"/listAssetSkus" method:"get" tags:"SKU管理" summary:"获取SKU列表" dc:"分页查询SKU列表支持多条件筛选"`
*beans.Page
Id int64 `json:"id" dc:"SKU ID"`
AssetId int64 `json:"assetId" v:"required" dc:"资产ID"`
Status consts.AssetSkuStatusType `json:"status" dc:"状态"`
Keyword string `json:"keyword" dc:"关键词搜索"`
MinPrice int `json:"minPrice" dc:"最低价格"`
MaxPrice int `json:"maxPrice" dc:"最高价格"`
CategoryPath string `json:"categoryPath" dc:"分类路径"`
Id int64 `json:"id" dc:"SKU ID"`
AssetId int64 `json:"assetId" v:"required" dc:"资产ID"`
Status consts.AssetSkuStatus `json:"status" dc:"状态"`
Keyword string `json:"keyword" dc:"关键词搜索"`
MinPrice int `json:"minPrice" dc:"最低价格"`
MaxPrice int `json:"maxPrice" dc:"最高价格"`
CategoryPath string `json:"categoryPath" dc:"分类路径"`
}
// ListAssetSkuRes 获取SKU列表响应
@@ -102,8 +102,8 @@ type ListAssetSkuRes struct {
}
type AssetSkuItem struct {
Id int64 `json:"id"` // SKU ID
AssetId int64 `json:"assetId"`
Id int64 `json:"id,string"` // SKU ID
AssetId int64 `json:"assetId,string"`
AssetName string `json:"assetName"` // 资产名称
SkuName string `json:"skuName"` // SKU名称
SpecsCount int `json:"specsCount"` // 规格数量
@@ -113,8 +113,9 @@ type AssetSkuItem struct {
UnlimitedStock bool `json:"unlimitedStock"` // 是否无库存限制
Stock int `json:"stock"` // 库存数量
Sort int `json:"sort"` // 排序
Status consts.AssetSkuStatusType `json:"status"` // 状态active/inactive/disabled
Status consts.AssetSkuStatus `json:"status"` // 状态active/inactive/disabled
StockMode stock.StockMode `json:"stockMode"` // 库存管理模式1-明细模式 2-批次模式
ImageURL string `json:"imageUrl"` // SKU主图
CreatedAt *gtime.Time `json:"createdAt"` // 创建时间
UpdatedAt *gtime.Time `json:"updatedAt"` // 更新时间
}

View File

@@ -12,15 +12,15 @@ import (
// CreateCategoryReq 创建分类请求
type CreateCategoryReq struct {
g.Meta `path:"/createCategory" method:"post" tags:"分类管理" summary:"创建分类" dc:"创建新的分类"`
Name string `json:"name" v:"required" dc:"分类名称"`
ParentId int64 `json:"parentId" dc:"父分类ID"`
IsLeafNode *bool `json:"isLeafNode" dc:"是否叶子节点"`
Image string `json:"image" dc:"分类图片"`
Sort int `json:"sort" dc:"排序"`
Path string `json:"path" dc:"分类路径"`
Level int `json:"level" dc:"分类层级"`
Status consts.CategoryStatusType `json:"status" v:"in:1,0" default:"1" dc:"状态1启用0禁用"`
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
Name string `json:"name" v:"required" dc:"分类名称"`
ParentId int64 `json:"parentId" dc:"父分类ID"`
IsLeafNode *bool `json:"isLeafNode" dc:"是否叶子节点"`
Image string `json:"image" dc:"分类图片"`
Sort int `json:"sort" dc:"排序"`
Path string `json:"path" dc:"分类路径"`
Level int `json:"level" dc:"分类层级"`
Status consts.CategoryStatus `json:"status" v:"in:1,0" default:"1" dc:"状态1启用0禁用"`
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
}
// CreateCategoryRes 创建分类响应
@@ -31,21 +31,21 @@ type CreateCategoryRes struct {
// UpdateCategoryReq 更新分类请求
type UpdateCategoryReq struct {
g.Meta `path:"/updateCategory" method:"put" tags:"分类管理" summary:"更新分类" dc:"更新分类信息"`
Id int64 `json:"id" v:"required" dc:"分类ID"`
Name string `json:"name" dc:"分类名称"`
ParentId int64 `json:"parentId" dc:"父分类ID"`
Image string `json:"image" dc:"分类图片"`
Sort int `json:"sort" dc:"排序"`
IsLeafNode *bool `json:"isLeafNode" dc:"是否叶子节点"`
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
Status consts.CategoryStatusType `json:"status" dc:"状态1启用0禁用"`
Id int64 `json:"id" v:"required" dc:"分类ID"`
Name string `json:"name" dc:"分类名称"`
ParentId int64 `json:"parentId" dc:"父分类ID"`
Image string `json:"image" dc:"分类图片"`
Sort int `json:"sort" dc:"排序"`
IsLeafNode *bool `json:"isLeafNode" dc:"是否叶子节点"`
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
Status consts.CategoryStatus `json:"status" dc:"状态1启用0禁用"`
}
// UpdateCategoryStatusReq 更新分类状态请求
type UpdateCategoryStatusReq struct {
g.Meta `path:"/updateCategoryStatus" method:"put" tags:"分类管理" summary:"更新分类状态" dc:"更新分类状态"`
Id int64 `json:"id" v:"required" dc:"分类ID"`
Status consts.CategoryStatusType `json:"status" v:"in:1,0" dc:"状态1启用0禁用"`
Id int64 `json:"id" v:"required" dc:"分类ID"`
Status consts.CategoryStatus `json:"status" v:"in:1,0" dc:"状态1启用0禁用"`
}
// DeleteCategoryReq 删除分类请求
@@ -67,26 +67,26 @@ type GetCategoryTreeRes struct {
// CategoryTreeNode 分类树节点
type CategoryTreeNode struct {
Id int64 `json:"id,string" dc:"分类ID"`
Name string `json:"name" dc:"分类名称"`
Level int `json:"level" dc:"分类层级"`
Type string `json:"type" dc:"分类类型"`
Path string `json:"path" dc:"分类路径"`
IsLeafNode bool `json:"isLeafNode" dc:"是否叶子节点"`
Status consts.CategoryStatusType `json:"status" dc:"状态"`
Sort int `json:"sort" dc:"排序"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
Children []*CategoryTreeNode `json:"children" dc:"子分类"`
Id int64 `json:"id,string" dc:"分类ID"`
Name string `json:"name" dc:"分类名称"`
Level int `json:"level" dc:"分类层级"`
Type string `json:"type" dc:"分类类型"`
Path string `json:"path" dc:"分类路径"`
IsLeafNode bool `json:"isLeafNode" dc:"是否叶子节点"`
Status consts.CategoryStatus `json:"status" dc:"状态"`
Sort int `json:"sort" dc:"排序"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
Children []*CategoryTreeNode `json:"children" dc:"子分类"`
}
// ListCategoryReq 获取分类列表请求
type ListCategoryReq struct {
g.Meta `path:"/listCategories" method:"get" tags:"分类管理" summary:"获取分类列表" dc:"获取分类列表"`
*beans.Page
ParentId int64 `json:"parentId" dc:"父分类ID"`
Status consts.CategoryStatusType `json:"status" dc:"状态1启用0禁用"`
Keyword string `json:"keyword" dc:"关键词搜索"`
ParentId int64 `json:"parentId" dc:"父分类ID"`
Status consts.CategoryStatus `json:"status" dc:"状态1启用0禁用"`
Keyword string `json:"keyword" dc:"关键词搜索"`
}
// ListCategoryRes 获取分类列表响应
@@ -103,18 +103,18 @@ type GetCategoryReq struct {
// GetCategoryRes 获取分类详情响应
type GetCategoryRes struct {
Id int64 `json:"id,string" dc:"分类ID"`
Name string `json:"name" dc:"分类名称"`
ParentId int64 `json:"parentId,string" dc:"父分类ID"`
Path string `json:"path" dc:"分类路径"`
Level int `json:"level" dc:"分类层级"`
IsLeafNode bool `json:"isLeafNode" dc:"是否叶子节点"`
Sort int `json:"sort" dc:"排序"`
Image string `json:"image" dc:"分类图片"`
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
Status consts.CategoryStatusType `json:"status" dc:"状态1启用0禁用"`
Creator string `json:"creator" dc:"创建人"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
Updater string `json:"updater" dc:"更新人"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
Id int64 `json:"id,string" dc:"分类ID"`
Name string `json:"name" dc:"分类名称"`
ParentId int64 `json:"parentId,string" dc:"父分类ID"`
Path string `json:"path" dc:"分类路径"`
Level int `json:"level" dc:"分类层级"`
IsLeafNode bool `json:"isLeafNode" dc:"是否叶子节点"`
Sort int `json:"sort" dc:"排序"`
Image string `json:"image" dc:"分类图片"`
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
Status consts.CategoryStatus `json:"status" dc:"状态1启用0禁用"`
Creator string `json:"creator" dc:"创建人"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
Updater string `json:"updater" dc:"更新人"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
}

View File

@@ -3,24 +3,11 @@ package dto
import (
"assets/consts/stock"
"gitea.com/red-future/common/beans"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"go.mongodb.org/mongo-driver/v2/bson"
)
// CommonResp 通用响应
type CommonResp struct {
Success bool `json:"success"` // 是否成功
Message string `json:"message"` // 消息
}
// --- 批次管理API相关结构 ---
// CreateBatchReq 创建批次请求
type CreateBatchReq struct {
g.Meta `path:"/createBatch" method:"post" tags:"库存批次管理" summary:"创建批次" dc:"创建新的库存批次"`
// CreateSockBatchReq 创建批次请求
type CreateSockBatchReq struct {
AssetId int64 `json:"assetId" v:"required" dc:"资产ID"`
AssetSkuId int64 `json:"assetSkuId" v:"required" dc:"SKU ID"`
BatchNo string `json:"batchNo" v:"required" dc:"批次号"`
@@ -33,58 +20,13 @@ type CreateBatchReq struct {
ExpiryWarningDate *gtime.Time `json:"expiryWarningDate" dc:"临期预警时间(格式:2006-01-02)"`
}
// CreateBatchRes 创建批次响应
type CreateBatchRes struct {
Id *bson.ObjectID `json:"id"` // 批次ID
}
// UpdateBatchReq 更新批次请求
type UpdateBatchReq struct {
g.Meta `path:"/updateBatch" method:"put" tags:"库存批次管理" summary:"更新批次" dc:"更新批次信息"`
type UpdateSockBatchReq struct {
Id int64 `json:"id" v:"required" dc:"批次ID"`
BatchQty int `json:"batchQty" v:"required|min:1" dc:"批次数量"`
AvailableQty int `json:"availableQty" v:"required|min:1" dc:"可用数量"`
}
// DeleteBatchReq 删除批次请求
type DeleteBatchReq struct {
g.Meta `path:"/deleteBatch" method:"delete" tags:"库存批次管理" summary:"删除批次" dc:"删除批次"`
Id *bson.ObjectID `json:"id" v:"required" dc:"批次ID"`
}
// GetBatchReq 获取批次详情请求
type GetBatchReq struct {
g.Meta `path:"/getBatch" method:"get" tags:"库存批次管理" summary:"获取批次详情" dc:"获取批次详情"`
Id *bson.ObjectID `json:"id" v:"required" dc:"批次ID"`
}
// GetBatchRes 获取批次详情响应
type GetBatchRes struct {
Id *bson.ObjectID `json:"id"`
AssetId *bson.ObjectID `json:"assetId"`
AssetSkuId *bson.ObjectID `json:"assetSkuId"`
BatchNo string `json:"batchNo"`
BatchQty int `json:"batchQty"`
AvailableQty int `json:"availableQty"`
Metadata []map[string]interface{} `json:"metadata"`
Status stock.BatchStatus `json:"status"`
ProductionDate *gtime.Time `json:"productionDate"`
ExpiryDate *gtime.Time `json:"expiryDate"`
ExpiryWarningDate *gtime.Time `json:"expiryWarningDate"`
}
// ListBatchReq 获取批次列表请求
type ListBatchReq struct {
g.Meta `path:"/listBatches" method:"get" tags:"库存批次管理" summary:"获取批次列表" dc:"分页查询批次列表"`
*beans.Page
OrderBy []beans.OrderBy `json:"orderBy" dc:"排序规则"`
AssetId *bson.ObjectID `json:"assetId" dc:"资产ID"`
AssetSkuId *bson.ObjectID `json:"assetSkuId" dc:"SKU ID"`
}
// ListBatchRes 获取批次列表响应
type ListBatchRes struct {
List []GetBatchRes `json:"list"`
Total int64 `json:"total"`
type GetSockBatchReq struct {
Id int64 `json:"id" v:"required" dc:"批次ID"`
BatchNo string `json:"batchNo" dc:"批次"`
}

View File

@@ -4,64 +4,25 @@ import (
"assets/consts/stock"
"gitea.com/red-future/common/beans"
"github.com/gogf/gf/v2/frame/g"
"go.mongodb.org/mongo-driver/v2/bson"
)
// GetStockDetailsReq 获取库存明细详情请求
type GetStockDetailsReq struct {
g.Meta `path:"/getStockDetails" method:"get" tags:"库存明细管理" summary:"获取库存明细详情" dc:"获取库存明细详情"`
Id *bson.ObjectID `json:"id" v:"required" dc:"库存明细ID"`
// CreateSockDetailsReq 创建明细请求
type CreateSockDetailsReq struct {
AssetId int64 `json:"assetId" v:"required" dc:"资产ID"`
AssetSkuId int64 `json:"assetSkuId" v:"required" dc:"SKU ID"`
Status stock.StockStatus `json:"status" dc:"状态"`
Metadata []map[string]interface{} `json:"metadata" dc:"元数据"`
}
// GetStockDetailsRes 获取库存明细详情响应
type GetStockDetailsRes struct {
Id *bson.ObjectID `json:"id"`
AssetId *bson.ObjectID `json:"assetId"`
AssetSkuId *bson.ObjectID `json:"assetSkuId"`
Status stock.StockStatus `json:"status"`
OrderId *bson.ObjectID `json:"orderId"`
LockExpire string `json:"lockExpire"`
Metadata map[string]interface{} `json:"metadata"`
TokenId string `json:"tokenId"`
AssignedChannel string `json:"assignedChannel"`
ChannelSKU string `json:"channelSku"`
AllocatedAt string `json:"allocatedAt"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
type DeleteSockDetailsReq struct {
Id int64 `json:"Id" v:"required" dc:"库存明细ID"`
}
// ListStockDetailsReq 获取库存明细列表请求
type ListStockDetailsReq struct {
g.Meta `path:"/listStockDetails" method:"get" tags:"库存明细管理" summary:"获取库存明细列表" dc:"分页查询库存明细列表,支持多条件筛选"`
type GetSockDetailsReq struct {
*beans.Page
OrderBy []beans.OrderBy `json:"orderBy" dc:"排序规则"`
Id int64 `json:"id" dc:"库存明细ID"`
AssetId int64 `json:"assetId" dc:"资产ID"`
AssetSkuId int64 `json:"assetSkuId" dc:"SKU ID"`
CategoryPath string `json:"categoryPath" dc:"分类路径"`
Status stock.StockStatus `json:"status" dc:"状态"`
}
// ListStockDetailsRes 获取库存明细列表响应
type ListStockDetailsRes struct {
List []*StockDetailsListItem `json:"list" dc:"库存明细列表"`
Total int64 `json:"total" dc:"总数"`
}
// StockDetailsListItem 库存明细列表项
type StockDetailsListItem struct {
Id *bson.ObjectID `json:"id"`
AssetId *bson.ObjectID `json:"assetId"`
AssetSkuId *bson.ObjectID `json:"assetSkuId"`
Status stock.StockStatus `json:"status"`
OrderId *bson.ObjectID `json:"orderId"`
LockExpire string `json:"lockExpire"`
Metadata map[string]interface{} `json:"metadata"`
TokenId *bson.ObjectID `json:"tokenId"`
AssignedChannel string `json:"assignedChannel"`
ChannelSKU string `json:"channelSku"`
AllocatedAt string `json:"allocatedAt"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}

View File

@@ -29,8 +29,8 @@ type StockPublishMessage struct {
StockCount int `json:"stockCount"`
OperationType string `json:"operationType"`
Metadata []map[string]interface{} `json:"metadata"`
StockId string `json:"stockId"`
StockMode int `json:"stockMode"`
StockId int64 `json:"stockId"`
StockMode stock.StockMode `json:"stockMode"`
BatchNo string `json:"batchNo"`
ProductionDate *gtime.Time `json:"productionDate"`
ExpiryDate *gtime.Time `json:"expiryDate"`

View File

@@ -3,9 +3,9 @@ package entity
import (
consts "assets/consts/asset"
"assets/consts/stock"
"assets/model/config"
"gitea.com/red-future/common/beans"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
@@ -59,29 +59,29 @@ var AssetCol = assetCol{
type Asset struct {
beans.SQLBaseDO `orm:",inherit"`
// 基础信息
Name string `orm:"name" json:"name" description:"资产名称"`
Description string `orm:"description" json:"description" description:"资产描述"`
Type consts.AssetType `orm:"type" json:"type" description:"资产类型physical实物/virtual虚拟/service服务"`
CategoryId int64 `orm:"category_id" json:"categoryId" description:"分类ID"`
CategoryPath string `orm:"category_path" json:"categoryPath" description:"分类路径"`
ImageURL string `orm:"image_url" json:"imageUrl" description:"主图URL"`
Images []string `orm:"images" json:"images" description:"图片列表(JSONB)"`
Status consts.AssetStatusType `orm:"status" json:"status" description:"资产状态1启用/0停用"`
BasePrice int `orm:"base_price" json:"basePrice" description:"基础价格(分为单位)"`
Currency string `orm:"currency" json:"currency" description:"货币单位默认CNY"`
UnlimitedStock bool `orm:"unlimited_stock" json:"unlimitedStock" description:"是否无库存限制"`
StockMode stock.StockMode `orm:"stock_mode" json:"stockMode" description:"库存管理模式1-明细模式 2-批次模式"`
OnlineTime *gtime.Time `orm:"online_time" json:"onlineTime,omitempty" description:"上线时间"` // 上线和下线时间配置(由定时任务处理资产状态)
OfflineTime *gtime.Time `orm:"offline_time" json:"offlineTime,omitempty" description:"下线时间"` // 上线和下线时间配置(由定时任务处理资产状态)
Name string `orm:"name" json:"name" description:"资产名称"`
Description string `orm:"description" json:"description" description:"资产描述"`
Type consts.AssetType `orm:"type" json:"type" description:"资产类型physical实物/virtual虚拟/service服务"`
CategoryId int64 `orm:"category_id" json:"categoryId,string" description:"分类ID"`
CategoryPath string `orm:"category_path" json:"categoryPath" description:"分类路径"`
ImageURL string `orm:"image_url" json:"imageUrl" description:"主图URL"`
Images []string `orm:"images" json:"images" description:"图片列表(JSONB)"`
Status consts.AssetStatus `orm:"status" json:"status" description:"资产状态1启用/0停用"`
BasePrice int `orm:"base_price" json:"basePrice" description:"基础价格(分为单位)"`
Currency string `orm:"currency" json:"currency" description:"货币单位默认CNY"`
UnlimitedStock bool `orm:"unlimited_stock" json:"unlimitedStock" description:"是否无库存限制"`
StockMode stock.StockMode `orm:"stock_mode" json:"stockMode" description:"库存管理模式1-明细模式 2-批次模式"`
OnlineTime *gtime.Time `orm:"online_time" json:"onlineTime,omitempty" description:"上线时间"` // 上线和下线时间配置(由定时任务处理资产状态)
OfflineTime *gtime.Time `orm:"offline_time" json:"offlineTime,omitempty" description:"下线时间"` // 上线和下线时间配置(由定时任务处理资产状态)
// 类型专用配置 - 实物资产配置(JSONB)
PhysicalAssetConfig *gjson.Json `orm:"physical_asset_config" json:"physicalAssetConfig" description:"实物资产配置(JSONB)"`
PhysicalAssetConfig *config.PhysicalAssetConfig `orm:"physical_asset_config" json:"physicalAssetConfig" description:"实物资产配置(JSONB)"`
// 类型专用配置 - 服务资产配置(JSONB)
ServiceAssetConfig *gjson.Json `orm:"service_asset_config" json:"serviceAssetConfig" description:"服务资产配置(JSONB)"`
ServiceAssetConfig *config.ServiceAssetConfig `orm:"service_asset_config" json:"serviceAssetConfig" description:"服务资产配置(JSONB)"`
// 类型专用配置 - 虚拟资产配置(JSONB)
VirtualAssetConfig *gjson.Json `orm:"virtual_asset_config" json:"virtualAssetConfig" description:"虚拟资产配置(JSONB)"`
VirtualAssetConfig *config.VirtualAssetConfig `orm:"virtual_asset_config" json:"virtualAssetConfig" description:"虚拟资产配置(JSONB)"`
// 扩展字段(JSONB)
Metadata []gjson.Json `orm:"metadata" json:"metadata" description:"动态元数据(JSONB)"`
Metadata []map[string]interface{} `orm:"metadata" json:"metadata" description:"动态元数据(JSONB)"`
TenantModuleType beans.TenantModuleType `orm:"tenant_module_type" json:"tenantModuleType" description:"租户模块类型"`
}

View File

@@ -3,77 +3,75 @@ package entity
import (
consts "assets/consts/asset"
"assets/consts/stock"
"assets/model/config"
"gitea.com/red-future/common/beans"
"github.com/gogf/gf/v2/encoding/gjson"
)
type assetSkuCol struct {
beans.SQLBaseCol
AssetId string
AssetName string
SkuName string
ImageURL string
SpecValues string
Price string
UnlimitedStock string
Stock string
SpecsCount string
SpecsUnit string
Sort string
Status string
StockMode string
CategoryId string
CategoryPath string
CapacityUnitType string
Capacity string
AssetId string
AssetName string
SkuName string
ImageURL string
SpecValues string
Price string
UnlimitedStock string
Stock string
SpecsCount string
SpecsUnit string
Sort string
Status string
StockMode string
CategoryId string
CategoryPath string
//CapacityUnitType string
//Capacity string
TenantModuleType string
}
var AssetSkuCol = assetSkuCol{
SQLBaseCol: beans.DefSQLBaseCol,
AssetId: "asset_id",
AssetName: "asset_name",
SkuName: "sku_name",
ImageURL: "image_url",
SpecValues: "spec_values",
Price: "price",
UnlimitedStock: "unlimited_stock",
Stock: "stock",
SpecsCount: "specs_count",
SpecsUnit: "specs_unit",
Sort: "sort",
Status: "status",
StockMode: "stock_mode",
CategoryId: "category_id",
CategoryPath: "category_path",
CapacityUnitType: "capacity_unit_type",
Capacity: "capacity",
SQLBaseCol: beans.DefSQLBaseCol,
AssetId: "asset_id",
AssetName: "asset_name",
SkuName: "sku_name",
ImageURL: "image_url",
SpecValues: "spec_values",
Price: "price",
UnlimitedStock: "unlimited_stock",
Stock: "stock",
SpecsCount: "specs_count",
SpecsUnit: "specs_unit",
Sort: "sort",
Status: "status",
StockMode: "stock_mode",
CategoryId: "category_id",
CategoryPath: "category_path",
//CapacityUnitType: "capacity_unit_type",
//Capacity: "capacity",
TenantModuleType: "tenant_module_type",
}
// AssetSku 资产SKU实体
type AssetSku struct {
beans.SQLBaseDO `orm:",inherit"`
AssetId int64 `orm:"asset_id" json:"assetId"` // 关联资产ID
AssetName string `orm:"asset_name" json:"assetName"` // 资产名称
SkuName string `orm:"sku_name" json:"skuName"` // SKU名称
ImageURL string `orm:"image_url,omitempty" json:"imageUrl"` // SKU主图
SpecValues []gjson.Json `orm:"spec_values" json:"specValues"` // 规格值:{"颜色":"红色","尺寸":"L","时长":"1个月","平台":"抖音"}
Price int `orm:"price" json:"price"` // 价格(分为单位)
UnlimitedStock bool `orm:"unlimited_stock" json:"unlimitedStock"` // 是否无库存限制
Stock int `orm:"stock" json:"stock"` // 库存数量
SpecsCount int `orm:"specs_count" json:"specsCount"` // 规格数量
SpecsUnit *gjson.Json `orm:"specs_unit" json:"specsUnit"` // 规格单位 SpecsUnitKeyValue
Sort int `orm:"sort" json:"sort"` // 排序
Status consts.AssetSkuStatusType `orm:"status" json:"status"` // 状态active/inactive/disabled
StockMode stock.StockMode `orm:"stock_mode" json:"stockMode"` // 库存管理模式1-明细模式 2-批次模式
CategoryId int64 `orm:"category_id" json:"categoryId"` // 分类ID
CategoryPath string `orm:"category_path" json:"categoryPath"` // 分类路径
CapacityUnitType stock.CapacityUnitType `orm:"capacity_unit_type" json:"capacityUnitType"` // 容量单位类型
Capacity config.Capacity `orm:"capacity" json:"capacity"` // 容量
TenantModuleType beans.TenantModuleType `orm:"tenant_module_type" json:"tenantModuleType"` // 租户模块类型
beans.SQLBaseDO `orm:",inherit"`
AssetId int64 `orm:"asset_id" json:"assetId"` // 关联资产ID
AssetName string `orm:"asset_name" json:"assetName"` // 资产名称
SkuName string `orm:"sku_name" json:"skuName"` // SKU名称
ImageURL string `orm:"image_url,omitempty" json:"imageUrl"` // SKU主图
SpecValues []map[string]interface{} `orm:"spec_values" json:"specValues"` // 规格值:{"颜色":"红色","尺寸":"L","时长":"1个月","平台":"抖音"}
Price int `orm:"price" json:"price"` // 价格(分为单位)
UnlimitedStock bool `orm:"unlimited_stock" json:"unlimitedStock"` // 是否无库存限制
Stock int `orm:"stock" json:"stock"` // 库存数量
SpecsCount int `orm:"specs_count" json:"specsCount"` // 规格数量
SpecsUnit *SpecsUnitKeyValue `orm:"specs_unit" json:"specsUnit"` // 规格单位 SpecsUnitKeyValue
Sort int `orm:"sort" json:"sort"` // 排序
Status consts.AssetSkuStatus `orm:"status" json:"status"` // 状态active/inactive/disabled
StockMode stock.StockMode `orm:"stock_mode" json:"stockMode"` // 库存管理模式1-明细模式 2-批次模式
CategoryId int64 `orm:"category_id" json:"categoryId"` // 分类ID
CategoryPath string `orm:"category_path" json:"categoryPath"` // 分类路径
//CapacityUnitType stock.CapacityUnitType `orm:"capacity_unit_type" json:"capacityUnitType"` // 容量单位类型
//Capacity int `orm:"capacity" json:"capacity"` // 容量
TenantModuleType beans.TenantModuleType `orm:"tenant_module_type" json:"tenantModuleType"` // 租户模块类型
}
type SpecsUnitKeyValue struct {

View File

@@ -35,15 +35,15 @@ var CategoryCol = categoryCol{
// Category 分类实体
type Category struct {
beans.SQLBaseDO `orm:",inherit"`
Name string `orm:"name" json:"name"` // 分类名称
ParentId int64 `orm:"parent_id" json:"parentId"` // 父分类ID为空表示根分类
Path string `orm:"path" json:"path"` // 分类路径,如:/root/parent/child
Level int `orm:"level" json:"level"` // 分类层级
IsLeafNode *bool `orm:"is_leaf_node" json:"isLeafNode"` // 是叶子节点
Sort int `orm:"sort" json:"sort"` // 排序
Image string `orm:"image" json:"image"` // 分类图片
Status consts.CategoryStatusType `orm:"status" json:"status"` // 状态1启用/0禁用
Attrs []CategoryAttr `orm:"attrs" json:"attrs,omitempty"` // 分类属性 CategoryAttr
Name string `orm:"name" json:"name"` // 分类名称
ParentId int64 `orm:"parent_id" json:"parentId"` // 父分类ID为空表示根分类
Path string `orm:"path" json:"path"` // 分类路径,如:/root/parent/child
Level int `orm:"level" json:"level"` // 分类层级
IsLeafNode *bool `orm:"is_leaf_node" json:"isLeafNode"` // 是叶子节点
Sort int `orm:"sort" json:"sort"` // 排序
Image string `orm:"image" json:"image"` // 分类图片
Status consts.CategoryStatus `orm:"status" json:"status"` // 状态1启用/0禁用
Attrs []CategoryAttr `orm:"attrs" json:"attrs,omitempty"` // 分类属性 CategoryAttr
// 使用场景说明:
// 1. 商品分类属性:为该分类下的商品定义标准化的属性模板,如服装分类可定义尺寸、颜色、材质等属性
// 2. 服务分类属性:为服务类目定义特性参数,如咨询服务可定义服务时长、服务方式、专业领域等

View File

@@ -1,48 +1,80 @@
package entity
import (
"assets/consts/public"
"assets/consts/stock"
"gitea.com/red-future/common/beans"
"github.com/gogf/gf/v2/os/gtime"
"go.mongodb.org/mongo-driver/v2/bson"
)
type stockBatchCol struct {
beans.SQLBaseCol
AssetId string
AssetSkuId string
BatchNo string
BatchQty string
AvailableQty string
Metadata string
Status string
OrderId string
AssignedChannel string
ChannelSKU string
ChannelMetadata string
AllocatedAt string
ProductionDate string
ExpiryDate string
ExpiryWarningDate string
CategoryPath string
}
var StockBatchCol = stockBatchCol{
SQLBaseCol: beans.DefSQLBaseCol,
AssetId: "asset_id",
AssetSkuId: "asset_sku_id",
BatchNo: "batch_no",
BatchQty: "batch_qty",
AvailableQty: "available_qty",
Metadata: "metadata",
Status: "status",
OrderId: "order_id",
AssignedChannel: "assigned_channel",
ChannelSKU: "channel_sku",
ChannelMetadata: "channel_metadata",
AllocatedAt: "allocated_at",
ProductionDate: "production_date",
ExpiryDate: "expiry_date",
ExpiryWarningDate: "expiry_warning_date",
CategoryPath: "category_path",
}
// StockBatch 库存批次实体(用于批次管理模式)
type StockBatch struct {
beans.MongoBaseDO `bson:",inline"` // 嵌入基础字段Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
AssetID *bson.ObjectID `bson:"assetId" json:"assetId"` // 关联资产ID
AssetSkuID *bson.ObjectID `bson:"assetSkuId" json:"assetSkuId"` // 关联资产SKU ID
BatchNo string `bson:"batchNo" json:"batchNo"` // 批次
BatchQty int `bson:"batchQty" json:"batchQty"` // 批次总数量(入库后不可变
AvailableQty int `bson:"availableQty" json:"availableQty"` // 可用数量(实时变化)
beans.SQLBaseDO `orm:",inherit"`
AssetId int64 `orm:"asset_id" json:"assetId"` // 关联资产ID
AssetSkuId int64 `orm:"asset_sku_id" json:"assetSkuId"` // 关联资产SKU ID
BatchNo string `orm:"batch_no" json:"batchNo"` // 批次号
BatchQty int `orm:"batch_qty" json:"batchQty"` // 批次总数量(入库后不可变)
AvailableQty int `orm:"available_qty" json:"availableQty"` // 可用数量(实时变化
// 批次元数据
Metadata []map[string]interface{} `bson:"metadata" json:"metadata"` // 其他元数据
Metadata []map[string]interface{} `orm:"metadata" json:"metadata"` // 其他元数据
// 状态
Status *stock.BatchStatus `bson:"status" json:"status"` // 批次状态
Status stock.BatchStatus `orm:"status" json:"status"` // 批次状态
// 锁定数量 = BatchQty - AvailableQty
// 订单关联
OrderID *bson.ObjectID `bson:"orderId" json:"orderId"` // 关联订单ID如果有
OrderID int64 `orm:"order_id" json:"orderId"` // 关联订单ID如果有
// 渠道分配信息
AssignedChannel string `bson:"assignedChannel" json:"assignedChannel"` // 分配的销售渠道
ChannelSKU string `bson:"channelSku" json:"channelSku"` // 渠道商品SKU
ChannelMetadata map[string]interface{} `bson:"channelMetadata" json:"channelMetadata"` // 渠道专属数据
AllocatedAt *gtime.Time `bson:"allocatedAt" json:"allocatedAt"` // 分配时间
AssignedChannel string `orm:"assigned_channel" json:"assignedChannel"` // 分配的销售渠道
ChannelSKU string `orm:"channel_sku" json:"channelSku"` // 渠道商品SKU
ChannelMetadata map[string]interface{} `orm:"channel_metadata" json:"channelMetadata"` // 渠道专属数据
AllocatedAt *gtime.Time `orm:"allocated_at" json:"allocatedAt"` // 分配时间
// 临期管理
ProductionDate *gtime.Time `bson:"productionDate" json:"productionDate"` // 生产日期
ExpiryDate *gtime.Time `bson:"expiryDate" json:"expiryDate"` // 过期日期
ExpiryWarningDate *gtime.Time `bson:"expiryWarningDate" json:"expiryWarningDate"` // 临期预警时间(有过期日期时建议填写)
CategoryPath string `bson:"categoryPath" json:"categoryPath"` // 分类路径
}
// CollectionName 获取集合名称
func (StockBatch) CollectionName() string {
return public.StockBatchCollection
ProductionDate *gtime.Time `orm:"production_date" json:"productionDate"` // 生产日期
ExpiryDate *gtime.Time `orm:"expiry_date" json:"expiryDate"` // 过期日期
ExpiryWarningDate *gtime.Time `orm:"expiry_warning_date" json:"expiryWarningDate"` // 临期预警时间(有过期日期时建议填写)
CategoryPath string `orm:"category_path" json:"categoryPath"` // 分类路径
}

View File

@@ -1,35 +1,59 @@
package entity
import (
"assets/consts/public"
"assets/consts/stock"
"gitea.com/red-future/common/beans"
"github.com/gogf/gf/v2/os/gtime"
"go.mongodb.org/mongo-driver/v2/bson"
)
type stockDetailsCol struct {
beans.SQLBaseCol
AssetId string
AssetSkuId string
Status string
OrderId string
LockExpire string
Metadata string
TokenId string
AssignedChannel string
ChannelSKU string
ChannelMetadata string
AllocatedAt string
CategoryPath string
}
var StockDetailsCol = stockDetailsCol{
SQLBaseCol: beans.DefSQLBaseCol,
AssetId: "asset_id",
AssetSkuId: "asset_sku_id",
Status: "status",
OrderId: "order_id",
LockExpire: "lock_expire",
Metadata: "metadata",
TokenId: "token_id",
AssignedChannel: "assigned_channel",
ChannelSKU: "channel_sku",
ChannelMetadata: "channel_metadata",
AllocatedAt: "allocated_at",
CategoryPath: "category_path",
}
// StockDetails 库存实体每一件商品都有独立ID用于后期做区块链虚拟资产
type StockDetails struct {
beans.MongoBaseDO `bson:",inline"` // 嵌入基础字段Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
AssetId int64 `bson:"assetId" json:"assetId"` // 关联资产ID
AssetSkuId int64 `bson:"assetSkuId" json:"assetSkuId"` // 关联资产SKU ID
Status stock.StockStatus `bson:"status" json:"status"` // 库存状态
OrderId *bson.ObjectID `bson:"orderId" json:"orderId"` // 关联订单ID如果有
LockExpire *gtime.Time `bson:"lockExpire" json:"lockExpire"` // 锁定过期时间
Metadata []map[string]interface{} `bson:"metadata" json:"metadata"` // 其他元数据
TokenId string `bson:"tokenId" json:"tokenId"` // 区块链TokenID如果有
beans.SQLBaseDO `orm:",inherit"`
AssetId int64 `orm:"asset_id" json:"assetId"` // 关联资产ID
AssetSkuId int64 `orm:"asset_sku_id" json:"assetSkuId"` // 关联资产SKU ID
Status stock.StockStatus `orm:"status" json:"status"` // 库存状态
OrderId int64 `orm:"order_id" json:"orderId"` // 关联订单ID如果有
LockExpire *gtime.Time `orm:"lock_expire" json:"lockExpire"` // 锁定过期时间
Metadata []map[string]interface{} `orm:"metadata" json:"metadata"` // 其他元数据
TokenId string `orm:"token_id" json:"tokenId"` // 区块链TokenID如果有
// 渠道分配信息
AssignedChannel string `bson:"assignedChannel" json:"assignedChannel"` // 分配的销售渠道
ChannelSKU string `bson:"channelSku" json:"channelSku"` // 渠道商品SKU
ChannelMetadata map[string]interface{} `bson:"channelMetadata" json:"channelMetadata"` // 渠道专属数据
AllocatedAt *gtime.Time `bson:"allocatedAt" json:"allocatedAt"` // 分配时间
CategoryPath string `bson:"categoryPath" json:"categoryPath"` // 分类路径
}
// CollectionName 库存集合名称
func (StockDetails) CollectionName() string {
return public.StockDetailsCollection
AssignedChannel string `orm:"assigned_channel" json:"assignedChannel"` // 分配的销售渠道
ChannelSKU string `orm:"channel_sku" json:"channelSku"` // 渠道商品SKU
ChannelMetadata map[string]interface{} `orm:"channel_metadata" json:"channelMetadata"` // 渠道专属数据
AllocatedAt *gtime.Time `orm:"allocated_at" json:"allocatedAt"` // 分配时间
CategoryPath string `orm:"category_path" json:"categoryPath"` // 分类路径
}