Files
jiang13-bbs/frontend/lib/postMeta.ts
freefire 01e2fd05ca feat(compose): 正文内嵌隐藏块并升级 Markdown 编辑器
去掉整帖可见性表单,改为 :::hide 按块脱敏;工具栏补齐代码块、链接/图片对话框与粘贴拖拽上传。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 04:58:20 +08:00

93 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** 帖子类型 / 可见性 / 展示文案(前后端共用约定) */
export const POST_TYPES = [
{ value: "discussion", label: "讨论", hint: "默认讨论帖" },
{ value: "question", label: "问答", hint: "提问求解" },
{ value: "poll", label: "投票", hint: "发起投票,读者可参与" },
{ value: "bounty", label: "悬赏", hint: "发布时托管积分,采纳后发放" },
{ value: "lottery", label: "抽奖", hint: "奖品类型+数量入池,评论后锁定奖品" },
] as const;
export type PostTypeValue = (typeof POST_TYPES)[number]["value"];
export const CONTENT_ACCESS = [
{ value: "public", label: "公开" },
{ value: "login", label: "登录可见" },
{ value: "reply", label: "回复可见" },
{ value: "points", label: "积分可见" },
{ value: "mixed", label: "含隐藏内容" },
] as const;
export type ContentAccessValue = (typeof CONTENT_ACCESS)[number]["value"];
export const BOUNTY_EXPIRE_DAYS = [3, 7, 14, 30] as const;
export const LOTTERY_EXPIRE_DAYS = [1, 3, 7, 14] as const;
export const POLL_EXPIRE_DAYS = [1, 3, 7, 14] as const;
export function normalizePostType(t?: string): PostTypeValue {
if (!t) return "discussion";
if (POST_TYPES.some((x) => x.value === t)) return t as PostTypeValue;
return "discussion";
}
export function postTypeLabel(t?: string): string {
const n = normalizePostType(t);
return POST_TYPES.find((x) => x.value === n)?.label || "讨论";
}
export function contentAccessLabel(a?: string): string {
const hit = CONTENT_ACCESS.find((x) => x.value === a);
return hit?.label || "公开";
}
/** 列表 type_status → 徽章文案 */
export function typeStatusLabel(postType?: string, typeStatus?: string): string {
const pt = normalizePostType(postType);
const s = (typeStatus || "").toLowerCase();
switch (pt) {
case "question":
return s === "solved" ? "已解决" : "未解决";
case "poll":
return s === "closed" ? "已结束" : "进行中";
case "bounty":
if (s === "solved") return "已采纳";
if (s === "expired") return "已过期";
return "进行中";
case "lottery":
if (s === "drawn") return "已开奖";
if (s === "closed") return "已截止";
return "进行中";
default:
return "";
}
}
/** 状态徽章 CSS class(浅色区分) */
export function typeStatusClass(postType?: string, typeStatus?: string): string {
const pt = normalizePostType(postType);
const s = (typeStatus || "").toLowerCase();
let kind = "open";
switch (pt) {
case "question":
kind = s === "solved" ? "solved" : "unsolved";
break;
case "poll":
kind = s === "closed" ? "closed" : "open";
break;
case "bounty":
if (s === "solved") kind = "solved";
// 已过期:与投票「已结束」同色(灰胶囊,标识已到期)
else if (s === "expired") kind = "closed";
else kind = "open";
break;
case "lottery":
// 已开奖 / 已截止:与投票「已结束」同色(灰胶囊)
if (s === "drawn" || s === "closed") kind = "closed";
else kind = "open";
break;
default:
return "";
}
return `badge-status badge-status-${kind}`;
}