Browse Source

添加sourceType和supplyStatus字段支持,更新产品详情接口和前端展示

pull/1/head
Default User 2 months ago
parent
commit
148d6d2558
  1. 10
      pages/buyer/index.js
  2. 3
      pages/buyer/index.wxml
  3. 17
      pages/favorites/index.js
  4. 3
      pages/favorites/index.wxml
  5. 55
      pages/goods-detail/goods-detail.js
  6. 11
      pages/goods-detail/goods-detail.wxml
  7. 38
      pages/goods-detail/goods-detail.wxss
  8. 2
      project.private.config.json
  9. 16
      server-example/server-mysql.js
  10. 13
      utils/api.js

10
pages/buyer/index.js

@ -856,6 +856,14 @@ Page({
(reservedCountValue !== undefined && reservedCountValue !== null ? reservedCountValue :
(reservationCountValue || 0));
// 转换supplyStatus字段值
let supplyStatusValue = product.supplyStatus || '';
if (['平台货源', '三方认证'].includes(supplyStatusValue)) {
supplyStatusValue = '现货';
} else if (supplyStatusValue === '三方未认证') {
supplyStatusValue = '预售';
}
return {
id: productIdStr,
productId: productIdStr,
@ -875,6 +883,8 @@ Page({
reservedCount: finalReservationCount,
product_contact: product.product_contact || '', // 【新增】添加联系人字段
contact_phone: product.contact_phone || '', // 【新增】添加联系人电话字段
supplyStatus: supplyStatusValue, // 添加supplyStatus字段并进行转换
sourceType: product.sourceType || '', // 新增sourceType字段
debugInfo: {
originalSelected: selectedValue,
originalReservedCount: reservedCountValue,

3
pages/buyer/index.wxml

@ -55,8 +55,9 @@
<view style="flex: 0.6; padding: 0rpx 15rpx 15rpx 15rpx; cursor: pointer;" bindtap="showGoodsDetail" data-item="{{item}}">
<view>
<view style="margin-bottom: 15rpx; margin-top: -5rpx;">
<view style="display: inline-block; margin-right: 10rpx; font-size: 18rpx; color: #fff; background-color: #DAA520; padding: 2rpx 8rpx; border-radius: 10rpx; vertical-align: middle;">金标蛋</view>
<view style="display: inline-block; margin-right: 10rpx; font-size: 18rpx; color: #fff; background: rgba(218, 165, 32, 0.8); padding: 4rpx 10rpx; border-radius: 15rpx; vertical-align: middle; backdrop-filter: blur(10rpx); border: 1rpx solid rgba(255, 255, 255, 0.3); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15), inset 0 1rpx 0 rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.2); font-weight: bold;">{{item.supplyStatus || '暂无状态'}}</view>
<span style="vertical-align: middle; font-size: 36rpx; font-weight: bold;">{{item.name}}</span>
<span style="vertical-align: middle; font-size: 20rpx; color: white; background: linear-gradient(135deg, #4a90e2 0%, #2b66f0 50%, #1a4bbd 100%); padding: 4rpx 8rpx; clip-path: polygon(50% 0%, 70% 10%, 100% 30%, 100% 70%, 70% 90%, 50% 100%, 30% 90%, 0% 70%, 0% 30%, 30% 10%); margin-left: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3), inset 0 1rpx 2rpx rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); font-weight: bold;">V</span>
</view>
<view style="font-size: 28rpx; font-weight: bold; margin-top: 30rpx;">
{{item.specification || '无'}} | {{item.yolk || '无'}} | {{item.minOrder || item.quantity || 1}}件

17
pages/favorites/index.js

@ -160,7 +160,22 @@ Page({
console.log('获取收藏列表成功:', res);
// 检查API返回是否成功
if (res && res.code === 200 && res.data) {
const favorites = res.data.favorites || [];
let favorites = res.data.favorites || [];
// 转换supplyStatus字段值
favorites = favorites.map(item => {
if (item.Product && item.Product.supplyStatus) {
// 将supplyStatus由"平台货源"、"三方认证"、"三方未认证"修改为"预售"、"现货"
// 平台货源和三方认证转为现货,三方未认证转为预售
if (['平台货源', '三方认证'].includes(item.Product.supplyStatus)) {
item.Product.supplyStatus = "现货";
} else if (item.Product.supplyStatus === '三方未认证') {
item.Product.supplyStatus = "预售";
}
}
return item;
});
this.setData({
favoritesList: favorites,
hasFavorites: favorites.length > 0,

3
pages/favorites/index.wxml

@ -54,8 +54,9 @@
<view style="flex: 0.6; padding: 0rpx 15rpx 15rpx 15rpx; cursor: pointer;" bindtap="goToGoodsDetail" data-item="{{item}}">
<view>
<view style="margin-bottom: 15rpx; margin-top: -5rpx;">
<view style="display: inline-block; margin-right: 10rpx; font-size: 18rpx; color: #fff; background-color: #DAA520; padding: 2rpx 8rpx; border-radius: 10rpx; vertical-align: middle;">金标蛋</view>
<view style="display: inline-block; margin-right: 10rpx; font-size: 18rpx; color: #fff; background: rgba(218, 165, 32, 0.8); padding: 4rpx 10rpx; border-radius: 15rpx; vertical-align: middle; backdrop-filter: blur(10rpx); border: 1rpx solid rgba(255, 255, 255, 0.3); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15), inset 0 1rpx 0 rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.2); font-weight: bold;">{{item.Product.supplyStatus || '暂无状态'}}</view>
<span style="vertical-align: middle; font-size: 36rpx; font-weight: bold;">{{item.Product.productName || '未命名商品'}}</span>
<span style="vertical-align: middle; font-size: 20rpx; color: white; background: linear-gradient(135deg, #4a90e2 0%, #2b66f0 50%, #1a4bbd 100%); padding: 4rpx 8rpx; clip-path: polygon(50% 0%, 70% 10%, 100% 30%, 100% 70%, 70% 90%, 50% 100%, 30% 90%, 0% 70%, 0% 30%, 30% 10%); margin-left: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3), inset 0 1rpx 2rpx rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); font-weight: bold;">V</span>
</view>
<view style="font-size: 28rpx; font-weight: bold; margin-top: 30rpx;">
{{(item.Product.spec && item.Product.spec !== '无') ? item.Product.spec : (item.Product.specification && item.Product.specification !== '无') ? item.Product.specification : '无'}} | {{item.Product.yolk || '无'}} | {{item.Product.minOrder || item.Product.quantity || 1}}件

55
pages/goods-detail/goods-detail.js

@ -1,6 +1,16 @@
// pages/goods-detail/goods-detail.js
const API = require('../../utils/api.js')
// 根据sourceType获取对应的颜色
function getSourceTypeColor(sourceType) {
const colorMap = {
'三方认证': '#4d9dff',
'三方未认证': '#ff4d4f',
'平台货源': '#2ad21f'
};
return colorMap[sourceType] || '#4d9dff';
}
// 格式化毛重显示的辅助函数
function formatGrossWeight(grossWeight, weight) {
console.log('===== formatGrossWeight 函数调用 =====');
@ -24,6 +34,36 @@ function formatGrossWeight(grossWeight, weight) {
return "";
}
// 提取地区中的省份信息
function extractProvince(region) {
if (!region || typeof region !== 'string') {
return region;
}
// 查找各种省份格式的位置
const provinceEndIndex = region.indexOf('省');
const autonomousRegionEndIndex = region.indexOf('自治区');
const municipalityEndIndex = region.indexOf('市'); // 用于直辖市,如北京市、上海市
const specialRegionEndIndex = region.indexOf('特别行政区'); // 用于香港、澳门
if (provinceEndIndex !== -1) {
// 包含"省"字,提取到"省"字结束
return region.substring(0, provinceEndIndex + 1);
} else if (autonomousRegionEndIndex !== -1) {
// 包含"自治区",提取到"自治区"结束
return region.substring(0, autonomousRegionEndIndex + 3);
} else if (specialRegionEndIndex !== -1) {
// 包含"特别行政区",提取到"特别行政区"结束
return region.substring(0, specialRegionEndIndex + 5);
} else if (municipalityEndIndex === 2) {
// 直辖市(如北京市、上海市),市字在第2个字符位置
return region.substring(0, municipalityEndIndex + 1);
}
// 如果没有找到匹配的格式,返回原字符串
return region;
}
Page({
data: {
goodsDetail: {}, // 当前商品详情
@ -128,6 +168,14 @@ Page({
// 处理grossWeight为null或无效的情况,返回空字符串以支持文字输入
const grossWeightValue = product.grossWeight !== null && product.grossWeight !== undefined ? product.grossWeight : '';
// 转换supplyStatus字段值
let supplyStatusValue = product.supplyStatus || '';
// 将"平台货源"、"三方认证"、"三方未认证"修改为"预售"、"现货"
if (supplyStatusValue === '平台货源' || supplyStatusValue === '三方认证') {
supplyStatusValue = '现货';
} else if (supplyStatusValue === '三方未认证') {
supplyStatusValue = '预售';
}
// 转换商品数据格式
const formattedGoods = {
id: productIdStr,
@ -137,7 +185,7 @@ Page({
minOrder: product.minOrder || product.quantity,
yolk: product.yolk,
spec: product.spec || product.specification,
region: product.region,
region: extractProvince(product.region),
contact_phone: product.contact_phone || product.contactPhone,
product_contact: product.product_contact || product.contactName,
imageUrls: product.imageUrls || product.images || [],
@ -146,7 +194,10 @@ Page({
reservedCount: finalReservationCount,
created_at: product.created_at || product.createdAt,
updated_at: product.updated_at || product.updatedAt,
status: product.status
status: product.status,
supplyStatus: supplyStatusValue,
sourceType: product.sourceType || '',
sourceTypeColor: getSourceTypeColor(product.sourceType)
};
this.setData({

11
pages/goods-detail/goods-detail.wxml

@ -30,11 +30,18 @@
</view>
<!-- 商品基本信息 -->
<view class="goods-info">
<view class="goods-info" style="margin-top: -40rpx;">
<view style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10rpx;">
<view style="display: flex; align-items: center;">
<view style="display: inline-block; margin-right: 10rpx; font-size: 18rpx; color: #fff; background: rgba(218, 165, 32, 0.8); padding: 4rpx 10rpx; border-radius: 15rpx; vertical-align: middle; backdrop-filter: blur(10rpx); border: 1rpx solid rgba(255, 255, 255, 0.3); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15), inset 0 1rpx 0 rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.2); font-weight: bold; margin-top: -20rpx;">{{goodsDetail.supplyStatus || '暂无状态'}}</view>
<text class="goods-name">{{goodsDetail.name}}</text>
<span style="vertical-align: middle; font-size: 20rpx; color: white; background: linear-gradient(135deg, #4a90e2 0%, #2b66f0 50%, #1a4bbd 100%); padding: 4rpx 8rpx; clip-path: polygon(50% 0%, 70% 10%, 100% 30%, 100% 70%, 70% 90%, 50% 100%, 30% 90%, 0% 70%, 0% 30%, 30% 10%); margin-left: 8rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3), inset 0 1rpx 2rpx rgba(255, 255, 255, 0.5); text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.5); font-weight: bold; margin-top: -20rpx;">V</span>
</view>
<view class="goods-price">
<view class="source-type-badge">
<text style="color: {{goodsDetail.sourceTypeColor}}; font-weight: bold;">{{goodsDetail.sourceType || '暂无'}}</text>
</view>
</view>
<view class="goods-price" style="position: relative; display: flex; align-items: center;">
<text class="price-symbol">价格:</text>
<text class="price-value">{{goodsDetail.price}}</text>
</view>

38
pages/goods-detail/goods-detail.wxss

@ -136,30 +136,60 @@
.goods-price {
display: flex;
align-items: baseline;
align-items: center;
margin-bottom: 4px;
}
.price-symbol {
font-size: 15px;
font-size: 18px;
color: #666;
margin-right: 4px;
font-weight: 500;
display: inline-flex;
align-items: center;
justify-content: center;
}
.price-value {
font-size: 28px;
font-size: 24px;
color: #ff4d4f;
font-weight: 700;
letter-spacing: -0.5px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.price-value::before {
content: '¥';
font-size: 20px;
font-size: 24px;
margin-right: 2px;
}
.source-type-badge {
font-size: 24rpx;
color: #ffffff;
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(12rpx);
-webkit-backdrop-filter: blur(12rpx);
border: 1rpx solid rgba(255, 255, 255, 0.25);
padding: 4rpx 12rpx;
border-radius: 8rpx;
font-weight: bold;
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.12), inset 0 1rpx 0 rgba(255, 255, 255, 0.3);
text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.2);
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
justify-content: center;
margin-top: -22rpx;
}
.source-type-badge:active {
transform: scale(0.98);
box-shadow: 0 3rpx 8rpx rgba(0, 0, 0, 0.15), inset 0 1rpx 0 rgba(255, 255, 255, 0.3);
}
/* 商品详细信息网格 */
.info-grid {
background-color: #ffffff;

2
project.private.config.json

@ -1,6 +1,6 @@
{
"libVersion": "3.10.3",
"projectname": "miniprogram-x27",
"projectname": "xxx",
"setting": {
"urlCheck": false,
"coverView": true,

16
server-example/server-mysql.js

@ -675,6 +675,17 @@ User.init({
defaultValue: Sequelize.NOW,
onUpdate: Sequelize.NOW
},
// 新增字段
sourceType: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '货源类型'
},
supplyStatus: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '供应状态'
},
}, {
sequelize,
@ -1709,7 +1720,9 @@ app.post('/api/product/list', async (req, res) => {
],
attributes: {
include: [
'region' // 【新增】确保返回地区字段
'region', // 【新增】确保返回地区字段
'sourceType', // 【新增】确保返回货源类型字段
'supplyStatus' // 【新增】确保返回供应状态字段
]
},
order: [['created_at', 'DESC']],
@ -3536,6 +3549,7 @@ app.post('/api/products/detail', async (req, res) => {
// 查询商品详情 - 排除hidden状态商品,直接使用Product表中的reservedCount字段
const product = await Product.findOne({
attributes: ['productId', 'productName', 'price', 'quantity', 'grossWeight', 'imageUrls', 'created_at', 'specification', 'yolk', 'sourceType', 'supplyStatus'],
where: {
productId,
status: { [Sequelize.Op.not]: 'hidden' }

13
utils/api.js

@ -3392,7 +3392,18 @@ module.exports = {
// 获取产品详情
getProductDetail: function ({ productId }) {
console.log('API.getProductDetail - productId:', productId);
return request('/api/products/detail', 'POST', { productId: productId });
return request('/api/products/detail', 'POST', { productId: productId }).then(data => {
console.log('商品详情API响应:', data);
if (data && data.data) {
console.log('商品详情字段检查:');
console.log('- 是否包含sourceType:', 'sourceType' in data.data);
console.log('- 是否包含supplyStatus:', 'supplyStatus' in data.data);
console.log('- sourceType值:', data.data.sourceType);
console.log('- supplyStatus值:', data.data.supplyStatus);
console.log('- 完整字段:', Object.keys(data.data));
}
return data;
});
},
// 预约商品

Loading…
Cancel
Save