// pages/seller/index.js const API = require('../../utils/api.js') Page({ data: { supplies: [], publishedSupplies: [], pendingSupplies: [], // 审核中的货源 rejectedSupplies: [], // 审核失败的货源 draftSupplies: [], showModal: false, showEditModal: false, showRejectReasonModal: false, // 控制审核失败原因弹窗显示 currentRejectSupply: null, // 当前显示的审核失败货源 rejectReason: '', // 审核失败原因 showTabBar: true, // 控制底部自定义tab-bar的显示状态 showSpecSelectModal: false, // 控制规格选择弹窗显示 modalSpecSearchKeyword: '', // 规格弹窗中的搜索关键词 filteredModalSpecOptions: [], // 弹窗中过滤后的规格选项 selectedModalSpecIndex: -1, // 弹窗中选中的规格索引 currentSpecMode: 'create', // 当前规格选择模式:create 或 edit showNameSelectModal: false, // 控制商品名称选择弹窗显示 showYolkSelectModal: false, // 控制蛋黄选择弹窗显示 selectedNameIndex: -1, // 商品名称弹窗中选中的索引 selectedYolkIndex: -1,//蛋黄弹窗中选中的索引, // 商品名称选项列表 productNameOptions: ['罗曼粉', '伊莎粉', '罗曼灰', '海蓝灰', '海蓝褐', '绿壳', '粉一', '粉二', '粉八', '京粉1号', '京红', '京粉6号', '京粉3号', '农大系列', '黑鸡土蛋', '双黄蛋', '大午金凤', '黑凤'], // 蛋黄选项 yolkOptions: ['红心', '黄心', '双色'], // 规格选项 specOptions: ['格子装', '散托', '不限规格','净重47+', '净重46-47', '净重45-46', '净重44-45', '净重43-44', '净重42-43', '净重41-42', '净重40-41', '净重39-40', '净重38-39', '净重37-39','净重37-38' , '净重36-38', '净重36-37', '净重35-36', '净重34-35', '净重33-34', '净重32-33', '净重32-34', '净重31-32', '净重30-35', '净重30-34', '净重30-32', '净重30-31', '净重29-31', '净重29-30', '净重28-29', '净重28以下', '毛重52以上', '毛重50-51', '毛重48-49', '毛重47-48', '毛重46-47', '毛重45-47', '毛重45-46', '毛重44-45', '毛重43-44', '毛重42-43', '毛重41-42', '毛重40-41', '毛重38-39', '毛重36-37', '毛重34-35', '毛重32-33', '毛重30-31', '毛重30以下'], // 规格搜索相关变量 specSearchKeyword: '', // 创建货源弹窗中的规格搜索关键词 editSpecSearchKeyword: '', // 编辑货源弹窗中的规格搜索关键词 filteredSpecOptions: [], // 过滤后的规格选项数组 filteredEditSpecOptions: [], // 编辑货源过滤后的规格选项数组 newSupply: { name: '', // 品种 price: '', minOrder: '', yolk: '', // 蛋黄字段 yolkIndex: 0, // 蛋黄选项索引 spec: '', // 规格字段 specIndex: 0, // 规格选项索引 region: '', // 【新增】地区字段 grossWeight: '', // 【新增】毛重字段,支持中文 imageUrls: [] // 图片URL数组,支持多张图片 }, newSupplyRegionArray: [], // 新创建货源的省市区数组 editSupplyRegionArray: [], // 编辑货源的省市区数组, editSupply: { yolkIndex: 0, specIndex: 0 }, currentImageIndex: 0, // 用于滑动时记录当前图片索引 searchKeyword: '', // 搜索关键词 // 图片缩放相关数据 scale: 1, // 缩放比例 offsetX: 0, // X轴偏移 offsetY: 0, // Y轴偏移 lastDistance: 0, // 上一次两指距离 lastTouchPoint: null, // 上一次触摸点 imageWidth: 375, // 图片原始宽度 imageHeight: 375, // 图片原始高度 minScale: 1, // 最小缩放比例 maxScale: 4, // 最大缩放比例 doubleTapTimeout: null, // 双击超时计时器 doubleTapCount: 0, // 双击计数 // 分页相关数据 pagination: { published: { page: 1, pageSize: 20, hasMore: true, loading: false }, pending: { page: 1, pageSize: 20, hasMore: true, loading: false }, rejected: { page: 1, pageSize: 20, hasMore: true, loading: false }, draft: { page: 1, pageSize: 20, hasMore: true, loading: false } }, // 当前正在加载的状态类型 currentLoadingType: null, // 图片预览相关状态 showImagePreview: false, // 控制图片预览弹窗显示 previewImageUrls: [], // 预览的图片URL列表 previewImageIndex: 0, // 当前预览图片的索引 // 折叠状态控制 isPublishedExpanded: true, // 已上架货源是否展开 isPendingExpanded: true, // 审核中货源是否展开 isRejectedExpanded: true, // 审核失败货源是否展开 isDraftExpanded: true, // 下架状态货源是否展开 // 自动发布控制 autoPublishAfterEdit: false, // 编辑后是否自动发布(上架) // 页面加载状态控制 _hasLoadedOnShow: false, // 标记onShow是否已经加载过数据 // 页面滚动锁定状态 pageScrollLock: false, // 控制页面是否锁定滚动 touchMoveBlocked: false, // iOS设备触摸事件阻止 // 授权登录相关状态 showAuthModal: false, // 控制未授权提示弹窗显示 showOneKeyLoginModal: false, // 控制一键登录弹窗显示 pendingUserType: 'seller', // 记录用户即将选择的身份类型 avatarUrl: '/images/default-avatar.png', // 默认头像 partnerstatus: '' // 用户入驻状态,用于显示入驻/未入驻 }, onLoad() { console.log('卖家页面onLoad开始执行'); // 移除强制登录检查,允许用户浏览货源页面 this.loadSupplies(); // 初始化规格搜索相关数据 this.setData({ specSearchKeyword: '', editSpecSearchKeyword: '', filteredSpecOptions: this.data.specOptions, filteredEditSpecOptions: this.data.specOptions }); // 尝试从本地存储加载草稿数据 const draftData = wx.getStorageSync('newSupplyDraft'); if (draftData) { this.setData({ newSupply: draftData }); console.log('从本地存储加载了草稿数据'); } console.log('卖家页面onLoad执行完毕'); }, // 重新登录方法 - 跳转到登录页面 reLogin() { console.log('执行reLogin方法,跳转到登录页面'); wx.showToast({ title: '请先登录', icon: 'none', duration: 2000, complete: () => { setTimeout(() => { wx.switchTab({ url: '/pages/index/index' }); }, 2000); } }); }, // 轮播图切换事件 swiperChange: function (e) { const current = e.detail.current; const id = e.currentTarget.dataset.id; if (!id) { console.error('swiperChange: 缺少商品ID'); return; } console.log(`商品 ${id} 的轮播图切换到第 ${current} 张`); // 更新特定商品的当前图片索引 this.updateProductCurrentIndex(id, current); }, // 更新商品当前图片索引 updateProductCurrentIndex: function (productId, index) { // 更新所有货源列表中的对应商品 const updateSupplies = (supplies) => { return supplies.map(supply => { if (supply.id === productId) { return { ...supply, currentImageIndex: index }; } return supply; }); }; this.setData({ supplies: updateSupplies(this.data.supplies), publishedSupplies: updateSupplies(this.data.publishedSupplies), pendingSupplies: updateSupplies(this.data.pendingSupplies), rejectedSupplies: updateSupplies(this.data.rejectedSupplies), draftSupplies: updateSupplies(this.data.draftSupplies) }); }, // 切换已上架货源的折叠状态 togglePublishedExpand() { this.setData({ isPublishedExpanded: !this.data.isPublishedExpanded }); }, // 切换审核中货源的折叠状态 togglePendingExpand() { this.setData({ isPendingExpanded: !this.data.isPendingExpanded }); }, // 切换审核失败货源的折叠状态 toggleRejectedExpand() { this.setData({ isRejectedExpanded: !this.data.isRejectedExpanded }); }, // 切换下架状态货源的折叠状态 toggleDraftExpand() { this.setData({ isDraftExpanded: !this.data.isDraftExpanded }); }, // 清除搜索 clearSearch() { this.setData({ searchKeyword: '' }, () => { // 重新加载所有数据 this.loadSupplies(); }); }, // 处理搜索输入 onSearchInput(e) { this.setData({ searchKeyword: e.detail.value }); }, // 搜索货源 searchSupplies() { console.log('搜索货源,关键词:', this.data.searchKeyword); // 根据搜索关键词过滤所有状态的货源 const keyword = this.data.searchKeyword.toLowerCase().trim(); if (!keyword) { // 如果关键词为空,重新加载所有数据 this.loadSupplies(); return; } // 获取所有货源 const allSupplies = this.data.supplies; // 过滤符合条件的货源 const filteredSupplies = allSupplies.filter(supply => { // 搜索名称、品种等字段 const name = (supply.name || '').toLowerCase(); const productName = (supply.productName || '').toLowerCase(); const yolk = (supply.yolk || '').toLowerCase(); const spec = (supply.spec || '').toLowerCase(); return name.includes(keyword) || productName.includes(keyword) || yolk.includes(keyword) || spec.includes(keyword); }); // 将过滤后的货源按照状态分类 const publishedSupplies = filteredSupplies.filter(s => s.status === 'published'); const pendingSupplies = filteredSupplies.filter(s => s.status === 'pending_review'); const rejectedSupplies = filteredSupplies.filter(s => s.status === 'rejected'); const draftSupplies = filteredSupplies.filter(s => s.status === 'draft'); // 更新UI显示 this.setData({ publishedSupplies, pendingSupplies, rejectedSupplies, draftSupplies }); // 显示搜索结果提示 wx.showToast({ title: `找到${filteredSupplies.length}个货源`, icon: 'none', duration: 1500 }); }, // 下拉刷新处理函数 onPullDownRefresh() { console.log('====== 触发下拉刷新 ======'); // 重新加载所有货源数据 this.loadSupplies() .then(() => { console.log('下拉刷新数据加载成功'); wx.showToast({ title: '刷新成功', icon: 'success', duration: 1500 }); }) .catch(err => { console.error('下拉刷新数据加载失败:', err); wx.showToast({ title: '刷新失败,请重试', icon: 'none', duration: 2000 }); }) .finally(() => { console.log('====== 下拉刷新动画停止 ======'); wx.stopPullDownRefresh(); }); }, onShow() { console.log('seller页面onShow开始加载') // 获取用户入驻状态 this.getUserStatus(); // 检查页面是否是初次加载(onLoad已调用loadSupplies) // 避免在页面初次加载时重复加载数据 if (!this.data._hasLoadedOnShow) { this.setData({ _hasLoadedOnShow: true }); // 为了避免onLoad和onShow的重复加载,这里不立即调用 // 而是在短暂延迟后调用,确保不会与onLoad的加载冲突 setTimeout(() => { this.loadSupplies(); }, 500); } else { // 页面不是初次显示,正常加载数据 this.loadSupplies(); } // 更新自定义tabBar状态 if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().setData({ selected: 2 }); } // 更新全局tab状态 const app = getApp(); app.updateCurrentTab('seller'); }, // 获取用户入驻状态 getUserStatus() { const openid = wx.getStorageSync('openid'); if (openid) { API.getUserInfo(openid) .then(response => { console.log('获取到的用户信息响应:', response); // 修复:访问data字段获取用户信息 const userInfo = response.data || {}; console.log('处理后的用户信息:', userInfo); this.setData({ partnerstatus: userInfo.partnerstatus || '' }); }) .catch(err => { console.error('获取用户信息失败:', err); }); } }, // 加载货源列表并分类 - 修改为分页加载 loadSupplies() { console.log('开始加载货源数据 - 分页模式'); // 重置所有分页状态 this.resetAllPagination(); // 并行加载所有类型的货源 return Promise.all([ this.loadSuppliesFromServer('published', 1), this.loadSuppliesFromServer('pending', 1), this.loadSuppliesFromServer('rejected', 1), this.loadSuppliesFromServer('draft', 1) ]).then(results => { console.log('所有类型货源加载完成'); return results; }).catch(err => { console.error('加载货源失败:', err); throw err; }); }, // 重置所有分页状态 resetAllPagination() { this.setData({ 'pagination.published.page': 1, 'pagination.published.hasMore': true, 'pagination.published.loading': false, 'pagination.pending.page': 1, 'pagination.pending.hasMore': true, 'pagination.pending.loading': false, 'pagination.rejected.page': 1, 'pagination.rejected.hasMore': true, 'pagination.rejected.loading': false, 'pagination.draft.page': 1, 'pagination.draft.hasMore': true, 'pagination.draft.loading': false, currentLoadingType: null }); }, // 搜索货源 - 修改为使用本地数据 searchSupplies() { console.log('搜索货源,关键词:', this.data.searchKeyword); const keyword = this.data.searchKeyword.toLowerCase().trim(); if (!keyword) { // 如果关键词为空,重新加载所有数据 this.loadSupplies(); return; } // 从所有货源中搜索 const allSupplies = this.data.supplies; // 过滤符合条件的货源 const filteredSupplies = allSupplies.filter(supply => { const name = (supply.name || '').toLowerCase(); const productName = (supply.productName || '').toLowerCase(); const yolk = (supply.yolk || '').toLowerCase(); const spec = (supply.spec || '').toLowerCase(); return name.includes(keyword) || productName.includes(keyword) || yolk.includes(keyword) || spec.includes(keyword); }); // 将过滤后的货源按照状态分类 const publishedSupplies = filteredSupplies.filter(s => s.status === 'published'); const pendingSupplies = filteredSupplies.filter(s => s.status === 'pending_review' || s.status === 'reviewed'); const rejectedSupplies = filteredSupplies.filter(s => s.status === 'rejected'); const draftSupplies = filteredSupplies.filter(s => s.status === 'draft' || s.status === 'sold_out'); // 更新UI显示 this.setData({ publishedSupplies, pendingSupplies, rejectedSupplies, draftSupplies }); // 显示搜索结果提示 wx.showToast({ title: `找到${filteredSupplies.length}个货源`, icon: 'none', duration: 1500 }); }, // 修改图片URL处理函数 processImageUrls: function (imageUrls) { if (!imageUrls || !Array.isArray(imageUrls)) { return []; } return imageUrls.map(url => { if (!url || typeof url !== 'string') return ''; let processedUrl = url.trim(); // 处理占位符URL - 替换为本地默认图片 if (processedUrl.startsWith('placeholder://')) { console.log('检测到占位符URL,替换为默认图片:', processedUrl); return '/images/default-product.png'; // 使用本地默认图片 } // 处理临时文件路径 if (processedUrl.startsWith('http://tmp/') || processedUrl.startsWith('wxfile://')) { console.log('检测到临时文件路径,保持原样:', processedUrl); return processedUrl; } // 确保HTTP URL格式正确 if (processedUrl.startsWith('//')) { processedUrl = 'https:' + processedUrl; } else if (!processedUrl.startsWith('http') && !processedUrl.startsWith('/')) { // 如果是相对路径但没有斜杠,添加斜杠 processedUrl = '/' + processedUrl; } return processedUrl; }).filter(url => url && url !== ''); }, // 直接从服务器获取货源数据并显示 - 支持分页 loadSuppliesFromServer(type = 'all', page = 1) { return new Promise((resolve, reject) => { const openid = wx.getStorageSync('openid'); console.log(`loadSuppliesFromServer - type: ${type}, page: ${page}, openid:`, openid); if (!openid) { console.warn('openid不存在,显示空数据状态,允许用户浏览页面'); // 未登录状态下显示空数据,不跳转,允许用户浏览页面 this.setData({ supplies: [], publishedSupplies: [], pendingSupplies: [], rejectedSupplies: [], draftSupplies: [] }); resolve([]); return; } console.log(`开始从服务器获取${type}类型商品数据,第${page}页`); // 根据类型设置请求参数 let status = []; let pageSize = 20; switch (type) { case 'published': status = ['published']; pageSize = this.data.pagination.published.pageSize; this.setData({ 'pagination.published.loading': true, currentLoadingType: 'published' }); break; case 'pending': status = ['pending_review', 'reviewed']; pageSize = this.data.pagination.pending.pageSize; this.setData({ 'pagination.pending.loading': true, currentLoadingType: 'pending' }); break; case 'rejected': status = ['rejected']; pageSize = this.data.pagination.rejected.pageSize; this.setData({ 'pagination.rejected.loading': true, currentLoadingType: 'rejected' }); break; case 'draft': status = ['draft', 'sold_out']; pageSize = this.data.pagination.draft.pageSize; this.setData({ 'pagination.draft.loading': true, currentLoadingType: 'draft' }); break; default: // 全部加载,不分类型 status = ['all']; pageSize = 100; // 初始加载时使用较大值 } const requestData = { openid: openid, viewMode: 'seller', status: status, page: page, pageSize: pageSize }; console.log('请求参数:', requestData); API.getAllSupplies(requestData) .then(res => { console.log(`从服务器获取${type}类型数据响应:`, res); if (res && res.success && res.products) { console.log(`从服务器获取到${type}类型商品数据,共`, res.products.length, '条'); // 处理服务器返回的商品数据 const serverSupplies = res.products .filter(product => product.status !== 'hidden') .map(serverProduct => { // 状态映射 const mappedStatus = serverProduct.status; // 处理图片URL let imageUrls = this.processImageUrls(serverProduct.imageUrls); // 处理创建时间 const createdAt = serverProduct.created_at || null; const formattedCreatedAt = this.formatCreateTime(createdAt); return { id: serverProduct.productId, name: serverProduct.productName, price: serverProduct.price, minOrder: serverProduct.quantity, grossWeight: serverProduct.grossWeight, yolk: serverProduct.yolk, spec: serverProduct.specification, region: serverProduct.region || '未知地区', // 【修复】添加默认地区 serverProductId: serverProduct.productId, status: mappedStatus, rejectReason: serverProduct.rejectReason || '', imageUrls: imageUrls, created_at: createdAt, formattedCreatedAt: formattedCreatedAt, currentImageIndex: 0 }; }); // 根据类型更新数据 this.updateSuppliesByType(type, serverSupplies, res, page); resolve(serverSupplies); } else { console.log(`服务器没有返回${type}类型商品数据或返回格式不正确`); this.handleNoData(type); resolve([]); } }) .catch(err => { console.error(`从服务器获取${type}类型数据失败:`, err); this.handleLoadError(type, err); reject(err); }) .finally(() => { // 重置加载状态 this.resetLoadingState(type); }); }); }, // 根据类型更新货源数据 updateSuppliesByType(type, newSupplies, response, currentPage) { const paginationKey = `pagination.${type}`; // 更新分页信息 const hasMore = currentPage < (response.totalPages || 1); this.setData({ [`${paginationKey}.hasMore`]: hasMore, [`${paginationKey}.page`]: currentPage }); // 更新货源列表 if (currentPage === 1) { // 第一页,直接替换 this.setData({ [`${type}Supplies`]: newSupplies }); } else { // 后续页面,追加数据 const existingSupplies = this.data[`${type}Supplies`] || []; const updatedSupplies = [...existingSupplies, ...newSupplies]; this.setData({ [`${type}Supplies`]: updatedSupplies }); } // 更新总列表(用于搜索等功能) this.updateAllSupplies(); console.log(`更新${type}类型货源完成,当前数量:`, this.data[`${type}Supplies`].length, '是否有更多:', hasMore); }, // 更新所有货源列表(用于搜索) updateAllSupplies() { const allSupplies = [ ...this.data.publishedSupplies, ...this.data.pendingSupplies, ...this.data.rejectedSupplies, ...this.data.draftSupplies ]; this.setData({ supplies: allSupplies }); }, // 处理无数据情况 handleNoData(type) { const paginationKey = `pagination.${type}`; this.setData({ [`${paginationKey}.hasMore`]: false, [`${type}Supplies`]: [] }); }, // 处理加载错误 handleLoadError(type, err) { const paginationKey = `pagination.${type}`; this.setData({ [`${paginationKey}.loading`]: false }); // 检查是否是用户不存在的错误 if (err.message && (err.message.includes('404') || err.message.includes('用户不存在'))) { console.log('用户不存在,跳转到登录页面'); wx.showToast({ title: '用户不存在,请重新登录', icon: 'none', duration: 2000, success: () => { wx.removeStorageSync('openid'); wx.removeStorageSync('userInfo'); setTimeout(() => { wx.switchTab({ url: '/pages/index/index' }); }, 2000); } }); } }, // 重置加载状态 resetLoadingState(type) { if (type !== 'all') { this.setData({ [`pagination.${type}.loading`]: false, currentLoadingType: null }); } }, // 加载更多货源 loadMoreSupplies(type) { const pagination = this.data.pagination[type]; if (!pagination.hasMore || pagination.loading) { console.log(`没有更多${type}类型数据或正在加载中`); return; } console.log(`开始加载更多${type}类型数据,当前页码:`, pagination.page); const nextPage = pagination.page + 1; this.loadSuppliesFromServer(type, nextPage) .then(() => { console.log(`加载更多${type}类型数据成功`); }) .catch(err => { console.error(`加载更多${type}类型数据失败:`, err); wx.showToast({ title: '加载失败,请重试', icon: 'none', duration: 2000 }); }); }, // 已上架货源加载更多 onReachPublishedBottom() { console.log('已上架货源滚动到底部,加载更多'); this.loadMoreSupplies('published'); }, // 审核中货源加载更多 onReachPendingBottom() { console.log('审核中货源滚动到底部,加载更多'); this.loadMoreSupplies('pending'); }, // 审核失败货源加载更多 onReachRejectedBottom() { console.log('审核失败货源滚动到底部,加载更多'); this.loadMoreSupplies('rejected'); }, // 下架状态货源加载更多 onReachDraftBottom() { console.log('下架状态货源滚动到底部,加载更多'); this.loadMoreSupplies('draft'); }, // 从服务器同步最新的商品数据 (现在直接使用服务器数据,不再保存到本地存储) syncSuppliesFromServer() { // 调用新的直接从服务器获取数据的方法 console.log('syncSuppliesFromServer: 直接从服务器获取最新数据'); this.loadSuppliesFromServer(); }, // 从本地存储加载货源数据(已废弃,现在直接从服务器获取) loadSuppliesFromLocal() { console.log('loadSuppliesFromLocal: 已废弃,现在直接从服务器获取数据'); this.loadSuppliesFromServer(); }, // 同步货源数据到商品列表 - 移除本地存储操作 syncSuppliesToGoods(supplies) { try { console.log('开始同步货源数据到商品列表 - 通过服务器同步') // 直接通知服务器同步已上架商品,不操作本地存储 // 修复:移除supply.status === 'reviewed',reviewed状态不应被视为已上架 const publishedSupplies = supplies.filter(supply => supply.status === 'published' ); if (publishedSupplies.length > 0) { // 延迟一小段时间,避免与服务器交互过于频繁 setTimeout(() => { // 这里应该有一个API调用,通知服务器同步商品 // API.syncPublishedSuppliesToGoods(publishedSupplies) // .then(res => { // console.log('服务器同步商品成功:', res) // }) // .catch(err => { // console.error('服务器同步商品失败:', err) // }) console.log('已上架商品:', publishedSupplies) }, 500); } } catch (error) { console.error('同步货源到商品列表过程中发生错误:', error) } }, // 显示一键登录弹窗 showOneKeyLogin() { this.setData({ showAuthModal: false, showOneKeyLoginModal: true }) }, // 关闭未授权提示弹窗 closeAuthModal() { this.setData({ showAuthModal: false }) }, // 关闭一键登录弹窗 closeOneKeyLoginModal() { this.setData({ showOneKeyLoginModal: false }) }, // 选择头像 onChooseAvatar(e) { const { avatarUrl } = e.detail this.setData({ avatarUrl }) }, // 处理昵称提交 getUserName(e) { const { nickname } = e.detail.value const type = 'seller' // 卖家页面固定为卖家类型 if (!nickname) { wx.showToast({ title: '请输入昵称', icon: 'none', duration: 2000 }) return } // 创建用户信息对象 const userInfo = { nickName: nickname, avatarUrl: this.data.avatarUrl, gender: 0, country: '', province: '', city: '', language: 'zh_CN' } // 保存用户信息 this.saveUserInfo(userInfo, type) // 隐藏表单 this.setData({ showUserInfoForm: false }) // 完成设置 this.finishSetUserType(type) }, // 取消用户信息表单 cancelUserInfoForm() { this.setData({ showUserInfoForm: false }) wx.hideLoading() }, // 处理手机号授权 async onGetPhoneNumber(e) { // 打印详细错误信息,方便调试 console.log('getPhoneNumber响应:', e.detail) // 关闭手机号授权弹窗 this.setData({ showOneKeyLoginModal: false }) // 用户点击拒绝授权 if (e.detail.errMsg === 'getPhoneNumber:fail user deny') { wx.showToast({ title: '需要授权手机号才能使用', icon: 'none', duration: 2000 }) return } // 处理没有权限的情况 if (e.detail.errMsg === 'getPhoneNumber:fail no permission') { wx.showToast({ title: '当前环境无法获取手机号权限', icon: 'none', duration: 3000 }) console.warn('获取手机号权限失败: 请注意,微信小程序获取手机号功能需要满足以下条件:1. 小程序必须完成微信企业认证;2. 需要在小程序后台配置相应权限;3. 必须使用button组件的open-type="getPhoneNumber"触发。') return } // 检查是否已经登录,避免重复授权 const existingOpenid = wx.getStorageSync('openid') const existingUserId = wx.getStorageSync('userId') const existingUserInfo = wx.getStorageSync('userInfo') if (existingOpenid && existingUserId && existingUserInfo && existingUserInfo.phoneNumber) { console.log('用户已登录且手机号有效,直接完成身份设置') // 直接完成身份设置,跳过重复授权 const currentUserType = this.data.pendingUserType || 'seller' this.finishSetUserType(currentUserType) return } wx.showLoading({ title: '登录中...', mask: true }) try { if (e.detail.errMsg === 'getPhoneNumber:ok') { // 用户同意授权,实际处理授权流程 console.log('用户同意授权获取手机号') // 1. 先执行微信登录获取code const loginRes = await new Promise((resolve, reject) => { wx.login({ success: resolve, fail: reject }) }) if (!loginRes.code) { throw new Error('获取登录code失败') } console.log('获取登录code成功:', loginRes.code) // 2. 使用code换取openid const openidRes = await API.getOpenid(loginRes.code) let openid = null; let userId = null; console.log('openidRes完整响应:', JSON.stringify(openidRes)); if (openidRes && typeof openidRes === 'object') { if (openidRes.data && typeof openidRes.data === 'object') { console.log('识别到标准服务器返回格式,从data字段提取信息'); openid = openidRes.data.openid || openidRes.data.OpenID || null; userId = openidRes.data.userId || null; } else { console.log('尝试从根对象直接提取openid'); openid = openidRes.openid || openidRes.OpenID || null; userId = openidRes.userId || null; } } if (!openid) { console.error('无法从服务器响应中提取openid,完整响应:', JSON.stringify(openidRes)); throw new Error(`获取openid失败: 服务器返回数据格式可能不符合预期,请检查服务器配置。响应数据为: ${JSON.stringify(openidRes)}`); } console.log('获取openid成功:', openid) // 3. 存储openid和session_key wx.setStorageSync('openid', openid) if (openidRes && openidRes.session_key) { wx.setStorageSync('sessionKey', openidRes.session_key) } else if (openidRes && openidRes.data && openidRes.data.session_key) { wx.setStorageSync('sessionKey', openidRes.data.session_key) } if (userId) { wx.setStorageSync('userId', userId) console.log('使用从服务器data字段提取的userId:', userId) } else if (openidRes && openidRes.userId) { wx.setStorageSync('userId', openidRes.userId) console.log('使用服务器根对象中的userId:', openidRes.userId) } else { const tempUserId = 'user_' + Date.now() wx.setStorageSync('userId', tempUserId) console.log('生成临时userId:', tempUserId) } // 4. 上传手机号加密数据到服务器解密 const phoneData = { ...e.detail, openid: openid } console.log('准备上传手机号加密数据到服务器') const phoneRes = await API.uploadPhoneNumberData(phoneData) if (!phoneRes || (!phoneRes.success && !phoneRes.phoneNumber)) { if (phoneRes && phoneRes.phoneNumber) { console.warn('服务器返回格式可能不符合预期,但成功获取手机号'); } else { throw new Error('获取手机号失败: ' + (phoneRes && phoneRes.message ? phoneRes.message : '未知错误')) } } const hasPhoneConflict = phoneRes.phoneNumberConflict || false const isNewPhone = phoneRes.isNewPhone || true const phoneNumber = phoneRes.phoneNumber || null const finalPhoneNumber = phoneNumber console.log('手机号解密结果:', { phoneNumber: finalPhoneNumber, hasPhoneConflict: hasPhoneConflict, isNewPhone: isNewPhone }) // 5. 创建临时用户信息并保存 const tempUserInfo = { nickName: '微信用户', avatarUrl: this.data.avatarUrl, gender: 0, country: '', province: '', city: '', language: 'zh_CN', phoneNumber: finalPhoneNumber } const storedUserId = wx.getStorageSync('userId') const currentUserType = this.data.pendingUserType || 'seller' console.log('用户身份类型:', currentUserType) if (this.data.pendingUserType) { this.setData({ pendingUserType: null }) } // 保存用户信息并等待上传完成 console.log('开始保存用户信息并上传到服务器...') const uploadResult = await this.saveUserInfo(tempUserInfo, currentUserType) console.log('用户信息保存并上传完成') wx.hideLoading() if (uploadResult && uploadResult.phoneNumberConflict) { wx.showToast({ title: '登录成功,但手机号已被其他账号绑定', icon: 'none', duration: 3000 }) } else { wx.showToast({ title: '登录成功,手机号已绑定', icon: 'success', duration: 2000 }) } // 完成设置并跳转 this.finishSetUserType(currentUserType) } else { console.log('手机号授权失败:', e.detail.errMsg) wx.hideLoading() wx.showToast({ title: '需要授权手机号才能使用', icon: 'none', duration: 2000 }) return } } catch (error) { wx.hideLoading() console.error('登录过程中发生错误:', error) let errorMsg = '登录失败,请重试' if (error.message.includes('网络')) { errorMsg = '网络连接失败,请检查网络后重试' } else if (error.message.includes('服务器')) { errorMsg = '服务器连接失败,请稍后重试' } wx.showToast({ title: errorMsg, icon: 'none', duration: 3000 }) try { wx.removeStorageSync('openid') wx.removeStorageSync('sessionKey') wx.removeStorageSync('userId') } catch (e) { console.error('清除临时登录信息失败:', e) } } }, // 保存用户信息 async saveUserInfo(userInfo, type) { try { // 获取userId const userId = wx.getStorageSync('userId') // 保存用户信息到本地存储 wx.setStorageSync('userInfo', userInfo) // 更新用户类型信息 let users = wx.getStorageSync('users') || {} users[userId] = { ...users[userId], type: type, userInfo: userInfo, lastLoginTime: Date.now() } wx.setStorageSync('users', users) console.log('用户信息保存成功:', userInfo) // 上传用户信息到服务器 return await this.uploadUserInfoToServer(userInfo, userId, type) } catch (error) { console.error('保存用户信息失败:', error) throw error } }, // 上传用户信息到服务器 async uploadUserInfoToServer(userInfo, userId, type) { const openid = wx.getStorageSync('openid') const uploadData = { userId: userId, openid: openid, ...userInfo, type: type, timestamp: Date.now() } try { const res = await API.uploadUserInfo(uploadData) console.log('用户信息上传成功:', res) // 入驻成功后,将用户类型设置为seller API.updateUserType('seller'); return res } catch (err) { console.error('用户信息上传失败:', err) return { success: true, message: '本地登录成功,服务器连接失败' } } }, // 完成用户类型设置并跳转 finishSetUserType(type) { const userId = wx.getStorageSync('userId') // 更新用户类型 let users = wx.getStorageSync('users') if (typeof users !== 'object' || users === null) { users = {} } if (!users[userId]) { users[userId] = {} } users[userId].type = type wx.setStorageSync('users', users) // 打标签 let tags = wx.getStorageSync('tags') if (typeof tags !== 'object' || tags === null) { tags = {} } tags[userId] = tags[userId] || [] tags[userId] = tags[userId].filter(tag => !tag.startsWith('身份:')) tags[userId].push(`身份:${type}`) wx.setStorageSync('tags', tags) console.log('用户类型设置完成,准备跳转到', type === 'buyer' ? '买家页面' : '卖家页面') setTimeout(() => { if (type === 'buyer') { wx.switchTab({ url: '/pages/buyer/index' }) } else { // 卖家登录成功后,重新显示创建货源弹窗 // 从本地存储加载保存的表单数据 const savedSupply = wx.getStorageSync('newSupplyDraft') || { name: '', price: '', minOrder: '', yolk: '', spec: '', imageUrls: [] }; this.setData({ showImagePreview: false, showModal: true, newSupply: savedSupply }); this.disablePageScroll(); } }, 500) }, // 显示添加货源弹窗 showAddSupply(e) { console.log('点击创建新货源按钮'); // 阻止事件冒泡,防止触发父元素的点击事件 if (e && e.stopPropagation) { e.stopPropagation(); } // 从本地存储加载之前保存的货源数据 const savedSupply = wx.getStorageSync('newSupplyDraft') || { name: '', price: '', minOrder: '', yolk: '', spec: '', imageUrls: [] }; // 直接显示创建货源弹窗,无需登录验证 this.setData({ showImagePreview: false, showModal: true, newSupply: savedSupply }); // 锁定页面滚动 this.disablePageScroll(); }, // 隐藏弹窗 hideModal() { this.setData({ showModal: false, showImagePreview: false // 确保图片预览弹窗关闭 }) // 恢复页面滚动 this.enablePageScroll() }, // 隐藏编辑弹窗 hideEditModal() { this.setData({ showEditModal: false }) // 恢复页面滚动 this.enablePageScroll() }, // 禁用页面滚动 disablePageScroll() { // 获取页面实例并设置样式来禁用滚动 const pages = getCurrentPages() const currentPage = pages[pages.length - 1] if (currentPage) { currentPage.setData({ pageScrollLock: true }) } // iOS设备特殊处理:阻止触摸事件 if (this.isIOS()) { this.blockTouchMove() } }, // 启用页面滚动 enablePageScroll() { // 获取页面实例并恢复滚动 const pages = getCurrentPages() const currentPage = pages[pages.length - 1] if (currentPage) { currentPage.setData({ pageScrollLock: false }) } // iOS设备特殊处理:恢复触摸事件 if (this.isIOS()) { this.unblockTouchMove() } }, // 输入内容处理 onInput(e) { const field = e.currentTarget.dataset.field const value = e.detail.value const newSupply = this.data.newSupply newSupply[field] = value this.setData({ newSupply }) // 实时保存到本地存储 wx.setStorageSync('newSupplyDraft', newSupply); }, // 编辑输入处理 onEditInput(e) { const field = e.currentTarget.dataset.field const value = e.detail.value // 创建一个新的对象,而不是直接修改data中的对象 this.setData({ editSupply: { ...this.data.editSupply, [field]: value } }) }, // 新创建货源地区选择处理 onNewSupplyRegionChange(e) { const regionArray = e.detail.value const region = regionArray.join(' ') this.setData({ newSupplyRegionArray: regionArray, newSupply: { ...this.data.newSupply, region: region } }) // 实时保存到本地存储 wx.setStorageSync('newSupplyDraft', this.data.newSupply); }, // 编辑货源地区选择处理 onEditSupplyRegionChange(e) { const regionArray = e.detail.value const region = regionArray.join(' ') this.setData({ editSupplyRegionArray: regionArray, editSupply: { ...this.data.editSupply, region: region } }) }, // 处理蛋黄选择变更 onYolkChange(e) { const index = e.detail.value const yolk = this.data.yolkOptions[index] this.setData({ 'newSupply.yolkIndex': index, 'newSupply.yolk': yolk }) }, // 处理规格选择变更 - 现在直接打开自定义弹窗 onSpecChange(e) { // 由于我们使用自定义弹窗,这个函数现在只需要打开弹窗即可 this.openSpecSelectModal({ currentTarget: { dataset: { mode: 'create' } } }); }, // 处理编辑模式下的蛋黄选择变更 onEditYolkChange(e) { console.warn('此方法已弃用,请使用openYolkSelectModal替代'); }, // 处理编辑模式下的规格选择变更 - 现在直接打开自定义弹窗 onEditSpecChange(e) { // 由于我们使用自定义弹窗,这个函数现在只需要打开弹窗即可 this.openSpecSelectModal({ currentTarget: { dataset: { mode: 'edit' } } }); }, // 商品名称选择变化处理 onNameChange(e) { const index = e.detail.value const productName = this.data.productNameOptions[index] const newSupply = this.data.newSupply newSupply.name = productName this.setData({ newSupply }) }, // 编辑商品名称选择变化处理 onEditNameChange(e) { console.warn('此方法已弃用,请使用openNameSelectModal替代'); }, // 添加新货源 - 先创建商品再上传图片(修复版) addSupply() { // 检查登录状态 const userId = wx.getStorageSync('userId'); const openid = wx.getStorageSync('openid'); const userInfo = wx.getStorageSync('userInfo'); if (!userId || !openid || !userInfo) { console.log('用户未登录,显示登录提示'); // 登录前保存当前表单数据到本地存储 wx.setStorageSync('newSupplyDraft', this.data.newSupply); // 用户未登录,显示未授权提示弹窗 wx.showModal({ title: '登录提示', content: '请先登录再发布商品', showCancel: true, confirmText: '去登录', success: (res) => { if (res.confirm) { // 用户点击确定,跳转到登录页面或显示登录弹窗 this.setData({ showAuthModal: true, pendingUserType: 'seller' }); } } }); return; } const { name, price, minOrder, yolk, spec, region, imageUrls } = this.data.newSupply if (!name || !price || !minOrder || !yolk) { wx.showToast({ title: '请填写完整信息', icon: 'none', duration: 2000 }) return } // 显示加载中提示 wx.showLoading({ title: '正在验证权限...', mask: true }) // 检查用户的partnerstatus是否为approved API.getUserInfo(openid) .then(response => { const userInfoRes = response.data; console.log('获取用户信息成功:', userInfoRes) // 检查partnerstatus字段 const partnerStatus = userInfoRes.partnerstatus || 'pending' console.log('用户合作状态:', partnerStatus) if (partnerStatus !== 'approved') { throw new Error('partnerstatus_not_approved') } // 第一步:先创建商品(不带图片) const productData = { productName: name, price: price, // 保留原始字符串,不进行数字转换 quantity: Number(minOrder), grossWeight: this.data.newSupply.grossWeight && this.data.newSupply.grossWeight !== '' ? this.data.newSupply.grossWeight : "", yolk: yolk, specification: spec || '', region: region || '', // 【新增】添加地区字段 rejectReason: '', imageUrls: [] // 明确设置为空数组 } console.log('第一步:准备创建商品,数据:', productData) // 更新加载提示 wx.showLoading({ title: '正在创建商品...', mask: true }) // 调用API创建商品(不带图片) return API.publishProduct(productData) }) .then(res => { console.log('商品创建成功:', res) // 第二步:如果有图片,上传图片到已创建的商品 if (imageUrls && imageUrls.length > 0) { wx.showLoading({ title: '正在上传图片...', mask: true }) console.log('开始上传图片到已创建商品,数量:', imageUrls.length) // 获取创建的商品ID - 从多个可能的位置获取 const productId = res.productId || res.data?.productId || res.product?.productId if (productId) { console.log('找到商品ID:', productId) // 【关键修复】使用专门的方法上传图片到已存在商品 return this.uploadImagesToExistingProduct(productId, imageUrls, openid) .then(uploadRes => { console.log('图片上传成功:', uploadRes) return { ...res, imageUpload: uploadRes } }) } else { console.error('无法获取商品ID,响应数据:', res) throw new Error('无法获取商品ID,无法上传图片') } } else { // 没有图片,直接返回 return res } }) .then(finalRes => { wx.hideLoading() wx.showToast({ title: imageUrls && imageUrls.length > 0 ? '创建成功,图片已上传' : '创建成功', duration: 3000 }) // 重置表单 this.setData({ showModal: false, newSupply: { name: '', price: '', minOrder: '', yolk: '', spec: '', imageUrls: [] } }) // 清除本地存储的草稿数据 wx.removeStorageSync('newSupplyDraft'); this.enablePageScroll() // 重新加载数据 this.loadSupplies() }) .catch(err => { console.error('商品创建或图片上传失败:', err) wx.hideLoading() // 处理权限不足的情况 if (err.message === 'partnerstatus_not_approved') { wx.showModal({ title: '权限不足', content: '您的合作伙伴身份尚未通过审核,请等待审核通过后再发布商品', showCancel: true, cancelText: '取消', confirmText: '立即入驻', success: (res) => { if (res.confirm) { // 跳转到入驻页面 wx.navigateTo({ url: '/pages/settlement/index' }) } } }) return } // 其他错误处理:所有错误都显示通用提示,不再跳转登录 let errorMsg = '上传服务器失败' if (err.message && err.message.includes('商品不存在')) { errorMsg = '商品创建失败,无法上传图片' } wx.showModal({ title: '发布失败', content: errorMsg + '\n\n错误详情: ' + (err.message || JSON.stringify(err)), showCancel: false, success: () => { this.loadSupplies() } }) }) }, // 上传商品图片 - 修复版,专门用于为已存在商品上传图片 uploadProductImages(productId, imageUrls) { return new Promise((resolve, reject) => { if (!productId) { reject(new Error('商品ID不能为空')) return } if (!imageUrls || imageUrls.length === 0) { resolve({ success: true, message: '没有图片需要上传' }) return } console.log('开始为已存在商品上传图片,商品ID:', productId, '图片数量:', imageUrls.length) // 获取openid const openid = wx.getStorageSync('openid') if (!openid) { reject(new Error('用户未登录')) return } // 【关键修复】使用专门的图片上传方法,而不是创建新商品 this.uploadImagesToExistingProduct(productId, imageUrls, openid) .then(resolve) .catch(reject) }) }, // 【修复】上传商品图片 - 确保顺序执行 uploadImagesToExistingProduct(productId, imageUrls, openid) { return new Promise((resolve, reject) => { console.log('【图片上传】开始为已存在商品上传图片,商品ID:', productId); // 【关键修复】顺序上传图片,避免并发问题 const uploadSequentially = async () => { const results = []; for (let i = 0; i < imageUrls.length; i++) { try { console.log(`顺序上传第${i + 1}/${imageUrls.length}张图片`); const result = await new Promise((resolveUpload, rejectUpload) => { const formData = { productId: productId, openid: openid, action: 'add_images_only', imageIndex: i, totalImages: imageUrls.length, isUpdate: 'true', timestamp: Date.now() }; wx.uploadFile({ url: API.BASE_URL + '/api/products/upload', filePath: imageUrls[i], name: 'images', formData: formData, success: (res) => { if (res.statusCode === 200) { try { const data = JSON.parse(res.data); if (data.success) { console.log(`第${i + 1}张图片上传成功,当前总数:`, data.totalCount); resolveUpload(data); } else { rejectUpload(new Error(data.message || '图片上传失败')); } } catch (parseError) { rejectUpload(new Error('服务器响应格式错误')); } } else { rejectUpload(new Error(`HTTP ${res.statusCode}`)); } }, fail: (err) => { rejectUpload(new Error('网络错误: ' + err.errMsg)); } }); }); results.push(result); // 添加延迟,避免服务器处理压力过大 if (i < imageUrls.length - 1) { await new Promise(resolve => setTimeout(resolve, 500)); } } catch (error) { console.error(`第${i + 1}张图片上传失败:`, error); // 继续上传其他图片,不中断流程 results.push({ success: false, error: error.message }); } } return results; }; uploadSequentially() .then(results => { // 取最后一个成功的结果作为最终状态 const successfulResults = results.filter(r => r && r.success); if (successfulResults.length > 0) { const lastResult = successfulResults[successfulResults.length - 1]; resolve({ success: true, message: `成功上传${successfulResults.length}张图片`, imageUrls: lastResult.imageUrls || [], allImageUrls: lastResult.allImageUrls || [], uploadedCount: successfulResults.length, totalCount: lastResult.totalCount || successfulResults.length, results: results }); } else { reject(new Error('所有图片上传失败')); } }) .catch(error => { console.error('图片上传失败:', error); reject(error); }); }); }, // 准备上架操作:只显示编辑页面,用户点击提交后才执行上架 preparePublishSupply(e) { // 阻止事件冒泡,防止触发父元素的点击事件 if (e && e.stopPropagation) { e.stopPropagation(); } // 设置自动上架标志为true this.setData({ autoPublishAfterEdit: true }); console.log('设置编辑后自动上架标志为true'); // 调用showEditSupply方法显示编辑页面,但不自动执行上架 this.showEditSupply(e, true); // 传递第二个参数表示这是上架操作 }, // 保存编辑后的货源信息 saveEdit() { const { editSupply, autoPublishAfterEdit } = this.data; // 验证必填信息 if (!editSupply.name || !editSupply.price || !editSupply.minOrder || !editSupply.yolk) { wx.showToast({ title: '请填写完整信息', icon: 'none', duration: 2000 }); return; } // 显示加载中提示 wx.showLoading({ title: '正在同步...', mask: true }); // 获取openid const openid = wx.getStorageSync('openid'); if (!openid) { wx.hideLoading(); wx.showModal({ title: '登录状态异常', content: '您的登录状态已失效,请重新登录后再尝试保存', showCancel: false, success: () => { wx.showToast({ title: '保存失败,请先登录', icon: 'none', duration: 3000 }); this.setData({ showEditModal: false }); this.enablePageScroll(); } }); return; } // 检查用户合作状态 API.getUserInfo(openid) .then(response => { const userInfo = response.data; if (userInfo.partnerstatus !== 'approved') { wx.hideLoading(); wx.showModal({ title: '权限不足', content: '您的合作伙伴身份尚未通过审核,无法保存商品', showCancel: true, cancelText: '取消', confirmText: '立即入驻', success: (res) => { if (res.confirm) { // 跳转到入驻页面 wx.navigateTo({ url: '/pages/settlement/index' }) } this.setData({ showEditModal: false }); this.enablePageScroll(); } }); return Promise.reject('partnerstatus not approved'); } return Promise.resolve(); }) .catch(err => { if (err !== 'partnerstatus not approved') { wx.hideLoading(); wx.showToast({ title: '获取用户信息失败', icon: 'none', duration: 3000 }); this.setData({ showEditModal: false }); this.enablePageScroll(); } return Promise.reject(err); }) .then(() => { // 【关键修复】准备商品数据 - 确保包含地区字段 const productData = { productName: editSupply.name, price: editSupply.price, // 保留原始字符串,不进行数字转换 quantity: Number(editSupply.minOrder), grossWeight: editSupply.grossWeight !== undefined && editSupply.grossWeight !== null && editSupply.grossWeight !== '' ? editSupply.grossWeight : "", yolk: editSupply.yolk, specification: editSupply.spec || '', region: editSupply.region || '', // 【重要】确保地区字段传递 imageUrls: editSupply.imageUrls || [], created_at: new Date().toISOString(), status: autoPublishAfterEdit ? 'pending_review' : '' }; console.log('【调试】准备提交的商品数据:', { productData: productData, hasRegion: !!productData.region, regionValue: productData.region }); // 判断是编辑现有商品还是创建新商品 if (editSupply.serverProductId) { // 编辑现有商品 productData.productId = editSupply.serverProductId; console.log('【调试】调用API.editProduct,商品ID:', editSupply.serverProductId); // 【关键修复】使用正确的API调用格式 const requestData = { openid: openid, productId: editSupply.serverProductId, product: { productName: productData.productName, price: productData.price, quantity: productData.quantity, grossWeight: productData.grossWeight, yolk: productData.yolk, specification: productData.specification, region: productData.region, // 【重要】确保在product对象中传递地区字段 imageUrls: productData.imageUrls }, status: productData.status || '' }; console.log('【调试】最终发送的请求数据:', requestData); // 直接使用wx.request调用,避免API封装层的问题 wx.request({ url: API.BASE_URL + '/api/product/edit', method: 'POST', data: requestData, success: (res) => { console.log('【调试】编辑商品成功响应:', res); wx.hideLoading(); this.setData({ showEditModal: false }); this.enablePageScroll(); wx.showToast({ title: '更新成功', duration: 2000 }); // 重新加载数据 setTimeout(() => { this.loadSupplies(); }, 100); }, fail: (err) => { console.error('【调试】编辑商品失败:', err); wx.hideLoading(); wx.showToast({ title: '保存失败,请重试', icon: 'none', duration: 2000 }); } }); } else { // 创建新商品并提交审核 // 调用添加商品接口 wx.request({ url: API.BASE_URL + '/api/product/add', method: 'POST', data: productData, success: (res) => { console.log('商品创建成功:', res); wx.hideLoading(); // 关闭编辑弹窗 this.setData({ showEditModal: false }); // 恢复页面滚动 this.enablePageScroll(); wx.showToast({ title: '更新成功,等待审核', duration: 2000 }); // 重新加载商品列表 setTimeout(() => { this.loadSupplies(); }, 100); }, fail: (err) => { console.error('商品创建失败:', err); wx.hideLoading(); wx.showToast({ title: '创建失败,请重试', icon: 'none', duration: 2000 }); } }); } }); }, // 预览图片 previewImage(e) { const { urls, index } = e.currentTarget.dataset console.log('准备预览图片,原始URLs:', urls); console.log('当前预览图片索引:', index); console.log('当前预览图片原始URL:', urls[index]); // 修复图片URL格式化问题 const formattedUrls = urls.map(url => { if (!url) return ''; // 移除URL中的引号 let formattedUrl = url.toString().replace(/['"`]/g, ''); // 确保URL以http://或https://开头,特殊处理wxfile://格式 // 特殊处理占位符URL(以placeholder://协议开头) const isHttpProtocol = formattedUrl.startsWith('http'); const isWxfileProtocol = formattedUrl.startsWith('wxfile://'); const isPlaceholderUrl = formattedUrl.startsWith('placeholder://'); console.log('previewImage - 原始URL:', url); console.log('previewImage - 移除引号后的URL:', formattedUrl); console.log('previewImage - isHttpProtocol:', isHttpProtocol, 'isWxfileProtocol:', isWxfileProtocol, 'isPlaceholderUrl:', isPlaceholderUrl); // 对于占位符URL,返回空字符串,这样就不会在预览中显示它们 if (isPlaceholderUrl) { console.log('previewImage - 占位符URL,不参与预览:', formattedUrl); return ''; } if (formattedUrl && !isHttpProtocol && !isWxfileProtocol) { console.warn('previewImage - 图片URL缺少协议,添加https://前缀:', formattedUrl); formattedUrl = 'https://' + formattedUrl; } else { console.log('previewImage - URL已包含有效协议或为wxfile格式,无需添加前缀:', formattedUrl); } // 尝试解码可能被编码的URL路径段 try { // 先检查是否包含%2F等已编码的斜杠 if (formattedUrl.includes('%2F')) { // 只解码路径部分,保留查询参数 const parts = formattedUrl.split('?'); if (parts.length > 1) { formattedUrl = decodeURIComponent(parts[0]) + '?' + parts[1]; } else { formattedUrl = decodeURIComponent(formattedUrl); } } } catch (e) { console.error('解码URL失败:', e); } // 简单验证URL格式 if (formattedUrl && /^https?:\/\/.+\..+/.test(formattedUrl)) { return formattedUrl; } return ''; }); console.log('格式化后的URLs:', formattedUrls); console.log('当前预览图片格式化后URL:', formattedUrls[index]); // 锁定页面滚动 this.disablePageScroll(); this.setData({ showImagePreview: true, previewImageUrls: formattedUrls.filter(url => url), // 过滤掉无效URL previewImageIndex: parseInt(index) }) }, // 关闭图片预览 closeImagePreview() { this.setData({ showImagePreview: false }) // 恢复页面滚动 this.enablePageScroll(); }, // 切换预览图片 onPreviewImageChange(e) { this.setData({ previewImageIndex: e.detail.current, // 切换图片时重置缩放状态 scale: 1, offsetX: 0, offsetY: 0 }) }, // 处理图片点击事件 handleImageTap() { // 清除之前的双击计时器 if (this.data.doubleTapTimeout) { clearTimeout(this.data.doubleTapTimeout) this.setData({ doubleTapTimeout: null }) } // 增加双击计数 const newDoubleTapCount = this.data.doubleTapCount + 1 this.setData({ doubleTapCount: newDoubleTapCount }) // 如果是第一次点击,设置计时器 if (newDoubleTapCount === 1) { const timer = setTimeout(() => { // 单击操作:重置缩放 this.resetZoom() this.setData({ doubleTapCount: 0, doubleTapTimeout: null }) }, 300) this.setData({ doubleTapTimeout: timer }) } else if (newDoubleTapCount === 2) { // 双击操作:切换缩放状态 if (this.data.scale > 1) { this.resetZoom() } else { this.zoomToFit(this.data.imageWidth, this.data.imageHeight) } this.setData({ doubleTapCount: 0, doubleTapTimeout: null }) } }, // 处理触摸开始事件 handleTouchStart(e) { // 清除双击计时器 if (this.data.doubleTapTimeout) { clearTimeout(this.data.doubleTapTimeout) this.setData({ doubleTapTimeout: null, doubleTapCount: 0 }) } // 双指触摸时计算距离 if (e.touches.length === 2) { const distance = this.calculateDistance(e.touches[0], e.touches[1]) this.setData({ lastDistance: distance }) } else if (e.touches.length === 1) { // 单指触摸时记录触摸点 - 使用pageX和pageY而非clientX和clientY const touch = e.touches[0] this.setData({ lastTouchPoint: { pageX: touch.pageX, pageY: touch.pageY } }) } }, // 处理触摸移动事件 handleTouchMove(e) { // 小程序中阻止冒泡通过catchtap等方式实现 if (e.touches.length === 2) { // 双指缩放 const currentDistance = this.calculateDistance(e.touches[0], e.touches[1]) const scaleRatio = currentDistance / this.data.lastDistance let newScale = this.data.scale * scaleRatio // 限制缩放范围 newScale = Math.max(this.data.minScale, Math.min(this.data.maxScale, newScale)) this.setData({ scale: newScale, lastDistance: currentDistance }) } else if (e.touches.length === 1 && this.data.scale > 1 && this.data.lastTouchPoint) { // 单指移动(仅在缩放后可移动) const currentTouch = e.touches[0] // 使用pageX和pageY而非clientX和clientY const deltaX = currentTouch.pageX - this.data.lastTouchPoint.pageX const deltaY = currentTouch.pageY - this.data.lastTouchPoint.pageY let newOffsetX = this.data.offsetX + deltaX let newOffsetY = this.data.offsetY + deltaY // 限制拖动范围 const maxOffsetX = (this.data.imageWidth * this.data.scale - this.data.imageWidth) / 2 const maxOffsetY = (this.data.imageHeight * this.data.scale - this.data.imageHeight) / 2 newOffsetX = Math.max(-maxOffsetX, Math.min(maxOffsetX, newOffsetX)) newOffsetY = Math.max(-maxOffsetY, Math.min(maxOffsetY, newOffsetY)) this.setData({ offsetX: newOffsetX, offsetY: newOffsetY, lastTouchPoint: { pageX: currentTouch.pageX, pageY: currentTouch.pageY } }) } }, // 处理触摸结束事件 handleTouchEnd() { // 重置触摸点和距离 this.setData({ lastTouchPoint: null, lastDistance: 0 }) }, // 重置缩放 resetZoom() { this.setData({ scale: 1, offsetX: 0, offsetY: 0 }) }, // 计算两点之间的距离 calculateDistance(touch1, touch2) { // 在小程序中使用pageX和pageY而非clientX和clientY const dx = touch1.pageX - touch2.pageX const dy = touch1.pageY - touch2.pageY return Math.sqrt(dx * dx + dy * dy) }, // 缩放图片以适应屏幕 zoomToFit(imageWidth, imageHeight) { // 假设屏幕宽度为375px const screenWidth = 375 let newScale = 2 this.setData({ scale: newScale }) }, // 图片加载完成事件 onPreviewImageLoad(e) { this.setData({ imageWidth: e.detail.width, imageHeight: e.detail.height }) }, // 图片加载失败处理 - 增强版 imageError(e) { const url = e.currentTarget.dataset.src || '未知URL'; const errMsg = e.detail.errMsg || '未知错误'; console.error(`图片加载失败 [${errMsg}]: ${url}`); // 尝试使用占位图替代 const target = e.currentTarget; try { // 在实际运行中,小程序会自动使用fallback-src // 这里添加日志记录以便追踪 console.log(`为失败图片设置占位图: ${url}`); } catch (err) { console.error('设置占位图时出错:', err); } // 记录失败的URL到本地,便于调试 try { const failedUrls = wx.getStorageSync('imageLoadFailures') || []; if (!failedUrls.includes(url)) { failedUrls.push({ url, time: new Date().toISOString(), error: errMsg }); // 只保留最近20条记录 if (failedUrls.length > 20) { failedUrls.shift(); } wx.setStorageSync('imageLoadFailures', failedUrls); } } catch (storageErr) { console.error('存储失败URL时出错:', storageErr); } }, // 图片加载成功处理 - 增强版 imageLoad(e) { const url = e.currentTarget.dataset.src; const width = e.detail.width; const height = e.detail.height; console.log(`图片加载成功: ${url} (${width}x${height})`); // 可以在这里添加图片统计逻辑 try { const successCount = wx.getStorageSync('imageLoadSuccessCount') || 0; wx.setStorageSync('imageLoadSuccessCount', successCount + 1); } catch (storageErr) { console.error('存储成功计数时出错:', storageErr); } }, // 显示编辑弹窗 - 修复版 showEditSupply(e, isPublishOperation = false) { // 阻止事件冒泡,防止触发父元素的点击事件 if (e && e.stopPropagation) { e.stopPropagation(); } // 确保图片预览弹窗关闭 this.setData({ showImagePreview: false }); const id = e.currentTarget.dataset.id; console.log('显示编辑弹窗,货源ID:', id, '是否上架操作:', isPublishOperation); if (!id) { console.error('显示编辑弹窗失败:缺少货源ID'); wx.showToast({ title: '操作失败,缺少货源信息', icon: 'none', duration: 2000 }); return; } // 在所有货源列表中查找 let supply = null; const allSupplies = [ ...this.data.publishedSupplies, ...this.data.pendingSupplies, ...this.data.rejectedSupplies, ...this.data.draftSupplies ]; supply = allSupplies.find(s => s.id === id); // 如果没找到,尝试在主列表中查找 if (!supply) { supply = this.data.supplies.find(s => s.id === id); } // 安全检查:确保supply存在 if (!supply) { console.error('未找到ID为', id, '的货源'); wx.showToast({ title: '未找到该货源', icon: 'none', duration: 2000 }); this.setData({ showEditModal: false }); // 确保页面滚动状态正常 this.enablePageScroll(); this.loadSupplies(); return; } // 计算蛋黄和规格的索引值 const yolkIndex = this.data.yolkOptions.indexOf(supply.yolk) >= 0 ? this.data.yolkOptions.indexOf(supply.yolk) : 0; const specIndex = this.data.specOptions.indexOf(supply.spec) >= 0 ? this.data.specOptions.indexOf(supply.spec) : 0; // 设置编辑货源数据,显示编辑弹窗 const supplyWithFormattedTime = { ...supply, formattedCreatedAt: this.formatCreateTime(supply.created_at), region: supply.region || '', // 【新增】确保地区字段存在 yolkIndex: yolkIndex, specIndex: specIndex }; // 解析地区字符串为省市区数组,用于初始化三级下拉框 let editSupplyRegionArray = []; if (supply.region) { // 尝试将地区字符串拆分为省市区数组 // 假设地区格式为 "省份 城市 区县" editSupplyRegionArray = supply.region.split(' ').filter(item => item.trim() !== ''); } console.log('【调试】编辑弹窗数据设置:', { supplyRegion: supply.region, editSupplyRegion: supplyWithFormattedTime.region, editSupplyRegionArray: editSupplyRegionArray }); // 如果是上架操作,设置自动上架标志 if (isPublishOperation) { this.setData({ autoPublishAfterEdit: true }); console.log('设置编辑后自动上架标志为true'); } else { this.setData({ autoPublishAfterEdit: false }); console.log('设置编辑后自动上架标志为false'); } this.setData({ editSupply: supplyWithFormattedTime, editSupplyRegionArray: editSupplyRegionArray, showEditModal: true }); // 锁定页面滚动 this.disablePageScroll(); // 显示提示信息 wx.showToast({ title: '请编辑信息后点击提交', icon: 'none', duration: 2000 }); }, // 上架货源 - 移除本地存储操作 publishSupply(e) { // 阻止事件冒泡,防止触发父元素的点击事件 if (e && e.stopPropagation) { e.stopPropagation(); } // 确保图片预览弹窗关闭 this.setData({ showImagePreview: false }); // 登录验证 const userId = wx.getStorageSync('userId'); const openid = wx.getStorageSync('openid'); const userInfo = wx.getStorageSync('userInfo'); if (!userId || !openid || !userInfo) { wx.showModal({ title: '提示', content: '请先登录再进行商品上架操作', showCancel: false, success: (res) => { if (res.confirm) { this.setData({ showAuthModal: true }); } } }); return; } // 检查用户合作状态 API.getUserInfo(openid) .then(response => { const userInfo = response.data; if (userInfo.partnerstatus !== 'approved') { wx.hideLoading(); this.enablePageScroll(); wx.showModal({ title: '权限不足', content: '您的合作状态尚未通过审核,暂时无法进行商品上架操作', showCancel: true, cancelText: '取消', confirmText: '立即入驻', success: (res) => { if (res.confirm) { // 跳转到入驻页面 wx.navigateTo({ url: '/pages/settlement/index' }) } } }); return; } const id = e.currentTarget.dataset.id // 优先使用编辑中的商品数据 let supply = null // 检查是否存在编辑中的数据 if (this.data.editSupply && this.data.editSupply.id === id) { supply = { ...this.data.editSupply }; } else { // 否则从supplies中查找 supply = this.data.supplies.find(s => s.id === id) } if (!supply) { wx.hideLoading(); this.enablePageScroll(); wx.showToast({ title: '货源信息不存在', icon: 'none', duration: 2000 }); return; } wx.showLoading({ title: '处理中...', mask: true }); // 判断当前货源状态,决定设置什么状态 // 重新提交的商品应该先进入审核中 let newStatus = 'pending_review'; // 默认审核中 if (supply.status === 'reviewed') { newStatus = 'published'; // 已审核通过的货源可以直接上架 } // 同步数据到服务器数据库 // 仅当有serverProductId时才同步到服务器 if (supply.serverProductId) { const openid = wx.getStorageSync('openid'); if (openid) { // 审核失败、隐藏、审核中或下架的货源重新提交时,调用编辑接口同步商品内容和状态 if (supply.status === 'rejected' || supply.status === 'hidden' || supply.status === 'pending_review' || supply.status === 'sold_out') { console.log('审核失败、隐藏、审核中或下架货源重新提交,同步商品内容和状态到服务器'); // 准备商品数据,转换为服务器需要的格式 const productData = { openid: openid, productId: supply.serverProductId, product: { productName: supply.name, price: supply.price, quantity: supply.minOrder, grossWeight: supply.grossWeight || "", yolk: supply.yolk, specification: supply.spec, resubmit: true // 关键参数:告诉服务器这是重新提交审核 }, status: newStatus // 明确传递状态参数,确保变为审核中状态 }; console.log('准备发送商品编辑请求 - URL:', API.BASE_URL + '/api/product/edit'); console.log('准备发送的商品数据:', productData); // 调用编辑商品接口,该接口会自动设置状态为pending_review wx.request({ url: API.BASE_URL + '/api/product/edit', method: 'POST', data: productData, success: (res) => { console.log('商品内容和状态同步成功:', res); // 重新加载数据以更新UI this.loadSupplies(); }, fail: (err) => { console.error('商品内容和状态同步失败:', err); // 重新加载数据以更新UI this.loadSupplies(); }, complete: () => { // 确保在请求完成后隐藏loading并显示提示 try { wx.hideLoading(); // 恢复页面滚动 this.enablePageScroll(); wx.showToast({ title: newStatus === 'published' ? '上架成功' : '重新提交成功,等待审核', duration: 2000 }); } catch (e) { console.error('显示提示时出错:', e); // 确保即使在错误情况下也隐藏loading并恢复滚动 try { wx.hideLoading(); this.enablePageScroll(); } catch (innerErr) { console.error('隐藏loading时出错:', innerErr); } } } }); return; // 异步操作,稍后再继续执行 } else { // 其他情况只更新状态 wx.request({ url: API.BASE_URL + '/api/product/review', method: 'POST', data: { openid: openid, productId: supply.serverProductId, status: newStatus }, success: () => { this.loadSupplies(); }, fail: (err) => { console.error('更新状态失败:', err); this.loadSupplies(); }, complete: () => { try { wx.hideLoading(); // 恢复页面滚动 this.enablePageScroll(); wx.showToast({ title: newStatus === 'published' ? '上架成功' : '重新提交成功,等待审核', duration: 2000 }); } catch (e) { console.error('显示提示时出错:', e); // 确保即使在错误情况下也隐藏loading并恢复滚动 try { wx.hideLoading(); this.enablePageScroll(); } catch (innerErr) { console.error('隐藏loading时出错:', innerErr); } } } }); return; // 异步操作,稍后再继续执行 } } else { // 没有openid时的处理 wx.hideLoading(); // 恢复页面滚动 this.enablePageScroll(); wx.showToast({ title: '登录状态异常,请重新登录', icon: 'none', duration: 2000 }); } } else { // 如果没有serverProductId,提示用户 wx.hideLoading(); // 恢复页面滚动 this.enablePageScroll(); wx.showToast({ title: '无法上架,商品未上传到服务器', icon: 'none', duration: 2000 }); } }) .catch(err => { console.error('获取用户信息失败:', err); wx.hideLoading(); this.enablePageScroll(); wx.showToast({ title: '获取用户信息失败', icon: 'none', duration: 2000 }); }); }, // 下架货源 - 移除本地存储操作 unpublishSupply(e) { // 阻止事件冒泡,防止触发父元素的点击事件 if (e && e.stopPropagation) { e.stopPropagation(); } const supplyId = e.currentTarget.dataset.id; console.log('下架商品 - ID:', supplyId); console.log('当前商品列表长度:', this.data.supplies.length); console.log('当前已上架商品列表长度:', this.data.publishedSupplies.length); // 查找对应商品 let supply = this.data.supplies.find(s => s.id === supplyId); // 如果在主列表中找不到,尝试在已上架商品列表中查找 if (!supply) { supply = this.data.publishedSupplies.find(s => s.id === supplyId); console.log('在已上架列表中查找结果:', supply ? '找到' : '未找到'); } // 如果仍然找不到商品,尝试直接使用传入的ID下架(容错处理) if (!supply) { console.warn('未在本地列表中找到商品,但尝试直接下架:', supplyId); // 禁用页面滚动 this.disablePageScroll(); wx.showLoading({ title: '下架中...', mask: true }); // 直接使用传入的ID尝试下架 API.hideProduct(supplyId) .then(res => { console.log('直接下架成功:', res); wx.hideLoading(); this.enablePageScroll(); wx.showToast({ title: '已下架', icon: 'success', duration: 2000 }); // 清理购物车并重新加载列表 this.cleanUnpublishedFromAllCarts(supplyId); setTimeout(() => { this.loadSupplies(); }, 100); }) .catch(err => { console.error('直接下架失败:', err); wx.hideLoading(); this.enablePageScroll(); wx.showToast({ title: '下架失败,请重试', icon: 'none', duration: 2000 }); }); return; } // 检查是否有serverProductId,只有上传到服务器的商品才能下架 if (!supply.serverProductId) { // 没有serverProductId,提示用户 wx.showToast({ title: '无法下架,商品未上传到服务器', icon: 'none', duration: 2000 }); return; } // 禁用页面滚动 this.disablePageScroll(); wx.showLoading({ title: '下架中...', mask: true }); // 调用API下架商品 API.hideProduct(supply.serverProductId) .then(res => { console.log('服务器下架成功:', res); wx.hideLoading(); // 恢复页面滚动 this.enablePageScroll(); wx.showToast({ title: '已下架', icon: 'success', duration: 2000 }); // 清理所有用户购物车中已下架的商品 this.cleanUnpublishedFromAllCarts(supply.serverProductId); // 只需要调用一次loadSupplies setTimeout(() => { this.loadSupplies(); }, 100); }) .catch(err => { console.error('服务器下架失败:', err); wx.hideLoading(); // 恢复页面滚动 this.enablePageScroll(); wx.showToast({ title: '服务器同步失败,请重试', icon: 'none', duration: 3000 }); // 只需要调用一次loadSupplies setTimeout(() => { this.loadSupplies(); }, 100); }); }, // 清理所有用户购物车中已下架的商品 - 移除本地存储操作 cleanUnpublishedFromAllCarts(supplyId) { try { console.log('开始清理购物车中的已下架商品:', supplyId) // 直接通知服务器清理购物车 setTimeout(() => { API.removeFromAllCarts(supplyId) .then(res => { console.log('清理所有购物车中的已下架商品完成:', res) }) .catch(err => { console.error('清理服务器购物车失败:', err) }) }, 0); } catch (error) { console.error('清理购物车过程中发生错误:', error) } }, // 删除货源(软删除:只在服务器标记为隐藏) deleteSupply(e) { // 阻止事件冒泡,防止触发父元素的点击事件 if (e && e.stopPropagation) { e.stopPropagation(); } // 确保图片预览弹窗关闭 this.setData({ showImagePreview: false }); const id = e.currentTarget.dataset.id const supply = this.data.supplies.find(s => s.id === id) if (!supply) { wx.showToast({ title: '货源不存在', icon: 'none', duration: 2000 }) return } // 显示确认弹窗 wx.showModal({ title: '确认删除', content: '确定要删除该货源吗?删除后将不再显示,但数据会保留。', success: (res) => { if (res.confirm) { wx.showLoading({ title: '删除中...' }) // 确保使用正确的productId格式 let productIdToHide; // 将id转换为字符串,避免startsWith调用错误 const idStr = String(id); if (supply.serverProductId) { productIdToHide = supply.serverProductId; console.log('使用服务器返回的productId:', productIdToHide); } else if (idStr.startsWith('product_')) { productIdToHide = id; console.log('使用已有的product_前缀ID:', productIdToHide); } else { // 如果本地ID不是以product_开头,尝试直接使用 productIdToHide = id; console.log('使用本地ID作为productId:', productIdToHide); } API.deleteProduct(productIdToHide).then(() => { console.log('服务器标记商品为隐藏成功:', productIdToHide) wx.hideLoading() wx.showToast({ title: '删除成功', icon: 'success', duration: 2000 }) // 手动加载数据更新UI this.loadSupplies() }).catch(error => { console.error('服务器标记商品为隐藏失败:', error); console.error('错误详情:', JSON.stringify(error)); wx.hideLoading() // 手动加载数据更新UI this.loadSupplies() // 提供更详细的错误信息 let errorMsg = '服务器操作失败'; if (error.message && error.message.includes('连接失败')) { errorMsg = '无法连接服务器,请检查网络连接后重试'; } else if (error.message && error.message.includes('商品不存在')) { errorMsg = '该商品在服务器上可能已不存在'; } wx.showToast({ title: errorMsg, icon: 'none', duration: 3000 }) }) } } }) }, // 格式化创建时间为 年/月/日 时:分 格式 formatCreateTime: function (timeValue) { // 添加详细日志记录传入的参数 console.log('formatCreateTime - 输入值:', timeValue, '类型:', typeof timeValue); if (!timeValue) { console.log('formatCreateTime - 输入为空,返回"无"'); return '无'; } try { // 首先尝试直接创建Date对象 let date = new Date(timeValue); // 如果日期无效,且输入是字符串,尝试将其转换为数字,再创建Date对象 if (isNaN(date.getTime()) && typeof timeValue === 'string') { console.log('formatCreateTime - 尝试将字符串转换为数字'); const numericTime = Number(timeValue); // 只有当转换后的数字不是NaN时才使用新的Date对象 if (!isNaN(numericTime)) { date = new Date(numericTime); } } console.log('formatCreateTime - Date对象:', date, '时间戳:', date.getTime()); // 检查日期是否有效 if (isNaN(date.getTime())) { console.log('formatCreateTime - 日期无效,返回"无"'); return '无'; } const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = date.getDate().toString().padStart(2, '0'); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); const formattedTime = `${year}/${month}/${day} ${hours}:${minutes}`; console.log('formatCreateTime - 格式化结果:', formattedTime); return formattedTime; } catch (error) { console.error('时间格式化错误:', error); return '无'; } }, // 格式化时间为北京时间(UTC+8)并转换为 年-月-日-时:分 格式 formatTimeToBeijing: function (timeValue) { if (!timeValue) { return '无'; } try { // 创建Date对象 const date = new Date(timeValue); // 检查日期是否有效 if (isNaN(date.getTime())) { return '无'; } // 使用Date对象的方法直接获取UTC时间,然后加8小时计算北京时间 const utcYear = date.getUTCFullYear(); const utcMonth = date.getUTCMonth(); const utcDate = date.getUTCDate(); const utcHours = date.getUTCHours() + 8; // 直接加8小时 // 创建北京时间Date对象 const beijingTime = new Date(Date.UTC(utcYear, utcMonth, utcDate, utcHours, date.getUTCMinutes())); // 格式化时间,使用连字符分隔 const year = beijingTime.getFullYear(); const month = (beijingTime.getMonth() + 1).toString().padStart(2, '0'); const day = beijingTime.getDate().toString().padStart(2, '0'); const hours = beijingTime.getHours().toString().padStart(2, '0'); const minutes = beijingTime.getMinutes().toString().padStart(2, '0'); // 返回格式:年-月-日-时:分 return `${year}-${month}-${day}-${hours}:${minutes}`; } catch (error) { console.error('北京时间格式化错误:', error); return '无'; } }, // 显示审核失败原因弹窗 showRejectReason: function (e) { // 阻止事件冒泡 if (e && e.stopPropagation) { e.stopPropagation(); } const id = e.currentTarget.dataset.id; console.log('显示审核失败原因,货源ID:', id); // 在所有货源列表中查找 let supply = null; const allSupplies = [ ...this.data.publishedSupplies, ...this.data.pendingSupplies, ...this.data.rejectedSupplies, ...this.data.draftSupplies ]; supply = allSupplies.find(s => s.id === id); // 如果没找到,尝试在主列表中查找 if (!supply) { supply = this.data.supplies.find(s => s.id === id); } if (!supply) { console.error('未找到ID为', id, '的货源'); wx.showToast({ title: '未找到该货源', icon: 'none', duration: 2000 }); return; } console.log('找到货源信息:', supply); // 锁定页面滚动 this.disablePageScroll(); // 设置当前显示的货源和失败原因 this.setData({ currentRejectSupply: supply, rejectReason: supply.rejectReason || '暂无详细的审核失败原因,请联系客服了解详情。', showRejectReasonModal: true }); }, // 关闭审核失败原因弹窗 closeRejectReasonModal: function () { console.log('关闭审核失败原因弹窗'); this.setData({ showRejectReasonModal: false // 注意:这里不立即清空 currentRejectSupply,确保后续操作能使用 }); }, // 打开规格选择弹窗 openSpecSelectModal: function (e) { const mode = e.currentTarget.dataset.mode || 'create'; const currentSpec = mode === 'create' ? this.data.newSupply.spec : this.data.editSupply.spec; const specOptions = this.data.specOptions; let selectedIndex = -1; // 查找当前选中规格的索引 if (currentSpec) { selectedIndex = specOptions.indexOf(currentSpec); } // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = false; } this.setData({ showSpecSelectModal: true, currentSpecMode: mode, modalSpecSearchKeyword: '', filteredModalSpecOptions: specOptions, selectedModalSpecIndex: selectedIndex, showTabBar: false // 隐藏底部tab-bar }); }, // 关闭规格选择弹窗 closeSpecSelectModal: function () { // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = true; } this.setData({ showSpecSelectModal: false, modalSpecSearchKeyword: '', selectedModalSpecIndex: -1, showTabBar: true // 显示底部tab-bar }); }, // 弹窗中规格搜索输入 onModalSpecSearchInput: function (e) { const keyword = e.detail.value; const specOptions = this.data.specOptions; let filteredOptions = specOptions; if (keyword) { filteredOptions = specOptions.filter(option => { return option.toLowerCase().includes(keyword.toLowerCase()); }); } this.setData({ modalSpecSearchKeyword: keyword, filteredModalSpecOptions: filteredOptions, selectedModalSpecIndex: -1 // 搜索时重置选择 }); }, // 清除弹窗中的规格搜索关键词 clearModalSpecSearch: function () { this.setData({ modalSpecSearchKeyword: '', filteredModalSpecOptions: this.data.specOptions, selectedModalSpecIndex: -1 }); }, // 双击检测变量 lastTapTime: {}, tapCount: {}, // 通用双击检测函数 handleDoubleTap: function(e, type, callback) { const currentTime = Date.now(); const tapKey = `${type}-${e.currentTarget.dataset.index}`; const lastTap = this.lastTapTime[tapKey] || 0; const tapInterval = currentTime - lastTap; if (tapInterval < 300 && tapInterval > 0) { // 双击事件触发,执行确认选择 callback(); } else { // 单击事件触发,执行选择操作 this.lastTapTime[tapKey] = currentTime; setTimeout(() => { delete this.lastTapTime[tapKey]; }, 300); } }, // 弹窗中选择规格 onModalSpecSelect: function (e) { const index = e.currentTarget.dataset.index; const selectedSpec = this.data.filteredModalSpecOptions[index]; this.setData({ selectedModalSpecIndex: index, modalSpecSearchKeyword: selectedSpec // 自动填充搜索框为当前选择的规格 }); // 检测双击 this.handleDoubleTap(e, 'spec', () => { this.confirmSpecSelection(); }); }, // 确认规格选择 confirmSpecSelection: function () { if (this.data.selectedModalSpecIndex === -1) { wx.showToast({ title: '请选择规格', icon: 'none' }); return; } const selectedSpec = this.data.filteredModalSpecOptions[this.data.selectedModalSpecIndex]; const specOptions = this.data.specOptions; const originalIndex = specOptions.indexOf(selectedSpec); // 根据当前模式更新对应的规格信息 if (this.data.currentSpecMode === 'create') { const newSupply = this.data.newSupply; newSupply.spec = selectedSpec; newSupply.specIndex = originalIndex; this.setData({ newSupply: newSupply }); // 实时保存到本地存储 wx.setStorageSync('newSupplyDraft', newSupply); } else if (this.data.currentSpecMode === 'edit') { this.setData({ 'editSupply.spec': selectedSpec, 'editSupply.specIndex': originalIndex }); } // 关闭弹窗 this.closeSpecSelectModal(); // 恢复页面滚动 this.enablePageScroll(); // 延迟清空数据,确保操作完成 setTimeout(() => { this.setData({ currentRejectSupply: null, rejectReason: '' }); }, 500); }, // 编辑审核失败的货源 editRejectedSupply: function () { // 先保存当前货源数据,再关闭弹窗 const currentRejectSupply = this.data.currentRejectSupply; if (!currentRejectSupply || !currentRejectSupply.id) { wx.showToast({ title: '货源信息不存在', icon: 'none', duration: 2000 }); return; } // 关闭失败原因弹窗 this.closeRejectReasonModal(); // 延迟一小段时间确保弹窗完全关闭 setTimeout(() => { // 模拟点击编辑按钮的事件对象 const mockEvent = { stopPropagation: function () { }, currentTarget: { dataset: { id: currentRejectSupply.id } } }; // 调用显示编辑弹窗的方法 this.showEditSupply(mockEvent); }, 100); }, // 重新提交审核失败的货源 resubmitRejectedSupply: function () { // 先保存当前货源数据,再关闭弹窗 const currentRejectSupply = this.data.currentRejectSupply; if (!currentRejectSupply || !currentRejectSupply.id) { wx.showToast({ title: '货源信息不存在', icon: 'none', duration: 2000 }); return; } // 关闭失败原因弹窗 this.closeRejectReasonModal(); // 延迟一小段时间确保弹窗完全关闭 setTimeout(() => { // 模拟点击上架按钮的事件对象 const mockEvent = { stopPropagation: function () { }, currentTarget: { dataset: { id: currentRejectSupply.id } } }; // 设置自动上架标志 this.setData({ autoPublishAfterEdit: true }); // 调用上架方法 this.preparePublishSupply(mockEvent); }, 100); }, // 选择图片方法 - 修复添加照片功能 chooseImage: function (e) { const type = e.currentTarget.dataset.type; // 获取操作类型:new或edit let currentImages = []; // 根据类型获取当前已选择的图片列表 if (type === 'new') { currentImages = this.data.newSupply.imageUrls || []; } else { currentImages = this.data.editSupply.imageUrls || []; } // 计算还能选择的图片数量 const maxCount = 5 - currentImages.length; if (maxCount <= 0) { wx.showToast({ title: '最多只能上传5张图片', icon: 'none', duration: 2000 }); return; } // 调用微信小程序的图片选择API wx.chooseImage({ count: maxCount, sizeType: ['compressed'], // 压缩图片以减小尺寸 sourceType: ['album', 'camera'], // 可以从相册选择或拍照 success: (res) => { // 获取选择的图片临时文件路径 const tempFilePaths = res.tempFilePaths; // 合并已选择的图片和新选择的图片 const updatedImages = [...currentImages, ...tempFilePaths]; // 根据类型更新数据 if (type === 'new') { const newSupply = this.data.newSupply; newSupply.imageUrls = updatedImages; this.setData({ newSupply: newSupply }); // 实时保存到本地存储 wx.setStorageSync('newSupplyDraft', newSupply); } else { this.setData({ 'editSupply.imageUrls': updatedImages }); } console.log(`成功选择了${tempFilePaths.length}张图片,当前共${updatedImages.length}张`); }, fail: (err) => { console.error('选择图片失败:', err); if (err.errMsg !== 'chooseImage:fail cancel') { // 排除用户主动取消的情况 wx.showToast({ title: '选择图片失败,请重试', icon: 'none', duration: 2000 }); } } }); }, // 格式化创建时间 formatCreateTime: function (timeValue) { console.log('formatCreateTime - 输入值:', timeValue, '类型:', typeof timeValue); if (!timeValue) { console.log('formatCreateTime - 输入为空,返回"无"'); return '无'; } try { // 处理 ISO 8601 格式的字符串 (如: 2025-10-20T08:21:06.000Z) let date; if (typeof timeValue === 'string') { // 直接使用 ISO 字符串创建 Date 对象 date = new Date(timeValue); // 如果日期无效,尝试其他解析方式 if (isNaN(date.getTime())) { // 尝试移除可能的额外字符 const cleanTime = timeValue.replace(/[^\d\-T:.]/g, ''); date = new Date(cleanTime); } } else if (typeof timeValue === 'number') { // 如果是时间戳 date = new Date(timeValue); } else { // 其他情况尝试直接创建 date = new Date(timeValue); } console.log('formatCreateTime - 解析后的Date对象:', date); // 检查日期是否有效 if (isNaN(date.getTime())) { console.log('formatCreateTime - 日期无效,返回"无"'); return '无'; } // 获取本地时间(考虑时区) const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = date.getDate().toString().padStart(2, '0'); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); const formattedTime = `${year}/${month}/${day} ${hours}:${minutes}`; console.log('formatCreateTime - 格式化结果:', formattedTime); return formattedTime; } catch (error) { console.error('时间格式化错误:', error); return timeValue; // 出错时返回原始值 } }, /** * 删除图片 */ deleteImage: function (e) { const index = e.currentTarget.dataset.index; const type = e.currentTarget.dataset.type || 'new'; // 默认处理new类型 if (type === 'new') { const newSupply = this.data.newSupply; const imageUrls = newSupply.imageUrls; imageUrls.splice(index, 1); newSupply.imageUrls = imageUrls; this.setData({ newSupply: newSupply }); // 实时保存到本地存储 wx.setStorageSync('newSupplyDraft', newSupply); } else { const imageUrls = this.data.editSupply.imageUrls; imageUrls.splice(index, 1); this.setData({ 'editSupply.imageUrls': imageUrls }); } console.log(`成功删除${type}类型第${index}张图片`); }, /** * iOS设备检测 */ isIOS() { const systemInfo = wx.getSystemInfoSync() return systemInfo.platform === 'ios' }, /** * 阻止触摸移动事件(iOS专用) */ blockTouchMove() { // 添加全局触摸事件监听器 this.touchMoveHandler = (e) => { e.preventDefault() e.stopPropagation() } // 在页面根元素上阻止触摸移动 this.setData({ touchMoveBlocked: true }) }, /** * 恢复触摸移动事件(iOS专用) */ unblockTouchMove() { this.touchMoveHandler = null // 移除触摸事件阻止 this.setData({ touchMoveBlocked: false }) }, // 处理创建货源弹窗中的规格搜索输入 onSpecSearchInput(e) { const keyword = e.detail.value.toLowerCase().trim(); this.setData({ specSearchKeyword: keyword }); // 过滤规格选项 this.filterSpecOptions(keyword, 'create'); }, // 处理编辑货源弹窗中的规格搜索输入 onEditSpecSearchInput(e) { const keyword = e.detail.value.toLowerCase().trim(); this.setData({ editSpecSearchKeyword: keyword }); // 过滤规格选项 this.filterSpecOptions(keyword, 'edit'); }, // 过滤规格选项的通用函数 filterSpecOptions(keyword, type) { const specOptions = this.data.specOptions; let filteredOptions = specOptions; if (keyword) { filteredOptions = specOptions.filter(option => { return option.toLowerCase().includes(keyword); }); // 如果有匹配的规格选项,自动填充第一个匹配项 if (filteredOptions.length > 0) { if (type === 'create') { const firstMatchIndex = specOptions.indexOf(filteredOptions[0]); this.setData({ 'newSupply.spec': filteredOptions[0], 'newSupply.specIndex': firstMatchIndex }); } else if (type === 'edit') { const firstMatchIndex = specOptions.indexOf(filteredOptions[0]); this.setData({ 'editSupply.spec': filteredOptions[0], 'editSupply.specIndex': firstMatchIndex }); } } } else { // 当关键词为空时,重置规格选择 if (type === 'create') { this.setData({ 'newSupply.spec': '', 'newSupply.specIndex': 0 }); } else if (type === 'edit') { this.setData({ 'editSupply.spec': '', 'editSupply.specIndex': 0 }); } } if (type === 'create') { this.setData({ filteredSpecOptions: filteredOptions }); } else if (type === 'edit') { this.setData({ filteredEditSpecOptions: filteredOptions }); } }, // 清除规格搜索关键词 clearSpecSearch() { this.setData({ specSearchKeyword: '', filteredSpecOptions: this.data.specOptions, 'newSupply.spec': '', // 重置规格选择 'newSupply.specIndex': 0 // 重置规格索引 }); }, // 清除编辑弹窗中的规格搜索关键词 clearEditSpecSearch() { this.setData({ editSpecSearchKeyword: '', filteredEditSpecOptions: this.data.specOptions, 'editSupply.spec': '', // 重置规格选择 'editSupply.specIndex': 0 // 重置规格索引 }); }, /** * 阻止触摸移动事件(用于WXML绑定) */ preventTouchMove(e) { // iOS设备上阻止触摸事件冒泡和默认行为 if (this.isIOS() && this.data.touchMoveBlocked) { e.preventDefault() e.stopPropagation() return false } }, /** * 输入框触摸事件处理(防止iOS抖动) */ onInputTouchStart(e) { // 阻止输入框触摸事件冒泡到页面 if (this.isIOS()) { e.stopPropagation() } }, /** * 输入框触摸移动事件处理(防止iOS抖动) */ onInputTouchMove(e) { // 完全阻止输入框区域的触摸移动事件 if (this.isIOS()) { e.preventDefault() e.stopPropagation() return false } }, /** * 弹窗触摸开始事件处理(增强iOS触摸锁定) */ onModalTouchStart(e) { // 在iOS设备上阻止弹窗区域的触摸事件冒泡到页面 if (this.isIOS()) { e.stopPropagation() } }, /** * 弹窗触摸移动事件处理(增强iOS触摸锁定) */ onModalTouchMove(e) { // 完全阻止弹窗区域的触摸移动事件传播到页面 if (this.isIOS()) { e.preventDefault() e.stopPropagation() return false } }, // 商品名称选择弹窗相关函数 openNameSelectModal() { // 设置当前选中的索引 let currentName = ''; if (this.data.showEditModal && this.data.editSupply.name) { currentName = this.data.editSupply.name; } else { currentName = this.data.newSupply.name; } const index = currentName ? this.data.productNameOptions.indexOf(currentName) : -1; // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = false; } this.setData({ showNameSelectModal: true, selectedNameIndex: index >= 0 ? index : -1, showTabBar: false // 隐藏底部tab-bar }); }, closeNameSelectModal() { // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = true; } this.setData({ showNameSelectModal: false, showTabBar: true // 显示底部tab-bar }); }, onNameSelect(e) { const index = e.currentTarget.dataset.index; this.setData({ selectedNameIndex: index }); // 检测双击 this.handleDoubleTap(e, 'name', () => { this.confirmNameSelection(); }); }, confirmNameSelection() { if (this.data.selectedNameIndex >= 0) { const selectedName = this.data.productNameOptions[this.data.selectedNameIndex]; // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = true; } // 根据当前是编辑还是创建模式,更新对应的对象 if (this.data.showEditModal) { this.setData({ 'editSupply.name': selectedName, showNameSelectModal: false, showTabBar: true // 显示底部tab-bar }); } else { const newSupply = this.data.newSupply; newSupply.name = selectedName; this.setData({ newSupply: newSupply, showNameSelectModal: false, showTabBar: true // 显示底部tab-bar }); // 实时保存到本地存储 wx.setStorageSync('newSupplyDraft', newSupply); } } }, // 蛋黄选择弹窗相关函数 openYolkSelectModal() { // 设置当前选中的索引 let currentYolk = ''; if (this.data.showEditModal && this.data.editSupply.yolk) { currentYolk = this.data.editSupply.yolk; } else { currentYolk = this.data.newSupply.yolk; } const index = currentYolk ? this.data.yolkOptions.indexOf(currentYolk) : -1; // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = false; } this.setData({ showYolkSelectModal: true, selectedYolkIndex: index >= 0 ? index : -1, showTabBar: false // 隐藏底部tab-bar }); }, closeYolkSelectModal() { // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = true; } this.setData({ showYolkSelectModal: false, showTabBar: true // 显示底部tab-bar }); }, onYolkSelect(e) { const index = e.currentTarget.dataset.index; this.setData({ selectedYolkIndex: index }); // 检测双击 this.handleDoubleTap(e, 'yolk', () => { this.confirmYolkSelection(); }); }, confirmYolkSelection() { if (this.data.selectedYolkIndex >= 0) { const selectedYolk = this.data.yolkOptions[this.data.selectedYolkIndex]; // 通过全局数据控制自定义tab-bar的显示状态 const app = getApp(); if (app && app.globalData) { app.globalData.showTabBar = true; } // 根据当前是编辑还是创建模式,更新对应的对象 if (this.data.showEditModal) { this.setData({ 'editSupply.yolk': selectedYolk, 'editSupply.yolkIndex': this.data.selectedYolkIndex, showYolkSelectModal: false, showTabBar: true // 显示底部tab-bar }); } else { const newSupply = this.data.newSupply; newSupply.yolk = selectedYolk; newSupply.yolkIndex = this.data.selectedYolkIndex; this.setData({ newSupply: newSupply, showYolkSelectModal: false, showTabBar: true // 显示底部tab-bar }); // 实时保存到本地存储 wx.setStorageSync('newSupplyDraft', newSupply); } } }, // 联系客服 contactCustomerService() { wx.showModal({ title: '客服电话', content: '123456', showCancel: true, cancelText: '取消', confirmText: '拨打', success: (res) => { if (res.confirm) { wx.makePhoneCall({ phoneNumber: '123456', success: () => { console.log('拨打电话成功'); }, fail: (err) => { console.error('拨打电话失败', err); wx.showToast({ title: '拨打电话失败', icon: 'none' }); } }); } } }); }, // 入驻申请 applyForSettlement() { const openid = wx.getStorageSync('openid'); if (openid) { API.getUserInfo(openid) .then(response => { console.log('获取到的用户信息:', response); const userInfo = response.data; const partnerstatus = userInfo.partnerstatus || ''; if (partnerstatus === 'approved') { // 如果已经审核通过,显示提示 wx.showToast({ title: '您已成功入驻', icon: 'success', duration: 2000 }); } else if (partnerstatus === 'reviewfailed') { // 审核失败状态,进入审核失败页面 wx.navigateTo({ url: '/pages/settlement/index' }); } else { // 其他状态进入入驻页面 wx.navigateTo({ url: '/pages/settlement/index' }); } }) .catch(err => { console.error('获取用户信息失败:', err); // 获取失败时,默认进入入驻页面 wx.navigateTo({ url: '/pages/settlement/index' }); }); } else { // 未登录时,直接进入入驻页面 wx.navigateTo({ url: '/pages/settlement/index' }); } } })