混凝土运输管理微信小程序、替班
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.
 
 
 

321 lines
7.4 KiB

<template>
<view class="select-datetime-container">
<picker
mode="multiSelector"
:range="pickerRange"
:value="pickerValue"
@change="onPickerChange"
@columnchange="onColumnChange"
>
<slot>
<view class="datetime-display">
<text>{{ displayText }}</text>
<uv-icon name="arrow-down" size="16" color="#999"></uv-icon>
</view>
</slot>
</picker>
</view>
</template>
<script>
export default {
name: 'SelectDatetime',
props: {
// 选择器类型: 'datetime', 'date', 'time'
type: {
type: String,
default: 'datetime'
},
// 默认值
value: {
type: String,
default: ''
},
// 占位文本
placeholder: {
type: String,
default: '请选择时间'
},
// 最小年份
minYear: {
type: Number,
default: 2020
},
// 最大年份
maxYear: {
type: Number,
default: 2030
}
},
data() {
return {
pickerValue: [0, 0, 0, 0, 0],
pickerRange: [],
currentDate: new Date(),
selectedDateTime: ''
}
},
computed: {
displayText() {
if (this.selectedDateTime) {
return this.selectedDateTime;
}
return this.placeholder;
},
// 年份数组
years() {
const years = [];
for (let i = this.minYear; i <= this.maxYear; i++) {
years.push(i + '年');
}
return years;
},
// 月份数组
months() {
const months = [];
for (let i = 1; i <= 12; i++) {
months.push(i + '月');
}
return months;
},
// 日期数组
days() {
const year = this.minYear + this.pickerValue[0];
const month = this.pickerValue[1] + 1;
const daysInMonth = new Date(year, month, 0).getDate();
const days = [];
for (let i = 1; i <= daysInMonth; i++) {
days.push(i + '日');
}
return days;
},
// 小时数组
hours() {
const hours = [];
for (let i = 0; i < 24; i++) {
hours.push(i.toString().padStart(2, '0') + '时');
}
return hours;
},
// 分钟数组
minutes() {
const minutes = [];
for (let i = 0; i < 60; i += 5) { // 每5分钟一个选项
minutes.push(i.toString().padStart(2, '0') + '分');
}
return minutes;
}
},
mounted() {
this.initPicker();
if (this.value) {
this.parseValue(this.value);
}
},
watch: {
value(newVal) {
if (newVal) {
this.parseValue(newVal);
}
},
type() {
this.initPicker();
}
},
methods: {
// 初始化选择器
initPicker() {
switch (this.type) {
case 'datetime':
this.pickerRange = [this.years, this.months, this.days, this.hours, this.minutes];
this.pickerValue = [0, 0, 0, 0, 0];
break;
case 'date':
this.pickerRange = [this.years, this.months, this.days];
this.pickerValue = [0, 0, 0];
break;
case 'time':
this.pickerRange = [this.hours, this.minutes];
this.pickerValue = [0, 0];
break;
}
this.setDefaultValue();
},
// 设置默认值为当前时间
setDefaultValue() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const day = now.getDate() - 1;
const hour = now.getHours();
const minute = Math.floor(now.getMinutes() / 5);
switch (this.type) {
case 'datetime':
this.pickerValue = [
year - this.minYear,
month,
day,
hour,
minute
];
break;
case 'date':
this.pickerValue = [
year - this.minYear,
month,
day
];
break;
case 'time':
this.pickerValue = [hour, minute];
break;
}
this.updateDisplayText();
},
// 解析传入的值
parseValue(value) {
try {
const date = new Date(value);
if (isNaN(date.getTime())) {
return;
}
const year = date.getFullYear();
const month = date.getMonth();
const day = date.getDate() - 1;
const hour = date.getHours();
const minute = Math.floor(date.getMinutes() / 5);
switch (this.type) {
case 'datetime':
this.pickerValue = [
year - this.minYear,
month,
day,
hour,
minute
];
break;
case 'date':
this.pickerValue = [
year - this.minYear,
month,
day
];
break;
case 'time':
this.pickerValue = [hour, minute];
break;
}
this.updateDisplayText();
} catch (e) {
console.error('解析时间值失败:', e);
}
},
// 选择器值改变
onPickerChange(e) {
this.pickerValue = e.detail.value;
this.updateDisplayText();
this.emitChange();
},
// 列改变时更新日期选项
onColumnChange(e) {
const column = e.detail.column;
const value = e.detail.value;
// 如果改变的是年份或月份,需要更新日期选项
if ((column === 0 || column === 1) && this.type !== 'time') {
this.pickerValue[column] = value;
this.$nextTick(() => {
this.pickerRange[2] = this.days;
// 如果当前选择的日期超出了新月份的天数,调整到最后一天
if (this.pickerValue[2] >= this.days.length) {
this.pickerValue[2] = this.days.length - 1;
}
});
}
},
// 更新显示文本
updateDisplayText() {
switch (this.type) {
case 'datetime':
this.selectedDateTime = `${this.years[this.pickerValue[0]]} ${this.months[this.pickerValue[1]]} ${this.days[this.pickerValue[2]]} ${this.hours[this.pickerValue[3]]} ${this.minutes[this.pickerValue[4]]}`;
break;
case 'date':
this.selectedDateTime = `${this.years[this.pickerValue[0]]} ${this.months[this.pickerValue[1]]} ${this.days[this.pickerValue[2]]}`;
break;
case 'time':
this.selectedDateTime = `${this.hours[this.pickerValue[0]]} ${this.minutes[this.pickerValue[1]]}`;
break;
}
},
// 发送改变事件
emitChange() {
let dateValue = '';
switch (this.type) {
case 'datetime':
const year = this.minYear + this.pickerValue[0];
const month = (this.pickerValue[1] + 1).toString().padStart(2, '0');
const day = (this.pickerValue[2] + 1).toString().padStart(2, '0');
const hour = this.pickerValue[3].toString().padStart(2, '0');
const minute = (this.pickerValue[4] * 5).toString().padStart(2, '0');
dateValue = `${year}-${month}-${day} ${hour}:${minute}:00`;
break;
case 'date':
const dateYear = this.minYear + this.pickerValue[0];
const dateMonth = (this.pickerValue[1] + 1).toString().padStart(2, '0');
const dateDay = (this.pickerValue[2] + 1).toString().padStart(2, '0');
dateValue = `${dateYear}-${dateMonth}-${dateDay}`;
break;
case 'time':
const timeHour = this.pickerValue[0].toString().padStart(2, '0');
const timeMinute = (this.pickerValue[1] * 5).toString().padStart(2, '0');
dateValue = `${timeHour}:${timeMinute}:00`;
break;
}
this.$emit('change', {
value: dateValue,
displayText: this.selectedDateTime,
pickerValue: this.pickerValue
});
}
}
}
</script>
<style scoped lang="scss">
.select-datetime-container {
width: 100%;
}
.datetime-display {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx;
background-color: #fff;
border: 1rpx solid #e0e0e0;
border-radius: 8rpx;
font-size: 28rpx;
color: #333;
text {
flex: 1;
}
}
</style>