package logic import ( "context" "crypto/rand" "encoding/hex" "time" "muyu-apiserver/model" "muyu-apiserver/pkg/tenantctx" "muyu-apiserver/pkg/uid" "muyu-apiserver/rpc/production/internal/svc" "muyu-apiserver/rpc/production/pb" "github.com/zeromicro/go-zero/core/logx" ) type CreateShareLinkLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewCreateShareLinkLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateShareLinkLogic { return &CreateShareLinkLogic{ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx)} } func (l *CreateShareLinkLogic) CreateShareLink(in *pb.CreateShareLinkReq) (*pb.ShareLinkInfo, error) { tenantId := tenantctx.ExtractTenantId(l.ctx) // Validate plan exists _, err := l.svcCtx.PlanModel.FindOneByPlanId(l.ctx, in.PlanId) if err != nil { return nil, ErrPlanNotFound } // Generate 8-char short code using crypto/rand b := make([]byte, 8) if _, err := rand.Read(b); err != nil { return nil, err } shortCode := hex.EncodeToString(b)[:8] // Generate token tb := make([]byte, 16) if _, err := rand.Read(tb); err != nil { return nil, err } token := hex.EncodeToString(tb) // Default expiry: 30 minutes (override with ExpiresHours if provided) expiry := 30 * time.Minute if in.ExpiresHours > 0 { expiry = time.Duration(in.ExpiresHours) * time.Hour } expiresAt := time.Now().Add(expiry) linkId := uid.Generate() link := &model.ProShareLink{ LinkId: linkId, TenantId: tenantId, PlanId: in.PlanId, ShortCode: shortCode, Token: token, FactoryType: in.FactoryType, HideSensitive: in.HideSensitive, Status: 0, // created ExpiresAt: expiresAt, CreatedBy: tenantId, } if _, err := l.svcCtx.ShareLinkModel.Insert(l.ctx, link); err != nil { return nil, err } return &pb.ShareLinkInfo{ LinkId: linkId, TenantId: tenantId, PlanId: in.PlanId, ShortCode: shortCode, Token: token, FactoryType: in.FactoryType, HideSensitive: in.HideSensitive, Status: 0, ExpiresAt: expiresAt.Format("2006-01-02 15:04:05"), CreatedBy: tenantId, }, nil }