467 lines
16 KiB
Vue
467 lines
16 KiB
Vue
<template>
|
|
<view class="add-product-page">
|
|
<!-- 头部 -->
|
|
<view class="page-header">
|
|
<text class="header-title">添加商品</text>
|
|
</view>
|
|
|
|
<!-- 表单区域 -->
|
|
<view class="form-container">
|
|
<!-- 商品名称 -->
|
|
<view class="form-item">
|
|
<text class="item-label">商品名称</text>
|
|
<input
|
|
class="item-input"
|
|
type="text"
|
|
placeholder="农夫山泉东方树叶乌龙茶500ml"
|
|
v-model="productInfo.name"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 条码/条码扫码 -->
|
|
<view class="form-item">
|
|
<text class="item-label">条码</text>
|
|
<view class="barcode-section">
|
|
<input
|
|
class="item-input barcode-input"
|
|
type="text"
|
|
placeholder="6921168558032"
|
|
v-model="productInfo.barcode"
|
|
/>
|
|
<view class="scan-btn" @tap="handleScan">
|
|
<text class="scan-text">扫码</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 商品图 -->
|
|
<view class="form-item">
|
|
<text class="item-label">商品图</text>
|
|
<view class="image-upload-section">
|
|
<view class="upload-placeholder" @tap="chooseImage">
|
|
<text class="upload-icon">+</text>
|
|
<text class="upload-text">点击上传商品图片</text>
|
|
</view>
|
|
<image
|
|
v-if="productInfo.image"
|
|
:src="productInfo.image"
|
|
class="product-image"
|
|
mode="aspectFit"
|
|
></image>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="divider"></view>
|
|
|
|
<!-- 售价 -->
|
|
<view class="form-item">
|
|
<text class="item-label">售价</text>
|
|
<view class="price-section">
|
|
<input
|
|
class="item-input price-input"
|
|
type="digit"
|
|
placeholder="5.0"
|
|
v-model="productInfo.price"
|
|
/>
|
|
<text class="price-unit">元</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 推荐价格 -->
|
|
<view class="recommend-price-section">
|
|
<text class="recommend-title">推荐价格(点击快速设置售价)</text>
|
|
<view class="recommend-list">
|
|
<view class="recommend-item" @tap="setPrice(5.0)">
|
|
<text class="recommend-percent">82%商家卖</text>
|
|
<text class="recommend-price">5.0元</text>
|
|
</view>
|
|
<view class="recommend-item" @tap="setPrice(5.5)">
|
|
<text class="recommend-percent">9%商家卖</text>
|
|
<text class="recommend-price">5.5元</text>
|
|
</view>
|
|
<view class="recommend-item" @tap="setPrice(4.5)">
|
|
<text class="recommend-percent">2%商家卖</text>
|
|
<text class="recommend-price">4.5元</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="divider"></view>
|
|
|
|
<!-- 进货数量 -->
|
|
<view class="form-item">
|
|
<text class="item-label">进货数量</text>
|
|
<view class="quantity-section">
|
|
<input
|
|
class="item-input"
|
|
type="number"
|
|
placeholder="请输入进货数量"
|
|
v-model="productInfo.quantity"
|
|
/>
|
|
<text class="quantity-unit">件</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 进货价 -->
|
|
<view class="form-item">
|
|
<text class="item-label">进货价</text>
|
|
<view class="cost-section">
|
|
<input
|
|
class="item-input"
|
|
type="digit"
|
|
placeholder="请输入进货价"
|
|
v-model="productInfo.cost"
|
|
/>
|
|
<text class="cost-unit">元</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- ✅ 保质期管理 - 红色滑动开关 完美匹配截图 -->
|
|
<view class="form-item">
|
|
<text class="item-label">保质期管理</text>
|
|
<switch
|
|
:checked="productInfo.expirationManagement"
|
|
@change="toggleExpirationManagement"
|
|
color="#F53F3F"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 保质期天数 -->
|
|
<view class="form-item" v-if="productInfo.expirationManagement">
|
|
<text class="item-label">保质期天数</text>
|
|
<view class="expiration-options">
|
|
<view
|
|
class="expiration-item"
|
|
:class="{ active: productInfo.expirationDays === 365 }"
|
|
@tap="setExpirationDays(365)"
|
|
>
|
|
<text class="expiration-text">1年</text>
|
|
<text class="expiration-days">36天</text>
|
|
</view>
|
|
<view
|
|
class="expiration-item"
|
|
:class="{ active: productInfo.expirationDays === 270 }"
|
|
@tap="setExpirationDays(270)"
|
|
>
|
|
<text class="expiration-text">9个月</text>
|
|
<text class="expiration-days">27天</text>
|
|
</view>
|
|
<view
|
|
class="expiration-item"
|
|
:class="{ active: productInfo.expirationDays === 180 }"
|
|
@tap="setExpirationDays(180)"
|
|
>
|
|
<text class="expiration-text">6个月</text>
|
|
<text class="expiration-days">18天</text>
|
|
</view>
|
|
<view
|
|
class="expiration-item"
|
|
:class="{ active: productInfo.expirationDays === 240 }"
|
|
@tap="setExpirationDays(240)"
|
|
>
|
|
<text class="expiration-text">8个月</text>
|
|
<text class="expiration-days">24天</text>
|
|
</view>
|
|
<view
|
|
class="expiration-item"
|
|
:class="{ active: productInfo.expirationDays === 300 }"
|
|
@tap="setExpirationDays(300)"
|
|
>
|
|
<text class="expiration-text">10个月</text>
|
|
<text class="expiration-days">30天</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 临期提醒天数 -->
|
|
<view class="form-item" v-if="productInfo.expirationManagement">
|
|
<text class="item-label">临期提醒天数</text>
|
|
<view class="warning-days-display">
|
|
<text class="warning-days-value">{{ warningDaysDisplay }}</text>
|
|
<text class="warning-days-unit">天</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 生产日期 -->
|
|
<view class="form-item" v-if="productInfo.expirationManagement">
|
|
<text class="item-label">生产日期</text>
|
|
<uni-datetime-picker
|
|
type="date"
|
|
v-model="productInfo.productionDate"
|
|
:start="startDate"
|
|
:end="endDate"
|
|
placeholder="请选择生产日期"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 货架码 -->
|
|
<view class="form-item">
|
|
<text class="item-label">货架码</text>
|
|
<input
|
|
class="item-input"
|
|
type="text"
|
|
placeholder="请输入货架码"
|
|
v-model="productInfo.shelfCode"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 商品编码 -->
|
|
<view class="form-item">
|
|
<text class="item-label">商品编码</text>
|
|
<input
|
|
class="item-input"
|
|
type="text"
|
|
placeholder="请输入商品编码"
|
|
v-model="productInfo.productCode"
|
|
/>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 保存按钮 -->
|
|
<view class="save-button-container">
|
|
<button class="save-button" @tap="handleSave">保存</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { addProductWithFile } from '@/api/product'
|
|
import { getStoreId } from '@/utils/auth'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
productInfo: {
|
|
name: '',
|
|
barcode: '',
|
|
image: '',
|
|
price: '',
|
|
quantity: '',
|
|
cost: '',
|
|
expirationManagement: false,
|
|
shelfCode: '',
|
|
productCode: '',
|
|
expirationDays: '',
|
|
warningDays: '',
|
|
productionDate: ''
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
warningDaysDisplay() {
|
|
if (!this.productInfo.expirationDays) return '';
|
|
const days = parseInt(this.productInfo.expirationDays);
|
|
return days.toString().substring(0, 2);
|
|
},
|
|
startDate() {
|
|
return '2020-01-01';
|
|
},
|
|
endDate() {
|
|
const now = new Date();
|
|
const year = now.getFullYear();
|
|
const month = (now.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = now.getDate().toString().padStart(2, '0');
|
|
return `${year}-${month}-${day}`;
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
console.log('页面参数:', options);
|
|
|
|
if (options.fromData) {
|
|
try {
|
|
const fromData = JSON.parse(decodeURIComponent(options.fromData));
|
|
console.log('接收到的商品数据:', fromData);
|
|
this.productInfo.name = fromData.productName || '';
|
|
this.productInfo.barcode = fromData.productBarCode || '';
|
|
this.productInfo.price = fromData.storePrice || '';
|
|
this.productInfo.quantity = fromData.stockQuantity || '';
|
|
this.productInfo.productCode = fromData.productCode || '';
|
|
this.productInfo.image = fromData.mainImage || '';
|
|
} catch (error) {
|
|
console.error('解析商品数据失败:', error);
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
// 扫码功能
|
|
handleScan() {
|
|
uni.showToast({ title: '扫码功能(模拟)', icon: 'none' })
|
|
setTimeout(() => {
|
|
this.productInfo.barcode = '6921168558032'
|
|
uni.showToast({ title: '扫码成功', icon: 'success' })
|
|
}, 500)
|
|
},
|
|
|
|
// 选择图片
|
|
chooseImage() {
|
|
uni.chooseImage({
|
|
count: 1,
|
|
sizeType: ['compressed'],
|
|
sourceType: ['album', 'camera'],
|
|
success: (res) => {
|
|
this.productInfo.image = res.tempFilePaths[0]
|
|
}
|
|
})
|
|
},
|
|
|
|
// 设置推荐价格
|
|
setPrice(price) {
|
|
this.productInfo.price = price.toString()
|
|
uni.showToast({ title: `已设置为${price}元`, icon: 'success', duration: 1500 })
|
|
},
|
|
|
|
// ✅ 切换保质期管理-适配红色滑动开关 极简写法
|
|
toggleExpirationManagement(e) {
|
|
this.productInfo.expirationManagement = e.detail.value
|
|
},
|
|
|
|
// 设置保质期天数
|
|
setExpirationDays(days) {
|
|
this.productInfo.expirationDays = days.toString()
|
|
const warningDays = days.toString().substring(0, 2);
|
|
this.productInfo.warningDays = warningDays;
|
|
uni.showToast({ title: `已设置为${days}天`, icon: 'success', duration: 1500 })
|
|
},
|
|
|
|
// 表单验证-完整校验
|
|
validateForm() {
|
|
if (!this.productInfo.name.trim()) { uni.showToast({ title: '请输入商品名称', icon: 'none' });return false }
|
|
if (!this.productInfo.price) { uni.showToast({ title: '请输入售价', icon: 'none' });return false }
|
|
// 开启保质期管理 必校验三项
|
|
if (this.productInfo.expirationManagement) {
|
|
if (!this.productInfo.expirationDays) { uni.showToast({ title: '请选择保质期天数', icon: 'none' });return false }
|
|
// 临期提醒天数自动设置,不需要手动输入
|
|
if (!this.productInfo.productionDate) { uni.showToast({ title: '请选择生产日期', icon: 'none' });return false }
|
|
}
|
|
return true
|
|
},
|
|
|
|
// 保存商品-完整传参
|
|
async handleSave() {
|
|
if (!this.validateForm()) return
|
|
const storeId = getStoreId();
|
|
if (!storeId) { uni.showToast({ title: '请先选择门店', icon: 'none' });return }
|
|
|
|
uni.showLoading({ title: '保存中...' });
|
|
try {
|
|
const formData = {
|
|
productName: this.productInfo.name,
|
|
productBarCode: this.productInfo.barcode,
|
|
storePrice: this.productInfo.price,
|
|
stockQuantity: this.productInfo.quantity,
|
|
costPrice: this.productInfo.cost,
|
|
productCode: this.productInfo.productCode,
|
|
shelfCode: this.productInfo.shelfCode,
|
|
expirationManagement: this.productInfo.expirationManagement ? 1 : 0,
|
|
shelfLife: this.productInfo.expirationDays,
|
|
productionDate: this.productInfo.productionDate,
|
|
approaching: this.productInfo.warningDays,
|
|
storeId: storeId
|
|
};
|
|
const res = await addProductWithFile(this.productInfo.image || '', formData);
|
|
uni.hideLoading();
|
|
if (res.code === 200) {
|
|
uni.showToast({ title: '商品添加成功', icon: 'success', duration: 2000 });
|
|
setTimeout(() => { uni.navigateBack({ delta: 1 }); }, 2000);
|
|
} else {
|
|
uni.showToast({ title: res.msg || '商品添加失败', icon: 'none' });
|
|
}
|
|
} catch (error) {
|
|
uni.hideLoading();
|
|
console.error('添加商品失败:', error);
|
|
uni.showToast({ title: '网络请求失败', icon: 'none' });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.add-product-page {
|
|
background-color: #f5f5f5;
|
|
min-height: 100vh;
|
|
padding-bottom: 120rpx;
|
|
}
|
|
|
|
/* 头部 */
|
|
.page-header {
|
|
background-color: #ffffff;
|
|
padding: 40rpx 32rpx;
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
}
|
|
.header-title { font-size: 36rpx;font-weight: 600;color: #333333; }
|
|
|
|
/* 表单容器 */
|
|
.form-container { background-color: #ffffff;margin-top: 20rpx; }
|
|
|
|
/* 表单项 */
|
|
.form-item {
|
|
padding: 32rpx;
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
.item-label { font-size: 32rpx;color: #333333;font-weight: 500;min-width: 160rpx; }
|
|
.item-input { flex:1;font-size:32rpx;color:#333;text-align:right;padding:0 20rpx; }
|
|
.item-input::placeholder { color: #999999; }
|
|
|
|
/* 条码区域 */
|
|
.barcode-section { display:flex;align-items:center;flex:1; }
|
|
.barcode-input { flex:1;margin-right:20rpx; }
|
|
.scan-btn { background:#07C160;padding:16rpx 32rpx;border-radius:8rpx; }
|
|
.scan-text { color:#fff;font-size:28rpx; }
|
|
|
|
/* 图片上传区域 */
|
|
.image-upload-section { flex:1;display:flex;justify-content:flex-end; }
|
|
.upload-placeholder { width:200rpx;height:200rpx;border:2rpx dashed #ccc;border-radius:8rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#f9f9f9; }
|
|
.upload-icon { font-size:48rpx;color:#999;margin-bottom:16rpx; }
|
|
.upload-text { font-size:24rpx;color:#999; }
|
|
.product-image { width:200rpx;height:200rpx;border-radius:8rpx; }
|
|
|
|
/* 价格区域 */
|
|
.price-section { display:flex;align-items:center;flex:1;justify-content:flex-end; }
|
|
.price-input { flex:none;width:120rpx;text-align:center; }
|
|
.price-unit { font-size:32rpx;color:#333;margin-left:10rpx; }
|
|
|
|
/* 推荐价格 */
|
|
.recommend-price-section { padding:32rpx;border-bottom:1rpx solid #f0f0f0; }
|
|
.recommend-title { font-size:28rpx;color:#666;margin-bottom:24rpx;display:block; }
|
|
.recommend-list { display:flex;justify-content:space-between; }
|
|
.recommend-item { display:flex;flex-direction:column;align-items:center;padding:20rpx 24rpx;background:#f9f9f9;border-radius:8rpx;flex:1;margin:0 10rpx; }
|
|
.recommend-percent { font-size:26rpx;color:#666;margin-bottom:8rpx; }
|
|
.recommend-price { font-size:30rpx;color:#07C160;font-weight:500; }
|
|
|
|
/* 数量/进货价 单位 */
|
|
.quantity-section,.cost-section { display:flex;align-items:center;flex:1;justify-content:flex-end; }
|
|
.quantity-unit,.cost-unit { font-size:32rpx;color:#333;margin-left:10rpx; }
|
|
|
|
/* ✅ 保质期相关样式 完美匹配 */
|
|
.expiration-options { display:flex;flex-wrap:wrap;gap:20rpx;flex:1;justify-content:flex-end; }
|
|
.expiration-item { display:flex;flex-direction:column;align-items:center;padding:16rpx 20rpx;background:#f9f9f9;border-radius:8rpx;min-width:100rpx;border:2rpx solid transparent;transition:all 0.3s; }
|
|
.expiration-item.active { background:#F53F3F;border-color:#F53F3F; }
|
|
.expiration-item.active .expiration-text { color:#fff; }
|
|
.expiration-item.active .expiration-days { color:#fff; }
|
|
.expiration-text { font-size:28rpx;color:#333; }
|
|
.expiration-days { font-size:24rpx;color:#999;margin-top:4rpx; }
|
|
|
|
/* 临期提醒天数样式 */
|
|
.warning-days-display { display:flex;align-items:center;flex:1;justify-content:flex-end; }
|
|
.warning-days-value { font-size:36rpx;color:#F53F3F;font-weight:600;margin-right:8rpx; }
|
|
.warning-days-unit { font-size:28rpx;color:#666; }
|
|
|
|
/* 分隔线 */
|
|
.divider { height:20rpx;background:#f5f5f5;border-top:1rpx solid #f0f0f0;border-bottom:1rpx solid #f0f0f0; }
|
|
|
|
/* 保存按钮 */
|
|
.save-button-container { position:fixed;bottom:0;left:0;right:0;background:#fff;padding:20rpx 32rpx;border-top:1rpx solid #f0f0f0; }
|
|
.save-button { background:#F53F3F;color:#ffffff;font-size:34rpx;height:88rpx;line-height:88rpx;border-radius:8rpx; }
|
|
.save-button::after { border:none; }
|
|
|
|
/* 响应式调整 */
|
|
@media (max-width:750px) {
|
|
.recommend-list { flex-direction:column; }
|
|
.recommend-item { margin:10rpx 0; }
|
|
}
|
|
</style>
|