feat: 可配置站点 URL 风格

- 新增 urlStyle 工具与测试:postPath/userPath/sitePagePath 统一生成链接
- 管理端新增 UrlStylePanel 设置面板,settings 服务与 handler 适配
- 全站路由链接与 JSON-LD/sitemap 切换为统一 URL 生成
- middleware 与相关组件适配
This commit is contained in:
2026-09-27 04:01:42 +08:00
parent 1d862a0dd3
commit 7a44c1f2cf
64 changed files with 1183 additions and 200 deletions

View File

@@ -36,6 +36,8 @@ import {
import { isOwner, ROLES } from "@/lib/roles";
import { formatDate, formatRelative } from "@/lib/format";
import { realtime } from "@/lib/realtime";
import { userPath } from "@/lib/urlStyle";
import { useUrlStyle } from "@/components/SiteBrandProvider";
import Avatar from "@/components/Avatar";
import RoleBadge from "@/components/RoleBadge";
import Modal from "@/components/Modal";
@@ -302,6 +304,7 @@ export default function UsersAdmin({
currentUserId: number;
currentUserRole: string;
}) {
const urlStyle = useUrlStyle();
const [users, setUsers] = useState<AdminUser[]>(initial?.users ?? []);
const [summary, setSummary] = useState<AdminUserSummary>(
initial?.summary ?? {
@@ -686,7 +689,7 @@ export default function UsersAdmin({
return (
<div className="flex items-center gap-1.5 flex-wrap">
{auditBtn}
<Link href={`/u/${u.id}`} className="btn btn-line btn-sm gap-1" aria-label={`查看 ${u.nickname} 的个人主页`}>
<Link href={userPath(urlStyle, u.id)} className="btn btn-line btn-sm gap-1" aria-label={`查看 ${u.nickname} 的个人主页`}>
<ExternalLink size={13} />
主页
</Link>
@@ -697,7 +700,7 @@ export default function UsersAdmin({
return (
<div className="flex items-center gap-1.5 flex-wrap">
{auditBtn}
<Link href={`/u/${u.id}`} className="btn btn-line btn-sm gap-1" aria-label={`查看 ${u.nickname} 的个人主页`}>
<Link href={userPath(urlStyle, u.id)} className="btn btn-line btn-sm gap-1" aria-label={`查看 ${u.nickname} 的个人主页`}>
<ExternalLink size={13} />
主页
</Link>
@@ -718,7 +721,7 @@ export default function UsersAdmin({
return (
<div className="flex items-center gap-1.5 flex-wrap">
{auditBtn}
<Link href={`/u/${u.id}`} className="btn btn-line btn-sm gap-1" aria-label={`查看 ${u.nickname} 的个人主页`}>
<Link href={userPath(urlStyle, u.id)} className="btn btn-line btn-sm gap-1" aria-label={`查看 ${u.nickname} 的个人主页`}>
<ExternalLink size={13} />
主页
</Link>