|
|
|
@ -1261,7 +1261,7 @@ |
|
|
|
<div>3. 敲开鸡蛋后清晰显示蛋清、蛋黄状态,以体现新鲜度;</div> |
|
|
|
<div>4. 其他能佐证蛋重、品种的辅助图片。</div> |
|
|
|
</div> |
|
|
|
<div style="font-size: 12px; color: #999; margin-top: 10px; text-align: left;">最多上传2张图片</div> |
|
|
|
<div style="font-size: 12px; color: #999; margin-top: 10px; text-align: left;">最多上传2张图片或视频</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
@ -1408,6 +1408,7 @@ |
|
|
|
</div> |
|
|
|
<div class="modal-footer"> |
|
|
|
<button class="modal-btn modal-btn-cancel" onclick="hideAddSupplyModal()">取消</button> |
|
|
|
<button class="modal-btn" onclick="clearFormMemory()">清除</button> |
|
|
|
<button class="modal-btn modal-btn-primary" onclick="addSupply()">创建</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
@ -1671,12 +1672,12 @@ |
|
|
|
</div> |
|
|
|
<div class="add-image" onclick="triggerEditImageUpload()">+</div> |
|
|
|
|
|
|
|
<div style="font-size: 12px; color: #999; margin-top: 10px; text-align: left;">最多上传2张图片</div> |
|
|
|
<div style="font-size: 12px; color: #999; margin-top: 10px; text-align: left;">最多上传2张图片或视频</div> |
|
|
|
</div> |
|
|
|
<div style="font-size: 12px; color: #999; margin-top: 10px;">最多上传2张图片</div> |
|
|
|
<div style="font-size: 12px; color: #999; margin-top: 10px;">最多上传2张图片或视频</div> |
|
|
|
<input type="file" id="editImageUpload" multiple accept="image/*,video/mp4,video/mov,video/avi,video/wmv,video/flv" style="display: none;" onchange="handleEditImageUpload(event)"> |
|
|
|
<button type="button" onclick="triggerEditImageUpload()" style="margin-top: 10px; padding: 8px 16px; background-color: #f0f0f0; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer;"> |
|
|
|
添加图片 |
|
|
|
添加图片或视频 |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
|
|
|
|
@ -2539,11 +2540,12 @@ |
|
|
|
uploadArea.style.backgroundColor = '#fff'; |
|
|
|
|
|
|
|
const files = Array.from(e.dataTransfer.files); |
|
|
|
// 过滤出图片文件 |
|
|
|
// 过滤出图片和视频文件 |
|
|
|
const imageFiles = files.filter(file => file.type.startsWith('image/')); |
|
|
|
const videoFiles = files.filter(file => file.type.startsWith('video/')); |
|
|
|
|
|
|
|
if (imageFiles.length > 0) { |
|
|
|
handleDroppedImages(imageFiles); |
|
|
|
if (imageFiles.length > 0 || videoFiles.length > 0) { |
|
|
|
handleDroppedMedia(imageFiles, videoFiles); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
@ -2580,11 +2582,12 @@ |
|
|
|
editUploadArea.style.padding = '0'; |
|
|
|
|
|
|
|
const files = Array.from(e.dataTransfer.files); |
|
|
|
// 过滤出图片文件 |
|
|
|
// 过滤出图片和视频文件 |
|
|
|
const imageFiles = files.filter(file => file.type.startsWith('image/')); |
|
|
|
const videoFiles = files.filter(file => file.type.startsWith('video/')); |
|
|
|
|
|
|
|
if (imageFiles.length > 0) { |
|
|
|
handleEditDroppedImages(imageFiles); |
|
|
|
if (imageFiles.length > 0 || videoFiles.length > 0) { |
|
|
|
handleEditDroppedMedia(imageFiles, videoFiles); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -2597,9 +2600,10 @@ |
|
|
|
|
|
|
|
// 检查是否在创建或编辑货源模态框中(现在使用active类来控制显示) |
|
|
|
if (createSupplyModal && createSupplyModal.classList.contains('active')) { |
|
|
|
// 检查是否有粘贴的图片 |
|
|
|
// 检查是否有粘贴的图片和视频 |
|
|
|
const items = e.clipboardData.items; |
|
|
|
const imageFiles = []; |
|
|
|
const videoFiles = []; |
|
|
|
|
|
|
|
for (let i = 0; i < items.length; i++) { |
|
|
|
if (items[i].type.startsWith('image/')) { |
|
|
|
@ -2607,16 +2611,22 @@ |
|
|
|
if (file) { |
|
|
|
imageFiles.push(file); |
|
|
|
} |
|
|
|
} else if (items[i].type.startsWith('video/')) { |
|
|
|
const file = items[i].getAsFile(); |
|
|
|
if (file) { |
|
|
|
videoFiles.push(file); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (imageFiles.length > 0) { |
|
|
|
handleDroppedImages(imageFiles); |
|
|
|
if (imageFiles.length > 0 || videoFiles.length > 0) { |
|
|
|
handleDroppedMedia(imageFiles, videoFiles); |
|
|
|
} |
|
|
|
} else if (editSupplyModal && editSupplyModal.classList.contains('active')) { |
|
|
|
// 检查是否有粘贴的图片 |
|
|
|
// 检查是否有粘贴的图片和视频 |
|
|
|
const items = e.clipboardData.items; |
|
|
|
const imageFiles = []; |
|
|
|
const videoFiles = []; |
|
|
|
|
|
|
|
for (let i = 0; i < items.length; i++) { |
|
|
|
if (items[i].type.startsWith('image/')) { |
|
|
|
@ -2624,21 +2634,27 @@ |
|
|
|
if (file) { |
|
|
|
imageFiles.push(file); |
|
|
|
} |
|
|
|
} else if (items[i].type.startsWith('video/')) { |
|
|
|
const file = items[i].getAsFile(); |
|
|
|
if (file) { |
|
|
|
videoFiles.push(file); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (imageFiles.length > 0) { |
|
|
|
handleEditDroppedImages(imageFiles); |
|
|
|
if (imageFiles.length > 0 || videoFiles.length > 0) { |
|
|
|
handleEditDroppedMedia(imageFiles, videoFiles); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 处理拖拽或粘贴的图片 |
|
|
|
async function handleDroppedImages(imageFiles) { |
|
|
|
// 处理拖拽或粘贴的图片和视频 |
|
|
|
async function handleDroppedMedia(imageFiles, videoFiles) { |
|
|
|
// 处理图片 |
|
|
|
for (let i = 0; i < imageFiles.length; i++) { |
|
|
|
if (supplyData.uploadedImages.length >= 2) { |
|
|
|
alert('最多只能上传2张图片'); |
|
|
|
alert('最多只能上传2张图片/视频'); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
@ -2659,13 +2675,46 @@ |
|
|
|
|
|
|
|
reader.readAsDataURL(file); |
|
|
|
} |
|
|
|
|
|
|
|
// 处理视频 |
|
|
|
for (let i = 0; i < videoFiles.length; i++) { |
|
|
|
if (supplyData.uploadedImages.length >= 2) { |
|
|
|
alert('最多只能上传2张图片/视频'); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
const file = videoFiles[i]; |
|
|
|
const reader = new FileReader(); |
|
|
|
|
|
|
|
reader.onload = function(e) { |
|
|
|
try { |
|
|
|
const videoUrl = e.target.result; |
|
|
|
|
|
|
|
supplyData.uploadedImages.push(videoUrl); |
|
|
|
renderUploadedImages(); |
|
|
|
// 视频上传后自动保存表单数据 |
|
|
|
saveFormData(); |
|
|
|
} catch (error) { |
|
|
|
console.error('视频处理失败:', error); |
|
|
|
alert('视频处理失败,请重试'); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
reader.onerror = function(error) { |
|
|
|
console.error('视频读取失败:', error); |
|
|
|
alert('视频读取失败,请重试'); |
|
|
|
}; |
|
|
|
|
|
|
|
reader.readAsDataURL(file); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 处理编辑页面拖拽或粘贴的图片 |
|
|
|
async function handleEditDroppedImages(imageFiles) { |
|
|
|
// 处理编辑页面拖拽或粘贴的图片和视频 |
|
|
|
async function handleEditDroppedMedia(imageFiles, videoFiles) { |
|
|
|
// 处理图片 |
|
|
|
for (let i = 0; i < imageFiles.length; i++) { |
|
|
|
if (editCurrentImages.length >= 2) { |
|
|
|
alert('最多只能上传2张图片'); |
|
|
|
alert('最多只能上传2张图片/视频'); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
@ -2684,13 +2733,45 @@ |
|
|
|
// 更新显示 |
|
|
|
updateEditImageDisplay(); |
|
|
|
} catch (error) { |
|
|
|
console.error('图片处理失败:', error); |
|
|
|
alert('图片处理失败,请重试'); |
|
|
|
console.error('媒体处理失败:', error); |
|
|
|
alert('媒体处理失败,请重试'); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
reader.readAsDataURL(file); |
|
|
|
} |
|
|
|
|
|
|
|
// 处理视频 |
|
|
|
for (let i = 0; i < videoFiles.length; i++) { |
|
|
|
if (editCurrentImages.length >= 2) { |
|
|
|
alert('最多只能上传2张图片/视频'); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
const file = videoFiles[i]; |
|
|
|
const reader = new FileReader(); |
|
|
|
|
|
|
|
reader.onload = function(e) { |
|
|
|
try { |
|
|
|
const videoUrl = e.target.result; |
|
|
|
|
|
|
|
// 添加到当前编辑图片列表 |
|
|
|
editCurrentImages.push(videoUrl); |
|
|
|
// 更新显示 |
|
|
|
updateEditImageDisplay(); |
|
|
|
} catch (error) { |
|
|
|
console.error('视频处理失败:', error); |
|
|
|
alert('视频处理失败,请重试'); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
reader.onerror = function(error) { |
|
|
|
console.error('视频读取失败:', error); |
|
|
|
alert('视频读取失败,请重试'); |
|
|
|
}; |
|
|
|
|
|
|
|
reader.readAsDataURL(file); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 规格选择功能 |
|
|
|
@ -4423,25 +4504,31 @@ |
|
|
|
let mediaType = 'image'; // 默认为图片 |
|
|
|
let mediaPreviewHTML = ''; |
|
|
|
|
|
|
|
if (supply.imageUrls && supply.imageUrls.length > 0) { |
|
|
|
// 确保imageUrls是数组 |
|
|
|
const imageUrls = Array.isArray(supply.imageUrls) ? supply.imageUrls : |
|
|
|
(typeof supply.imageUrls === 'string' ? [supply.imageUrls] : |
|
|
|
(supply.imageUrls ? [supply.imageUrls] : [])); |
|
|
|
|
|
|
|
if (imageUrls.length > 0) { |
|
|
|
// 获取第一个媒体文件 |
|
|
|
firstMediaUrl = supply.imageUrls[0]; |
|
|
|
firstMediaUrl = imageUrls[0]; |
|
|
|
|
|
|
|
// 检测媒体类型 |
|
|
|
if (firstMediaUrl.startsWith('data:video/') || |
|
|
|
firstMediaUrl.match(/\.(mp4|mov|avi|wmv|flv|webm|mkv)$/i) || |
|
|
|
firstMediaUrl.includes('video') || |
|
|
|
(supply.imageUrls && supply.imageUrls.some(url => url.startsWith('data:video/') || url.match(/\.(mp4|mov|avi|wmv|flv|webm|mkv)$/i)))) { |
|
|
|
firstMediaUrl.match(/\.(mp4|mov|avi|wmv|flv|webm|mkv)$/i)) { |
|
|
|
mediaType = 'video'; |
|
|
|
mediaPreviewHTML = ` |
|
|
|
<div style="position: relative; width: 100px; height: 100px;"> |
|
|
|
<video |
|
|
|
src="${firstMediaUrl}" |
|
|
|
style="width: 100px; height: 100px; object-fit: cover; border-radius: 8px;" |
|
|
|
onclick="previewImage('${firstMediaUrl}', ${JSON.stringify(supply.imageUrls || []).replace(/"/g, '"')})" |
|
|
|
style="width: 100%; height: 100%; object-fit: cover; border-radius: 8px;" |
|
|
|
onclick="previewImage('${firstMediaUrl}', ${JSON.stringify(imageUrls || []).replace(/\"/g, '"')})" |
|
|
|
muted |
|
|
|
preload="metadata" |
|
|
|
playsinline |
|
|
|
></video> |
|
|
|
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 24px; pointer-events: none;">▶</div> |
|
|
|
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 24px; pointer-events: none; background-color: rgba(0, 0, 0, 0.5); border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;">▶</div> |
|
|
|
</div> |
|
|
|
`; |
|
|
|
} else { |
|
|
|
mediaType = 'image'; |
|
|
|
@ -4450,7 +4537,7 @@ |
|
|
|
src="${firstMediaUrl}" |
|
|
|
alt="${supply.productName}" |
|
|
|
style="width: 100px; height: 100px; object-fit: cover; border-radius: 8px;" |
|
|
|
onclick="previewImage('${firstMediaUrl}', ${JSON.stringify(supply.imageUrls || []).replace(/"/g, '"')})" |
|
|
|
onclick="previewImage('${firstMediaUrl}', ${JSON.stringify(imageUrls || []).replace(/\"/g, '"')})" |
|
|
|
> |
|
|
|
`; |
|
|
|
} |
|
|
|
@ -4787,9 +4874,85 @@ |
|
|
|
if (productingDisplay) productingDisplay.textContent = supply.producting || '请选择产品包装'; |
|
|
|
selectedProducting = supply.producting || ''; |
|
|
|
|
|
|
|
// 不复制图片,保持图片列表为空 |
|
|
|
supplyData.uploadedImages = []; |
|
|
|
// 种类 |
|
|
|
const categoryInput = document.getElementById('category'); |
|
|
|
if (categoryInput) categoryInput.value = supply.category || ''; |
|
|
|
|
|
|
|
const categoryDisplay = document.getElementById('categoryDisplayText'); |
|
|
|
if (categoryDisplay) categoryDisplay.textContent = supply.category || '请选择种类'; |
|
|
|
selectedCategory = supply.category || ''; |
|
|
|
|
|
|
|
// 新鲜程度 |
|
|
|
const freshnessInput = document.getElementById('freshness'); |
|
|
|
if (freshnessInput) freshnessInput.value = supply.freshness || ''; |
|
|
|
|
|
|
|
const freshnessDisplay = document.getElementById('freshnessDisplayText'); |
|
|
|
if (freshnessDisplay) freshnessDisplay.textContent = supply.freshness || '请选择新鲜程度'; |
|
|
|
selectedFreshness = supply.freshness || ''; |
|
|
|
|
|
|
|
// 复制图片 |
|
|
|
supplyData.uploadedImages = supply.images || supply.imageUrls || supply.imageList || []; |
|
|
|
renderUploadedImages(); |
|
|
|
|
|
|
|
// 规格和件数 - 支持中文逗号分隔和英文逗号分隔字符串 |
|
|
|
let specifications = []; |
|
|
|
let quantities = []; |
|
|
|
|
|
|
|
// 解析规格(中文逗号分隔字符串) |
|
|
|
try { |
|
|
|
if (supply.specification) { |
|
|
|
if (typeof supply.specification === 'string') { |
|
|
|
specifications = supply.specification.split(',').filter(spec => spec.trim()); |
|
|
|
} else if (Array.isArray(supply.specification)) { |
|
|
|
specifications = supply.specification; |
|
|
|
} else { |
|
|
|
specifications = [supply.specification]; |
|
|
|
} |
|
|
|
} else if (supply.spec) { |
|
|
|
specifications = [supply.spec]; |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
specifications = [supply.specification || supply.spec || '']; |
|
|
|
} |
|
|
|
|
|
|
|
// 解析件数(英文逗号分隔字符串) |
|
|
|
try { |
|
|
|
if (supply.quantity) { |
|
|
|
if (typeof supply.quantity === 'string') { |
|
|
|
quantities = supply.quantity.split(',').filter(qty => qty.trim()); |
|
|
|
} else if (Array.isArray(supply.quantity)) { |
|
|
|
quantities = supply.quantity; |
|
|
|
} else { |
|
|
|
quantities = [supply.quantity]; |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
quantities = [supply.quantity || '']; |
|
|
|
} |
|
|
|
|
|
|
|
// 动态生成规格-件数对输入框 |
|
|
|
const specQuantityPairs = document.getElementById('specQuantityPairs'); |
|
|
|
if (specQuantityPairs) { |
|
|
|
// 清空现有对 |
|
|
|
specQuantityPairs.innerHTML = ''; |
|
|
|
|
|
|
|
// 如果没有规格-件数对,添加一个空的 |
|
|
|
if (specifications.length === 0) { |
|
|
|
addSpecQuantityPair(); |
|
|
|
} else { |
|
|
|
// 根据规格数量生成相应的规格-件数对 |
|
|
|
for (let i = 0; i < specifications.length; i++) { |
|
|
|
const pair = document.createElement('div'); |
|
|
|
pair.className = 'spec-quantity-pair'; |
|
|
|
pair.innerHTML = ` |
|
|
|
<input type="text" class="spec-value" placeholder="请选择规格" readonly onclick="showSpecSelectModalForPair(this)" value="${specifications[i] || ''}"> |
|
|
|
<input type="number" class="form-input quantity-input" placeholder="请输入件数" onwheel="this.blur()" value="${quantities[i] || ''}"> |
|
|
|
<button type="button" class="remove-quantity-btn" onclick="removeSpecQuantityPair(this)">×</button> |
|
|
|
`; |
|
|
|
specQuantityPairs.appendChild(pair); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 检查是否为重复货源 |
|
|
|
@ -5001,6 +5164,22 @@ |
|
|
|
inStockBtn.style.borderColor = '#d9d9d9'; |
|
|
|
inStockBtn.style.color = '#666'; |
|
|
|
} |
|
|
|
|
|
|
|
// 重置新鲜程度字段 |
|
|
|
const freshness = document.getElementById('freshness'); |
|
|
|
if (freshness) freshness.value = ''; |
|
|
|
|
|
|
|
const freshnessDisplayText = document.getElementById('freshnessDisplayText'); |
|
|
|
if (freshnessDisplayText) { |
|
|
|
freshnessDisplayText.textContent = '请选择新鲜程度'; |
|
|
|
} |
|
|
|
selectedFreshness = ''; |
|
|
|
|
|
|
|
// 重置自动下架时间选择框 |
|
|
|
const autoOfflineMinutes = document.getElementById('autoOfflineMinutes'); |
|
|
|
if (autoOfflineMinutes) { |
|
|
|
autoOfflineMinutes.value = '1440'; // 默认24小时 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 显示创建货源模态框 |
|
|
|
@ -5171,7 +5350,7 @@ |
|
|
|
|
|
|
|
for (let i = 0; i < files.length; i++) { |
|
|
|
if (editCurrentImages.length >= 2) { |
|
|
|
alert('最多只能上传2张图片'); |
|
|
|
alert('最多只能上传2张图片或视频'); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
@ -5226,7 +5405,7 @@ |
|
|
|
mediaElement.className = 'upload-image'; |
|
|
|
|
|
|
|
let mediaContent; |
|
|
|
if (imageUrl.startsWith('data:video/')) { |
|
|
|
if (imageUrl.startsWith('data:video/') || imageUrl.match(/\.(mp4|mov|avi|wmv|flv|webm|mkv)$/i)) { |
|
|
|
// 视频文件 |
|
|
|
mediaContent = ` |
|
|
|
<video src="${imageUrl}" alt="商品视频" onclick="previewImage('${imageUrl}')" controls style="width: 100%; height: 100%; object-fit: cover;"></video> |
|
|
|
@ -5249,7 +5428,7 @@ |
|
|
|
function addWatermarkToImage(imageUrl) { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
// 如果是视频文件,直接返回,不添加水印 |
|
|
|
if (imageUrl.startsWith('data:video/')) { |
|
|
|
if (imageUrl.startsWith('data:video/') || imageUrl.match(/\.(mp4|mov|avi|wmv|flv|webm|mkv)$/i)) { |
|
|
|
resolve(imageUrl); |
|
|
|
return; |
|
|
|
} |
|
|
|
@ -5305,7 +5484,7 @@ |
|
|
|
|
|
|
|
for (let i = 0; i < files.length; i++) { |
|
|
|
if (supplyData.uploadedImages.length >= 2) { |
|
|
|
alert('最多只能上传2张图片'); |
|
|
|
alert('最多只能上传2张图片/视频'); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
@ -5450,6 +5629,7 @@ |
|
|
|
const regionValue = document.getElementById('regionValue'); |
|
|
|
const contactId = document.getElementById('contactId'); |
|
|
|
const category = document.getElementById('category'); |
|
|
|
const freshness = document.getElementById('freshness'); |
|
|
|
const specDisplayText = document.getElementById('specDisplayText'); |
|
|
|
const regionDisplayText = document.getElementById('regionDisplayText'); |
|
|
|
const sourceTypeDisplayText = document.getElementById('sourceTypeDisplayText'); |
|
|
|
@ -5457,11 +5637,13 @@ |
|
|
|
const yolkDisplayText = document.getElementById('yolkDisplayText'); |
|
|
|
const contactIdDisplayText = document.getElementById('contactIdDisplayText'); |
|
|
|
const categoryDisplayText = document.getElementById('categoryDisplayText'); |
|
|
|
const freshnessDisplayText = document.getElementById('freshnessDisplayText'); |
|
|
|
|
|
|
|
// 确保所有字段都是安全获取的 |
|
|
|
const formData = { |
|
|
|
productName: productName ? productName.value : '', |
|
|
|
category: category ? category.value : '', |
|
|
|
freshness: freshness ? freshness.value : '', |
|
|
|
price: price ? price.value : '', |
|
|
|
quantity: quantity ? quantity.value : '', |
|
|
|
grossWeight: grossWeight ? grossWeight.value : '', |
|
|
|
@ -5480,6 +5662,7 @@ |
|
|
|
yolkDisplay: yolkDisplayText ? yolkDisplayText.textContent : '请选择蛋黄类型', |
|
|
|
contactIdDisplay: contactIdDisplayText ? contactIdDisplayText.textContent : '请选择联系人', |
|
|
|
categoryDisplay: categoryDisplayText ? categoryDisplayText.textContent : '请选择种类', |
|
|
|
freshnessDisplay: freshnessDisplayText ? freshnessDisplayText.textContent : '请选择新鲜程度', |
|
|
|
// 深拷贝图片数组,避免引用问题 |
|
|
|
imageUrls: Array.isArray(supplyData.uploadedImages) ? [...supplyData.uploadedImages] : [], |
|
|
|
// 保存自定义选择状态 |
|
|
|
@ -5491,6 +5674,7 @@ |
|
|
|
selectedYolk: selectedYolk || '', |
|
|
|
selectedContactId: selectedContactId || '', |
|
|
|
selectedCategory: selectedCategory || '', |
|
|
|
selectedFreshness: selectedFreshness || '', |
|
|
|
// 添加时间戳,用于调试和潜在的过期处理 |
|
|
|
lastSaved: new Date().toISOString() |
|
|
|
}; |
|
|
|
@ -5504,6 +5688,80 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 清除表单记忆数据 |
|
|
|
function clearFormMemory() { |
|
|
|
try { |
|
|
|
// 1. 从localStorage中移除保存的表单数据 |
|
|
|
localStorage.removeItem('supplyFormDraft'); |
|
|
|
|
|
|
|
// 2. 清空上传的图片/视频 |
|
|
|
supplyData.uploadedImages = []; |
|
|
|
renderUploadedImages(); |
|
|
|
|
|
|
|
// 3. 重置表单字段 |
|
|
|
const productName = document.getElementById('productName'); |
|
|
|
const price = document.getElementById('price'); |
|
|
|
const quantity = document.getElementById('quantity'); |
|
|
|
const grossWeight = document.getElementById('grossWeight'); |
|
|
|
const yolk = document.getElementById('yolk'); |
|
|
|
const specValue = document.getElementById('specValue'); |
|
|
|
const supplyStatus = document.getElementById('supplyStatus'); |
|
|
|
const sourceType = document.getElementById('sourceType'); |
|
|
|
const description = document.getElementById('description'); |
|
|
|
const regionValue = document.getElementById('regionValue'); |
|
|
|
const contactId = document.getElementById('contactId'); |
|
|
|
const category = document.getElementById('category'); |
|
|
|
|
|
|
|
// 重置输入框 |
|
|
|
[productName, price, quantity, grossWeight, yolk, specValue, supplyStatus, sourceType, description, regionValue, contactId, category].forEach(field => { |
|
|
|
if (field) { |
|
|
|
field.value = ''; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 4. 重置下拉框显示文本 |
|
|
|
const specDisplayText = document.getElementById('specDisplayText'); |
|
|
|
const regionDisplayText = document.getElementById('regionDisplayText'); |
|
|
|
const sourceTypeDisplayText = document.getElementById('sourceTypeDisplayText'); |
|
|
|
const productNameDisplayText = document.getElementById('productNameDisplayText'); |
|
|
|
const yolkDisplayText = document.getElementById('yolkDisplayText'); |
|
|
|
const contactIdDisplayText = document.getElementById('contactIdDisplayText'); |
|
|
|
const categoryDisplayText = document.getElementById('categoryDisplayText'); |
|
|
|
|
|
|
|
const displayFields = [ |
|
|
|
{ field: specDisplayText, text: '请选择规格' }, |
|
|
|
{ field: regionDisplayText, text: '请选择地区' }, |
|
|
|
{ field: sourceTypeDisplayText, text: '请选择货源类型' }, |
|
|
|
{ field: productNameDisplayText, text: '请选择商品名称' }, |
|
|
|
{ field: yolkDisplayText, text: '请选择蛋黄类型' }, |
|
|
|
{ field: contactIdDisplayText, text: '请选择联系人' }, |
|
|
|
{ field: categoryDisplayText, text: '请选择种类' } |
|
|
|
]; |
|
|
|
|
|
|
|
displayFields.forEach(item => { |
|
|
|
if (item.field) { |
|
|
|
item.field.textContent = item.text; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 5. 重置选择状态变量 |
|
|
|
selectedSpec = ''; |
|
|
|
selectedProvince = ''; |
|
|
|
selectedCity = ''; |
|
|
|
selectedSourceType = ''; |
|
|
|
selectedProductName = ''; |
|
|
|
selectedYolk = ''; |
|
|
|
selectedContactId = ''; |
|
|
|
selectedCategory = ''; |
|
|
|
|
|
|
|
console.log('表单记忆数据已清除'); |
|
|
|
alert('表单记忆已清除'); |
|
|
|
} catch (e) { |
|
|
|
console.error('清除表单记忆失败:', e); |
|
|
|
alert('清除表单记忆失败,请重试'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 加载表单数据 |
|
|
|
function loadFormData() { |
|
|
|
try { |
|
|
|
@ -5622,6 +5880,17 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 恢复新鲜程度 |
|
|
|
if (formData.freshness) { |
|
|
|
const freshnessElement = document.getElementById('freshness'); |
|
|
|
const freshnessDisplayElement = document.getElementById('freshnessDisplayText'); |
|
|
|
if (freshnessElement && freshnessDisplayElement) { |
|
|
|
freshnessElement.value = formData.freshness; |
|
|
|
freshnessDisplayElement.textContent = formData.freshnessDisplay || '请选择新鲜程度'; |
|
|
|
selectedFreshness = formData.selectedFreshness || ''; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 恢复图片 |
|
|
|
if (Array.isArray(formData.imageUrls)) { |
|
|
|
supplyData.uploadedImages = formData.imageUrls; |
|
|
|
@ -5669,11 +5938,12 @@ |
|
|
|
|
|
|
|
// 获取自动下架分钟数 |
|
|
|
const autoOfflineMinutes = document.getElementById('autoOfflineMinutes').value; |
|
|
|
// 将分钟转换为小时(用于存储到数据库) |
|
|
|
const autoOfflineHours = parseFloat(autoOfflineMinutes) / 60; |
|
|
|
// 将分钟转换为小时(用于存储到数据库),确保有默认值 |
|
|
|
const minutes = parseFloat(autoOfflineMinutes) || 1440; // 默认24小时(1440分钟) |
|
|
|
const autoOfflineHours = minutes / 60; |
|
|
|
// 计算自动下架时间(当前时间 + 分钟数) |
|
|
|
const autoOfflineTime = new Date(); |
|
|
|
autoOfflineTime.setMinutes(autoOfflineTime.getMinutes() + parseFloat(autoOfflineMinutes)); |
|
|
|
autoOfflineTime.setMinutes(autoOfflineTime.getMinutes() + minutes); |
|
|
|
|
|
|
|
const formData = { |
|
|
|
productName: document.getElementById('productName').value, |
|
|
|
@ -5712,12 +5982,16 @@ |
|
|
|
alert('请输入价格'); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (specifications.length === 0) { |
|
|
|
alert('请选择规格'); |
|
|
|
return; |
|
|
|
// 验证规格和件数 - 确保至少有一个有效的规格-件数对 |
|
|
|
let hasValidPair = false; |
|
|
|
for (let i = 0; i < specifications.length; i++) { |
|
|
|
if (specifications[i].trim() !== '' && quantities[i].trim() !== '') { |
|
|
|
hasValidPair = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (quantities.length === 0) { |
|
|
|
alert('请输入件数'); |
|
|
|
if (!hasValidPair) { |
|
|
|
alert('请至少添加一个有效的规格和件数对'); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!formData.supplyStatus) { |
|
|
|
@ -6187,7 +6461,7 @@ |
|
|
|
// 显示编辑货源 |
|
|
|
// 删除货源 |
|
|
|
async function deleteSupply(id) { |
|
|
|
if (confirm('确定要删除该货源吗?删除后将无法恢复。')) { |
|
|
|
if (confirm('确定要删除该货源吗?')) { |
|
|
|
try { |
|
|
|
const response = await fetch(`/api/supplies/${id}/delete`, { |
|
|
|
method: 'POST' |
|
|
|
@ -6404,20 +6678,38 @@ |
|
|
|
// 显示商品图片 |
|
|
|
const editUploadImages = document.getElementById('editUploadImages'); |
|
|
|
editUploadImages.innerHTML = ''; |
|
|
|
if (supply.imageUrls && Array.isArray(supply.imageUrls)) { |
|
|
|
supply.imageUrls.forEach((imageUrl, index) => { |
|
|
|
// 确保imageUrls是数组 |
|
|
|
const editImageUrls = Array.isArray(supply.imageUrls) ? supply.imageUrls : |
|
|
|
(typeof supply.imageUrls === 'string' ? [supply.imageUrls] : |
|
|
|
(supply.imageUrls ? [supply.imageUrls] : [])); |
|
|
|
|
|
|
|
if (editImageUrls.length > 0) { |
|
|
|
editImageUrls.forEach((mediaUrl, index) => { |
|
|
|
const imageElement = document.createElement('div'); |
|
|
|
imageElement.className = 'upload-image'; |
|
|
|
imageElement.innerHTML = ` |
|
|
|
<img src="${imageUrl}" alt="商品图片" onclick="previewImage('${imageUrl}')"> |
|
|
|
<button class="delete-image-btn" onclick="deleteEditImage('${imageUrl}')">×</button> |
|
|
|
|
|
|
|
let mediaContent; |
|
|
|
if (mediaUrl.startsWith('data:video/') || mediaUrl.match(/\.(mp4|mov|avi|wmv|flv|webm|mkv)$/i)) { |
|
|
|
// 视频文件 |
|
|
|
mediaContent = ` |
|
|
|
<video src="${mediaUrl}" alt="商品视频" onclick="previewImage('${mediaUrl}')" controls style="width: 100%; height: 100%; object-fit: cover;"></video> |
|
|
|
<button class="delete-image-btn" onclick="deleteEditImage('${mediaUrl}')">×</button> |
|
|
|
`; |
|
|
|
} else { |
|
|
|
// 图片文件 |
|
|
|
mediaContent = ` |
|
|
|
<img src="${mediaUrl}" alt="商品图片" onclick="previewImage('${mediaUrl}')"> |
|
|
|
<button class="delete-image-btn" onclick="deleteEditImage('${mediaUrl}')">×</button> |
|
|
|
`; |
|
|
|
} |
|
|
|
|
|
|
|
imageElement.innerHTML = mediaContent; |
|
|
|
editUploadImages.appendChild(imageElement); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 保存当前图片列表到全局变量,用于编辑时使用 |
|
|
|
editCurrentImages = supply.imageUrls && Array.isArray(supply.imageUrls) ? [...supply.imageUrls] : []; |
|
|
|
editCurrentImages = [...editImageUrls]; |
|
|
|
|
|
|
|
// 根据模式修改保存按钮文本和状态 |
|
|
|
const saveButton = document.querySelector('#editSupplyModal .modal-btn-primary'); |
|
|
|
@ -7487,15 +7779,13 @@ |
|
|
|
|
|
|
|
// 获取自动下架分钟数 |
|
|
|
const autoOfflineMinutes = document.getElementById('editAutoOfflineMinutes')?.value; |
|
|
|
// 将分钟转换为小时(用于存储到数据库) |
|
|
|
const autoOfflineHours = parseFloat(autoOfflineMinutes) / 60; |
|
|
|
// 将分钟转换为小时(用于存储到数据库),确保有默认值 |
|
|
|
const minutes = parseFloat(autoOfflineMinutes) || 1440; // 默认24小时(1440分钟) |
|
|
|
const autoOfflineHours = minutes / 60; |
|
|
|
// 计算自动下架时间(当前时间 + 分钟数) |
|
|
|
let autoOfflineTime = null; |
|
|
|
if (autoOfflineMinutes) { |
|
|
|
autoOfflineTime = new Date(); |
|
|
|
autoOfflineTime.setMinutes(autoOfflineTime.getMinutes() + parseFloat(autoOfflineMinutes)); |
|
|
|
autoOfflineTime = autoOfflineTime.toISOString(); |
|
|
|
} |
|
|
|
const autoOfflineTime = new Date(); |
|
|
|
autoOfflineTime.setMinutes(autoOfflineTime.getMinutes() + minutes); |
|
|
|
const autoOfflineTimeISO = autoOfflineTime.toISOString(); |
|
|
|
|
|
|
|
const formData = { |
|
|
|
productName: document.getElementById('editProductName').value, |
|
|
|
@ -7515,7 +7805,7 @@ |
|
|
|
contactId: document.getElementById('editContactId').value, |
|
|
|
freshness: document.getElementById('editFreshness').value, |
|
|
|
imageUrls: editCurrentImages, // 添加编辑后的图片列表 |
|
|
|
autoOfflineTime: autoOfflineTime, // 自动下架时间 |
|
|
|
autoOfflineTime: autoOfflineTimeISO, // 自动下架时间 |
|
|
|
autoOfflineDays: null, // 不再使用天数,设置为null |
|
|
|
autoOfflineHours: autoOfflineHours // 自动下架小时数(分钟转换而来) |
|
|
|
}; |
|
|
|
@ -7533,12 +7823,16 @@ |
|
|
|
alert('请输入价格'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
if (specifications.length === 0) { |
|
|
|
alert('请选择规格'); |
|
|
|
return false; |
|
|
|
// 验证规格和件数 - 确保至少有一个有效的规格-件数对 |
|
|
|
let hasValidPair = false; |
|
|
|
for (let i = 0; i < specifications.length; i++) { |
|
|
|
if (specifications[i].trim() !== '' && quantities[i].trim() !== '') { |
|
|
|
hasValidPair = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (quantities.length === 0) { |
|
|
|
alert('请输入件数'); |
|
|
|
if (!hasValidPair) { |
|
|
|
alert('请至少添加一个有效的规格和件数对'); |
|
|
|
return false; |
|
|
|
} |
|
|
|
if (!formData.supplyStatus) { |
|
|
|
|