You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

206 lines
6.9 KiB

// 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
};