feat: slot-based adv upload with server video preview
This commit is contained in:
parent
5b1c3a169a
commit
60d0e40b76
3 changed files with 736 additions and 724 deletions
File diff suppressed because it is too large
Load diff
47
src/routes/api/adv-file/+server.ts
Normal file
47
src/routes/api/adv-file/+server.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { logger } from '$lib/core/utils/logger';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { verifyAuthToken } from '$lib/server/auth';
|
||||
|
||||
// Adv videos are served by the same taobin_image service as menu images.
|
||||
const ADV_API_BASE = env.PUBLIC_POST_IMAGE;
|
||||
|
||||
// Stream a single adv .mp4 back to the browser. The frontend fetches this with a
|
||||
// Bearer token and turns the response into a Blob/object URL for a <video> tag
|
||||
// (adv videos live only on the FTP server, so they can't be linked directly).
|
||||
export const GET: RequestHandler = async ({ request, url }) => {
|
||||
try {
|
||||
await verifyAuthToken(request);
|
||||
|
||||
const country = url.searchParams.get('country');
|
||||
const filename = url.searchParams.get('filename');
|
||||
if (!country || !filename) {
|
||||
throw error(400, 'Missing country or filename');
|
||||
}
|
||||
|
||||
// POST (not GET): the kong gateway only routes POST to the taobin-image service.
|
||||
const endpoint = `${ADV_API_BASE}/adv/file/${encodeURIComponent(country)}/${encodeURIComponent(filename)}`;
|
||||
const response = await fetch(endpoint, { method: 'POST' });
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ detail: response.statusText }));
|
||||
throw error(response.status, errorData.detail || 'Failed to fetch adv video');
|
||||
}
|
||||
|
||||
return new Response(response.body, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': response.headers.get('Content-Type') || 'video/mp4',
|
||||
'Content-Length': response.headers.get('Content-Length') || '',
|
||||
'Cache-Control': 'no-store'
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error('[Adv File Proxy] Error:', err);
|
||||
if (err && typeof err === 'object' && 'status' in err) {
|
||||
throw err;
|
||||
}
|
||||
throw error(500, err instanceof Error ? err.message : 'Internal server error');
|
||||
}
|
||||
};
|
||||
36
src/routes/api/adv-list/+server.ts
Normal file
36
src/routes/api/adv-list/+server.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { logger } from '$lib/core/utils/logger';
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { verifyAuthToken } from '$lib/server/auth';
|
||||
|
||||
// Adv videos are served by the same taobin_image service as menu images.
|
||||
const ADV_API_BASE = env.PUBLIC_POST_IMAGE;
|
||||
|
||||
// List the adv .mp4 files currently on a country's FTP folder (for preview).
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
try {
|
||||
await verifyAuthToken(request);
|
||||
|
||||
const { country } = await request.json();
|
||||
if (!country || typeof country !== 'string') {
|
||||
throw error(400, 'Missing country');
|
||||
}
|
||||
|
||||
const endpoint = `${ADV_API_BASE}/adv/list/${encodeURIComponent(country)}`;
|
||||
const response = await fetch(endpoint, { method: 'POST' });
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ detail: response.statusText }));
|
||||
throw error(response.status, errorData.detail || 'Failed to list adv videos');
|
||||
}
|
||||
|
||||
return json(await response.json());
|
||||
} catch (err) {
|
||||
logger.error('[Adv List Proxy] Error:', err);
|
||||
if (err && typeof err === 'object' && 'status' in err) {
|
||||
throw err;
|
||||
}
|
||||
throw error(500, err instanceof Error ? err.message : 'Internal server error');
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue