Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9ea9d4862 | ||
|
|
e170d5451e |
BIN
0e10fd7fa68c9dda45b221f98145dd7a.jpg
Normal file
BIN
0e10fd7fa68c9dda45b221f98145dd7a.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
Reference in New Issue
Block a user