Browse Source

feat: 添加估价功能,包括商品列表、规格选择和价格计算

pull/19/head
徐飞洋 1 month ago
parent
commit
ae675cbe97
  1. 7
      app.json
  2. 34
      custom-tab-bar/index.js
  3. 237
      pages/evaluate1/index.js
  4. 4
      pages/evaluate1/index.json
  5. 58
      pages/evaluate1/index.wxml
  6. 285
      pages/evaluate1/index.wxss
  7. 47
      pages/evaluate1/product-list.js
  8. 4
      pages/evaluate1/product-list.json
  9. 40
      pages/evaluate1/product-list.wxml
  10. 180
      pages/evaluate1/product-list.wxss
  11. 49
      pages/evaluate1/spec-detail.js
  12. 4
      pages/evaluate1/spec-detail.json
  13. 45
      pages/evaluate1/spec-detail.wxml
  14. 127
      pages/evaluate1/spec-detail.wxss
  15. 6
      utils/api.js

7
app.json

@ -2,6 +2,9 @@
"pages": [ "pages": [
"pages/index/index", "pages/index/index",
"pages/evaluate/index", "pages/evaluate/index",
"pages/evaluate1/index",
"pages/evaluate1/product-list",
"pages/evaluate1/spec-detail",
"pages/settlement/index", "pages/settlement/index",
"pages/publish/index", "pages/publish/index",
"pages/buyer/index", "pages/buyer/index",
@ -74,8 +77,8 @@
"text": "消息" "text": "消息"
}, },
{ {
"pagePath": "pages/evaluate/index", "pagePath": "pages/evaluate1/index",
"text": "估" "text": "估"
}, },
{ {
"pagePath": "pages/settlement/index", "pagePath": "pages/settlement/index",

34
custom-tab-bar/index.js

@ -94,7 +94,7 @@ Component({
const tabBarPages = [ const tabBarPages = [
'pages/index/index', 'pages/index/index',
'pages/chat/index', 'pages/chat/index',
'pages/evaluate/index', 'pages/evaluate1/index',
'pages/settlement/index', 'pages/settlement/index',
'pages/favorites/index', 'pages/favorites/index',
'pages/profile/index' 'pages/profile/index'
@ -176,6 +176,38 @@ Component({
}) })
}, },
// 跳转到估价页面
goToEvaluatePage() {
wx.switchTab({
url: '/pages/evaluate1/index',
success: (res) => {
console.log('跳转到估价页面成功:', res)
// 更新选中状态
this.setData({ selected: 'evaluate' })
// 更新全局状态
const app = getApp()
if (app && app.globalData) {
app.globalData.currentTab = 'evaluate'
}
},
fail: (err) => {
console.error('跳转到估价页面失败:', err)
// 失败时尝试使用reLaunch
wx.reLaunch({
url: '/pages/evaluate1/index',
success: (res) => {
console.log('使用reLaunch跳转到估价页面成功:', res)
this.setData({ selected: 'evaluate' })
const app = getApp()
if (app && app.globalData) {
app.globalData.currentTab = 'evaluate'
}
}
})
}
})
},
// 从全局数据同步状态的方法 - 增强版 // 从全局数据同步状态的方法 - 增强版

237
pages/evaluate1/index.js

@ -0,0 +1,237 @@
Page({
data: {
productName: '',
specifications: [],
loading: false,
error: ''
},
onLoad(options) {
let productName = '';
// 首先检查URL参数
if (options.productName) {
productName = options.productName;
} else {
// 然后检查本地存储(用于wx.switchTab导航)
productName = wx.getStorageSync('selectedProductName') || '';
// 清除本地存储中的商品名称,避免影响下次进入
if (productName) {
wx.removeStorageSync('selectedProductName');
}
}
if (productName) {
this.setData({ productName: productName });
this.loadSpecifications(productName);
} else {
// 如果没有商品名称参数,跳转到商品列表页面
wx.redirectTo({
url: '/pages/evaluate1/product-list'
});
}
},
loadSpecifications(productName) {
this.setData({ loading: true, specifications: [] });
// 直接从本地存储获取商品数据,避免重复请求
const localGoods = wx.getStorageSync('goods') || [];
console.log('从本地存储获取的商品数量:', localGoods.length);
if (localGoods.length > 0) {
this.processSpecifications(productName, localGoods);
} else {
// 如果本地没有数据,再请求服务器
const api = require('../../utils/api');
api.getProducts().then(products => {
this.processSpecifications(productName, products);
}).catch(err => {
console.error('获取规格失败:', err);
this.setData({
error: '获取规格失败,请稍后重试',
loading: false
});
});
}
},
// 解析规格,提取类型(净重/毛重)和数值范围
parseSpecification(spec) {
const weightMatch = spec.match(/(净重|毛重)(\d+)-(\d+)/);
if (weightMatch) {
const type = weightMatch[1]; // 净重或毛重
const min = parseFloat(weightMatch[2]);
const max = parseFloat(weightMatch[3]);
const avg = (min + max) / 2;
return {
type: type,
min: min,
max: max,
avg: avg
};
}
return null;
},
processSpecifications(productName, products) {
console.log('处理的商品数据数量:', products.length);
console.log('当前处理的商品名称:', productName);
// 检查products是否为空
if (!products || products.length === 0) {
console.error('商品数据为空');
this.setData({
error: '商品数据为空',
loading: false
});
return;
}
// 过滤出当前商品名称的所有商品
const filteredProducts = products.filter(product => {
const match = product.productName === productName;
console.log('商品:', product.productName, '规格:', product.specification, '价格:', product.price, '匹配:', match);
return match;
});
console.log('过滤后的商品数量:', filteredProducts.length);
console.log('过滤后的商品详情:', filteredProducts);
// 检查filteredProducts是否为空
if (filteredProducts.length === 0) {
console.error('未找到对应商品名称的商品');
this.setData({
error: '未找到对应商品名称的商品',
loading: false
});
return;
}
// 提取规格和价格,处理可能的空值和空格
const specPriceMap = {};
filteredProducts.forEach((product, productIndex) => {
const specStr = (product.specification || product.spec || '').trim();
const price = product.price || '';
console.log(`处理第${productIndex + 1}个商品: 规格字符串='${specStr}', 价格字符串='${price}'`);
if (specStr.length > 0) {
// 处理逗号分隔的多个规格,确保每个规格都被正确分割
// 首先按逗号分割
let specs = specStr.split(',').map(spec => spec.trim()).filter(spec => spec.length > 0);
// 进一步处理规格,确保每个规格都是独立的
const processedSpecs = [];
specs.forEach(spec => {
// 检查规格是否包含多个规格(例如:"净重29-30,净重31-32")
if (spec.includes(',')) {
// 按中文逗号分割
const subSpecs = spec.split(',').map(s => s.trim()).filter(s => s.length > 0);
processedSpecs.push(...subSpecs);
} else {
processedSpecs.push(spec);
}
});
specs = processedSpecs;
// 处理逗号分隔的多个价格
const prices = (price || '').split(',').map(p => p.trim());
console.log(`规格数组:`, specs);
console.log(`价格数组:`, prices);
// 将规格和价格配对
specs.forEach((spec, index) => {
if (spec.length > 0) {
// 确保价格索引不超出范围
const priceIndex = index % prices.length;
const matchedPrice = prices[priceIndex] || '';
console.log(`规格'${spec}' 配对价格: '${matchedPrice}'`);
// 只有当价格不为空时才添加该规格
if (matchedPrice) {
// 直接使用商品的原始价格,不做任何处理
specPriceMap[spec] = matchedPrice;
} else {
console.log(`规格'${spec}' 价格为空,不添加`);
}
}
});
}
});
console.log('规格价格映射:', specPriceMap);
// 检查specPriceMap是否为空
if (Object.keys(specPriceMap).length === 0) {
console.error('未提取到有效规格');
this.setData({
error: '未提取到有效规格',
loading: false
});
return;
}
// 转换为规格对象数组
const specifications = Object.keys(specPriceMap).map(spec => {
const price = specPriceMap[spec];
console.log(`最终规格'${spec}' 对应价格: '${price}'`);
// 解析规格
const specInfo = this.parseSpecification(spec);
let finalPrice = price;
let finalPriceText = price;
// 根据规格类型和价格水平计算最终价格
if (specInfo && parseFloat(price) < 10) {
if (specInfo.type === '净重') {
// 净重:规格平均值 × 价格
finalPrice = specInfo.avg * parseFloat(price);
finalPriceText = finalPrice.toFixed(2);
console.log(`规格'${spec}' 是净重,计算最终价格: ${finalPriceText}`);
} else if (specInfo.type === '毛重') {
// 毛重:(规格平均值 - 5) × 价格
finalPrice = (specInfo.avg - 5) * parseFloat(price);
finalPriceText = finalPrice.toFixed(2);
console.log(`规格'${spec}' 是毛重,计算最终价格: ${finalPriceText}`);
}
}
return {
name: spec,
price: price,
priceText: price,
finalPrice: finalPrice,
finalPriceText: finalPriceText
};
});
console.log('提取的规格和价格:', specifications);
this.setData({
specifications: specifications,
error: '', // 清除之前的错误
loading: false
});
},
// 跳转到规格详情页面
goToSpecDetail(e) {
const specItem = e.currentTarget.dataset.spec;
wx.navigateTo({
url: `/pages/evaluate1/spec-detail?productName=${encodeURIComponent(this.data.productName)}&specification=${encodeURIComponent(specItem.name)}&price=${encodeURIComponent(specItem.finalPrice)}`
});
},
// 返回上一页
goBack() {
wx.navigateBack();
},
// 返回商品列表页面
goBackToProductList() {
wx.redirectTo({
url: '/pages/evaluate1/product-list'
});
}
});

4
pages/evaluate1/index.json

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "估价",
"usingComponents": {}
}

58
pages/evaluate1/index.wxml

@ -0,0 +1,58 @@
<view class="container">
<view class="header">
<text class="title">选择规格</text>
</view>
<view class="content">
<!-- 加载中状态 -->
<view wx:if="{{loading}}" class="loading">
<view class="loading-spinner"></view>
<text>加载中...</text>
</view>
<!-- 错误提示 -->
<view wx:if="{{error}}" class="error">
<view class="error-icon">⚠️</view>
<text>{{error}}</text>
<button bindtap="loadSpecifications" data-product="{{productName}}" type="primary" class="retry-button">重试</button>
</view>
<!-- 商品信息 -->
<view wx:else class="product-info">
<text class="product-label">商品名称:</text>
<text class="product-value">{{productName}}</text>
<button bindtap="goBackToProductList" type="default" class="back-button">返回上一步</button>
</view>
<!-- 规格列表 -->
<view wx:if="{{!loading && !error && specifications.length > 0}}" class="spec-list">
<view class="section-header">
<text class="section-title">可用规格</text>
<text class="section-count">{{specifications.length}}个</text>
</view>
<view class="spec-items">
<view
wx:for="{{specifications}}"
wx:key="item.name"
class="spec-item"
data-spec="{{item}}"
bindtap="goToSpecDetail"
>
<view class="spec-info">
<text class="spec-name">{{item.name}}</text>
</view>
<view class="spec-price-arrow">
<text class="spec-price">¥{{item.finalPriceText}}</text>
<view class="spec-arrow">→</view>
</view>
</view>
</view>
</view>
<!-- 无规格提示 -->
<view wx:if="{{!loading && !error && specifications.length === 0}}" class="hint">
<view class="hint-icon">📋</view>
<text>该商品暂无可用规格</text>
</view>
</view>
</view>

285
pages/evaluate1/index.wxss

@ -0,0 +1,285 @@
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
}
.header {
padding: 30rpx 0;
text-align: center;
background-color: #fff;
border-bottom: 1rpx solid #eee;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
letter-spacing: 2rpx;
}
.content {
flex: 1;
padding: 20rpx;
}
.product-info {
background-color: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.08);
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 20rpx;
}
.back-button {
width: 100%;
height: 70rpx;
line-height: 70rpx;
font-size: 28rpx;
border-radius: 35rpx;
margin-top: 10rpx;
}
.product-label {
font-size: 28rpx;
color: #666;
margin-right: 20rpx;
}
.product-value {
font-size: 32rpx;
font-weight: bold;
color: #FF6B81;
flex: 1;
}
.loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
color: #666;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 6rpx solid #f3f3f3;
border-top: 6rpx solid #FF6B81;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.error {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40rpx;
background-color: #fff;
border-radius: 12rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
}
.error-icon {
font-size: 60rpx;
margin-bottom: 20rpx;
}
.error text {
display: block;
color: #ff4d4f;
margin-bottom: 30rpx;
font-size: 28rpx;
text-align: center;
}
.retry-button {
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
font-size: 28rpx;
border-radius: 35rpx;
background-color: #FF6B81;
color: #fff;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.section-title {
font-size: 30rpx;
font-weight: bold;
color: #333;
padding-left: 15rpx;
border-left: 5rpx solid #FF6B81;
}
.section-count {
font-size: 24rpx;
color: #999;
background-color: #f5f5f5;
padding: 5rpx 15rpx;
border-radius: 20rpx;
}
.product-list,
.spec-list {
background-color: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.08);
}
.product-items,
.spec-items {
display: flex;
flex-direction: column;
gap: 15rpx;
}
.product-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-radius: 10rpx;
background-color: #f9f9f9;
border: 1rpx solid #eee;
transition: all 0.3s ease;
cursor: pointer;
}
.spec-item {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 30rpx;
border-radius: 10rpx;
background-color: #f9f9f9;
border: 1rpx solid #eee;
transition: all 0.3s ease;
cursor: pointer;
flex-direction: column;
gap: 15rpx;
}
.spec-info {
flex: 1;
}
.spec-price-arrow {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 10rpx;
width: 100%;
}
.product-item:hover,
.spec-item:hover {
background-color: #f0f0f0;
transform: translateY(-2rpx);
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
}
.product-item.selected {
background-color: #FFE6E6;
border-color: #FF6B81;
color: #FF6B81;
}
.product-name,
.spec-name {
font-size: 28rpx;
color: #333;
flex: 1;
}
.spec-price {
font-size: 28rpx;
font-weight: bold;
color: #FF6B81;
margin-right: 20rpx;
}
.product-item.selected .product-name {
color: #FF6B81;
font-weight: bold;
}
.product-arrow,
.spec-arrow {
font-size: 30rpx;
color: #999;
margin-left: 20rpx;
}
.product-item.selected .product-arrow {
color: #FF6B81;
}
.hint {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
color: #999;
font-size: 28rpx;
}
.hint-icon {
font-size: 80rpx;
margin-bottom: 30rpx;
}
/* 响应式设计 */
@media (max-width: 375px) {
.content {
padding: 15rpx;
}
.product-list,
.spec-list {
padding: 20rpx;
}
.product-item,
.spec-item {
padding: 20rpx;
}
.title {
font-size: 32rpx;
}
.section-title {
font-size: 26rpx;
}
.product-name,
.spec-name {
font-size: 26rpx;
}
}

47
pages/evaluate1/product-list.js

@ -0,0 +1,47 @@
Page({
data: {
productNames: [],
loading: false,
error: ''
},
onLoad(options) {
this.loadProductNames();
},
loadProductNames() {
this.setData({ loading: true, error: '' });
const api = require('../../utils/api');
api.getProducts().then(products => {
// 提取唯一的productName
const uniqueProductNames = [...new Set(products.map(product => product.productName).filter(Boolean))];
this.setData({
productNames: uniqueProductNames,
loading: false
});
}).catch(err => {
console.error('获取商品列表失败:', err);
this.setData({
error: '获取商品列表失败,请稍后重试',
loading: false
});
});
},
selectProduct(e) {
const productName = e.currentTarget.dataset.product;
console.log('选择商品:', productName);
// 将商品名称存储到本地存储,因为wx.switchTab不支持URL参数
wx.setStorageSync('selectedProductName', productName);
// 使用wx.switchTab导航到tabBar页面
wx.switchTab({
url: '/pages/evaluate1/index',
success: function(res) {
console.log('跳转成功:', res);
},
fail: function(err) {
console.error('跳转失败:', err);
}
});
}
});

4
pages/evaluate1/product-list.json

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "选择商品",
"usingComponents": {}
}

40
pages/evaluate1/product-list.wxml

@ -0,0 +1,40 @@
<view class="container">
<view class="header">
<text class="title">选择商品</text>
</view>
<view class="content">
<!-- 加载中状态 -->
<view wx:if="{{loading}}" class="loading">
<view class="loading-spinner"></view>
<text>加载中...</text>
</view>
<!-- 错误提示 -->
<view wx:if="{{error}}" class="error">
<view class="error-icon">⚠️</view>
<text>{{error}}</text>
<button bindtap="loadProductNames" type="primary" class="retry-button">重试</button>
</view>
<!-- 商品名称列表 -->
<view wx:else class="product-list">
<view class="section-header">
<text class="section-title">商品名称</text>
<text class="section-count">{{productNames.length}}个</text>
</view>
<view class="product-items">
<view
wx:for="{{productNames}}"
wx:key="*this"
class="product-item"
data-product="{{item}}"
bindtap="selectProduct"
>
<text class="product-name">{{item}}</text>
<view class="product-arrow">→</view>
</view>
</view>
</view>
</view>
</view>

180
pages/evaluate1/product-list.wxss

@ -0,0 +1,180 @@
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #f5f5f5;
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
}
.header {
padding: 30rpx 0;
text-align: center;
background-color: #fff;
border-bottom: 1rpx solid #eee;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
letter-spacing: 2rpx;
}
.content {
flex: 1;
padding: 20rpx;
}
.loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
color: #666;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 6rpx solid #f3f3f3;
border-top: 6rpx solid #FF6B81;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.error {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40rpx;
background-color: #fff;
border-radius: 12rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
}
.error-icon {
font-size: 60rpx;
margin-bottom: 20rpx;
}
.error text {
display: block;
color: #ff4d4f;
margin-bottom: 30rpx;
font-size: 28rpx;
text-align: center;
}
.retry-button {
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
font-size: 28rpx;
border-radius: 35rpx;
background-color: #FF6B81;
color: #fff;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.section-title {
font-size: 30rpx;
font-weight: bold;
color: #333;
padding-left: 15rpx;
border-left: 5rpx solid #FF6B81;
}
.section-count {
font-size: 24rpx;
color: #999;
background-color: #f5f5f5;
padding: 5rpx 15rpx;
border-radius: 20rpx;
}
.product-list {
background-color: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.08);
}
.product-items {
display: flex;
flex-direction: column;
gap: 15rpx;
}
.product-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-radius: 10rpx;
background-color: #f9f9f9;
border: 1rpx solid #eee;
transition: all 0.3s ease;
cursor: pointer;
}
.product-item:hover {
background-color: #f0f0f0;
transform: translateY(-2rpx);
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
}
.product-name {
font-size: 28rpx;
color: #333;
flex: 1;
}
.product-arrow {
font-size: 30rpx;
color: #999;
margin-left: 20rpx;
}
/* 响应式设计 */
@media (max-width: 375px) {
.content {
padding: 15rpx;
}
.product-list {
padding: 20rpx;
}
.product-item {
padding: 20rpx;
}
.title {
font-size: 32rpx;
}
.section-title {
font-size: 26rpx;
}
.product-name {
font-size: 26rpx;
}
}

49
pages/evaluate1/spec-detail.js

@ -0,0 +1,49 @@
Page({
data: {
productName: '',
specification: '',
price: 0,
quantity: 1,
totalPrice: 0,
loading: false,
error: ''
},
onLoad(options) {
if (options.productName && options.specification && options.price) {
const price = parseFloat(options.price) || 0;
this.setData({
productName: decodeURIComponent(options.productName),
specification: decodeURIComponent(options.specification),
price: price,
totalPrice: price
});
}
},
// 件数输入变化
onQuantityChange(e) {
const quantity = parseInt(e.detail.value) || 1;
this.setData({
quantity: quantity,
totalPrice: this.data.price * quantity
});
},
// 计算价格
calculatePrice() {
const totalPrice = this.data.price * this.data.quantity;
this.setData({
totalPrice: totalPrice
});
wx.showToast({
title: '计算完成',
icon: 'success',
duration: 1000
});
},
// 返回上一页
goBack() {
wx.navigateBack();
}
});

4
pages/evaluate1/spec-detail.json

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "规格详情",
"usingComponents": {}
}

45
pages/evaluate1/spec-detail.wxml

@ -0,0 +1,45 @@
<view class="container">
<view class="header">
<text class="title">{{productName}}</text>
</view>
<view class="content">
<view class="spec-card">
<view class="spec-item">
<text class="label">规格:</text>
<text class="value">{{specification}}</text>
</view>
<view class="spec-item">
<text class="label">单价:</text>
<text class="value price">¥{{price.toFixed(2)}}</text>
</view>
<view class="spec-info">
<text>您已选择此规格进行估价</text>
</view>
</view>
<view class="quantity-section">
<text class="label">件数:</text>
<input
class="quantity-input"
type="number"
value="{{quantity}}"
bindinput="onQuantityChange"
min="1"
/>
</view>
<view class="calculate-section">
<button bindtap="calculatePrice" type="primary" class="calculate-button">计算价格</button>
</view>
<view class="result-section">
<text class="result-label">总价:</text>
<text class="result-value">¥{{totalPrice.toFixed(2)}}</text>
</view>
<view class="action">
<button bindtap="goBack" type="default">返回</button>
</view>
</view>
</view>

127
pages/evaluate1/spec-detail.wxss

@ -0,0 +1,127 @@
.container {
min-height: 100vh;
background-color: #f5f5f5;
}
.header {
padding: 30rpx 0;
text-align: center;
background-color: #fff;
border-bottom: 1rpx solid #eee;
}
.title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.content {
padding: 30rpx;
}
.spec-card {
background-color: #fff;
border-radius: 12rpx;
padding: 40rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.08);
margin-bottom: 40rpx;
}
.spec-item {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.label {
font-size: 28rpx;
color: #666;
margin-right: 20rpx;
width: 120rpx;
}
.value {
font-size: 32rpx;
font-weight: bold;
color: #FF6B81;
flex: 1;
}
.price {
color: #FF6B81;
}
.spec-info {
padding-top: 20rpx;
border-top: 1rpx solid #eee;
text-align: center;
}
.spec-info text {
font-size: 24rpx;
color: #999;
}
.quantity-section {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.quantity-input {
flex: 1;
height: 80rpx;
border: 2rpx solid #ddd;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
}
.calculate-section {
display: flex;
justify-content: center;
margin-bottom: 30rpx;
}
.calculate-button {
width: 80%;
height: 80rpx;
font-size: 28rpx;
border-radius: 40rpx;
}
.result-section {
display: flex;
align-items: center;
margin-bottom: 40rpx;
padding: 20rpx;
background-color: #f9f9f9;
border-radius: 8rpx;
}
.result-label {
font-size: 28rpx;
color: #666;
margin-right: 20rpx;
width: 120rpx;
}
.result-value {
font-size: 36rpx;
font-weight: bold;
color: #FF6B81;
flex: 1;
}
.action {
display: flex;
justify-content: center;
}
button {
width: 80%;
height: 80rpx;
font-size: 28rpx;
border-radius: 40rpx;
}

6
utils/api.js

@ -814,17 +814,19 @@ module.exports = {
status: 'all', // 请求所有状态的商品(除了hidden) status: 'all', // 请求所有状态的商品(除了hidden)
viewMode: 'buyer', // 使用buyer模式获取所有商品,而非仅当前用户的商品 viewMode: 'buyer', // 使用buyer模式获取所有商品,而非仅当前用户的商品
page: 1, page: 1,
pageSize: 100 // 获取足够多的商品 pageSize: 1000 // 增加pageSize以获取更多商品
}).then(res => { }).then(res => {
if (res && (res.code === 200 || res.success) && res.products) { if (res && (res.code === 200 || res.success) && res.products) {
console.log('API.getProducts - 获取到的商品数量:', res.products.length);
// 将商品列表存储到本地缓存 // 将商品列表存储到本地缓存
wx.setStorageSync('goods', res.products || []); wx.setStorageSync('goods', res.products || []);
resolve(res.products); resolve(res.products);
} else { } else {
console.error('API.getProducts - 获取商品列表失败:', res);
reject(new Error('获取商品列表失败')); reject(new Error('获取商品列表失败'));
} }
}).catch(err => { }).catch(err => {
console.error('获取商品列表失败:', err); console.error('API.getProducts - 获取商品列表失败:', err);
reject(new Error('获取商品列表失败,请稍后重试')); reject(new Error('获取商品列表失败,请稍后重试'));
}); });
}); });

Loading…
Cancel
Save