package logic import ( "context" "encoding/json" "strconv" "time" "product/internal/dao" "product/internal/model" "product/internal/svc" "product/product" "pkg.local/log" "pkg.local/modelbase" "pkg.local/redis" "github.com/zeromicro/go-zero/core/logx" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" ) type AddLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewAddLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddLogic { return &AddLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *AddLogic) Add(in *product.AddReq) (*product.AddResp, error) { l.Info("zero logx 方式 ... ") log.Info("原始 zap 方式 ... ") redis.Client.Get(l.ctx, redis.GetRedisKey("product:test")) if in.GetType() == dao.ProductTypeNormal { if in.GetAgentPrice() == 0 || in.GetStorePrice() == 0 || in.GetSalePrice() == 0 || in.GetSharePrice() == 0 || in.GetSaleReward() == "" { return nil, status.Error(codes.InvalidArgument, "缺少相关价格") } } publishTime := time.Now() if len(in.GetPublishTime()) > 1 { t, err := parsePublishTime(in.GetPublishTime()) if err != nil { return nil, status.Error(codes.InvalidArgument, "时间错误") } publishTime = t } var check dao.ProductCheckExist err := model.ProductModel{}.Init().GetOne(modelbase.Params{ Eq: map[string]string{"name": in.GetName()}, }, &check) if err != nil { log.Errorf("check product name: %v", err) return nil, status.Error(codes.Internal, "查询失败") } if check.Id > 0 { return nil, status.Error(codes.AlreadyExists, "数据已存在") } // 管理员信息后续从 ctx / metadata 取 adminId := 0 adminName := "" data := dao.ProductCreate{ Name: in.GetName(), Subhead: in.GetSubhead(), Content: in.GetContent(), ModelCode: in.GetModelCode(), Price: float32(in.GetPrice()), StorePrice: float32(in.GetStorePrice()), SalePrice: float32(in.GetSalePrice()), SharePrice: float32(in.GetSharePrice()), AgentPrice: float32(in.GetAgentPrice()), SaleReward: in.GetSaleReward(), Waybill: in.GetWaybill(), SalesModel: uint8(in.GetSalesModel()), Weight: float32(in.GetWeight()), Images: in.GetImages(), PeriodValidity: int16(in.GetPeriodValidity()), Type: uint8(in.GetType()), NormsNumber: uint8(in.GetNormsNumber()), Number: uint(in.GetNumber()), Sort: 1, Label: in.GetLabel(), Cubage: in.GetCubage(), BoxNumber: in.GetBoxNumber(), IsIndex: uint8(in.GetIsIndex()), IndexImage: in.GetIndexImage(), IsBuy: uint8(in.GetIsBuy()), PublishTime: publishTime, TryNumber: uint8(in.GetTryNumber()), AdminName: adminName, AdminId: adminId, } if data.IsIndex == 0 { data.IsIndex = 2 } if data.IsBuy == 0 { data.IsBuy = 2 } if data.Type == 0 { data.Type = dao.ProductTypeNormal } if data.NormsNumber == 0 { data.NormsNumber = 1 } if data.TryNumber == 0 { data.TryNumber = 1 } if data.SalesModel == 0 { data.SalesModel = dao.ProductSalesModelOffline } err = l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error { if err := (model.ProductModel{}.Init().WithTX(tx).Create(&data)); err != nil { return err } content := dao.ProductVerify{ Id: data.Id, ModelCode: data.ModelCode, Price: data.Price, StorePrice: data.StorePrice, SalePrice: data.SalePrice, SharePrice: data.SharePrice, AgentPrice: data.AgentPrice, SaleReward: data.SaleReward, Type: data.Type, BoxNumber: data.BoxNumber, NormsNumber: data.NormsNumber, AdminName: data.AdminName, AdminId: data.AdminId, } contentBytes, err := json.Marshal(content) if err != nil { return err } verify := dao.VerifyCreate{ VerifyId: strconv.Itoa(data.Id), Content: string(contentBytes), Type: dao.VerifyTypeProduct, } return model.VerifyModel{}.Init().WithTX(tx).Create(&verify) }) if err != nil { log.Errorf("create product: %v", err) return nil, status.Error(codes.Internal, "创建失败") } // redis 用法示例 key := redis.GetRedisKey("product:last_add") if err := redis.Client.Set(l.ctx, key, in.GetName(), time.Hour).Err(); err != nil { log.Errorf("redis set %s: %v", key, err) } else { log.Infof("add product success id=%d", data.Id) } return &product.AddResp{}, nil } func parsePublishTime(s string) (time.Time, error) { for _, layout := range []string{time.DateTime, time.DateOnly} { if t, err := time.ParseInLocation(layout, s, time.Local); err == nil { return t, nil } } return time.Time{}, status.Error(codes.InvalidArgument, "invalid time format") }