f
This commit is contained in:
@@ -28,6 +28,7 @@ func NewAdminCreateProductLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||
}
|
||||
}
|
||||
|
||||
// AdminCreateProduct 创建产品后,在同一事务内写入一条 agent_product_config(与代理产品配置列表一致)。
|
||||
func (l *AdminCreateProductLogic) AdminCreateProduct(req *types.AdminCreateProductReq) (resp *types.AdminCreateProductResp, err error) {
|
||||
// 1. 数据转换
|
||||
data := &model.Product{
|
||||
@@ -36,7 +37,7 @@ func (l *AdminCreateProductLogic) AdminCreateProduct(req *types.AdminCreateProdu
|
||||
ProductEn: req.ProductEn,
|
||||
Description: req.Description,
|
||||
Notes: sql.NullString{String: req.Notes, Valid: req.Notes != ""},
|
||||
CostPrice: req.CostPrice,
|
||||
CostPrice: 0, // 成本由关联模块汇总,创建后为 0,保存模块关联后写入
|
||||
SellPrice: req.SellPrice,
|
||||
}
|
||||
|
||||
@@ -51,7 +52,14 @@ func (l *AdminCreateProductLogic) AdminCreateProduct(req *types.AdminCreateProdu
|
||||
}
|
||||
productId = data.Id
|
||||
|
||||
// 2.2 同步创建代理产品配置(使用默认值)
|
||||
// 2.2 同步创建代理产品配置(使用默认值);已存在则跳过(幂等)
|
||||
if _, findErr := l.svcCtx.AgentProductConfigModel.FindOneByProductId(ctx, productId); findErr == nil {
|
||||
return nil
|
||||
} else if findErr != model.ErrNotFound {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
|
||||
"检查代理产品配置失败, err: %v, productId: %s", findErr, productId)
|
||||
}
|
||||
|
||||
agentProductConfig := &model.AgentProductConfig{
|
||||
Id: uuid.NewString(),
|
||||
ProductId: productId,
|
||||
|
||||
@@ -2,8 +2,10 @@ package admin_product
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"qnc-server/app/main/api/internal/svc"
|
||||
"qnc-server/app/main/api/internal/types"
|
||||
"qnc-server/app/main/model"
|
||||
"qnc-server/common/xerr"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -25,12 +27,13 @@ func NewAdminDeleteProductLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||
}
|
||||
}
|
||||
|
||||
// AdminDeleteProduct 软删除产品后,在同一事务内软删除对应 agent_product_config(与产品列表一致)。
|
||||
func (l *AdminDeleteProductLogic) AdminDeleteProduct(req *types.AdminDeleteProductReq) (resp *types.AdminDeleteProductResp, err error) {
|
||||
// 1. 查询记录是否存在
|
||||
record, err := l.svcCtx.ProductModel.FindOne(l.ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
|
||||
"查找产品失败, err: %v, id: %d", err, req.Id)
|
||||
"查找产品失败, err: %v, id: %s", err, req.Id)
|
||||
}
|
||||
|
||||
// 2. 执行软删除(使用事务确保产品表和代理产品配置表同步)
|
||||
@@ -39,20 +42,22 @@ func (l *AdminDeleteProductLogic) AdminDeleteProduct(req *types.AdminDeleteProdu
|
||||
err = l.svcCtx.ProductModel.DeleteSoft(ctx, session, record)
|
||||
if err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
|
||||
"删除产品失败, err: %v, id: %d", err, req.Id)
|
||||
"删除产品失败, err: %v, id: %s", err, record.Id)
|
||||
}
|
||||
|
||||
// 2.2 同步软删除代理产品配置
|
||||
agentProductConfig, err := l.svcCtx.AgentProductConfigModel.FindOneByProductId(ctx, req.Id)
|
||||
if err != nil {
|
||||
// 如果代理产品配置不存在,记录日志但不影响主流程
|
||||
l.Infof("同步删除代理产品配置失败:代理产品配置不存在, productId: %d, err: %v", req.Id, err)
|
||||
} else {
|
||||
err = l.svcCtx.AgentProductConfigModel.DeleteSoft(ctx, session, agentProductConfig)
|
||||
if err != nil {
|
||||
// 2.2 同步软删除代理产品配置(按产品主键 product_id)
|
||||
agentProductConfig, findErr := l.svcCtx.AgentProductConfigModel.FindOneByProductId(ctx, record.Id)
|
||||
switch {
|
||||
case findErr == nil:
|
||||
if err = l.svcCtx.AgentProductConfigModel.DeleteSoft(ctx, session, agentProductConfig); err != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
|
||||
"同步删除代理产品配置失败, err: %v, productId: %d", err, req.Id)
|
||||
"同步删除代理产品配置失败, err: %v, productId: %s", err, record.Id)
|
||||
}
|
||||
case findErr == model.ErrNotFound:
|
||||
l.Infof("产品无对应代理产品配置,跳过同步删除, productId: %s", record.Id)
|
||||
default:
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
|
||||
"查询代理产品配置失败, err: %v, productId: %s", findErr, record.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -32,14 +32,21 @@ func (l *AdminGetProductDetailLogic) AdminGetProductDetail(req *types.AdminGetPr
|
||||
"查找产品失败, err: %v, id: %d", err, req.Id)
|
||||
}
|
||||
|
||||
// 2. 构建响应
|
||||
// 2. 成本价为关联模块 cost_price 之和
|
||||
costSum, err := l.svcCtx.ProductFeatureModel.SumFeatureCostPriceByProductId(l.ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
|
||||
"汇总产品模块成本失败, err: %v, id: %s", err, req.Id)
|
||||
}
|
||||
|
||||
// 3. 构建响应
|
||||
resp = &types.AdminGetProductDetailResp{
|
||||
Id: record.Id,
|
||||
ProductName: record.ProductName,
|
||||
ProductEn: record.ProductEn,
|
||||
Description: record.Description,
|
||||
Notes: record.Notes.String,
|
||||
CostPrice: record.CostPrice,
|
||||
CostPrice: costSum,
|
||||
SellPrice: record.SellPrice,
|
||||
CreateTime: record.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
UpdateTime: record.UpdateTime.Format("2006-01-02 15:04:05"),
|
||||
|
||||
@@ -105,6 +105,7 @@ func (l *AdminGetProductFeatureListLogic) AdminGetProductFeatureList(req *types.
|
||||
FeatureId: item.FeatureId,
|
||||
ApiId: feature.ApiId,
|
||||
Name: feature.Name,
|
||||
CostPrice: feature.CostPrice,
|
||||
Sort: item.Sort,
|
||||
Enable: item.Enable,
|
||||
IsImportant: item.IsImportant,
|
||||
|
||||
@@ -44,16 +44,26 @@ func (l *AdminGetProductListLogic) AdminGetProductList(req *types.AdminGetProduc
|
||||
"查询产品列表失败, err: %v, req: %+v", err, req)
|
||||
}
|
||||
|
||||
// 4. 构建响应列表
|
||||
// 4. 构建响应列表(成本价为关联模块 cost_price 之和,非库表字段直读)
|
||||
items := make([]types.ProductListItem, 0, len(list))
|
||||
productIds := make([]string, 0, len(list))
|
||||
for _, item := range list {
|
||||
productIds = append(productIds, item.Id)
|
||||
}
|
||||
costByProduct, err := l.svcCtx.ProductFeatureModel.SumFeatureCostPriceByProductIds(l.ctx, productIds)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR),
|
||||
"汇总产品模块成本失败, err: %v, req: %+v", err, req)
|
||||
}
|
||||
for _, item := range list {
|
||||
cost := costByProduct[item.Id]
|
||||
listItem := types.ProductListItem{
|
||||
Id: item.Id,
|
||||
ProductName: item.ProductName,
|
||||
ProductEn: item.ProductEn,
|
||||
Description: item.Description,
|
||||
Notes: item.Notes.String,
|
||||
CostPrice: item.CostPrice,
|
||||
CostPrice: cost,
|
||||
SellPrice: item.SellPrice,
|
||||
CreateTime: item.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
UpdateTime: item.UpdateTime.Format("2006-01-02 15:04:05"),
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package admin_product
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"qnc-server/app/main/api/internal/svc"
|
||||
"qnc-server/app/main/api/internal/types"
|
||||
"qnc-server/app/main/model"
|
||||
"qnc-server/common/xerr"
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/mr"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/google/uuid"
|
||||
"qnc-server/app/main/api/internal/logic/productcost"
|
||||
"qnc-server/app/main/api/internal/svc"
|
||||
"qnc-server/app/main/api/internal/types"
|
||||
"qnc-server/app/main/model"
|
||||
"qnc-server/common/xerr"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/mr"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
type AdminUpdateProductFeaturesLogic struct {
|
||||
@@ -120,15 +122,15 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// 新增关联
|
||||
newFeature := &model.ProductFeature{
|
||||
Id: uuid.NewString(),
|
||||
ProductId: req.ProductId,
|
||||
FeatureId: data.featureId,
|
||||
Sort: data.newItem.Sort,
|
||||
Enable: data.newItem.Enable,
|
||||
IsImportant: data.newItem.IsImportant,
|
||||
}
|
||||
// 新增关联
|
||||
newFeature := &model.ProductFeature{
|
||||
Id: uuid.NewString(),
|
||||
ProductId: req.ProductId,
|
||||
FeatureId: data.featureId,
|
||||
Sort: data.newItem.Sort,
|
||||
Enable: data.newItem.Enable,
|
||||
IsImportant: data.newItem.IsImportant,
|
||||
}
|
||||
_, err = l.svcCtx.ProductFeatureModel.Insert(ctx, session, newFeature)
|
||||
if err != nil {
|
||||
updateErr = errors.Wrapf(err, "新增产品功能关联失败, product_id: %d, feature_id: %d",
|
||||
@@ -156,6 +158,10 @@ func (l *AdminUpdateProductFeaturesLogic) AdminUpdateProductFeatures(req *types.
|
||||
"更新产品功能关联失败, err: %v, req: %+v", err, req)
|
||||
}
|
||||
|
||||
if err := productcost.SyncProductCostFromModules(l.ctx, l.svcCtx, req.ProductId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 5. 返回结果
|
||||
return &types.AdminUpdateProductFeaturesResp{Success: true}, nil
|
||||
}
|
||||
|
||||
@@ -47,9 +47,6 @@ func (l *AdminUpdateProductLogic) AdminUpdateProduct(req *types.AdminUpdateProdu
|
||||
if req.Notes != nil {
|
||||
record.Notes = sql.NullString{String: *req.Notes, Valid: *req.Notes != ""}
|
||||
}
|
||||
if req.CostPrice != nil {
|
||||
record.CostPrice = *req.CostPrice
|
||||
}
|
||||
if req.SellPrice != nil {
|
||||
record.SellPrice = *req.SellPrice
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user