<template>
<view class="ccq-week-picker">
<view class="ccq-week-popup_header">
<text class="cancel" @click="onCancel">取消</text>
<text class="title">选择时间</text>
<text class="sure" @click="onSure">确定</text>
</view>
<view class="typeList">
<view
class="typeItem"
v-for="(item, index) in typeList"
:key="item.value"
:class="{ on: type === item.value }"
@click="changeType(index)"
>{{ item.name }}</view
>
<!-- <u-subsection :list="typeList" :current="formatType" @change="changeType"></u-subsection>-->
</view>
<view class="valueBox">
<view v-if="type !== 'custom'">{{ checkval }}</view>
<view class="valueBox-custom" v-else>
<view
class="startTime customTime"
:class="{ on: editTimeKey === 0, customtext: !formatTime(result[0]) }"
@click="changeCustom(0)"
>
{{ formatTime(result[0]) || " 请选择开始时间 " }}
</view>
<view>-</view>
<view
class="endTime customTime"
:class="{ on: editTimeKey === 1, customtext: !formatTime(result[1]) }"
@click="changeCustom(1)"
>
{{ formatTime(result[1]) || " 请选择结束时间 " }}
</view>
</view>
</view>
<picker-view
:value="pickerValue"
@change="bindChange"
class="ccq-week-picker_view"
indicatorStyle="height: 80rpx;"
@pickstart="pickStart"
@pickend="pickEnd"
>
<picker-view-column class="ccq-week-picker_item years">
<view
class="ccq-week-picker_item_view"
:style="{ height: height + 'px' }"
v-for="(item, index) in years"
:key="index"
>{{ item }}年</view
>
</picker-view-column>
<picker-view-column
class="ccq-week-picker_item months"
v-if="type !== 'week'"
>
<view
class="ccq-week-picker_item_view"
:style="{ height: height + 'px' }"
v-for="(item, index) in months"
:key="index"
>{{ index + 1 }}月</view
>
</picker-view-column>
<picker-view-column
class="ccq-week-picker_item days"
v-if="(type === 'day' || type === 'custom' || type === 'oldday')&&showDays"
>
<view
class="ccq-week-picker_item_view"
:style="{ height: height + 'px' }"
v-for="(item, index) in days"
:key="index"
>{{ index + 1 }}日</view
>
</picker-view-column>
<picker-view-column
class="ccq-week-picker_item weeks"
v-if="type === 'week'"
>
<view
class="ccq-week-picker_item_view"
:style="{ height: height + 'px' }"
v-for="(item, index) in weeks"
:key="index"
>{{ index + 1 }}周</view
>
</picker-view-column>
</picker-view>
</view>
</template>
<script>
import dayjs from "dayjs";
import weekOfYear from "dayjs/plugin/weekOfYear";
import isoWeeksInYear from "dayjs/plugin/isoWeeksInYear";
import isoWeek from "dayjs/plugin/isoWeek";
import isLeapYear from "dayjs/plugin/isLeapYear";
dayjs.extend(isLeapYear);
dayjs.extend(isoWeek);
dayjs.extend(weekOfYear);
dayjs.extend(isoWeeksInYear);
const nowDate = new Date();
var yesterTime = new Date().getTime();
var yesterTimeStamp = new Date(yesterTime);
var month = yesterTimeStamp.getMonth(); //昨天的月
var day = yesterTimeStamp.getDate(); //昨天的日
//昨天的日期20220630
var yesterday =
yesterTimeStamp.getFullYear() +
"" +
(yesterTimeStamp.getMonth() > 9
? yesterTimeStamp.getMonth() + 1
: "0" + (yesterTimeStamp.getMonth() + 1)) +
"" +
(yesterTimeStamp.getDate() > 9
? yesterTimeStamp.getDate()
: "0" + yesterTimeStamp.getDate());
export default {
name: "ccq-week-picker",
props: {
value: {
type: String,
default: "",
},
currentType: {
type: String,
default: "day",
},
typeList: {
type: Array,
default: () => {
return [
{ name: "今日", value: "day" },
{ name: "昨日", value: "oldday" },
{ name: "本周", value: "week" },
{ name: "本月", value: "month" },
{ name: "自定义", value: "custom" },
];
},
},
/**
* 格式化
* 0: 2021-06-01
* 1: 2021年06月01日
*/
formatType: {
type: Number,
default: 0,
},
// 列的高度
height: {
type: [Number, String],
default: 50,
},
// 自定义类型时 日期最大跨度 默认30天
customMax: {
type: [Number],
default: 30,
},
//是否解除30天限制
unfreeze:{
type:Boolean,
default:false
}
},
data() {
return {
years: [],
months: 12,
days: 30,
weeks: 52,
pickerValue: [0, 0, 0],
result: [],
type: "",
editTimeKey: 0,
record: [], //选择过的日期记录
isMoveing: false,
showDays:true,
update:0,
};
},
watch: {
pickerValue(newValue) {
//监听控制可选择范围
if (this.pickerValue[0] == 0) {
//当选择最新一年时
this.months = new Date().getMonth() + 1;
if (this.type == "day" || this.type === "oldday") {
//按日时 可选当天
// 当前结果日期
const currentValue = this.result[0].split("-");
if (
new Date().getFullYear() == currentValue[0] &&
new Date().getMonth() + 1 == currentValue[1]
) {
//同年当月
this.days = new Date().getDate();
} else {
this.days = dayjs(this.result[0]).daysInMonth();
}
}
if (this.type == "custom") {
//按自定义时 控制日最大值
if (this.pickerValue[1] + 1 == new Date().getMonth() + 1) {
this.days = new Date().getDate();
} else {
if ([1, 3, 5, 7, 8, 10, 12].includes(this.pickerValue[1] + 1)) {
this.days = 31;
} else if ([4, 6, 9, 11].includes(this.pickerValue[1] + 1)) {
this.days = 30;
} else if (this.pickerValue[1] + 1 === 2) {
this.days = new Date().getFullYear() % 4 ? 28 : 29;
}
}
}
if (this.type == "week") {
//最新一年的周最大值
if (dayjs().day() == 1) {
//明天测
this.weeks = dayjs().isoWeek();
} else {
this.weeks = dayjs().isoWeek();
}
}
} else {
if (
this.type == "day" ||
this.type == "custom" ||
this.type == "oldday"
) {
this.days = dayjs(this.result[0]).daysInMonth();
}
this.months = 12;
this.weeks = 52;
}
this.showDays = true
},
},
computed: {
checkval() {
//计算返回日期格式
if (this.type === "day" || this.type == "oldday") {
let weekWord = ["日", "一", "二", "三", "四", "五", "六"];
let oldyesterTime = new Date().getTime() - 24 * 60 * 60 * 1000;
let oldyesterTimeStamp = new Date(oldyesterTime);
//昨天的日期20220630
let oldyesterday =
oldyesterTimeStamp.getFullYear() +
"" +
(oldyesterTimeStamp.getMonth() > 9
? oldyesterTimeStamp.getMonth() + 1
: "0" + (oldyesterTimeStamp.getMonth() + 1)) +
"" +
(oldyesterTimeStamp.getDate() > 9
? oldyesterTimeStamp.getDate()
: "0" + oldyesterTimeStamp.getDate());
if (this.result[0] == dayjs().format("YYYY-MM-DD")) {
return `${dayjs(this.result[0]).format("YYYY年MM月DD日")} (今日)`;
} else if (this.result[0] == dayjs(oldyesterday).format("YYYY-MM-DD")) {
return `${dayjs(this.result[0]).format("YYYY年MM月DD日")} (昨日)`;
} else {
return `${dayjs(this.result[0]).format("YYYY年MM月DD日")} (周${
weekWord[dayjs(this.result[0]).day()]
})`;
}
} else if (this.type === "week") {
return `${dayjs(this.result[0]).format("YYYY年")}${
this.pickerValue[1] + 1
}周 ${dayjs(this.result[0]).format("MM月DD日")}-${dayjs(
this.result[1]
).format("MM月DD日")}`;
} else if (this.type === "month") {
return `${dayjs(this.result[0]).format("YYYY年MM月")} ${dayjs(
this.result[0]
).format("MM月DD日")}-${dayjs(this.result[1]).format("MM月DD日")}`;
}
return dayjs().format("YYYY-MM-DD");
},
},
created() {
this.$nextTick(() => {
this.type = this.currentType;
console.log(this.type, "类型");
this.dateInit();
});
},
methods: {
pickStart() {
this.isMoveing = true;
},
pickEnd() {
this.isMoveing = false;
},
//添加日期选择记录
addRecord(item) {
var record = JSON.parse(JSON.stringify(this.record));
record = record.filter((e) => {
return e.type != item.type;
});
record.unshift(item);
this.record = record;
},
async dateInit() {
this.$set(this.pickerValue, 0, 0);
//初始化 控制选择范围
var date = yesterday;
if (this.type == "oldday") {
date = dayjs().subtract(1, "days").format("YYYYMMDD");
}
if (this.type == "day") date = dayjs().format("YYYYMMDD");
let v = dayjs(date).format("YYYY-MM-DD").split("-");
let s = Number(v[0]) - 50;
let e = Number(v[0]);
let y = Number(v[0]),
y_index;
let m = Number(v[1]);
// 年
let arr = []
for (let i = s; i <= e; i++) {
if (i == y) {
//所选年的index
y = i;
y_index = e - s - (e - y);
}
arr.unshift(i);
}
this.years = arr
// 月
for (let i = 1; i <= 12; i++) {
if (i == Number(m)) {
//所选月的index
m = i;
break;
}
}
this.$set(this.pickerValue, 1, dayjs(date).month());
if ([1, 3, 5, 7, 8, 10, 12].includes(dayjs(date).month())) {
this.days = 31;
} else if ([4, 6, 9, 11].includes(dayjs(date).month())) {
this.days = e % 4 ? 29 : 28;
} else if (dayjs(date).month() === 2) {
this.days = e % 4 ? 29 : 28;
}
this.$set(this.pickerValue, 2, dayjs(date).date() - 1);
this.result = [
dayjs(date).format("YYYY-MM-DD"),
dayjs(date).format("YYYY-MM-DD"),
];
const pickerValueCopy = JSON.parse(JSON.stringify(this.pickerValue));
this.pickerValue = [];
this.$nextTick(() => {
this.pickerValue = pickerValueCopy;
});
},
//选择日期类型
changeType(index) {
let type = this.typeList[index].value;
if (this.type === type) return;
this.type = type;
if (type === "day") {
this.dateInit();
} else if (type === "oldday") {
this.dateInit();
} else if (type === "week") {
this.pickerValue = [0, dayjs().isoWeek() - 1];
this.result = [
dayjs().startOf("isoWeek").format("YYYY-MM-DD"),
dayjs().format("YYYY-MM-DD"),
];
} else if (type === "month") {
this.pickerValue = [0, dayjs().month()];
this.result = [
dayjs().startOf("month").format("YYYY-MM-DD"),
dayjs().format("YYYY-MM-DD"),
];
} else {
this.pickerValue = [0, dayjs().month(), dayjs().date() - 1];
}
this.editTimeKey = 0;
},
// 自定义切换
changeCustom(key) {
if (this.editTimeKey === key) return;
// this.showDays = false
this.editTimeKey = key;
let date = this.result[key].split('-')
let years = 0
this.years.forEach((val,index)=>{
if(val==date[0]){
years = index
}
})
let result = [years,date[1] - 1,date[2] - 1]
// this.$nextTick(()=>{
// setTimeout(()=>{
this.pickerValue = result
// },300)
// })
},
formatWord(num) {
return num > 9 ? `${num}` : `0${num}`;
},
formatTime(time) {
return time ? dayjs(time).format("YYYY年MM月DD日") : "";
},
// picker change
//选择日期
bindChange: function (e) {
let v = e.detail.value;
this.pickerValue = v;
//限定日的选择范围
if (this.type !== "week" && this.type !== "month") {
if ([1, 3, 5, 7, 8, 10, 12].includes(v[1] + 1)) {
this.days = 31;
} else if (v[1] + 1 === 2) {
this.days = this.years[v[0]] % 4 ? 29 : 28;
} else {
this.days = 30;
}
if (this.days < v[2] + 1) v[2] = this.days - 1;
}
if (this.type === "day" || this.type === "oldday") {
this.result = [
`${this.years[v[0]]}-${this.formatWord(v[1] + 1)}-${this.formatWord(
v[2] + 1
)}`,
`${this.years[v[0]]}-${this.formatWord(v[1] + 1)}-${this.formatWord(
v[2] + 1
)}`,
];
} else if (this.type === "week") {
var selectWeek = v[1] + 1; //第几周
const today = dayjs().format("YYYY-MM-DD");
const firstDayOfWeek = dayjs()
.isoWeek(selectWeek)
.startOf("isoWeek")
.format("YYYY-MM-DD");
let endDayOfWeek = dayjs()
.isoWeek(selectWeek)
.endOf("isoWeek")
.format("YYYY-MM-DD");
if (today === endDayOfWeek) {
endDayOfWeek = today;
}
this.result = [firstDayOfWeek, endDayOfWeek];
} else if (this.type === "month") {
let time = `${this.years[v[0]]}-${this.formatWord(v[1] + 1)}`;
this.result = [
dayjs(time).startOf("month").format("YYYY-MM-DD"),
dayjs(time).endOf("month").format("YYYY-MM-DD"),
];
} else if (this.type === "custom") {
let time = `${this.years[v[0]]}-${this.formatWord(v[1] + 1)}-${this.formatWord(v[2] + 1)}`;
this.result[this.editTimeKey] = time;
if (this.editTimeKey == 1) {
//调整自定义--结束时间时
if (dayjs(this.result[0]).isAfter(dayjs(this.result[1]))) {
this.result[0] = dayjs(this.result[1]).subtract(this.customMax, "day").format("YYYY-MM-DD");
} else {
if (-1 * dayjs(this.result[0]).diff(dayjs(this.result[1]), "day") >= this.customMax + 1) {
//选择开始时间 发现与结束时间相差大于31天时
this.$nextTick(() => {
this.result[0] = dayjs(this.result[1])
.subtract(this.customMax, "day")
.format("YYYY-MM-DD");
this.update++ // 更新视图
})
}
}
} else {
//调整自定义--开始时间时
if (dayjs(this.result[0]).isAfter(dayjs(this.result[1]))) {
if (dayjs().isBefore(dayjs(dayjs(this.result[0]).add(this.customMax, "day").format("YYYY-MM-DD")))) {
//增加30天后的日期大于今天
this.result[1] = dayjs().subtract(1, "day").format("YYYY-MM-DD");
} else {
this.result[1] = dayjs(this.result[0]).add(this.customMax, "day").format("YYYY-MM-DD");
}
}
else {
if (dayjs(this.result[1]).diff(dayjs(this.result[0]), "day") >= this.customMax + 1) {
//选择开始时间 发现与结束时间相差大于31天时
this.result[1] = dayjs(this.result[0]).add(this.customMax, "day").format("YYYY-MM-DD");
}
}
}
}
this.addRecord({
type: this.type,
result: this.result,
pickerValue: this.pickerValue,
});
},
// 取消
onCancel() {
this.$emit("cancal");
},
// 确认
onSure() {
if (this.isMoveing) {
return;
}
if (this.type === "custom") {
if (!this.result[0] || !this.result[1]) {
return;
}
if (dayjs(this.result[0]).isAfter(dayjs(this.result[1]))) {
return;
}
}
this.$nextTick(() => {
this.$emit("change", this.result, this.type, this.checkval);
});
},
},
};
</script>
<style lang="scss" scoped>
.ccq-week-picker {
background-color: #ffffff;
.typeList {
display: flex;
justify-content: space-between;
padding: 24rpx;
.typeItem {
padding: 14rpx 32rpx;
border-radius: 8rpx;
border: 2rpx solid #dcdcdc;
display: flex;
justify-content: center;
align-items: center;
}
.on {
font-size: 26rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #19b691;
line-height: 36rpx;
background: #e9faf3;
border-radius: 8rpx;
border: 2rpx solid #19b691;
}
}
.valueBox {
font-size: 28rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: rgba(0, 0, 0, 0.9);
line-height: 44rpx;
display: flex;
justify-content: center;
align-items: center;
.valueBox-custom {
display: flex;
align-items: center;
justify-content: center;
.startTime {
margin-right: 24rpx;
}
.endTime {
margin-left: 24rpx;
}
.customTime {
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: rgba(0, 0, 0, 0.9);
line-height: 44rpx;
width: 318rpx;
height: 64rpx;
background: #f3f3f3;
border-radius: 8rpx;
display: flex;
justify-content: center;
align-items: center;
}
.customtext {
// color: rgba(0,0,0,.26);
}
.on {
background-color: $u-type-primary-c;
color: rgba(0, 0, 0, 0.6);
}
}
}
}
.ccq-week-popup_header {
width: 100%;
height: 112rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 42rpx;
border-bottom: 1rpx solid #e7e7e7;
.cancel {
font-size: 32rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.6);
line-height: 48rpx;
}
.title {
font-size: 32rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: rgba(0, 0, 0, 0.9);
line-height: 48rpx;
}
.sure {
font-size: 32rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #19b691;
line-height: 48rpx;
}
}
.ccq-week-popup-text {
font-size: 32rpx;
&.cancel {
color: rgba(0, 0, 0, 0.6);
}
&.sure {
color: #1ab592;
}
}
.ccq-week-picker_view {
width: 100%;
height: 500rpx;
}
.ccq-week-picker_item {
display: flex;
align-items: center;
justify-content: center;
&.years {
flex: 1;
}
&.months {
flex: 1;
}
&.weeks {
flex: 1;
}
}
.ccq-week-picker_item_view {
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
</style>
需要下载dayjs
页面使用:
<u-popup v-model="showScreen" border-radius="16" mode="bottom" height="800rpx">
<weekPicker :customMax="3600" :unfreeze="true" @change="changeTypeOption" @cancal="showScreen = false"
ref="weekPicker">
</weekPicker>
</u-popup>
显示时间:
<view style="padding: 24rpx 0 0 24rpx;font-size: 32rpx;line-height: 48rpx;font-weight: 600;"
@click="showScreen = true">{{showDate}}
<text class="fwhfont icon-icon-caret-down" style="font-size: 40rpx;"></text>
</view>
// 日期变化
changeTypeOption(arr, type, checkval) {
console.log(arr, type, checkval);
var now = new Date();
var selectDate = '';
if (type === 'day') {
selectDate = checkval.substr(5, checkval.length);
}
if (type === 'week') {
selectDate = checkval.substr(5, checkval.length);
}
if (type === 'month') {
selectDate = checkval;
if (dayjs(arr[1]).isBefore(dayjs(dayjs(now).format('YYYY-MM-DD')))) { //选择的月底日期在今天之前为true
} else {
let nowYear = now.getFullYear();
let nowMonth = now.getMonth() + 1 > 9 ? now.getMonth() + 1 : '0' + (now.getMonth() + 1);
let nowDate = now.getDate();
arr[1] = nowYear + '-' + nowMonth + '-' + (nowDate > 9 ? nowDate : '0' + nowDate);
}
}
if (type === 'custom') {
selectDate = arr[0] + '-' + arr[1];
}
this.showScreen = false;
this.typeSelect = type;
this.checkval = checkval;
this.typeOption = arr
let stimer = (new Date(arr[0]).getTime() / 1000) + ''
console.log(stimer, 'stimer', new Date('2023-06-26').getTime());
this.sTime = type === 'day' ? '' : stimer;
let etimer = new Date(arr[1])
etimer.setHours(24, 0, 0, 0)
this.eTime = type === 'day' ? '' : (etimer.getTime() / 1000) + '';
this.showDate = this.getShowDate();
this.currPage = 0;
this.Backup()
this.getDouTypeCouponList()
},
getShowDate() {
if (this.typeSelect === 'day') {
let weekWord = ['日', '一', '二', '三', '四', '五', '六'];
if (!Number(this.checkval.substr(0, 4))) {
//默认当天日期
var nowDay = dayjs().format('YYYYMMDD');
return nowDay.substr(4, 2) + '月' + nowDay.substr(6, 2) + '日' + '(今日)';
}
if (Number(this.checkval.substr(0, 4)) < currentDate.getFullYear()) {
return this.checkval;
} else {
return this.checkval.substring(5); //.substr(5,this.checkval.length)
}
} else if (this.typeSelect === 'oldday') {
return this.checkval.substring(5);
} else if (this.typeSelect === 'week') {
return this.checkval;
} else if (this.typeSelect === 'month') {
return this.checkval;
} else if (this.typeSelect === 'custom') {
var dateArr =
this.typeOption[0].substr(0, 4) +
'年' +
this.typeOption[0].substr(5, 2) +
'月' +
this.typeOption[0].substr(8, 2) +
'日' +
'-' +
(this.typeOption[0].substr(0, 4) == this.typeOption[1].substr(0, 4) ? '' : this.typeOption[1]
.substr(0, 4) + '年') +
this.typeOption[1].substr(5, 2) +
'月' +
this.typeOption[1].substr(8, 2) +
'日';
return dateArr;
}
},