create branch dev and commit code
This commit is contained in:
parent
3b70cc9fe8
commit
ea68fa5cc4
44 changed files with 12421 additions and 214 deletions
42
src/routes/api/adv-manifest/+server.ts
Normal file
42
src/routes/api/adv-manifest/+server.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { json, error } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { env } from '$env/dynamic/public';
|
||||
|
||||
// Method 2: forward a machine-generated sync_1.file to the adv FTP server.
|
||||
const ADV_API_BASE = env.PUBLIC_POST_IMAGE;
|
||||
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
try {
|
||||
const formData = await request.formData();
|
||||
|
||||
const country = formData.get('country') as string;
|
||||
const uid = formData.get('uid') as string;
|
||||
const displayName = formData.get('displayName') as string;
|
||||
const email = formData.get('email') as string;
|
||||
const file = formData.get('file') as File;
|
||||
|
||||
if (!country || !uid || !displayName || !email || !file) {
|
||||
throw error(400, 'Missing required fields');
|
||||
}
|
||||
|
||||
const endpoint = `${ADV_API_BASE}/adv/manifest/${encodeURIComponent(country)}/${encodeURIComponent(uid)}/${encodeURIComponent(displayName)}/${encodeURIComponent(email)}`;
|
||||
|
||||
const uploadFormData = new FormData();
|
||||
uploadFormData.append('file', file);
|
||||
|
||||
const response = await fetch(endpoint, { method: 'POST', body: uploadFormData });
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ detail: response.statusText }));
|
||||
throw error(response.status, errorData.detail || 'Manifest upload failed');
|
||||
}
|
||||
|
||||
return json(await response.json());
|
||||
} catch (err) {
|
||||
console.error('[Adv Manifest Proxy] Error:', err);
|
||||
if (err && typeof err === 'object' && 'status' in err) {
|
||||
throw err;
|
||||
}
|
||||
throw error(500, err instanceof Error ? err.message : 'Internal server error');
|
||||
}
|
||||
};
|
||||
55
src/routes/api/adv-upload/+server.ts
Normal file
55
src/routes/api/adv-upload/+server.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { json, error } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { env } from '$env/dynamic/public';
|
||||
|
||||
// Adv videos are served by the same taobin_image service as menu images.
|
||||
const ADV_API_BASE = env.PUBLIC_POST_IMAGE;
|
||||
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
try {
|
||||
const formData = await request.formData();
|
||||
|
||||
const country = formData.get('country') as string;
|
||||
const uid = formData.get('uid') as string;
|
||||
const displayName = formData.get('displayName') as string;
|
||||
const email = formData.get('email') as string;
|
||||
const file = formData.get('file') as File;
|
||||
// 'false' when the manifest is generated on a machine (method 2).
|
||||
const regenerate = (formData.get('regenerate') as string) ?? 'true';
|
||||
|
||||
if (!country || !uid || !displayName || !email || !file) {
|
||||
throw error(400, 'Missing required fields');
|
||||
}
|
||||
|
||||
const endpoint =
|
||||
`${ADV_API_BASE}/adv/upload/${encodeURIComponent(country)}/${encodeURIComponent(uid)}/${encodeURIComponent(displayName)}/${encodeURIComponent(email)}` +
|
||||
`?regenerate=${encodeURIComponent(regenerate)}`;
|
||||
|
||||
console.log('[Adv Upload Proxy] Endpoint:', endpoint, 'file:', file.name);
|
||||
|
||||
// Upstream expects the multipart field name `files`.
|
||||
const uploadFormData = new FormData();
|
||||
uploadFormData.append('files', file);
|
||||
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
body: uploadFormData
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ detail: response.statusText }));
|
||||
throw error(response.status, errorData.detail || 'Upload failed');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return json(result);
|
||||
} catch (err) {
|
||||
console.error('[Adv Upload Proxy] Error:', err);
|
||||
|
||||
if (err && typeof err === 'object' && 'status' in err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw error(500, err instanceof Error ? err.message : 'Internal server error');
|
||||
}
|
||||
};
|
||||
58
src/routes/api/image-upload/+server.ts
Normal file
58
src/routes/api/image-upload/+server.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { json, error } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { env } from '$env/dynamic/public';
|
||||
|
||||
const IMAGE_API_BASE = env.PUBLIC_POST_IMAGE;
|
||||
|
||||
export const POST: RequestHandler = async ({ request }) => {
|
||||
try {
|
||||
const formData = await request.formData();
|
||||
|
||||
const country = formData.get('country') as string;
|
||||
const folder = formData.get('folder') as string;
|
||||
const uid = formData.get('uid') as string;
|
||||
const displayName = formData.get('displayName') as string;
|
||||
const email = formData.get('email') as string;
|
||||
const file = formData.get('file') as File;
|
||||
|
||||
if (!folder || !uid || !displayName || !email || !file) {
|
||||
throw error(400, 'Missing required fields');
|
||||
}
|
||||
|
||||
|
||||
// Build the upload endpoint
|
||||
let endpoint: string;
|
||||
if (country) {
|
||||
endpoint = `${IMAGE_API_BASE}/inter/${encodeURIComponent(country)}/image/${encodeURIComponent(folder)}/upload/${encodeURIComponent(uid)}/${encodeURIComponent(displayName)}/${encodeURIComponent(email)}`;
|
||||
} else {
|
||||
endpoint = `${IMAGE_API_BASE}/image/${encodeURIComponent(folder)}/upload/${encodeURIComponent(uid)}/${encodeURIComponent(displayName)}/${encodeURIComponent(email)}`;
|
||||
}
|
||||
|
||||
console.log('[Image Upload Proxy] Endpoint:', endpoint);
|
||||
|
||||
// Create new FormData for the upstream request
|
||||
const uploadFormData = new FormData();
|
||||
uploadFormData.append('files', file);
|
||||
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
body: uploadFormData
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ detail: response.statusText }));
|
||||
throw error(response.status, errorData.detail || 'Upload failed');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return json(result);
|
||||
} catch (err) {
|
||||
console.error('[Image Upload Proxy] Error:', err);
|
||||
|
||||
if (err && typeof err === 'object' && 'status' in err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw error(500, err instanceof Error ? err.message : 'Internal server error');
|
||||
}
|
||||
};
|
||||
91
src/routes/api/sheet/stream/+server.ts
Normal file
91
src/routes/api/sheet/stream/+server.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
|
||||
// In-memory store for streamed catalog data
|
||||
// Format: { batchId: { chunks: [...], status: 'collecting'|'complete'|'error' } }
|
||||
const streamCache = new Map<string, any>();
|
||||
|
||||
export async function POST({ request }) {
|
||||
try {
|
||||
const data = await request.json();
|
||||
const { batch_id, msg, content, current_chunk, total_chunks } = data.payload;
|
||||
|
||||
// Initialize or update batch
|
||||
if (!streamCache.has(batch_id)) {
|
||||
streamCache.set(batch_id, {
|
||||
chunks: [],
|
||||
status: 'collecting',
|
||||
total_chunks,
|
||||
createdAt: Date.now()
|
||||
});
|
||||
}
|
||||
|
||||
const batch = streamCache.get(batch_id);
|
||||
|
||||
// Handle different message types
|
||||
if (msg === 'start') {
|
||||
console.log(`[API] Stream started for batch ${batch_id}`);
|
||||
} else if (msg === 'chunk') {
|
||||
batch.chunks.push(content);
|
||||
console.log(`[API] Received chunk ${current_chunk}/${total_chunks} for batch ${batch_id}`);
|
||||
} else if (msg === 'end') {
|
||||
batch.status = 'complete';
|
||||
console.log(`[API] Stream complete for batch ${batch_id}, total chunks: ${batch.chunks.length}`);
|
||||
} else if (msg === 'error') {
|
||||
batch.status = 'error';
|
||||
batch.error = content;
|
||||
console.log(`[API] Stream error for batch ${batch_id}:`, content);
|
||||
}
|
||||
|
||||
return json({ status: 'received', batch_id });
|
||||
} catch (error) {
|
||||
console.error('[API] Error processing stream:', error);
|
||||
return json({ status: 'error', message: String(error) }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export function GET({ url }) {
|
||||
const batchId = url.searchParams.get('batch_id');
|
||||
|
||||
// Clean up old cache entries (older than 5 minutes)
|
||||
const now = Date.now();
|
||||
for (const [key, value] of streamCache.entries()) {
|
||||
if (now - value.createdAt > 5 * 60 * 1000) {
|
||||
streamCache.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
// If batch_id specified, return that specific batch
|
||||
if (batchId) {
|
||||
const batch = streamCache.get(batchId);
|
||||
|
||||
if (!batch) {
|
||||
return json({ status: 'not_found' }, { status: 404 });
|
||||
}
|
||||
|
||||
return json({
|
||||
batch_id: batchId,
|
||||
status: batch.status,
|
||||
chunks: batch.chunks,
|
||||
total_chunks: batch.total_chunks,
|
||||
error: batch.error || null,
|
||||
createdAt: new Date(batch.createdAt).toISOString()
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise return list of all recent batches
|
||||
const batches = Array.from(streamCache.entries()).map(([batchId, batch]) => ({
|
||||
batch_id: batchId,
|
||||
status: batch.status,
|
||||
chunks_count: batch.chunks.length,
|
||||
total_chunks: batch.total_chunks,
|
||||
error: batch.error || null,
|
||||
createdAt: new Date(batch.createdAt).toISOString()
|
||||
}));
|
||||
|
||||
return json({
|
||||
status: 'success',
|
||||
batches: batches.sort(
|
||||
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
||||
)
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue