diff --git a/app.json b/app.json index b26f62d..21cb189 100644 --- a/app.json +++ b/app.json @@ -7,7 +7,8 @@ "pages/buyer/index", "pages/seller/index", "pages/profile/index", - "pages/notopen/index" + "pages/notopen/index", + "pages/create-supply/index" ], "subpackages": [ { diff --git a/pages/create-supply/index.js b/pages/create-supply/index.js new file mode 100644 index 0000000..1b23439 --- /dev/null +++ b/pages/create-supply/index.js @@ -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 + }); + } +}) \ No newline at end of file diff --git a/pages/create-supply/index.json b/pages/create-supply/index.json new file mode 100644 index 0000000..e738d1c --- /dev/null +++ b/pages/create-supply/index.json @@ -0,0 +1,6 @@ +{ + "navigationBarTitleText": "创建新货源", + "navigationBarBackgroundColor": "#fff", + "navigationBarTextStyle": "black", + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/create-supply/index.wxml b/pages/create-supply/index.wxml new file mode 100644 index 0000000..3526824 --- /dev/null +++ b/pages/create-supply/index.wxml @@ -0,0 +1,50 @@ + + + + + 品种 * + + + + + 价格 (元/斤) * + + + + + 数量 (斤) * + + + + + 毛重 (斤) + + + + + 蛋黄 + + + + + 规格 + + + + + + 商品图片(最多5张) + + + + × + + + + + + + + + + + \ No newline at end of file diff --git a/pages/create-supply/index.wxss b/pages/create-supply/index.wxss new file mode 100644 index 0000000..9aa5f0d --- /dev/null +++ b/pages/create-supply/index.wxss @@ -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; +} \ No newline at end of file