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

651 lines
18 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 日期组件 -->
<template>
<view class="tm-pickersDateView flex-start px-24" :class="[black_tmeme ? 'grey-darken-5' : bgColor]">
<!-- :value="value_default" @change="change" -->
<picker-view
@pickstart="$emit('aniStart')"
@pickend="$emit('aniEnd')"
@change="change"
v-if="list_cD != null"
:value="value_default"
:mask-style="black_tmeme ? 'opacity:0;' : ''"
indicator-style="height:50px;"
indicator-class="tm-pickersCView-item-h"
class="tm-pickersCView-wk"
>
<picker-view-column v-show="syheng_key[key]" v-for="(item, key) in list_cD" :key="key">
<view
class="tm-pickersCView-item fulled-height flex-center "
style="margin: 0 5px;"
:class="[value_default[key] == index_pub ? ' text-weight-b active' : '', black_tmeme ? 'bk' : '', 'text-size-n']"
v-for="(item_data, index_pub) in item"
:key="index_pub"
>
<text>{{ buqi(item_data) }}</text>
<text v-if="mode">{{ modhz[key] }}</text>
</view>
</picker-view-column>
</picker-view>
</view>
</template>
<script>
/**
* 日期下拉选择器(嵌入式)
* @description 多级关联,单级关联选择
* @property {Array} default-value = [] 默认:当前的时间,初始显示的时间
* @property {String|Number} item-height = [34|42|50|58|62] 项目的高度单位px
* @property {String|Boolean} black = [true|false] 是否开启暗黑模式。
* @property {String|Boolean} disabled = [true|false] 是否禁用
* @property {String} bg-color = [white|blue] 默认white,白色背景;请填写背景的主题色名称。
* @property {Object} show-detail = [{year:true,month:true,day:true,hour:false,min:false,sec:false}] 默认:{year:true,month:true,day:true,hour:false,min:false,sec:false}
* @property {String} start = [1900-1-1 00:00:00] 默认1900-1-1 00:00:00开始的时间
* @property {String} end = [] 默认:当前,结束的时间
* @property {String|Boolean} mode = [true|false] 默认true是否显示中文年月后缀
* @property {String|Boolean} full-number = [true|false] 默认true是否把个位数补齐双位数
*/
export default {
name: 'tm-pickersDateView',
props: {
// 行高。
itemHeight: {
type: String | Number,
default: 40
},
black: {
type: String | Boolean,
default: null
},
// 是否禁用
disabled: {
type: String | Boolean,
default: false
},
// 背景颜色,主题色名称。
bgColor: {
type: String,
default: 'white'
},
//要展示的时间。
showDetail: {
type: Object,
default: () => {
return {
year: true, //年
month: true, //月
day: true, //天
hour: false, //小时
min: false, //分
sec: false //秒
};
}
},
start: {
type: String,
default: '1949-1-1 00:00:00'
},
end: {
type: String,
default: ''
},
defaultValue: '',
// 是否显示中文年,月后缀
mode: {
type: String | Boolean,
default: true
},
//要展示的时间。
modeValue: {
type: Object,
default: () => {
return {
year: '年', //年
month: '月', //月
day: '日', //天
hour: '时', //小时
min: '分', //分
sec: '秒' //秒
};
}
},
// 是否把个位数补齐双位数
fullNumber: {
type: String | Boolean,
default: true
}
},
data() {
return {
dataCauser: {
year: false, //年
month: false, //月
day: false, //天
hour: false, //小时
min: false, //分
sec: false //秒
},
hoz: {
year: '年', //年
month: '月', //月
day: '日', //天
hour: '时', //小时
min: '分', //分
sec: '秒' //秒
},
totalRow:0,
syheng_key: {},
//当前生成的所有数据年~秒
r_list:[],
list_cD: null,
value_default: [],
nowObj:null,
};
},
created() {
this.dataCauser = {...this.dataCauser,...(this.showDetail||{})}
this.setdataCauserArray();
this._reInits();
},
mounted() {
},
watch: {
showDetail:{
deep:true,
handler(){
this.dataCauser = {...this.dataCauser,...this.showDetail};
this.setdataCauserArray();
}
},
defaultValue: function(val) {
let nowdateVal;
if (val) {
nowdateVal = new Date(val.replace(/-/g, '/'));
} else {
nowdateVal = new Date();
}
this.nowObj = nowdateVal;
if(this.list_cD==null) return;
this._reInits();
},
start: async function() {
if(this.list_cD==null) return;
this._reInits();
},
end: async function() {
if(this.list_cD==null) return;
this._reInits();
}
},
computed: {
black_tmeme: function() {
if (this.black !== null) return this.black;
return this.$tm.vx.state().tmVuetify.black;
},
modhz: function() {
let hz = [];
let moz = { ...this.hoz, ...this.modeValue };
hz.push(moz.year)
hz.push(moz.month)
hz.push(moz.day)
hz.push(moz.hour)
hz.push(moz.min)
hz.push(moz.sec)
return hz;
},
detavlue:function () {
let d = this.defaultValue;
if(!d){
let ys = new Date();
d = ys.getFullYear()+'-'+(ys.getMonth()+1)+'-'+ys.getDate()+' '+ys.getHours()+':'+ys.getMinutes()+':'+ys.getSeconds()
}
return d.replace(/-/g, '/');
},
//结束的日期,默认为当前
end_str:function () {
let d = this.end;
if(!d){
let ys = new Date();
d = ys.getFullYear()+'-'+(ys.getMonth()+1)+'-'+ys.getDate()+' '+ys.getHours()+':'+ys.getMinutes()+':'+ys.getSeconds()
}
return d.replace(/-/g, '/');
},
//开始默认为1960年
start_str:function () {
let d = this.start;
if(!d){
d='1960-1-1 00:00:00'
}
return d.replace(/-/g, '/');
},
},
methods: {
//设置显示的行当。
setdataCauserArray(){
let t = this;
let f = {
'0':this.dataCauser['year'],
'1':this.dataCauser['month'],
'2':this.dataCauser['day'],
'3':this.dataCauser['hour'],
'4':this.dataCauser['min'],
'5':this.dataCauser['sec'],
}
//显示的列表数。
let totalHoz = 0;
let p = Object.keys(this.dataCauser);
p = p.filter(el=>t.dataCauser[el]==true)
this.totalRow = p.length;
this.syheng_key = f;
},
//初始生成对应的开始和结束日期数据。
_reInits(date){
let t = this;
let nowdateVal;
if (date) {
nowdateVal = new Date(date.replace(/-/g, '/'));
} else {
nowdateVal = new Date(this.detavlue);
}
this.nowObj = nowdateVal;
/**
* 接下来,需要比对,年月,日。
* 分开比较的原因是:如果年不变的话,只是改变月,那么只需重新
* 更改日的数据(如果每月的日期一样,也不需要改变。)
*/
//根据提供的值nodwdateVal来划定开始和结束的日期数据。为了保证流畅采用一次性生成的方法。
//先生成开始的数据。
//开始
const start = new Date(this.start_str);
//结束
const end = new Date(this.end_str);
//当前
const now = nowdateVal;
let list = [];
let year = this.range(start.getFullYear(),end.getFullYear())
list.push(year)
// 月。是需要根据nowdateVal提供的值来生成。因为月是不固定的。
//默认先生成start到12的
let month_s = this.range(start.getMonth()+1,12)
let month_e = this.range(1,end.getMonth()+1)
//同年同月
if(start.getFullYear()==end.getFullYear()&&start.getMonth()==end.getMonth()){
let tn = this.range(start.getMonth()+1,end.getMonth()+1);
list.push([tn,tn])
}else{
list.push([month_s,month_e])
}
let day_s = this.range(start.getDate(),this.monthDay(start.getFullYear(),start.getMonth()))
let day_e = this.range(1,end.getDate())
//同年同月同日
if(start.getFullYear()==end.getFullYear()
&&start.getMonth()==end.getMonth()
&&start.getDate()==end.getDate()
){
let tn = this.range(start.getDate(),end.getDate());
list.push([tn,tn])
}else{
list.push([day_s,day_e])
}
let hours_s = this.range(start.getHours(),23)
let hours_e = this.range(0,end.getHours())
//同年同月同日同时
if(start.getFullYear()==end.getFullYear()
&&start.getMonth()==end.getMonth()
&&start.getDate()==end.getDate()
&&start.getHours()==end.getHours()
){
let tn = this.range(start.getHours(),end.getHours());
list.push([tn,tn])
}else{
list.push([hours_s,hours_e])
}
let minutes_s = this.range(start.getMinutes(),59)
let minutes_e = this.range(0,end.getMinutes())
//同年同月同日同时同分
if(start.getFullYear()==end.getFullYear()
&&start.getMonth()==end.getMonth()
&&start.getDate()==end.getDate()
&&start.getHours()==end.getHours()
){
let tn = this.range(start.getMinutes(),end.getMinutes());
list.push([tn,tn])
}else{
list.push([minutes_s,minutes_e])
}
let seconds_s = this.range(start.getSeconds(),59)
let seconds_e = this.range(0,end.getSeconds())
//同年同月同日同时同分同秒
if(start.getFullYear()==end.getFullYear()
&&start.getMonth()==end.getMonth()
&&start.getDate()==end.getDate()
&&start.getHours()==end.getHours()
&&start.getSeconds()==end.getSeconds()
){
let tn = this.range(start.getSeconds(),end.getSeconds());
list.push([tn,tn])
}else{
list.push([seconds_s,seconds_e])
}
this.r_list = list;
this.$nextTick(function () {
this._getListCd(start,end,now)
})
},
//生成对应的列表数据,以供选择。不需要生成所有,只要生成默认当前时间的。
_getListCd(start,end,now,issetd){
let list_cD = [];
//年
list_cD.push(this.r_list[0])
//月。
let year_s = new Date(String(start.getFullYear())+'/1/1').getTime()
let year_e = new Date(String(end.getFullYear())+'/1/1').getTime()
let year_n = new Date(String(now.getFullYear())+'/1/1').getTime()
if(
year_s===year_e //开始和结束相同
||(year_s!=year_e&&year_n==year_s) //现在=开始。
||(year_s!=year_e&&year_n<year_s) //
){
list_cD.push(this.r_list[1][0])
}else if(
(year_s!=year_e&&year_n==year_e) //=
||(year_s!=year_e&&year_n>year_e) //现在大于结束
){
list_cD.push(this.r_list[1][1])
}else{ //在开始和结束之间。
list_cD.push(this.range(1,12))
}
//日。
let day_s = new Date(start.getFullYear()+'/'+(start.getMonth()+1)+'/1').getTime()
let day_e = new Date(end.getFullYear()+'/'+(end.getMonth()+1)+'/1').getTime()
let day_n = new Date(now.getFullYear()+'/'+(now.getMonth()+1)+'/1').getTime()
if(
day_s===day_e //开始和结束相同
||(day_s!=day_e&&day_n==day_s) //现在=开始。
||(day_s!=day_e&&day_n<day_s) //
){
list_cD.push(this.r_list[2][0])
}else if(
(day_s!=day_e&&day_n==day_e) //=
||(day_s!=day_e&&day_n>day_e) //现在大于结束
){
list_cD.push(this.r_list[2][1])
}else{ //在开始和结束之间。
list_cD.push(this.range(1,this.monthDay(now.getFullYear(),now.getMonth())))
}
//时。
let hours_s = new Date(String(start.getFullYear())+'/'+(start.getMonth()+1)+'/'+start.getDate()).getTime()
let hours_e = new Date(String(end.getFullYear())+'/'+(end.getMonth()+1)+'/'+end.getDate()).getTime()
let hours_n = new Date(String(now.getFullYear())+'/'+(now.getMonth()+1)+'/'+now.getDate()).getTime()
if(
hours_s===hours_e //开始和结束相同
||(hours_s!=hours_e&&hours_n==hours_s) //现在=开始。
||(hours_s!=hours_e&&hours_n<hours_s) //
){
list_cD.push(this.r_list[3][0])
}else if(
(hours_s!=hours_e&&hours_n==hours_e) //=
||(hours_s!=hours_e&&hours_n>hours_e) //现在大于结束
){
list_cD.push(this.r_list[3][1])
}else{ //在开始和结束之间。
list_cD.push(this.range(0,23))
}
//分。
let min_s = new Date(String(start.getFullYear())+'/'+(start.getMonth()+1)+'/'+start.getDate()+' '+start.getHours()+':00:00').getTime()
let min_e = new Date(String(end.getFullYear())+'/'+(end.getMonth()+1)+'/'+end.getDate()+' '+end.getHours()+':00:00').getTime()
let min_n = new Date(String(now.getFullYear())+'/'+(now.getMonth()+1)+'/'+now.getDate()+' '+now.getHours()+':00:00').getTime()
if(
min_s===min_e //开始和结束相同
||(min_s!=min_e&&min_n==min_s) //现在=开始。
||(min_s!=min_e&&min_n<min_s) //
){
list_cD.push(this.r_list[4][0])
}else if(
(min_s!=min_e&&min_n==min_e) //=
||(min_s!=min_e&&min_n>min_e) //现在大于结束
){
list_cD.push(this.r_list[4][1])
}else{ //在开始和结束之间。
list_cD.push(this.range(0,59))
}
//秒。
let seccode_s = new Date(String(start.getFullYear())+'/'+(start.getMonth()+1)+'/'+start.getDate()+' '+start.getHours()+':'+start.getMinutes()+':00').getTime()
let seccode_e = new Date(String(end.getFullYear())+'/'+(end.getMonth()+1)+'/'+end.getDate()+' '+end.getHours()+':'+start.getMinutes()+':00').getTime()
let seccode_n = new Date(String(now.getFullYear())+'/'+(now.getMonth()+1)+'/'+now.getDate()+' '+now.getHours()+':'+start.getMinutes()+':00').getTime()
if(
seccode_s===seccode_e //开始和结束相同
||(seccode_s!=seccode_e&&seccode_n==seccode_s) //现在=开始。
||(seccode_s!=seccode_e&&seccode_n<seccode_s) //
){
list_cD.push(this.r_list[4][0])
}else if(
(seccode_s!=seccode_e&&seccode_n==seccode_e) //=
||(seccode_s!=seccode_e&&seccode_n>seccode_e) //现在大于结束
){
list_cD.push(this.r_list[4][1])
}else{ //在开始和结束之间。
list_cD.push(this.range(0,59))
}
this.$nextTick(function () {
this.list_cD = list_cD;
if(!issetd){
this.$nextTick(function () {
this.setDefaultIndex();
})
}
})
},
monthDay(year, month) {
let date = new Date(year, month, 1, 0, 0, 0);
date.setMonth(date.getMonth()+1)
let yesterDay = new Date(date - 1000);
return yesterDay.getDate();
},
//生成一个数据数组。
range(from=0,to){
const range = [];
if(from===to) return [from];
for (let i = from; i <= to; i++) {
range.push(i)
}
return range
},
//设置当前选中的索引。
setDefaultIndex(){
if(!this.list_cD) return;
let value_default = [];
let t = this;
// 年。
let year = this.list_cD[0].findIndex(el=>el==t.nowObj.getFullYear());
year=year<=0?0:year;
let month = this.list_cD[1].findIndex(el=>el==t.nowObj.getMonth()+1);
month=month<=0?0:month;
let day = this.list_cD[2].findIndex(el=>el==t.nowObj.getDate());
day=day<=0?0:day;
let hours = this.list_cD[3].findIndex(el=>el==t.nowObj.getHours());
hours=hours<=0?0:hours;
let minutes = this.list_cD[4].findIndex(el=>el==t.nowObj.getMinutes());
minutes=minutes<=0?0:minutes;
let seconds = this.list_cD[5].findIndex(el=>el==t.nowObj.getSeconds());
seconds=seconds<=0?0:seconds;
// 开始设置,如果当前默认的日期不在范围内。默认选中的索引日期。
value_default = [year,month,day,hours,minutes,seconds]
this.$nextTick(function () {
this.value_default = value_default;
})
},
//回显到初始化值。
resetVal(setd){
let val = this.defaultValue;
if(setd) val = setd;
let nowdateVal;
if (val) {
nowdateVal = new Date(val.replace(/-/g, '/'));
} else {
nowdateVal = new Date();
}
this.nowObj = nowdateVal;
if(this.list_cD==null) return;
this._reInits();
this.$nextTick(function () {
this.setDefaultIndex();
})
},
buqi(val) {
return val > 9 ? '' + val : '0' + val;
},
//通过索引获取当前数据
SeletecdeIndexdefault(value_default) {
if(!value_default) value_default = this.value_default;
let t = this;
let ap = [];
this.value_default.forEach((item,index) => {
let f = t.list_cD[index][parseInt(item)];
f = typeof(f)=="undefined"? t.list_cD[index][ t.list_cD[index].length-1]:f;
ap.push(f);
});
return ap;
},
// 获取当前选中的数据。
getSelectedValue() {
let t = this;
let ap = this.SeletecdeIndexdefault();
let jg = {
year: ap[0], //年
month: ap[1], //月
day: ap[2], //天
hour: ap[3], //小时
min: ap[4], //分
sec: ap[5] //秒
};
let ar = Object.keys(this.dataCauser);
ar.forEach(item => {
if (t.dataCauser[item] === false) {
delete jg[item];
}
});
return jg;
},
getSelsectDate() {
let t = this;
let ap = this.SeletecdeIndexdefault();
let jg = {
year: ap[0], //年
month: ap[1], //月
day: ap[2], //天
hour: ap[3], //小时
min: ap[4], //分
sec: ap[5] //秒
};
return new Date(ap[0]+'/'+ap[1]+'/'+ap[2]+' '+ap[3]+':'+ap[4]+':'+ap[5]);
},
change(e) {
//滑动后,要动态修改数据。
let val = e.detail.value;
let index =0;
// 找出修改的index项。
let nowD = [this.nowObj.getFullYear(),1,1,0,0,0];
let nowObj = [this.nowObj.getFullYear(),this.nowObj.getMonth()+1,this.nowObj.getDate(),this.nowObj.getHours(),this.nowObj.getMinutes(),this.nowObj.getSeconds()];
for (var i = 0; i < 6; i++) {
if(this.value_default[i]!==val[i]){
nowD[i] = this.list_cD[i][val[i]]
}else{
let idx = this.list_cD[i].findIndex(el=>el==nowObj[i])
if(idx==-1){
nowD[i] = this.list_cD[i][0]
}else{
nowD[i] = nowObj[i]
}
}
}
const now = nowD[0]+'/'+(nowD[1])+'/'+nowD[2]+' '+nowD[3]+':'+nowD[4]+':'+nowD[5];
this._reInits(now)
let nowVal = val.map(el=>{
let dsdd = el<=0?0:el;
return dsdd
})
this.$nextTick(function () {
this.value_default = nowVal;
// 发送滚动选中的时间数据。
this.$emit('change',this.getSelectedValue());
})
},
jswid() {
let wd = this.gridNum - 1 - 2;
if (wd <= 0) wd = 1;
return 100 / wd;
},
}
};
</script>
<style>
.tm-pickersDateView .tm-pickersCView-item-h {
height: 50px;
background-color: rgba(0, 0, 0, 0.03);
width: calc(100% - 10px);
margin-left: 5px;
border-radius: 20rpx;
border: none;
}
.tm-pickersDateView .tm-pickersCView-item-h::after,
.tm-pickersDateView .tm-pickersCView-item-h::before {
border: none;
}
.tm-pickersDateView .tm-pickersCView-wk {
position: relative;
width: 750rpx;
height: 500rpx;
}
.tm-pickersDateView .tm-pickersCView-wk .tm-pickersCView-item.bk {
opacity: 0.4;
}
.tm-pickersDateView .tm-pickersCView-wk .tm-pickersCView-item.active {
opacity: 1;
border-radius: 20rpx;
border: none;
background-color: rgba(0, 0, 0, 0.06);
}
.tm-pickersDateView .tm-pickersCView-wk .tm-pickersCView-item.active.bk {
background-color: rgba(255, 255, 255, 0.06);
}
</style>