Compare commits

...

4 Commits

Author SHA1 Message Date
root 0f4310c345 fix(admin-web): prevent source link overflow in article drawer
Frontend CI / Frontend (push) Has been cancelled
Backend CI / Backend (push) Has been cancelled
将来源链接外层改成 grid wrapper 并固定图标 flex-shrink,
避免长 URL 把图标挤出布局或超过描述列宽。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 10:22:05 +08:00
root 764abf32ae refactor(desktop-client): tidy PublishManagementView copy and errors
将队列提示与英文 eyebrow 全部本地化为中文,并改为通过
unwrapClientErrorMessage + normalizeTaskErrorMessage 统一兜底,
避免不同操作回退到原始 Error.message 时漏掉发布器归一化结果。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 10:22:03 +08:00
root 7b6ae0f6d0 feat(desktop-client): expand publisher error normalization
新增登录态失效与微信公众号外链缺失两类发布错误归一化,
将原本散落在适配器里的中文提示集中到 shared/publisher-errors,
让渲染层与 main 进程共用同一份用户可读文案。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 10:21:54 +08:00
root 3436d9536d 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>
2026-05-01 10:21:46 +08:00
12 changed files with 179 additions and 33 deletions
@@ -301,21 +301,23 @@ async function copyPublishLink(record: PublishRecord): Promise<void> {
:label="t('article.meta.sourceArticle')" :label="t('article.meta.sourceArticle')"
:span="2" :span="2"
> >
<a <div class="article-drawer__source-wrapper">
class="article-drawer__source-link" <a
:href="sourceArticleURL" class="article-drawer__source-link"
target="_blank" :href="sourceArticleURL"
rel="noopener noreferrer" target="_blank"
:title="sourceArticleURL" rel="noopener noreferrer"
> :title="sourceArticleURL"
<LinkOutlined /> >
<span class="article-drawer__source-copy"> <LinkOutlined class="article-drawer__source-icon" />
<span v-if="sourceArticleTitle" class="article-drawer__source-title"> <span class="article-drawer__source-copy">
{{ sourceArticleTitle }} <span v-if="sourceArticleTitle" class="article-drawer__source-title">
{{ sourceArticleTitle }}
</span>
<span class="article-drawer__source-url">{{ sourceArticleURL }}</span>
</span> </span>
<span class="article-drawer__source-url">{{ sourceArticleURL }}</span> </a>
</span> </div>
</a>
</a-descriptions-item> </a-descriptions-item>
</a-descriptions> </a-descriptions>
</section> </section>
@@ -459,14 +461,24 @@ async function copyPublishLink(record: PublishRecord): Promise<void> {
margin-top: 24px; margin-top: 24px;
} }
.article-drawer__source-wrapper {
display: grid;
grid-template-columns: minmax(0, 1fr);
width: 100%;
}
.article-drawer__source-link { .article-drawer__source-link {
display: inline-flex; display: flex;
max-width: 100%; width: 100%;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
color: #1677ff; color: #1677ff;
} }
.article-drawer__source-icon {
flex-shrink: 0;
}
.article-drawer__source-copy { .article-drawer__source-copy {
display: flex; display: flex;
min-width: 0; min-width: 0;
+1 -1
View File
@@ -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.", 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.", previewHintFree: "There is no forced cover ratio right now. You can upload the original image directly or adjust framing before confirming.",
requirementsTitle: "Platform requirements", 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", recommendedRatio: "Recommended ratio",
recommendedSize: "Recommended size", recommendedSize: "Recommended size",
required: "Required", required: "Required",
+1 -1
View File
@@ -1110,7 +1110,7 @@ const zhCN = {
previewHintLocked: "已选择需要固定封面比例的平台,确认时会按当前平台要求输出封面。", previewHintLocked: "已选择需要固定封面比例的平台,确认时会按当前平台要求输出封面。",
previewHintFree: "当前不限制封面比例,可直接上传原图;如需调整也可拖拽缩放后再确认。", previewHintFree: "当前不限制封面比例,可直接上传原图;如需调整也可拖拽缩放后再确认。",
requirementsTitle: "平台封面要求", requirementsTitle: "平台封面要求",
requirementsHint: "会根据当前选中的发布平台自动切换要求,百家号和懂车帝为强制上传。", requirementsHint: "会根据当前选中的发布平台自动切换要求,微信公众号、百家号和懂车帝为强制上传。",
recommendedRatio: "推荐比例", recommendedRatio: "推荐比例",
recommendedSize: "推荐尺寸", recommendedSize: "推荐尺寸",
required: "必传", required: "必传",
@@ -24,6 +24,15 @@ const defaultRequirement = {
}; };
const requirementCatalog: Record<string, Partial<PlatformCoverRequirement>> = { 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: { baijiahao: {
required: true, required: true,
supportMode: "native", supportMode: "native",
@@ -8,6 +8,10 @@ import {
sessionFetchText, sessionFetchText,
uploadHtmlImages, uploadHtmlImages,
} from "./common"; } from "./common";
import {
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
normalizeWeixinGzhPublishErrorMessage,
} from "../../shared/publisher-errors";
import { import {
fetchImageAssetBlob, fetchImageAssetBlob,
getCenteredCropRect, getCenteredCropRect,
@@ -1932,10 +1936,10 @@ function failureResult(error: unknown): ReturnType<PublishAdapter["publish"]> ex
if (message.startsWith("weixin_gzh_public_url_missing")) { if (message.startsWith("weixin_gzh_public_url_missing")) {
return { return {
status: "failed", status: "failed",
summary: "微信公众号已提交发布,但未能获取外部文章链接,请在公众号后台发表记录确认。", summary: WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
error: { error: {
code: "weixin_gzh_public_url_missing", code: "weixin_gzh_public_url_missing",
message, message: normalizeWeixinGzhPublishErrorMessage(message) ?? WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
}, },
}; };
} }
@@ -14,6 +14,7 @@ import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import StatusBadge from "../components/StatusBadge.vue"; import StatusBadge from "../components/StatusBadge.vue";
import { useDesktopRuntime } from "../composables/useDesktopRuntime"; import { useDesktopRuntime } from "../composables/useDesktopRuntime";
import { unwrapClientErrorMessage } from "../lib/client-errors";
import { formatDateTime, formatRelativeTime } from "../lib/formatters"; import { formatDateTime, formatRelativeTime } from "../lib/formatters";
import { desktopPlatformShortName, desktopPublishMediaCatalog, translateDesktopPlatform } from "../lib/media-catalog"; import { desktopPlatformShortName, desktopPublishMediaCatalog, translateDesktopPlatform } from "../lib/media-catalog";
import { normalizePublisherErrorMessage } from "../../shared/publisher-errors"; import { normalizePublisherErrorMessage } from "../../shared/publisher-errors";
@@ -199,7 +200,7 @@ function summaryForTask(
): string { ): string {
switch (status) { switch (status) {
case "queued": case "queued":
return "任务已进入队列,前面的 PublishTasks 翻完后再继续展示历史记录。"; return "任务已进入队列,前面的发布任务完成后继续执行。";
case "in_progress": case "in_progress":
return "当前正在由桌面端执行发送,请避免重复触发。"; return "当前正在由桌面端执行发送,请避免重复触发。";
case "succeeded": case "succeeded":
@@ -277,7 +278,7 @@ async function refreshTasks(page = currentPage.value) {
taskPage.value = response; taskPage.value = response;
currentPage.value = response.page; currentPage.value = response.page;
} catch (err) { } catch (err) {
error.value = err instanceof Error ? err.message : "desktop publish tasks unavailable"; error.value = normalizeTaskErrorMessage(unwrapClientErrorMessage(err, "发布任务暂时不可用"));
} finally { } finally {
loading.value = false; loading.value = false;
} }
@@ -291,7 +292,7 @@ async function retryTask(taskId: string) {
notifySuccess("已重新加入发布队列"); notifySuccess("已重新加入发布队列");
await refreshTasks(); await refreshTasks();
} catch (err) { } catch (err) {
notifyActionError(err instanceof Error ? err.message : "重新发送失败"); notifyActionError(normalizeTaskErrorMessage(unwrapClientErrorMessage(err, "重新发送失败")) ?? "重新发送失败");
} finally { } finally {
actionPendingTaskId.value = null; actionPendingTaskId.value = null;
} }
@@ -305,7 +306,7 @@ async function openExternalUrl(url: string | null) {
try { try {
await window.desktopBridge.app.openExternalUrl(url); await window.desktopBridge.app.openExternalUrl(url);
} catch (err) { } catch (err) {
notifyActionError(err instanceof Error ? err.message : "打开外链失败"); notifyActionError(normalizeTaskErrorMessage(unwrapClientErrorMessage(err, "打开外链失败")) ?? "打开外链失败");
} }
} }
@@ -321,7 +322,7 @@ async function openAccountWorkbench(record: PublishTaskItem) {
displayName: account?.displayName ?? record.accountName, displayName: account?.displayName ?? record.accountName,
}); });
} catch (err) { } catch (err) {
notifyActionError(err instanceof Error ? err.message : "打开账号工作台失败"); notifyActionError(normalizeTaskErrorMessage(unwrapClientErrorMessage(err, "打开账号工作台失败")) ?? "打开账号工作台失败");
} finally { } finally {
consolePendingTaskId.value = null; consolePendingTaskId.value = null;
} }
@@ -359,7 +360,7 @@ async function copyErrorMessage(record: PublishTaskItem) {
} }
}, 1_500); }, 1_500);
} catch (err) { } catch (err) {
notifyActionError(err instanceof Error ? err.message : "复制错误详情失败"); notifyActionError(normalizeTaskErrorMessage(unwrapClientErrorMessage(err, "复制错误详情失败")) ?? "复制错误详情失败");
} }
} }
@@ -470,7 +471,7 @@ const tableScroll = { x: 1080 } as const;
<section class="hero-card"> <section class="hero-card">
<div class="hero-header"> <div class="hero-header">
<div class="hero-title"> <div class="hero-title">
<p class="eyebrow">PUBLISH EXECUTION DESK</p> <p class="eyebrow">发布执行台</p>
<h2>发布管理</h2> <h2>发布管理</h2>
</div> </div>
<div class="hero-actions"> <div class="hero-actions">
@@ -505,7 +506,7 @@ const tableScroll = { x: 1080 } as const;
<div class="hero-header table-toolbar"> <div class="hero-header table-toolbar">
<div class="toolbar-meta"> <div class="toolbar-meta">
<h3 class="section-title">待发布与已发送记录</h3> <h3 class="section-title">待发布与已发送记录</h3>
<p class="section-desc">待发布任务始终排在最前每页 10 分页与总数以服务端返回的 PublishTasks 为准</p> <p class="section-desc">待发布任务始终排在最前每页 10 分页与总数以服务端返回的发布任务为准</p>
</div> </div>
<div class="toolbar-filters"> <div class="toolbar-filters">
<a-input <a-input
@@ -1,14 +1,18 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { import {
PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE,
QIEHAO_REAL_NAME_AUTH_MESSAGE, QIEHAO_REAL_NAME_AUTH_MESSAGE,
WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE, WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE,
WANGYIHAO_PUBLISH_CLICK_MESSAGE, WANGYIHAO_PUBLISH_CLICK_MESSAGE,
WANGYIHAO_TOKEN_MISSING_MESSAGE, WANGYIHAO_TOKEN_MISSING_MESSAGE,
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
isQiehaoRealNameAuthError, isQiehaoRealNameAuthError,
normalizePublisherErrorMessage, normalizePublisherErrorMessage,
normalizePublisherLoginErrorMessage,
normalizeQiehaoPublishErrorMessage, normalizeQiehaoPublishErrorMessage,
normalizeWangyihaoPublishErrorMessage, normalizeWangyihaoPublishErrorMessage,
normalizeWeixinGzhPublishErrorMessage,
} from "./publisher-errors"; } from "./publisher-errors";
describe("publisher error normalization", () => { describe("publisher error normalization", () => {
@@ -23,6 +27,24 @@ describe("publisher error normalization", () => {
expect(normalizeQiehaoPublishErrorMessage("publish rejected", -5022)).toBe(QIEHAO_REAL_NAME_AUTH_MESSAGE); expect(normalizeQiehaoPublishErrorMessage("publish rejected", -5022)).toBe(QIEHAO_REAL_NAME_AUTH_MESSAGE);
}); });
it("normalizes publisher login-state failures", () => {
expect(normalizePublisherErrorMessage("wangyihao_not_logged_in")).toBe(
"网易号账号登录态已失效,请重新登录该平台后再重试。",
);
expect(normalizePublisherErrorMessage("Error: weixin_gzh_not_logged_in")).toBe(
"微信公众号账号登录态已失效,请重新登录该平台后再重试。",
);
expect(normalizePublisherErrorMessage("qiehao_cookie_missing")).toBe(
"企鹅号账号登录态已失效,请重新登录该平台后再重试。",
);
});
it("uses a generic Chinese message for unknown publisher login-state failures", () => {
expect(normalizePublisherLoginErrorMessage("unknown_platform_not_logged_in")).toBe(
PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE,
);
});
it("normalizes Wangyihao token missing failures", () => { it("normalizes Wangyihao token missing failures", () => {
expect(normalizePublisherErrorMessage("wangyihao_token_missing")).toBe(WANGYIHAO_TOKEN_MISSING_MESSAGE); expect(normalizePublisherErrorMessage("wangyihao_token_missing")).toBe(WANGYIHAO_TOKEN_MISSING_MESSAGE);
expect(normalizeWangyihaoPublishErrorMessage("Error: wangyihao_token_missing")).toBe( expect(normalizeWangyihaoPublishErrorMessage("Error: wangyihao_token_missing")).toBe(
@@ -48,6 +70,15 @@ describe("publisher error normalization", () => {
); );
}); });
it("normalizes Weixin GZH missing public URL failures", () => {
expect(normalizePublisherErrorMessage("weixin_gzh_public_url_missing:100000093")).toBe(
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
);
expect(normalizeWeixinGzhPublishErrorMessage("Error: weixin_gzh_public_url_missing")).toBe(
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
);
});
it("leaves unknown publisher errors unchanged", () => { it("leaves unknown publisher errors unchanged", () => {
expect(normalizePublisherErrorMessage("qiehao_publish_failed")).toBe("qiehao_publish_failed"); expect(normalizePublisherErrorMessage("qiehao_publish_failed")).toBe("qiehao_publish_failed");
}); });
@@ -1,9 +1,28 @@
export const QIEHAO_REAL_NAME_AUTH_MESSAGE = "企鹅号账号未完成实名认证,请先到企鹅号后台完成实名认证后再重试。"; export const QIEHAO_REAL_NAME_AUTH_MESSAGE = "企鹅号账号未完成实名认证,请先到企鹅号后台完成实名认证后再重试。";
export const PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE = "发布账号登录态已失效,请重新打开平台后台完成登录后再重试。";
export const WANGYIHAO_TOKEN_MISSING_MESSAGE = "网易号发布凭证获取失败,请重新打开网易号后台确认登录状态。"; export const WANGYIHAO_TOKEN_MISSING_MESSAGE = "网易号发布凭证获取失败,请重新打开网易号后台确认登录状态。";
export const WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE = export const WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE =
"网易号草稿保存失败:参数错误。请检查标题、正文、封面或账号状态后重试。"; "网易号草稿保存失败:参数错误。请检查标题、正文、封面或账号状态后重试。";
export const WANGYIHAO_PUBLISH_CLICK_MESSAGE = export const WANGYIHAO_PUBLISH_CLICK_MESSAGE =
"网易号草稿已保存,但自动发布未完成。请打开网易号后台确认草稿状态后重试。"; "网易号草稿已保存,但自动发布未完成。请打开网易号后台确认草稿状态后重试。";
export const WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE =
"微信公众号可能已触发管理员/运营者授权发布,桌面端未能获取到文章外链。请打开公众号后台完成授权发布,并在发表记录中确认文章链接。";
const PUBLISH_PLATFORM_LABELS: Record<string, string> = {
baijiahao: "百家号",
bilibili: "bilibili",
dongchedi: "懂车帝",
jianshu: "简书",
juejin: "稀土掘金",
qiehao: "企鹅号",
smzdm: "什么值得买",
sohuhao: "搜狐号",
toutiaohao: "头条号",
wangyihao: "网易号",
weixin_gzh: "微信公众号",
zhihu: "知乎",
zol: "中关村在线",
};
function normalizeErrorText(value: string | null | undefined): string | null { function normalizeErrorText(value: string | null | undefined): string | null {
const trimmed = value?.trim(); const trimmed = value?.trim();
@@ -42,6 +61,23 @@ export function normalizeQiehaoPublishErrorMessage(
return isQiehaoRealNameAuthError(normalized, code) ? QIEHAO_REAL_NAME_AUTH_MESSAGE : normalized; return isQiehaoRealNameAuthError(normalized, code) ? QIEHAO_REAL_NAME_AUTH_MESSAGE : normalized;
} }
export function normalizePublisherLoginErrorMessage(message: string | null | undefined): string | null {
const normalized = normalizeErrorText(message);
if (!normalized) {
return null;
}
const match = normalized.match(
/\b([a-z0-9_]+?)_(not_logged_in|token_missing|cookie_missing|csrf_missing)\b/i,
);
if (!match) {
return normalized;
}
const platformLabel = PUBLISH_PLATFORM_LABELS[match[1]?.toLowerCase() ?? ""];
return platformLabel ? `${platformLabel}账号登录态已失效,请重新登录该平台后再重试。` : PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE;
}
export function normalizeWangyihaoPublishErrorMessage(message: string | null | undefined): string | null { export function normalizeWangyihaoPublishErrorMessage(message: string | null | undefined): string | null {
const normalized = normalizeErrorText(message); const normalized = normalizeErrorText(message);
if (!normalized) { if (!normalized) {
@@ -63,7 +99,21 @@ export function normalizeWangyihaoPublishErrorMessage(message: string | null | u
return normalized; return normalized;
} }
export function normalizeWeixinGzhPublishErrorMessage(message: string | null | undefined): string | null {
const normalized = normalizeErrorText(message);
if (!normalized) {
return null;
}
if (/\bweixin_gzh_public_url_missing\b/i.test(normalized)) {
return WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE;
}
return normalized;
}
export function normalizePublisherErrorMessage(message: string | null | undefined): string | null { export function normalizePublisherErrorMessage(message: string | null | undefined): string | null {
const qiehaoMessage = normalizeQiehaoPublishErrorMessage(message); const qiehaoMessage = normalizeQiehaoPublishErrorMessage(message);
return normalizeWangyihaoPublishErrorMessage(qiehaoMessage); const wangyihaoMessage = normalizeWangyihaoPublishErrorMessage(qiehaoMessage);
const loginMessage = normalizePublisherLoginErrorMessage(wangyihaoMessage);
return normalizeWeixinGzhPublishErrorMessage(loginMessage);
} }
+11 -1
View File
@@ -4,6 +4,7 @@ import (
"context" "context"
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"strings"
"time" "time"
"github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/pgxpool"
@@ -136,13 +137,22 @@ func (s *MediaService) listArticlePublishRecords(ctx context.Context, tenantID,
func publishBatchRequiresCover(accounts []platformAccountSeed) bool { func publishBatchRequiresCover(accounts []platformAccountSeed) bool {
for _, account := range accounts { for _, account := range accounts {
if account.PlatformID == "baijiahao" || account.PlatformID == "dongchedi" { if publishPlatformRequiresCover(account.PlatformID) {
return true return true
} }
} }
return false 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 { func pointerStringValue(value *string) string {
if value == nil { if value == nil {
return "" return ""
@@ -162,7 +162,7 @@ func (s *PublishJobService) Create(ctx context.Context, actor auth.Actor, req Cr
accountSeeds = append(accountSeeds, *target.accountSeed) accountSeeds = append(accountSeeds, *target.accountSeed)
} }
if publishBatchRequiresCover(accountSeeds) && strings.TrimSpace(pointerStringValue(articleMeta.CoverAssetURL)) == "" { 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( 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 { func schedulePublishPlatformsRequireCover(platformIDs []string) bool {
for _, platformID := range platformIDs { for _, platformID := range platformIDs {
switch strings.TrimSpace(platformID) { if publishPlatformRequiresCover(platformID) {
case "baijiahao", "dongchedi":
return true return true
} }
} }