diff --git a/pages/goods/internal-goods.js b/pages/goods/internal-goods.js new file mode 100644 index 0000000..f12fbef --- /dev/null +++ b/pages/goods/internal-goods.js @@ -0,0 +1,206 @@ +// utils/internal-goods.js +// 内部货源管理模块 +const API = require('./api.js'); + +// 媒体类型判断函数 +function isVideoUrl(url) { + if (!url || typeof url !== 'string') { + return false; + } + const lowerUrl = url.toLowerCase(); + const videoExtensions = ['.mp4', '.mov', '.avi', '.wmv', '.flv', '.webm', '.m4v', '.3gp']; + for (const ext of videoExtensions) { + if (lowerUrl.endsWith(ext)) { + return true; + } + } + return false; +} + +// 格式化时间 +function formatDateTime(dateString) { + if (!dateString) return '未知时间'; + + // 检查是否已经是格式化好的北京时间字符串(如:2026-01-05 17:30) + if (typeof dateString === 'string' && /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2})?$/.test(dateString)) { + // 直接返回格式化好的字符串,只保留到分钟 + return dateString.slice(0, 16); + } + + // 检查是否是ISO格式的字符串(如:2026-01-05T12:00:00.000Z) + if (typeof dateString === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/.test(dateString)) { + // 转换ISO格式为本地时间 + const date = new Date(dateString); + if (isNaN(date.getTime())) { + 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'); + return `${year}-${month}-${day} ${hours}:${minutes}`; + } + + // 对于其他格式的字符串,直接返回,不进行转换 + // 这是为了避免对后端返回的北京时间字符串进行错误的时区转换 + return dateString; +} + +// 构建商品对象的辅助方法 - 增强版,确保所有必要字段都有默认值和正确格式 +function buildProductObject(goodsItem) { + const imageUrls = goodsItem.imageUrls || goodsItem.images || []; + const formattedImageUrls = Array.isArray(imageUrls) ? imageUrls : [imageUrls]; + const mediaItems = formattedImageUrls.map(url => ({ + url: url, + type: isVideoUrl(url) ? 'video' : 'image' + })); + + // 确定creatorName + const sellerNickName = goodsItem.seller?.nickName || goodsItem.seller?.sellerNickName || goodsItem.seller?.name || '未知'; + const creatorName = sellerNickName; + + // 处理商品状态 + let status = goodsItem.status; + const isSoldOut = status === 'sold_out' || + status === 'sold' || + status === 'out_of_stock' || + (goodsItem.supplyStatus && goodsItem.supplyStatus.includes('售空')); + + if (isSoldOut) { + status = 'sold_out'; + } else if (status !== 'published') { + status = 'published'; + } + + // 处理价格 + let processedPrice = goodsItem.price; + if (processedPrice && typeof processedPrice === 'string') { + const priceArray = processedPrice.split(/[,,、]/).map(p => p.trim()).filter(p => p); + if (priceArray.length > 0) { + processedPrice = priceArray[0]; + } + } + + const productName = goodsItem.productName || goodsItem.name || '未命名商品'; + const displayTime = goodsItem.updated_at || goodsItem.updatedAt || goodsItem.created_at || goodsItem.createTime; + + return { + ...goodsItem, + productName: productName, + name: productName, + status: status, + price: processedPrice, + formattedCreatedAt: formatDateTime(displayTime), + creatorName: creatorName, + imageUrls: formattedImageUrls, + mediaItems: mediaItems + }; +} + +// 获取商品列表的方法(用于刷新商品信息)- 修复接口路径和请求方式 +function getProducts() { + return new Promise((resolve, reject) => { + // 从本地存储获取openid + const openid = wx.getStorageSync('openid') || ''; + + // 使用正确的接口路径和POST请求方式 + API.request('/api/product/list', 'POST', { + openid: openid, + status: 'all', // 请求所有状态的商品(除了hidden) + viewMode: 'buyer', // 使用buyer模式获取所有商品,而非仅当前用户的商品 + page: 1, + pageSize: 100 // 获取足够多的商品 + }).then(res => { + if (res && (res.code === 200 || res.success) && res.products) { + // 将商品列表存储到本地缓存 + wx.setStorageSync('goods', res.products || []); + resolve(res.products); + } else { + reject(new Error('获取商品列表失败')); + } + }).catch(err => { + console.error('获取商品列表失败:', err); + reject(new Error('获取商品列表失败,请稍后重试')); + }); + }); +} + +// 加载所有商品数据 - 辅助方法 +async function loadAllGoodsData() { + try { + // 使用getProducts方法获取所有商品数据 + const allGoods = await getProducts(); + + // 对所有商品进行格式化处理 + const formattedGoods = allGoods.map(item => buildProductObject(item)); + + return formattedGoods; + } catch (err) { + console.error('加载所有商品数据失败:', err); + return []; + } +} + +// 搜索商品列表 +function searchGoodsList(goodsList, keyword) { + if (!keyword || keyword.trim() === '') { + return goodsList; + } + + const searchTerm = keyword.toLowerCase().trim(); + + return goodsList.filter(item => { + // 确保creatorName字段存在 + const creatorName = item.creatorName || ''; + + // 检查多个字段是否包含搜索关键词,包括creatorName + const fieldsToCheck = [ + // 产品基本信息 + item.productName || item.name || '', // 产品名称 + item.specification || item.spec || '', // 规格 + item.description || item.remark || '', // 描述 + item.region || item.area || '', // 地区 + item.yolk || item.variety || '', // 蛋黄 + item.price || '', // 价格 + item.costprice || '', // 采购价格 + item.grossWeight || item.weight || '', // 重量 + item.category || '', // 种类 + item.minOrder || item.quantity || '', // 最小起订量 + + // 创建人信息 + creatorName, // 已处理的创建人名称,确保能搜索到 + + // 创建/更新时间 + item.formattedCreatedAt || item.updated_at || item.updatedAt || item.created_at || item.createdAt || '' // 创建/更新时间 + ]; + + // 检查是否有任何字段包含搜索关键词 + return fieldsToCheck.some(field => { + return field.toLowerCase().includes(searchTerm); + }); + }); +} + +// 根据筛选条件过滤数据 +function filterGoodsList(goodsList, filterConfig, activeFilter) { + if (activeFilter === 'all') { + return goodsList; + } + + const allowedCreators = filterConfig[activeFilter] || []; + return goodsList.filter(item => { + return allowedCreators.includes(item.creatorName); + }); +} + +module.exports = { + getProducts: getProducts, + loadAllGoodsData: loadAllGoodsData, + searchGoodsList: searchGoodsList, + filterGoodsList: filterGoodsList, + buildProductObject: buildProductObject, + formatDateTime: formatDateTime, + isVideoUrl: isVideoUrl +}; \ No newline at end of file diff --git a/pages/index/index.wxml b/pages/index/index.wxml index 74a2156..f70b75e 100644 --- a/pages/index/index.wxml +++ b/pages/index/index.wxml @@ -3,8 +3,8 @@ - - + + 🔍