diff --git a/supply.html b/supply.html index 983e66d..fbb0bd5 100644 --- a/supply.html +++ b/supply.html @@ -1025,6 +1025,10 @@ flex: 1; } + .costprice-input { + flex: 1; + } + .remove-quantity-btn { width: 32px; height: 32px; @@ -1168,7 +1172,7 @@
@@ -1342,7 +1346,7 @@
- +
@@ -1371,9 +1375,9 @@ -
+ @@ -1758,7 +1762,7 @@
- +
@@ -1787,9 +1791,9 @@ -
+ @@ -2010,10 +2014,9 @@
- +
-
+
货源类型: ${supply.sourceType || '无'}
+
品种: ${supply.category || '无'}
蛋黄: ${supply.yolk || '无'}
+
包装: ${supply.producting || '无'}
+
新鲜程度: ${supply.freshness || '无'}
货源状态: ${supply.supplyStatus || '未设置'}
货源描述: ${supply.description || '无'}
-
斤重: ${supply.grossWeight || ''}斤
地区: ${supply.region || '未设置'}
-
价格: ¥${supply.costprice || '0'}
+
创建时间: ${formatDate(supply.created_at)}
- ${supply.autoOfflineHours && supply.autoOfflineHours !== '' && supply.autoOfflineHours !== null ? `
剩余下架时间: 计算中...
` : ''} + ${supply.status === 'published' ? `
上架时间: ${formatDate(getPublishTime(supply))}
` : ''}
@@ -4678,9 +4697,82 @@ function formatDate(dateString) { if (!dateString) return '未知'; const date = new Date(dateString); + // 检查是否为有效的日期 + if (isNaN(date.getTime())) { + return '未知'; + } return `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; } + // 判断是否为第一次上架 + function isFirstPublish(supply) { + // 如果没有修改时间,使用创建时间 + if (!supply.updated_at) { + return true; + } + + // 如果没有创建时间,直接使用修改时间 + if (!supply.created_at) { + return false; + } + + // 将创建时间和修改时间转换为时间戳 + try { + const createdAt = new Date(supply.created_at).getTime(); + const updatedAt = new Date(supply.updated_at).getTime(); + + // 计算时间差(毫秒) + const diffMs = updatedAt - createdAt; + + // 如果时间差小于60秒(1分钟),认为是第一次上架 + // 因为创建货源时,系统可能会自动更新修改时间 + return diffMs < 60 * 1000; + } catch (error) { + console.error('时间转换失败:', error); + // 如果转换失败,默认使用创建时间 + return true; + } + } + + // 获取上架时间 + function getPublishTime(supply) { + try { + // 检查是否为第一次上架 + if (isFirstPublish(supply)) { + // 第一次上架,使用创建时间 + if (supply.created_at) { + return supply.created_at; + } + } else { + // 重新上架,使用修改时间 + if (supply.updated_at) { + return supply.updated_at; + } + } + + // 如果以上条件都不满足,尝试使用可用的时间 + if (supply.created_at) { + return supply.created_at; + } + if (supply.updated_at) { + return supply.updated_at; + } + if (supply.onlineTime) { + return supply.onlineTime; + } + if (supply.publishTime) { + return supply.publishTime; + } + + // 所有时间字段都不可用,返回null + return null; + } catch (error) { + console.error('获取上架时间失败:', error); + // 发生错误时,返回创建时间或null + return supply.created_at || null; + } + } + // 复制货源信息 function copySupply(supplyId) { try { @@ -4908,9 +5000,10 @@ supplyData.uploadedImages = supply.images || supply.imageUrls || supply.imageList || []; renderUploadedImages(); - // 规格和件数 - 支持中文逗号分隔和英文逗号分隔字符串 - let specifications = []; - let quantities = []; + // 规格、件数和采购价 - 支持中文逗号分隔和英文逗号分隔字符串 + let specifications = []; + let quantities = []; + let costprices = []; // 解析规格(中文逗号分隔字符串) try { @@ -4961,6 +5054,7 @@ pair.innerHTML = ` + `; specQuantityPairs.appendChild(pair); @@ -5937,15 +6031,18 @@ const pairs = document.querySelectorAll('#specQuantityContainer .spec-quantity-pair'); const specifications = []; const quantities = []; + const costprices = []; pairs.forEach(pair => { const specValue = pair.querySelector('.spec-value').value.trim(); const quantityValue = pair.querySelector('.quantity-input').value.trim(); + const costpriceValue = pair.querySelector('.costprice-input').value.trim(); if (specValue) { specifications.push(specValue); // 件数可以为0,所以只检查是否有值(包括"0") quantities.push(quantityValue); + costprices.push(costpriceValue); } }); @@ -5971,7 +6068,7 @@ category: document.getElementById('category').value, price: document.getElementById('price').value, - costprice: document.getElementById('costprice').value, // 添加采购价 + costprice: costprices.join(','), // 将采购价以英文逗号分隔的字符串形式提交 quantity: quantities.join(','), // 将件数以英文逗号分隔的字符串形式提交 grossWeight: document.getElementById('grossWeight').value, yolk: document.getElementById('yolk').value, @@ -6578,11 +6675,6 @@ document.getElementById('editProductingValue').value = supply.producting || ''; editSelectedProducting = supply.producting || ''; - // 产品包装 - document.getElementById('editProductingDisplayText').textContent = supply.producting || '请选择产品包装'; - document.getElementById('editProductingValue').value = supply.producting || ''; - editSelectedProducting = supply.producting || ''; - // 货源状态(使用按钮组) const supplyStatus = supply.supplyStatus || '预售'; document.getElementById('editSupplyStatus').value = supplyStatus; @@ -6622,9 +6714,10 @@ document.getElementById('editAutoOfflineMinutes').value = Math.round(autoOfflineMinutes); - // 规格和件数 - 支持中文逗号分隔和英文逗号分隔字符串 + // 规格、件数和采购价 - 支持中文逗号分隔和英文逗号分隔字符串 let specifications = []; let quantities = []; + let costprices = []; // 解析规格(支持中英文逗号分隔字符串) try { @@ -6661,6 +6754,21 @@ quantities = [supply.quantity || '0']; } + // 解析采购价(英文逗号分隔字符串) + try { + if (supply.costprice) { + if (typeof supply.costprice === 'string') { + costprices = supply.costprice.split(',').filter(cp => cp.trim()); + } else if (Array.isArray(supply.costprice)) { + costprices = supply.costprice; + } else { + costprices = [supply.costprice]; + } + } + } catch (e) { + costprices = [supply.costprice || '0']; + } + // 动态生成规格-件数对输入框 const specQuantityPairs = document.getElementById('editSpecQuantityPairs'); // 清空现有对 @@ -6671,7 +6779,7 @@ addEditSpecQuantityPair(); } else { // 根据规格数量生成相应的规格-件数对 - for (let i = 0; i < Math.max(specifications.length, quantities.length); i++) { + for (let i = 0; i < Math.max(specifications.length, quantities.length, costprices.length); i++) { // 确保即使数量不匹配,也能正确显示对应的数据 const spec = specifications[i] || ''; const qty = quantities[i] || ''; @@ -6681,6 +6789,7 @@ pair.innerHTML = ` + `; specQuantityPairs.appendChild(pair); @@ -6809,13 +6918,11 @@ // 编辑后上架货源 async function publishSupplyAfterEdit() { try { - // 先保存编辑的货源信息 - const saveResult = await saveEditSupply(); - if (saveResult) { - // 保存成功后,上架货源 - await publishSupply(currentEditSupplyId); - // 关闭模态框 - hideEditSupplyModal(); + // 直接调用saveEditSupply,它会处理保存和上架逻辑 + const result = await saveEditSupply(); + if (!result) { + // 编辑失败,saveEditSupply函数已经显示了错误信息 + return; } } catch (error) { console.error('上架失败:', error); @@ -7021,6 +7128,7 @@ pair.innerHTML = ` + `; container.appendChild(pair); @@ -7039,8 +7147,10 @@ // 否则,只清除输入值 const specInput = pair.querySelector('.spec-value'); const quantityInput = pair.querySelector('.quantity-input'); + const costpriceInput = pair.querySelector('.costprice-input'); if (specInput) specInput.value = ''; if (quantityInput) quantityInput.value = ''; + if (costpriceInput) costpriceInput.value = ''; } } @@ -7092,6 +7202,9 @@ // 添加当前选项的选中状态 option.classList.add('selected'); editSelectedProducting = producting; + // 自动更新隐藏字段的值 + document.getElementById('editProductingDisplayText').textContent = producting; + document.getElementById('editProductingValue').value = producting; }; option.ondblclick = () => { // 双击直接确认选择 @@ -7162,6 +7275,9 @@ // 添加当前选项的选中状态 option.classList.add('selected'); editSelectedFreshness = freshness; + // 自动更新隐藏字段的值 + document.getElementById('editFreshnessDisplayText').textContent = freshness; + document.getElementById('editFreshness').value = freshness; }; option.ondblclick = () => { // 双击直接确认选择 @@ -7204,7 +7320,6 @@ // 重置选择 editSelectedProvince = ''; editSelectedCity = ''; - editSelectedDistrict = ''; // 更新显示 updateEditRegionDisplay(); // 生成地区选项 @@ -7221,7 +7336,7 @@ function generateEditRegionOptions() { const provinceList = document.getElementById('editProvinceList'); const cityList = document.getElementById('editCityList'); - const districtList = document.getElementById('editDistrictList'); + // 生成省份选项 provinceList.innerHTML = ''; @@ -7235,12 +7350,13 @@ option.onclick = () => { editSelectedProvince = province.province; editSelectedCity = ''; - editSelectedDistrict = ''; updateEditRegionDisplay(); // 生成城市选项 generateEditCityOptions(province.cities); - // 清空区县选项 - districtList.innerHTML = ''; + // 直接滚动城市列表到顶部 + setTimeout(() => { + cityList.scrollTop = 0; + }, 100); }; provinceList.appendChild(option); }); @@ -7261,10 +7377,7 @@ } option.onclick = () => { editSelectedCity = city.city; - editSelectedDistrict = ''; updateEditRegionDisplay(); - // 生成区县选项 - generateEditDistrictOptions(city.districts); }; cityList.appendChild(option); }); @@ -7294,9 +7407,7 @@ function updateEditRegionDisplay() { const currentRegion = document.getElementById('editCurrentRegion'); let displayText = '当前选择: '; - if (editSelectedProvince && editSelectedCity && editSelectedDistrict) { - displayText += `${editSelectedProvince} ${editSelectedCity} ${editSelectedDistrict}`; - } else if (editSelectedProvince && editSelectedCity) { + if (editSelectedProvince && editSelectedCity) { displayText += `${editSelectedProvince} ${editSelectedCity}`; } else if (editSelectedProvince) { displayText += editSelectedProvince; @@ -7314,7 +7425,6 @@ // 重置选择 editSelectedProvince = ''; editSelectedCity = ''; - editSelectedDistrict = ''; // 先尝试直接查找区县 let foundDistrict = false; @@ -7390,10 +7500,10 @@ // 确认编辑地区选择 function confirmEditRegionSelection() { - if (editSelectedProvince && editSelectedCity && editSelectedDistrict) { + if (editSelectedProvince && editSelectedCity) { const regionDisplayText = document.getElementById('editRegionDisplayText'); const regionValue = document.getElementById('editRegionValue'); - const regionText = `${editSelectedProvince} ${editSelectedCity} ${editSelectedDistrict}`; + const regionText = `${editSelectedProvince} ${editSelectedCity}`; regionDisplayText.textContent = regionText; regionValue.value = regionText; } @@ -7434,6 +7544,9 @@ }); option.classList.add('selected'); editSelectedSourceType = sourceType; + // 自动更新隐藏字段的值 + document.getElementById('editSourceTypeDisplayText').textContent = sourceType; + document.getElementById('editSourceType').value = sourceType; }; option.ondblclick = () => { editSelectedSourceType = sourceType; @@ -7498,6 +7611,9 @@ }); option.classList.add('selected'); editSelectedCategory = category; + // 自动更新隐藏字段的值 + document.getElementById('editCategoryDisplayText').textContent = category; + document.getElementById('editCategory').value = category; }; option.ondblclick = () => { editSelectedCategory = category; @@ -7562,6 +7678,9 @@ }); option.classList.add('selected'); editSelectedProductName = productName; + // 自动更新隐藏字段的值 + document.getElementById('editProductNameDisplayText').textContent = productName; + document.getElementById('editProductName').value = productName; }; option.ondblclick = () => { editSelectedProductName = productName; @@ -7626,6 +7745,9 @@ }); option.classList.add('selected'); editSelectedYolk = yolk; + // 自动更新隐藏字段的值 + document.getElementById('editYolkDisplayText').textContent = yolk; + document.getElementById('editYolk').value = yolk; }; option.ondblclick = () => { editSelectedYolk = yolk; @@ -7774,19 +7896,22 @@ try { // 获取规格和件数数据 - const pairs = document.querySelectorAll('#editSpecQuantityPairs .spec-quantity-pair'); - const specifications = []; - const quantities = []; + const pairs = document.querySelectorAll('#editSpecQuantityPairs .spec-quantity-pair'); + const specifications = []; + const quantities = []; + const costprices = []; + + pairs.forEach(pair => { + const specValue = pair.querySelector('.spec-value').value.trim(); + const quantityValue = pair.querySelector('.quantity-input').value.trim(); + const costpriceValue = pair.querySelector('.costprice-input').value.trim(); - pairs.forEach(pair => { - const specValue = pair.querySelector('.spec-value').value.trim(); - const quantityValue = pair.querySelector('.quantity-input').value.trim(); - - // 保存所有添加的规格和件数对,即使其中一个为空 - // 这样可以保持记忆功能,下次编辑时还能看到之前添加的对 - specifications.push(specValue); - quantities.push(quantityValue); - }); + // 保存所有添加的规格和件数对,即使其中一个为空 + // 这样可以保持记忆功能,下次编辑时还能看到之前添加的对 + specifications.push(specValue); + quantities.push(quantityValue); + costprices.push(costpriceValue); + }); // 获取自动下架分钟数 @@ -7811,7 +7936,7 @@ category: document.getElementById('editCategory').value, price: document.getElementById('editPrice').value, - costprice: document.getElementById('editCostprice').value, // 添加采购价 + costprice: costprices.join(','), // 将采购价以英文逗号分隔的字符串形式提交 quantity: quantities.join(','), // 将件数以英文逗号分隔的字符串形式提交 grossWeight: document.getElementById('editGrossWeight').value, yolk: document.getElementById('editYolk').value, @@ -7841,16 +7966,16 @@ alert('请输入采购价'); return false; } - // 验证规格和件数 - 确保至少有一个有效的规格-件数对 + // 验证规格、件数和采购价 - 确保至少有一个有效的规格-件数-采购价对 let hasValidPair = false; for (let i = 0; i < specifications.length; i++) { - if (specifications[i].trim() !== '' && quantities[i].trim() !== '') { + if (specifications[i].trim() !== '' && quantities[i].trim() !== '' && costprices[i].trim() !== '') { hasValidPair = true; break; } } if (!hasValidPair) { - alert('请至少添加一个有效的规格和件数对'); + alert('请至少添加一个有效的规格、件数和采购价对'); return false; } if (!formData.supplyStatus) { @@ -7901,8 +8026,11 @@ loadSupplies(); } else { alert('上架失败: ' + (publishResult.message || '未知错误')); + return false; } } + // 返回成功状态,无论是什么模式 + return true; } else { alert('编辑失败: ' + (result.message || '未知错误')); return false; @@ -7935,7 +8063,31 @@ } }); } - } + }; + + // 页面卸载时清理WebSocket资源 + window.onbeforeunload = function() { + // 关闭WebSocket连接 + if (ws) { + try { + ws.close(1000, '页面卸载'); + ws = null; + } catch (error) { + console.error('关闭WebSocket连接失败:', error); + ws = null; + } + } + + // 清理定时器 + if (timers && Object.keys(timers).length > 0) { + Object.values(timers).forEach(timer => { + if (timer) { + clearInterval(timer); + clearTimeout(timer); + } + }); + } + }; \ No newline at end of file