2 Commits

Author SHA1 Message Date
erio
a9ea9d4862 feat: 帮助图片点击放大(lightbox)
点击支付页右侧帮助区域的联系二维码图片,在屏幕正中以全屏遮罩放大展示;
点击背景或再次点击可关闭。
2026-03-02 03:39:49 +08:00
erio
e170d5451e fix: 帮助内容改为服务端变量经 API 下发,运行时可配无需重新构建 2026-03-02 02:46:51 +08:00
5 changed files with 30 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@@ -12,4 +12,7 @@ services:
ports:
- '${APP_PORT:-3001}:3000'
env_file: .env
volumes:
# 宿主机 uploads 目录挂载到 Next.js public/uploads可通过 /uploads/* 访问
- ./uploads:/app/public/uploads:ro
restart: unless-stopped

View File

@@ -27,6 +27,8 @@ export async function GET(request: NextRequest) {
maxAmount: env.MAX_RECHARGE_AMOUNT,
maxDailyAmount: env.MAX_DAILY_RECHARGE_AMOUNT,
methodLimits,
helpImageUrl: env.PAY_HELP_IMAGE_URL ?? null,
helpText: env.PAY_HELP_TEXT ?? null,
},
});
} catch (error) {

View File

@@ -27,6 +27,8 @@ interface AppConfig {
maxAmount: number;
maxDailyAmount: number;
methodLimits?: Record<string, MethodLimitInfo>;
helpImageUrl?: string | null;
helpText?: string | null;
}
function PayContent() {
@@ -60,12 +62,13 @@ function PayContent() {
maxDailyAmount: 0,
});
const [userNotFound, setUserNotFound] = useState(false);
const [helpImageOpen, setHelpImageOpen] = useState(false);
const effectiveUserId = resolvedUserId || userId;
const isEmbedded = uiMode === 'embedded' && isIframeContext;
const hasToken = token.length > 0;
const helpImageUrl = (process.env.NEXT_PUBLIC_PAY_HELP_IMAGE_URL || '').trim();
const helpText = (process.env.NEXT_PUBLIC_PAY_HELP_TEXT || '').trim();
const helpImageUrl = (config.helpImageUrl || '').trim();
const helpText = (config.helpText || '').trim();
const hasHelpContent = Boolean(helpImageUrl || helpText);
useEffect(() => {
@@ -100,6 +103,8 @@ function PayContent() {
maxAmount: cfgData.config.maxAmount ?? 1000,
maxDailyAmount: cfgData.config.maxDailyAmount ?? 0,
methodLimits: cfgData.config.methodLimits,
helpImageUrl: cfgData.config.helpImageUrl ?? null,
helpText: cfgData.config.helpText ?? null,
});
}
} else if (cfgRes.status === 404) {
@@ -428,7 +433,8 @@ function PayContent() {
<img
src={helpImageUrl}
alt='help'
className='mt-3 max-h-40 w-full rounded-lg object-contain bg-white/70 p-2'
onClick={() => setHelpImageOpen(true)}
className='mt-3 max-h-40 w-full cursor-zoom-in rounded-lg object-contain bg-white/70 p-2'
/>
)}
{helpText && (
@@ -463,6 +469,20 @@ function PayContent() {
{step === 'result' && (
<OrderStatus status={finalStatus} onBack={handleBack} dark={isDark} />
)}
{helpImageOpen && helpImageUrl && (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/75 p-4 backdrop-blur-sm"
onClick={() => setHelpImageOpen(false)}
>
<img
src={helpImageUrl}
alt='help'
className='max-h-[90vh] max-w-full rounded-xl object-contain shadow-2xl'
onClick={(e) => e.stopPropagation()}
/>
</div>
)}
</PayPageLayout>
);
}

View File

@@ -56,8 +56,8 @@ const envSchema = z.object({
ADMIN_TOKEN: z.string().min(1),
NEXT_PUBLIC_APP_URL: z.string().url(),
NEXT_PUBLIC_PAY_HELP_IMAGE_URL: optionalTrimmedString,
NEXT_PUBLIC_PAY_HELP_TEXT: optionalTrimmedString,
PAY_HELP_IMAGE_URL: optionalTrimmedString,
PAY_HELP_TEXT: optionalTrimmedString,
});
export type Env = z.infer<typeof envSchema>;