时味苏州
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

575 lines
13 KiB

<template>
<view class="bg">
<!-- 日期选择区域 -->
<view class="date-all-box">
<!-- 月份选择 -->
<view class="month-box">
<view @tap="changeMonth(index)" :class="'month-item' + (monthIndex === index ? ' active' : '')"
v-for="(item, index) in month" :key="index">
{{ item }}月
</view>
</view>
<!-- 星期表头 -->
<view class="day-header">
<view class="day-header-item">日</view>
<view class="day-header-item">一</view>
<view class="day-header-item">二</view>
<view class="day-header-item">三</view>
<view class="day-header-item">四</view>
<view class="day-header-item">五</view>
<view class="day-header-item">六</view>
</view>
<!-- 日期展示 -->
<view class="day-box" v-if="selectDate">
<!-- 填充空白 -->
<view class="day-item" v-for="(item, index) in currentMonthDays[1]" :key="index">
<view class="date-item-in">
<view class="date-num"></view>
<view class="date-price-place"></view>
</view>
</view>
<!-- 显示日期 -->
<view
:class="'day-item' + (selectDate.selectMonth === month[monthIndex] && selectDate.selectDate === index + 1 ? ' active' : '')"
v-for="(item, index) in currentMonthDays[0]" :key="index">
<view class="date-item-in" @tap="selectDateFun(index + 1)">
<view :class="
'date-num' + (getPriceInfo(month[monthIndex], index + 1) && getPriceInfo(month[monthIndex], index + 1).product_price !== null ? ' active' : '')
">
{{ formatDay(index + 1) }}
</view>
<view class="price" v-if="
getPriceInfo(month[monthIndex], index + 1) &&
getPriceInfo(month[monthIndex], index + 1).product_price !== null &&
getPriceInfo(month[monthIndex], index + 1).stock !== null
">
¥{{ getPriceInfo(month[monthIndex], index + 1).m_price / 100 }}
</view>
<view class="date-price-place"
v-else-if="getPriceInfo(month[monthIndex], index + 1) && getPriceInfo(month[monthIndex], index + 1).stock === 0">
售罄
</view>
<view class="date-price-place" v-else></view>
</view>
</view>
</view>
</view>
<!-- 规格选择区域 -->
<view class="box" v-for="(item, index) in sku" :key="index">
<view class="box-top">
<view class="box-title">{{ item.sku_name }}</view>
<view class="box-tip text-overflow">{{ item.sku_type_info }}</view>
<view :class="'iconfont' + (nums[index] === 0 ? ' disable' : '')" @tap="minus(index)">-</view>
<view class="number">{{ nums[index] }}</view>
<view :class="'iconfont' + (nums[index] === selectDate.info[index].stock ? ' disable' : '')"
@tap="add(index)">+</view>
</view>
<view class="single-price" v-if="selectDate">{{ selectDate.info[index].price / 100 }}</view>
</view>
<!-- 底部固定栏 -->
<view class="fixed-bottom">
<text class="fixed-text">合计</text>
<view class="price">{{ totalPrice() / 100 }}</view>
<view class="btn" @tap="order">下一步</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
id: '',
monthCount: 2, // 显示的月份数量
month: [],
monthDays: [],
monthIndex: 0,
productInfo: null,
sku: [],
nums: [],
selectDate: null,
price: 0,
prices: {}
};
},
onLoad(option) {
if (option && option.id) this.id = option.id;
},
onShow() {
this.getSku();
this.initDate();
},
computed: {
// 计算当前月份的天数信息
currentMonthDays() {
return this.monthDays[this.monthIndex];
}
},
methods: {
// 获取产品下的规格
getSku() {
this.Post({
id: this.id
}, '/api/product/get_product_detail').then(res => {
const nums = res.data.sku.map(() => 1);
// 排序
this.sortSku(res.data.sku);
this.productInfo = res.data;
this.sku = res.data.sku;
this.nums = nums;
});
},
// 初始化日期信息
initDate() {
const today = new Date();
const monthInfoList = [];
// 生成monthCount个月份的数据
for (let i = 0; i < this.monthCount; i++) {
const month = today.getMonth() + 1 + i;
const year = today.getFullYear() + Math.floor((month - 1) / 12);
const currentMonth = (month - 1) % 12 + 1;
monthInfoList.push({
month: currentMonth,
year
});
}
this.month = monthInfoList.map(item => item.month);
this.monthDays = monthInfoList.map(item => this.getMonthDays(item.month, item.year));
// 计算日期范围,获取更多月份的价格信息
const startDate = this.formatDate(today);
const endYear = monthInfoList[this.monthCount - 1].year;
const endMonth = monthInfoList[this.monthCount - 1].month;
const endDay = this.monthDays[this.monthCount - 1][0];
const endDate = `${endYear}/${endMonth}/${endDay}`;
this.Post({
product_id: this.id,
start_date: startDate,
end_date: endDate
}, '/api/product/get_product_sku_price_by_date').then(res => {
const prices = this.processPriceData(res.data);
this.prices = prices;
const {
selectDate,
selectMonth
} = this.findFirstAvailableDate(prices);
if (!selectDate) {
return;
}
const info = prices[`${selectMonth}-${selectDate}`];
info.selectMonth = selectMonth;
info.selectDate = selectDate;
this.selectDate = info;
this.monthIndex = this.month.indexOf(selectMonth);
console.log(111, this.selectDate);
});
},
// 获取月份信息
getMonthInfo(today) {
const month1 = today.getMonth() + 1;
const month2 = (month1 + 1) % 12;
const year = today.getFullYear();
const year2 = month1 < month2 ? year : year + 1;
return {
month1,
month2,
year,
year2
};
},
// 获取这个月有几天
getMonthDays(month, year) {
const date = new Date(`${year}/${month}/01`).getDay();
if (month === 2) {
if ((year % 100 !== 0 && year % 4 === 0) || year % 400 === 0) {
return [29, date];
} else {
return [28, date];
}
} else if ((month < 8 && month % 2 === 1) || (month >= 8 && month % 2 === 0)) {
return [31, date];
} else {
return [30, date];
}
},
// 格式化日期
formatDate(date) {
const year = date.getFullYear();
const month = date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1;
const day = date.getDate();
return [year, month, day].join('-');
},
// 切换月份
changeMonth(index) {
this.monthIndex = index;
},
// 选择日期
selectDateFun(day) {
const selectMonth = this.month[this.monthIndex];
if (!selectMonth) {
return;
}
const info = this.getPriceInfo(selectMonth, day);
if (info && info.product_price && info.product_price !== null && info.stock !== 0) {
info.selectMonth = selectMonth;
info.selectDate = day;
this.selectDate = info;
}
},
// 减少数量
minus(index) {
if (!this.selectDate) {
uni.showToast({
title: '请先选择出行日期',
icon: 'none'
});
return;
}
if (this.nums[index] === 0) {
return;
}
this.nums[index]--;
this.$forceUpdate();
},
// 添加数量
add(index) {
if (!this.selectDate) {
uni.showToast({
title: '请先选择出行日期',
icon: 'none'
});
return;
}
if (this.selectDate.info[index].stock === this.nums[index]) {
return;
}
this.nums[index]++;
this.$forceUpdate();
},
// 总价
totalPrice() {
if (!this.selectDate) return 0;
return this.nums.reduce((total, num, index) => {
return total + num * this.selectDate.info[index].price;
}, 0);
},
// 下一步
order() {
if (!this.selectDate) {
uni.showToast({
title: '请先选择日期',
icon: 'none'
});
return;
}
const allNum = this.nums.reduce((total, num) => total + num, 0);
if (allNum === 0) {
uni.showToast({
title: '至少选择一个规格',
icon: 'none'
});
return;
}
this.sku.forEach((item, index) => {
item.num = this.nums[index];
item.price = this.selectDate.info[index].price;
});
const data = {
product: this.productInfo,
sku: this.sku,
selectDate: this.selectDate,
price: this.totalPrice()
};
this.$store.commit('changeLineInfo', data);
uni.navigateTo({
url: '/subPackages/line/orders'
});
},
// 规格排序
sortSku(sku) {
sku.sort((a, b) => a.id - b.id);
},
// 处理价格数据
processPriceData(data) {
const prices = {};
data.forEach(item => {
this.sortSku(item.info);
const stock = item.info.reduce((total, i) => total + i.stock, 0);
item.stock = stock;
if (item.stock > 0) {
const [, ...dateParts] = item.date.split('-');
const newDate = dateParts.map(d => parseInt(d));
const key = newDate.join('-');
prices[key] = item;
}
});
return prices;
},
// 查找第一个可用日期
findFirstAvailableDate(prices) {
let selectDate;
let selectMonth;
for (const key in prices) {
const [month, day] = key.split('-');
if (!selectDate) {
selectDate = parseInt(day);
selectMonth = parseInt(month);
}
}
return {
selectDate,
selectMonth
};
},
// 获取价格信息
getPriceInfo(month, day) {
return this.prices[`${month}-${day}`];
},
// 格式化日期显示
formatDay(day) {
return day >= 10 ? day : `0${day}`;
}
}
};
</script>
<style scoped lang="scss">
/* 样式部分保持不变 */
.bg {
background: #f6f6f6;
padding-bottom: 200rpx;
}
.date-all-box {
margin: 25rpx;
.month-box {
padding: 0 20rpx;
height: 116rpx;
display: flex;
border-bottom: 1rpx solid #ccc;
align-items: center;
overflow-x: auto;
::-webkit-scrollbar {
display: none;
}
.month-item {
margin-right: 70rpx;
font-size: 33rpx;
color: #000;
font-weight: 500;
line-height: 116rpx;
position: relative;
}
.month-item.active::after {
content: '1';
display: block;
font-size: 0;
position: absolute;
left: 0;
right: 0;
height: 8rpx;
background: #6A8A27;
border-radius: 4rpx;
bottom: 0;
}
}
.day-header {
padding-top: 40rpx;
line-height: 45rpx;
font-size: 29rpx;
color: #000;
display: flex;
align-items: center;
flex-wrap: wrap;
margin-bottom: 50rpx;
.day-header-item {
width: calc(702rpx / 7);
text-align: center;
flex-shrink: 0;
}
}
.day-box {
display: flex;
align-items: center;
font-size: 35rpx;
flex-wrap: wrap;
color: #999;
.day-item {
width: calc(702rpx / 7);
text-align: center;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 30rpx;
.date-item-in {
width: 87rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 87rpx;
.date-num {
line-height: 40rpx;
}
.date-num.active {
color: #000;
}
.price {
font-size: 23rpx;
color: #F84A56;
line-height: 20rpx;
}
.price::after {
content: '起';
font-size: 17rpx;
}
.date-price-place {
height: 20rpx;
}
}
}
.day-item.active {
.date-item-in {
background: #6A8A27;
color: #fff;
border-radius: 7rpx;
.price {
color: #fff;
}
.date-num {
color: #fff;
}
}
}
}
}
.box {
background: white;
margin: 25rpx;
background: #ffffff;
border-radius: 9rpx;
padding: 35rpx 20rpx;
.box-top {
display: flex;
justify-content: space-between;
align-items: center;
line-height: 50rpx;
font-size: 28rpx;
color: #666;
.box-title {
font-size: 31rpx;
color: #000;
}
.box-tip {
flex: 1;
margin-left: 30rpx;
}
.iconfont {
color: #000;
font-size: 34rpx;
}
.iconfont.disable {
color: #666;
}
.number {
width: 67rpx;
height: 50rpx;
background: #f0f0f0;
border-radius: 7rpx;
text-align: center;
margin: 0 23rpx;
}
}
.single-price {
font-size: 33rpx;
color: #F84A56;
text-align: right;
margin-top: 20rpx;
}
.single-price::before {
content: '¥';
font-size: 24rpx;
margin-right: 4rpx;
}
}
.fixed-bottom {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 113rpx;
background: white;
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 25rpx;
box-shadow: 0px 0px 16rpx 0px rgba(6, 0, 1, 0.1);
z-index: 999;
.fixed-text {
font-weight: bold;
font-size: 32rpx;
color: #000000;
}
.price {
flex: 1;
font-size: 40rpx;
color: #DC2525;
font-weight: bold;
}
.price::before {
font-size: 24rpx;
content: '¥';
}
.btn {
width: 233rpx;
text-align: center;
line-height: 73rpx;
background: #6A8A27;
border-radius: 11rpx;
font-weight: bold;
font-size: 32rpx;
color: #FFFFFF;
margin: 0 26rpx 0 auto;
}
}
</style>