feat(publish): require cover image for WeChat Official Account
WeChat 公众号在管理员/运营者授权发布场景下需要 2.35:1 封面, 新增共享 publishPlatformRequiresCover 校验并同步前端封面要求与文案, 避免在调度与即时发布两条路径上重复维护平台名单。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1101,7 +1101,7 @@ const enUS = {
|
||||
previewHintLocked: "A selected platform requires a fixed cover ratio, so the cover will be exported using the current platform requirement.",
|
||||
previewHintFree: "There is no forced cover ratio right now. You can upload the original image directly or adjust framing before confirming.",
|
||||
requirementsTitle: "Platform requirements",
|
||||
requirementsHint: "Requirements switch automatically based on the selected publish platforms. Baijiahao and Dongchedi require a cover image.",
|
||||
requirementsHint: "Requirements switch automatically based on the selected publish platforms. WeChat Official Account, Baijiahao, and Dongchedi require a cover image.",
|
||||
recommendedRatio: "Recommended ratio",
|
||||
recommendedSize: "Recommended size",
|
||||
required: "Required",
|
||||
|
||||
@@ -1110,7 +1110,7 @@ const zhCN = {
|
||||
previewHintLocked: "已选择需要固定封面比例的平台,确认时会按当前平台要求输出封面。",
|
||||
previewHintFree: "当前不限制封面比例,可直接上传原图;如需调整也可拖拽缩放后再确认。",
|
||||
requirementsTitle: "平台封面要求",
|
||||
requirementsHint: "会根据当前选中的发布平台自动切换要求,百家号和懂车帝为强制上传。",
|
||||
requirementsHint: "会根据当前选中的发布平台自动切换要求,微信公众号、百家号和懂车帝为强制上传。",
|
||||
recommendedRatio: "推荐比例",
|
||||
recommendedSize: "推荐尺寸",
|
||||
required: "必传",
|
||||
|
||||
@@ -24,6 +24,15 @@ const defaultRequirement = {
|
||||
};
|
||||
|
||||
const requirementCatalog: Record<string, Partial<PlatformCoverRequirement>> = {
|
||||
weixin_gzh: {
|
||||
required: true,
|
||||
supportMode: "native",
|
||||
aspectRatio: 2.35,
|
||||
aspectLabel: "2.35:1",
|
||||
outputWidth: 1200,
|
||||
outputHeight: 511,
|
||||
priority: 110,
|
||||
},
|
||||
baijiahao: {
|
||||
required: true,
|
||||
supportMode: "native",
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
@@ -136,13 +137,22 @@ func (s *MediaService) listArticlePublishRecords(ctx context.Context, tenantID,
|
||||
|
||||
func publishBatchRequiresCover(accounts []platformAccountSeed) bool {
|
||||
for _, account := range accounts {
|
||||
if account.PlatformID == "baijiahao" || account.PlatformID == "dongchedi" {
|
||||
if publishPlatformRequiresCover(account.PlatformID) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func publishPlatformRequiresCover(platformID string) bool {
|
||||
switch strings.TrimSpace(platformID) {
|
||||
case "weixin_gzh", "baijiahao", "dongchedi":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func pointerStringValue(value *string) string {
|
||||
if value == nil {
|
||||
return ""
|
||||
|
||||
@@ -162,7 +162,7 @@ func (s *PublishJobService) Create(ctx context.Context, actor auth.Actor, req Cr
|
||||
accountSeeds = append(accountSeeds, *target.accountSeed)
|
||||
}
|
||||
if publishBatchRequiresCover(accountSeeds) && strings.TrimSpace(pointerStringValue(articleMeta.CoverAssetURL)) == "" {
|
||||
return nil, response.ErrBadRequest(40044, "publish_cover_required", "baijiahao publishing requires a cover image")
|
||||
return nil, response.ErrBadRequest(40044, "publish_cover_required", "selected publishing platform requires a cover image")
|
||||
}
|
||||
|
||||
publishBatchID, publishRecordIDs, err := createPublishBatchRecords(
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package app
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPublishPlatformRequiresCover(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, platformID := range []string{"weixin_gzh", "baijiahao", "dongchedi"} {
|
||||
if !publishPlatformRequiresCover(platformID) {
|
||||
t.Fatalf("publishPlatformRequiresCover(%q) = false, want true", platformID)
|
||||
}
|
||||
}
|
||||
|
||||
if publishPlatformRequiresCover("zhihu") {
|
||||
t.Fatal("publishPlatformRequiresCover(\"zhihu\") = true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublishCoverRequirementCallersIncludeWeixinGzh(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
accounts := []platformAccountSeed{{PlatformID: "weixin_gzh"}}
|
||||
if !publishBatchRequiresCover(accounts) {
|
||||
t.Fatal("publishBatchRequiresCover() = false for weixin_gzh, want true")
|
||||
}
|
||||
|
||||
if !schedulePublishPlatformsRequireCover([]string{"weixin_gzh"}) {
|
||||
t.Fatal("schedulePublishPlatformsRequireCover() = false for weixin_gzh, want true")
|
||||
}
|
||||
}
|
||||
@@ -564,8 +564,7 @@ func (s *ScheduleTaskService) loadPublishAccountPlatformIDs(ctx context.Context,
|
||||
|
||||
func schedulePublishPlatformsRequireCover(platformIDs []string) bool {
|
||||
for _, platformID := range platformIDs {
|
||||
switch strings.TrimSpace(platformID) {
|
||||
case "baijiahao", "dongchedi":
|
||||
if publishPlatformRequiresCover(platformID) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user