Files
jiang13-bbs/frontend/lib/postMeta.ts
freefire c44b0efa7d feat(hide): 密码可见隐藏块,发帖双栏预览与门禁体验修复
增加密码解锁与游客签名 cookie;发帖页对齐 1440 并默认双栏预览;修复 locked 解析、按钮对比度与回复聚焦。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 05:46:42 +08:00

94 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: "password", 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}`;
}