fix version 1

This commit is contained in:
2026-09-22 21:15:34 +08:00
parent 9f86366638
commit d63d7e8b3a
277 changed files with 9959 additions and 1514 deletions

View File

@@ -15,7 +15,7 @@ import (
// Forbidden 批量操作
func ItemBatchOp(ctx context.Context, in *pb.OpRequest) (reply *pb.IdentityStatusReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -23,12 +23,23 @@ func ItemBatchOp(ctx context.Context, in *pb.OpRequest) (reply *pb.IdentityStatu
if len(in.GetIdentity()) == 0 {
return nil, errcode.ErrInvalidArgument
}
// TODO: add your logic code & delete this line.
err = impl.DBService.Model(&models.MallProduct{}).Where("identity in ?", in.Identity).Update("status", in.Status).Error
if err != nil {
printer.Error(err.Error())
// 只能批量操作当前登录者所属店铺的商品
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" {
return nil, errcode.ErrPermissionDenied
}
tx := impl.DBService.Model(&models.MallProduct{}).Where("identity in ?", in.Identity).
Where("store_identity = ?", storeIdentity).Update("status", in.Status)
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
if tx.RowsAffected == 0 {
return nil, errcode.ErrPermissionDenied
}
return &pb.IdentityStatusReply{
Code: 0,

View File

@@ -15,7 +15,7 @@ import (
// 删除产品
func ItemDelete(ctx context.Context, in *pb.IdentRequest) (reply *pb.IdentityStatusReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -25,11 +25,22 @@ func ItemDelete(ctx context.Context, in *pb.IdentRequest) (reply *pb.IdentitySta
return nil, errcode.ErrInvalidArgument
}
err = impl.DBService.Where("id=? or identity=?", in.GetId(), in.GetIdentity()).Delete(&models.MallProduct{}).Error
if err != nil {
printer.Error(err.Error())
// 只能删除当前登录者所属店铺的商品
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" {
return nil, errcode.ErrPermissionDenied
}
tx := impl.DBService.Where("id=? or identity=?", in.GetId(), in.GetIdentity()).
Where("store_identity = ?", storeIdentity).Delete(&models.MallProduct{})
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
if tx.RowsAffected == 0 {
return nil, errcode.ErrPermissionDenied
}
return &pb.IdentityStatusReply{
Code: 0,

View File

@@ -8,6 +8,7 @@ import (
pb "bsm/full/module/ec/mall/pb"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/printer"
"git.apinb.com/bsm-sdk/core/service"
)
// Detail 获取产品详情
@@ -42,5 +43,19 @@ func ItemDetail(ctx context.Context, in *pb.IdentRequest) (reply *pb.ProductItem
for _, v := range data.Specs {
reply.SpecId = append(reply.SpecId, int64(v.SpecId))
}
// 成本类价格(进货价/代理价)仅店铺内部可见:匿名或非本店调用者不下发。
callerStore := ""
if auth, e := service.ParseMetaCtx(ctx, nil); e == nil && auth != nil {
if owner, ok := auth.Owner.(map[string]any); ok {
callerStore, _ = owner["store_identity"].(string)
}
}
if callerStore == "" || callerStore != data.Store_Identity {
for _, s := range reply.Specification {
s.PurchasingPrice = 0
s.Wholesale = 0
}
}
return reply, nil
}

View File

@@ -19,7 +19,7 @@ func ItemDetailBySerial(ctx context.Context, in *pb.StoreSerialRequest) (reply *
}
data := make([]*models.MallProduct, 0)
err = impl.DBService.Preload("Spec").Preload("Images").Preload("Category").Where("store_identity=? and serial_id in ?", in.StoreIdentity, in.SerialId).Find(&data).Error
err = impl.DBService.Preload("Specs.Spec").Preload("Images").Preload("Categories.Category").Where("store_identity=? and serial_id in ?", in.StoreIdentity, in.SerialId).Find(&data).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {

View File

@@ -13,9 +13,6 @@ func ItemDetailBySpec(ctx context.Context, in *pb.DetailBySpecRequest) (reply *p
return nil, errcode.ErrInvalidArgument
}
// TODO: valid code
// TODO: add your logic code & delete this line.
return
// 该接口尚未实现,显式返回未实现错误,避免调用方误判成功。
return nil, errcode.ErrUnimplemented
}

View File

@@ -25,7 +25,6 @@ func ItemFetch(ctx context.Context, in *pb.MallFetchRequest) (reply *pb.ListRepl
params = map[string]string{
"mall_product.store_identity": in.GetStoreIdentity(),
}
idList = make([]uint, 0)
product []*models.MallProduct
)
@@ -39,16 +38,10 @@ func ItemFetch(ctx context.Context, in *pb.MallFetchRequest) (reply *pb.ListRepl
offset = (pageNo - 1) * pageSize
}
if err := impl.DBService.Model(&models.MallProduct{}).Where(params).Preload("Images").Preload("Specs.Spec").Preload("Categories.Category").
Order("created_at desc").Count(&cnt).Offset(int(offset)).Limit(int(pageSize)).Find(&product).Error; err != nil {
printer.Error(err.Error())
return nil, errcode.ErrDB
}
tx := impl.DBService.Model(&models.MallProduct{})
// 根据传入的分类id进行过滤
if len(in.GetCategoryId()) != 0 {
tx = tx.Where("product_category.category_id in ?", idList).
tx = tx.Where("product_category.category_id in ?", in.GetCategoryId()).
Joins("left join product_category on mall_product.id = product_category.product_id").
Joins("left join mall_category on mall_category.id = product_category.category_id")
}
@@ -56,11 +49,18 @@ func ItemFetch(ctx context.Context, in *pb.MallFetchRequest) (reply *pb.ListRepl
if in.GetKeyword() != "" {
tx = tx.Where("mall_product.title like ?", "%"+in.GetKeyword()+"%")
}
// 根据传入的价格区间进行价格过滤
// 根据传入的价格区间进行价格过滤(分别支持只传最小值、只传最大值与两者都传)
if in.GetMinPrice() != 0 || in.GetMaxPrice() != 0 {
tx = tx.Joins("left join product_spec on product_spec.product_id = mall_product.id").
Joins("left join mall_product_spec on mall_product_spec.id = product_spec.spec_id").
Where("mall_product_spec.price between ? and ?", in.GetMinPrice(), in.GetMaxPrice())
Joins("left join mall_product_spec on mall_product_spec.id = product_spec.spec_id")
switch {
case in.GetMinPrice() != 0 && in.GetMaxPrice() != 0:
tx = tx.Where("mall_product_spec.price between ? and ?", in.GetMinPrice(), in.GetMaxPrice())
case in.GetMinPrice() != 0:
tx = tx.Where("mall_product_spec.price >= ?", in.GetMinPrice())
default:
tx = tx.Where("mall_product_spec.price <= ?", in.GetMaxPrice())
}
}
// 根据传入sort排序

View File

@@ -15,7 +15,7 @@ import (
// Modify 发布/取消发布 产品
func ItemModify(ctx context.Context, in *pb.ModifyRequest) (reply *pb.IdentityStatusReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -25,11 +25,22 @@ func ItemModify(ctx context.Context, in *pb.ModifyRequest) (reply *pb.IdentitySt
return nil, errcode.ErrInvalidArgument
}
// TODO: add your logic code & delete this line.
if err := impl.DBService.Model(&models.MallProduct{}).Where("identity = ?", in.Identity).Update("status", in.Status).Error; err != nil {
printer.Error(err.Error())
// 只能修改当前登录者所属店铺的商品
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" {
return nil, errcode.ErrPermissionDenied
}
tx := impl.DBService.Model(&models.MallProduct{}).Where("identity = ?", in.Identity).
Where("store_identity = ?", storeIdentity).Update("status", in.Status)
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
if tx.RowsAffected == 0 {
return nil, errcode.ErrPermissionDenied
}
return &pb.IdentityStatusReply{
Code: 0,
Message: "OK",

View File

@@ -33,9 +33,12 @@ func PhotoCreate(ctx context.Context, in *pb.PhotoItem) (reply *pb.IdentityStatu
}
photo.Identity = utils.UUID()
tx := impl.DBService.Create(&photo)
cnt, err := tx.RowsAffected, tx.Error
if cnt == 0 || err != nil {
printer.Error(err.Error())
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
if tx.RowsAffected == 0 {
printer.Error("添加产品图片失败: 未写入任何记录")
return nil, errcode.ErrDB
}

View File

@@ -15,7 +15,7 @@ import (
// 删除产品图片
func PhotoDelete(ctx context.Context, in *pb.IdentRequest) (reply *pb.IdentityStatusReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -25,11 +25,23 @@ func PhotoDelete(ctx context.Context, in *pb.IdentRequest) (reply *pb.IdentitySt
return nil, errcode.ErrInvalidArgument
}
err = impl.DBService.Where("id=? or identity=?", in.GetId(), in.GetIdentity()).Delete(&models.MallProductPhotos{}).Error
if err != nil {
printer.Error(err.Error())
// 只能删除当前登录者所属店铺商品的图片(图片表无店铺字段,按所属商品归属判定)
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" {
return nil, errcode.ErrPermissionDenied
}
tx := impl.DBService.Where("id=? or identity=?", in.GetId(), in.GetIdentity()).
Where("product_identity in (?)", impl.DBService.Model(&models.MallProduct{}).Select("identity").Where("store_identity = ?", storeIdentity)).
Delete(&models.MallProductPhotos{})
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
if tx.RowsAffected == 0 {
return nil, errcode.ErrPermissionDenied
}
// TODO: add your logic code & delete this line.

View File

@@ -16,7 +16,7 @@ import (
// CreateSpec 添加产品规格
func SpecCreate(ctx context.Context, in *pb.SpecItem) (reply *pb.IdentityStatusReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -27,16 +27,27 @@ func SpecCreate(ctx context.Context, in *pb.SpecItem) (reply *pb.IdentityStatusR
return nil, err
}
// 规格归属以 token 中的店铺为准,不采信请求参数
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" {
return nil, errcode.ErrPermissionDenied
}
// 数据组装
data, err := requestToModelSpec(in)
if err != nil {
return nil, err
}
data.Identity = utils.UUID()
data.StoreIdentity = storeIdentity
tx := impl.DBService.Create(data)
cnt, err := tx.RowsAffected, tx.Error
if cnt == 0 || err != nil {
printer.Error(err.Error())
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
if tx.RowsAffected == 0 {
printer.Error("创建产品规格失败: 未写入任何记录")
return nil, errcode.ErrDB
}
@@ -93,9 +104,6 @@ func requestToModelSpec(in *pb.SpecItem) (*models.MallProductSpec, error) {
PurchasingPrice: in.PurchasingPrice,
Wholesale: in.Wholesale,
}
if in.StockType != 2 {
specification.Stock = int64(in.StockType)
}
if in.TpType != 2 {
specification.TpType = in.TpType
}

View File

@@ -15,7 +15,7 @@ import (
// 删除产品规格
func SpecDelete(ctx context.Context, in *pb.IdentRequest) (reply *pb.IdentityStatusReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -25,12 +25,22 @@ func SpecDelete(ctx context.Context, in *pb.IdentRequest) (reply *pb.IdentitySta
return nil, errcode.ErrInvalidArgument
}
err = impl.DBService.Where("id=? or identity=?", in.GetId(), in.GetIdentity()).Delete(&models.MallProductSpec{}).Error
if err != nil {
printer.Error(err.Error())
// 只能删除当前登录者所属店铺的规格
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" {
return nil, errcode.ErrPermissionDenied
}
tx := impl.DBService.Where("id=? or identity=?", in.GetId(), in.GetIdentity()).
Where("store_identity = ?", storeIdentity).Delete(&models.MallProductSpec{})
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
// TODO: add your logic code & delete this line.
if tx.RowsAffected == 0 {
return nil, errcode.ErrPermissionDenied
}
return &pb.IdentityStatusReply{
Code: 0,

View File

@@ -8,6 +8,7 @@ import (
pb "bsm/full/module/ec/mall/pb"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/printer"
"git.apinb.com/bsm-sdk/core/service"
)
// DetailSpec 产品详情
@@ -23,7 +24,7 @@ func SpecDetail(ctx context.Context, in *pb.IdentRequest) (reply *pb.SpecItem, e
printer.Error(err.Error())
return nil, errcode.ErrDB
}
return &pb.SpecItem{
reply = &pb.SpecItem{
Id: int64(data.ID),
Identity: data.Identity,
SupplyId: data.SupplyId,
@@ -37,5 +38,18 @@ func SpecDetail(ctx context.Context, in *pb.IdentRequest) (reply *pb.SpecItem, e
Img: data.Img,
PurchasingPrice: data.PurchasingPrice,
Wholesale: data.Wholesale,
}, nil
}
// 成本类价格(进货价/代理价)仅店铺内部可见:匿名或非本店调用者不下发。
callerStore := ""
if auth, e := service.ParseMetaCtx(ctx, nil); e == nil && auth != nil {
if owner, ok := auth.Owner.(map[string]any); ok {
callerStore, _ = owner["store_identity"].(string)
}
}
if callerStore == "" || callerStore != data.StoreIdentity {
reply.PurchasingPrice = 0
reply.Wholesale = 0
}
return reply, nil
}

View File

@@ -14,7 +14,7 @@ import (
// 产品规格列表
func SpecFetch(ctx context.Context, in *pb.MallFetchRequest) (reply *pb.SpecReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -23,8 +23,15 @@ func SpecFetch(ctx context.Context, in *pb.MallFetchRequest) (reply *pb.SpecRepl
return nil, errcode.ErrInvalidArgument
}
// 只能查询当前登录者所属店铺的规格
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" || storeIdentity != in.StoreIdentity {
return nil, errcode.ErrPermissionDenied
}
spec := make([]*models.MallProductSpec, 0)
tx := impl.DBService.Model(&models.MallProductSpec{}).Where("store_identity = ?", in.StoreIdentity)
tx := impl.DBService.Model(&models.MallProductSpec{}).Where("store_identity = ?", storeIdentity)
if in.Keyword != "" {
tx = tx.Where("keyword like ?", "%"+in.Keyword+"%")
}

View File

@@ -14,7 +14,7 @@ import (
// ModifySpec 修改产品规格
func SpecModify(ctx context.Context, in *pb.SpecItem) (reply *pb.IdentityStatusReply, err error) {
// parse authorization meta.
_, err = service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
auth, err := service.ParseMetaCtx(ctx, &service.ParseOptions{RoleValue: "Mall_Admin"})
if err != nil {
return nil, err
}
@@ -26,16 +26,27 @@ func SpecModify(ctx context.Context, in *pb.SpecItem) (reply *pb.IdentityStatusR
}
// 只能修改当前登录者所属店铺的规格,规格归属以 token 中的店铺为准
owner, _ := auth.Owner.(map[string]any)
storeIdentity, _ := owner["store_identity"].(string)
if storeIdentity == "" {
return nil, errcode.ErrPermissionDenied
}
// 数据组装
data, err := requestToModelSpec(in)
if err != nil {
return nil, err
}
err = impl.DBService.Where("identity=?", data.Identity).Updates(data).Error
if err != nil {
printer.Error(err.Error())
data.StoreIdentity = storeIdentity
tx := impl.DBService.Where("identity=?", data.Identity).Where("store_identity = ?", storeIdentity).Updates(data)
if tx.Error != nil {
printer.Error(tx.Error.Error())
return nil, errcode.ErrDB
}
if tx.RowsAffected == 0 {
return nil, errcode.ErrPermissionDenied
}
return &pb.IdentityStatusReply{
Code: 0,