Save worktree changes
This commit is contained in:
+31
-27
@@ -1,6 +1,7 @@
|
||||
const { parseJsonSafe, readFormArray } = require('./utils');
|
||||
|
||||
const ALLOWED_TEMPLATE_REGION_TYPES = ['text', 'image', 'webpage', 'html'];
|
||||
const ALLOWED_TEMPLATE_REGION_TYPES = ['text', 'image', 'webpage', 'html', 'rtmp', 'rss', 'api'];
|
||||
const FONT_FAMILY_REGION_TYPES = ['text', 'html', 'rss', 'api'];
|
||||
|
||||
function sanitizeBackgroundColor(value) {
|
||||
const raw = String(value || '').trim();
|
||||
@@ -15,6 +16,14 @@ function normalizeTemplateRegionType(value) {
|
||||
return ALLOWED_TEMPLATE_REGION_TYPES.includes(rawType) ? rawType : 'text';
|
||||
}
|
||||
|
||||
function normalizeTemplateRegionLockRatio(value) {
|
||||
const rawRatio = String(value || '').trim();
|
||||
if (!/^\d+\s*:\s*\d+$/.test(rawRatio)) {
|
||||
return null;
|
||||
}
|
||||
return rawRatio.replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
function normalizeTemplateRegionName(value) {
|
||||
return String(value || '').trim();
|
||||
}
|
||||
@@ -49,7 +58,7 @@ async function fetchTemplateById(pool, id) {
|
||||
return null;
|
||||
}
|
||||
const template = templates[0];
|
||||
const [regions] = await pool.query('SELECT id, template_id, region_key, region_type, label, font_family, x, y, width, height, z_index, created_at, modified_at, created_by, modified_by FROM slide_template_regions WHERE template_id = ? ORDER BY z_index ASC, id ASC', [id]);
|
||||
const [regions] = await pool.query('SELECT id, template_id, region_key, region_type, label, font_family, lock_ratio, x, y, width, height, z_index, created_at, modified_at, created_by, modified_by FROM slide_template_regions WHERE template_id = ? ORDER BY z_index ASC, id ASC', [id]);
|
||||
template.regions = regions;
|
||||
return template;
|
||||
}
|
||||
@@ -62,7 +71,7 @@ async function fetchTemplatesData(pool) {
|
||||
LEFT JOIN canvas_sizes cs ON cs.id = st.canvas_size_id
|
||||
ORDER BY st.id DESC
|
||||
`);
|
||||
const [templateRegions] = await pool.query('SELECT id, template_id, region_key, region_type, label, font_family, x, y, width, height, z_index, created_at, modified_at, created_by, modified_by FROM slide_template_regions ORDER BY template_id ASC, z_index ASC, id ASC');
|
||||
const [templateRegions] = await pool.query('SELECT id, template_id, region_key, region_type, label, font_family, lock_ratio, x, y, width, height, z_index, created_at, modified_at, created_by, modified_by FROM slide_template_regions ORDER BY template_id ASC, z_index ASC, id ASC');
|
||||
return { templates, templateRegions };
|
||||
}
|
||||
|
||||
@@ -71,17 +80,21 @@ function extractTemplateRegions(body) {
|
||||
if (regionsJson) {
|
||||
const parsed = parseJsonSafe(regionsJson);
|
||||
if (Array.isArray(parsed)) {
|
||||
return parsed.map((region) => ({
|
||||
region_key: String(region.region_name || region.region_key || region.label || '').trim(),
|
||||
region_type: normalizeTemplateRegionType(region.region_type),
|
||||
label: String(region.region_name || region.label || region.region_key || '').trim(),
|
||||
font_family: ['text', 'html'].includes(normalizeTemplateRegionType(region.region_type)) ? String(region.font_family || '').trim() || null : null,
|
||||
x: Number(region.x || 0),
|
||||
y: Number(region.y || 0),
|
||||
width: Number(region.width || 100),
|
||||
height: Number(region.height || 100),
|
||||
z_index: Number(region.z_index || 0)
|
||||
})).filter((region) => region.region_key && region.label);
|
||||
return parsed.map((region) => {
|
||||
const regionType = normalizeTemplateRegionType(region.region_type);
|
||||
return {
|
||||
region_key: String(region.region_name || region.region_key || region.label || '').trim(),
|
||||
region_type: regionType,
|
||||
label: String(region.region_name || region.label || region.region_key || '').trim(),
|
||||
font_family: FONT_FAMILY_REGION_TYPES.includes(regionType) ? String(region.font_family || '').trim() || null : null,
|
||||
lock_ratio: normalizeTemplateRegionLockRatio(region.lock_ratio),
|
||||
x: Number(region.x || 0),
|
||||
y: Number(region.y || 0),
|
||||
width: Number(region.width || 100),
|
||||
height: Number(region.height || 100),
|
||||
z_index: Number(region.z_index || 0)
|
||||
};
|
||||
}).filter((region) => region.region_key && region.label);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +102,7 @@ function extractTemplateRegions(body) {
|
||||
const names = readFormArray(body, 'region_name[]');
|
||||
const labels = readFormArray(body, 'region_label[]');
|
||||
const types = readFormArray(body, 'region_type[]');
|
||||
const ratios = readFormArray(body, 'region_lock_ratio[]');
|
||||
const xs = readFormArray(body, 'region_x[]');
|
||||
const ys = readFormArray(body, 'region_y[]');
|
||||
const widths = readFormArray(body, 'region_width[]');
|
||||
@@ -108,7 +122,8 @@ function extractTemplateRegions(body) {
|
||||
region_key: name,
|
||||
region_type: regionType,
|
||||
label: name,
|
||||
font_family: ['text', 'html'].includes(regionType) ? String(fonts[i] || 'Arial').trim() || 'Arial' : null,
|
||||
font_family: FONT_FAMILY_REGION_TYPES.includes(regionType) ? String(fonts[i] || 'Arial').trim() || 'Arial' : null,
|
||||
lock_ratio: normalizeTemplateRegionLockRatio(ratios[i]),
|
||||
x: Number(xs[i] || 0),
|
||||
y: Number(ys[i] || 0),
|
||||
width: Number(widths[i] || 100),
|
||||
@@ -139,7 +154,7 @@ async function buildTemplatePayload(pool, req, existingTemplate) {
|
||||
const removeBackgroundImage = Boolean(req.body.remove_background_image);
|
||||
const backgroundColor = sanitizeBackgroundColor(req.body.background_color || (existingTemplate && existingTemplate.background_color));
|
||||
const backgroundImagePath = backgroundImage
|
||||
? `/uploads/${backgroundImage.filename}`
|
||||
? `/media/${backgroundImage.filename}`
|
||||
: removeBackgroundImage
|
||||
? null
|
||||
: String(req.body.existing_background_image_path || (existingTemplate && existingTemplate.background_image_path) || '').trim() || null;
|
||||
@@ -171,17 +186,6 @@ async function buildTemplatePayload(pool, req, existingTemplate) {
|
||||
error.statusCode = 400;
|
||||
throw error;
|
||||
}
|
||||
regions = [{
|
||||
region_key: 'region_1',
|
||||
region_type: 'text',
|
||||
label: 'Region 1',
|
||||
font_family: 'Arial',
|
||||
x: 120,
|
||||
y: 120,
|
||||
width: Math.max(200, Math.round(canvasWidth * 0.22)),
|
||||
height: Math.max(120, Math.round(canvasHeight * 0.15)),
|
||||
z_index: 1
|
||||
}];
|
||||
}
|
||||
|
||||
ensureUniqueTemplateRegionNames(regions);
|
||||
|
||||
Reference in New Issue
Block a user