156 lines
5.0 KiB
TypeScript
156 lines
5.0 KiB
TypeScript
/**
|
||
* 服务配置 - PocketBase、支付等第三方服务
|
||
* 可通过环境变量覆盖,不同主题可配置不同集合/金额
|
||
* 域名更换:设置 ROOT_DOMAIN(如 nomadro.com)可推导默认 API 地址
|
||
*/
|
||
|
||
import { getThemeConfig } from "./site.config";
|
||
import {
|
||
DEFAULT_PAYMENT_API_URL,
|
||
DEFAULT_POCKETBASE_URL,
|
||
DEFAULT_MINIO_HOST,
|
||
} from "./domain.config";
|
||
|
||
export interface PocketBaseConfig {
|
||
enabled: boolean;
|
||
/** PocketBase 服务地址 */
|
||
url: string;
|
||
/** 用户认证集合 */
|
||
usersCollection: string;
|
||
/** 申请/加入表单集合(如 solan、applications) */
|
||
joinCollection: string;
|
||
}
|
||
|
||
export interface PaymentConfig {
|
||
enabled: boolean;
|
||
/** 支付 API 地址(payjsapi) */
|
||
apiUrl: string;
|
||
/** 支付提供商:zpay | xorpay */
|
||
provider: "zpay" | "xorpay";
|
||
/** 默认金额(分) */
|
||
defaultAmount: number;
|
||
/** 默认订单类型 */
|
||
defaultType: string;
|
||
/** ZPAY 提交地址 */
|
||
zpaySubmitUrl: string;
|
||
}
|
||
|
||
export interface MinioConfig {
|
||
enabled: boolean;
|
||
/** MinIO 服务端点 */
|
||
endPoint: string;
|
||
/** 端口 */
|
||
port: number;
|
||
/** 是否使用 SSL */
|
||
useSSL: boolean;
|
||
/** 存储桶 */
|
||
bucket: string;
|
||
/** Access Key */
|
||
accessKey: string;
|
||
/** Secret Key */
|
||
secretKey: string;
|
||
/** 区域 */
|
||
region: string;
|
||
/** 公开访问 URL(用于生成文件链接) */
|
||
publicUrl: string;
|
||
/** 上传路径前缀(如 joins、uploads) */
|
||
uploadPrefix: string;
|
||
}
|
||
|
||
export interface ServicesConfig {
|
||
pocketbase: PocketBaseConfig;
|
||
payment: PaymentConfig;
|
||
minio: MinioConfig;
|
||
}
|
||
|
||
const isDev = process.env.NODE_ENV === "development";
|
||
const PAYJSAPI_PORT = process.env.PAYJSAPI_PORT || "8007";
|
||
|
||
/** 站点标识,用于 VIP 按站点隔离。digital 专题站(ai.xx/android.xx)各自独立,如 digital_ai、digital_android */
|
||
export const SITE_ID = process.env.NEXT_PUBLIC_SITE_ID || "digital";
|
||
|
||
/** vip 站(vip.hackrobot.cn)的 site_id,其付费 VIP 可解锁所有 digital 专题站 */
|
||
export const VIP_MASTER_SITE_ID = "vip";
|
||
|
||
export function getApiUrlFromRequest(hostHeader: string | null): string | null {
|
||
if (!hostHeader) return null;
|
||
if (!isDev) return process.env.PAYMENT_API_URL || DEFAULT_PAYMENT_API_URL;
|
||
const hostname = hostHeader.split(":")[0];
|
||
return `http://${hostname}:${PAYJSAPI_PORT}`;
|
||
}
|
||
|
||
/** 获取 PocketBase 配置(可传入主题覆盖) */
|
||
export function getPocketBaseConfig(themeOverride?: { joinCollection?: string }): PocketBaseConfig {
|
||
const joinCollection =
|
||
themeOverride?.joinCollection ||
|
||
process.env.POCKETBASE_JOIN_COLLECTION ||
|
||
"solan";
|
||
return {
|
||
enabled: true,
|
||
url: process.env.NEXT_PUBLIC_POCKETBASE_URL || process.env.POCKETBASE_URL || DEFAULT_POCKETBASE_URL,
|
||
usersCollection: "users",
|
||
joinCollection,
|
||
};
|
||
}
|
||
|
||
/** 获取支付配置(可传入主题覆盖,如 join 金额/类型) */
|
||
export function getPaymentConfig(themeOverride?: { amount?: number; type?: string }): PaymentConfig {
|
||
const base = {
|
||
enabled: true,
|
||
apiUrl: process.env.PAYMENT_API_URL || DEFAULT_PAYMENT_API_URL,
|
||
provider: (process.env.PAYMENT_PROVIDER as "zpay" | "xorpay") || "zpay",
|
||
defaultAmount: Number(process.env.PAYMENT_DEFAULT_AMOUNT) || 8800,
|
||
defaultType: process.env.PAYMENT_DEFAULT_TYPE || "meetup",
|
||
zpaySubmitUrl: process.env.ZPAY_SUBMIT_URL || "https://zpayz.cn/submit.php",
|
||
};
|
||
if (themeOverride) {
|
||
if (themeOverride.amount != null) base.defaultAmount = themeOverride.amount;
|
||
if (themeOverride.type) base.defaultType = themeOverride.type;
|
||
}
|
||
return base;
|
||
}
|
||
|
||
/** 获取 MinIO 配置(可传入主题覆盖 bucket/prefix) */
|
||
export function getMinioConfig(themeOverride?: { bucket?: string; uploadPrefix?: string }): MinioConfig {
|
||
const endPoint = process.env.MINIO_ENDPOINT || DEFAULT_MINIO_HOST;
|
||
const port = parseInt(process.env.MINIO_PORT || "9035", 10);
|
||
const useSSL = process.env.MINIO_USE_SSL === "true";
|
||
const bucket = themeOverride?.bucket || process.env.MINIO_BUCKET || "hackrobot";
|
||
const publicUrl =
|
||
process.env.MINIO_PUBLIC_URL ||
|
||
`https://${endPoint}/${bucket}`;
|
||
const uploadPrefix = themeOverride?.uploadPrefix || process.env.MINIO_UPLOAD_PREFIX || "joins";
|
||
|
||
return {
|
||
enabled: true,
|
||
endPoint,
|
||
port,
|
||
useSSL,
|
||
bucket,
|
||
accessKey: process.env.MINIO_ACCESS_KEY || "6i56HHfg4zPfYItCZtnp",
|
||
secretKey: process.env.MINIO_SECRET_KEY || "vDJCqEit3ejH5UmWKAZnvqhziNfbVsoOlBW12G8Q",
|
||
region: process.env.MINIO_REGION || "china",
|
||
publicUrl: publicUrl.replace(/\/$/, ""),
|
||
uploadPrefix,
|
||
};
|
||
}
|
||
|
||
/** 获取完整服务配置 */
|
||
export function getServicesConfig(): ServicesConfig {
|
||
return {
|
||
pocketbase: getPocketBaseConfig(),
|
||
payment: getPaymentConfig(),
|
||
minio: getMinioConfig(),
|
||
};
|
||
}
|
||
|
||
/** 获取「加入/申请」场景的支付配置(含主题覆盖) */
|
||
export function getJoinPaymentConfig(): { amount: number; type: string } {
|
||
const theme = getThemeConfig();
|
||
const payment = getPaymentConfig();
|
||
return {
|
||
amount: theme.services?.join?.amount ?? payment.defaultAmount,
|
||
type: theme.services?.join?.type ?? payment.defaultType,
|
||
};
|
||
}
|