refactor: 重构资产模型与DAO层实现

This commit is contained in:
2026-03-19 17:45:06 +08:00
parent 5236c45a39
commit f30141679c
24 changed files with 570 additions and 600 deletions

View File

@@ -3,18 +3,19 @@ package service
import (
"assets/consts/stock"
dao "assets/dao/asset"
"assets/dao/base"
dto "assets/model/dto/asset"
enumDto "assets/model/dto/enum"
entity "assets/model/entity/asset"
service "assets/service/enum"
"context"
"errors"
"fmt"
"gitea.com/red-future/common/http"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
"gitea.com/red-future/common/beans"
"gitea.com/red-future/common/minio"
"gitea.com/red-future/common/utils"
)
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 {
return
}
if !isSuperAdmin {
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 {
req.TenantModuleType = beans.TenantModuleTypePlatform
}
@@ -87,7 +58,7 @@ func (s *asset) Create(ctx context.Context, req *dto.CreateAssetReq) (res *dto.C
return
}
res = &dto.CreateAssetRes{
Id: gconv.Uint64(id),
Id: id,
}
return
}
@@ -98,79 +69,88 @@ func (s *asset) List(ctx context.Context, req *dto.ListAssetReq) (res *dto.ListA
if err != nil {
return
}
user, err := utils.GetUserInfo(ctx)
if err != nil {
return
}
fmt.Println(user)
res = &dto.ListAssetRes{
Total: total,
}
err = utils.Struct(assetList, &res.List)
err = gconv.Struct(assetList, &res.List)
return
}
// GetOne 获取单个资产
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 {
return
}
// TODO: CategoryId类型不匹配需要同步修改category为uint64
// getCategoryRes, err := dao.Category.GetOne(ctx, &dto.GetCategoryReq{
// Id: assetOne.CategoryId,
// })
// if err != nil {
// return
// }
return &dto.GetAssetRes{
Asset: assetOne,
CategoryName: "", // getCategoryRes.Name,
AssetItem: assetListItem,
CategoryName: getCategoryRes.Name,
ImgAddressPrefix: minio.GetFileAddressPrefix(ctx),
}, nil
}
// GetAssetAndSku 获取资产和Sku详情
func (s *asset) GetAssetAndSku(ctx context.Context, req *dto.GetAssetAndSkuReq) (res *dto.GetAssetAndSkuRes, err error) {
// 跳过租户ID过滤获取资产
// TODO: AssetId 类型不匹配bson.ObjectID 需要转换为 uint64
// 使用 SkipTenantId 跳过租户ID过滤
assetOne, err := dao.Asset.GetOneById(base.SkipTenantId(ctx), 0)
_ = req.AssetId
var updateReq *dto.GetAssetReq
if err = gconv.Struct(req, &updateReq); err != nil {
return
}
assetOne, err := dao.Asset.GetOne(ctx, updateReq)
if err != nil {
return
}
// TODO: AssetId类型不匹配需要适配
// moduleType, err := service.Enum.GetTenantModuleType(ctx, &enumDto.GetTenantModuleTypeReq{AssetId: req.AssetId.Hex()})
// if err != nil {
// return
// }
// TODO: AssetId类型不匹配需要同步修改AssetSku为uint64
// skus, _, err := dao.AssetSku.List(ctx, &dto.ListAssetSkuReq{AssetId: req.AssetId}, true)
// if err != nil {
// return
// }
var assetListItem *dto.AssetItem
if err = gconv.Struct(assetOne, assetListItem); err != nil {
return
}
moduleType, err := service.Enum.GetTenantModuleType(ctx, &enumDto.GetTenantModuleTypeReq{AssetId: assetOne.Id})
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{
Asset: assetOne,
Skus: nil, // skus,
TenantModuleType: nil, // moduleType.Options,
AssetItem: assetListItem,
Skus: assetSkuListResItem,
TenantModuleType: moduleType.Options,
ImgAddressPrefix: minio.GetFileAddressPrefix(ctx),
}, nil
}
// Update 更新资产
func (s *asset) Update(ctx context.Context, req *dto.UpdateAssetReq) error {
return dao.Asset.Update(ctx, req)
func (s *asset) Update(ctx context.Context, req *dto.UpdateAssetReq) (err error) {
_, err = dao.Asset.Update(ctx, req)
return
}
// UpdateStatus 更新资产状态
func (s *asset) UpdateStatus(ctx context.Context, req *dto.UpdateAssetStatusReq) (err error) {
var updateReq *dto.UpdateAssetReq
err = utils.Struct(req, &updateReq)
return dao.Asset.Update(ctx, updateReq)
if err = gconv.Struct(req, &updateReq); err != nil {
return err
}
_, err = dao.Asset.Update(ctx, updateReq)
return
}
// Delete 删除资产
func (s *asset) Delete(ctx context.Context, req *dto.DeleteAssetReq) error {
return dao.Asset.DeleteFake(ctx, req)
func (s *asset) Delete(ctx context.Context, req *dto.DeleteAssetReq) (err error) {
_, err = dao.Asset.Delete(ctx, req)
return
}

View File

@@ -13,7 +13,6 @@ import (
"gitea.com/red-future/common/utils"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
"go.mongodb.org/mongo-driver/v2/bson"
)
type assetSku struct{}
@@ -28,7 +27,7 @@ func (s *assetSku) CreateAssetSku(ctx context.Context, req *dto.CreateAssetSkuRe
return nil, errors.New("关联资产不存在")
}
// 根据资产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 {
return
}
@@ -39,26 +38,23 @@ func (s *assetSku) CreateAssetSku(ctx context.Context, req *dto.CreateAssetSkuRe
}
req.UnlimitedStock = assetEntity.UnlimitedStock
req.StockMode = assetEntity.StockMode
// TODO: 类型不匹配 uint64 vs *bson.ObjectID
// req.CategoryId = assetEntity.CategoryId
req.CategoryId = assetEntity.CategoryId
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 {
return
}
id := ids[0].(bson.ObjectID)
res = &dto.CreateAssetSkuRes{
Id: &id,
Id: id,
}
return
}
// UpdateAssetSku 更新SKU
func (s *assetSku) UpdateAssetSku(ctx context.Context, req *dto.UpdateAssetSkuReq) error {
getOne, err := dao.AssetSku.GetOne(ctx, &dto.GetAssetSkuReq{Id: req.Id}, false)
func (s *assetSku) UpdateAssetSku(ctx context.Context, req *dto.UpdateAssetSkuReq) (err error) {
getOne, err := dao.AssetSku.GetOne(ctx, &dto.GetAssetSkuReq{Id: req.Id})
if err != nil {
return errors.New("SUK不存在")
}
@@ -78,7 +74,8 @@ func (s *assetSku) UpdateAssetSku(ctx context.Context, req *dto.UpdateAssetSkuRe
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) {
@@ -112,7 +109,8 @@ func (s *assetSku) parameterValidation(ctx context.Context, assetEntity *entity.
for key, subValue := range specValues {
// 1. 检查请求参数 map 中是否存在该键
for _, subValues := range list.SpecValues {
parentValue, ok := subValues[gconv.String(key)]
mapSubValues := gconv.Map(subValues)
parentValue, ok := mapSubValues[gconv.String(key)]
if ok {
// 2. 检查对应的值是否相等
if reflect.DeepEqual(parentValue, subValue) {
@@ -146,13 +144,14 @@ func (s *assetSku) parameterValidation(ctx context.Context, assetEntity *entity.
}
// DeleteAssetSku 删除SKU软删除
func (s *assetSku) DeleteAssetSku(ctx context.Context, req *dto.DeleteAssetSkuReq) error {
return dao.AssetSku.DeleteFake(ctx, req)
func (s *assetSku) DeleteAssetSku(ctx context.Context, req *dto.DeleteAssetSkuReq) (err error) {
_, err = dao.AssetSku.Delete(ctx, req)
return
}
// GetAssetSku 获取SKU详情
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 {
return
}
@@ -163,7 +162,7 @@ func (s *assetSku) GetAssetSku(ctx context.Context, req *dto.GetAssetSkuReq) (re
// ListAssetSkus 获取SKU列表
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 {
return
}
@@ -176,14 +175,19 @@ func (s *assetSku) ListAssetSkus(ctx context.Context, req *dto.ListAssetSkuReq)
// GetAssetSkuModule 获取SKU详情
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 {
return
}
res = &dto.GetAssetSkuModuleRes{}
// 计算到期时间
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.AssetId = one.AssetId
}

View File

@@ -8,7 +8,6 @@ import (
"errors"
"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/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) {
// 构建分类路径和层级
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 {
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
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
var r *entity.Category
if r, err = dao.Category.Insert(ctx, req); err != nil {
return err
}
// 更新新创建分类的 IsLeafNode 为 true
if err = s.updateLeafNode(ctx, r.Bid, true); err != nil {
var id int64
req.IsLeafNode = gconv.PtrBool(true)
if id, err = dao.Category.Insert(ctx, req); err != nil {
return err
}
@@ -54,7 +51,7 @@ func (s *CategoryService) Create(ctx context.Context, req *dto.CreateCategoryReq
}
res = &dto.CreateCategoryRes{
Bid: r.Bid,
Id: id,
}
return nil
@@ -64,11 +61,12 @@ func (s *CategoryService) Create(ctx context.Context, req *dto.CreateCategoryReq
}
// updateLeafNode 更新分类的 IsLeafNode 字段
func (s *CategoryService) updateLeafNode(ctx context.Context, categoryId string, isLeaf bool) error {
return dao.Category.Update(ctx, &dto.UpdateCategoryReq{
Bid: categoryId,
IsLeafNode: isLeaf,
func (s *CategoryService) updateLeafNode(ctx context.Context, categoryId int64, isLeaf bool) (err error) {
_, err = dao.Category.Update(ctx, &dto.UpdateCategoryReq{
Id: categoryId,
IsLeafNode: &isLeaf,
})
return
}
// GetOne 获取单个分类
@@ -78,11 +76,12 @@ func (s *CategoryService) GetOne(ctx context.Context, req *dto.GetCategoryReq) (
return nil, err
}
res := new(dto.GetCategoryRes)
err = utils.Struct(one, &res)
if err != nil {
return nil, err
if err = gconv.Scan(one, &res); err != nil {
panic(err)
}
return res, nil
return res, err
}
// List 获取分类列表
@@ -107,7 +106,7 @@ func (s *CategoryService) GetTree(ctx context.Context, req *dto.GetCategoryTreeR
if err != nil {
return nil, err
}
tree, err := s.buildTree(ctx, list, "")
tree, err := s.buildTree(ctx, list, 0)
if err != nil {
return nil, err
}
@@ -115,7 +114,7 @@ func (s *CategoryService) GetTree(ctx context.Context, req *dto.GetCategoryTreeR
}
// 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)
for _, cat := range categories {
if !s.isChildOf(cat.ParentId, parentId) {
@@ -131,7 +130,7 @@ func (s *CategoryService) buildTree(ctx context.Context, categories []entity.Cat
}
// isChildOf 判断分类是否为指定父节点的子节点
func (s *CategoryService) isChildOf(childParentId, parentId string) bool {
func (s *CategoryService) isChildOf(childParentId, parentId int64) bool {
if g.IsEmpty(childParentId) && g.IsEmpty(parentId) {
return true
}
@@ -147,7 +146,7 @@ func (s *CategoryService) convertToTreeNode(ctx context.Context, category *entit
if err := gconv.Struct(&category, &res); err != nil {
return res, err
}
children, err := s.buildTree(ctx, allCategories, category.Bid)
children, err := s.buildTree(ctx, allCategories, category.Id)
if err != nil {
return res, err
}
@@ -157,7 +156,7 @@ func (s *CategoryService) convertToTreeNode(ctx context.Context, category *entit
}
// 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{
ParentId: parentId,
})
@@ -165,7 +164,7 @@ func (s *CategoryService) hasChildren(ctx context.Context, parentId string) (boo
}
// 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)
if err != nil {
return err
@@ -174,12 +173,13 @@ func (s *CategoryService) updateLeafNodeIfNoChildren(ctx context.Context, parent
}
// 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
if err := gconv.Struct(req, &updateReq); err != nil {
return err
if err = gconv.Struct(req, &updateReq); err != nil {
return
}
return dao.Category.Update(ctx, updateReq)
_, err = dao.Category.Update(ctx, updateReq)
return
}
// Update 更新分类
@@ -189,7 +189,7 @@ func (s *CategoryService) Update(ctx context.Context, req *dto.UpdateCategoryReq
return err
}
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
}
@@ -213,7 +213,7 @@ func (s *CategoryService) Update(ctx context.Context, req *dto.UpdateCategoryReq
}
// parentIdChanged 判断父分类是否发生变化
func (s *CategoryService) parentIdChanged(newParentId, oldParentId string) bool {
func (s *CategoryService) parentIdChanged(newParentId, oldParentId int64) bool {
if g.IsEmpty(newParentId) && g.IsEmpty(oldParentId) {
return false
}
@@ -226,7 +226,7 @@ func (s *CategoryService) parentIdChanged(newParentId, oldParentId string) bool
// Delete 删除分类
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 {
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{
CategoryId: req.Bid,
CategoryId: req.Id,
}); err != nil {
return err
} 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 {
return err
}
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
}