Initial commit: 积分兑换电商平台多商户版 MER-2.2
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
*此函数的作用是根据传入的一个日期,返回这一周的日期或者这一个月的日期,
|
||||
* 如果是月的话注意还包含上个月和下个月的日期,月的话总共数据有 6 * 7 = 42个
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* 时间格式化函数
|
||||
* 重要提示,微信小程序new Date('2020-04-16')在ios中无法获取时间对象
|
||||
* 解决方式: 建议将时间都格式化成'2020/04/16 00:00:00'的格式
|
||||
* 函数示例: formatDate(new Date(), 'YYYY/MM/dd hh:mm:ss')
|
||||
*/
|
||||
export const formatDate = (date, fmt) => {
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
|
||||
}
|
||||
let o = {
|
||||
'M+': date.getMonth() + 1,
|
||||
'd+': date.getDate(),
|
||||
'h+': date.getHours(),
|
||||
'm+': date.getMinutes(),
|
||||
's+': date.getSeconds()
|
||||
}
|
||||
for (let k in o) {
|
||||
if (new RegExp(`(${k})`).test(fmt)) {
|
||||
let str = o[k] + ''
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
|
||||
}
|
||||
}
|
||||
return fmt
|
||||
}
|
||||
const padLeftZero = (str) => {
|
||||
return ('00' + str).substr(str.length)
|
||||
}
|
||||
export const judgeType = (s) => {
|
||||
// 函数返回数据的具体类型
|
||||
return Object.prototype.toString.call(s).slice(8,-1);
|
||||
}
|
||||
export const equalDate = (d1, d2) => {
|
||||
let result = false;
|
||||
if (d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate()) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* 比较时间,时间格式为2020-04-04
|
||||
*/
|
||||
export const dateEqual = (before, after) => {
|
||||
before = new Date(before.replace('-', '/').replace('-', '/'))
|
||||
after = new Date(after.replace('-', '/').replace('-', '/'))
|
||||
if (before.getTime() - after.getTime() === 0) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export const gegerateDates = (date = new Date(), type='week') => {
|
||||
const result = [];
|
||||
if (judgeType(date) === 'Date') {
|
||||
// 年,月,日
|
||||
const y = date.getFullYear();
|
||||
const m = date.getMonth();
|
||||
const d = date.getDate();
|
||||
const days = new Date(y, m+1, 0).getDate();
|
||||
// 获取日期是星期几
|
||||
let weekIndex = date.getDay() === 0 ? 7 : date.getDay();
|
||||
if (type === 'month') {
|
||||
const dobj = new Date(y,m,1);
|
||||
weekIndex = dobj.getDay() === 0 ? 7 : dobj.getDay();
|
||||
}
|
||||
if (type === 'week') {
|
||||
for(let i = weekIndex - 1; i >0; i--) {
|
||||
const dtemp = new Date(y,m,d);
|
||||
dtemp.setDate(dtemp.getDate() - i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: dtemp.getMonth()+1 == new Date(y,m,d).getMonth() + 1,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
})
|
||||
}
|
||||
for(let i = 0; i <= 7 - weekIndex; i++) {
|
||||
const dtemp = new Date(y,m,d);
|
||||
dtemp.setDate(dtemp.getDate() + i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: dtemp.getMonth()+1 == new Date(y,m,d).getMonth() + 1,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
})
|
||||
}
|
||||
} else if (type === 'month') {
|
||||
// 上个月
|
||||
for(let i = weekIndex - 1; i > 0; i--) {
|
||||
const dtemp = new Date(y,m,1);
|
||||
dtemp.setDate(dtemp.getDate() - i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: false,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
});
|
||||
}
|
||||
// 这个月的日期
|
||||
for (let i = 0; i < days; i++) {
|
||||
const dtemp = new Date(y,m,1);
|
||||
dtemp.setDate(dtemp.getDate() + i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: true,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
});
|
||||
}
|
||||
const len = 42 - result.length;
|
||||
// 下个月的日期
|
||||
for (let i = 1; i <= len;i++) {
|
||||
const dtemp = new Date(y,m+1,0);
|
||||
dtemp.setDate(dtemp.getDate() + i);
|
||||
result.push({
|
||||
time: dtemp,
|
||||
show: false,
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'),
|
||||
isToday: equalDate(new Date(), dtemp)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
<template>
|
||||
<view class="zzx-calendar">
|
||||
<view class="calendar-heander acea-row row-center-wrapper">
|
||||
<view class="title">预约时间</view>
|
||||
<view class="iconfont icon-ic_left2" :class="ymArr?'':'text-w111-ddd'" @click="daysPre(1)"></view>
|
||||
<view class="dates">{{timeStr}}</view>
|
||||
<view class="iconfont icon-ic_right2" @click="daysNext(1)"></view>
|
||||
<view class="back-today" @click="goback" v-if="showBack">
|
||||
返回今日
|
||||
</view>
|
||||
</view>
|
||||
<view class="calendar-weeks">
|
||||
<view class="calendar-week" v-for="(week, index) in weeks" :key="index">
|
||||
{{week}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="calendar-content">
|
||||
<view class="calendar-swiper" :style="{
|
||||
width: '100%',
|
||||
height: sheight
|
||||
}" :indicator-dots="false" :autoplay="false" :duration="duration" :current="current" @change="changeSwp"
|
||||
:circular="true">
|
||||
<view class="calendar-item" v-for="sitem in swiper" :key="sitem">
|
||||
<view class="calendar-days">
|
||||
<template v-if="sitem === current">
|
||||
<view class="calendar-day" v-for="(item,index) in days" :key="index" :class="{
|
||||
'day-hidden': !item.show
|
||||
}" @click="clickItem(item)">
|
||||
<view class="date" :class="[
|
||||
dotListData.indexOf(item.fullDate)==-1?'text-w111-ccc':'',
|
||||
item.isToday ? todayClass : '',
|
||||
item.fullDate == selectedDate ? checkedClass : ''
|
||||
]">
|
||||
<text v-if="item.isToday">今</text>
|
||||
<text v-else>{{item.time.getDate()>9?item.time.getDate():'0'+item.time.getDate()}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="current - sitem === 1 || current-sitem ===-2">
|
||||
<view class="calendar-day" v-for="(item,index) in predays" :key="index" :class="{
|
||||
'day-hidden': !item.show
|
||||
}">
|
||||
<view class="date" :class="[
|
||||
item.isToday ? todayClass : ''
|
||||
]">
|
||||
{{item.time.getDate()}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="calendar-day" v-for="(item,index) in nextdays" :key="index" :class="{
|
||||
'day-hidden': !item.show
|
||||
}">
|
||||
<view class="date" :class="[
|
||||
item.isToday ? todayClass : ''
|
||||
]">
|
||||
{{item.time.getDate()}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mode-change" @click="changeMode">
|
||||
<view class="iconfont" :class="weekMode ? 'icon-ic_downarrow' : 'icon-ic_uparrow'">
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
gegerateDates,
|
||||
dateEqual,
|
||||
formatDate
|
||||
} from './generateDates.js';
|
||||
export default {
|
||||
props: {
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 500
|
||||
},
|
||||
dotList: {
|
||||
type: Array, /// 打点日期列表
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
reservationDefaultDate:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
showBack: {
|
||||
type: Boolean, // 是否返回今日
|
||||
default: false
|
||||
},
|
||||
todayClass: {
|
||||
type: String, // 今日的自定义样式class
|
||||
default: 'is-today'
|
||||
},
|
||||
checkedClass: {
|
||||
type: String, // 选中日期的样式class
|
||||
default: 'is-checked'
|
||||
},
|
||||
dotStyle: {
|
||||
type: Object, // 打点日期的自定义样式
|
||||
default () {
|
||||
return {
|
||||
background: '#c6c6c6'
|
||||
}
|
||||
}
|
||||
},
|
||||
initDay: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dotList: function(newvalue) {
|
||||
const days = this.days.slice(0);
|
||||
this.days = days;
|
||||
},
|
||||
reservationDefaultDate: function(newvalue){
|
||||
this.selectedDate = newvalue
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
ymArr() {
|
||||
const nowY = new Date().getFullYear()
|
||||
const nowM = new Date().getMonth() + 1
|
||||
return nowY<this.currentYear || (nowY==this.currentYear && parseInt(nowM)<parseInt(this.currentMonth));
|
||||
},
|
||||
dotListData(){
|
||||
let data = [];
|
||||
this.dotList.forEach(item=>{
|
||||
data.push(item.date)
|
||||
})
|
||||
return data
|
||||
},
|
||||
sheight() {
|
||||
// 根据年月判断有多少行
|
||||
// 判断该月有多少天
|
||||
let h = '70rpx';
|
||||
if (!this.weekMode) {
|
||||
const d = new Date(this.currentYear, this.currentMonth, 0);
|
||||
const days = d.getDate(); // 判断本月有多少天
|
||||
let day = new Date(d.setDate(1)).getDay();
|
||||
if (day === 0) {
|
||||
day = 7;
|
||||
}
|
||||
const pre = 8 - day;
|
||||
const rows = Math.ceil((days - pre) / 7) + 1;
|
||||
h = 70 * rows + 'rpx'
|
||||
}
|
||||
return h
|
||||
},
|
||||
timeStr() {
|
||||
let str = '';
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate);
|
||||
const y = d.getFullYear();
|
||||
const m = (d.getMonth() + 1) <= 9 ? `0${d.getMonth()+1}` : d.getMonth() + 1;
|
||||
str = `${y}年${m}月`;
|
||||
return str;
|
||||
},
|
||||
predays() {
|
||||
let pres = [];
|
||||
if (this.weekMode) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate)
|
||||
d.setDate(d.getDate() - 7);
|
||||
pres = gegerateDates(d, 'week')
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 2, 1)
|
||||
pres = gegerateDates(d, 'month')
|
||||
}
|
||||
return pres;
|
||||
},
|
||||
nextdays() {
|
||||
let nexts = [];
|
||||
if (this.weekMode) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate)
|
||||
d.setDate(d.getDate() + 7);
|
||||
nexts = gegerateDates(d, 'week')
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth, 1)
|
||||
nexts = gegerateDates(d, 'month')
|
||||
}
|
||||
return nexts;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
weeks: ['一', '二', '三', '四', '五', '六', '日'],
|
||||
current: 1,
|
||||
currentYear: '',
|
||||
currentMonth: '',
|
||||
currentDate: '',
|
||||
days: [],
|
||||
weekMode: true,
|
||||
swiper: [1],
|
||||
selectedDate: this.initDay
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeSwp(e) {
|
||||
const pre = this.current;
|
||||
const current = e.target.current;
|
||||
/* 根据前一个减去目前的值我们可以判断是下一个月/周还是上一个月/周
|
||||
*current - pre === 1, -2时是下一个月/周
|
||||
*current -pre === -1, 2时是上一个月或者上一周
|
||||
*/
|
||||
this.current = current;
|
||||
if (current - pre === 1 || current - pre === -2) {
|
||||
this.daysNext();
|
||||
} else {
|
||||
this.daysPre();
|
||||
}
|
||||
},
|
||||
// 初始化日历的方法
|
||||
initDate(cur) {
|
||||
let date = ''
|
||||
if (cur) {
|
||||
date = new Date(cur)
|
||||
} else {
|
||||
date = new Date()
|
||||
}
|
||||
this.currentDate = date.getDate() // 今日日期 几号
|
||||
this.currentYear = date.getFullYear() // 当前年份
|
||||
this.currentMonth = date.getMonth() + 1 // 当前月份
|
||||
this.currentWeek = date.getDay() === 0 ? 7 : date.getDay() // 1...6,0 // 星期几
|
||||
const nowY = new Date().getFullYear() // 当前年份
|
||||
const nowM = new Date().getMonth() + 1
|
||||
const nowD = new Date().getDate() // 今日日期 几号
|
||||
const nowW = new Date().getDay();
|
||||
this.days = [];
|
||||
let days = [];
|
||||
if (this.weekMode) {
|
||||
days = gegerateDates(date, 'week');
|
||||
} else {
|
||||
days = gegerateDates(date, 'month');
|
||||
}
|
||||
this.days = days;
|
||||
// 派发事件,时间发生改变
|
||||
let obj = {
|
||||
start: '',
|
||||
end: ''
|
||||
};
|
||||
if (this.weekMode) {
|
||||
obj.start = this.days[0].time;
|
||||
obj.end = this.days[6].time
|
||||
} else {
|
||||
const start = new Date(this.currentYear, this.currentMonth - 1, 1);
|
||||
const end = new Date(this.currentYear, this.currentMonth, 0);
|
||||
obj.start = start;
|
||||
obj.end = end;
|
||||
}
|
||||
this.$emit('days-change', obj)
|
||||
},
|
||||
// 上一个
|
||||
daysPre(num) {
|
||||
if(!this.ymArr) return
|
||||
if (this.weekMode && !num) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate);
|
||||
d.setDate(d.getDate() - 7);
|
||||
this.initDate(d);
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 2, 1);
|
||||
this.initDate(d);
|
||||
}
|
||||
this.$emit('dateChange', this.currentYear + '-' + (this.currentMonth<10?'0'+this.currentMonth:this.currentMonth)); //传给调用模板页面去拿新数据
|
||||
},
|
||||
// 下一个
|
||||
daysNext(num) {
|
||||
if (this.weekMode && !num) {
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate);
|
||||
d.setDate(d.getDate() + 7);
|
||||
this.initDate(d);
|
||||
} else {
|
||||
const d = new Date(this.currentYear, this.currentMonth, 1);
|
||||
this.initDate(d);
|
||||
}
|
||||
this.$emit('dateChange', this.currentYear + '-' + (this.currentMonth<10?'0'+this.currentMonth:this.currentMonth)); //传给调用模板页面去拿新数据
|
||||
},
|
||||
changeMode() {
|
||||
const premode = this.weekMode;
|
||||
let isweek = false;
|
||||
if (premode) {
|
||||
isweek = !!this.days.find(item => item.fullDate === this.selectedDate)
|
||||
}
|
||||
this.weekMode = !this.weekMode;
|
||||
let d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate)
|
||||
const sel = new Date(this.selectedDate.replace('-', '/').replace('-', '/'));
|
||||
const isMonth = sel.getFullYear() === this.currentYear && (sel.getMonth() + 1) === this.currentMonth;
|
||||
if ((this.selectedDate && isMonth) || isweek) {
|
||||
d = new Date(this.selectedDate.replace('-', '/').replace('-', '/'))
|
||||
}
|
||||
this.initDate(d)
|
||||
},
|
||||
// 点击日期
|
||||
clickItem(e) {
|
||||
if(this.dotListData.indexOf(e.fullDate)==-1 || e.fullDate == this.selectedDate) return
|
||||
this.selectedDate = e.fullDate;
|
||||
this.$emit('dayChange', e.fullDate);
|
||||
},
|
||||
goback() {
|
||||
const d = new Date();
|
||||
this.initDate(d);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initDate();
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text-w111-ccc{
|
||||
color: #ccc !important;
|
||||
}
|
||||
.text-w111-ddd {
|
||||
color: #ddd;
|
||||
}
|
||||
.zzx-calendar {
|
||||
width: 710rpx;
|
||||
height: auto;
|
||||
background-color: #ffffff;
|
||||
margin: 20rpx auto 0 auto;
|
||||
border-radius: 16rpx;
|
||||
padding-top: 20rpx;
|
||||
.calendar-heander {
|
||||
text-align: center;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
position: relative;
|
||||
font-size: 30rpx;
|
||||
.iconfont{
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
text-align: center;
|
||||
line-height: 52rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.dates {
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
.title{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
padding-left: 24rpx;
|
||||
}
|
||||
.back-today {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100rpx;
|
||||
height: 30rpx;
|
||||
line-height: 30rpx;
|
||||
font-size: 20rpx;
|
||||
top: 15rpx;
|
||||
border-radius: 15rpx 0 0 15rpx;
|
||||
color: #ffffff;
|
||||
background-color: #FF6633;
|
||||
}
|
||||
}
|
||||
.calendar-weeks {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
margin: 26rpx 0 14rpx 0;
|
||||
.calendar-week {
|
||||
width: calc(100% / 7);
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
swiper {
|
||||
width: 100%;
|
||||
height: 60rpx;
|
||||
}
|
||||
.calendar-content {
|
||||
min-height: 60rpx;
|
||||
}
|
||||
.calendar-swiper {
|
||||
min-height: 70rpx;
|
||||
transition: height ease-out 0.3s;
|
||||
}
|
||||
.calendar-item {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.calendar-days {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
.calendar-day {
|
||||
width: calc(100% / 7);
|
||||
height: 70rpx;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.day-hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
.mode-change {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 10rpx;
|
||||
.iconfont{
|
||||
width: 80rpx;
|
||||
height: 60rpx;
|
||||
line-height: 32rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.mode-arrow-top {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 12rpx solid transparent;
|
||||
border-right: 12rpx solid transparent;
|
||||
border-bottom: 10rpx solid #FF6633;
|
||||
}
|
||||
.mode-arrow-bottom {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 12rpx solid transparent;
|
||||
border-right: 12rpx solid transparent;
|
||||
border-top: 10rpx solid #FF6633;
|
||||
}
|
||||
}
|
||||
.is-today {
|
||||
background: #ffffff;
|
||||
border-radius: 50%;
|
||||
// color: var(--view-theme);
|
||||
}
|
||||
.is-checked {
|
||||
@include main_color(theme);
|
||||
@include coupons_light_color(theme);
|
||||
font-weight: 500;
|
||||
}
|
||||
.date {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
margin: 0 auto;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.dot-show {
|
||||
margin-top: 4rpx;
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
background: #c6c6c6;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user