Browse Source

修改复制货源功能,移除图片复制

Boss2
Default User 2 months ago
parent
commit
124940e772
  1. 65
      Reject.js
  2. 323
      supply.html

65
Reject.js

@ -29,7 +29,8 @@ const dbConfig = {
database: 'wechat_app', // 连接到wechat_app数据库
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
queueLimit: 0,
timezone: '+08:00' // 设置为北京时间时区
};
// userlogin数据库配置
@ -40,7 +41,8 @@ const userLoginDbConfig = {
database: 'userlogin', // 连接到userlogin数据库
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
queueLimit: 0,
timezone: '+08:00' // 设置为北京时间时区
};
// 创建数据库连接池
@ -373,7 +375,13 @@ app.post('/api/login', async (req, res) => {
return sendResponse(res, false, null, '职位名称、用户名和密码不能为空');
}
// 1. 在login表中验证登录信息
// 1. 验证职位名称是否为允许的类型
const allowedProjectNames = ['采购员', '管理员'];
if (!allowedProjectNames.includes(projectName)) {
return sendResponse(res, false, null, '仅允许采购员和管理员登录');
}
// 2. 在login表中验证登录信息
const userLoginConnection = await userLoginPool.getConnection();
const [loginResult] = await userLoginConnection.query(
'SELECT id, projectName, userName, managerId FROM login WHERE projectName = ? AND userName = ? AND password = ?',
@ -712,6 +720,18 @@ app.post('/api/supplies/create', async (req, res) => {
sellerId = 'default_seller';
}
// 检查是否为重复货源
console.log('检查是否为重复货源...');
const [existingProducts] = await connection.query(
'SELECT id FROM products WHERE productName = ? AND specification = ? AND region = ? AND price = ? AND yolk = ?',
[productName, specification, region, price, yolk]
);
if (existingProducts.length > 0) {
connection.release();
return sendResponse(res, false, null, '检测到重复的货源数据,不允许创建');
}
// 处理联系人信息
let productContact = '';
let contactPhone = '';
@ -1024,7 +1044,7 @@ app.put('/api/supplies/:id/edit', async (req, res) => {
try {
const connection = await pool.getConnection();
const productId = req.params.id;
const { productName, price, quantity, grossWeight, yolk, specification, supplyStatus, description, region, contactId, producting } = req.body;
const { productName, price, quantity, grossWeight, yolk, specification, supplyStatus, description, region, contactId, producting, imageUrls } = req.body;
// 开始事务
await connection.beginTransaction();
@ -1059,19 +1079,52 @@ app.put('/api/supplies/:id/edit', async (req, res) => {
}
}
// 处理图片上传
let uploadedImageUrls = [];
if (Array.isArray(imageUrls) && imageUrls.length > 0) {
console.log('开始处理编辑图片上传,共', imageUrls.length, '张图片');
for (const imageUrl of imageUrls) {
if (imageUrl.startsWith('data:image/')) {
// 处理DataURL
const base64Data = imageUrl.replace(/^data:image\/(png|jpeg|jpg|gif);base64,/, '');
let buffer = Buffer.from(base64Data, 'base64');
const ext = imageUrl.match(/^data:image\/(png|jpeg|jpg|gif);base64,/)?.[1] || 'png';
const filename = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}.${ext}`;
try {
// 不再添加水印,前端已处理
console.log('【水印处理】前端已添加水印,跳过后端水印处理');
// 使用OSS上传带水印的图片
const ossUrl = await OssUploader.uploadBuffer(buffer, filename, `products/${productName || 'general'}`, 'image');
uploadedImageUrls.push(ossUrl);
console.log('图片上传成功:', ossUrl);
} catch (uploadError) {
console.error('图片上传失败:', uploadError.message);
// 继续上传其他图片,不中断流程
}
} else {
// 已经是URL,直接使用
uploadedImageUrls.push(imageUrl);
}
}
console.log('图片处理完成,成功上传', uploadedImageUrls.length, '张图片');
}
// 更新货源信息
const updateQuery = `
UPDATE products
SET productName = ?, price = ?, quantity = ?, grossWeight = ?,
yolk = ?, specification = ?, producting = ?, supplyStatus = ?, description = ?, region = ?,
product_contact = ?, contact_phone = ?
product_contact = ?, contact_phone = ?, imageUrls = ?
WHERE id = ?
`;
await connection.query(updateQuery, [
productName, price.toString(), parseInt(quantity), grossWeight,
yolk, specification, producting, supplyStatus, description, region,
productContact, contactPhone, productId
productContact, contactPhone, JSON.stringify(uploadedImageUrls), productId
]);
// 提交事务

323
supply.html

@ -267,6 +267,23 @@
background-color: #8c8c8c;
}
.copy-supply-btn {
display: inline-block;
padding: 4px 12px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 12px;
background-color: #fff;
color: #333;
cursor: pointer;
margin-left: 8px;
}
.copy-supply-btn:hover {
border-color: #1677ff;
color: #1677ff;
}
.supply-details {
display: grid;
grid-template-columns: repeat(2, 1fr);
@ -464,6 +481,29 @@
transition: all 0.3s;
}
.delete-image-btn {
position: absolute;
top: 5px;
right: 5px;
width: 24px;
height: 24px;
background-color: rgba(245, 34, 45, 0.9);
color: white;
border: none;
border-radius: 50%;
font-size: 16px;
line-height: 20px;
text-align: center;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.delete-image-btn:hover {
background-color: #f5222d;
}
.upload-image:hover {
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
@ -1066,7 +1106,7 @@
<div>3. 敲开鸡蛋后清晰显示蛋清、蛋黄状态,以体现新鲜度;</div>
<div>4. 其他能佐证蛋重、品种的辅助图片。</div>
</div>
<div style="font-size: 12px; color: #999; margin-top: 10px; text-align: left;">最多上传5张图片</div>
<div style="font-size: 12px; color: #999; margin-top: 10px; text-align: left;">最多上传2张图片</div>
</div>
</div>
@ -1435,7 +1475,11 @@
<div id="editUploadImages" class="upload-images" style="display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 15px;">
<!-- 图片将通过JavaScript动态加载 -->
</div>
<div style="font-size: 12px; color: #999;">提示:图片暂不支持编辑</div>
<div style="font-size: 12px; color: #999; margin-top: 10px;">最多上传2张图片</div>
<input type="file" id="editImageUpload" multiple accept="image/*" style="display: none;" onchange="handleEditImageUpload(event)">
<button type="button" onclick="triggerEditImageUpload()" style="margin-top: 10px; padding: 8px 16px; background-color: #f0f0f0; border: 1px solid #d9d9d9; border-radius: 4px; font-size: 14px; cursor: pointer;">
添加图片
</button>
</div>
<!-- 货源类型 -->
@ -1793,6 +1837,7 @@
let editFilteredProductingOptions = [...editAllProductingOptions];
let editSelectedProducting = '';
let editFilteredContacts = [];
let editCurrentImages = []; // 编辑时当前的图片列表
let editSelectedContactId = '';
// 联系人数据
@ -1918,8 +1963,8 @@
// 处理拖拽或粘贴的图片
async function handleDroppedImages(imageFiles) {
for (let i = 0; i < imageFiles.length; i++) {
if (supplyData.uploadedImages.length >= 5) {
alert('最多只能上传5张图片');
if (supplyData.uploadedImages.length >= 2) {
alert('最多只能上传2张图片');
break;
}
@ -3448,6 +3493,7 @@
<div class="supply-name">
${supply.productName}
<span class="supply-status ${status.class}">${status.text}</span>
<button class="copy-supply-btn" onclick="copySupply('${supply.id}')">复制</button>
</div>
<div class="supply-details">
<div class="detail-item">蛋黄: ${supply.yolk || '无'}</div>
@ -3475,6 +3521,183 @@
return `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
}
// 复制货源信息
function copySupply(supplyId) {
try {
// 查找对应的货源信息
let supply = null;
// 1. 首先尝试直接从所有货源数组中查找
if (supplyData.supplies && supplyData.supplies.length > 0) {
supply = supplyData.supplies.find(item => {
return String(item.id) === String(supplyId) || String(item.productId) === String(supplyId) || String(item._id) === String(supplyId);
});
}
// 2. 如果没找到,遍历所有状态的货源列表查找
if (!supply) {
const allSupplies = [
...supplyData.publishedSupplies,
...supplyData.pendingSupplies,
...supplyData.rejectedSupplies,
...supplyData.draftSupplies
];
supply = allSupplies.find(item => {
return String(item.id) === String(supplyId) || String(item.productId) === String(supplyId) || String(item._id) === String(supplyId);
});
}
// 3. 如果没找到,遍历所有分页货源列表查找
if (!supply) {
const paginatedSupplies = [
...(supplyData.paginatedSupplies.published || []),
...(supplyData.paginatedSupplies.pending || []),
...(supplyData.paginatedSupplies.rejected || []),
...(supplyData.paginatedSupplies.draft || [])
];
supply = paginatedSupplies.find(item => {
return String(item.id) === String(supplyId) || String(item.productId) === String(supplyId) || String(item._id) === String(supplyId);
});
}
// 4. 如果还是没找到,尝试从DOM中获取
if (!supply) {
const supplyItem = document.querySelector(`[data-id="${supplyId}"]`);
if (supplyItem) {
// 从DOM中提取关键信息
const productName = supplyItem.querySelector('.supply-name').textContent.replace(/已上架|审核中|审核失败|已隐藏|已下架|复制/g, '').trim();
const priceText = supplyItem.querySelector('.detail-item:last-child').textContent;
const price = priceText.replace(/价格: ¥/, '').trim();
// 创建一个简化的supply对象
supply = {
id: supplyId,
productName: productName,
price: price
};
}
}
// 调试日志
console.log('复制货源信息:', {
supplyId: supplyId,
supplyFound: !!supply,
allSuppliesCount: (supplyData.supplies ? supplyData.supplies.length : 0) +
supplyData.publishedSupplies.length +
supplyData.pendingSupplies.length +
supplyData.rejectedSupplies.length +
supplyData.draftSupplies.length,
paginatedSuppliesCount:
(supplyData.paginatedSupplies.published ? supplyData.paginatedSupplies.published.length : 0) +
(supplyData.paginatedSupplies.pending ? supplyData.paginatedSupplies.pending.length : 0) +
(supplyData.paginatedSupplies.rejected ? supplyData.paginatedSupplies.rejected.length : 0) +
(supplyData.paginatedSupplies.draft ? supplyData.paginatedSupplies.draft.length : 0),
supplyDataKeys: supply ? Object.keys(supply) : 'none',
supplyData: supply
});
if (!supply) {
alert('未找到对应的货源信息');
return;
}
// 保存到全局变量
supplyData.copiedSupply = supply;
// 打开创建货源弹窗
showAddSupplyModal();
// 填充表单数据
fillFormWithSupplyData(supply);
alert('货源信息已复制到创建表单');
} catch (error) {
console.error('复制货源失败:', error);
alert('复制货源失败,请重试');
}
}
// 用货源数据填充表单
function fillFormWithSupplyData(supply) {
// 重置表单
resetForm();
// 填充表单字段
document.getElementById('price').value = supply.price || '';
document.getElementById('quantity').value = supply.quantity || '';
document.getElementById('grossWeight').value = supply.grossWeight || '';
document.getElementById('description').value = supply.description || '';
// 填充选择字段
// 商品名称
document.getElementById('productName').value = supply.productName || '';
document.getElementById('productNameDisplayText').textContent = supply.productName || '请选择商品名称';
selectedProductName = supply.productName || '';
// 货源类型
document.getElementById('sourceType').value = supply.sourceType || '';
document.getElementById('sourceTypeDisplayText').textContent = supply.sourceType || '请选择货源类型';
selectedSourceType = supply.sourceType || '';
// 蛋黄类型
document.getElementById('yolk').value = supply.yolk || '';
document.getElementById('yolkDisplayText').textContent = supply.yolk || '请选择蛋黄类型';
selectedYolk = supply.yolk || '';
// 地区
document.getElementById('regionValue').value = supply.region || '';
document.getElementById('regionDisplayText').textContent = supply.region || '请选择地区';
// 规格
document.getElementById('specValue').value = supply.specification || supply.spec || '';
document.getElementById('specDisplayText').textContent = (supply.specification || supply.spec) || '请选择规格';
selectedSpec = supply.specification || supply.spec || '';
// 货源状态
document.getElementById('supplyStatus').value = supply.supplyStatus || '';
// 联系人
document.getElementById('contactId').value = supply.contactId || '';
document.getElementById('contactIdDisplayText').textContent = supply.product_contact || '请选择联系人';
selectedContactId = supply.contactId || '';
// 产品包装
document.getElementById('productingValue').value = supply.producting || '';
document.getElementById('productingDisplayText').textContent = supply.producting || '请选择产品包装';
selectedProducting = supply.producting || '';
// 不复制图片,保持图片列表为空
supplyData.uploadedImages = [];
renderUploadedImages();
}
// 检查是否为重复货源
async function checkDuplicateSupply(formData) {
try {
// 构建查询参数
const queryParams = new URLSearchParams({
productName: formData.productName,
spec: formData.specification || formData.spec,
region: formData.region,
price: formData.price,
checkDuplicate: true
});
const response = await fetch(`/api/supplies?${queryParams}`);
const result = await response.json();
if (result.success && result.data && result.data.length > 0) {
return true; // 存在重复货源
}
return false; // 不存在重复货源
} catch (error) {
console.error('检查重复货源失败:', error);
return false; // 出错时默认允许创建
}
}
// 切换列表展开/折叠
function toggleSection(type) {
const listElement = document.getElementById(`${type}List`);
@ -3730,6 +3953,78 @@
document.getElementById('imageUpload').click();
}
// 触发编辑页面图片上传
function triggerEditImageUpload() {
document.getElementById('editImageUpload').click();
}
// 处理编辑页面图片上传
function handleEditImageUpload(event) {
const files = event.target.files;
const editUploadImages = document.getElementById('editUploadImages');
for (let i = 0; i < files.length; i++) {
if (editCurrentImages.length >= 2) {
alert('最多只能上传2张图片');
break;
}
const file = files[i];
const reader = new FileReader();
reader.onload = async function(e) {
let imageUrl = e.target.result;
try {
// 为图片添加水印
imageUrl = await addWatermarkToImage(imageUrl);
// 添加到当前图片列表
editCurrentImages.push(imageUrl);
// 更新显示
updateEditImageDisplay();
} catch (error) {
console.error('图片处理失败:', error);
alert('图片处理失败,请重试');
}
};
reader.readAsDataURL(file);
}
// 清空文件输入,以便再次选择同一文件
event.target.value = '';
}
// 删除编辑页面图片
function deleteEditImage(imageUrl) {
// 从当前图片列表中删除
const index = editCurrentImages.indexOf(imageUrl);
if (index > -1) {
editCurrentImages.splice(index, 1);
}
// 更新显示
updateEditImageDisplay();
}
// 更新编辑页面图片显示
function updateEditImageDisplay() {
const editUploadImages = document.getElementById('editUploadImages');
editUploadImages.innerHTML = '';
editCurrentImages.forEach(imageUrl => {
const imageElement = document.createElement('div');
imageElement.className = 'upload-image';
imageElement.innerHTML = `
<img src="${imageUrl}" alt="商品图片" onclick="previewImage('${imageUrl}')">
<button class="delete-image-btn" onclick="deleteEditImage('${imageUrl}')">×</button>
`;
editUploadImages.appendChild(imageElement);
});
}
// 为图片添加水印(前端Canvas实现)
function addWatermarkToImage(imageUrl) {
return new Promise((resolve, reject) => {
@ -3783,8 +4078,8 @@
const uploadArea = document.getElementById('uploadImages');
for (let i = 0; i < files.length; i++) {
if (supplyData.uploadedImages.length >= 5) {
alert('最多只能上传5张图片');
if (supplyData.uploadedImages.length >= 2) {
alert('最多只能上传2张图片');
break;
}
@ -4172,6 +4467,13 @@
return;
}
// 检查是否为重复货源
const isDuplicate = await checkDuplicateSupply(formData);
if (isDuplicate) {
alert('检测到重复的货源数据,不允许创建');
return;
}
try {
// 设置为提交中状态,禁用按钮
isSubmitting = true;
@ -4680,16 +4982,20 @@
const editUploadImages = document.getElementById('editUploadImages');
editUploadImages.innerHTML = '';
if (supply.imageUrls && Array.isArray(supply.imageUrls)) {
supply.imageUrls.forEach(imageUrl => {
supply.imageUrls.forEach((imageUrl, index) => {
const imageElement = document.createElement('div');
imageElement.className = 'upload-image';
imageElement.innerHTML = `
<img src="${imageUrl}" alt="商品图片" onclick="previewImage('${imageUrl}')">
<button class="delete-image-btn" onclick="deleteEditImage('${imageUrl}')">×</button>
`;
editUploadImages.appendChild(imageElement);
});
}
// 保存当前图片列表到全局变量,用于编辑时使用
editCurrentImages = supply.imageUrls && Array.isArray(supply.imageUrls) ? [...supply.imageUrls] : [];
// 根据模式修改保存按钮文本
const saveButton = document.querySelector('#editSupplyModal .modal-btn-primary');
if (saveButton) {
@ -5470,7 +5776,8 @@
supplyStatus: document.getElementById('editSupplyStatus').value,
description: document.getElementById('editDescription').value,
region: document.getElementById('editRegionValue').value,
contactId: document.getElementById('editContactId').value
contactId: document.getElementById('editContactId').value,
imageUrls: editCurrentImages // 添加编辑后的图片列表
};
// 验证表单

Loading…
Cancel
Save