feat(characters): use local character catalog

This commit is contained in:
2026-07-17 16:03:18 +08:00
parent a210a98d98
commit b3ebd5cf3b
96 changed files with 1023 additions and 522 deletions
+51
View File
@@ -9,6 +9,7 @@
import type { PayChannel } from "@/data/schemas/payment";
import type { AppSubscriptionReturnTo } from "@/router/navigation-types";
import type { CharacterProfile } from "@/data/constants/character";
import {
PAYMENT_ANALYTICS_ENTRY_PARAM,
PAYMENT_ANALYTICS_REASON_PARAM,
@@ -32,6 +33,52 @@ export const ROUTES = {
export type StaticRoute = (typeof ROUTES)[keyof typeof ROUTES];
export interface CharacterRoutes {
readonly splash: string;
readonly chat: string;
readonly privateRoom: string;
readonly tip: string;
readonly sidebar: string;
readonly feedback: string;
readonly coinsRules: string;
}
export function getCharacterRoutes(
characterSlug: CharacterProfile["slug"],
): CharacterRoutes {
const root = `/characters/${encodeURIComponent(characterSlug)}`;
return {
splash: `${root}/splash`,
chat: `${root}/chat`,
privateRoom: `${root}/private-room`,
tip: `${root}/tip`,
sidebar: `${root}/sidebar`,
feedback: `${root}/feedback`,
coinsRules: `${root}/coins-rules`,
};
}
export type RouteSearchParams = Record<
string,
string | readonly string[] | undefined
>;
export function appendRouteSearchParams(
pathname: string,
searchParams: RouteSearchParams,
): string {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(searchParams)) {
if (typeof value === "string") {
params.set(key, value);
continue;
}
value?.forEach((item) => params.append(key, item));
}
const query = params.toString();
return query ? `${pathname}?${query}` : pathname;
}
/** 动态查询路由构造器 */
export const ROUTE_BUILDERS = {
subscription: (
@@ -39,12 +86,16 @@ export const ROUTE_BUILDERS = {
options: {
payChannel?: PayChannel;
returnTo?: Exclude<AppSubscriptionReturnTo, null>;
characterSlug?: string;
analytics?: PaymentAnalyticsContext;
} = {},
): `/subscription?${string}` => {
const params = new URLSearchParams({ type });
if (options.payChannel) params.set("payChannel", options.payChannel);
if (options.returnTo) params.set("returnTo", options.returnTo);
if (options.characterSlug) {
params.set("character", options.characterSlug);
}
if (options.analytics) {
params.set(
PAYMENT_ANALYTICS_ENTRY_PARAM,