diff --git a/Reject.html b/Reject.html index 78d4fa8..c5a1715 100644 --- a/Reject.html +++ b/Reject.html @@ -1054,7 +1054,7 @@ "> - + @@ -1073,15 +1073,6 @@ - - -
{ - console.log(`第${index + 1}条记录的图片相关字段:`); - console.log('- imageUrls:', item.imageUrls); - console.log('- images:', item.images); - console.log('- imgUrls:', item.imgUrls); - console.log('- picUrls:', item.picUrls); - console.log('- imageUrl:', item.imageUrl); - console.log('- image:', item.image); - console.log('- imgUrl:', item.imgUrl); - console.log('- picUrl:', item.picUrl); - }); - } else if (data && data.supplies && Array.isArray(data.supplies)) { - console.log('响应数据包含supplies数组,共', data.supplies.length, '条记录'); - data.supplies.slice(0, 3).forEach((item, index) => { - console.log(`第${index + 1}条记录的图片相关字段:`); - console.log('- imageUrls:', item.imageUrls); - console.log('- images:', item.images); - console.log('- imgUrls:', item.imgUrls); - console.log('- picUrls:', item.picUrls); - console.log('- imageUrl:', item.imageUrl); - console.log('- image:', item.image); - console.log('- imgUrl:', item.imgUrl); - console.log('- picUrl:', item.picUrl); - }); - } else if (data && data.data && Array.isArray(data.data)) { - console.log('响应数据包含data数组,共', data.data.length, '条记录'); - data.data.slice(0, 3).forEach((item, index) => { - console.log(`第${index + 1}条记录的图片相关字段:`); - console.log('- imageUrls:', item.imageUrls); - console.log('- images:', item.images); - console.log('- imgUrls:', item.imgUrls); - console.log('- picUrls:', item.picUrls); - console.log('- imageUrl:', item.imageUrl); - console.log('- image:', item.image); - console.log('- imgUrl:', item.imgUrl); - console.log('- picUrl:', item.picUrl); - }); - } else if (Array.isArray(data)) { - console.log('响应数据是数组,共', data.length, '条记录'); - data.slice(0, 3).forEach((item, index) => { - console.log(`第${index + 1}条记录的图片相关字段:`); - console.log('- imageUrls:', item.imageUrls); - console.log('- images:', item.images); - console.log('- imgUrls:', item.imgUrls); - console.log('- picUrls:', item.picUrls); - console.log('- imageUrl:', item.imageUrl); - console.log('- image:', item.image); - console.log('- imgUrl:', item.imgUrl); - console.log('- picUrl:', item.picUrl); - }); - } else { - console.log('响应数据既不是预期的数组格式也不包含supplies字段'); - } - - // 宽松处理,适应多种可能的数据格式 - let suppliesList = []; - let totalCount = 0; - - // 情况1: 标准格式 {success: true, data: {list: [], total: n}} - 后端实际返回格式 - if (data.success === true && data.data && data.data.list && Array.isArray(data.data.list)) { - suppliesList = data.data.list; - totalCount = data.data.total || suppliesList.length; - console.log('情况1 - 后端实际返回格式: 从data.data.list中获取了', suppliesList.length, '条记录'); - } - // 情况2: 标准格式 {success: true, data: {supplies: [], total: n}} - else if (data.success === true && data.data && data.data.supplies && Array.isArray(data.data.supplies)) { - suppliesList = data.data.supplies; - totalCount = data.data.total || suppliesList.length; - console.log('情况2 - 备用格式: 从data.data.supplies中获取了', suppliesList.length, '条记录'); - } - // 情况2: 简化格式 {data: []} 或 {supplies: []} - else if (data.data && Array.isArray(data.data)) { - suppliesList = data.data; - totalCount = suppliesList.length; - console.log('情况2 - 简化格式: 从data.data中获取了', suppliesList.length, '条记录'); - } - else if (data.supplies && Array.isArray(data.supplies)) { - suppliesList = data.supplies; - totalCount = data.total || suppliesList.length; - console.log('情况2 - 简化格式: 从data.supplies中获取了', suppliesList.length, '条记录'); - } - // 情况3: 直接返回数组 - else if (Array.isArray(data)) { - suppliesList = data; - totalCount = suppliesList.length; - console.log('情况3 - 直接数组: 从根级获取了', suppliesList.length, '条记录'); - } - // 情况4: 检查data是否为对象数组的可能性 - else if (data.data && typeof data.data === 'object' && !Array.isArray(data.data) && Object.keys(data.data).length > 0) { - // 尝试将对象转换为数组(可能是索引对象) - const values = Object.values(data.data); - if (values.length > 0 && typeof values[0] === 'object') { - suppliesList = values; - totalCount = suppliesList.length; - console.log('情况4 - 对象转数组: 从data.data对象转换为数组,获取了', suppliesList.length, '条记录'); + supplyListEl.innerHTML = '
加载中...
'; + + // 构建请求URL + const url = `/api/supplies?status=${currentStatus}&page=${currentPage}&pageSize=${pageSize}&search=${encodeURIComponent(searchInputEl.value)}&phone=${encodeURIComponent(phoneInputEl.value)}`; + + // 发送请求 + const response = await fetch(url, { + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('token')}` } + }); + + if (!response.ok) { + throw new Error('Network response was not ok'); } - // 其他情况 - else { - console.warn('未识别的数据格式,尝试提取可能的数组字段:'); - - // 检查常见的数组字段名称 - const arrayFields = ['supplies', 'products', 'items', 'data', 'list', 'records', 'results']; - - for (const field of arrayFields) { - if (data[field] && Array.isArray(data[field])) { - suppliesList = data[field]; - totalCount = data.total || suppliesList.length; - console.log(`发现数组字段${field}: 获取了`, suppliesList.length, '条记录'); - break; - } + + const result = await response.json(); + + if (result.success) { + const supplies = result.data.list; + const total = result.data.total; + + // 更新总数显示 + const totalCountEl = document.getElementById('totalCount'); + if (totalCountEl) { + totalCountEl.textContent = total; } - } - - // 显示数据详情 - console.log('总记录数:', totalCount); - - // 更新总货源数量显示 - const totalCountEl = document.getElementById('totalCount'); - if (totalCountEl) { - totalCountEl.textContent = totalCount; - } - - if (suppliesList.length > 0) { - console.log('第一个数据项的所有字段:', Object.keys(suppliesList[0])); - console.log('第一个数据项详情:', JSON.stringify(suppliesList[0], null, 2)); - } - - console.log('最终处理结果:', { - suppliesLength: suppliesList.length, - totalCount: totalCount - }); - - // 对货源列表进行排序,按照创建时间倒序排列(最新的在前) - suppliesList.sort((a, b) => { - // 获取创建时间,支持多种可能的字段名称 - const aCreatedAt = a.createdAt || a.created_at || a.create_time || a.add_time || a.upload_time || new Date().toISOString(); - const bCreatedAt = b.createdAt || b.created_at || b.create_time || b.add_time || b.upload_time || new Date().toISOString(); - // 转换为时间戳并比较,降序排列 - return new Date(bCreatedAt).getTime() - new Date(aCreatedAt).getTime(); - }); - - // 先加载联系人数据,再渲染货源列表,确保联系人下拉框能正确显示选中状态 - await loadContacts(); - renderSupplies(suppliesList); - renderPagination(totalCount, currentPage, Math.ceil(totalCount / pageSize)); + // 渲染货源列表 + renderSupplyList(supplies); + + // 渲染分页 + renderPagination(total); + } else { + supplyListEl.innerHTML = `
⚠️

加载失败

${result.message || '获取货源数据失败,请稍后重试'}

`; + } } catch (error) { console.error('加载货源失败:', error); - let errorMessage = '加载失败,请稍后重试'; - if (error.message.includes('JSON解析失败')) { - errorMessage = '数据格式错误,可能是服务器响应异常'; - } else if (error.message.includes('服务器响应异常')) { - errorMessage = '服务器连接失败,请检查网络'; - } - supplyListEl.innerHTML = `
-
⚠️
-

加载失败

-

${errorMessage}

-

详细错误: ${error.message}

- -
`; + supplyListEl.innerHTML = '
⚠️

加载失败

网络错误,请稍后重试

'; } } - + // 渲染货源列表 - function renderSupplies(supplies) { - console.log('渲染数据类型:', typeof supplies, '数据是否为数组:', Array.isArray(supplies)); - console.log('渲染数据详情:', JSON.stringify(supplies, null, 2)); - - // 确保supplies是数组 + function renderSupplyList(supplies) { if (!supplies || !Array.isArray(supplies)) { console.error('supplies不是有效的数组:', supplies); supplyListEl.innerHTML = `
@@ -1918,1560 +1687,271 @@ } if (supplies.length === 0) { - console.log('没有数据可渲染'); supplyListEl.innerHTML = `
📦

暂无货源数据

-

${searchInputEl.value.trim() || phoneInputEl.value.trim() ? '没有找到匹配的货源' : '当前没有待审核的货源'}

+

${searchInputEl.value.trim() || phoneInputEl.value.trim() ? '没有找到匹配的货源' : '当前没有货源数据'}

`; return; } - // 显示第一个数据项的所有字段,方便调试 - console.log('第一个数据项的所有字段:', Object.keys(supplies[0])); - - supplyListEl.innerHTML = supplies.map((product, index) => { - // 使用更灵活的字段映射,考虑多种可能的字段名称 - // ID字段 - const id = product.id || product.product_id || product.p_id || product.item_id || `unknown-${index}`; - - // 名称字段 - 更全面的映射 - const name = product.name || product.title || product.productName || product.product_name - || product.goodsName || product.goods_name || product.itemName || product.item_name - || '未命名商品'; - - // 价格字段 - 支持更多可能的名称 - const price = product.price || product.cost || product.unitPrice || product.unit_price - || product.selling_price || product.amount || '0.00'; - - // 数量字段 - 更多映射选项 - const quantity = product.quantity || product.stock || product.inventory || product.count - || product.num || product.amount || '0'; - - // 重量字段 - const weight = product.weight || product.grossWeight || product.netWeight || product.gross_weight - || product.net_weight || product.unit_weight || '0'; - - // 蛋黄字段 - const yolk = product.yolk || product.yolk_info || product.egg_yolk || '未知'; - - // 描述字段 - 更全面的映射 - const description = product.description || product.remark || product.detail || product.info - || product.intro || product.note || ''; - - // 创建时间 - 支持更多时间字段名称 - const createdAt = product.createdAt || product.created_at || product.create_time || product.add_time - || product.upload_time || new Date().toISOString(); - - // 状态字段 - 更灵活的状态处理 - const status = product.status || product.state || product.audit_status || 'pending'; - - // 拒绝理由字段 - const rejectReason = product.rejectReason || product.reject_reason || product.reason || product.note || ''; + supplyListEl.innerHTML = supplies.map((supply, index) => { + // 状态处理 + let statusClass = 'status-pending'; + let statusText = '待审核'; - // 地区字段 - const region = product.region || product.address || product.location || ''; - - // 渲染图片 - let imageHtml = ''; - let imageUrls = []; - - // 1. 优先使用优化后的imageUrls字段(云存储架构的主要字段) - if (product.imageUrls && Array.isArray(product.imageUrls) && product.imageUrls.length > 0) { - // 过滤并验证URLs - imageUrls = product.imageUrls.filter(url => { - if (!url || typeof url !== 'string') return false; - const trimmedUrl = url.trim(); - return trimmedUrl && (trimmedUrl.startsWith('http://') || trimmedUrl.startsWith('https://')); - }); - } else if (product.imageUrls && typeof product.imageUrls === 'string') { - try { - // 处理JSON字符串格式的图片URLs - const parsedImages = JSON.parse(product.imageUrls); - if (Array.isArray(parsedImages)) { - imageUrls = parsedImages.filter(url => { - if (!url || typeof url !== 'string') return false; - const trimmedUrl = url.trim(); - return trimmedUrl && (trimmedUrl.startsWith('http://') || trimmedUrl.startsWith('https://')); - }); - } - } catch (e) { - console.log('解析imageUrls字符串失败:', e); - } - } - - // 2. 检查图片元数据(云存储架构的扩展字段) - if (product.imageMetadata) { - console.log(`产品ID ${id} 图片元数据:`, product.imageMetadata); - // 可以根据元数据执行特定操作,如显示来源标记等 - } - - // 3. 如果主字段没有有效图片,尝试其他可能的图片字段 - if (imageUrls.length === 0) { - const possibleImageFields = ['images', 'imgUrls', 'picUrls', 'pictures', 'imageUrl', 'image', 'imgUrl', 'picUrl', 'picture']; - for (const field of possibleImageFields) { - if (product[field]) { - if (Array.isArray(product[field])) { - const validUrls = product[field].filter(url => { - if (!url || typeof url !== 'string') return false; - const trimmedUrl = url.trim(); - return trimmedUrl && (trimmedUrl.startsWith('http://') || trimmedUrl.startsWith('https://')); - }); - if (validUrls.length > 0) { - imageUrls = validUrls; - break; - } - } else if (typeof product[field] === 'string') { - const trimmedUrl = product[field].trim(); - if (trimmedUrl && (trimmedUrl.startsWith('http://') || trimmedUrl.startsWith('https://'))) { - imageUrls = [trimmedUrl]; - break; - } - } - } - } - } - - // 4. 如果仍然没有找到图片,使用内联SVG数据URI作为占位图,避免依赖外部服务 - if (imageUrls.length === 0) { - // 基于产品ID生成一致的占位图颜色 - const color = `hsl(${(id || 0) * 37 % 360}, 70%, 80%)`; - const textColor = '666666'; - // 使用内联SVG数据URI,避免外部服务依赖 - const placeholder = `data:image/svg+xml,${encodeURIComponent(` - - - 暂无图片 - - `)}`; - imageUrls = [placeholder]; - console.log(`产品ID ${id} 使用内联SVG占位图`); - } - - // 显示所有可用图片,不再限制数量 - // imageUrls = imageUrls.slice(0, 1); // 移除数量限制 - - // 状态处理更灵活 - let statusClass = ''; - let statusText = ''; - - // 根据当前类型应用不同状态映射 - if (currentType === 'supply') { - // 货源审核状态 - if (status === 'pending_review') { - statusClass = 'status-pending'; - statusText = '审核中'; - } else if (status === 'published') { - statusClass = 'status-published'; - statusText = '已上架'; - } else if (status === 'rejected') { - statusClass = 'status-rejected'; - statusText = '审核失败'; - } else if (status === 'sold_out') { - statusClass = 'status-soldout'; - statusText = '已售罄'; - } else if (status === 'hidden') { - statusClass = 'status-hidden'; - statusText = '已下架'; - } - } else if (currentType === 'supplier') { - // 供应商审核状态 - if (status === 'underreview') { - statusClass = 'status-underreview'; - statusText = '审核中'; - } else if (status === 'reviewfailed') { - statusClass = 'status-reviewfailed'; - statusText = '审核失败'; - } else if (status === 'approved') { - statusClass = 'status-approved'; - statusText = '审核通过'; - } else if (status === 'incooperation') { - statusClass = 'status-incooperation'; - statusText = '合作中'; - } else if (status === 'notcooperative') { - statusClass = 'status-notcooperative'; - statusText = '未合作'; - } - } - - // 根据当前类型判断可审核状态 - let canReview = false; - if (currentType === 'supply') { - // 货源只有在pending_review状态下可以审核 - canReview = status === 'pending_review'; - } else if (currentType === 'supplier') { - // 供应商只有在underreview状态下可以审核 - canReview = status === 'underreview'; + if (supply.status === 'published') { + statusClass = 'status-published'; + statusText = '已审核'; + } else if (supply.status === 'rejected') { + statusClass = 'status-rejected'; + statusText = '已拒绝'; + } else if (supply.status === 'hidden') { + statusClass = 'status-hidden'; + statusText = '已下架'; } - - // 生成HTML,简化结构确保能正确显示 + + // 图片处理 + const imageUrls = Array.isArray(supply.imageUrls) ? supply.imageUrls : + (typeof supply.imageUrls === 'string' ? [supply.imageUrls] : + (supply.imageUrls ? [supply.imageUrls] : [])); + + // 联系人处理 + const contacts = Array.isArray(supply.contacts) ? supply.contacts : []; + return ` -
+
-
${name}
+
${supply.productName}
${statusText}
- -
- ${imageUrls.map(url => { - // 直接使用原始URL,不再强制替换阿里云OSS图片 - let displayUrl = url; - // 为所有URL添加时间戳防止缓存 - displayUrl = `${displayUrl}?t=${new Date().getTime()}`; - console.log(`产品ID ${id} 使用原始图片URL: ${displayUrl}`); - - return ` -
- -
- ${name} - - ${url.includes('placeholder') ? - '占位图' : ''} -
- `; - }).join('')} -
- - +
-
蛋黄
-
${yolk}
-
-
-
数量
-
${quantity}
- -
+
ID
+
${supply.id}

-
地区
-
${region || '未知'}
+
创建时间
+
${formatTime(supply.created_at)}
-
重量
-
${weight} kg
- -
+
供应商
+
${supply.company || '未知供应商'}

-
用户信息
-
昵称: ${product.nickName || '未知'}
-
电话: ${product.phoneNumber || '未知'}
+
联系人
+
${supply.contact || '未知联系人'}
价格
-
¥${price}
- -
+
¥${supply.price || '0'}

-
创建时间
-
${formatTime(createdAt)}
+
地区
+
${supply.region || '未知地区'}
-
- - -
-
ID
-
${id}
+
规格
+
${supply.spec || '未知规格'}
+
+
最小起订量
+
${supply.minOrder || '1'}件
- ${description ? ` -
-
描述
-
${description}
-
- ` : ''} - - ${rejectReason ? ` -
-
拒绝理由:
-
${rejectReason}
-
+ + ${imageUrls.length > 0 ? ` +
+ ${imageUrls.slice(0, 3).map(imgUrl => ` + 货源图片 + `).join('')} + ${imageUrls.length > 3 ? `
+${imageUrls.length - 3}
` : ''} +
` : ''} - - ${currentType === 'supply' ? ` - ${status !== 'pending_review' ? ` -
-
联系人:
-
-
${product.product_contact || '未分配'}
- ${product.contact_phone ? `
${product.contact_phone}
` : ''} -
-
- ` : ''} - ` : ` -
-
联系人:
- ${canReview ? ` - - ` : ` -
-
${product.product_contact || '未分配'}
- ${product.contact_phone ? `
${product.contact_phone}
` : ''} -
- `} + + ${supply.rejectReason ? ` +
+
拒绝理由:
+
${supply.rejectReason}
- `} + ` : ''} +
- ${canReview ? ` - - - ` : ` -
- 审核时间:${formatTime(product.audit_time || createdAt)} -
- `} + ` : ''}
`; }).join(''); - - console.log('成功渲染了', supplies.length, '条数据'); - - // 绑定联系人选择事件 - bindContactSelectEvents(); } - // 绑定联系人选择事件 - function bindContactSelectEvents() { - const selectElements = document.querySelectorAll('.contact-select'); - selectElements.forEach(select => { - // 移除已存在的事件监听器(防止重复绑定) - select.removeEventListener('change', handleContactChange); - // 添加新的事件监听器 - select.addEventListener('change', handleContactChange); - }); - } - - // 处理联系人选择变化 - function handleContactChange(event) { - const select = event.target; - const supplyId = select.dataset.id; - const contactId = parseInt(select.value); // 将contactId转换为数字类型 + // 渲染分页 + function renderPagination(total) { + const totalPages = Math.ceil(total / pageSize); + let html = ''; - if (!contactId) { - // 如果选择的是默认选项,不执行更新 - select.dataset.selected = ''; + if (totalPages <= 1) { + paginationEl.innerHTML = ''; return; } - // 获取选中的联系人信息 - const selectedContact = contacts.find(contact => contact.id === contactId); - if (!selectedContact) { - console.error('未找到选中的联系人信息:', contactId); - return; - } + // 上一页按钮 + html += ``; - // 更新下拉框的选中状态 - select.dataset.selected = contactId; + // 页码按钮 + const startPage = Math.max(1, currentPage - 2); + const endPage = Math.min(totalPages, currentPage + 2); - // 调用API更新货源的联系人信息 - updateSupplyContact(supplyId, selectedContact); - } - - // 更新货源的联系人信息 - function updateSupplyContact(supplyId, contact) { - fetch(`/api/supplies/${supplyId}/contact`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - productContact: `${contact.name}`, - contactPhone: contact.phoneNumber - }) - }) - .then(response => { - if (!response.ok) { - throw new Error('服务器响应异常'); - } - return response.json(); - }) - .then(data => { - if (data.success) { - console.log('联系人分配成功:', data); - // 显示成功提示 - showSuccessModal('联系人分配成功'); - } else { - console.error('联系人分配失败:', data.message); - alert('联系人分配失败: ' + (data.message || '未知错误')); + if (startPage > 1) { + html += ``; + if (startPage > 2) { + html += `...`; } - }) - .catch(error => { - console.error('更新联系人信息失败:', error); - alert('网络错误,请稍后重试'); - }); - } - - // 渲染分页 - function renderPagination(total, current, totalPages) { - let paginationHTML = ''; - - // 上一页 - paginationHTML += ``; - - // 页码按钮 - const startPage = Math.max(1, current - 2); - const endPage = Math.min(totalPages, startPage + 4); - + } + for (let i = startPage; i <= endPage; i++) { - paginationHTML += ``; + html += ``; } - - // 下一页 - paginationHTML += ``; - - paginationEl.innerHTML = paginationHTML; + + if (endPage < totalPages) { + if (endPage < totalPages - 1) { + html += `...`; + } + html += ``; + } + + // 下一页按钮 + html += ``; + + paginationEl.innerHTML = html; } - - // 改变页码 + + // 页面跳转 function changePage(page) { - if (page < 1) return; currentPage = page; - if (currentType === 'supply') { - loadSupplies(); - } else { - loadSuppliers(); - } + loadSupplies(); } - - // 处理搜索 - function handleSearch() { - if (currentType === 'supply') { - loadSupplies(); - } else { - loadSuppliers(); - } + + // 格式化时间 + function formatTime(timeStr) { + if (!timeStr) return '未知时间'; + const date = new Date(timeStr); + return date.toLocaleString('zh-CN'); } - - // 处理刷新 - function handleRefresh() { - if (currentType === 'supply') { - loadSupplies(); - } else { - loadSuppliers(); + + // 显示通过模态框 + function showApproveModal(id) { + currentSupplyId = id; + approveModalEl.style.display = 'flex'; + } + + // 关闭通过模态框 + function closeApproveModal() { + approveModalEl.style.display = 'none'; + currentSupplyId = null; + } + + // 确认通过 + async function confirmApprove() { + if (!currentSupplyId) return; + + try { + const response = await fetch(`/api/supplies/${currentSupplyId}/approve`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('token')}` + } + }); + + const result = await response.json(); + if (result.success) { + closeApproveModal(); + loadSupplies(); + alert('审核通过成功'); + } else { + alert('审核通过失败:' + (result.message || '未知错误')); + } + } catch (error) { + console.error('审核通过失败:', error); + alert('网络错误,请稍后重试'); } } - - // 显示拒绝理由弹窗 - function showRejectModal(supplyId) { - currentSupplyId = supplyId; + + // 显示拒绝模态框 + function showRejectModal(id) { + currentSupplyId = id; rejectReasonEl.value = ''; charCountEl.textContent = '0'; - charCountEl.style.color = '#999'; rejectModalEl.style.display = 'flex'; - rejectReasonEl.focus(); } - - // 关闭拒绝理由弹窗 + + // 关闭拒绝模态框 function closeRejectModal() { rejectModalEl.style.display = 'none'; currentSupplyId = null; } - + // 确认拒绝 async function confirmReject() { + if (!currentSupplyId) return; + const reason = rejectReasonEl.value.trim(); - if (!reason) { alert('请输入拒绝理由'); return; } - - if (reason.length > 500) { - alert('拒绝理由不能超过500个字符'); - return; - } - + try { - // 判断是货源拒绝还是供应商拒绝 - let apiUrl = ''; - if (currentSupplyId) { - apiUrl = `/api/supplies/${currentSupplyId}/reject?_t=${Date.now()}`; - } else if (currentSupplierId) { - apiUrl = `/api/suppliers/${currentSupplierId}/reject?_t=${Date.now()}`; - } else { - alert('未找到待处理的ID'); - return; - } - - // 添加时间戳参数防止缓存 - const response = await fetch(apiUrl, { // 使用相对路径避免跨电脑访问问题 + const response = await fetch(`/api/supplies/${currentSupplyId}/reject`, { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Cache-Control': 'no-cache, no-store, must-revalidate', - 'Pragma': 'no-cache', - 'Expires': '0' + 'Authorization': `Bearer ${localStorage.getItem('token')}` }, body: JSON.stringify({ rejectReason: reason }) }); - - if (!response.ok) { - throw new Error('服务器响应异常'); - } - - const data = await response.json(); - - if (data.success) { + + const result = await response.json(); + if (result.success) { closeRejectModal(); - // 强制重新加载数据,确保与数据库同步 - console.log('拒绝成功,重新加载数据...'); - // 清除可能的缓存状态 - if ('caches' in window) { - if (currentSupplyId) { - caches.delete(`/api/supplies?page=${currentPage}&pageSize=${pageSize}&status=${currentStatus}`).catch(e => console.warn('清除缓存失败:', e)); - // 重新加载数据 - loadSupplies(); - } else if (currentSupplierId) { - caches.delete(`/api/suppliers?page=${currentPage}&pageSize=${pageSize}&status=${currentStatus}`).catch(e => console.warn('清除缓存失败:', e)); - // 重新加载数据 - loadSuppliers(); // 注意:这里使用相同的函数名,确保loadSuppliers能处理两种情况 - } - } - // 显示自定义成功弹窗 - showSuccessModal('拒绝成功'); + loadSupplies(); + alert('拒绝成功'); } else { - alert(data.message || '拒绝失败'); + alert('拒绝失败:' + (result.message || '未知错误')); } } catch (error) { - console.error('拒绝货源失败:', error); + console.error('拒绝失败:', error); alert('网络错误,请稍后重试'); } } - - // 显示通过确认弹窗 - function showApproveModal(supplyId) { - currentSupplyId = supplyId; - approveModalEl.style.display = 'flex'; - } - - // 关闭通过确认弹窗 - function closeApproveModal() { - approveModalEl.style.display = 'none'; - currentSupplyId = null; - } - // 显示成功提示弹窗 - function showSuccessModal(message) { - const successModalEl = document.getElementById('successModal'); - const successMessageEl = document.getElementById('successMessage'); - successMessageEl.textContent = message; - successModalEl.style.display = 'flex'; + // 搜索处理 + function handleSearch() { + currentPage = 1; + loadSupplies(); } - // 关闭成功提示弹窗 - function closeSuccessModal() { - const successModalEl = document.getElementById('successModal'); - successModalEl.style.display = 'none'; + // 刷新处理 + function handleRefresh() { + currentPage = 1; + searchInputEl.value = ''; + phoneInputEl.value = ''; + loadSupplies(); } - // 加载联系人数据 - async function loadContacts() { - try { - const response = await fetch('/api/contacts'); - if (!response.ok) { - throw new Error('服务器响应异常'); - } - const data = await response.json(); - // 确保contacts是一个数组 - contacts = data.data || []; - console.log('联系人数据加载成功:', contacts); - // 加载联系人数据后,更新所有下拉框 - updateContactSelects(); - } catch (error) { - console.error('加载联系人数据失败:', error); - // 出错时将contacts设为空数组,避免后续错误 - contacts = []; - } - } - - // 更新所有联系人选择下拉框 - function updateContactSelects() { - const selectElements = document.querySelectorAll('.contact-select'); - selectElements.forEach(select => { - // 获取对应的产品ID - const supplyId = select.dataset.id; - - // 清空现有选项 - select.innerHTML = ''; - - // 添加默认选项 - const defaultOption = document.createElement('option'); - defaultOption.value = ''; - defaultOption.textContent = '请选择联系人'; - select.appendChild(defaultOption); - - // 添加联系人选项,只显示有电话号码的联系人 - contacts.forEach(contact => { - // 确保联系人有电话号码 - if (contact.phoneNumber && contact.phoneNumber.trim() !== '') { - const option = document.createElement('option'); - option.value = contact.id; - option.textContent = `${contact.name} (${contact.phoneNumber})`; - select.appendChild(option); - } - }); - - // 查找对应的产品数据,设置选中状态 - const supplyItem = document.querySelector(`.supply-item[data-id="${supplyId}"]`); - if (supplyItem) { - // 从DOM中获取产品数据(如果有) - const productData = supplyItem.dataset; - // 或者可以重新查询API获取最新数据 - // 这里我们直接使用现有的产品数据 - fetch(`/api/supplies?search=${supplyId}`) - .then(response => response.json()) - .then(data => { - if (data.success && data.list && data.list.length > 0) { - const product = data.list[0]; - if (product.product_contact) { - // 查找匹配的联系人ID,支持新旧格式 - const matchedContact = contacts.find(contact => - `${contact.salesPerson} - ${contact.name}` === product.product_contact || - contact.name === product.product_contact || - contact.phoneNumber === product.contact_phone - ); - if (matchedContact) { - select.value = matchedContact.id; - select.dataset.selected = matchedContact.id; - } else { - // 如果没有匹配的联系人,添加一个自定义选项显示产品表中的联系人信息 - const customOption = document.createElement('option'); - customOption.value = 'custom'; - customOption.textContent = `${product.product_contact} (${product.contact_phone})`; - customOption.selected = true; - select.appendChild(customOption); - select.dataset.selected = 'custom'; - } - } - } - }) - .catch(error => { - console.error('获取产品联系人信息失败:', error); - }); - } - }); + // 修复showImageViewer未定义问题 + function showImageViewer(imgElement) { + openImageViewer(imgElement); } - - // 绑定成功弹窗的确认按钮 - document.getElementById('successConfirmBtn').addEventListener('click', closeSuccessModal); - - // 确认通过 - async function confirmApprove() { - // 检查是货源审核还是供应商审核 - let isSupply = false; - let isSupplier = false; - let id = null; - - if (currentSupplyId) { - isSupply = true; - id = currentSupplyId; - - // 检查当前货源是否已经分配了联系人 - const selectElement = document.querySelector(`.contact-select[data-id="${id}"]`); - if (selectElement) { - const contactId = selectElement.dataset.selected || selectElement.value; - if (!contactId) { - alert('请先为该货源分配联系人,然后再进行审核通过操作'); - return; - } - } else { - // 如果没有找到下拉框(可能已经审核过),可以跳过检查 - console.log('未找到联系人下拉框,可能该货源已审核'); - } - } else if (currentSupplierId) { - isSupplier = true; - id = currentSupplierId; - } else { - return; - } - - try { - // 使用相对路径确保请求正确发送 - const apiUrl = isSupply - ? `/api/supplies/${id}/approve` - : `/api/suppliers/${id}/approve`; - const response = await fetch(apiUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({}) // 确保发送空对象作为请求体,避免req.body为undefined - }); - - if (!response.ok) { - throw new Error('服务器响应异常'); - } - - const data = await response.json(); - - if (data.success) { - closeApproveModal(); - // 强制重新加载数据,确保与数据库同步 - console.log('审核通过成功,重新加载数据...'); - // 清除可能的缓存状态 - if ('caches' in window) { - if (isSupply) { - caches.delete(`/api/supplies?page=${currentPage}&pageSize=${pageSize}&status=${currentStatus}`).catch(e => console.warn('清除缓存失败:', e)); - } else if (isSupplier) { - caches.delete(`/api/suppliers?page=${currentPage}&pageSize=${pageSize}&status=${currentStatus}`).catch(e => console.warn('清除缓存失败:', e)); - } - } - // 重新加载数据 - loadSupplies(); - // 显示自定义成功弹窗 - showSuccessModal(isSupply ? '通过成功' : '供应商通过成功'); - } else { - alert(data.message || '通过失败'); - } - } catch (error) { - console.error('批准货源失败:', error); - alert('网络错误,请稍后重试'); - } - } - - // 格式化时间 - function formatTime(timeStr) { - if (!timeStr) return '未知'; - - const date = new Date(timeStr); - if (isNaN(date.getTime())) return '未知'; - - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - - return `${year}/${month}/${day} ${hours}:${minutes}`; - } - - // 处理图片加载错误 - function handleImageError(imgElement, productId) { - // 防止重复触发错误处理 - if (imgElement.dataset.errorHandled) return; - imgElement.dataset.errorHandled = 'true'; - - // 记录详细错误日志 - console.warn(`产品ID ${productId} 图片加载失败!`, { - originalSrc: imgElement.src, - errorInfo: imgElement.error ? imgElement.error.message : '未知错误' - }); - - // 使用内联SVG数据URI作为备用占位图,避免外部服务依赖 - const hue = (productId || 0) * 37 % 360; - const color = `hsl(${hue}, 60%, 70%)`; - const errorTextColor = '#ff4d4f'; - imgElement.src = `data:image/svg+xml,${encodeURIComponent(` - - - 图片加载失败 - - `)}`; - - // 确保错误图片可见 - imgElement.style.display = 'block'; - imgElement.style.opacity = '1'; - imgElement.style.border = '2px solid red'; - - // 添加错误标记 - imgElement.classList.add('image-error'); - } - - // 隐藏图片骨架屏 - function hideImageSkeleton(imgElement) { - const skeleton = imgElement.parentElement.querySelector('.image-skeleton'); - if (skeleton) { - skeleton.style.display = 'none'; - } - // 确保图片可见 - imgElement.style.display = 'block'; - imgElement.style.opacity = '1'; - console.log('图片加载成功并显示:', imgElement.src); - } - - // 创建货源相关函数 - // 显示创建货源模态框 - function showCreateSupplyModal() { - // 重置表单 - supplyNameEl.value = ''; - supplyPriceEl.value = ''; - supplyMinOrderEl.value = ''; - supplyYolkEl.value = '红心'; - supplySpecEl.value = '格子装'; - supplyRegionEl.value = ''; - supplyGrossWeightEl.value = ''; - supplyImages = []; - supplyImagesEl.innerHTML = ''; - - // 显示模态框 - createSupplyModalEl.style.display = 'flex'; - } - - // 关闭创建货源模态框 - function closeCreateSupplyModal() { - createSupplyModalEl.style.display = 'none'; - } - - // 处理图片上传 - function handleImageUpload(e) { - const files = Array.from(e.target.files); - if (files.length === 0) return; - - // 限制图片数量 - const remainingSlots = 5 - supplyImages.length; - if (files.length > remainingSlots) { - alert(`最多只能上传5张图片,还可以上传${remainingSlots}张`); - return; - } - - // 处理每张图片 - files.forEach(file => { - // 检查文件类型 - if (!file.type.startsWith('image/')) { - alert('只能上传图片文件'); - return; - } - - // 检查文件大小(限制5MB) - if (file.size > 5 * 1024 * 1024) { - alert('图片大小不能超过5MB'); - return; - } - - // 预览图片 - const reader = new FileReader(); - reader.onload = (event) => { - const imageUrl = event.target.result; - supplyImages.push({ - file: file, - url: imageUrl - }); - - // 更新图片预览 - renderImagePreviews(); - }; - reader.readAsDataURL(file); - }); - - // 清空文件输入,允许再次选择相同的文件 - supplyImageUploadEl.value = ''; - } - - // 渲染图片预览 - function renderImagePreviews() { - supplyImagesEl.innerHTML = ''; - - supplyImages.forEach((image, index) => { - const previewContainer = document.createElement('div'); - previewContainer.style.position = 'relative'; - previewContainer.style.marginRight = '10px'; - previewContainer.style.marginBottom = '10px'; - previewContainer.style.display = 'inline-block'; - - const img = document.createElement('img'); - img.src = image.url; - img.style.width = '100px'; - img.style.height = '100px'; - img.style.objectFit = 'cover'; - img.style.borderRadius = '4px'; - - const deleteBtn = document.createElement('button'); - deleteBtn.textContent = '×'; - deleteBtn.style.position = 'absolute'; - deleteBtn.style.top = '-5px'; - deleteBtn.style.right = '-5px'; - deleteBtn.style.width = '20px'; - deleteBtn.style.height = '20px'; - deleteBtn.style.border = 'none'; - deleteBtn.style.borderRadius = '50%'; - deleteBtn.style.backgroundColor = 'rgba(255, 0, 0, 0.8)'; - deleteBtn.style.color = 'white'; - deleteBtn.style.fontSize = '14px'; - deleteBtn.style.display = 'flex'; - deleteBtn.style.alignItems = 'center'; - deleteBtn.style.justifyContent = 'center'; - deleteBtn.style.cursor = 'pointer'; - deleteBtn.style.zIndex = '10'; - - // 删除图片 - deleteBtn.addEventListener('click', () => { - supplyImages.splice(index, 1); - renderImagePreviews(); - }); - - previewContainer.appendChild(img); - previewContainer.appendChild(deleteBtn); - supplyImagesEl.appendChild(previewContainer); - }); - } - - // 确认创建货源 - async function confirmCreateSupply() { - // 获取表单数据 - const name = supplyNameEl.value.trim(); - const price = supplyPriceEl.value.trim(); - const minOrder = supplyMinOrderEl.value.trim(); - const yolk = supplyYolkEl.value; - const spec = supplySpecEl.value; - const region = supplyRegionEl.value.trim(); - const grossWeight = supplyGrossWeightEl.value.trim(); - const quality = document.getElementById('supplyQuality').value; - const contact = document.getElementById('supplyContact').value; - - // 验证表单 - if (!name) { - alert('请输入商品名称'); - return; - } - if (!price) { - alert('请输入价格'); - return; - } - if (!minOrder) { - alert('请输入最小起订量'); - return; - } - if (!quality) { - alert('请选择鸡蛋品质'); - return; - } - - // 获取当前登录用户信息 - const userInfo = JSON.parse(localStorage.getItem('userInfo')); - const sellerId = userInfo ? userInfo.userId : null; - - if (!sellerId) { - alert('请先登录或联系管理员获取权限'); - window.location.href = 'login.html'; - return; - } - - // 创建商品数据 - const productData = { - productName: name, - price: parseFloat(price), - quantity: parseInt(minOrder), - grossWeight: grossWeight, - yolk: yolk, - specification: spec, - quality: quality, - region: region, - rejectReason: '', - imageUrls: [], - sellerId: sellerId - }; - - try { - // 显示加载状态 - confirmCreateSupplyBtnEl.textContent = '创建中...'; - confirmCreateSupplyBtnEl.disabled = true; - - // 第一步:准备图片数据 - 提取base64字符串数组 - productData.imageUrls = supplyImages.map(image => image.url); - console.log('准备上传的图片数据:', productData.imageUrls); - - // 第二步:创建商品 - console.log('创建商品数据:', productData); - // 调用实际的API - const response = await fetch('/api/supplies/create', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(productData) - }); - - const result = await response.json(); - if (!result.success) { - throw new Error(result.message || '创建商品失败'); - } - - // 关闭模态框 - closeCreateSupplyModal(); - - // 显示成功提示 - showSuccessModal('货源创建成功'); - - // 刷新货源列表 - if (currentType === 'supply') { - loadSupplies(); - } - - } catch (error) { - console.error('创建货源失败:', error); - alert('创建货源失败,请稍后重试:' + error.message); - } finally { - // 恢复按钮状态 - confirmCreateSupplyBtnEl.textContent = '确认创建'; - confirmCreateSupplyBtnEl.disabled = false; - } - } - - // 供应商相关数据处理函数 - // 当前选中的供应商ID - let currentSupplierId = null; - - // 加载供应商列表 - async function loadSuppliers() { - supplyListEl.innerHTML = '
加载中...
'; - - try { - const searchKeyword = searchInputEl.value.trim(); - const phoneNumber = phoneInputEl.value.trim(); - - // 构建查询参数,添加时间戳防止缓存 - let queryParams = `page=${currentPage}&pageSize=${pageSize}&status=${currentStatus}&_t=${Date.now()}`; - if (searchKeyword) { - queryParams += `&keyword=${encodeURIComponent(searchKeyword)}`; - } - if (phoneNumber) { - queryParams += `&phoneNumber=${encodeURIComponent(phoneNumber)}`; - } - - // 使用相对路径,避免硬编码地址导致的跨电脑访问问题 - const response = await fetch(`/api/suppliers?${queryParams}`); - - if (!response.ok) { - throw new Error('服务器响应异常'); - } - - // 直接使用Text格式先获取原始响应,确保正确解析 - const responseText = await response.text(); - console.log('原始响应文本:', responseText); - - // 然后再解析为JSON - let data; - try { - data = JSON.parse(responseText); - console.log('成功解析JSON数据'); - } catch (parseError) { - console.error('JSON解析失败:', parseError); - console.error('原始响应:', responseText); - throw new Error('返回数据格式错误'); - } - - // 宽松处理,适应多种可能的数据格式 - let suppliersList = []; - let totalCount = 0; - - // 情况1: 标准格式 {success: true, data: {list: [], total: n}} - 后端实际返回格式 - if (data.success === true && data.data && data.data.list && Array.isArray(data.data.list)) { - suppliersList = data.data.list; - totalCount = data.data.total || suppliersList.length; - console.log('情况1 - 后端实际返回格式: 从data.data.list中获取了', suppliersList.length, '条记录'); - } - // 情况2: 标准格式 {success: true, data: {suppliers: [], total: n}} - else if (data.success === true && data.data && data.data.suppliers && Array.isArray(data.data.suppliers)) { - suppliersList = data.data.suppliers; - totalCount = data.data.total || suppliersList.length; - } - // 情况2: 简化格式 {data: []} 或 {suppliers: []} - else if (data.data && Array.isArray(data.data)) { - suppliersList = data.data; - totalCount = suppliersList.length; - } - else if (data.suppliers && Array.isArray(data.suppliers)) { - suppliersList = data.suppliers; - totalCount = data.total || suppliersList.length; - } - // 情况3: 直接返回数组 - else if (Array.isArray(data)) { - suppliersList = data; - totalCount = suppliersList.length; - } - - // 更新总数显示 - const totalCountEl = document.getElementById('totalCount'); - if (totalCountEl) { - totalCountEl.textContent = totalCount; - } - - // 对供应商列表进行排序,按照创建时间倒序排列(最新的在前) - suppliersList.sort((a, b) => { - // 获取创建时间,支持多种可能的字段名称 - const aCreatedAt = a.created_at || a.create_time || a.createdAt || new Date().toISOString(); - const bCreatedAt = b.created_at || b.create_time || b.createdAt || new Date().toISOString(); - - // 转换为时间戳并比较,降序排列 - return new Date(bCreatedAt).getTime() - new Date(aCreatedAt).getTime(); - }); - - // 渲染数据 - renderSuppliers(suppliersList); - renderPagination(totalCount, currentPage, Math.ceil(totalCount / pageSize)); - } catch (error) { - console.error('加载供应商失败:', error); - let errorMessage = '加载失败,请稍后重试'; - if (error.message.includes('JSON解析失败')) { - errorMessage = '数据格式错误,可能是服务器响应异常'; - } else if (error.message.includes('服务器响应异常')) { - errorMessage = '服务器连接失败,请检查网络'; - } - supplyListEl.innerHTML = `
-
⚠️
-

加载失败

-

${errorMessage}

-

详细错误: ${error.message}

- -
`; - } - } - - // 渲染供应商列表 - function renderSuppliers(suppliers) { - console.log('渲染供应商数据类型:', typeof suppliers, '数据是否为数组:', Array.isArray(suppliers)); - console.log('渲染供应商数据详情:', JSON.stringify(suppliers, null, 2)); - - // 确保suppliers是数组 - if (!suppliers || !Array.isArray(suppliers)) { - console.error('suppliers不是有效的数组:', suppliers); - supplyListEl.innerHTML = `
-

数据格式错误,请刷新页面重试

-
`; - return; - } - - if (suppliers.length === 0) { - console.log('没有供应商数据可渲染'); - supplyListEl.innerHTML = `
-
👥
-

暂无供应商数据

-

${searchInputEl.value.trim() || phoneInputEl.value.trim() ? '没有找到匹配的供应商' : '当前没有供应商数据'}

- -
`; - return; - } - - supplyListEl.innerHTML = suppliers.map((supplier, index) => { - // 使用更灵活的字段映射 - const id = supplier.userId || supplier.id || supplier.user_id || `unknown-${index}`; - const name = supplier.userName || supplier.name || supplier.company || '未命名供应商'; - const phone = supplier.phoneNumber || supplier.phone || '未知电话'; - const company = supplier.company || '未设置公司'; - const collaborationId = supplier.collaborationid || '未知合作商ID'; - const cooperation = supplier.cooperation || '未知合作模式'; - - // 地址信息 - const province = supplier.province || ''; - const city = supplier.city || ''; - const district = supplier.district || ''; - const detailedAddress = supplier.detailedaddress || ''; - const fullAddress = generateAddress(province, city, district, detailedAddress); - - // 证明材料 - const businessLicenseUrl = supplier.businesslicenseurl || ''; - const proofUrl = supplier.proofurl || ''; - const brandUrl = supplier.brandurl || ''; - - // 状态 - const status = supplier.partnerstatus || supplier.status || 'underreview'; - const createdAt = supplier.created_at || supplier.create_time || new Date().toISOString(); - const rejectReason = supplier.rejectReason || supplier.reject_reason || supplier.reason || ''; - const auditTime = supplier.audit_time || createdAt; - - // 状态处理 - let statusClass = 'status-underreview'; - let statusText = '审核中'; - - if (status === 'reviewfailed' || status === '已拒绝') { - statusClass = 'status-reviewfailed'; - statusText = '审核失败'; - } else if (status === 'approved' || status === '已通过') { - statusClass = 'status-approved'; - statusText = '审核通过'; - } else if (status === 'incooperation' || status === '合作中') { - statusClass = 'status-incooperation'; - statusText = '合作中'; - } else if (status === 'notcooperative' || status === '未合作') { - statusClass = 'status-notcooperative'; - statusText = '未合作'; - } - - // 审核按钮控制 - const canReview = status === 'underreview'; - const canTerminate = status === 'incooperation'; - const canCooperate = status === 'approved'; - - return ` -
-
-
${company}
-
${statusText}
-
- - -
-
-
合作商ID
-
${collaborationId}
-
-
合作模式
-
${cooperation}
-
-
-
联系人
-
${name}
-
-
电话
-
${phone}
-
-
-
地址
-
${fullAddress}
-
-
-
创建时间
-
${formatTime(createdAt)}
-
-
ID
-
${id}
-
-
- - - ${generateProofMaterialsHtml(businessLicenseUrl, proofUrl, brandUrl)} - - - ${rejectReason ? ` -
-
拒绝理由:
-
${rejectReason}
-
- ` : ''} - - -
- ${canReview ? ` - - - ` : canTerminate ? ` - -
- 审核时间:${formatTime(auditTime)} -
- ` : canCooperate ? ` - -
- 审核时间:${formatTime(auditTime)} -
- ` : ` -
- 审核时间:${formatTime(auditTime)} -
- `} -
-
- `; - }).join(''); - } - - // 生成地址信息 - function generateAddress(province, city, district, detailedAddress) { - const addressParts = [province, city, district, detailedAddress].filter(Boolean); - return addressParts.length > 0 ? addressParts.join('') : '未设置地址'; - } - - // 生成证明材料HTML - function generateProofMaterialsHtml(businessLicenseUrl, proofUrl, brandUrl) { - let materials = []; - - // 检查是否为图片文件的函数 - function isImageUrl(url) { - if (!url) return false; - const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']; - const lowerUrl = url.toLowerCase(); - return imageExtensions.some(ext => lowerUrl.includes(ext)); - } - - // 处理单个URL的函数 - function processUrl(url, title) { - if (!url) return ''; - - // 处理多个URL的情况(用逗号分隔) - const urls = url.split(',').map(u => u.trim()).filter(u => u); - - if (urls.length === 0) return ''; - - let itemsHtml = ''; - - urls.forEach((singleUrl, index) => { - const displayIndex = urls.length > 1 ? ` (${index + 1})` : ''; - - if (isImageUrl(singleUrl)) { - // 图片类型,显示预览图 - itemsHtml += ` -
-
${title}${displayIndex}
-
- - ${title} -
- 点击查看 -
-
- 下载原图 -
- `; - } else { - // 非图片类型,仅提供链接 - itemsHtml += ` -
-
${title}${displayIndex}
- 查看${title} -
- `; - } - }); - - return itemsHtml; - } - - materials.push(processUrl(businessLicenseUrl, '营业执照')); - materials.push(processUrl(proofUrl, '证明材料')); - materials.push(processUrl(brandUrl, '品牌授权链')); - - // 过滤空字符串 - materials = materials.filter(m => m); - - if (materials.length === 0) { - return ''; - } - - return ` -
- ${materials.join('')} -
- `; - } - - // 供应商相关模态框函数 - - // 显示供应商通过确认弹窗 - function showSupplierApproveModal(supplierId) { - currentSupplierId = supplierId; - currentSupplyId = null; // 清除货源ID,确保是供应商审核操作 - approveModalEl.style.display = 'flex'; - } - - // 显示供应商拒绝理由弹窗 - function showSupplierRejectModal(supplierId) { - currentSupplierId = supplierId; - currentSupplyId = null; // 清除货源ID,确保是供应商拒绝操作 - rejectReasonEl.value = ''; - charCountEl.textContent = '0'; - charCountEl.style.color = '#999'; - rejectModalEl.style.display = 'flex'; - rejectReasonEl.focus(); - } - - // 显示终止合作弹窗 - function showTerminateModal(supplierId) { - currentSupplierId = supplierId; - // 使用终止合作专用的文本框和字符计数 - const terminateReasonEl = document.getElementById('terminateReason'); - const terminateCharCountEl = document.getElementById('terminateCharCount'); - - if (terminateReasonEl) { - terminateReasonEl.value = ''; - terminateReasonEl.focus(); - } - if (terminateCharCountEl) { - terminateCharCountEl.textContent = '0'; - } - - const terminateModalEl = document.getElementById('terminateModal'); - if (terminateModalEl) { - terminateModalEl.style.display = 'flex'; - } - } - - // 确认终止合作 - async function confirmTerminate() { - const terminateReasonEl = document.getElementById('terminateReason'); - const terminateModalEl = document.getElementById('terminateModal'); - const reason = terminateReasonEl ? terminateReasonEl.value.trim() : ''; - - if (!reason) { - alert('请输入终止合作理由'); - return; - } - - try { - const response = await fetch(`/api/suppliers/${currentSupplierId}/terminate?_t=${Date.now()}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ reason }) - }); - - if (!response.ok) { - throw new Error('服务器响应异常'); - } - - const data = await response.json(); - - if (data.success) { - if (terminateModalEl) { - terminateModalEl.style.display = 'none'; - } - loadSuppliers(); - showSuccessModal('终止合作成功'); - } else { - alert(data.message || '终止合作失败'); - } - } catch (error) { - console.error('终止合作失败:', error); - alert('网络错误,请稍后重试'); - } - } - - // 确认供应商开始合作 - async function confirmSupplierToCooperation(supplierId) { - try { - const response = await fetch(`/api/suppliers/${supplierId}/cooperate?_t=${Date.now()}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - } - }); - - if (!response.ok) { - throw new Error('服务器响应异常'); - } - - const data = await response.json(); - - if (data.success) { - loadSuppliers(); - showSuccessModal('开始合作成功'); - } else { - alert(data.message || '开始合作失败'); - } - } catch (error) { - console.error('开始合作失败:', error); - alert('网络错误,请稍后重试'); - } - } - - // 为终止合作模态框添加事件监听 - const terminateModalEl = document.getElementById('terminateModal'); - if (terminateModalEl) { - const terminateReasonEl = document.getElementById('terminateReason'); - const terminateCharCountEl = document.getElementById('terminateCharCount'); - const cancelTerminateBtnEl = document.getElementById('cancelTerminateBtn'); - const confirmTerminateBtnEl = document.getElementById('confirmTerminateBtn'); - - // 字符计数 - if (terminateReasonEl && terminateCharCountEl) { - terminateReasonEl.addEventListener('input', () => { - const length = terminateReasonEl.value.length; - terminateCharCountEl.textContent = length; - terminateCharCountEl.style.color = length > 400 ? '#ff4d4f' : '#999'; - }); - } - - // 取消按钮 - if (cancelTerminateBtnEl) { - cancelTerminateBtnEl.addEventListener('click', function(e) { - e.preventDefault(); - terminateModalEl.style.display = 'none'; - }); - } - - // 确认终止按钮 - if (confirmTerminateBtnEl) { - confirmTerminateBtnEl.addEventListener('click', function(e) { - e.preventDefault(); - confirmTerminate(); - }); - } - - // 点击模态框外部关闭 - terminateModalEl.addEventListener('click', (e) => { - if (e.target === terminateModalEl) { - terminateModalEl.style.display = 'none'; - } - }); - } - - // 将函数暴露到全局 - window.showApproveModal = showApproveModal; - window.closeApproveModal = closeApproveModal; - window.confirmApprove = confirmApprove; - window.showRejectModal = showRejectModal; - window.closeRejectModal = closeRejectModal; - window.confirmReject = confirmReject; - window.changePage = changePage; - window.showSupplierApproveModal = showSupplierApproveModal; - window.showSupplierRejectModal = showSupplierRejectModal; - window.showTerminateModal = showTerminateModal; - window.confirmTerminate = confirmTerminate; - window.confirmSupplierToCooperation = confirmSupplierToCooperation; - window.loadSuppliers = loadSuppliers; - // 修复showImageViewer未定义问题,直接调用openImageViewer函数 -function showImageViewer(imgElement) { - openImageViewer(imgElement); -} diff --git a/Reject.js b/Reject.js index c4345e7..da9c1cd 100644 --- a/Reject.js +++ b/Reject.js @@ -1764,7 +1764,7 @@ app.get('/api/suppliers', async (req, res) => { console.log('收到供应商列表查询请求:', req.query); try { const connection = await pool.getConnection(); - const { page = 1, pageSize = 10, status = '', keyword = '', phoneNumber = '' } = req.query; + const { page = 1, pageSize = 10, status = '', keyword = '', phoneNumber = '', currentUserName = '', currentUserPhone = '' } = req.query; // 构建查询条件 let whereClause = ''; @@ -1790,6 +1790,13 @@ app.get('/api/suppliers', async (req, res) => { params.push(`%${phoneNumber}%`); } + // 添加对接人匹配逻辑,只显示当前登录者对接的供应商 + if (currentUserName || currentUserPhone) { + whereClause += (status || keyword || phoneNumber) ? ' AND' : ' WHERE'; + whereClause += ` (liaison LIKE ? OR liaison LIKE ?)`; + params.push(`%${currentUserName}%`, `%${currentUserPhone}%`); + } + // 获取总数 const [totalResult] = await connection.query( `SELECT COUNT(*) as total FROM users${whereClause}`, @@ -1803,7 +1810,7 @@ app.get('/api/suppliers', async (req, res) => { // 查询供应商列表,按创建时间倒序排序,确保最新创建的在前面 const [suppliers] = await connection.query( - `SELECT userId, phoneNumber, province, city, district, detailedaddress, company, collaborationid, cooperation, businesslicenseurl, proofurl, brandurl, partnerstatus, reasonforfailure, reject_reason, terminate_reason, audit_time, created_at + `SELECT userId, phoneNumber, province, city, district, detailedaddress, company, collaborationid, cooperation, businesslicenseurl, proofurl, brandurl, partnerstatus, reasonforfailure, reject_reason, terminate_reason, audit_time, created_at, liaison FROM users${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`, params diff --git a/SupplierReview.html b/SupplierReview.html new file mode 100644 index 0000000..0355fc7 --- /dev/null +++ b/SupplierReview.html @@ -0,0 +1,2276 @@ + + + + + + + 供应商审核系统 + + + + +
+ +
+ 未登录 + +
+ +

供应商审核系统

+ + +
+ + +
+ + + + +
+ + + + + +
+ + +
+ 总共 0 个供应商 +
+ +
+
加载中...
+
+ + +
+ + + + + + + + + + + + + + + + +
+ +
+ 大图查看 + +
+ + + +
+ + + + \ No newline at end of file