diff --git a/Reject.js b/Reject.js index e879083..c4345e7 100644 --- a/Reject.js +++ b/Reject.js @@ -1245,6 +1245,95 @@ app.post('/api/supplies/:id/unpublish', async (req, res) => { } }); +// 按规格下架API - /api/supplies/:id/unpublish-spec +console.log('正在注册按规格下架API路由: /api/supplies/:id/unpublish-spec'); +app.post('/api/supplies/:id/unpublish-spec', async (req, res) => { + console.log('收到按规格下架请求:', req.params.id, req.body); + try { + const connection = await pool.getConnection(); + const productId = req.params.id; + const { specIndex } = req.body; + + // 开始事务 + await connection.beginTransaction(); + + // 检查当前状态 + const [currentProduct] = await connection.query( + 'SELECT spec_status, status FROM products WHERE id = ?', + [productId] + ); + + if (currentProduct.length === 0) { + await connection.rollback(); + connection.release(); + return sendResponse(res, false, null, '货源不存在'); + } + + // 解析spec_status为数组 + let specStatuses = []; + if (currentProduct[0].spec_status) { + if (typeof currentProduct[0].spec_status === 'string') { + specStatuses = currentProduct[0].spec_status.split(',').map(s => s.trim()); + } else if (Array.isArray(currentProduct[0].spec_status)) { + specStatuses = currentProduct[0].spec_status; + } else { + specStatuses = [currentProduct[0].spec_status]; + } + } + + // 确保specIndex是数组 + let specIndices = specIndex; + if (!Array.isArray(specIndices)) { + specIndices = [specIndices]; + } + + // 将所有指定索引的规格状态改为1 + specIndices.forEach(index => { + if (index >= 0 && index < specStatuses.length) { + specStatuses[index] = '1'; + } + }); + + // 检查是否所有规格都已下架 + const allUnpublished = specStatuses.every(status => status === '1'); + + // 更新规格状态 + let updateQuery = 'UPDATE products SET spec_status = ?, updated_at = NOW() WHERE id = ?'; + let updateParams = [specStatuses.join(','), productId]; + + // 如果所有规格都已下架,更新货源状态和label + if (allUnpublished) { + updateQuery = 'UPDATE products SET spec_status = ?, status = ?, label = 1, updated_at = NOW() WHERE id = ?'; + updateParams = [specStatuses.join(','), 'sold_out', productId]; + } + + await connection.query(updateQuery, updateParams); + + // 查询更新后的完整货源数据 + const [updatedProduct] = await connection.query('SELECT * FROM products WHERE id = ?', [productId]); + + // 提交事务 + await connection.commit(); + connection.release(); + + // 发送WebSocket消息通知所有客户端 + broadcastMessage({ + type: 'supply_status_change', + supplyId: productId, + action: 'unpublish_spec', + specIndex: specIndex, + status: allUnpublished ? 'sold_out' : currentProduct[0].status + }); + + // 返回更新后的完整货源数据 + sendResponse(res, true, updatedProduct[0], '规格下架成功'); + } catch (error) { + console.error('按规格下架失败:', error.message); + console.error('错误详情:', error); + sendResponse(res, false, null, '按规格下架失败'); + } +}); + // 上架货源API - /api/supplies/:id/publish console.log('正在注册上架货源API路由: /api/supplies/:id/publish'); app.post('/api/supplies/:id/publish', async (req, res) => { diff --git a/supply.html b/supply.html index ac6f272..93effe7 100644 --- a/supply.html +++ b/supply.html @@ -4806,12 +4806,34 @@ costprices = [supply.costprice || '0']; } + // 解析规格状态数据 + let specStatuses = []; + try { + if (supply.spec_status) { + if (typeof supply.spec_status === 'string') { + // 规格状态存储为英文逗号分隔的字符串 + specStatuses = supply.spec_status.split(',').map(s => s.trim()); + } else if (Array.isArray(supply.spec_status)) { + specStatuses = supply.spec_status; + } else { + specStatuses = [supply.spec_status]; + } + } + } catch (e) { + specStatuses = []; + } + const maxLength = Math.max(specifications.length, quantities.length, costprices.length); for (let i = 0; i < maxLength; i++) { const spec = specifications[i] || '无'; const quantity = quantities[i] || '0'; const costprice = costprices[i] || '0'; - specQuantityBoxes += `
• 规格${i + 1}: ${spec} - 件数: ${quantity}件 - 采购价: ¥${costprice}
`; + const specStatus = specStatuses[i] || '0'; + + // 添加售空标识 + const soldOutTag = specStatus === '1' ? '已售空' : ''; + + specQuantityBoxes += `
• 规格${i + 1}: ${spec} - 件数: ${quantity}件 - 采购价: ¥${costprice}${soldOutTag}
`; } return ` @@ -6851,26 +6873,177 @@ }); } - // 下架货源 - async function unpublishSupply(id) { - // 防止重复点击 - if (isOperating) { + // 按规格下架弹窗 + const unpublishSpecModal = document.createElement('div'); + unpublishSpecModal.id = 'unpublishSpecModal'; + unpublishSpecModal.className = 'select-modal'; + unpublishSpecModal.innerHTML = ` +
+
+

选择要下架的规格

+ +
+
+
+
+ +
+ `; + document.body.appendChild(unpublishSpecModal); + + let currentUnpublishSupplyId = null; + let selectedSpecIndex = null; + + // 显示按规格下架弹窗 + function showUnpublishSpecModal(supplyId) { + currentUnpublishSupplyId = supplyId; + const supply = supplyData.supplies.find(s => String(s.id) === String(supplyId)); + if (!supply) { + alert('找不到要下架的货源数据'); + return; + } + + // 解析规格 + let specifications = []; + 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]; + } + } + + // 解析件数 + let quantities = []; + 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]; + } + } + + // 解析采购价 + let costprices = []; + 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]; + } + } + + // 解析规格状态 + let specStatuses = []; + if (supply.spec_status) { + if (typeof supply.spec_status === 'string') { + specStatuses = supply.spec_status.split(',').map(s => s.trim()); + } else if (Array.isArray(supply.spec_status)) { + specStatuses = supply.spec_status; + } else { + specStatuses = [supply.spec_status]; + } + } + + // 生成规格选项 + const optionsList = document.getElementById('unpublishSpecOptionsList'); + optionsList.innerHTML = ''; + + for (let i = 0; i < specifications.length; i++) { + const spec = specifications[i] || `规格${i+1}`; + const qty = quantities[i] || '0件'; + const cp = costprices[i] || '¥0'; + const status = specStatuses[i] || '0'; + + const option = document.createElement('div'); + option.className = 'select-item'; + option.innerHTML = ` +
+ +
+
${spec}
+
件数: ${qty} | 采购价: ${cp}
+
+ ${status === '1' ? '已售空' : ''} +
+ `; + + // 添加点击事件,点击整个项时切换checkbox状态 + option.addEventListener('click', (e) => { + // 如果点击的是checkbox本身,不处理 + if (e.target.type === 'checkbox') return; + + const checkbox = option.querySelector('input[type="checkbox"]'); + // 只有在checkbox未禁用时才切换状态 + if (!checkbox.disabled) { + checkbox.checked = !checkbox.checked; + } + }); + + optionsList.appendChild(option); + } + + // 默认勾选所有未禁用的规格 + const checkboxes = optionsList.querySelectorAll('input[type="checkbox"]:not(:disabled)'); + checkboxes.forEach(checkbox => { + checkbox.checked = true; + }); + + // 显示弹窗 + document.getElementById('unpublishSpecModal').classList.add('active'); + } + + // 隐藏按规格下架弹窗 + function hideUnpublishSpecModal() { + document.getElementById('unpublishSpecModal').classList.remove('active'); + currentUnpublishSupplyId = null; + selectedSpecIndex = null; + } + + // 确认按规格下架 + async function confirmUnpublishSpec() { + // 获取所有选中的规格索引 + const selectedCheckboxes = document.querySelectorAll('input[name="specIndex"]:checked'); + if (selectedCheckboxes.length === 0) { + alert('请选择要下架的规格'); + return; + } + + // 将选中的索引收集到数组中 + const selectedSpecIndices = Array.from(selectedCheckboxes).map(checkbox => parseInt(checkbox.value)); + + // 添加确认提示,防止误触 + const isConfirmed = confirm('确定要下架所选规格吗?'); + if (!isConfirmed) { return; } - if (confirm('确定要下架该货源吗?')) { + if (currentUnpublishSupplyId) { try { isOperating = true; // 获取要下架的货源的原始数据 - const originalSupply = supplyData.supplies.find(s => String(s.id) === String(id)); + const originalSupply = supplyData.supplies.find(s => String(s.id) === String(currentUnpublishSupplyId)); if (!originalSupply) { alert('找不到要下架的货源数据'); return; } - const response = await fetch(`/api/supplies/${id}/unpublish`, { - method: 'POST' + const response = await fetch(`/api/supplies/${currentUnpublishSupplyId}/unpublish-spec`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ specIndex: selectedSpecIndices }) }); const result = await response.json(); if (result.success) { @@ -6878,31 +7051,44 @@ const userInfo = checkLogin(); if (userInfo) { // 传入修改后的数据,包含状态变化 - await logSupplyOperation('下架', id, originalSupply, result.data); + await logSupplyOperation('下架规格', currentUnpublishSupplyId, originalSupply, result.data); } // 向WebSocket服务器发送消息,通知其他客户端货源已下架 sendWebSocketMessage({ type: 'supply_status_change', - supplyId: id, - action: 'unpublish', - status: 'sold_out' + supplyId: currentUnpublishSupplyId, + action: 'unpublish_spec', + specIndex: selectedSpecIndex, + status: result.data.status }); - alert('下架成功'); + alert('规格下架成功'); loadSupplies(); + hideUnpublishSpecModal(); } else { - alert('下架失败: ' + (result.message || '未知错误')); + alert('规格下架失败: ' + (result.message || '未知错误')); } } catch (error) { - console.error('下架失败:', error); - alert('下架失败: 网络错误'); + console.error('规格下架失败:', error); + alert('规格下架失败: 网络错误'); } finally { isOperating = false; } } } + // 下架货源 + async function unpublishSupply(id) { + // 防止重复点击 + if (isOperating) { + return; + } + + // 显示按规格下架弹窗 + showUnpublishSpecModal(id); + } + // 显示编辑货源 // 删除货源 async function deleteSupply(id) { @@ -8480,7 +8666,8 @@ window.onclick = function(event) { // 确保只处理click事件,不处理拖拽选择文本导致的mouseup事件 if (event.type === 'click') { - const modals = document.querySelectorAll('.modal'); + // 处理类名为modal的模态框 + const modals = document.querySelectorAll('.modal, .select-modal'); modals.forEach(modal => { if (event.target === modal) { // 只在真正点击模态框背景时关闭,不在选择文本拖拽到外部时关闭 @@ -8491,7 +8678,17 @@ const selection = window.getSelection(); if (selection && selection.toString()) return; - modal.style.display = 'none'; + // 对于普通modal,使用display: none隐藏 + if (modal.classList.contains('modal')) { + modal.style.display = 'none'; + } + // 对于select-modal,使用移除active类来隐藏 + else if (modal.classList.contains('select-modal')) { + modal.classList.remove('active'); + // 重置相关变量 + currentUnpublishSupplyId = null; + selectedSpecIndex = null; + } } }); }