Fix image matching to use Toast item ID from filename, not alt text
This commit is contained in:
parent
4471ddc92b
commit
04f65e3495
1 changed files with 54 additions and 32 deletions
|
|
@ -1449,8 +1449,12 @@
|
|||
// Remove loading message and start conversation flow
|
||||
document.getElementById('conversation').innerHTML = '';
|
||||
|
||||
// In add-menu mode, skip business info and header
|
||||
if (config.businessId && config.menuId) {
|
||||
// Check if any items have imageUrl - if so, offer image upload matching
|
||||
const itemsWithImages = (config.extractedData.items || []).filter(item => item.imageUrl).length;
|
||||
if (itemsWithImages > 0) {
|
||||
showImageMatchingStep();
|
||||
} else if (config.businessId && config.menuId) {
|
||||
// In add-menu mode, skip business info and header
|
||||
showCategoriesStep();
|
||||
} else {
|
||||
showBusinessInfoStep();
|
||||
|
|
@ -1489,12 +1493,12 @@
|
|||
// Show step to upload images from saved webpage subfolder and match to items
|
||||
function showImageMatchingStep() {
|
||||
const itemCount = config.extractedData.items ? config.extractedData.items.length : 0;
|
||||
const mappingCount = config.imageMappings.length;
|
||||
const itemsWithImages = (config.extractedData.items || []).filter(item => item.imageUrl).length;
|
||||
|
||||
addMessage('ai', `
|
||||
<p>I found <strong>${itemCount} menu items</strong> and detected <strong>${mappingCount} image references</strong> in the HTML.</p>
|
||||
<p>To add images to your menu items, upload the images from the saved webpage folder (usually named something like <code>pagename_files</code>).</p>
|
||||
<p style="font-size:13px;color:var(--gray-500);">I'll automatically match images to items based on filenames.</p>
|
||||
<p>I found <strong>${itemCount} menu items</strong> with <strong>${itemsWithImages} image references</strong>.</p>
|
||||
<p>Upload the images from your saved webpage folder to add them to menu items.</p>
|
||||
<p style="font-size:13px;color:var(--gray-500);">I'll match by Toast item ID in the filename.</p>
|
||||
<div style="margin-top:16px;">
|
||||
<input type="file" id="matchImagesInput" accept="image/*" multiple style="display:none;" onchange="handleImageMatching(event)">
|
||||
<button class="btn btn-primary" onclick="document.getElementById('matchImagesInput').click()">
|
||||
|
|
@ -1517,38 +1521,56 @@
|
|||
|
||||
let matchedCount = 0;
|
||||
const matchResults = [];
|
||||
const items = config.extractedData.items || [];
|
||||
|
||||
// Extract Toast-style item ID from filename (e.g., "item-600000000167924464_1636677556.jpg")
|
||||
function extractToastId(str) {
|
||||
// Match the long numeric ID pattern from Toast filenames
|
||||
const match = str.match(/item-(\d{15,})/i);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
// Skip duplicate sizes (_002, _003, _004 suffixes)
|
||||
function isBaseSizeImage(filename) {
|
||||
return !/_00[234]\.[^.]+$/i.test(filename);
|
||||
}
|
||||
|
||||
Array.from(files).forEach(file => {
|
||||
const filename = file.name.toLowerCase();
|
||||
const filename = file.name;
|
||||
|
||||
// Try to find a matching mapping
|
||||
for (const mapping of config.imageMappings) {
|
||||
const mappingFilename = mapping.filename.toLowerCase();
|
||||
// Skip smaller size variants - only use base image
|
||||
if (!isBaseSizeImage(filename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for exact filename match or close match
|
||||
if (filename === mappingFilename ||
|
||||
filename.includes(mappingFilename.replace(/\.[^.]+$/, '')) ||
|
||||
mappingFilename.includes(filename.replace(/\.[^.]+$/, ''))) {
|
||||
// Extract Toast item ID from uploaded filename
|
||||
const uploadedToastId = extractToastId(filename);
|
||||
|
||||
// Find matching item by alt text or name
|
||||
const altText = (mapping.alt || '').toLowerCase();
|
||||
const matchedItem = config.extractedData.items.find(item => {
|
||||
const itemName = (item.name || '').toLowerCase();
|
||||
const itemAlt = (item.imageAlt || '').toLowerCase();
|
||||
return itemName === altText ||
|
||||
itemAlt === altText ||
|
||||
itemName.includes(altText) ||
|
||||
altText.includes(itemName) ||
|
||||
(itemAlt && (itemAlt.includes(altText) || altText.includes(itemAlt)));
|
||||
});
|
||||
// Try to match to an item
|
||||
let matchedItem = null;
|
||||
|
||||
if (matchedItem) {
|
||||
config.itemImages[matchedItem.id] = file;
|
||||
matchedCount++;
|
||||
matchResults.push({ item: matchedItem.name, file: file.name });
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uploadedToastId) {
|
||||
// Match by Toast ID in imageUrl
|
||||
matchedItem = items.find(item => {
|
||||
if (!item.imageUrl) return false;
|
||||
const itemToastId = extractToastId(item.imageUrl);
|
||||
return itemToastId === uploadedToastId;
|
||||
});
|
||||
}
|
||||
|
||||
// Fallback: match by filename contained in imageUrl
|
||||
if (!matchedItem) {
|
||||
const filenameBase = filename.replace(/\.[^.]+$/, '').toLowerCase();
|
||||
matchedItem = items.find(item => {
|
||||
if (!item.imageUrl) return false;
|
||||
return item.imageUrl.toLowerCase().includes(filenameBase);
|
||||
});
|
||||
}
|
||||
|
||||
if (matchedItem && !config.itemImages[matchedItem.id]) {
|
||||
config.itemImages[matchedItem.id] = file;
|
||||
matchedCount++;
|
||||
matchResults.push({ item: matchedItem.name, file: file.name });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
Reference in a new issue