5 changed files with 432 additions and 1 deletions
@ -0,0 +1,267 @@ |
|||||
|
// pages/create-supply/index.js
|
||||
|
// 引入API工具
|
||||
|
const API = require('../../utils/api.js'); |
||||
|
|
||||
|
Page({ |
||||
|
/** |
||||
|
* 页面的初始数据 |
||||
|
*/ |
||||
|
data: { |
||||
|
variety: '', // 品种
|
||||
|
price: '', |
||||
|
quantity: '', |
||||
|
grossWeight: '', |
||||
|
yolk: '', // 蛋黄
|
||||
|
specification: '', |
||||
|
images: [] // 图片数组
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面加载 |
||||
|
*/ |
||||
|
onLoad(options) { |
||||
|
// 页面加载时的初始化
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 品种输入处理 |
||||
|
*/ |
||||
|
onVarietyInput(e) { |
||||
|
this.setData({ |
||||
|
variety: e.detail.value |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 蛋黄输入处理 |
||||
|
*/ |
||||
|
onYolkInput(e) { |
||||
|
this.setData({ |
||||
|
yolk: e.detail.value |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 价格输入处理 |
||||
|
*/ |
||||
|
onPriceInput(e) { |
||||
|
this.setData({ |
||||
|
price: e.detail.value |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 数量输入处理 |
||||
|
*/ |
||||
|
onQuantityInput(e) { |
||||
|
const value = parseFloat(e.detail.value); |
||||
|
this.setData({ |
||||
|
quantity: isNaN(value) ? '' : value |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 毛重输入处理 |
||||
|
*/ |
||||
|
onGrossWeightInput(e) { |
||||
|
this.setData({ |
||||
|
grossWeight: e.detail.value |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 规格输入处理 |
||||
|
*/ |
||||
|
onSpecificationInput(e) { |
||||
|
this.setData({ |
||||
|
specification: e.detail.value |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 表单验证 |
||||
|
*/ |
||||
|
validateForm() { |
||||
|
const { variety, price, quantity } = this.data; |
||||
|
|
||||
|
if (!variety || !variety.trim()) { |
||||
|
wx.showToast({ title: '请输入品种', icon: 'none' }); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (!price || price.trim() === '') { |
||||
|
wx.showToast({ title: '请输入有效价格', icon: 'none' }); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (quantity === '' || quantity === undefined || quantity === null || quantity <= 0) { |
||||
|
wx.showToast({ title: '请输入有效数量', icon: 'none' }); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 创建货源按钮点击事件 |
||||
|
*/ |
||||
|
onCreateTap() { |
||||
|
if (!this.validateForm()) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
const { variety, price, quantity, grossWeight, yolk, specification, images } = this.data; |
||||
|
|
||||
|
// 构建商品数据
|
||||
|
const productData = { |
||||
|
productName: variety.trim(), |
||||
|
price: price.toString(), |
||||
|
quantity: quantity.toString(), |
||||
|
grossWeight: grossWeight || '', |
||||
|
yolk: yolk || '', |
||||
|
specification: specification || '', |
||||
|
images: images, |
||||
|
imageUrls: images |
||||
|
}; |
||||
|
|
||||
|
console.log('创建货源数据:', productData); |
||||
|
|
||||
|
// 显示加载提示
|
||||
|
wx.showLoading({ title: '正在创建货源...' }); |
||||
|
|
||||
|
// 使用API发布商品
|
||||
|
API.publishProduct(productData) |
||||
|
.then(res => { |
||||
|
wx.hideLoading(); |
||||
|
console.log('创建货源成功:', res); |
||||
|
|
||||
|
// 保存到本地存储
|
||||
|
this.saveToLocalStorage(productData, res); |
||||
|
|
||||
|
// 显示成功弹窗
|
||||
|
wx.showModal({ |
||||
|
title: '创建成功', |
||||
|
content: '新货源已成功创建!', |
||||
|
showCancel: false, |
||||
|
confirmText: '确定', |
||||
|
success: function() { |
||||
|
// 返回到上一页
|
||||
|
wx.navigateBack(); |
||||
|
} |
||||
|
}); |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
wx.hideLoading(); |
||||
|
console.error('创建货源失败:', err); |
||||
|
wx.showToast({ |
||||
|
title: err.message || '创建失败,请重试', |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 保存到本地存储 |
||||
|
*/ |
||||
|
saveToLocalStorage(formData, apiResponse) { |
||||
|
// 从本地存储获取userId
|
||||
|
const userId = wx.getStorageSync('userId') || 'anonymous'; |
||||
|
|
||||
|
// 获取卖家信息
|
||||
|
const users = wx.getStorageSync('users') || {}; |
||||
|
const sellerName = users[userId] && users[userId].info && users[userId].info.nickName |
||||
|
? users[userId].info.nickName |
||||
|
: '未知卖家'; |
||||
|
|
||||
|
// 获取当前已有的货源列表
|
||||
|
const supplies = wx.getStorageSync('supplies') || []; |
||||
|
const newId = supplies.length > 0 ? Math.max(...supplies.map(s => s.id)) + 1 : 1; |
||||
|
const serverProductId = apiResponse.product && apiResponse.product.productId |
||||
|
? apiResponse.product.productId |
||||
|
: ''; |
||||
|
|
||||
|
// 创建新的货源记录
|
||||
|
const newSupply = { |
||||
|
id: newId, |
||||
|
productId: serverProductId, |
||||
|
serverProductId: serverProductId, |
||||
|
name: formData.productName, |
||||
|
productName: formData.productName, |
||||
|
price: formData.price, |
||||
|
minOrder: formData.quantity, |
||||
|
yolk: formData.yolk, |
||||
|
spec: formData.specification, |
||||
|
grossWeight: formData.grossWeight || '', |
||||
|
seller: sellerName, |
||||
|
status: apiResponse.product && apiResponse.product.status |
||||
|
? apiResponse.product.status |
||||
|
: 'pending_review', |
||||
|
imageUrls: formData.imageUrls || [], |
||||
|
reservedCount: 0, |
||||
|
isReserved: false |
||||
|
}; |
||||
|
|
||||
|
// 保存到supplies本地存储
|
||||
|
supplies.push(newSupply); |
||||
|
wx.setStorageSync('supplies', supplies); |
||||
|
|
||||
|
// 同时保存到goods本地存储,供买家查看
|
||||
|
const goods = wx.getStorageSync('goods') || []; |
||||
|
const newGoodForBuyer = { |
||||
|
id: String(newId), |
||||
|
productId: String(serverProductId), |
||||
|
name: formData.productName, |
||||
|
productName: formData.productName, |
||||
|
price: formData.price, |
||||
|
minOrder: formData.quantity, |
||||
|
yolk: formData.yolk, |
||||
|
spec: formData.specification, |
||||
|
grossWeight: formData.grossWeight || '', |
||||
|
displayGrossWeight: formData.grossWeight || '', |
||||
|
seller: sellerName, |
||||
|
status: apiResponse.product && apiResponse.product.status |
||||
|
? apiResponse.product.status |
||||
|
: 'pending_review', |
||||
|
imageUrls: formData.imageUrls || [], |
||||
|
reservedCount: 0, |
||||
|
isReserved: false |
||||
|
}; |
||||
|
|
||||
|
goods.push(newGoodForBuyer); |
||||
|
wx.setStorageSync('goods', goods); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 选择图片 |
||||
|
*/ |
||||
|
chooseImage() { |
||||
|
const that = this; |
||||
|
wx.chooseMedia({ |
||||
|
count: 5 - that.data.images.length, |
||||
|
mediaType: ['image'], |
||||
|
sourceType: ['album', 'camera'], |
||||
|
success: function (res) { |
||||
|
console.log('选择图片成功:', res); |
||||
|
const tempFiles = res.tempFiles.map(file => file.tempFilePath); |
||||
|
that.setData({ |
||||
|
images: [...that.data.images, ...tempFiles] |
||||
|
}); |
||||
|
}, |
||||
|
fail: function (err) { |
||||
|
console.error('选择图片失败:', err); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 删除图片 |
||||
|
*/ |
||||
|
deleteImage(e) { |
||||
|
const index = e.currentTarget.dataset.index; |
||||
|
const images = this.data.images; |
||||
|
images.splice(index, 1); |
||||
|
this.setData({ |
||||
|
images: images |
||||
|
}); |
||||
|
} |
||||
|
}) |
||||
@ -0,0 +1,6 @@ |
|||||
|
{ |
||||
|
"navigationBarTitleText": "创建新货源", |
||||
|
"navigationBarBackgroundColor": "#fff", |
||||
|
"navigationBarTextStyle": "black", |
||||
|
"usingComponents": {} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
<!-- pages/create-supply/index.wxml --> |
||||
|
<view class="create-supply-container"> |
||||
|
<view class="form-container"> |
||||
|
<view class="form-item"> |
||||
|
<text class="label">品种 *</text> |
||||
|
<input class="input" type="text" placeholder="请输入品种" bindinput="onVarietyInput" value="{{variety}}" /> |
||||
|
</view> |
||||
|
|
||||
|
<view class="form-item"> |
||||
|
<text class="label">价格 (元/斤) *</text> |
||||
|
<input class="input" type="text" placeholder="请输入商品价格" bindinput="onPriceInput" value="{{price}}" /> |
||||
|
</view> |
||||
|
|
||||
|
<view class="form-item"> |
||||
|
<text class="label">数量 (斤) *</text> |
||||
|
<input class="input" type="digit" placeholder="请输入商品数量" bindinput="onQuantityInput" value="{{quantity}}" /> |
||||
|
</view> |
||||
|
|
||||
|
<view class="form-item"> |
||||
|
<text class="label">毛重 (斤)</text> |
||||
|
<input class="input" type="text" placeholder="请输入商品毛重" bindinput="onGrossWeightInput" value="{{grossWeight}}" /> |
||||
|
</view> |
||||
|
|
||||
|
<view class="form-item"> |
||||
|
<text class="label">蛋黄</text> |
||||
|
<input class="input" type="text" placeholder="请输入蛋黄信息" bindinput="onYolkInput" value="{{yolk}}" /> |
||||
|
</view> |
||||
|
|
||||
|
<view class="form-item"> |
||||
|
<text class="label">规格</text> |
||||
|
<input class="input" type="text" placeholder="请输入商品规格" bindinput="onSpecificationInput" value="{{specification}}" /> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 图片上传区域 --> |
||||
|
<view class="image-upload-container"> |
||||
|
<text class="label">商品图片(最多5张)</text> |
||||
|
<view class="image-list"> |
||||
|
<view class="image-item" wx:for="{{images}}" wx:key="index"> |
||||
|
<image src="{{item}}" mode="aspectFill"></image> |
||||
|
<view class="image-delete" bindtap="deleteImage" data-index="{{index}}">×</view> |
||||
|
</view> |
||||
|
<view class="image-upload" wx:if="{{images.length < 5}}" bindtap="chooseImage"> |
||||
|
<text>+</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<button class="create-btn" type="primary" bindtap="onCreateTap">创建货源</button> |
||||
|
</view> |
||||
|
</view> |
||||
@ -0,0 +1,107 @@ |
|||||
|
/* pages/create-supply/index.wxss */ |
||||
|
.create-supply-container { |
||||
|
background-color: #f5f5f5; |
||||
|
min-height: 100vh; |
||||
|
padding: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.form-container { |
||||
|
background-color: #fff; |
||||
|
border-radius: 16rpx; |
||||
|
padding: 30rpx; |
||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
||||
|
} |
||||
|
|
||||
|
.form-item { |
||||
|
margin-bottom: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.label { |
||||
|
display: block; |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
margin-bottom: 10rpx; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.input { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
border: 2rpx solid #e5e5e5; |
||||
|
border-radius: 12rpx; |
||||
|
padding: 0 20rpx; |
||||
|
font-size: 28rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.input:focus { |
||||
|
border-color: #FF6B81; |
||||
|
outline: none; |
||||
|
} |
||||
|
|
||||
|
.image-upload-container { |
||||
|
margin-bottom: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.image-list { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
gap: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.image-item { |
||||
|
position: relative; |
||||
|
width: 180rpx; |
||||
|
height: 180rpx; |
||||
|
border-radius: 12rpx; |
||||
|
overflow: hidden; |
||||
|
border: 2rpx solid #e5e5e5; |
||||
|
} |
||||
|
|
||||
|
.image-item image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.image-delete { |
||||
|
position: absolute; |
||||
|
top: -10rpx; |
||||
|
right: -10rpx; |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
background-color: rgba(255, 0, 0, 0.8); |
||||
|
color: #fff; |
||||
|
border-radius: 50%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.image-upload { |
||||
|
width: 180rpx; |
||||
|
height: 180rpx; |
||||
|
border: 2rpx dashed #e5e5e5; |
||||
|
border-radius: 12rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
color: #999; |
||||
|
font-size: 80rpx; |
||||
|
} |
||||
|
|
||||
|
.create-btn { |
||||
|
margin-top: 40rpx; |
||||
|
width: 100%; |
||||
|
height: 90rpx; |
||||
|
border-radius: 45rpx; |
||||
|
font-size: 32rpx; |
||||
|
background-color: #FF6B81; |
||||
|
color: #fff; |
||||
|
border: none; |
||||
|
} |
||||
|
|
||||
|
.create-btn::after { |
||||
|
border: none; |
||||
|
} |
||||
Loading…
Reference in new issue