refactor: 重构资产模型与DAO层实现
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
server:
|
server:
|
||||||
address: ":3003"
|
address: ":3003"
|
||||||
name: "assets"
|
name: "assets"
|
||||||
|
workerId: 1
|
||||||
#logPath: "resource/log/server"
|
#logPath: "resource/log/server"
|
||||||
logStdout: true
|
logStdout: true
|
||||||
errorStack: true
|
errorStack: true
|
||||||
|
|||||||
@@ -1,17 +1,9 @@
|
|||||||
package consts
|
package consts
|
||||||
|
|
||||||
// AssetSkuStatus SKU状态枚举
|
// AssetSkuStatus SKU状态枚举
|
||||||
type AssetSkuStatus int
|
|
||||||
|
|
||||||
const (
|
type AssetSkuStatusType *int
|
||||||
AssetSkuStatusActive AssetSkuStatus = 1 // 启用
|
|
||||||
AssetSkuStatusInactive AssetSkuStatus = 0 // 停用
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetAllSkuStatuses 获取所有SKU状态
|
type AssetSkuStatus struct {
|
||||||
func GetAllSkuStatuses() []AssetSkuStatus {
|
Status AssetSkuStatusType
|
||||||
return []AssetSkuStatus{
|
|
||||||
AssetSkuStatusActive,
|
|
||||||
AssetSkuStatusInactive,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,9 @@
|
|||||||
package consts
|
package consts
|
||||||
|
|
||||||
// AssetStatus 资产状态枚举
|
// AssetStatus 资产状态枚举
|
||||||
type AssetStatus int
|
|
||||||
|
|
||||||
const (
|
type AssetStatusType *int
|
||||||
AssetStatusActive AssetStatus = 1 // 启用
|
|
||||||
AssetStatusInactive AssetStatus = 0 // 停用
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetAllAssetStatuses 获取所有资产状态
|
type AssetStatus struct {
|
||||||
func GetAllAssetStatuses() []AssetStatus {
|
Status AssetStatusType
|
||||||
return []AssetStatus{
|
|
||||||
AssetStatusActive,
|
|
||||||
AssetStatusInactive,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ package consts
|
|||||||
type AttributeType string
|
type AttributeType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AttributeTypeText AttributeType = "text" // 文本
|
AttributeTypeText AttributeType = "text" // 文本
|
||||||
//AttributeTypeNumber AttributeType = "number" // 数字
|
|
||||||
//AttributeTypeDate AttributeType = "date" // 日期
|
|
||||||
AttributeTypeSelect AttributeType = "select" // 单选
|
AttributeTypeSelect AttributeType = "select" // 单选
|
||||||
AttributeTypeMultiSelect AttributeType = "multi_select" // 多选
|
AttributeTypeMultiSelect AttributeType = "multi_select" // 多选
|
||||||
)
|
)
|
||||||
@@ -15,8 +13,6 @@ const (
|
|||||||
func GetAllAttributeTypes() []AttributeType {
|
func GetAllAttributeTypes() []AttributeType {
|
||||||
return []AttributeType{
|
return []AttributeType{
|
||||||
AttributeTypeText,
|
AttributeTypeText,
|
||||||
//AttributeTypeNumber,
|
|
||||||
//AttributeTypeDate,
|
|
||||||
AttributeTypeSelect,
|
AttributeTypeSelect,
|
||||||
AttributeTypeMultiSelect,
|
AttributeTypeMultiSelect,
|
||||||
}
|
}
|
||||||
@@ -29,9 +25,7 @@ type AttrTypeKeyValue struct {
|
|||||||
|
|
||||||
// 定义枚举实例(Key-Value 绑定),相当于改造后的常量
|
// 定义枚举实例(Key-Value 绑定),相当于改造后的常量
|
||||||
var (
|
var (
|
||||||
AttrTypeTextKeyValue = AttrTypeKeyValue{Key: AttributeTypeText, Value: "文本"}
|
AttrTypeTextKeyValue = AttrTypeKeyValue{Key: AttributeTypeText, Value: "文本"}
|
||||||
//AttrTypeNumberKeyValue = AttrTypeKeyValue{Key: AttributeTypeNumber, Value: "数字"}
|
|
||||||
//AttrTypeDateKeyValue = AttrTypeKeyValue{Key: AttributeTypeDate, Value: "日期"}
|
|
||||||
AttrTypeSelectKeyValue = AttrTypeKeyValue{Key: AttributeTypeSelect, Value: "单选"}
|
AttrTypeSelectKeyValue = AttrTypeKeyValue{Key: AttributeTypeSelect, Value: "单选"}
|
||||||
AttrTypeMultiSelectKeyValue = AttrTypeKeyValue{Key: AttributeTypeMultiSelect, Value: "多选"}
|
AttrTypeMultiSelectKeyValue = AttrTypeKeyValue{Key: AttributeTypeMultiSelect, Value: "多选"}
|
||||||
)
|
)
|
||||||
@@ -39,8 +33,6 @@ var (
|
|||||||
func GetAllAttrTypeKeyValue() []AttrTypeKeyValue {
|
func GetAllAttrTypeKeyValue() []AttrTypeKeyValue {
|
||||||
return []AttrTypeKeyValue{
|
return []AttrTypeKeyValue{
|
||||||
AttrTypeTextKeyValue,
|
AttrTypeTextKeyValue,
|
||||||
//AttrTypeNumberKeyValue,
|
|
||||||
//AttrTypeDateKeyValue,
|
|
||||||
AttrTypeSelectKeyValue,
|
AttrTypeSelectKeyValue,
|
||||||
AttrTypeMultiSelectKeyValue,
|
AttrTypeMultiSelectKeyValue,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,92 +19,79 @@ type assetDao struct {
|
|||||||
|
|
||||||
// Insert 插入资产
|
// Insert 插入资产
|
||||||
func (d *assetDao) Insert(ctx context.Context, req *dto.CreateAssetReq) (id int64, err error) {
|
func (d *assetDao) Insert(ctx context.Context, req *dto.CreateAssetReq) (id int64, err error) {
|
||||||
var result entity.Asset
|
var res *entity.Asset
|
||||||
if err = gconv.Struct(req, &result); err != nil {
|
if err = gconv.Struct(req, &res); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).Data(&result).InsertAndGetId()
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).Data(&res).Insert()
|
||||||
}
|
if err != nil {
|
||||||
|
return
|
||||||
// GetOne 获取单个资产
|
}
|
||||||
func (d *assetDao) GetOne(ctx context.Context, req *dto.GetAssetReq) (res *entity.Asset, err error) {
|
return r.LastInsertId()
|
||||||
err = gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).Where("id", req.Id).Scan(&res)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update 更新资产
|
// Update 更新资产
|
||||||
func (d *assetDao) Update(ctx context.Context, req *dto.UpdateAssetReq) (err error) {
|
func (d *assetDao) Update(ctx context.Context, req *dto.UpdateAssetReq) (rows int64, err error) {
|
||||||
data := g.Map{
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).OmitEmpty().Where(entity.AssetCol.Id, req.Id).Update()
|
||||||
"name": req.Name,
|
if err != nil {
|
||||||
"description": req.Description,
|
return
|
||||||
"type": req.Type,
|
|
||||||
"category_id": req.CategoryId,
|
|
||||||
"image_url": req.ImageURL,
|
|
||||||
"images": req.Images,
|
|
||||||
"status": req.Status,
|
|
||||||
"online_time": req.OnlineTime,
|
|
||||||
"offline_time": req.OfflineTime,
|
|
||||||
"physical_asset_config": req.PhysicalAssetConfig,
|
|
||||||
"service_asset_config": req.ServiceAssetConfig,
|
|
||||||
"virtual_asset_config": req.VirtualAssetConfig,
|
|
||||||
"metadata": req.Metadata,
|
|
||||||
}
|
}
|
||||||
_, err = gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).Where("id", req.Id).Update(data)
|
return r.RowsAffected()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteFake 删除资产-根据id进行假删
|
// Delete 删除资产-根据id进行假删
|
||||||
func (d *assetDao) DeleteFake(ctx context.Context, req *dto.DeleteAssetReq) (err error) {
|
func (d *assetDao) Delete(ctx context.Context, req *dto.DeleteAssetReq) (rows int64, err error) {
|
||||||
_, err = gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).Where("id", req.Id).Update(g.Map{
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetCollection).Where(entity.AssetCol.Id, req.Id).Delete()
|
||||||
"is_deleted": true,
|
if err != nil {
|
||||||
})
|
return
|
||||||
return
|
}
|
||||||
|
return r.RowsAffected()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOneById 通过ID获取单个资产(内部使用uint64)
|
// GetOne 获取单个资产
|
||||||
func (d *assetDao) GetOneById(ctx context.Context, id uint64) (res *entity.Asset, err error) {
|
func (d *assetDao) GetOne(ctx context.Context, req *dto.GetAssetReq, fields ...string) (res *entity.Asset, err error) {
|
||||||
err = gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).Where("id", id).Scan(&res)
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetCollection).Ctx(ctx).Where(entity.AssetCol.Id, req.Id).Fields(fields).One()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = r.Struct(&res)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count 获取资产数量
|
// Count 获取资产数量
|
||||||
func (d *assetDao) Count(ctx context.Context, req *dto.ListAssetReq) (count int64, err error) {
|
func (d *assetDao) Count(ctx context.Context, req *dto.ListAssetReq) (count int, err error) {
|
||||||
m := d.buildListFilter(ctx, req)
|
return d.buildListFilter(ctx, req).Count()
|
||||||
c, err := m.Count()
|
|
||||||
return int64(c), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List 获取资产列表
|
// List 获取资产列表
|
||||||
func (d *assetDao) List(ctx context.Context, req *dto.ListAssetReq) (res []entity.Asset, total int, err error) {
|
func (d *assetDao) List(ctx context.Context, req *dto.ListAssetReq, fields ...string) (res []entity.Asset, total int, err error) {
|
||||||
m := d.buildListFilter(ctx, req)
|
model := d.buildListFilter(ctx, req)
|
||||||
|
model.Fields(fields)
|
||||||
|
model.OrderDesc(entity.AssetCol.CreatedAt)
|
||||||
if req.Page != nil {
|
if req.Page != nil {
|
||||||
m = m.Page(int(req.Page.PageNum), int(req.Page.PageSize))
|
model.Page(int(req.Page.PageNum), int(req.Page.PageSize))
|
||||||
}
|
}
|
||||||
err = m.ScanAndCount(&res, &total, false)
|
r, total, err := model.AllAndCount(false)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = r.Structs(&res)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildListFilter 构建列表查询的过滤条件
|
// buildListFilter 构建列表查询的过滤条件
|
||||||
func (d *assetDao) buildListFilter(ctx context.Context, req *dto.ListAssetReq) *gdb.Model {
|
func (d *assetDao) buildListFilter(ctx context.Context, req *dto.ListAssetReq) *gdb.Model {
|
||||||
m := gfdb.DB(ctx).Model(ctx, public.AssetCollection).Cache(ctx).Where("is_deleted", false)
|
model := gfdb.DB(ctx).Model(ctx, public.AssetCollection).Model
|
||||||
|
if !g.IsEmpty(req.Keyword) {
|
||||||
if !g.IsEmpty(req.Name) {
|
model.WhereLike(entity.AssetCol.Name, "%"+req.Keyword+"%")
|
||||||
m = m.Where("name", req.Name)
|
|
||||||
}
|
|
||||||
if !g.IsEmpty(req.Type) {
|
|
||||||
m = m.Where("type", req.Type)
|
|
||||||
}
|
|
||||||
if !g.IsEmpty(req.CategoryId) {
|
|
||||||
m = m.Where("category_id", req.CategoryId)
|
|
||||||
}
|
|
||||||
if !g.IsEmpty(req.Status) {
|
|
||||||
m = m.Where("status", req.Status)
|
|
||||||
}
|
}
|
||||||
if !g.IsEmpty(req.CategoryPath) {
|
if !g.IsEmpty(req.CategoryPath) {
|
||||||
m = m.WhereLike("category_path", req.CategoryPath+"%")
|
model.WhereLike(entity.AssetCol.CategoryPath, req.CategoryPath+"%")
|
||||||
}
|
}
|
||||||
if !g.IsEmpty(req.Keyword) {
|
model.Where(entity.AssetCol.Name, req.Name)
|
||||||
m = m.WhereLike("name", "%"+req.Keyword+"%")
|
model.Where(entity.AssetCol.Type, req.Type)
|
||||||
}
|
model.Where(entity.AssetCol.CategoryId, req.CategoryId)
|
||||||
return m
|
model.Where(entity.AssetCol.Status, req.Status)
|
||||||
|
model.OmitEmptyWhere()
|
||||||
|
return model
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ import (
|
|||||||
"assets/model/entity/asset"
|
"assets/model/entity/asset"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"gitea.com/red-future/common/beans"
|
"gitea.com/red-future/common/db/gfdb"
|
||||||
"gitea.com/red-future/common/db/mongo"
|
"github.com/gogf/gf/v2/database/gdb"
|
||||||
"gitea.com/red-future/common/utils"
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AssetSku = new(assetSku)
|
var AssetSku = new(assetSku)
|
||||||
@@ -19,112 +18,94 @@ type assetSku struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert 插入SKU
|
// Insert 插入SKU
|
||||||
func (d *assetSku) Insert(ctx context.Context, req *dto.CreateAssetSkuReq) (ids []any, err error) {
|
func (d *assetSku) Insert(ctx context.Context, req *dto.CreateAssetSkuReq) (id int64, err error) {
|
||||||
var result *entity.AssetSku
|
var res *entity.AssetSku
|
||||||
if err = utils.Struct(req, &result); err != nil {
|
if err = gconv.Struct(req, &res); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ids, err = mongo.DB().Insert(ctx, []interface{}{&result}, public.AssetSkuCollection)
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetSkuCollection).Ctx(ctx).Data(&res).Insert()
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update 更新SKU
|
|
||||||
func (d *assetSku) Update(ctx context.Context, req *dto.UpdateAssetSkuReq) (err error) {
|
|
||||||
buildUpdateData, err := mongo.BuildUpdateData(ctx, req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
filter := bson.M{"_id": req.Id}
|
return r.LastInsertId()
|
||||||
update := bson.M{"$set": buildUpdateData}
|
|
||||||
if !g.IsEmpty(req.Stock) {
|
|
||||||
// 从$set中移除stock字段避免$set和$inc冲突
|
|
||||||
delete(buildUpdateData, "stock")
|
|
||||||
update = bson.M{
|
|
||||||
"$inc": bson.M{
|
|
||||||
"stock": req.Stock,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if len(buildUpdateData) > 0 {
|
|
||||||
update["$set"] = buildUpdateData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = mongo.DB().Update(ctx, filter, update, public.AssetSkuCollection)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteFake 删除SKU-根据id进行假删
|
// Update 更新SKU
|
||||||
func (d *assetSku) DeleteFake(ctx context.Context, req *dto.DeleteAssetSkuReq) (err error) {
|
func (d *assetSku) Update(ctx context.Context, req *dto.UpdateAssetSkuReq) (rows int64, err error) {
|
||||||
filter := bson.M{"_id": req.Id}
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetSkuCollection).Ctx(ctx).OmitEmpty().Where(entity.AssetCol.Id, req.Id).Update()
|
||||||
_, err = mongo.DB().DeleteSoft(ctx, filter, public.AssetSkuCollection)
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
return r.RowsAffected()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除SKU-根据id进行假删
|
||||||
|
func (d *assetSku) Delete(ctx context.Context, req *dto.DeleteAssetSkuReq) (rows int64, err error) {
|
||||||
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetSkuCollection).Where(entity.AssetSkuCol.Id, req.Id).Delete()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return r.RowsAffected()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOne 获取单个SKU
|
// GetOne 获取单个SKU
|
||||||
func (d *assetSku) GetOne(ctx context.Context, req *dto.GetAssetSkuReq, noTenantId bool) (res *entity.AssetSku, err error) {
|
func (d *assetSku) GetOne(ctx context.Context, req *dto.GetAssetSkuReq, fields ...string) (res *entity.AssetSku, err error) {
|
||||||
filter := bson.M{"_id": req.Id}
|
r, err := gfdb.DB(ctx).Model(ctx, public.AssetSkuCollection).Ctx(ctx).Where(entity.AssetCol.Id, req.Id).Fields(fields).One()
|
||||||
if noTenantId {
|
if err != nil {
|
||||||
err = mongo.DB().NoTenantId().FindOne(ctx, filter, &res, public.AssetSkuCollection)
|
return
|
||||||
} else {
|
|
||||||
err = mongo.DB().FindOne(ctx, filter, &res, public.AssetSkuCollection)
|
|
||||||
}
|
}
|
||||||
|
err = r.Struct(&res)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetListByAssetIdExcludeCurrentSku 根据资产ID获取SKU列表并且排除当前SKU
|
// GetListByAssetIdExcludeCurrentSku 根据资产ID获取SKU列表并且排除当前SKU
|
||||||
func (d *assetSku) GetListByAssetIdExcludeCurrentSku(ctx context.Context, assetId *bson.ObjectID, req *dto.ListAssetSkuReq) (res []entity.AssetSku, total int64, err error) {
|
func (d *assetSku) GetListByAssetIdExcludeCurrentSku(ctx context.Context, assetId int64, req *dto.ListAssetSkuReq, fields ...string) (res []entity.AssetSku, total int, err error) {
|
||||||
filter := bson.M{"assetId": assetId, "_id": bson.M{"$ne": req.Id}}
|
model := gfdb.DB(ctx).Model(ctx, public.AssetSkuCollection)
|
||||||
total, err = mongo.DB().Find(ctx, filter, &res, public.AssetSkuCollection, req.Page, req.OrderBy)
|
model.Fields(fields)
|
||||||
|
model.Where(entity.AssetSkuCol.AssetId, assetId)
|
||||||
|
model.WhereNot(entity.AssetSkuCol.Id, req.Id)
|
||||||
|
if req.Page != nil {
|
||||||
|
model.Page(int(req.Page.PageNum), int(req.Page.PageSize))
|
||||||
|
}
|
||||||
|
r, total, err := model.AllAndCount(false)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = r.Structs(&res)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// List 获取SKU列表
|
// List 获取SKU列表
|
||||||
func (d *assetSku) List(ctx context.Context, req *dto.ListAssetSkuReq, noTenantId bool) (res []entity.AssetSku, total int64, err error) {
|
func (d *assetSku) List(ctx context.Context, req *dto.ListAssetSkuReq, fields ...string) (res []entity.AssetSku, total int, err error) {
|
||||||
// 构建查询过滤条件
|
model := d.buildListFilter(ctx, req)
|
||||||
filter, err := d.buildListFilter(ctx, req)
|
model.Fields(fields)
|
||||||
|
model.OrderAsc(entity.AssetSkuCol.Sort)
|
||||||
|
model.OrderDesc(entity.AssetSkuCol.CreatedAt)
|
||||||
|
if req.Page != nil {
|
||||||
|
model.Page(int(req.Page.PageNum), int(req.Page.PageSize))
|
||||||
|
}
|
||||||
|
r, total, err := model.AllAndCount(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 排序处理
|
err = r.Structs(&res)
|
||||||
req.OrderBy = []beans.OrderBy{
|
|
||||||
{Field: "sort", Order: beans.Asc},
|
|
||||||
{Field: "createdAt", Order: beans.Desc},
|
|
||||||
}
|
|
||||||
if noTenantId {
|
|
||||||
total, err = mongo.DB().NoTenantId().Find(ctx, filter, &res, public.AssetSkuCollection, req.Page, req.OrderBy)
|
|
||||||
} else {
|
|
||||||
total, err = mongo.DB().Find(ctx, filter, &res, public.AssetSkuCollection, req.Page, req.OrderBy)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildListFilter 构建列表查询的过滤条件
|
// buildListFilter 构建列表查询的过滤条件
|
||||||
func (d *assetSku) buildListFilter(ctx context.Context, req *dto.ListAssetSkuReq) (filter bson.M, err error) {
|
func (d *assetSku) buildListFilter(ctx context.Context, req *dto.ListAssetSkuReq) *gdb.Model {
|
||||||
_ = ctx
|
model := gfdb.DB(ctx).Model(ctx, public.AssetSkuCollection).Model
|
||||||
filter = bson.M{}
|
if !g.IsEmpty(req.Keyword) {
|
||||||
if !g.IsEmpty(req.AssetId) {
|
model.WhereLike(entity.AssetCol.Name, "%"+req.Keyword+"%")
|
||||||
filter["assetId"] = req.AssetId
|
model.WhereOrLike(entity.AssetSkuCol.SkuName, "%"+req.Keyword+"%")
|
||||||
}
|
|
||||||
if !g.IsEmpty(req.Status) {
|
|
||||||
filter["status"] = req.Status
|
|
||||||
}
|
}
|
||||||
if !g.IsEmpty(req.CategoryPath) {
|
if !g.IsEmpty(req.CategoryPath) {
|
||||||
filter["categoryPath"] = bson.M{"$regex": "^" + req.CategoryPath, "$options": "i"}
|
model.WhereLike(entity.AssetSkuCol.CategoryPath, req.CategoryPath+"%")
|
||||||
}
|
}
|
||||||
if !g.IsEmpty(req.Keyword) {
|
model.Where(entity.AssetSkuCol.Id, req.Id)
|
||||||
orConditions := bson.A{
|
model.Where(entity.AssetSkuCol.Status, req.Status)
|
||||||
bson.M{"skuName": bson.M{"$regex": req.Keyword, "$options": "i"}},
|
model.WhereGT(entity.AssetSkuCol.Price, req.MinPrice)
|
||||||
bson.M{"assetName": bson.M{"$regex": req.Keyword, "$options": "i"}},
|
model.WhereLT(entity.AssetSkuCol.Price, req.MaxPrice)
|
||||||
}
|
model.OmitEmptyWhere()
|
||||||
filter["$or"] = orConditions
|
return model
|
||||||
}
|
|
||||||
if req.MinPrice > 0 {
|
|
||||||
filter["price"] = bson.M{"$gte": req.MinPrice}
|
|
||||||
}
|
|
||||||
if req.MaxPrice > 0 {
|
|
||||||
if filter["price"] == nil {
|
|
||||||
filter["price"] = bson.M{}
|
|
||||||
}
|
|
||||||
filter["price"].(bson.M)["$lte"] = req.MaxPrice
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ import (
|
|||||||
|
|
||||||
"gitea.com/red-future/common/db/gfdb"
|
"gitea.com/red-future/common/db/gfdb"
|
||||||
"github.com/gogf/gf/v2/database/gdb"
|
"github.com/gogf/gf/v2/database/gdb"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
|
||||||
"github.com/gogf/gf/v2/util/guid"
|
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Category = new(category)
|
var Category = new(category)
|
||||||
@@ -20,63 +18,65 @@ type category struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert 插入分类
|
// Insert 插入分类
|
||||||
func (d *category) Insert(ctx context.Context, req *dto.CreateCategoryReq) (res *entity.Category, err error) {
|
func (d *category) Insert(ctx context.Context, req *dto.CreateCategoryReq) (id int64, err error) {
|
||||||
|
var res *entity.Category
|
||||||
if err = gconv.Struct(req, &res); err != nil {
|
if err = gconv.Struct(req, &res); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.Bid = guid.S()
|
r, err := gfdb.DB(ctx).Model(ctx, public.CategoryCollection).Insert(&res)
|
||||||
_, err = gfdb.DB(ctx).Model(ctx, public.CategoryCollection).Insert(&res)
|
if err != nil {
|
||||||
return res, nil
|
return
|
||||||
|
}
|
||||||
|
return r.LastInsertId()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update 更新分类
|
// Update 更新分类
|
||||||
func (d *category) Update(ctx context.Context, req *dto.UpdateCategoryReq) (err error) {
|
func (d *category) Update(ctx context.Context, req *dto.UpdateCategoryReq) (rows int64, err error) {
|
||||||
model := gfdb.DB(ctx).Model(ctx, public.CategoryCollection).Data(gconv.Map(&req)).OmitEmpty()
|
r, err := gfdb.DB(ctx).Model(ctx, public.CategoryCollection).Data(&req).OmitEmpty().Where(entity.CategoryCol.Id, req.Id).Update()
|
||||||
if !g.IsEmpty(req.Bid) {
|
if err != nil {
|
||||||
model.Where("bid", req.Bid)
|
return
|
||||||
}
|
}
|
||||||
if !g.IsEmpty(req.Id) {
|
return r.RowsAffected()
|
||||||
model.Where("id", req.Id)
|
}
|
||||||
|
|
||||||
|
// Delete 删除分类-根据id及父id进行假删
|
||||||
|
func (d *category) Delete(ctx context.Context, req *dto.DeleteCategoryReq) (rows int64, err error) {
|
||||||
|
r, err := gfdb.DB(ctx).Model(ctx, public.CategoryCollection).Where(entity.CategoryCol.Id, req.Id).Delete()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
_, err = model.Update()
|
return r.RowsAffected()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOne 获取单个分类
|
// GetOne 获取单个分类
|
||||||
func (d *category) GetOne(ctx context.Context, req *dto.GetCategoryReq, fields ...string) (category *entity.Category, err error) {
|
func (d *category) GetOne(ctx context.Context, req *dto.GetCategoryReq, fields ...string) (res *entity.Category, err error) {
|
||||||
model := gfdb.DB(ctx).Model(ctx, public.CategoryCollection)
|
r, err := gfdb.DB(ctx).Model(ctx, public.CategoryCollection).Where(entity.CategoryCol.Id, req.Id).Fields(fields).One()
|
||||||
if !g.IsEmpty(req.Bid) {
|
if err != nil {
|
||||||
model.Where(entity.CategoryCol.Bid, req.Bid)
|
return
|
||||||
}
|
}
|
||||||
if !g.IsEmpty(req.Id) {
|
err = r.Struct(&res)
|
||||||
model.Where(entity.CategoryCol.Id, req.Id)
|
|
||||||
}
|
|
||||||
res, err := model.Fields(fields).One()
|
|
||||||
err = res.Struct(&category)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteFake 删除分类-根据id及父id进行假删
|
|
||||||
func (d *category) DeleteFake(ctx context.Context, req *dto.DeleteCategoryReq) (err error) {
|
|
||||||
model := gfdb.DB(ctx).Model(ctx, public.CategoryCollection)
|
|
||||||
model.Where(entity.CategoryCol.Bid, req.Bid)
|
|
||||||
_, err = model.Delete()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count 根据条件统计分类数量
|
// Count 根据条件统计分类数量
|
||||||
func (d *category) Count(ctx context.Context, req *dto.ListCategoryReq) (count int64, err error) {
|
func (d *category) Count(ctx context.Context, req *dto.ListCategoryReq) (count int, err error) {
|
||||||
m := d.buildListFilter(ctx, req)
|
return d.buildListFilter(ctx, req).Count()
|
||||||
c, err := m.Count()
|
|
||||||
return int64(c), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List 获取分类列表
|
// List 获取分类列表
|
||||||
func (d *category) List(ctx context.Context, req *dto.ListCategoryReq, fields ...string) (res []entity.Category, total int, err error) {
|
func (d *category) List(ctx context.Context, req *dto.ListCategoryReq, fields ...string) (res []entity.Category, total int, err error) {
|
||||||
model := d.buildListFilter(ctx, req)
|
model := d.buildListFilter(ctx, req)
|
||||||
model.Fields(fields)
|
model.Fields(fields)
|
||||||
|
model.OrderAsc(entity.CategoryCol.Sort)
|
||||||
|
model.OrderDesc(entity.CategoryCol.CreatedAt)
|
||||||
|
if req.Page != nil {
|
||||||
|
model.Page(int(req.Page.PageNum), int(req.Page.PageSize))
|
||||||
|
}
|
||||||
r, total, err := model.AllAndCount(false)
|
r, total, err := model.AllAndCount(false)
|
||||||
err = gconv.Structs(r.List(), &res)
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = r.Structs(&res)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +88,6 @@ func (d *category) buildListFilter(ctx context.Context, req *dto.ListCategoryReq
|
|||||||
}
|
}
|
||||||
model.Where(entity.CategoryCol.ParentId, req.ParentId)
|
model.Where(entity.CategoryCol.ParentId, req.ParentId)
|
||||||
model.Where(entity.CategoryCol.Status, req.Status)
|
model.Where(entity.CategoryCol.Status, req.Status)
|
||||||
model.OrderAsc(entity.CategoryCol.Sort)
|
|
||||||
model.OrderDesc(entity.CategoryCol.CreatedAt)
|
|
||||||
model.OmitEmptyWhere()
|
model.OmitEmptyWhere()
|
||||||
return model
|
return model
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func (d *stockDetails) DeleteManyByIds(ctx context.Context, allStockIds []*bson.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetStockCountBySkuId 获取库存数根据SKU ID
|
// GetStockCountBySkuId 获取库存数根据SKU ID
|
||||||
func (d *stockDetails) GetStockCountBySkuId(ctx context.Context, assetSkuId *bson.ObjectID) (total int64, err error) {
|
func (d *stockDetails) GetStockCountBySkuId(ctx context.Context, assetSkuId int64) (total int64, err error) {
|
||||||
// 构建查询过滤条件
|
// 构建查询过滤条件
|
||||||
filter := bson.M{}
|
filter := bson.M{}
|
||||||
filter["assetSkuId"] = assetSkuId
|
filter["assetSkuId"] = assetSkuId
|
||||||
|
|||||||
@@ -5,32 +5,28 @@ import (
|
|||||||
"assets/consts/stock"
|
"assets/consts/stock"
|
||||||
"assets/model/config"
|
"assets/model/config"
|
||||||
enumDto "assets/model/dto/enum"
|
enumDto "assets/model/dto/enum"
|
||||||
entity "assets/model/entity/asset"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"gitea.com/red-future/common/beans"
|
"gitea.com/red-future/common/beans"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/os/gtime"
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateAssetReq 创建资产请求
|
// CreateAssetReq 创建资产请求
|
||||||
type CreateAssetReq struct {
|
type CreateAssetReq struct {
|
||||||
g.Meta `path:"/createAsset" method:"post" tags:"资产管理" summary:"创建资产" dc:"创建新的资产"`
|
g.Meta `path:"/createAsset" method:"post" tags:"资产管理" summary:"创建资产" dc:"创建新的资产"`
|
||||||
// 基础信息
|
// 基础信息
|
||||||
Name string `json:"name" v:"required" dc:"资产名称"`
|
Name string `json:"name" v:"required" dc:"资产名称"`
|
||||||
Description string `json:"description" dc:"资产描述"`
|
Description string `json:"description" dc:"资产描述"`
|
||||||
Type consts.AssetType `json:"type" v:"required" dc:"资产类型:physical实物/virtual虚拟/service服务"`
|
Type consts.AssetType `json:"type" v:"required" dc:"资产类型:physical实物/virtual虚拟/service服务"`
|
||||||
CategoryId uint64 `json:"categoryId" v:"required" dc:"分类ID"`
|
CategoryId int64 `json:"categoryId" v:"required" dc:"分类ID"`
|
||||||
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
||||||
ImageURL string `json:"imageUrl" dc:"主图URL"`
|
ImageURL string `json:"imageUrl" dc:"主图URL"`
|
||||||
Images []string `json:"images" dc:"图片列表"`
|
Images []string `json:"images" dc:"图片列表"`
|
||||||
Status *consts.AssetStatus `json:"status" dc:"状态:1/0" d:"1"`
|
Status consts.AssetStatusType `json:"status" dc:"状态:1/0" d:"1"`
|
||||||
UnlimitedStock bool `json:"unlimitedStock" dc:"是否无库存限制"`
|
UnlimitedStock bool `json:"unlimitedStock" dc:"是否无库存限制"`
|
||||||
StockMode stock.StockMode `json:"stockMode" dc:"库存管理模式:1-明细模式 2-批次模式" d:"2"`
|
StockMode stock.StockMode `json:"stockMode" dc:"库存管理模式:1-明细模式 2-批次模式" d:"2"`
|
||||||
// 上线和下线时间配置(由定时任务处理资产状态)
|
OnlineTime *gtime.Time `json:"onlineTime,omitempty" dc:"上线时间(格式:2006-01-02 15:04:05)"`
|
||||||
OnlineTime *time.Time `json:"onlineTime,omitempty" dc:"上线时间(格式:2006-01-02 15:04:05)"`
|
OfflineTime *gtime.Time `json:"offlineTime,omitempty" dc:"下线时间(格式:2006-01-02 15:04:05)"`
|
||||||
OfflineTime *time.Time `json:"offlineTime,omitempty" dc:"下线时间(格式:2006-01-02 15:04:05)"`
|
|
||||||
// 类型专用配置 - 实物资产配置
|
// 类型专用配置 - 实物资产配置
|
||||||
PhysicalAssetConfig *config.PhysicalAssetConfig `json:"physicalAssetConfig"`
|
PhysicalAssetConfig *config.PhysicalAssetConfig `json:"physicalAssetConfig"`
|
||||||
// 类型专用配置 - 服务资产配置
|
// 类型专用配置 - 服务资产配置
|
||||||
@@ -45,86 +41,83 @@ type CreateAssetReq struct {
|
|||||||
|
|
||||||
// CreateAssetRes 创建资产响应
|
// CreateAssetRes 创建资产响应
|
||||||
type CreateAssetRes struct {
|
type CreateAssetRes struct {
|
||||||
Id uint64 `json:"id" dc:"资产ID"`
|
Id int64 `json:"id" dc:"资产ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListAssetReq 获取资产列表请求
|
// ListAssetReq 获取资产列表请求
|
||||||
type ListAssetReq struct {
|
type ListAssetReq struct {
|
||||||
g.Meta `path:"/listAssets" method:"get" tags:"资产管理" summary:"获取资产列表" dc:"分页查询资产列表,支持多条件筛选"`
|
g.Meta `path:"/listAssets" method:"get" tags:"资产管理" summary:"获取资产列表" dc:"分页查询资产列表,支持多条件筛选"`
|
||||||
*beans.Page
|
*beans.Page
|
||||||
OrderBy []beans.OrderBy `json:"orderBy" dc:"排序规则"`
|
Name string `json:"name" dc:"资产名称"`
|
||||||
Name string `json:"name" dc:"资产名称"`
|
Type consts.AssetType `json:"type" dc:"资产类型"`
|
||||||
Type consts.AssetType `json:"type" dc:"资产类型"`
|
CategoryId int64 `json:"categoryId" dc:"分类ID"`
|
||||||
CategoryId string `json:"categoryId" dc:"分类ID"`
|
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
||||||
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:"关键词搜索"`
|
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListAssetRes 获取资产列表响应
|
// ListAssetRes 获取资产列表响应
|
||||||
type ListAssetRes struct {
|
type ListAssetRes struct {
|
||||||
List []AssetListItem `json:"list" dc:"资产列表"`
|
List []AssetItem `json:"list" dc:"资产列表"`
|
||||||
Total int `json:"total" dc:"总数"`
|
Total int `json:"total" dc:"总数"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AssetListItem struct {
|
type AssetItem struct {
|
||||||
// 基础信息
|
Id int64 `json:"id"` // 资产ID
|
||||||
Id uint64 `json:"id"` // 资产ID
|
Name string `json:"name"` // 资产名称
|
||||||
Name string `json:"name"` // 资产名称
|
Type consts.AssetType `json:"type"` // 资产类型:physical实物/virtual虚拟/service服务
|
||||||
Type consts.AssetType `json:"type"` // 资产类型:physical实物/virtual虚拟/service服务
|
TypeName string `json:"typeName"` // 资产类型:physical实物/virtual虚拟/service服务
|
||||||
TypeName string `json:"typeName"` // 资产类型:physical实物/virtual虚拟/service服务
|
CategoryId int64 `json:"categoryId"` // 分类ID
|
||||||
CategoryId uint64 `json:"categoryId"` // 分类ID
|
UnlimitedStock bool `json:"unlimitedStock"` // 是否无库存限制
|
||||||
UnlimitedStock bool `json:"unlimitedStock"` // 是否无库存限制
|
Status consts.AssetStatusType `json:"status"` // 资产状态:active启用/inactive停用
|
||||||
Status *consts.AssetStatus `json:"status"` // 资产状态:active启用/inactive停用
|
BasePrice int `json:"basePrice"` // 基础价格(分为单位)
|
||||||
BasePrice int `json:"basePrice"` // 基础价格(分为单位)
|
OnlineTime *gtime.Time `json:"onlineTime,omitempty"` // 上线时间
|
||||||
OnlineTime *gtime.Time `json:"onlineTime,omitempty"` // 上线时间
|
OfflineTime *gtime.Time `json:"offlineTime,omitempty"` // 下线时间
|
||||||
OfflineTime *gtime.Time `json:"offlineTime,omitempty"` // 下线时间
|
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||||
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
|
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
|
||||||
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetReq 获取资产详情请求
|
// GetAssetReq 获取资产详情请求
|
||||||
type GetAssetReq struct {
|
type GetAssetReq struct {
|
||||||
g.Meta `path:"/getAsset" method:"get" tags:"资产管理" summary:"获取资产详情" dc:"获取资产详情"`
|
g.Meta `path:"/getAsset" method:"get" tags:"资产管理" summary:"获取资产详情" dc:"获取资产详情"`
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"资产ID"`
|
Id int64 `json:"id" v:"required" dc:"资产ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetRes 获取资产详情响应
|
// GetAssetRes 获取资产详情响应
|
||||||
type GetAssetRes struct {
|
type GetAssetRes struct {
|
||||||
*entity.Asset
|
*AssetItem
|
||||||
CategoryName string `json:"categoryName" dc:"分类名称"`
|
CategoryName string `json:"categoryName" dc:"分类名称"`
|
||||||
ImgAddressPrefix string `json:"imgAddressPrefix"`
|
ImgAddressPrefix string `json:"imgAddressPrefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetAndSkuReq 获取资产和Sku详情请求
|
// GetAssetAndSkuReq 获取资产和Sku详情请求
|
||||||
type GetAssetAndSkuReq struct {
|
type GetAssetAndSkuReq struct {
|
||||||
g.Meta `path:"/getAssetAndSku" method:"get" tags:"资产管理" summary:"获取资产和SKU详情" dc:"获取资产和SKU详情"`
|
g.Meta `path:"/getAssetAndSku" method:"get" tags:"资产管理" summary:"获取资产和SKU详情" dc:"获取资产和SKU详情"`
|
||||||
AssetId *bson.ObjectID `json:"assetId" v:"required" dc:"资产ID"`
|
Id int64 `json:"id" v:"required" dc:"资产ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetAndSkuRes 获取资产详情响应
|
// GetAssetAndSkuRes 获取资产详情响应
|
||||||
type GetAssetAndSkuRes struct {
|
type GetAssetAndSkuRes struct {
|
||||||
*entity.Asset
|
*AssetItem
|
||||||
Skus []entity.AssetSku `json:"skus" dc:"SKU列表"`
|
Skus []AssetSkuItem `json:"skus" dc:"SKU列表"`
|
||||||
TenantModuleType []enumDto.KeyValue `json:"tenantModuleType" dc:"租户模块类型"`
|
TenantModuleType []enumDto.KeyValue `json:"tenantModuleType" dc:"租户模块类型"`
|
||||||
ImgAddressPrefix string `json:"imgAddressPrefix"`
|
ImgAddressPrefix string `json:"imgAddressPrefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAssetReq 更新资产请求
|
// UpdateAssetReq 更新资产请求
|
||||||
type UpdateAssetReq struct {
|
type UpdateAssetReq struct {
|
||||||
g.Meta `path:"/updateAsset" method:"put" tags:"资产管理" summary:"更新资产" dc:"更新资产信息"`
|
g.Meta `path:"/updateAsset" method:"put" tags:"资产管理" summary:"更新资产" dc:"更新资产信息"`
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"资产ID"`
|
Id int64 `json:"id" v:"required" dc:"资产ID"`
|
||||||
// 基础信息
|
Name string `json:"name" dc:"资产名称"`
|
||||||
Name string `json:"name" dc:"资产名称"`
|
Description string `json:"description" dc:"资产描述"`
|
||||||
Description string `json:"description" dc:"资产描述"`
|
Type consts.AssetType `json:"type" dc:"资产类型:physical实物/virtual虚拟/service服务"`
|
||||||
Type consts.AssetType `json:"type" dc:"资产类型:physical实物/virtual虚拟/service服务"`
|
CategoryId int64 `json:"categoryId" dc:"分类ID"`
|
||||||
CategoryId *bson.ObjectID `json:"categoryId" dc:"分类ID"`
|
ImageURL string `json:"imageUrl" dc:"主图URL"`
|
||||||
ImageURL string `json:"imageUrl" dc:"主图URL"`
|
Images []string `json:"images" dc:"图片列表"`
|
||||||
Images []string `json:"images" dc:"图片列表"`
|
Status consts.AssetStatusType `json:"status,omitempty" dc:"状态:1/0"`
|
||||||
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)"`
|
||||||
OnlineTime *time.Time `json:"onlineTime,omitempty" dc:"上线时间(格式:2006-01-02 15:04:05)"`
|
|
||||||
OfflineTime *time.Time `json:"offlineTime,omitempty" dc:"下线时间(格式:2006-01-02 15:04:05)"`
|
|
||||||
// 类型专用配置 - 实物资产配置
|
// 类型专用配置 - 实物资产配置
|
||||||
PhysicalAssetConfig *config.PhysicalAssetConfig `json:"physicalAssetConfig"`
|
PhysicalAssetConfig *config.PhysicalAssetConfig `json:"physicalAssetConfig"`
|
||||||
// 类型专用配置 - 服务资产配置
|
// 类型专用配置 - 服务资产配置
|
||||||
@@ -138,12 +131,12 @@ type UpdateAssetReq struct {
|
|||||||
// UpdateAssetStatusReq 更新资产状态请求
|
// UpdateAssetStatusReq 更新资产状态请求
|
||||||
type UpdateAssetStatusReq struct {
|
type UpdateAssetStatusReq struct {
|
||||||
g.Meta `path:"/updateAssetStatus" method:"put" tags:"资产管理" summary:"更新资产状态" dc:"更新资产状态"`
|
g.Meta `path:"/updateAssetStatus" method:"put" tags:"资产管理" summary:"更新资产状态" dc:"更新资产状态"`
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"资产ID"`
|
Id int64 `json:"id" v:"required" dc:"资产ID"`
|
||||||
Status *consts.AssetStatus `json:"status" v:"required|in:1,0" dc:"状态:1启用/0停用"`
|
Status consts.AssetStatusType `json:"status" v:"required|in:1,0" dc:"状态:1启用/0停用"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAssetReq 删除资产请求
|
// DeleteAssetReq 删除资产请求
|
||||||
type DeleteAssetReq struct {
|
type DeleteAssetReq struct {
|
||||||
g.Meta `path:"/deleteAsset" method:"delete" tags:"资产管理" summary:"删除资产" dc:"删除资产"`
|
g.Meta `path:"/deleteAsset" method:"delete" tags:"资产管理" summary:"删除资产" dc:"删除资产"`
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"资产ID"`
|
Id int64 `json:"id" v:"required" dc:"资产ID"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,13 @@ import (
|
|||||||
"gitea.com/red-future/common/beans"
|
"gitea.com/red-future/common/beans"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/os/gtime"
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateAssetSkuReq 创建SKU请求
|
// CreateAssetSkuReq 创建SKU请求
|
||||||
type CreateAssetSkuReq struct {
|
type CreateAssetSkuReq struct {
|
||||||
g.Meta `path:"/createAssetSku" method:"post" tags:"SKU管理" summary:"创建SKU" dc:"创建新的资产SKU"`
|
g.Meta `path:"/createAssetSku" method:"post" tags:"SKU管理" summary:"创建SKU" dc:"创建新的资产SKU"`
|
||||||
|
|
||||||
AssetId *bson.ObjectID `json:"assetId" v:"required" dc:"关联资产ID"`
|
AssetId int64 `json:"assetId" v:"required" dc:"关联资产ID"`
|
||||||
AssetName string `json:"assetName" v:"required" dc:"关联资产名称"`
|
AssetName string `json:"assetName" v:"required" dc:"关联资产名称"`
|
||||||
SkuName string `json:"skuName" v:"required" dc:"SKU名称"`
|
SkuName string `json:"skuName" v:"required" dc:"SKU名称"`
|
||||||
SpecsCount int `json:"specsCount" v:"required|min:1" dc:"规格数量"`
|
SpecsCount int `json:"specsCount" v:"required|min:1" dc:"规格数量"`
|
||||||
@@ -24,24 +23,24 @@ type CreateAssetSkuReq struct {
|
|||||||
ImageURL string `json:"imageUrl" v:"required" dc:"SKU主图"`
|
ImageURL string `json:"imageUrl" v:"required" dc:"SKU主图"`
|
||||||
Price int `json:"price" v:"required|min:0" dc:"价格(分为单位)"`
|
Price int `json:"price" v:"required|min:0" dc:"价格(分为单位)"`
|
||||||
Sort int `json:"sort" v:"required|min:0" dc:"排序"`
|
Sort int `json:"sort" v:"required|min:0" dc:"排序"`
|
||||||
Status *consts.AssetSkuStatus `json:"status" v:"required|in:1,0" dc:"状态"`
|
Status consts.AssetSkuStatusType `json:"status" v:"required|in:1,0" dc:"状态"`
|
||||||
UnlimitedStock bool `json:"unlimitedStock" v:"required" dc:"是否无库存限制"`
|
UnlimitedStock bool `json:"unlimitedStock" v:"required" dc:"是否无库存限制"`
|
||||||
StockMode stock.StockMode `json:"stockMode" dc:"库存管理模式:1-明细模式 2-批次模式"`
|
StockMode stock.StockMode `json:"stockMode" dc:"库存管理模式:1-明细模式 2-批次模式"`
|
||||||
CategoryId *bson.ObjectID `json:"categoryId" dc:"分类ID"`
|
CategoryId int64 `json:"categoryId" dc:"分类ID"`
|
||||||
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
||||||
TenantModuleType beans.TenantModuleType `json:"tenantModuleType" dc:"租户模块类型"`
|
TenantModuleType beans.TenantModuleType `json:"tenantModuleType" dc:"租户模块类型"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAssetSkuRes 创建SKU响应
|
// CreateAssetSkuRes 创建SKU响应
|
||||||
type CreateAssetSkuRes struct {
|
type CreateAssetSkuRes struct {
|
||||||
Id *bson.ObjectID `json:"id" dc:"SKU ID"`
|
Id int64 `json:"id" dc:"SKU ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAssetSkuReq 更新SKU请求
|
// UpdateAssetSkuReq 更新SKU请求
|
||||||
type UpdateAssetSkuReq struct {
|
type UpdateAssetSkuReq struct {
|
||||||
g.Meta `path:"/updateAssetSku" method:"put" tags:"SKU管理" summary:"更新SKU" dc:"更新SKU信息"`
|
g.Meta `path:"/updateAssetSku" method:"put" tags:"SKU管理" summary:"更新SKU" dc:"更新SKU信息"`
|
||||||
|
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"SKU ID"`
|
Id int64 `json:"id" v:"required" dc:"SKU ID"`
|
||||||
SkuName string `json:"skuName" dc:"SKU名称"`
|
SkuName string `json:"skuName" dc:"SKU名称"`
|
||||||
SpecsCount int `json:"specsCount" dc:"规格数量"`
|
SpecsCount int `json:"specsCount" dc:"规格数量"`
|
||||||
SpecsUnit *entity.SpecsUnitKeyValue `json:"specsUnit" dc:"规格单位"`
|
SpecsUnit *entity.SpecsUnitKeyValue `json:"specsUnit" dc:"规格单位"`
|
||||||
@@ -50,36 +49,36 @@ type UpdateAssetSkuReq struct {
|
|||||||
Price int `json:"price" dc:"价格(分为单位)"`
|
Price int `json:"price" dc:"价格(分为单位)"`
|
||||||
Sort int `json:"sort" dc:"排序"`
|
Sort int `json:"sort" dc:"排序"`
|
||||||
Stock int `json:"stock" dc:"库存数量"`
|
Stock int `json:"stock" dc:"库存数量"`
|
||||||
Status *consts.AssetSkuStatus `json:"status" dc:"状态"`
|
Status consts.AssetSkuStatusType `json:"status" dc:"状态"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAssetSkuReq 删除SKU请求
|
// DeleteAssetSkuReq 删除SKU请求
|
||||||
type DeleteAssetSkuReq struct {
|
type DeleteAssetSkuReq struct {
|
||||||
g.Meta `path:"/deleteAssetSku" method:"delete" tags:"SKU管理" summary:"删除SKU" dc:"删除SKU"`
|
g.Meta `path:"/deleteAssetSku" method:"delete" tags:"SKU管理" summary:"删除SKU" dc:"删除SKU"`
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"SKU ID"`
|
Id int64 `json:"id" v:"required" dc:"SKU ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetSkuModuleReq 获取SKU详情请求
|
// GetAssetSkuModuleReq 获取SKU详情请求
|
||||||
type GetAssetSkuModuleReq struct {
|
type GetAssetSkuModuleReq struct {
|
||||||
g.Meta `path:"/getAssetSkuModule" method:"get" tags:"SKU管理" summary:"获取SKU模块详情" dc:"获取SKU模块详情"`
|
g.Meta `path:"/getAssetSkuModule" method:"get" tags:"SKU管理" summary:"获取SKU模块详情" dc:"获取SKU模块详情"`
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"SKU ID"`
|
Id int64 `json:"id" v:"required" dc:"SKU ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetSkuModuleRes 获取SKU详情响应
|
// GetAssetSkuModuleRes 获取SKU详情响应
|
||||||
type GetAssetSkuModuleRes struct {
|
type GetAssetSkuModuleRes struct {
|
||||||
AssetId *bson.ObjectID `json:"assetId"`
|
AssetId int64 `json:"assetId"`
|
||||||
ExpireAt *gtime.Time `json:"expireAt"`
|
ExpireAt *gtime.Time `json:"expireAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetSkuReq 获取SKU详情请求
|
// GetAssetSkuReq 获取SKU详情请求
|
||||||
type GetAssetSkuReq struct {
|
type GetAssetSkuReq struct {
|
||||||
g.Meta `path:"/getAssetSku" method:"get" tags:"SKU管理" summary:"获取SKU详情" dc:"获取SKU详情"`
|
g.Meta `path:"/getAssetSku" method:"get" tags:"SKU管理" summary:"获取SKU详情" dc:"获取SKU详情"`
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"SKU ID"`
|
Id int64 `json:"id" v:"required" dc:"SKU ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetSkuRes 获取SKU详情响应
|
// GetAssetSkuRes 获取SKU详情响应
|
||||||
type GetAssetSkuRes struct {
|
type GetAssetSkuRes struct {
|
||||||
*entity.AssetSku
|
*AssetSkuItem
|
||||||
ImgAddressPrefix string `json:"imgAddressPrefix"`
|
ImgAddressPrefix string `json:"imgAddressPrefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,25 +86,24 @@ type GetAssetSkuRes struct {
|
|||||||
type ListAssetSkuReq struct {
|
type ListAssetSkuReq struct {
|
||||||
g.Meta `path:"/listAssetSkus" method:"get" tags:"SKU管理" summary:"获取SKU列表" dc:"分页查询SKU列表,支持多条件筛选"`
|
g.Meta `path:"/listAssetSkus" method:"get" tags:"SKU管理" summary:"获取SKU列表" dc:"分页查询SKU列表,支持多条件筛选"`
|
||||||
*beans.Page
|
*beans.Page
|
||||||
OrderBy []beans.OrderBy `json:"orderBy" dc:"排序规则"`
|
Id int64 `json:"id" dc:"SKU ID"`
|
||||||
Id *bson.ObjectID `json:"id" dc:"SKU ID"`
|
AssetId int64 `json:"assetId" v:"required" dc:"资产ID"`
|
||||||
AssetId *bson.ObjectID `json:"assetId" v:"required" dc:"资产ID"`
|
Status consts.AssetSkuStatusType `json:"status" dc:"状态"`
|
||||||
Status *consts.AssetSkuStatus `json:"status" dc:"状态"`
|
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||||
Keyword string `json:"keyword" dc:"关键词搜索"`
|
MinPrice int `json:"minPrice" dc:"最低价格"`
|
||||||
MinPrice int `json:"minPrice" dc:"最低价格"`
|
MaxPrice int `json:"maxPrice" dc:"最高价格"`
|
||||||
MaxPrice int `json:"maxPrice" dc:"最高价格"`
|
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
||||||
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListAssetSkuRes 获取SKU列表响应
|
// ListAssetSkuRes 获取SKU列表响应
|
||||||
type ListAssetSkuRes struct {
|
type ListAssetSkuRes struct {
|
||||||
List []*AssetSkuListResItem `json:"list" dc:"SKU列表"`
|
List []AssetSkuItem `json:"list" dc:"SKU列表"`
|
||||||
Total int64 `json:"total" dc:"总数"`
|
Total int `json:"total" dc:"总数"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AssetSkuListResItem struct {
|
type AssetSkuItem struct {
|
||||||
Id *bson.ObjectID `json:"id"` // SKU ID
|
Id int64 `json:"id"` // SKU ID
|
||||||
AssetId *bson.ObjectID `json:"assetId"`
|
AssetId int64 `json:"assetId"`
|
||||||
AssetName string `json:"assetName"` // 资产名称
|
AssetName string `json:"assetName"` // 资产名称
|
||||||
SkuName string `json:"skuName"` // SKU名称
|
SkuName string `json:"skuName"` // SKU名称
|
||||||
SpecsCount int `json:"specsCount"` // 规格数量
|
SpecsCount int `json:"specsCount"` // 规格数量
|
||||||
@@ -115,7 +113,7 @@ type AssetSkuListResItem struct {
|
|||||||
UnlimitedStock bool `json:"unlimitedStock"` // 是否无库存限制
|
UnlimitedStock bool `json:"unlimitedStock"` // 是否无库存限制
|
||||||
Stock int `json:"stock"` // 库存数量
|
Stock int `json:"stock"` // 库存数量
|
||||||
Sort int `json:"sort"` // 排序
|
Sort int `json:"sort"` // 排序
|
||||||
Status *consts.AssetSkuStatus `json:"status"` // 状态:active/inactive/disabled
|
Status consts.AssetSkuStatusType `json:"status"` // 状态:active/inactive/disabled
|
||||||
StockMode stock.StockMode `json:"stockMode"` // 库存管理模式:1-明细模式 2-批次模式
|
StockMode stock.StockMode `json:"stockMode"` // 库存管理模式:1-明细模式 2-批次模式
|
||||||
CreatedAt *gtime.Time `json:"createdAt"` // 创建时间
|
CreatedAt *gtime.Time `json:"createdAt"` // 创建时间
|
||||||
UpdatedAt *gtime.Time `json:"updatedAt"` // 更新时间
|
UpdatedAt *gtime.Time `json:"updatedAt"` // 更新时间
|
||||||
|
|||||||
@@ -11,32 +11,32 @@ import (
|
|||||||
|
|
||||||
// CreateCategoryReq 创建分类请求
|
// CreateCategoryReq 创建分类请求
|
||||||
type CreateCategoryReq struct {
|
type CreateCategoryReq struct {
|
||||||
g.Meta `path:"/createCategory" method:"post" tags:"分类管理" summary:"创建分类" dc:"创建新的分类"`
|
g.Meta `path:"/createCategory" method:"post" tags:"分类管理" summary:"创建分类" dc:"创建新的分类"`
|
||||||
Name string `json:"name" v:"required" dc:"分类名称"`
|
Name string `json:"name" v:"required" dc:"分类名称"`
|
||||||
ParentId string `json:"parentId" dc:"父分类ID"`
|
ParentId int64 `json:"parentId" dc:"父分类ID"`
|
||||||
Image string `json:"image" dc:"分类图片"`
|
IsLeafNode *bool `json:"isLeafNode" dc:"是否叶子节点"`
|
||||||
Sort int `json:"sort" dc:"排序"`
|
Image string `json:"image" dc:"分类图片"`
|
||||||
Path string `json:"path" dc:"分类路径"`
|
Sort int `json:"sort" dc:"排序"`
|
||||||
Level int `json:"level" dc:"分类层级"`
|
Path string `json:"path" dc:"分类路径"`
|
||||||
Status consts.CategoryStatusType `json:"status" v:"in:1,0" default:"1" dc:"状态:1启用0禁用"`
|
Level int `json:"level" dc:"分类层级"`
|
||||||
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
|
Status consts.CategoryStatusType `json:"status" v:"in:1,0" default:"1" dc:"状态:1启用0禁用"`
|
||||||
|
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCategoryRes 创建分类响应
|
// CreateCategoryRes 创建分类响应
|
||||||
type CreateCategoryRes struct {
|
type CreateCategoryRes struct {
|
||||||
Bid string `json:"bid" dc:"分类ID"`
|
Id int64 `json:"id,string" dc:"分类ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCategoryReq 更新分类请求
|
// UpdateCategoryReq 更新分类请求
|
||||||
type UpdateCategoryReq struct {
|
type UpdateCategoryReq struct {
|
||||||
g.Meta `path:"/updateCategory" method:"put" tags:"分类管理" summary:"更新分类" dc:"更新分类信息"`
|
g.Meta `path:"/updateCategory" method:"put" tags:"分类管理" summary:"更新分类" dc:"更新分类信息"`
|
||||||
Id uint64 `json:"id" v:"required-without:Bid|integer#Id不能为空|Id必须是整数" dc:"分类ID"`
|
Id int64 `json:"id" v:"required" dc:"分类ID"`
|
||||||
Bid string `json:"bid" v:"required-without:Id|string#Bid不能为空|Bid必须是字符串" dc:"分类ID"`
|
|
||||||
Name string `json:"name" dc:"分类名称"`
|
Name string `json:"name" dc:"分类名称"`
|
||||||
ParentId string `json:"parentId" dc:"父分类ID"`
|
ParentId int64 `json:"parentId" dc:"父分类ID"`
|
||||||
Image string `json:"image" dc:"分类图片"`
|
Image string `json:"image" dc:"分类图片"`
|
||||||
Sort int `json:"sort" dc:"排序"`
|
Sort int `json:"sort" dc:"排序"`
|
||||||
IsLeafNode bool `json:"isLeafNode" dc:"是否叶子节点"`
|
IsLeafNode *bool `json:"isLeafNode" dc:"是否叶子节点"`
|
||||||
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
|
Attrs []entity.CategoryAttr `json:"attrs" dc:"分类属性"`
|
||||||
Status consts.CategoryStatusType `json:"status" dc:"状态:1启用0禁用"`
|
Status consts.CategoryStatusType `json:"status" dc:"状态:1启用0禁用"`
|
||||||
}
|
}
|
||||||
@@ -44,14 +44,14 @@ type UpdateCategoryReq struct {
|
|||||||
// UpdateCategoryStatusReq 更新分类状态请求
|
// UpdateCategoryStatusReq 更新分类状态请求
|
||||||
type UpdateCategoryStatusReq struct {
|
type UpdateCategoryStatusReq struct {
|
||||||
g.Meta `path:"/updateCategoryStatus" method:"put" tags:"分类管理" summary:"更新分类状态" dc:"更新分类状态"`
|
g.Meta `path:"/updateCategoryStatus" method:"put" tags:"分类管理" summary:"更新分类状态" dc:"更新分类状态"`
|
||||||
Id string `json:"id" v:"required" dc:"分类ID"`
|
Id int64 `json:"id" v:"required" dc:"分类ID"`
|
||||||
Status consts.CategoryStatusType `json:"status" v:"in:1,0" dc:"状态:1启用0禁用"`
|
Status consts.CategoryStatusType `json:"status" v:"in:1,0" dc:"状态:1启用0禁用"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteCategoryReq 删除分类请求
|
// DeleteCategoryReq 删除分类请求
|
||||||
type DeleteCategoryReq struct {
|
type DeleteCategoryReq struct {
|
||||||
g.Meta `path:"/deleteCategory" method:"delete" tags:"分类管理" summary:"删除分类" dc:"删除分类"`
|
g.Meta `path:"/deleteCategory" method:"delete" tags:"分类管理" summary:"删除分类" dc:"删除分类"`
|
||||||
Bid string `json:"bid" v:"required" dc:"分类ID"`
|
Id int64 `json:"id" v:"required" dc:"分类ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCategoryTreeReq 获取分类树请求
|
// GetCategoryTreeReq 获取分类树请求
|
||||||
@@ -67,8 +67,7 @@ type GetCategoryTreeRes struct {
|
|||||||
|
|
||||||
// CategoryTreeNode 分类树节点
|
// CategoryTreeNode 分类树节点
|
||||||
type CategoryTreeNode struct {
|
type CategoryTreeNode struct {
|
||||||
Id uint64 `json:"id" dc:"分类ID"`
|
Id int64 `json:"id,string" dc:"分类ID"`
|
||||||
Bid string `json:"bid" dc:"分类ID"`
|
|
||||||
Name string `json:"name" dc:"分类名称"`
|
Name string `json:"name" dc:"分类名称"`
|
||||||
Level int `json:"level" dc:"分类层级"`
|
Level int `json:"level" dc:"分类层级"`
|
||||||
Type string `json:"type" dc:"分类类型"`
|
Type string `json:"type" dc:"分类类型"`
|
||||||
@@ -85,8 +84,7 @@ type CategoryTreeNode struct {
|
|||||||
type ListCategoryReq struct {
|
type ListCategoryReq struct {
|
||||||
g.Meta `path:"/listCategories" method:"get" tags:"分类管理" summary:"获取分类列表" dc:"获取分类列表"`
|
g.Meta `path:"/listCategories" method:"get" tags:"分类管理" summary:"获取分类列表" dc:"获取分类列表"`
|
||||||
*beans.Page
|
*beans.Page
|
||||||
OrderBy []beans.OrderBy `json:"orderBy" dc:"排序规则"`
|
ParentId int64 `json:"parentId" dc:"父分类ID"`
|
||||||
ParentId string `json:"parentId" dc:"父分类ID"`
|
|
||||||
Status consts.CategoryStatusType `json:"status" dc:"状态:1启用0禁用"`
|
Status consts.CategoryStatusType `json:"status" dc:"状态:1启用0禁用"`
|
||||||
Keyword string `json:"keyword" dc:"关键词搜索"`
|
Keyword string `json:"keyword" dc:"关键词搜索"`
|
||||||
}
|
}
|
||||||
@@ -100,16 +98,14 @@ type ListCategoryRes struct {
|
|||||||
// GetCategoryReq 获取分类详情请求
|
// GetCategoryReq 获取分类详情请求
|
||||||
type GetCategoryReq struct {
|
type GetCategoryReq struct {
|
||||||
g.Meta `path:"/getCategory" method:"get" tags:"分类管理" summary:"获取分类详情" dc:"获取分类详情"`
|
g.Meta `path:"/getCategory" method:"get" tags:"分类管理" summary:"获取分类详情" dc:"获取分类详情"`
|
||||||
Id uint64 `json:"id" v:"required-without:Bid|integer#Id不能为空|Id必须是整数" dc:"分类ID"`
|
Id int64 `json:"id" v:"required" dc:"分类ID"`
|
||||||
Bid string `json:"bid" v:"required-without:Id|string#Bid不能为空|Bid必须是字符串" dc:"分类ID"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCategoryRes 获取分类详情响应
|
// GetCategoryRes 获取分类详情响应
|
||||||
type GetCategoryRes struct {
|
type GetCategoryRes struct {
|
||||||
Id uint64 `json:"id" dc:"分类ID"`
|
Id int64 `json:"id,string" dc:"分类ID"`
|
||||||
Bid string `json:"bid" dc:"分类ID"`
|
|
||||||
Name string `json:"name" dc:"分类名称"`
|
Name string `json:"name" dc:"分类名称"`
|
||||||
ParentId string `json:"parentId" dc:"父分类ID"`
|
ParentId int64 `json:"parentId,string" dc:"父分类ID"`
|
||||||
Path string `json:"path" dc:"分类路径"`
|
Path string `json:"path" dc:"分类路径"`
|
||||||
Level int `json:"level" dc:"分类层级"`
|
Level int `json:"level" dc:"分类层级"`
|
||||||
IsLeafNode bool `json:"isLeafNode" dc:"是否叶子节点"`
|
IsLeafNode bool `json:"isLeafNode" dc:"是否叶子节点"`
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package dto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"assets/consts/asset"
|
"assets/consts/asset"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ type GetSpecsUnitRes struct {
|
|||||||
// GetTenantModuleTypeReq 获取租户模块类型请求
|
// GetTenantModuleTypeReq 获取租户模块类型请求
|
||||||
type GetTenantModuleTypeReq struct {
|
type GetTenantModuleTypeReq struct {
|
||||||
g.Meta `path:"/getTenantModuleType" method:"get" tags:"枚举管理" summary:"获取租户模块类型" dc:"获取租户模块类型"`
|
g.Meta `path:"/getTenantModuleType" method:"get" tags:"枚举管理" summary:"获取租户模块类型" dc:"获取租户模块类型"`
|
||||||
AssetId string `json:"assetId" v:"required|in:physical,virtual,service" dc:"资产id"`
|
AssetId int64 `json:"assetId" v:"required|in:physical,virtual,service" dc:"资产id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTenantModuleTypeRes 获取租户模块类型响应
|
// GetTenantModuleTypeRes 获取租户模块类型响应
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ type CommonResp struct {
|
|||||||
type CreateBatchReq struct {
|
type CreateBatchReq struct {
|
||||||
g.Meta `path:"/createBatch" method:"post" tags:"库存批次管理" summary:"创建批次" dc:"创建新的库存批次"`
|
g.Meta `path:"/createBatch" method:"post" tags:"库存批次管理" summary:"创建批次" dc:"创建新的库存批次"`
|
||||||
|
|
||||||
AssetId *bson.ObjectID `json:"assetId" v:"required" dc:"资产ID"`
|
AssetId int64 `json:"assetId" v:"required" dc:"资产ID"`
|
||||||
AssetSkuId *bson.ObjectID `json:"assetSkuId" v:"required" dc:"SKU ID"`
|
AssetSkuId int64 `json:"assetSkuId" v:"required" dc:"SKU ID"`
|
||||||
BatchNo string `json:"batchNo" v:"required" dc:"批次号"`
|
BatchNo string `json:"batchNo" v:"required" dc:"批次号"`
|
||||||
BatchQty int `json:"batchQty" v:"required|min:1" dc:"批次数量"`
|
BatchQty int `json:"batchQty" v:"required|min:1" dc:"批次数量"`
|
||||||
AvailableQty int `json:"availableQty" v:"required|min:1" dc:"可用数量"`
|
AvailableQty int `json:"availableQty" v:"required|min:1" dc:"可用数量"`
|
||||||
@@ -42,9 +42,9 @@ type CreateBatchRes struct {
|
|||||||
type UpdateBatchReq struct {
|
type UpdateBatchReq struct {
|
||||||
g.Meta `path:"/updateBatch" method:"put" tags:"库存批次管理" summary:"更新批次" dc:"更新批次信息"`
|
g.Meta `path:"/updateBatch" method:"put" tags:"库存批次管理" summary:"更新批次" dc:"更新批次信息"`
|
||||||
|
|
||||||
Id *bson.ObjectID `json:"id" v:"required" dc:"批次ID"`
|
Id int64 `json:"id" v:"required" dc:"批次ID"`
|
||||||
BatchQty int `json:"batchQty" v:"required|min:1" dc:"批次数量"`
|
BatchQty int `json:"batchQty" v:"required|min:1" dc:"批次数量"`
|
||||||
AvailableQty int `json:"availableQty" v:"required|min:1" dc:"可用数量"`
|
AvailableQty int `json:"availableQty" v:"required|min:1" dc:"可用数量"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBatchReq 删除批次请求
|
// DeleteBatchReq 删除批次请求
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ type ListStockDetailsReq struct {
|
|||||||
|
|
||||||
*beans.Page
|
*beans.Page
|
||||||
OrderBy []beans.OrderBy `json:"orderBy" dc:"排序规则"`
|
OrderBy []beans.OrderBy `json:"orderBy" dc:"排序规则"`
|
||||||
AssetId *bson.ObjectID `json:"assetId" dc:"资产ID"`
|
AssetId int64 `json:"assetId" dc:"资产ID"`
|
||||||
AssetSkuId *bson.ObjectID `json:"assetSkuId" dc:"SKU ID"`
|
AssetSkuId int64 `json:"assetSkuId" dc:"SKU ID"`
|
||||||
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
CategoryPath string `json:"categoryPath" dc:"分类路径"`
|
||||||
Status stock.StockStatus `json:"status" dc:"状态"`
|
Status stock.StockStatus `json:"status" dc:"状态"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
type StockOperationReq struct {
|
type StockOperationReq struct {
|
||||||
g.Meta `path:"/stockOperation" method:"post" tags:"库存管理" summary:"库存操作(创建/修改)" dc:"库存操作(创建/修改)"`
|
g.Meta `path:"/stockOperation" method:"post" tags:"库存管理" summary:"库存操作(创建/修改)" dc:"库存操作(创建/修改)"`
|
||||||
|
|
||||||
AssetSkuId *bson.ObjectID `json:"assetSkuId" v:"required" dc:"关联资产SKU ID"`
|
AssetSkuId int64 `json:"assetSkuId" v:"required" dc:"关联资产SKU ID"`
|
||||||
Stock int `json:"stock" v:"required|min:1" dc:"库存数量"`
|
Stock int `json:"stock" v:"required|min:1" dc:"库存数量"`
|
||||||
// 批次模式专用字段
|
// 批次模式专用字段
|
||||||
BatchNo string `json:"batchNo" dc:"批次号(批次模式必填)"`
|
BatchNo string `json:"batchNo" dc:"批次号(批次模式必填)"`
|
||||||
ProductionDate *gtime.Time `json:"productionDate" dc:"生产日期(批次模式,格式:2006-01-02)"`
|
ProductionDate *gtime.Time `json:"productionDate" dc:"生产日期(批次模式,格式:2006-01-02)"`
|
||||||
@@ -22,8 +22,8 @@ type StockOperationReq struct {
|
|||||||
|
|
||||||
// StockPublishMessage 库存发布消息
|
// StockPublishMessage 库存发布消息
|
||||||
type StockPublishMessage struct {
|
type StockPublishMessage struct {
|
||||||
AssetId string `json:"assetId"`
|
AssetId int64 `json:"assetId"`
|
||||||
AssetSkuId string `json:"assetSkuId"`
|
AssetSkuId int64 `json:"assetSkuId"`
|
||||||
TenantId interface{} `json:"tenantId"`
|
TenantId interface{} `json:"tenantId"`
|
||||||
UserName interface{} `json:"userName"`
|
UserName interface{} `json:"userName"`
|
||||||
StockCount int `json:"stockCount"`
|
StockCount int `json:"stockCount"`
|
||||||
@@ -41,7 +41,7 @@ type StockPublishMessage struct {
|
|||||||
type GetStockFormFieldsReq struct {
|
type GetStockFormFieldsReq struct {
|
||||||
g.Meta `path:"/getStockFormFields" method:"get" tags:"库存管理" summary:"获取库存操作表单字段" dc:"根据资产SKU的库存管理模式动态返回表单字段"`
|
g.Meta `path:"/getStockFormFields" method:"get" tags:"库存管理" summary:"获取库存操作表单字段" dc:"根据资产SKU的库存管理模式动态返回表单字段"`
|
||||||
|
|
||||||
AssetSkuId *bson.ObjectID `json:"assetSkuId" v:"required" dc:"关联资产ID"`
|
AssetSkuId int64 `json:"assetSkuId" v:"required" dc:"关联资产ID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStockFormFieldsRes 获取库存表单字段响应
|
// GetStockFormFieldsRes 获取库存表单字段响应
|
||||||
|
|||||||
@@ -5,30 +5,74 @@ import (
|
|||||||
"assets/consts/stock"
|
"assets/consts/stock"
|
||||||
|
|
||||||
"gitea.com/red-future/common/beans"
|
"gitea.com/red-future/common/beans"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/encoding/gjson"
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
"github.com/gogf/gf/v2/os/gtime"
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type assetCol struct {
|
||||||
|
beans.SQLBaseCol
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
Type string
|
||||||
|
CategoryId string
|
||||||
|
CategoryPath string
|
||||||
|
ImageURL string
|
||||||
|
Images string
|
||||||
|
Status string
|
||||||
|
BasePrice string
|
||||||
|
Currency string
|
||||||
|
UnlimitedStock string
|
||||||
|
StockMode string
|
||||||
|
OnlineTime string
|
||||||
|
OfflineTime string
|
||||||
|
PhysicalAssetConfig string
|
||||||
|
ServiceAssetConfig string
|
||||||
|
VirtualAssetConfig string
|
||||||
|
Metadata string
|
||||||
|
TenantModuleType string
|
||||||
|
}
|
||||||
|
|
||||||
|
var AssetCol = assetCol{
|
||||||
|
SQLBaseCol: beans.DefSQLBaseCol,
|
||||||
|
Name: "name",
|
||||||
|
Description: "description",
|
||||||
|
Type: "type",
|
||||||
|
CategoryId: "category_id",
|
||||||
|
CategoryPath: "category_path",
|
||||||
|
ImageURL: "image_url",
|
||||||
|
Images: "images",
|
||||||
|
Status: "status",
|
||||||
|
BasePrice: "base_price",
|
||||||
|
Currency: "currency",
|
||||||
|
UnlimitedStock: "unlimited_stock",
|
||||||
|
StockMode: "stock_mode",
|
||||||
|
OnlineTime: "online_time",
|
||||||
|
OfflineTime: "offline_time",
|
||||||
|
PhysicalAssetConfig: "physical_asset_config",
|
||||||
|
ServiceAssetConfig: "service_asset_config",
|
||||||
|
VirtualAssetConfig: "virtual_asset_config",
|
||||||
|
Metadata: "metadata",
|
||||||
|
TenantModuleType: "tenant_module_type",
|
||||||
|
}
|
||||||
|
|
||||||
// Asset 资产实体
|
// Asset 资产实体
|
||||||
type Asset struct {
|
type Asset struct {
|
||||||
beans.SQLBaseDO `orm:",inherit"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, IsDeleted
|
beans.SQLBaseDO `orm:",inherit"`
|
||||||
// 基础信息
|
// 基础信息
|
||||||
Name string `orm:"name" json:"name" description:"资产名称"`
|
Name string `orm:"name" json:"name" description:"资产名称"`
|
||||||
Description string `orm:"description" json:"description" description:"资产描述"`
|
Description string `orm:"description" json:"description" description:"资产描述"`
|
||||||
Type consts.AssetType `orm:"type" json:"type" description:"资产类型:physical实物/virtual虚拟/service服务"`
|
Type consts.AssetType `orm:"type" json:"type" description:"资产类型:physical实物/virtual虚拟/service服务"`
|
||||||
CategoryId uint64 `orm:"category_id" json:"categoryId" description:"分类ID"`
|
CategoryId int64 `orm:"category_id" json:"categoryId" description:"分类ID"`
|
||||||
CategoryPath string `orm:"category_path" json:"categoryPath" description:"分类路径"`
|
CategoryPath string `orm:"category_path" json:"categoryPath" description:"分类路径"`
|
||||||
ImageURL string `orm:"image_url" json:"imageUrl" description:"主图URL"`
|
ImageURL string `orm:"image_url" json:"imageUrl" description:"主图URL"`
|
||||||
Images []string `orm:"images" json:"images" description:"图片列表(JSONB)"`
|
Images []string `orm:"images" json:"images" description:"图片列表(JSONB)"`
|
||||||
Status *consts.AssetStatus `orm:"status" json:"status" description:"资产状态:1启用/0停用"`
|
Status consts.AssetStatusType `orm:"status" json:"status" description:"资产状态:1启用/0停用"`
|
||||||
BasePrice int `orm:"base_price" json:"basePrice" description:"基础价格(分为单位)"`
|
BasePrice int `orm:"base_price" json:"basePrice" description:"基础价格(分为单位)"`
|
||||||
Currency string `orm:"currency" json:"currency" description:"货币单位,默认CNY"`
|
Currency string `orm:"currency" json:"currency" description:"货币单位,默认CNY"`
|
||||||
UnlimitedStock bool `orm:"unlimited_stock" json:"unlimitedStock" description:"是否无库存限制"`
|
UnlimitedStock bool `orm:"unlimited_stock" json:"unlimitedStock" description:"是否无库存限制"`
|
||||||
StockMode stock.StockMode `orm:"stock_mode" json:"stockMode" description:"库存管理模式:1-明细模式 2-批次模式"`
|
StockMode stock.StockMode `orm:"stock_mode" json:"stockMode" description:"库存管理模式:1-明细模式 2-批次模式"`
|
||||||
// 上线和下线时间配置(由定时任务处理资产状态)
|
OnlineTime *gtime.Time `orm:"online_time" json:"onlineTime,omitempty" description:"上线时间"` // 上线和下线时间配置(由定时任务处理资产状态)
|
||||||
OnlineTime *gtime.Time `orm:"online_time" json:"onlineTime,omitempty" description:"上线时间"`
|
OfflineTime *gtime.Time `orm:"offline_time" json:"offlineTime,omitempty" description:"下线时间"` // 上线和下线时间配置(由定时任务处理资产状态)
|
||||||
OfflineTime *gtime.Time `orm:"offline_time" json:"offlineTime,omitempty" description:"下线时间"`
|
|
||||||
|
|
||||||
// 类型专用配置 - 实物资产配置(JSONB)
|
// 类型专用配置 - 实物资产配置(JSONB)
|
||||||
PhysicalAssetConfig *gjson.Json `orm:"physical_asset_config" json:"physicalAssetConfig" description:"实物资产配置(JSONB)"`
|
PhysicalAssetConfig *gjson.Json `orm:"physical_asset_config" json:"physicalAssetConfig" description:"实物资产配置(JSONB)"`
|
||||||
@@ -37,7 +81,7 @@ type Asset struct {
|
|||||||
// 类型专用配置 - 虚拟资产配置(JSONB)
|
// 类型专用配置 - 虚拟资产配置(JSONB)
|
||||||
VirtualAssetConfig *gjson.Json `orm:"virtual_asset_config" json:"virtualAssetConfig" description:"虚拟资产配置(JSONB)"`
|
VirtualAssetConfig *gjson.Json `orm:"virtual_asset_config" json:"virtualAssetConfig" description:"虚拟资产配置(JSONB)"`
|
||||||
// 扩展字段(JSONB)
|
// 扩展字段(JSONB)
|
||||||
Metadata *gjson.Json `orm:"metadata" json:"metadata" description:"动态元数据(JSONB)"`
|
Metadata []gjson.Json `orm:"metadata" json:"metadata" description:"动态元数据(JSONB)"`
|
||||||
|
|
||||||
TenantModuleType string `orm:"tenant_module_type" json:"tenantModuleType" description:"租户模块类型"`
|
TenantModuleType beans.TenantModuleType `orm:"tenant_module_type" json:"tenantModuleType" description:"租户模块类型"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,43 +2,81 @@ package entity
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
consts "assets/consts/asset"
|
consts "assets/consts/asset"
|
||||||
"assets/consts/public"
|
|
||||||
"assets/consts/stock"
|
"assets/consts/stock"
|
||||||
"assets/model/config"
|
"assets/model/config"
|
||||||
|
|
||||||
"gitea.com/red-future/common/beans"
|
"gitea.com/red-future/common/beans"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
"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
|
||||||
|
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",
|
||||||
|
TenantModuleType: "tenant_module_type",
|
||||||
|
}
|
||||||
|
|
||||||
// AssetSku 资产SKU实体
|
// AssetSku 资产SKU实体
|
||||||
type AssetSku struct {
|
type AssetSku struct {
|
||||||
beans.MongoBaseDO `bson:",inline"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
|
beans.SQLBaseDO `orm:",inherit"`
|
||||||
AssetId *bson.ObjectID `bson:"assetId" json:"assetId"` // 关联资产ID
|
AssetId int64 `orm:"asset_id" json:"assetId"` // 关联资产ID
|
||||||
AssetName string `bson:"assetName" json:"assetName"` // 资产名称
|
AssetName string `orm:"asset_name" json:"assetName"` // 资产名称
|
||||||
SkuName string `bson:"skuName" json:"skuName"` // SKU名称
|
SkuName string `orm:"sku_name" json:"skuName"` // SKU名称
|
||||||
ImageURL string `bson:"imageUrl,omitempty" json:"imageUrl"` // SKU主图
|
ImageURL string `orm:"image_url,omitempty" json:"imageUrl"` // SKU主图
|
||||||
SpecValues []map[string]interface{} `bson:"specValues" json:"specValues"` // 规格值:{"颜色":"红色","尺寸":"L","时长":"1个月","平台":"抖音"}
|
SpecValues []gjson.Json `orm:"spec_values" json:"specValues"` // 规格值:{"颜色":"红色","尺寸":"L","时长":"1个月","平台":"抖音"}
|
||||||
Price int `bson:"price" json:"price"` // 价格(分为单位)
|
Price int `orm:"price" json:"price"` // 价格(分为单位)
|
||||||
UnlimitedStock bool `bson:"unlimitedStock" json:"unlimitedStock"` // 是否无库存限制
|
UnlimitedStock bool `orm:"unlimited_stock" json:"unlimitedStock"` // 是否无库存限制
|
||||||
Stock int `bson:"stock" json:"stock"` // 库存数量
|
Stock int `orm:"stock" json:"stock"` // 库存数量
|
||||||
SpecsCount int `bson:"specsCount" json:"specsCount"` // 规格数量
|
SpecsCount int `orm:"specs_count" json:"specsCount"` // 规格数量
|
||||||
SpecsUnit *SpecsUnitKeyValue `bson:"specsUnit" json:"specsUnit"` // 规格单位
|
SpecsUnit *gjson.Json `orm:"specs_unit" json:"specsUnit"` // 规格单位 SpecsUnitKeyValue
|
||||||
Sort int `bson:"sort" json:"sort"` // 排序
|
Sort int `orm:"sort" json:"sort"` // 排序
|
||||||
Status *consts.AssetSkuStatus `bson:"status" json:"status"` // 状态:active/inactive/disabled
|
Status consts.AssetSkuStatusType `orm:"status" json:"status"` // 状态:active/inactive/disabled
|
||||||
StockMode stock.StockMode `bson:"stockMode" json:"stockMode"` // 库存管理模式:1-明细模式 2-批次模式
|
StockMode stock.StockMode `orm:"stock_mode" json:"stockMode"` // 库存管理模式:1-明细模式 2-批次模式
|
||||||
CategoryId *bson.ObjectID `bson:"categoryId" json:"categoryId"` // 分类ID
|
CategoryId int64 `orm:"category_id" json:"categoryId"` // 分类ID
|
||||||
CategoryPath string `bson:"categoryPath" json:"categoryPath"` // 分类路径
|
CategoryPath string `orm:"category_path" json:"categoryPath"` // 分类路径
|
||||||
CapacityUnitType stock.CapacityUnitType `bson:"capacityUnitType" json:"capacityUnitType"` // 容量单位类型
|
CapacityUnitType stock.CapacityUnitType `orm:"capacity_unit_type" json:"capacityUnitType"` // 容量单位类型
|
||||||
Capacity config.Capacity `bson:"capacity" json:"capacity"` //容量
|
Capacity config.Capacity `orm:"capacity" json:"capacity"` // 容量
|
||||||
TenantModuleType beans.TenantModuleType `bson:"tenantModuleType" json:"tenantModuleType"`
|
TenantModuleType beans.TenantModuleType `orm:"tenant_module_type" json:"tenantModuleType"` // 租户模块类型
|
||||||
}
|
}
|
||||||
|
|
||||||
type SpecsUnitKeyValue struct {
|
type SpecsUnitKeyValue struct {
|
||||||
Key string `bson:"key" json:"key"` // 对应原有常量值
|
Key string `bson:"key" json:"key"` // 对应原有常量值
|
||||||
Value string `bson:"value" json:"value"` // 对应描述信息
|
Value string `bson:"value" json:"value"` // 对应描述信息
|
||||||
}
|
}
|
||||||
|
|
||||||
// CollectionName 获取集合名称
|
|
||||||
func (AssetSku) CollectionName() string {
|
|
||||||
return public.AssetSkuCollection
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
consts "assets/consts/category"
|
consts "assets/consts/category"
|
||||||
|
|
||||||
"gitea.com/red-future/common/beans"
|
"gitea.com/red-future/common/beans"
|
||||||
"github.com/gogf/gf/v2/encoding/gjson"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type categoryCol struct {
|
type categoryCol struct {
|
||||||
@@ -26,7 +25,7 @@ var CategoryCol = categoryCol{
|
|||||||
ParentId: "parent_id",
|
ParentId: "parent_id",
|
||||||
Path: "path",
|
Path: "path",
|
||||||
Level: "level",
|
Level: "level",
|
||||||
IsLeafNode: "isLeaf_node",
|
IsLeafNode: "is_leaf_node",
|
||||||
Sort: "sort",
|
Sort: "sort",
|
||||||
Image: "image",
|
Image: "image",
|
||||||
Attrs: "attrs",
|
Attrs: "attrs",
|
||||||
@@ -35,15 +34,16 @@ var CategoryCol = categoryCol{
|
|||||||
|
|
||||||
// Category 分类实体
|
// Category 分类实体
|
||||||
type Category struct {
|
type Category struct {
|
||||||
beans.SQLBaseDO `orm:",inherit"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, IsDeleted
|
beans.SQLBaseDO `orm:",inherit"`
|
||||||
Name string `orm:"name" json:"name"` // 分类名称
|
Name string `orm:"name" json:"name"` // 分类名称
|
||||||
ParentId string `orm:"parent_id" json:"parentId"` // 父分类ID,为空表示根分类
|
ParentId int64 `orm:"parent_id" json:"parentId"` // 父分类ID,为空表示根分类
|
||||||
Path string `orm:"path" json:"path"` // 分类路径,如:/root/parent/child
|
Path string `orm:"path" json:"path"` // 分类路径,如:/root/parent/child
|
||||||
Level int `orm:"level" json:"level"` // 分类层级
|
Level int `orm:"level" json:"level"` // 分类层级
|
||||||
IsLeafNode bool `orm:"isLeaf_node" json:"isLeafNode"` // 是叶子节点
|
IsLeafNode *bool `orm:"is_leaf_node" json:"isLeafNode"` // 是叶子节点
|
||||||
Sort int `orm:"sort" json:"sort"` // 排序
|
Sort int `orm:"sort" json:"sort"` // 排序
|
||||||
Image string `orm:"image" json:"image"` // 分类图片
|
Image string `orm:"image" json:"image"` // 分类图片
|
||||||
Attrs []gjson.Json `orm:"attrs" json:"attrs,omitempty"` // 分类属性
|
Status consts.CategoryStatusType `orm:"status" json:"status"` // 状态:1启用/0禁用
|
||||||
|
Attrs []CategoryAttr `orm:"attrs" json:"attrs,omitempty"` // 分类属性 CategoryAttr
|
||||||
// 使用场景说明:
|
// 使用场景说明:
|
||||||
// 1. 商品分类属性:为该分类下的商品定义标准化的属性模板,如服装分类可定义尺寸、颜色、材质等属性
|
// 1. 商品分类属性:为该分类下的商品定义标准化的属性模板,如服装分类可定义尺寸、颜色、材质等属性
|
||||||
// 2. 服务分类属性:为服务类目定义特性参数,如咨询服务可定义服务时长、服务方式、专业领域等
|
// 2. 服务分类属性:为服务类目定义特性参数,如咨询服务可定义服务时长、服务方式、专业领域等
|
||||||
@@ -51,20 +51,18 @@ type Category struct {
|
|||||||
// 4. 搜索筛选:基于分类属性进行商品筛选和搜索,提升用户体验
|
// 4. 搜索筛选:基于分类属性进行商品筛选和搜索,提升用户体验
|
||||||
// 5. 数据标准化:确保同一分类下的商品具有统一的属性结构,便于数据管理
|
// 5. 数据标准化:确保同一分类下的商品具有统一的属性结构,便于数据管理
|
||||||
// 支持的属性类型:文本(text)、数字(number)、日期(date)、单选(select)、多选(multi_select)、布尔(boolean)、图片(image)
|
// 支持的属性类型:文本(text)、数字(number)、日期(date)、单选(select)、多选(multi_select)、布尔(boolean)、图片(image)
|
||||||
Status consts.CategoryStatusType `orm:"status" json:"status"` // 状态:1启用/0禁用
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CategoryAttr 分类属性
|
// CategoryAttr 分类属性
|
||||||
// 用于定义分类下商品或服务的标准化属性模板,确保同类商品属性统一
|
// Attrs 用于定义分类下商品或服务的标准化属性模板,确保同类商品属性统一
|
||||||
type CategoryAttr struct {
|
type CategoryAttr struct {
|
||||||
Name string `json:"name"` // 属性名称,如:尺寸、颜色、品牌等
|
Name string `json:"name"` // 属性名称,如:尺寸、颜色、品牌等
|
||||||
Type string `json:"type"` // 属性类型:text文本/number数字/date日期/select选择/multi_select多选/boolean布尔/image图片
|
Type string `json:"type"` // 属性类型:text文本/number数字/date日期/select选择/multi_select多选/boolean布尔/image图片
|
||||||
DictType string `json:"dictType"` // 字典类型,如果是select/multi_select类型时有效
|
DictType string `json:"dictType"` // 字典类型,如果是select/multi_select类型时有效
|
||||||
Required bool `json:"required"` // 是否必填,true表示商品发布时必须填写此属性
|
Required bool `json:"required"` // 是否必填,true表示商品发布时必须填写此属性
|
||||||
Options []FieldOption `json:"options"` // 选项配置,JSON字符串格式,用于select/multi_select类型的可选值列表
|
Options []FieldOption `json:"options"` // 选项配置,JSON字符串格式,用于select/multi_select类型的可选值列表 // 示例:'{"options":[{"label":"红色","value":"red"},{"label":"蓝色","value":"blue"}]}'
|
||||||
// 示例:'{"options":[{"label":"红色","value":"red"},{"label":"蓝色","value":"blue"}]}'
|
Description string `json:"description"` // 属性描述,向用户说明此属性的具体含义和填写要求
|
||||||
Description string `json:"description"` // 属性描述,向用户说明此属性的具体含义和填写要求
|
Sort int `json:"sort"` // 排序权重,数值越小排序越靠前,用于属性在界面的显示顺序
|
||||||
Sort int `json:"sort"` // 排序权重,数值越小排序越靠前,用于属性在界面的显示顺序
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldOption 字段选项
|
// FieldOption 字段选项
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import (
|
|||||||
type StockDetails struct {
|
type StockDetails struct {
|
||||||
beans.MongoBaseDO `bson:",inline"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
|
beans.MongoBaseDO `bson:",inline"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
|
||||||
|
|
||||||
AssetId *bson.ObjectID `bson:"assetId" json:"assetId"` // 关联资产ID
|
AssetId int64 `bson:"assetId" json:"assetId"` // 关联资产ID
|
||||||
AssetSkuId *bson.ObjectID `bson:"assetSkuId" json:"assetSkuId"` // 关联资产SKU ID
|
AssetSkuId int64 `bson:"assetSkuId" json:"assetSkuId"` // 关联资产SKU ID
|
||||||
Status stock.StockStatus `bson:"status" json:"status"` // 库存状态
|
Status stock.StockStatus `bson:"status" json:"status"` // 库存状态
|
||||||
OrderId *bson.ObjectID `bson:"orderId" json:"orderId"` // 关联订单ID(如果有)
|
OrderId *bson.ObjectID `bson:"orderId" json:"orderId"` // 关联订单ID(如果有)
|
||||||
LockExpire *gtime.Time `bson:"lockExpire" json:"lockExpire"` // 锁定过期时间
|
LockExpire *gtime.Time `bson:"lockExpire" json:"lockExpire"` // 锁定过期时间
|
||||||
|
|||||||
@@ -3,18 +3,19 @@ package service
|
|||||||
import (
|
import (
|
||||||
"assets/consts/stock"
|
"assets/consts/stock"
|
||||||
dao "assets/dao/asset"
|
dao "assets/dao/asset"
|
||||||
"assets/dao/base"
|
|
||||||
dto "assets/model/dto/asset"
|
dto "assets/model/dto/asset"
|
||||||
|
enumDto "assets/model/dto/enum"
|
||||||
|
entity "assets/model/entity/asset"
|
||||||
|
service "assets/service/enum"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"gitea.com/red-future/common/http"
|
"gitea.com/red-future/common/http"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
|
|
||||||
"gitea.com/red-future/common/beans"
|
"gitea.com/red-future/common/beans"
|
||||||
"gitea.com/red-future/common/minio"
|
"gitea.com/red-future/common/minio"
|
||||||
"gitea.com/red-future/common/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type asset struct{}
|
type asset struct{}
|
||||||
@@ -45,38 +46,8 @@ func (s *asset) Create(ctx context.Context, req *dto.CreateAssetReq) (res *dto.C
|
|||||||
if err = http.Get(ctx, "admin-go/api/v1/system/user/checkIsSuperAdmin", headers, &isSuperAdmin); err != nil {
|
if err = http.Get(ctx, "admin-go/api/v1/system/user/checkIsSuperAdmin", headers, &isSuperAdmin); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isSuperAdmin {
|
if !isSuperAdmin {
|
||||||
req.StockMode = stock.StockModeDetail
|
req.StockMode = stock.StockModeDetail
|
||||||
|
|
||||||
//var getUserInfo beans.User
|
|
||||||
//getUserInfo, err = utils.GetUserInfo(ctx)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//var get *gvar.Var
|
|
||||||
//get, err = message.GetRedisClientTest("test").Get(ctx, fmt.Sprintf("module_tenant:tenantId-%v", getUserInfo.TenantId))
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//if !g.IsEmpty(get.String()) {
|
|
||||||
// list := new(beans.ModuleTenant)
|
|
||||||
// if err = json.Unmarshal(get.Bytes(), &list); err != nil {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// req.TenantModuleType = list.TenantModuleType
|
|
||||||
//} else {
|
|
||||||
// moduleTenantRes := new(beans.ModuleTenant)
|
|
||||||
// err = message.CallRPC(ctx, "moduleService.AddRedisByTenantId", map[string]interface{}{"tenantId": getUserInfo.TenantId}, moduleTenantRes)
|
|
||||||
// if err != nil {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if !g.IsEmpty(moduleTenantRes.TenantModuleType) {
|
|
||||||
// req.TenantModuleType = moduleTenantRes.TenantModuleType
|
|
||||||
// } else {
|
|
||||||
// return nil, errors.New("您未开通此模块,请开通后再使用")
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
} else {
|
} else {
|
||||||
req.TenantModuleType = beans.TenantModuleTypePlatform
|
req.TenantModuleType = beans.TenantModuleTypePlatform
|
||||||
}
|
}
|
||||||
@@ -87,7 +58,7 @@ func (s *asset) Create(ctx context.Context, req *dto.CreateAssetReq) (res *dto.C
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
res = &dto.CreateAssetRes{
|
res = &dto.CreateAssetRes{
|
||||||
Id: gconv.Uint64(id),
|
Id: id,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -98,79 +69,88 @@ func (s *asset) List(ctx context.Context, req *dto.ListAssetReq) (res *dto.ListA
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user, err := utils.GetUserInfo(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(user)
|
|
||||||
res = &dto.ListAssetRes{
|
res = &dto.ListAssetRes{
|
||||||
Total: total,
|
Total: total,
|
||||||
}
|
}
|
||||||
err = utils.Struct(assetList, &res.List)
|
err = gconv.Struct(assetList, &res.List)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOne 获取单个资产
|
// GetOne 获取单个资产
|
||||||
func (s *asset) GetOne(ctx context.Context, req *dto.GetAssetReq) (res *dto.GetAssetRes, err error) {
|
func (s *asset) GetOne(ctx context.Context, req *dto.GetAssetReq) (res *dto.GetAssetRes, err error) {
|
||||||
assetOne, err := dao.Asset.GetOne(ctx, req)
|
var assetOne *entity.Asset
|
||||||
|
if assetOne, err = dao.Asset.GetOne(ctx, req); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var assetListItem *dto.AssetItem
|
||||||
|
if err = gconv.Struct(assetOne, assetListItem); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getCategoryRes, err := dao.Category.GetOne(ctx, &dto.GetCategoryReq{
|
||||||
|
Id: assetOne.CategoryId,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO: CategoryId类型不匹配,需要同步修改category为uint64
|
|
||||||
// getCategoryRes, err := dao.Category.GetOne(ctx, &dto.GetCategoryReq{
|
|
||||||
// Id: assetOne.CategoryId,
|
|
||||||
// })
|
|
||||||
// if err != nil {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
return &dto.GetAssetRes{
|
return &dto.GetAssetRes{
|
||||||
Asset: assetOne,
|
AssetItem: assetListItem,
|
||||||
CategoryName: "", // getCategoryRes.Name,
|
CategoryName: getCategoryRes.Name,
|
||||||
ImgAddressPrefix: minio.GetFileAddressPrefix(ctx),
|
ImgAddressPrefix: minio.GetFileAddressPrefix(ctx),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetAndSku 获取资产和Sku详情
|
// GetAssetAndSku 获取资产和Sku详情
|
||||||
func (s *asset) GetAssetAndSku(ctx context.Context, req *dto.GetAssetAndSkuReq) (res *dto.GetAssetAndSkuRes, err error) {
|
func (s *asset) GetAssetAndSku(ctx context.Context, req *dto.GetAssetAndSkuReq) (res *dto.GetAssetAndSkuRes, err error) {
|
||||||
// 跳过租户ID过滤获取资产
|
var updateReq *dto.GetAssetReq
|
||||||
// TODO: AssetId 类型不匹配,bson.ObjectID 需要转换为 uint64
|
if err = gconv.Struct(req, &updateReq); err != nil {
|
||||||
// 使用 SkipTenantId 跳过租户ID过滤
|
return
|
||||||
assetOne, err := dao.Asset.GetOneById(base.SkipTenantId(ctx), 0)
|
}
|
||||||
_ = req.AssetId
|
assetOne, err := dao.Asset.GetOne(ctx, updateReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO: AssetId类型不匹配,需要适配
|
var assetListItem *dto.AssetItem
|
||||||
// moduleType, err := service.Enum.GetTenantModuleType(ctx, &enumDto.GetTenantModuleTypeReq{AssetId: req.AssetId.Hex()})
|
if err = gconv.Struct(assetOne, assetListItem); err != nil {
|
||||||
// if err != nil {
|
return
|
||||||
// return
|
}
|
||||||
// }
|
moduleType, err := service.Enum.GetTenantModuleType(ctx, &enumDto.GetTenantModuleTypeReq{AssetId: assetOne.Id})
|
||||||
// TODO: AssetId类型不匹配,需要同步修改AssetSku为uint64
|
if err != nil {
|
||||||
// skus, _, err := dao.AssetSku.List(ctx, &dto.ListAssetSkuReq{AssetId: req.AssetId}, true)
|
return
|
||||||
// if err != nil {
|
}
|
||||||
// return
|
skus, _, err := dao.AssetSku.List(ctx, &dto.ListAssetSkuReq{AssetId: assetOne.Id})
|
||||||
// }
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var assetSkuListResItem []dto.AssetSkuItem
|
||||||
|
if err = gconv.Structs(skus, assetSkuListResItem); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return &dto.GetAssetAndSkuRes{
|
return &dto.GetAssetAndSkuRes{
|
||||||
Asset: assetOne,
|
AssetItem: assetListItem,
|
||||||
Skus: nil, // skus,
|
Skus: assetSkuListResItem,
|
||||||
TenantModuleType: nil, // moduleType.Options,
|
TenantModuleType: moduleType.Options,
|
||||||
ImgAddressPrefix: minio.GetFileAddressPrefix(ctx),
|
ImgAddressPrefix: minio.GetFileAddressPrefix(ctx),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update 更新资产
|
// Update 更新资产
|
||||||
func (s *asset) Update(ctx context.Context, req *dto.UpdateAssetReq) error {
|
func (s *asset) Update(ctx context.Context, req *dto.UpdateAssetReq) (err error) {
|
||||||
return dao.Asset.Update(ctx, req)
|
_, err = dao.Asset.Update(ctx, req)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateStatus 更新资产状态
|
// UpdateStatus 更新资产状态
|
||||||
func (s *asset) UpdateStatus(ctx context.Context, req *dto.UpdateAssetStatusReq) (err error) {
|
func (s *asset) UpdateStatus(ctx context.Context, req *dto.UpdateAssetStatusReq) (err error) {
|
||||||
var updateReq *dto.UpdateAssetReq
|
var updateReq *dto.UpdateAssetReq
|
||||||
err = utils.Struct(req, &updateReq)
|
if err = gconv.Struct(req, &updateReq); err != nil {
|
||||||
return dao.Asset.Update(ctx, updateReq)
|
return err
|
||||||
|
}
|
||||||
|
_, err = dao.Asset.Update(ctx, updateReq)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete 删除资产
|
// Delete 删除资产
|
||||||
func (s *asset) Delete(ctx context.Context, req *dto.DeleteAssetReq) error {
|
func (s *asset) Delete(ctx context.Context, req *dto.DeleteAssetReq) (err error) {
|
||||||
return dao.Asset.DeleteFake(ctx, req)
|
_, err = dao.Asset.Delete(ctx, req)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
"gitea.com/red-future/common/utils"
|
"gitea.com/red-future/common/utils"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type assetSku struct{}
|
type assetSku struct{}
|
||||||
@@ -28,7 +27,7 @@ func (s *assetSku) CreateAssetSku(ctx context.Context, req *dto.CreateAssetSkuRe
|
|||||||
return nil, errors.New("关联资产不存在")
|
return nil, errors.New("关联资产不存在")
|
||||||
}
|
}
|
||||||
// 根据资产ID查询SKU列表(用于下面验证,自定义属性和sku名称重不重复)
|
// 根据资产ID查询SKU列表(用于下面验证,自定义属性和sku名称重不重复)
|
||||||
skusList, _, err := dao.AssetSku.List(ctx, &dto.ListAssetSkuReq{AssetId: req.AssetId}, false)
|
skusList, _, err := dao.AssetSku.List(ctx, &dto.ListAssetSkuReq{AssetId: assetEntity.Id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -39,26 +38,23 @@ func (s *assetSku) CreateAssetSku(ctx context.Context, req *dto.CreateAssetSkuRe
|
|||||||
}
|
}
|
||||||
req.UnlimitedStock = assetEntity.UnlimitedStock
|
req.UnlimitedStock = assetEntity.UnlimitedStock
|
||||||
req.StockMode = assetEntity.StockMode
|
req.StockMode = assetEntity.StockMode
|
||||||
// TODO: 类型不匹配 uint64 vs *bson.ObjectID
|
req.CategoryId = assetEntity.CategoryId
|
||||||
// req.CategoryId = assetEntity.CategoryId
|
|
||||||
req.CategoryPath = assetEntity.CategoryPath
|
req.CategoryPath = assetEntity.CategoryPath
|
||||||
// TODO: 类型不匹配 string vs beans.TenantModuleType
|
req.TenantModuleType = assetEntity.TenantModuleType
|
||||||
// req.TenantModuleType = assetEntity.TenantModuleType
|
|
||||||
// 插入数据库
|
// 插入数据库
|
||||||
ids, err := dao.AssetSku.Insert(ctx, req)
|
id, err := dao.AssetSku.Insert(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
id := ids[0].(bson.ObjectID)
|
|
||||||
res = &dto.CreateAssetSkuRes{
|
res = &dto.CreateAssetSkuRes{
|
||||||
Id: &id,
|
Id: id,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAssetSku 更新SKU
|
// UpdateAssetSku 更新SKU
|
||||||
func (s *assetSku) UpdateAssetSku(ctx context.Context, req *dto.UpdateAssetSkuReq) error {
|
func (s *assetSku) UpdateAssetSku(ctx context.Context, req *dto.UpdateAssetSkuReq) (err error) {
|
||||||
getOne, err := dao.AssetSku.GetOne(ctx, &dto.GetAssetSkuReq{Id: req.Id}, false)
|
getOne, err := dao.AssetSku.GetOne(ctx, &dto.GetAssetSkuReq{Id: req.Id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("SUK不存在")
|
return errors.New("SUK不存在")
|
||||||
}
|
}
|
||||||
@@ -78,7 +74,8 @@ func (s *assetSku) UpdateAssetSku(ctx context.Context, req *dto.UpdateAssetSkuRe
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 更新数据库
|
// 更新数据库
|
||||||
return dao.AssetSku.Update(ctx, req)
|
_, err = dao.AssetSku.Update(ctx, req)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *assetSku) parameterValidation(ctx context.Context, assetEntity *entity.Asset, list []entity.AssetSku, skuName string, specValues []map[string]interface{}) (err error) {
|
func (s *assetSku) parameterValidation(ctx context.Context, assetEntity *entity.Asset, list []entity.AssetSku, skuName string, specValues []map[string]interface{}) (err error) {
|
||||||
@@ -112,7 +109,8 @@ func (s *assetSku) parameterValidation(ctx context.Context, assetEntity *entity.
|
|||||||
for key, subValue := range specValues {
|
for key, subValue := range specValues {
|
||||||
// 1. 检查请求参数 map 中是否存在该键
|
// 1. 检查请求参数 map 中是否存在该键
|
||||||
for _, subValues := range list.SpecValues {
|
for _, subValues := range list.SpecValues {
|
||||||
parentValue, ok := subValues[gconv.String(key)]
|
mapSubValues := gconv.Map(subValues)
|
||||||
|
parentValue, ok := mapSubValues[gconv.String(key)]
|
||||||
if ok {
|
if ok {
|
||||||
// 2. 检查对应的值是否相等
|
// 2. 检查对应的值是否相等
|
||||||
if reflect.DeepEqual(parentValue, subValue) {
|
if reflect.DeepEqual(parentValue, subValue) {
|
||||||
@@ -146,13 +144,14 @@ func (s *assetSku) parameterValidation(ctx context.Context, assetEntity *entity.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAssetSku 删除SKU(软删除)
|
// DeleteAssetSku 删除SKU(软删除)
|
||||||
func (s *assetSku) DeleteAssetSku(ctx context.Context, req *dto.DeleteAssetSkuReq) error {
|
func (s *assetSku) DeleteAssetSku(ctx context.Context, req *dto.DeleteAssetSkuReq) (err error) {
|
||||||
return dao.AssetSku.DeleteFake(ctx, req)
|
_, err = dao.AssetSku.Delete(ctx, req)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAssetSku 获取SKU详情
|
// GetAssetSku 获取SKU详情
|
||||||
func (s *assetSku) GetAssetSku(ctx context.Context, req *dto.GetAssetSkuReq) (res *dto.GetAssetSkuRes, err error) {
|
func (s *assetSku) GetAssetSku(ctx context.Context, req *dto.GetAssetSkuReq) (res *dto.GetAssetSkuRes, err error) {
|
||||||
one, err := dao.AssetSku.GetOne(ctx, req, false)
|
one, err := dao.AssetSku.GetOne(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -163,7 +162,7 @@ func (s *assetSku) GetAssetSku(ctx context.Context, req *dto.GetAssetSkuReq) (re
|
|||||||
// ListAssetSkus 获取SKU列表
|
// ListAssetSkus 获取SKU列表
|
||||||
func (s *assetSku) ListAssetSkus(ctx context.Context, req *dto.ListAssetSkuReq) (res *dto.ListAssetSkuRes, err error) {
|
func (s *assetSku) ListAssetSkus(ctx context.Context, req *dto.ListAssetSkuReq) (res *dto.ListAssetSkuRes, err error) {
|
||||||
// 查询数据库
|
// 查询数据库
|
||||||
list, total, err := dao.AssetSku.List(ctx, req, false)
|
list, total, err := dao.AssetSku.List(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -176,14 +175,19 @@ func (s *assetSku) ListAssetSkus(ctx context.Context, req *dto.ListAssetSkuReq)
|
|||||||
|
|
||||||
// GetAssetSkuModule 获取SKU详情
|
// GetAssetSkuModule 获取SKU详情
|
||||||
func (s *assetSku) GetAssetSkuModule(ctx context.Context, req *dto.GetAssetSkuModuleReq) (res *dto.GetAssetSkuModuleRes, err error) {
|
func (s *assetSku) GetAssetSkuModule(ctx context.Context, req *dto.GetAssetSkuModuleReq) (res *dto.GetAssetSkuModuleRes, err error) {
|
||||||
one, err := dao.AssetSku.GetOne(ctx, &dto.GetAssetSkuReq{Id: req.Id}, true)
|
one, err := dao.AssetSku.GetOne(ctx, &dto.GetAssetSkuReq{Id: req.Id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res = &dto.GetAssetSkuModuleRes{}
|
res = &dto.GetAssetSkuModuleRes{}
|
||||||
// 计算到期时间
|
// 计算到期时间
|
||||||
if one.SpecsUnit != nil && one.SpecsCount > 0 {
|
if one.SpecsUnit != nil && one.SpecsCount > 0 {
|
||||||
durationType := public.DurationType(one.SpecsUnit.Key)
|
var specsUnit *entity.SpecsUnitKeyValue
|
||||||
|
err = gconv.Struct(one.SpecsUnit, &specsUnit)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
durationType := public.DurationType(specsUnit.Key)
|
||||||
res.ExpireAt = durationType.AddTime(one.SpecsCount)
|
res.ExpireAt = durationType.AddTime(one.SpecsCount)
|
||||||
res.AssetId = one.AssetId
|
res.AssetId = one.AssetId
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"gitea.com/red-future/common/db/gfdb"
|
"gitea.com/red-future/common/db/gfdb"
|
||||||
"gitea.com/red-future/common/utils"
|
|
||||||
"github.com/gogf/gf/v2/database/gdb"
|
"github.com/gogf/gf/v2/database/gdb"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
|
|
||||||
@@ -29,22 +28,20 @@ var Category = new(CategoryService)
|
|||||||
func (s *CategoryService) Create(ctx context.Context, req *dto.CreateCategoryReq) (res *dto.CreateCategoryRes, err error) {
|
func (s *CategoryService) Create(ctx context.Context, req *dto.CreateCategoryReq) (res *dto.CreateCategoryRes, err error) {
|
||||||
|
|
||||||
// 构建分类路径和层级
|
// 构建分类路径和层级
|
||||||
parent, err := dao.Category.GetOne(ctx, &dto.GetCategoryReq{Bid: req.ParentId})
|
parent, err := dao.Category.GetOne(ctx, &dto.GetCategoryReq{Id: req.ParentId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Path = parent.Path + DefaultPathSeparator + req.ParentId
|
if g.IsEmpty(parent) {
|
||||||
|
return nil, errors.New("父分类不存在")
|
||||||
|
}
|
||||||
|
req.Path = parent.Path + DefaultPathSeparator + gconv.String(req.ParentId)
|
||||||
req.Level = parent.Level + 1
|
req.Level = parent.Level + 1
|
||||||
|
|
||||||
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||||
var r *entity.Category
|
var id int64
|
||||||
|
req.IsLeafNode = gconv.PtrBool(true)
|
||||||
if r, err = dao.Category.Insert(ctx, req); err != nil {
|
if id, err = dao.Category.Insert(ctx, req); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新新创建分类的 IsLeafNode 为 true
|
|
||||||
if err = s.updateLeafNode(ctx, r.Bid, true); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +51,7 @@ func (s *CategoryService) Create(ctx context.Context, req *dto.CreateCategoryReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
res = &dto.CreateCategoryRes{
|
res = &dto.CreateCategoryRes{
|
||||||
Bid: r.Bid,
|
Id: id,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -64,11 +61,12 @@ func (s *CategoryService) Create(ctx context.Context, req *dto.CreateCategoryReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
// updateLeafNode 更新分类的 IsLeafNode 字段
|
// updateLeafNode 更新分类的 IsLeafNode 字段
|
||||||
func (s *CategoryService) updateLeafNode(ctx context.Context, categoryId string, isLeaf bool) error {
|
func (s *CategoryService) updateLeafNode(ctx context.Context, categoryId int64, isLeaf bool) (err error) {
|
||||||
return dao.Category.Update(ctx, &dto.UpdateCategoryReq{
|
_, err = dao.Category.Update(ctx, &dto.UpdateCategoryReq{
|
||||||
Bid: categoryId,
|
Id: categoryId,
|
||||||
IsLeafNode: isLeaf,
|
IsLeafNode: &isLeaf,
|
||||||
})
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOne 获取单个分类
|
// GetOne 获取单个分类
|
||||||
@@ -78,11 +76,12 @@ func (s *CategoryService) GetOne(ctx context.Context, req *dto.GetCategoryReq) (
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
res := new(dto.GetCategoryRes)
|
res := new(dto.GetCategoryRes)
|
||||||
err = utils.Struct(one, &res)
|
|
||||||
if err != nil {
|
if err = gconv.Scan(one, &res); err != nil {
|
||||||
return nil, err
|
panic(err)
|
||||||
}
|
}
|
||||||
return res, nil
|
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// List 获取分类列表
|
// List 获取分类列表
|
||||||
@@ -107,7 +106,7 @@ func (s *CategoryService) GetTree(ctx context.Context, req *dto.GetCategoryTreeR
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tree, err := s.buildTree(ctx, list, "")
|
tree, err := s.buildTree(ctx, list, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -115,7 +114,7 @@ func (s *CategoryService) GetTree(ctx context.Context, req *dto.GetCategoryTreeR
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildTree 构建树形结构
|
// buildTree 构建树形结构
|
||||||
func (s *CategoryService) buildTree(ctx context.Context, categories []entity.Category, parentId string) ([]*dto.CategoryTreeNode, error) {
|
func (s *CategoryService) buildTree(ctx context.Context, categories []entity.Category, parentId int64) ([]*dto.CategoryTreeNode, error) {
|
||||||
tree := make([]*dto.CategoryTreeNode, 0)
|
tree := make([]*dto.CategoryTreeNode, 0)
|
||||||
for _, cat := range categories {
|
for _, cat := range categories {
|
||||||
if !s.isChildOf(cat.ParentId, parentId) {
|
if !s.isChildOf(cat.ParentId, parentId) {
|
||||||
@@ -131,7 +130,7 @@ func (s *CategoryService) buildTree(ctx context.Context, categories []entity.Cat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// isChildOf 判断分类是否为指定父节点的子节点
|
// isChildOf 判断分类是否为指定父节点的子节点
|
||||||
func (s *CategoryService) isChildOf(childParentId, parentId string) bool {
|
func (s *CategoryService) isChildOf(childParentId, parentId int64) bool {
|
||||||
if g.IsEmpty(childParentId) && g.IsEmpty(parentId) {
|
if g.IsEmpty(childParentId) && g.IsEmpty(parentId) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -147,7 +146,7 @@ func (s *CategoryService) convertToTreeNode(ctx context.Context, category *entit
|
|||||||
if err := gconv.Struct(&category, &res); err != nil {
|
if err := gconv.Struct(&category, &res); err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
children, err := s.buildTree(ctx, allCategories, category.Bid)
|
children, err := s.buildTree(ctx, allCategories, category.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@@ -157,7 +156,7 @@ func (s *CategoryService) convertToTreeNode(ctx context.Context, category *entit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hasChildren 检查分类是否有子分类
|
// hasChildren 检查分类是否有子分类
|
||||||
func (s *CategoryService) hasChildren(ctx context.Context, parentId string) (bool, error) {
|
func (s *CategoryService) hasChildren(ctx context.Context, parentId int64) (bool, error) {
|
||||||
count, err := dao.Category.Count(ctx, &dto.ListCategoryReq{
|
count, err := dao.Category.Count(ctx, &dto.ListCategoryReq{
|
||||||
ParentId: parentId,
|
ParentId: parentId,
|
||||||
})
|
})
|
||||||
@@ -165,7 +164,7 @@ func (s *CategoryService) hasChildren(ctx context.Context, parentId string) (boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// updateLeafNodeIfNoChildren 如果父分类没有子分类了,更新为叶子节点
|
// updateLeafNodeIfNoChildren 如果父分类没有子分类了,更新为叶子节点
|
||||||
func (s *CategoryService) updateLeafNodeIfNoChildren(ctx context.Context, parentId string) error {
|
func (s *CategoryService) updateLeafNodeIfNoChildren(ctx context.Context, parentId int64) error {
|
||||||
hasChildren, err := s.hasChildren(ctx, parentId)
|
hasChildren, err := s.hasChildren(ctx, parentId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -174,12 +173,13 @@ func (s *CategoryService) updateLeafNodeIfNoChildren(ctx context.Context, parent
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateStatus 更新分类状态
|
// UpdateStatus 更新分类状态
|
||||||
func (s *CategoryService) UpdateStatus(ctx context.Context, req *dto.UpdateCategoryStatusReq) error {
|
func (s *CategoryService) UpdateStatus(ctx context.Context, req *dto.UpdateCategoryStatusReq) (err error) {
|
||||||
var updateReq *dto.UpdateCategoryReq
|
var updateReq *dto.UpdateCategoryReq
|
||||||
if err := gconv.Struct(req, &updateReq); err != nil {
|
if err = gconv.Struct(req, &updateReq); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
return dao.Category.Update(ctx, updateReq)
|
_, err = dao.Category.Update(ctx, updateReq)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update 更新分类
|
// Update 更新分类
|
||||||
@@ -189,7 +189,7 @@ func (s *CategoryService) Update(ctx context.Context, req *dto.UpdateCategoryReq
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||||
if err = dao.Category.Update(ctx, req); err != nil {
|
if rows, err := dao.Category.Update(ctx, req); err != nil && rows > 0 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ func (s *CategoryService) Update(ctx context.Context, req *dto.UpdateCategoryReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parentIdChanged 判断父分类是否发生变化
|
// parentIdChanged 判断父分类是否发生变化
|
||||||
func (s *CategoryService) parentIdChanged(newParentId, oldParentId string) bool {
|
func (s *CategoryService) parentIdChanged(newParentId, oldParentId int64) bool {
|
||||||
if g.IsEmpty(newParentId) && g.IsEmpty(oldParentId) {
|
if g.IsEmpty(newParentId) && g.IsEmpty(oldParentId) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -226,7 +226,7 @@ func (s *CategoryService) parentIdChanged(newParentId, oldParentId string) bool
|
|||||||
// Delete 删除分类
|
// Delete 删除分类
|
||||||
func (s *CategoryService) Delete(ctx context.Context, req *dto.DeleteCategoryReq) error {
|
func (s *CategoryService) Delete(ctx context.Context, req *dto.DeleteCategoryReq) error {
|
||||||
// 检查是否有子分类
|
// 检查是否有子分类
|
||||||
hasChildren, err := s.hasChildren(ctx, req.Bid)
|
hasChildren, err := s.hasChildren(ctx, req.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -236,7 +236,7 @@ func (s *CategoryService) Delete(ctx context.Context, req *dto.DeleteCategoryReq
|
|||||||
|
|
||||||
// 检查是否有资产
|
// 检查是否有资产
|
||||||
if count, err := dao.Asset.Count(ctx, &dto.ListAssetReq{
|
if count, err := dao.Asset.Count(ctx, &dto.ListAssetReq{
|
||||||
CategoryId: req.Bid,
|
CategoryId: req.Id,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if count > 0 {
|
} else if count > 0 {
|
||||||
@@ -244,13 +244,13 @@ func (s *CategoryService) Delete(ctx context.Context, req *dto.DeleteCategoryReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取分类信息用于后续操作
|
// 获取分类信息用于后续操作
|
||||||
category, err := dao.Category.GetOne(ctx, &dto.GetCategoryReq{Bid: req.Bid})
|
category, err := dao.Category.GetOne(ctx, &dto.GetCategoryReq{Id: req.Id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||||
// 删除分类
|
// 删除分类
|
||||||
if err := dao.Category.DeleteFake(ctx, req); err != nil {
|
if rows, err := dao.Category.Delete(ctx, req); err != nil && rows > 0 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ var StockManage = new(stockManage)
|
|||||||
// GetStockFormFields 获取库存操作表单字段
|
// GetStockFormFields 获取库存操作表单字段
|
||||||
func (s *stockManage) GetStockFormFields(ctx context.Context, req *stockDto.GetStockFormFieldsReq) (*stockDto.GetStockFormFieldsRes, error) {
|
func (s *stockManage) GetStockFormFields(ctx context.Context, req *stockDto.GetStockFormFieldsReq) (*stockDto.GetStockFormFieldsRes, error) {
|
||||||
// 获取资产SKU信息
|
// 获取资产SKU信息
|
||||||
assetSku, err := assetDao.AssetSku.GetOne(ctx, &assetDto.GetAssetSkuReq{Id: req.AssetSkuId}, false)
|
assetSku, err := assetDao.AssetSku.GetOne(ctx, &assetDto.GetAssetSkuReq{Id: req.AssetSkuId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ func (s *stockManage) GetStockFormFields(ctx context.Context, req *stockDto.GetS
|
|||||||
// StockOperation 库存操作入口(入库/出库)
|
// StockOperation 库存操作入口(入库/出库)
|
||||||
// 根据SKU的StockMode区分明细模式和批次模式,计算差值后发布消息到NATS
|
// 根据SKU的StockMode区分明细模式和批次模式,计算差值后发布消息到NATS
|
||||||
func (s *stockManage) StockOperation(ctx context.Context, req *stockDto.StockOperationReq) (err error) {
|
func (s *stockManage) StockOperation(ctx context.Context, req *stockDto.StockOperationReq) (err error) {
|
||||||
assetSku, err := assetDao.AssetSku.GetOne(ctx, &assetDto.GetAssetSkuReq{Id: req.AssetSkuId}, false)
|
assetSku, err := assetDao.AssetSku.GetOne(ctx, &assetDto.GetAssetSkuReq{Id: req.AssetSkuId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -145,13 +145,13 @@ func (s *stockManage) stockPublishMessage(ctx context.Context, assetSku *assetEn
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
publishMessage := stockDto.StockPublishMessage{
|
publishMessage := stockDto.StockPublishMessage{
|
||||||
AssetId: assetSku.AssetId.Hex(),
|
AssetId: assetSku.AssetId,
|
||||||
AssetSkuId: assetSku.Id.Hex(),
|
AssetSkuId: assetSku.Id,
|
||||||
TenantId: user.TenantId,
|
TenantId: user.TenantId,
|
||||||
UserName: user.UserName,
|
UserName: user.UserName,
|
||||||
StockCount: stockCount,
|
StockCount: stockCount,
|
||||||
OperationType: operationType,
|
OperationType: operationType,
|
||||||
Metadata: assetSku.SpecValues,
|
Metadata: gconv.Maps(assetSku.SpecValues),
|
||||||
StockMode: int(assetSku.StockMode),
|
StockMode: int(assetSku.StockMode),
|
||||||
BatchNo: req.BatchNo,
|
BatchNo: req.BatchNo,
|
||||||
ProductionDate: req.ProductionDate,
|
ProductionDate: req.ProductionDate,
|
||||||
@@ -186,21 +186,9 @@ func (s *stockManage) stockPublishMessage(ctx context.Context, assetSku *assetEn
|
|||||||
// AddStock NATS消费者调用,执行实际的入库/出库操作
|
// AddStock NATS消费者调用,执行实际的入库/出库操作
|
||||||
// 使用Redis分布式锁防止并发冲突,支持明细模式和批次模式
|
// 使用Redis分布式锁防止并发冲突,支持明细模式和批次模式
|
||||||
func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{}) error {
|
func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{}) error {
|
||||||
assetId, err := bson.ObjectIDFromHex(gconv.String(msg["assetId"]))
|
assetId := gconv.Int64(msg["assetId"])
|
||||||
if err != nil {
|
assetSkuId := gconv.Int64(msg["assetSkuId"])
|
||||||
return err
|
stockId := gconv.Int64(msg["stockId"])
|
||||||
}
|
|
||||||
assetSkuId, err := bson.ObjectIDFromHex(gconv.String(msg["assetSkuId"]))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
stockId := bson.ObjectID{}
|
|
||||||
if !g.IsEmpty(msg["stockId"]) {
|
|
||||||
stockId, err = bson.ObjectIDFromHex(gconv.String(msg["stockId"]))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
userName := gconv.String(msg["userName"])
|
userName := gconv.String(msg["userName"])
|
||||||
tenantId := gconv.Float64(msg["tenantId"])
|
tenantId := gconv.Float64(msg["tenantId"])
|
||||||
stockCount := gconv.Int(msg["stockCount"])
|
stockCount := gconv.Int(msg["stockCount"])
|
||||||
@@ -219,9 +207,9 @@ func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{})
|
|||||||
success, err := redis.Lock(ctx, fileLockKey, int64(60), func(ctx context.Context) error {
|
success, err := redis.Lock(ctx, fileLockKey, int64(60), func(ctx context.Context) error {
|
||||||
if operationType == "add" {
|
if operationType == "add" {
|
||||||
if stockMode == stock.StockModeBatch {
|
if stockMode == stock.StockModeBatch {
|
||||||
if !stockId.IsZero() {
|
if !g.IsEmpty(stockId) {
|
||||||
batch := stockDto.UpdateBatchReq{
|
batch := stockDto.UpdateBatchReq{
|
||||||
Id: &stockId,
|
Id: stockId,
|
||||||
BatchQty: stockCount,
|
BatchQty: stockCount,
|
||||||
AvailableQty: stockCount,
|
AvailableQty: stockCount,
|
||||||
}
|
}
|
||||||
@@ -230,8 +218,8 @@ func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{})
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
batch := stockDto.CreateBatchReq{
|
batch := stockDto.CreateBatchReq{
|
||||||
AssetId: &assetId,
|
AssetId: assetId,
|
||||||
AssetSkuId: &assetSkuId,
|
AssetSkuId: assetSkuId,
|
||||||
Status: stock.BatchStatusActive,
|
Status: stock.BatchStatusActive,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
BatchNo: batchNo,
|
BatchNo: batchNo,
|
||||||
@@ -251,14 +239,14 @@ func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{})
|
|||||||
var stockInterfaces []interface{}
|
var stockInterfaces []interface{}
|
||||||
for i := 0; i < stockCount; i++ {
|
for i := 0; i < stockCount; i++ {
|
||||||
stockInterfaces = append(stockInterfaces, entity.StockDetails{
|
stockInterfaces = append(stockInterfaces, entity.StockDetails{
|
||||||
AssetId: &assetId,
|
AssetId: assetId,
|
||||||
AssetSkuId: &assetSkuId,
|
AssetSkuId: assetSkuId,
|
||||||
Status: stock.StockStatusAvailable,
|
Status: stock.StockStatusAvailable,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 批量插入数据库
|
// 批量插入数据库
|
||||||
if _, err = dao.StockDetails.BatchInsert(ctx, stockInterfaces); err != nil {
|
if _, err := dao.StockDetails.BatchInsert(ctx, stockInterfaces); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,7 +256,7 @@ func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{})
|
|||||||
stockCount = 0 - stockCount
|
stockCount = 0 - stockCount
|
||||||
// 更新批次
|
// 更新批次
|
||||||
batch := stockDto.UpdateBatchReq{
|
batch := stockDto.UpdateBatchReq{
|
||||||
Id: &stockId,
|
Id: stockId,
|
||||||
BatchQty: stockCount,
|
BatchQty: stockCount,
|
||||||
AvailableQty: stockCount,
|
AvailableQty: stockCount,
|
||||||
}
|
}
|
||||||
@@ -283,7 +271,7 @@ func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{})
|
|||||||
for pageNum := int64(1); ; pageNum++ {
|
for pageNum := int64(1); ; pageNum++ {
|
||||||
details, total, err := dao.StockDetails.List(ctx,
|
details, total, err := dao.StockDetails.List(ctx,
|
||||||
&stockDto.ListStockDetailsReq{
|
&stockDto.ListStockDetailsReq{
|
||||||
AssetSkuId: &assetSkuId,
|
AssetSkuId: assetSkuId,
|
||||||
Status: stock.StockStatusAvailable,
|
Status: stock.StockStatusAvailable,
|
||||||
Page: &beans.Page{PageNum: pageNum, PageSize: pageSize},
|
Page: &beans.Page{PageNum: pageNum, PageSize: pageSize},
|
||||||
})
|
})
|
||||||
@@ -317,7 +305,8 @@ func (s *stockManage) AddStock(ctx context.Context, msg map[string]interface{})
|
|||||||
stockCount = 0 - stockCount
|
stockCount = 0 - stockCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return assetDao.AssetSku.Update(ctx, &assetDto.UpdateAssetSkuReq{Id: &assetSkuId, Stock: stockCount})
|
_, err := assetDao.AssetSku.Update(ctx, &assetDto.UpdateAssetSkuReq{Id: assetSkuId, Stock: stockCount})
|
||||||
|
return err
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
46
update.sql
46
update.sql
@@ -1,20 +1,17 @@
|
|||||||
-----------张斌2025-06-16 15:00:00--------------
|
-----------张斌2025-06-16 15:00:00--------------
|
||||||
|
|
||||||
--------------------pgsql创建assets_category表语句---------------------------
|
--------------------pgsql创建assets_category表语句---------------------------
|
||||||
|
|
||||||
-- 分类主表
|
-- 分类主表
|
||||||
CREATE TABLE IF NOT EXISTS assets_category (
|
CREATE TABLE IF NOT EXISTS assets_category (
|
||||||
-- 基础字段
|
-- 基础字段
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGINT PRIMARY KEY, -- 从BIGSERIAL改为BIGINT,取消自增
|
||||||
creator VARCHAR(64) NOT NULL,
|
creator VARCHAR(64) NOT NULL,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updater VARCHAR(64) NOT NULL,
|
updater VARCHAR(64) NOT NULL,
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
deleter VARCHAR(64),
|
|
||||||
deleted_at timestamp(6),
|
deleted_at timestamp(6),
|
||||||
|
|
||||||
-- 分类核心字段
|
-- 分类核心字段(移除bid字段)
|
||||||
bid VARCHAR(64) NOT NULL,
|
|
||||||
name VARCHAR(128) NOT NULL,
|
name VARCHAR(128) NOT NULL,
|
||||||
parent_id VARCHAR(64) DEFAULT '',
|
parent_id VARCHAR(64) DEFAULT '',
|
||||||
path VARCHAR(512) DEFAULT '',
|
path VARCHAR(512) DEFAULT '',
|
||||||
@@ -23,27 +20,23 @@ CREATE TABLE IF NOT EXISTS assets_category (
|
|||||||
sort INT NOT NULL DEFAULT 0,
|
sort INT NOT NULL DEFAULT 0,
|
||||||
image VARCHAR(256) DEFAULT '',
|
image VARCHAR(256) DEFAULT '',
|
||||||
attrs JSONB DEFAULT '[]'::JSONB,
|
attrs JSONB DEFAULT '[]'::JSONB,
|
||||||
status SMALLINT NOT NULL DEFAULT 1,
|
status SMALLINT NOT NULL DEFAULT 1
|
||||||
|
|
||||||
-- 唯一索引 & 普通索引
|
|
||||||
CONSTRAINT uk_category_id UNIQUE (bid)
|
|
||||||
);
|
);
|
||||||
-- 为分类表添加索引(PostgreSQL 索引单独创建)
|
|
||||||
|
-- 为分类表添加索引(移除原uk_category_id唯一索引,保留其他索引)
|
||||||
CREATE INDEX idx_category_parent_id ON assets_category(parent_id);
|
CREATE INDEX idx_category_parent_id ON assets_category(parent_id);
|
||||||
CREATE INDEX idx_category_level ON assets_category(level);
|
CREATE INDEX idx_category_level ON assets_category(level);
|
||||||
CREATE INDEX idx_category_status ON assets_category(status);
|
CREATE INDEX idx_category_status ON assets_category(status);
|
||||||
CREATE INDEX idx_category_is_leaf_node ON assets_category(is_leaf_node);
|
CREATE INDEX idx_category_is_leaf_node ON assets_category(is_leaf_node);
|
||||||
|
|
||||||
-- 分类表字段注释
|
-- 分类表字段注释(移除bid字段注释)
|
||||||
COMMENT ON TABLE assets_category IS '商品/服务分类表';
|
COMMENT ON TABLE assets_category IS '商品/服务分类表';
|
||||||
COMMENT ON COLUMN assets_category.id IS '主键ID';
|
COMMENT ON COLUMN assets_category.id IS '主键ID(非自增)';
|
||||||
COMMENT ON COLUMN assets_category.creator IS '创建人';
|
COMMENT ON COLUMN assets_category.creator IS '创建人';
|
||||||
COMMENT ON COLUMN assets_category.created_at IS '创建时间';
|
COMMENT ON COLUMN assets_category.created_at IS '创建时间';
|
||||||
COMMENT ON COLUMN assets_category.updater IS '更新人';
|
COMMENT ON COLUMN assets_category.updater IS '更新人';
|
||||||
COMMENT ON COLUMN assets_category.updated_at IS '更新时间';
|
COMMENT ON COLUMN assets_category.updated_at IS '更新时间';
|
||||||
COMMENT ON COLUMN assets_category.deleter IS '删除人(软删)';
|
|
||||||
COMMENT ON COLUMN assets_category.deleted_at IS '删除时间(软删)';
|
COMMENT ON COLUMN assets_category.deleted_at IS '删除时间(软删)';
|
||||||
COMMENT ON COLUMN assets_category.bid IS '业务ID';
|
|
||||||
COMMENT ON COLUMN assets_category.name IS '分类名称';
|
COMMENT ON COLUMN assets_category.name IS '分类名称';
|
||||||
COMMENT ON COLUMN assets_category.parent_id IS '父分类ID,为空表示根分类';
|
COMMENT ON COLUMN assets_category.parent_id IS '父分类ID,为空表示根分类';
|
||||||
COMMENT ON COLUMN assets_category.path IS '分类路径,如:/root/parent/child';
|
COMMENT ON COLUMN assets_category.path IS '分类路径,如:/root/parent/child';
|
||||||
@@ -61,20 +54,18 @@ COMMENT ON COLUMN assets_category.status IS '状态:1启用/0禁用';
|
|||||||
-- 资产表(asset)
|
-- 资产表(asset)
|
||||||
CREATE TABLE IF NOT EXISTS assets_asset (
|
CREATE TABLE IF NOT EXISTS assets_asset (
|
||||||
-- 嵌入基础字段(复用 SQLBaseDO 结构)
|
-- 嵌入基础字段(复用 SQLBaseDO 结构)
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGINT PRIMARY KEY, -- 从BIGSERIAL改为BIGINT,取消自增
|
||||||
creator VARCHAR(64) NOT NULL,
|
creator VARCHAR(64) NOT NULL,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updater VARCHAR(64) NOT NULL,
|
updater VARCHAR(64) NOT NULL,
|
||||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
deleter VARCHAR(64),
|
|
||||||
deleted_at timestamp(6),
|
deleted_at timestamp(6),
|
||||||
|
|
||||||
-- 基础信息字段
|
-- 基础信息字段(移除bid字段)
|
||||||
bid VARCHAR(64) NOT NULL,
|
|
||||||
name VARCHAR(128) NOT NULL,
|
name VARCHAR(128) NOT NULL,
|
||||||
description TEXT DEFAULT '',
|
description TEXT DEFAULT '',
|
||||||
type VARCHAR(32) NOT NULL, -- 资产类型:physical实物/virtual虚拟/service服务
|
type VARCHAR(32) NOT NULL, -- 资产类型:physical实物/virtual虚拟/service服务
|
||||||
category_id BIGINT NOT NULL, -- 分类ID(对应分类表category_id,实体中定义为uint64,PG用BIGINT适配)
|
category_id BIGINT NOT NULL, -- 分类ID(对应category分类表id)
|
||||||
category_path VARCHAR(512) DEFAULT '',
|
category_path VARCHAR(512) DEFAULT '',
|
||||||
image_url VARCHAR(512) DEFAULT '',
|
image_url VARCHAR(512) DEFAULT '',
|
||||||
images JSONB DEFAULT '[]'::JSONB, -- 图片列表(字符串数组,JSONB存储)
|
images JSONB DEFAULT '[]'::JSONB, -- 图片列表(字符串数组,JSONB存储)
|
||||||
@@ -93,13 +84,10 @@ CREATE TABLE IF NOT EXISTS assets_asset (
|
|||||||
metadata JSONB, -- 扩展字段(动态元数据)
|
metadata JSONB, -- 扩展字段(动态元数据)
|
||||||
|
|
||||||
-- 租户相关
|
-- 租户相关
|
||||||
tenant_module_type VARCHAR(64) DEFAULT '',
|
tenant_module_type VARCHAR(64) DEFAULT ''
|
||||||
|
);
|
||||||
|
|
||||||
-- 唯一索引
|
-- 为资产表添加索引(移除原uk_asset_id唯一索引,保留其他索引)
|
||||||
CONSTRAINT uk_asset_id UNIQUE (bid)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 为资产表添加索引(优化查询性能)
|
|
||||||
CREATE INDEX idx_asset_category_id ON assets_asset(category_id);
|
CREATE INDEX idx_asset_category_id ON assets_asset(category_id);
|
||||||
CREATE INDEX idx_asset_type ON assets_asset(type);
|
CREATE INDEX idx_asset_type ON assets_asset(type);
|
||||||
CREATE INDEX idx_asset_status ON assets_asset(status);
|
CREATE INDEX idx_asset_status ON assets_asset(status);
|
||||||
@@ -107,20 +95,18 @@ CREATE INDEX idx_asset_online_time ON assets_asset(online_time);
|
|||||||
CREATE INDEX idx_asset_offline_time ON assets_asset(offline_time);
|
CREATE INDEX idx_asset_offline_time ON assets_asset(offline_time);
|
||||||
CREATE INDEX idx_asset_tenant_module_type ON assets_asset(tenant_module_type);
|
CREATE INDEX idx_asset_tenant_module_type ON assets_asset(tenant_module_type);
|
||||||
|
|
||||||
-- 为资产表添加注释(PostgreSQL 专属语法)
|
-- 为资产表添加注释(移除bid字段注释,更新id注释)
|
||||||
COMMENT ON TABLE assets_asset IS '资产主表';
|
COMMENT ON TABLE assets_asset IS '资产主表';
|
||||||
COMMENT ON COLUMN assets_asset.id IS '主键ID';
|
COMMENT ON COLUMN assets_asset.id IS '主键ID(非自增)';
|
||||||
COMMENT ON COLUMN assets_asset.creator IS '创建人';
|
COMMENT ON COLUMN assets_asset.creator IS '创建人';
|
||||||
COMMENT ON COLUMN assets_asset.created_at IS '创建时间';
|
COMMENT ON COLUMN assets_asset.created_at IS '创建时间';
|
||||||
COMMENT ON COLUMN assets_asset.updater IS '更新人';
|
COMMENT ON COLUMN assets_asset.updater IS '更新人';
|
||||||
COMMENT ON COLUMN assets_asset.updated_at IS '更新时间';
|
COMMENT ON COLUMN assets_asset.updated_at IS '更新时间';
|
||||||
COMMENT ON COLUMN assets_asset.deleter IS '删除人(软删)';
|
|
||||||
COMMENT ON COLUMN assets_asset.deleted_at IS '删除时间(软删)';
|
COMMENT ON COLUMN assets_asset.deleted_at IS '删除时间(软删)';
|
||||||
COMMENT ON COLUMN assets_asset.bid IS '业务ID';
|
|
||||||
COMMENT ON COLUMN assets_asset.name IS '资产名称';
|
COMMENT ON COLUMN assets_asset.name IS '资产名称';
|
||||||
COMMENT ON COLUMN assets_asset.description IS '资产描述';
|
COMMENT ON COLUMN assets_asset.description IS '资产描述';
|
||||||
COMMENT ON COLUMN assets_asset.type IS '资产类型:physical实物/virtual虚拟/service服务';
|
COMMENT ON COLUMN assets_asset.type IS '资产类型:physical实物/virtual虚拟/service服务';
|
||||||
COMMENT ON COLUMN assets_asset.category_id IS '分类ID';
|
COMMENT ON COLUMN assets_asset.category_id IS '分类ID(关联assets_category.id)';
|
||||||
COMMENT ON COLUMN assets_asset.category_path IS '分类路径';
|
COMMENT ON COLUMN assets_asset.category_path IS '分类路径';
|
||||||
COMMENT ON COLUMN assets_asset.image_url IS '主图URL';
|
COMMENT ON COLUMN assets_asset.image_url IS '主图URL';
|
||||||
COMMENT ON COLUMN assets_asset.images IS '图片列表(JSONB)';
|
COMMENT ON COLUMN assets_asset.images IS '图片列表(JSONB)';
|
||||||
|
|||||||
Reference in New Issue
Block a user