feat(kol): workspace KOL cards + article source type

This commit is contained in:
2026-04-17 15:19:11 +08:00
parent 641383a585
commit b6bd4f02fb
16 changed files with 192 additions and 5 deletions
@@ -81,6 +81,7 @@ type ArticleListItem struct {
ID int64 `json:"id"`
SourceType string `json:"source_type"`
TemplateID *int64 `json:"template_id"`
KolPromptID *int64 `json:"kol_prompt_id"`
TemplateName *string `json:"template_name"`
PromptRuleID *int64 `json:"prompt_rule_id"`
PromptRuleName *string `json:"prompt_rule_name"`
@@ -221,7 +222,7 @@ func (s *ArticleService) loadArticles(ctx context.Context, tenantID int64, param
return nil, response.ErrInternal(50010, "query_failed", "failed to count articles")
}
listQuery := `SELECT a.id, a.source_type, a.template_id, a.prompt_rule_id, a.generate_status, a.publish_status, a.created_at,
listQuery := `SELECT a.id, a.source_type, a.template_id, a.kol_prompt_id, a.prompt_rule_id, a.generate_status, a.publish_status, a.created_at,
COALESCE(av.title, NULLIF(a.wizard_state_json ->> 'title', ''), NULLIF(gt.input_params_json ->> 'title', '')), gt.error_message, COALESCE(av.word_count, 0), av.source_label, t.template_name, pr.name, a.wizard_state_json, gt.input_params_json
FROM articles a
LEFT JOIN article_versions av ON av.id = a.current_version_id
@@ -299,7 +300,7 @@ func (s *ArticleService) loadArticles(ctx context.Context, tenantID int64, param
var dbSourceType string
var wizardStateJSON []byte
var inputParamsJSON []byte
if err := rows.Scan(&item.ID, &dbSourceType, &item.TemplateID, &item.PromptRuleID, &item.GenerateStatus, &item.PublishStatus, &item.CreatedAt,
if err := rows.Scan(&item.ID, &dbSourceType, &item.TemplateID, &item.KolPromptID, &item.PromptRuleID, &item.GenerateStatus, &item.PublishStatus, &item.CreatedAt,
&item.Title, &item.GenerationErrorMessage, &item.WordCount, &item.SourceLabel, &item.TemplateName, &item.PromptRuleName, &wizardStateJSON, &inputParamsJSON); err != nil {
return nil, response.ErrInternal(50010, "scan_failed", err.Error())
}
@@ -64,11 +64,16 @@ func workspaceTemplateCardsCacheKey(tenantID int64) string {
return fmt.Sprintf("workspace:template_cards:%d", tenantID)
}
func workspaceKolCardsCacheKey(tenantID int64) string {
return fmt.Sprintf("workspace:kol_cards:%d", tenantID)
}
func invalidateWorkspaceCaches(ctx context.Context, c sharedcache.Cache, tenantID int64) {
deleteCacheKey(ctx, c, workspaceOverviewCacheKey(tenantID))
deleteCacheKey(ctx, c, workspaceRecentArticlesCacheKey(tenantID))
deleteCacheKey(ctx, c, workspaceQuotaSummaryCacheKey(tenantID))
deleteCacheKey(ctx, c, workspaceTemplateCardsCacheKey(tenantID))
deleteCacheKey(ctx, c, workspaceKolCardsCacheKey(tenantID))
}
func brandListCacheKey(tenantID int64) string {
@@ -148,3 +148,27 @@ func (s *WorkspaceService) TemplateCards(ctx context.Context) ([]TemplateCard, e
return cards, nil
})
}
func (s *WorkspaceService) KolCards(ctx context.Context) ([]domain.KolWorkspaceCard, error) {
actor := auth.MustActor(ctx)
return sharedcache.LoadJSON(ctx, s.cache, &s.cacheGroup, workspaceKolCardsCacheKey(actor.TenantID), defaultCacheTTL(), func(loadCtx context.Context) ([]domain.KolWorkspaceCard, error) {
rows, err := s.repo.ListKolCards(loadCtx, actor.TenantID)
if err != nil {
return nil, response.ErrInternal(50010, "query_failed", "failed to fetch KOL cards")
}
cards := make([]domain.KolWorkspaceCard, 0, len(rows))
for _, row := range rows {
cards = append(cards, domain.KolWorkspaceCard{
SubscriptionPromptID: row.SubscriptionPromptID,
GrantedAt: row.GrantedAt,
PromptName: row.PromptName,
PlatformHint: row.PlatformHint,
PackageName: row.PackageName,
PackageCover: row.PackageCover,
KolDisplayName: row.KolDisplayName,
})
}
return cards, nil
})
}