From f61934f31dc905e46595a2438c7eb1a10a8afa25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E9=A3=9E=E6=B4=8B?= <15778543+xufeiyang6017@user.noreply.gitee.com> Date: Thu, 5 Feb 2026 16:25:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86=20publish=20=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=EF=BC=8C=E6=9B=B4=E6=96=B0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.json | 1 - pages/publish/index.js | 555 --------------------------------------- pages/publish/index.json | 3 - pages/publish/index.wxml | 54 ---- pages/publish/index.wxss | 117 --------- 5 files changed, 730 deletions(-) delete mode 100644 pages/publish/index.js delete mode 100644 pages/publish/index.json delete mode 100644 pages/publish/index.wxml delete mode 100644 pages/publish/index.wxss diff --git a/app.json b/app.json index 61214cb..aa57705 100644 --- a/app.json +++ b/app.json @@ -6,7 +6,6 @@ "pages/evaluate2/product-list", "pages/evaluate2/spec-detail", "pages/settlement/index", - "pages/publish/index", "pages/buyer/index", "pages/profile/index", "pages/profile/authentication/index", diff --git a/pages/publish/index.js b/pages/publish/index.js deleted file mode 100644 index 5bdf1e0..0000000 --- a/pages/publish/index.js +++ /dev/null @@ -1,555 +0,0 @@ -// pages/publish/index.js -// 引入API工具 -const API = require('../../utils/api.js'); - -// 【终极修复】创建全局上传管理器,完全独立于页面生命周期 -if (!global.ImageUploadManager) { - global.ImageUploadManager = { - // 存储所有活动的上传任务 - activeTasks: {}, - // 深度克隆工具函数 - deepClone: function(obj) { - return JSON.parse(JSON.stringify(obj)); - }, - // 核心上传方法 - upload: function(formData, images, successCallback, failCallback) { - console.log('【全局上传管理器】开始上传,图片数量:', images.length); - - // 创建唯一的上传任务ID - const taskId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; - - // 创建深度克隆,完全隔离数据 - const clonedFormData = this.deepClone(formData); - const clonedImages = this.deepClone(images); - - // 将任务保存到全局状态中,防止页面重新编译时丢失 - this.activeTasks[taskId] = { - id: taskId, - formData: clonedFormData, - images: clonedImages, - status: 'started', - startTime: Date.now(), - uploadedCount: 0, - totalCount: clonedImages.length - }; - - console.log(`【全局上传管理器】创建任务 ${taskId},已保存到全局状态`); - - // 使用setTimeout完全隔离执行上下文,避免与页面生命周期耦合 - const self = this; - setTimeout(() => { - try { - console.log('【全局上传管理器】准备调用API.publishProduct'); - console.log('准备的商品数据:', clonedFormData); - console.log('准备的图片数量:', clonedImages.length); - - // 关键修改:使用API.publishProduct方法,这是正确的调用链 - // 包含所有必要字段 - const productData = { - ...clonedFormData, - images: clonedImages, // 直接传递图片数组 - imageUrls: clonedImages, // 同时设置imageUrls字段 - // 生成会话ID,确保所有图片关联同一商品 - sessionId: taskId, - uploadSessionId: taskId - }; - - console.log('最终传递给publishProduct的数据:', Object.keys(productData)); - - API.publishProduct(productData) - .then(res => { - console.log(`【全局上传管理器】任务 ${taskId} 上传完成,响应:`, res); - - // 更新任务状态 - if (self.activeTasks[taskId]) { - self.activeTasks[taskId].status = 'completed'; - self.activeTasks[taskId].endTime = Date.now(); - self.activeTasks[taskId].result = res; - } - - // 使用setTimeout隔离成功回调的执行 - setTimeout(() => { - if (successCallback) { - successCallback(res); - } - }, 0); - }) - .catch(err => { - console.error(`【全局上传管理器】任务 ${taskId} 上传失败:`, err); - - // 更新任务状态 - if (self.activeTasks[taskId]) { - self.activeTasks[taskId].status = 'failed'; - self.activeTasks[taskId].error = err; - self.activeTasks[taskId].endTime = Date.now(); - } - - // 使用setTimeout隔离失败回调的执行 - setTimeout(() => { - if (failCallback) { - failCallback(err); - } - }, 0); - }) - .finally(() => { - // 延迟清理任务,确保所有操作完成 - setTimeout(() => { - if (self.activeTasks[taskId]) { - delete self.activeTasks[taskId]; - console.log(`【全局上传管理器】任务 ${taskId} 已清理`); - } - }, 10000); - }); - } catch (e) { - console.error(`【全局上传管理器】任务 ${taskId} 发生异常:`, e); - setTimeout(() => { - if (failCallback) { - failCallback(e); - } - }, 0); - } - }, 0); - - return taskId; - }, - - // 获取任务状态的方法 - getTaskStatus: function(taskId) { - return this.activeTasks[taskId] || null; - }, - - // 获取所有活动任务 - getActiveTasks: function() { - return Object.values(this.activeTasks); - } - }; -} - -Page({ - /** - * 页面的初始数据 - */ - data: { - variety: '', // 品种 - price: '', - quantity: '', - grossWeight: '', - yolk: '', // 蛋黄 - specification: '', - images: [] // 新增图片数组 - }, - - /** - * 生命周期函数--监听页面加载 - */ - onLoad(options) { - // 移除登录检查,允许直接发布商品 - }, - - /** - * 品种输入处理 - */ - onVarietyInput(e) { - this.setData({ - variety: e.detail.value - }); - }, - - /** - * 蛋黄输入处理 - */ - onYolkInput(e) { - this.setData({ - yolk: e.detail.value - }); - }, - - /** - * 价格输入处理 - */ - onPriceInput(e) { - // 保存原始字符串值,不进行数字转换 - this.setData({ - price: e.detail.value - }); - }, - - /** - * 数量输入处理 - */ - onQuantityInput(e) { - const value = parseFloat(e.detail.value); - this.setData({ - quantity: isNaN(value) ? '' : value - }); - }, - - /** - * 毛重输入处理 - */ - onGrossWeightInput(e) { - // 直接保存原始字符串值,不进行数字转换 - this.setData({ - grossWeight: e.detail.value - }); - }, - - /** - * 规格输入处理 - */ - onSpecificationInput(e) { - this.setData({ - specification: e.detail.value - }); - }, - - /** - * 表单验证 - */ - validateForm() { - const { variety, price, quantity } = this.data; - - console.log('表单验证数据 - variety:', variety, 'price:', price, 'quantity:', quantity); - console.log('数据类型 - variety:', typeof variety, 'price:', typeof price, 'quantity:', typeof quantity); - - if (!variety || !variety.trim()) { - wx.showToast({ title: '请输入品种', icon: 'none' }); - return false; - } - - if (!price || price.trim() === '') { - wx.showToast({ title: '请输入有效价格', icon: 'none' }); - return false; - } - - if (quantity === '' || quantity === undefined || quantity === null || quantity <= 0) { - wx.showToast({ title: '请输入有效数量', icon: 'none' }); - return false; - } - - console.log('表单验证通过'); - return true; - }, - - /** - * 发布商品按钮点击事件 - */ - onPublishTap() { - console.log('发布按钮点击'); - - if (!this.validateForm()) { - console.log('表单验证失败'); - return; - } - - const { variety, price, quantity, grossWeight, yolk, specification } = this.data; - const images = this.data.images; - - // 构建商品数据,确保价格和数量为字符串类型 - const productData = { - productName: variety.trim(), // 使用品种作为商品名称 - price: price.toString(), - quantity: quantity.toString(), - grossWeight: grossWeight !== '' && grossWeight !== null && grossWeight !== undefined ? grossWeight : "", - yolk: yolk || '', - specification: specification || '', - images: images, - imageUrls: images, - allImageUrls: images, - hasMultipleImages: images.length > 1, - totalImages: images.length - }; - - console.log('【关键日志】商品数据:', productData); - console.log('【关键日志】图片数量:', images.length); - - // 【终极修复】在上传开始前立即清空表单 - // 先深度克隆所有数据 - console.log('【上传前检查】准备克隆数据'); - const formDataCopy = JSON.parse(JSON.stringify(productData)); - const imagesCopy = JSON.parse(JSON.stringify(images)); - - console.log('【上传前检查】克隆后图片数量:', imagesCopy.length); - console.log('【上传前检查】克隆后图片数据:', imagesCopy); - - // 立即清空表单,避免任何状态变化触发重新编译 - console.log('【上传前检查】清空表单'); - this.setData({ - variety: '', - price: '', - quantity: '', - grossWeight: '', - yolk: '', - specification: '', - images: [] - }); - - // 显示加载提示 - wx.showLoading({ title: '正在上传图片...' }); - - // 【终极修复】使用全局上传管理器处理上传,完全脱离页面生命周期 - // 将所有数据存储到全局对象中,防止被回收 - console.log('【上传前检查】存储数据到全局对象'); - // 从本地存储获取userId,如果不存在则使用默认值 - const userId = wx.getStorageSync('userId') || 'anonymous'; - global.tempUploadData = { - formData: formDataCopy, - images: imagesCopy, - userId: userId, - timestamp: Date.now() - }; - - // 预先生成会话ID,确保所有图片关联同一个商品 - const uploadSessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; - formDataCopy.sessionId = uploadSessionId; - formDataCopy.uploadSessionId = uploadSessionId; - - console.log(`【关键修复】预先生成会话ID:`, uploadSessionId); - console.log(`【上传前检查】准备调用全局上传管理器,图片数量:`, imagesCopy.length); - console.log(`【上传前检查】传递的formData结构:`, Object.keys(formDataCopy)); - - // 【核心修复】直接使用wx.uploadFile API,确保与服务器端测试脚本格式一致 - console.log(`【核心修复】使用wx.uploadFile API直接上传`); - - // 预先生成会话ID - const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; - formDataCopy.sessionId = sessionId; - formDataCopy.uploadSessionId = sessionId; - - console.log(`【核心修复】使用会话ID:`, sessionId); - console.log(`【核心修复】上传图片数量:`, imagesCopy.length); - - // 使用Promise处理上传 - const uploadPromise = new Promise((resolve, reject) => { - // 构建formData,与服务器测试脚本一致 - const formData = { - productData: JSON.stringify(formDataCopy), - sessionId: sessionId, - uploadSessionId: sessionId, - totalImages: imagesCopy.length.toString(), - isSingleUpload: 'false' // 关键参数:标记为多图片上传 - }; - - console.log(`【核心修复】准备上传,formData结构:`, Object.keys(formData)); - console.log(`【核心修复】上传URL:`, API.BASE_URL + '/api/products/upload'); - - // 直接使用wx.uploadFile上传第一张图片 - wx.uploadFile({ - url: API.BASE_URL + '/api/products/upload', - filePath: imagesCopy[0], // 先上传第一张 - name: 'images', - formData: formData, - timeout: 180000, - success: (res) => { - console.log('【核心修复】上传成功,状态码:', res.statusCode); - console.log('【核心修复】原始响应:', res.data); - try { - const data = JSON.parse(res.data); - resolve(data); - } catch (e) { - resolve({data: res.data}); - } - }, - fail: (err) => { - console.error('【核心修复】上传失败:', err); - reject(err); - } - }); - }); - - uploadPromise.then((res) => { - // 上传成功回调 - console.log('【核心修复】上传成功,响应:', res); - - // 使用setTimeout完全隔离回调执行上下文 - setTimeout(() => { - wx.hideLoading(); - - // 从全局临时存储获取数据 - const tempData = global.tempUploadData || {}; - const localFormData = tempData.formData; - const userId = tempData.userId; - - // 【关键修复】从多个来源提取图片URL,确保不丢失 - let allUploadedImageUrls = []; - - // 尝试从多个位置提取图片URLs - if (res.imageUrls && Array.isArray(res.imageUrls) && res.imageUrls.length > 0) { - allUploadedImageUrls = [...res.imageUrls]; - console.log('【全局上传】从res.imageUrls提取到图片:', allUploadedImageUrls.length); - } - - if (res.product && res.product.imageUrls && Array.isArray(res.product.imageUrls) && res.product.imageUrls.length > 0) { - allUploadedImageUrls = [...res.product.imageUrls]; - console.log('【全局上传】从res.product.imageUrls提取到图片:', allUploadedImageUrls.length); - } - - if (res.data && res.data.imageUrls && Array.isArray(res.data.imageUrls) && res.data.imageUrls.length > 0) { - allUploadedImageUrls = [...res.data.imageUrls]; - console.log('【全局上传】从res.data.imageUrls提取到图片:', allUploadedImageUrls.length); - } - - // 去重处理,确保URL不重复 - allUploadedImageUrls = [...new Set(allUploadedImageUrls)]; - - console.log('【全局上传】最终去重后的图片URL列表:', allUploadedImageUrls); - console.log('【全局上传】最终图片数量:', allUploadedImageUrls.length); - - // 获取卖家信息 - const users = wx.getStorageSync('users') || {}; - const sellerName = users[userId] && users[userId].info && (users[userId].info.name || users[userId].info.nickName) ? (users[userId].info.name || users[userId].info.nickName) : '未知卖家'; - - // 保存到本地存储 - setTimeout(() => { - // 获取当前已有的货源列表 - const supplies = wx.getStorageSync('supplies') || []; - const newId = supplies.length > 0 ? Math.max(...supplies.map(s => s.id)) + 1 : 1; - const serverProductId = res.product && res.product.productId ? res.product.productId : ''; - - // 创建新的货源记录 - const newSupply = { - id: newId, - productId: serverProductId, - serverProductId: serverProductId, - name: localFormData.productName, - productName: localFormData.productName, - price: localFormData.price, - minOrder: localFormData.quantity, - yolk: localFormData.yolk, - spec: localFormData.specification, - grossWeight: localFormData.grossWeight !== null ? localFormData.grossWeight : '', - seller: sellerName, - status: res.product && res.product.status ? res.product.status : 'pending_review', - imageUrls: allUploadedImageUrls, - reservedCount: 0, - isReserved: false - }; - - // 保存到supplies和goods本地存储 - supplies.push(newSupply); - wx.setStorageSync('supplies', supplies); - - const goods = wx.getStorageSync('goods') || []; - const newGoodForBuyer = { - id: String(newId), - productId: String(serverProductId), - name: localFormData.productName, - productName: localFormData.productName, - price: localFormData.price, - minOrder: localFormData.quantity, - yolk: localFormData.yolk, - spec: localFormData.specification, - grossWeight: localFormData.grossWeight !== null ? localFormData.grossWeight : '', - displayGrossWeight: localFormData.grossWeight !== null ? localFormData.grossWeight : '', - seller: sellerName, - status: res.product && res.product.status ? res.product.status : 'pending_review', - imageUrls: allUploadedImageUrls, - reservedCount: 0, - isReserved: false - }; - goods.push(newGoodForBuyer); - wx.setStorageSync('goods', goods); - - // 显示成功提示 - setTimeout(() => { - wx.showModal({ - title: '发布成功', - content: `所有${allUploadedImageUrls.length}张图片已成功上传!\n请手动返回查看您的商品。\n\n重要:请勿关闭小程序,等待3-5秒确保所有数据处理完成。`, - showCancel: false, - confirmText: '我知道了', - success: function() { - // 延迟清理全局临时数据,确保所有操作完成 - setTimeout(() => { - if (global.tempUploadData) { - delete global.tempUploadData; - } - }, 5000); - } - }); - }, 500); - }, 500); - }, 100); - }) - .catch((err) => { - // 上传失败回调 - console.error('【核心修复】上传失败:', err); - - // 使用setTimeout隔离错误处理 - setTimeout(() => { - wx.hideLoading(); - - // 直接显示错误提示,不进行登录验证 - wx.showToast({ title: err.message || '发布失败,请重试', icon: 'none' }); - - // 清理全局临时数据 - if (global.tempUploadData) { - delete global.tempUploadData; - } - }, 100); - }); - }, - - /** - * 生命周期函数--监听页面显示 - */ - onShow() { - // 页面显示时可以刷新数据 - }, - - /** - * 选择图片 - 修复版本 - */ - chooseImage: function () { - const that = this; - wx.chooseMedia({ - count: 5 - that.data.images.length, - mediaType: ['image'], - sourceType: ['album', 'camera'], - success: function (res) { - console.log('选择图片成功,返回数据:', res); - const tempFiles = res.tempFiles.map(file => file.tempFilePath); - that.setData({ - images: [...that.data.images, ...tempFiles] - }); - console.log('更新后的图片数组:', that.data.images); - }, - fail: function (err) { - console.error('选择图片失败:', err); - } - }); - }, - - /** - * 删除图片 - */ - deleteImage: function (e) { - const index = e.currentTarget.dataset.index; - const images = this.data.images; - images.splice(index, 1); - this.setData({ - images: images - }); - }, - - /** - * 用户点击右上角分享 - */ - onShareAppMessage: function () { - return { - title: '发布商品 - 又鸟蛋平台', - path: '/pages/publish/index', - imageUrl: '' - }; - }, - - /** - * 用户点击右上角分享到朋友圈 - */ - onShareTimeline: function () { - return { - title: '发布商品 - 又鸟蛋平台', - query: '', - imageUrl: '' - }; - } -}); \ No newline at end of file diff --git a/pages/publish/index.json b/pages/publish/index.json deleted file mode 100644 index 3928faa..0000000 --- a/pages/publish/index.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "usingComponents": {} -} \ No newline at end of file diff --git a/pages/publish/index.wxml b/pages/publish/index.wxml deleted file mode 100644 index e19d1db..0000000 --- a/pages/publish/index.wxml +++ /dev/null @@ -1,54 +0,0 @@ - - - - 发布新货源 - - - - - 品种 * - - - - - 价格 (元/斤) * - - - - - 数量 (斤) * - - - - - 毛重 (斤) - - - - - 蛋黄 - - - - - 规格 - - - - - - 商品图片(最多5张) - - - - × - - - + - - - - - - - \ No newline at end of file diff --git a/pages/publish/index.wxss b/pages/publish/index.wxss deleted file mode 100644 index ab7390d..0000000 --- a/pages/publish/index.wxss +++ /dev/null @@ -1,117 +0,0 @@ -/* pages/publish/index.wxss */ -.publish-container { - padding: 20rpx; - background-color: #f8f8f8; - min-height: 100vh; -} - -.publish-header { - background-color: #fff; - padding: 30rpx; - border-radius: 10rpx; - margin-bottom: 20rpx; - box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); -} - -.header-title { - font-size: 36rpx; - font-weight: bold; - color: #333; -} - -.form-container { - background-color: #fff; - padding: 30rpx; - border-radius: 10rpx; - box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); -} - -.form-item { - margin-bottom: 30rpx; -} - -.label { - display: block; - font-size: 28rpx; - color: #666; - margin-bottom: 10rpx; -} - -.input { - width: 100%; - height: 80rpx; - border: 1rpx solid #ddd; - border-radius: 8rpx; - padding: 0 20rpx; - font-size: 28rpx; - box-sizing: border-box; -} - -/* 图片上传样式 */ -.image-upload-container { - margin-bottom: 30rpx; -} - -.image-list { - display: flex; - flex-wrap: wrap; - gap: 20rpx; -} - -.image-item { - width: 160rpx; - height: 160rpx; - position: relative; - border: 1rpx solid #ddd; - border-radius: 8rpx; - overflow: hidden; -} - -.image-item image { - width: 100%; - height: 100%; -} - -.image-delete { - position: absolute; - top: 0; - right: 0; - width: 40rpx; - height: 40rpx; - background-color: rgba(0, 0, 0, 0.5); - color: #fff; - text-align: center; - line-height: 40rpx; - font-size: 32rpx; - border-radius: 0 8rpx 0 20rpx; -} - -.image-upload { - width: 160rpx; - height: 160rpx; - border: 2rpx dashed #ddd; - border-radius: 8rpx; - display: flex; - justify-content: center; - align-items: center; - background-color: #f8f8f8; -} - -.image-upload text { - font-size: 64rpx; - color: #999; -} - -.publish-btn { - margin-top: 40rpx; - background-color: #07c160; - color: #fff; - font-size: 32rpx; - height: 90rpx; - line-height: 90rpx; - border-radius: 45rpx; -} - -.publish-btn:active { - background-color: #06b356; -} \ No newline at end of file