-
-
- ${imageUrls.map(url => {
- // 直接使用原始URL,不再强制替换阿里云OSS图片
- let displayUrl = url;
- // 为所有URL添加时间戳防止缓存
- displayUrl = `${displayUrl}?t=${new Date().getTime()}`;
- console.log(`产品ID ${id} 使用原始图片URL: ${displayUrl}`);
-
- return `
-
-
-
-

-
- ${url.includes('placeholder') ?
- '
占位图' : ''}
-
- `;
- }).join('')}
-
-
-
+
-
-
数量
-
${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 ? `
-
- ` : ''}
-
- ${rejectReason ? `
-
-
拒绝理由:
-
${rejectReason}
-
+
+ ${imageUrls.length > 0 ? `
+
+ ${imageUrls.slice(0, 3).map(imgUrl => `
+

+ `).join('')}
+ ${imageUrls.length > 3 ? `
+${imageUrls.length - 3}
` : ''}
+
` : ''}
-
- ${currentType === 'supply' ? `
- ${status !== 'pending_review' ? `
-
- ` : ''}
- ` : `
-
`;
}).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 `
-
-
-
-
-
-
-
合作商ID
-
${collaborationId}
-
-
合作模式
-
${cooperation}
-
-
-
联系人
-
${name}
-
-
电话
-
${phone}
-
-
-
-
创建时间
-
${formatTime(createdAt)}
-
-
ID
-
${id}
-
-
-
-
- ${generateProofMaterialsHtml(businessLicenseUrl, proofUrl, brandUrl)}
-
-
- ${rejectReason ? `
-
-
拒绝理由:
-
${rejectReason}
-
- ` : ''}
-
-
-
-
- `;
- }).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}
-
-
-

-
- 点击查看
-
-
-
下载原图
-
- `;
- } else {
- // 非图片类型,仅提供链接
- itemsHtml += `
-
- `;
- }
- });
-
- 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