|
|
|
|
<!--
|
|
|
|
|
@ 作者: 秦东
|
|
|
|
|
@ 时间: 2024-11-14 13:08:53
|
|
|
|
|
@ 备注: 日期选择器
|
|
|
|
|
-->
|
|
|
|
|
<script lang='ts' setup>
|
|
|
|
|
import dayJs from 'dayjs'
|
|
|
|
|
import { ref, computed } from 'vue';
|
|
|
|
|
import { DatePicker } from '@nutui/nutui';
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
modelValue?: string
|
|
|
|
|
disabled?: boolean
|
|
|
|
|
data?: any
|
|
|
|
|
types?: number
|
|
|
|
|
}>(),
|
|
|
|
|
{}
|
|
|
|
|
)
|
|
|
|
|
const selectType = computed(() => {
|
|
|
|
|
switch (props.data.control.type) {
|
|
|
|
|
case "year":
|
|
|
|
|
return "single";
|
|
|
|
|
case "month":
|
|
|
|
|
return "single";
|
|
|
|
|
case "date":
|
|
|
|
|
return "single";
|
|
|
|
|
case "datetime":
|
|
|
|
|
return "single";
|
|
|
|
|
case "week":
|
|
|
|
|
return "single";
|
|
|
|
|
case "datetimerange":
|
|
|
|
|
return "range";
|
|
|
|
|
case "daterange":
|
|
|
|
|
return "range";
|
|
|
|
|
case "monthrange":
|
|
|
|
|
return "range";
|
|
|
|
|
default:
|
|
|
|
|
return "single";
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
function timestampToTargetFormat(timestamp: string) {
|
|
|
|
|
|
|
|
|
|
// 将输入转换为数字类型的时间戳(毫秒)
|
|
|
|
|
const ms = Number(timestamp);
|
|
|
|
|
// 创建Date对象
|
|
|
|
|
const date = new Date(ms);
|
|
|
|
|
// Date对象的toString()方法恰好返回目标格式
|
|
|
|
|
|
|
|
|
|
return date;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function convertToTimestamp(dateString: string) {
|
|
|
|
|
//console.log(dateString)
|
|
|
|
|
if (dateString) {
|
|
|
|
|
//console.log(dateString)
|
|
|
|
|
// 创建Date对象,JavaScript能直接解析这种格式
|
|
|
|
|
const date = new Date(dateString);
|
|
|
|
|
|
|
|
|
|
// 检查日期是否有效
|
|
|
|
|
if (isNaN(date.getTime())) {
|
|
|
|
|
throw new Error("无效的日期格式");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取时间戳(毫秒数)并转换为字符串
|
|
|
|
|
return date.getTime().toString();
|
|
|
|
|
} else {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const emits = defineEmits<{
|
|
|
|
|
(e: 'update:modelValue', value: string): void
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const value1 = ref("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const startValue1 = ref("")
|
|
|
|
|
|
|
|
|
|
const endValue1 = ref("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//阻止唤起键盘
|
|
|
|
|
const handleClick = (event: { target: { readOnly: boolean; }; }) => {
|
|
|
|
|
// 阻止输入框默认行为
|
|
|
|
|
event.target.readOnly = true;
|
|
|
|
|
};
|
|
|
|
|
const hasValue = ref(false)
|
|
|
|
|
//打印数据
|
|
|
|
|
const valPrint = (val1: string, group: string, type: string) => {
|
|
|
|
|
const val = new Date(parseInt(val1, 10));
|
|
|
|
|
/* console.log(val)
|
|
|
|
|
console.log(val1) */
|
|
|
|
|
if (val && val1) {
|
|
|
|
|
hasValue.value = true
|
|
|
|
|
switch (group) {
|
|
|
|
|
case "year":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY') + "年";
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "年";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "month":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "月";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "datetime":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日 HH时mm分ss秒');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "week":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年 第ww周');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "datetimerange":
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
|
let startTime = val[0]
|
|
|
|
|
let endNum = val.length - 1
|
|
|
|
|
if (endNum < 0) {
|
|
|
|
|
endNum = 0
|
|
|
|
|
}
|
|
|
|
|
let endEnd = val[endNum]
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(startTime).format('YYYY-MM-DD HH:mm:ss') + " - " + dayJs(endEnd).format('YYYY-MM-DD HH:mm:ss');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(startTime).format(type) + " - " + dayJs(endEnd).format(type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "daterange":
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
|
let startTime = val[0]
|
|
|
|
|
let endNum = val.length - 1
|
|
|
|
|
if (endNum < 0) {
|
|
|
|
|
endNum = 0
|
|
|
|
|
}
|
|
|
|
|
let endEnd = val[endNum]
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(startTime).format('YYYY-MM-DD') + " - " + dayJs(endEnd).format('YYYY-MM-DD');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(startTime).format(type) + " - " + dayJs(endEnd).format(type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "monthrange":
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
|
let startTime = val[0]
|
|
|
|
|
let endNum = val.length - 1
|
|
|
|
|
if (endNum < 0) {
|
|
|
|
|
endNum = 0
|
|
|
|
|
}
|
|
|
|
|
let endEnd = val[endNum]
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(startTime).format('YYYY-MM') + " - " + dayJs(endEnd).format('YYYY-MM');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(startTime).format(type) + " - " + dayJs(endEnd).format(type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
hasValue.value = false
|
|
|
|
|
return "请选择时间";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
const hasValue1 = ref(false)
|
|
|
|
|
const hasValue2 = ref(false)
|
|
|
|
|
|
|
|
|
|
const formatStart = computed(() => {
|
|
|
|
|
//console.log(value.value[0])
|
|
|
|
|
let val = new Date(parseInt(value.value[0], 10));
|
|
|
|
|
let group = props.data.control.type
|
|
|
|
|
let type = props.data.control.valueFormat
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* console.log(val)
|
|
|
|
|
console.log(group)
|
|
|
|
|
console.log(type) */
|
|
|
|
|
if (val && value.value[0] && value.value[0] != "") {
|
|
|
|
|
//console.log(111)
|
|
|
|
|
hasValue1.value = true
|
|
|
|
|
switch (group) {
|
|
|
|
|
case "year":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY') + "年";
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "年";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "month":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('MM') + "月";
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "月";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "datetime":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日 HH时mm分ss秒');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "week":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年 第ww周');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "datetimerange":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY-MM-DD HH:mm');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "daterange":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "monthrange":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "月";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
//alert(1)
|
|
|
|
|
hasValue1.value = false
|
|
|
|
|
return "请选择时间";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const formatEnd = computed(() => {
|
|
|
|
|
//console.log(value.value[1])
|
|
|
|
|
let val = new Date(parseInt(value.value[1], 10));
|
|
|
|
|
let group = props.data.control.type
|
|
|
|
|
let type = props.data.control.valueFormat
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* console.log(val)
|
|
|
|
|
console.log(group)
|
|
|
|
|
console.log(type) */
|
|
|
|
|
if (val && value.value[1] && value.value[1] != "") {
|
|
|
|
|
//console.log(111)
|
|
|
|
|
hasValue2.value = true
|
|
|
|
|
switch (group) {
|
|
|
|
|
case "year":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY') + "年";
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "年";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "month":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('MM') + "月";
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "月";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "datetime":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日 HH时mm分ss秒');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "week":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年 第ww周');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "datetimerange":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY-MM-DD HH:mm');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "daterange":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "monthrange":
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type) + "月";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (type != "" && type == "x") {
|
|
|
|
|
return dayJs(val).format('YYYY年MM月DD日');
|
|
|
|
|
} else {
|
|
|
|
|
return dayJs(val).format(type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
//alert(1)
|
|
|
|
|
hasValue2.value = false
|
|
|
|
|
return "请选择时间";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const showPicker = ref(false);
|
|
|
|
|
|
|
|
|
|
const show = ref(false)
|
|
|
|
|
|
|
|
|
|
const showStart = ref(false)
|
|
|
|
|
|
|
|
|
|
const showEnd = ref(false)
|
|
|
|
|
|
|
|
|
|
const value = computed({
|
|
|
|
|
get: () => {
|
|
|
|
|
//console.log(value.value)
|
|
|
|
|
//value1.value = timestampToTargetFormat(value.value)
|
|
|
|
|
if (selectType.value == "range") {
|
|
|
|
|
//console.log(props.modelValue)
|
|
|
|
|
|
|
|
|
|
return props.modelValue
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
return props.modelValue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
set: (newVal: any) => {
|
|
|
|
|
if (selectType.value == "range") {
|
|
|
|
|
emits('update:modelValue', newVal)
|
|
|
|
|
} else {
|
|
|
|
|
emits('update:modelValue', convertToTimestamp(newVal))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const confirm = () => {
|
|
|
|
|
flag.value = "single"
|
|
|
|
|
value.value = value1.value
|
|
|
|
|
show.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const cancel = () => {
|
|
|
|
|
value1.value = timestampToTargetFormat(value.value)
|
|
|
|
|
show.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const valueRange = computed(() => {
|
|
|
|
|
//当是start触发的时,要从父组件获取end,作为arr[1],反之亦然
|
|
|
|
|
let arr = []
|
|
|
|
|
arr[0] = convertToTimestamp(startValue1.value)
|
|
|
|
|
arr[1] = convertToTimestamp(endValue1.value)
|
|
|
|
|
return arr
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const flag = ref("")
|
|
|
|
|
const confirmStart = () => {
|
|
|
|
|
flag.value = "start"
|
|
|
|
|
//value.value = startValue1.value
|
|
|
|
|
value.value = valueRange.value
|
|
|
|
|
showStart.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const cancelStart = () => {
|
|
|
|
|
startValue1.value = timestampToTargetFormat(value.value[0])
|
|
|
|
|
showStart.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const confirmEnd = () => {
|
|
|
|
|
flag.value = "end"
|
|
|
|
|
//value.value = endValue1.value
|
|
|
|
|
value.value = valueRange.value
|
|
|
|
|
showEnd.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const cancelEnd = () => {
|
|
|
|
|
endValue1.value = timestampToTargetFormat(value.value[1])
|
|
|
|
|
showEnd.value = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const formatter = (type: any, option: { text: string; }) => {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'year':
|
|
|
|
|
option.text += '年'
|
|
|
|
|
break
|
|
|
|
|
case 'month':
|
|
|
|
|
option.text += '月'
|
|
|
|
|
break
|
|
|
|
|
case 'day':
|
|
|
|
|
option.text += '日'
|
|
|
|
|
break
|
|
|
|
|
case 'hour':
|
|
|
|
|
option.text += '时'
|
|
|
|
|
break
|
|
|
|
|
case 'minute':
|
|
|
|
|
option.text += '分'
|
|
|
|
|
break
|
|
|
|
|
default:
|
|
|
|
|
option.text += ''
|
|
|
|
|
}
|
|
|
|
|
return option
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const min = new Date(2010, 0, 1, 0o0, 0o0)
|
|
|
|
|
const max = new Date(2045, 10, 1, 23, 29)
|
|
|
|
|
|
|
|
|
|
const type = computed(() => {
|
|
|
|
|
switch (props.data.control.type) {
|
|
|
|
|
case "year":
|
|
|
|
|
return "year-month";
|
|
|
|
|
case "month":
|
|
|
|
|
return "year-month";
|
|
|
|
|
case "date":
|
|
|
|
|
return "date";
|
|
|
|
|
case "datetime":
|
|
|
|
|
return "datetime";
|
|
|
|
|
case "week":
|
|
|
|
|
return "date";
|
|
|
|
|
case "datetimerange":
|
|
|
|
|
return "datetime";
|
|
|
|
|
case "daterange":
|
|
|
|
|
return "date";
|
|
|
|
|
case "monthrange":
|
|
|
|
|
return "year-month";
|
|
|
|
|
default:
|
|
|
|
|
return "date";
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const shichang = computed(() => {
|
|
|
|
|
console.log(value.value)
|
|
|
|
|
let start = value.value[0]
|
|
|
|
|
let end = value.value[1]
|
|
|
|
|
console.log(start)
|
|
|
|
|
console.log(end)
|
|
|
|
|
let a = calculateTimeDiff(start, end)
|
|
|
|
|
return a
|
|
|
|
|
})
|
|
|
|
|
/* function calculateTimeDiff(startTimestamp: string, endTimestamp: string) {
|
|
|
|
|
// 解析时间戳为数字
|
|
|
|
|
const start = parseInt(startTimestamp, 10);
|
|
|
|
|
const end = parseInt(endTimestamp, 10);
|
|
|
|
|
|
|
|
|
|
// 计算时间差(毫秒)并取绝对值
|
|
|
|
|
const diffMs = Math.abs(end - start);
|
|
|
|
|
|
|
|
|
|
// 计算总分钟数并四舍五入
|
|
|
|
|
const totalMinutes = Math.round(diffMs / 60000);
|
|
|
|
|
|
|
|
|
|
// 计算总小时数(带小数)
|
|
|
|
|
const totalHours = totalMinutes / 60;
|
|
|
|
|
|
|
|
|
|
// 处理小时进位情况
|
|
|
|
|
if (totalHours < 24) {
|
|
|
|
|
// 不足一天:四舍五入到小时
|
|
|
|
|
return `${Math.round(totalHours)} 小时`;
|
|
|
|
|
} else {
|
|
|
|
|
// 计算完整天数
|
|
|
|
|
const days = Math.floor(totalHours / 24);
|
|
|
|
|
// 计算剩余小时数(四舍五入)
|
|
|
|
|
const remainingHours = Math.round(totalHours % 24);
|
|
|
|
|
|
|
|
|
|
// 处理小时进位(当剩余小时为24时)
|
|
|
|
|
if (remainingHours === 24) {
|
|
|
|
|
return `${days + 1} 天 0 小时`;
|
|
|
|
|
}
|
|
|
|
|
return `${days} 天 ${remainingHours} 小时`;
|
|
|
|
|
}
|
|
|
|
|
} */
|
|
|
|
|
|
|
|
|
|
function calculateTimeDiff(startTimestamp: string, endTimestamp: string) {
|
|
|
|
|
// 解析时间戳为数字
|
|
|
|
|
const start = parseInt(startTimestamp, 10);
|
|
|
|
|
const end = parseInt(endTimestamp, 10);
|
|
|
|
|
|
|
|
|
|
// 计算时间差(毫秒)并取绝对值
|
|
|
|
|
const diffMs = Math.abs(end - start);
|
|
|
|
|
|
|
|
|
|
// 计算总分钟数并向下取整
|
|
|
|
|
const totalMinutes = Math.floor(diffMs / 60000);
|
|
|
|
|
|
|
|
|
|
// 计算天数和剩余小时数
|
|
|
|
|
const days = Math.floor(totalMinutes / 1440); // 1440分钟 = 24小时
|
|
|
|
|
const remainingMinutesAfterDays = totalMinutes % 1440;
|
|
|
|
|
const hours = Math.floor(remainingMinutesAfterDays / 60);
|
|
|
|
|
const minutes = remainingMinutesAfterDays % 60;
|
|
|
|
|
|
|
|
|
|
// 构建返回字符串
|
|
|
|
|
let result = '';
|
|
|
|
|
|
|
|
|
|
if (days > 0) {
|
|
|
|
|
result += `${days} 天 `;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hours > 0) {
|
|
|
|
|
result += `${hours} 小时 `;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (minutes >= 0) { // 包含0分钟的情况
|
|
|
|
|
result += `${minutes} 分钟`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.trim(); // 去除末尾空格
|
|
|
|
|
}
|
|
|
|
|
const types = props.types;
|
|
|
|
|
function singleShow() {
|
|
|
|
|
if (types == 1||types == 2) {
|
|
|
|
|
if (value1.value == "") {
|
|
|
|
|
value1.value = getTimestamp()
|
|
|
|
|
}
|
|
|
|
|
show.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
function rangeShowStart() {
|
|
|
|
|
if (types == 1||types == 2) {
|
|
|
|
|
if (startValue1.value == "") {
|
|
|
|
|
startValue1.value = getTimestamp()
|
|
|
|
|
}
|
|
|
|
|
showStart.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function rangeShowEnd() {
|
|
|
|
|
if (types == 1||types == 2) {
|
|
|
|
|
if (endValue1.value == "") {
|
|
|
|
|
endValue1.value = getTimestamp()
|
|
|
|
|
}
|
|
|
|
|
showEnd.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getTimestamp() {
|
|
|
|
|
|
|
|
|
|
const now = new Date();
|
|
|
|
|
let timestamp;
|
|
|
|
|
|
|
|
|
|
switch (type.value) {
|
|
|
|
|
case 'year-month':
|
|
|
|
|
// 设置为当前年当前月1日0时0分1秒
|
|
|
|
|
const yearMonthDate = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 1);
|
|
|
|
|
timestamp = yearMonthDate
|
|
|
|
|
break;
|
|
|
|
|
case 'date':
|
|
|
|
|
// 设置为当前年当前月当前日0时0分1秒
|
|
|
|
|
const dateDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 1);
|
|
|
|
|
timestamp = dateDate
|
|
|
|
|
break;
|
|
|
|
|
case 'datetime':
|
|
|
|
|
// 返回当前时刻的时间戳
|
|
|
|
|
timestamp = now
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw new Error('参数必须是"year-month"、"date"或"datetime"之一');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return timestamp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 computed 替代方法调用
|
|
|
|
|
const displayText = computed(() => {
|
|
|
|
|
if (!props.modelValue) {
|
|
|
|
|
hasValue.value = false
|
|
|
|
|
return "请选择时间"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const val = new Date(parseInt(props.modelValue, 10))
|
|
|
|
|
if (isNaN(val.getTime())) {
|
|
|
|
|
hasValue.value = false
|
|
|
|
|
return "请选择时间"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hasValue.value = true
|
|
|
|
|
return formatDate(val, props.data.control.type, props.data.control.valueFormat)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 提取格式化逻辑到独立函数
|
|
|
|
|
function formatDate(date: Date, group: string, format: string) {
|
|
|
|
|
const validDate = dayJs(date)
|
|
|
|
|
if (!validDate.isValid()) return "请选择时间"
|
|
|
|
|
|
|
|
|
|
switch (group) {
|
|
|
|
|
case "year":
|
|
|
|
|
return format === "x"
|
|
|
|
|
? validDate.format('YYYY') + "年"
|
|
|
|
|
: validDate.format(format) + "年"
|
|
|
|
|
case "month":
|
|
|
|
|
return format === "x"
|
|
|
|
|
? validDate.format('YYYY年MM月')
|
|
|
|
|
: validDate.format(format) + "月"
|
|
|
|
|
case "datetime":
|
|
|
|
|
return format === "x"
|
|
|
|
|
? validDate.format('YYYY年MM月DD日 HH时mm分ss秒')
|
|
|
|
|
: validDate.format(format)
|
|
|
|
|
case "week":
|
|
|
|
|
return format === "x"
|
|
|
|
|
? validDate.format('YYYY年 第ww周')
|
|
|
|
|
: validDate.format(format)
|
|
|
|
|
default:
|
|
|
|
|
return format === "x"
|
|
|
|
|
? validDate.format('YYYY年MM月DD日')
|
|
|
|
|
: validDate.format(format)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<el-drawer v-model="show" :with-header="false" direction="btt" :append-to-body="true" size="44%">
|
|
|
|
|
<nut-date-picker v-if="selectType == 'single'" v-model="value1" :three-dimensional="false" @confirm="confirm"
|
|
|
|
|
:min-date="min" @cancel="cancel" :type="type" :max-date="max" :formatter="formatter"></nut-date-picker>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</el-drawer>
|
|
|
|
|
|
|
|
|
|
<el-drawer v-model="showStart" :with-header="false" direction="btt" size="44%">
|
|
|
|
|
|
|
|
|
|
<nut-date-picker v-if="selectType == 'range'" v-model="startValue1" :three-dimensional="false"
|
|
|
|
|
@confirm="confirmStart" :min-date="min" @cancel="cancelStart" :type="type" :max-date="max"
|
|
|
|
|
:formatter="formatter"></nut-date-picker>
|
|
|
|
|
</el-drawer>
|
|
|
|
|
<el-drawer v-model="showEnd" :with-header="false" direction="btt" size="44%">
|
|
|
|
|
|
|
|
|
|
<nut-date-picker v-if="selectType == 'range'" v-model="endValue1" :three-dimensional="false"
|
|
|
|
|
@confirm="confirmEnd" :min-date="min" @cancel="cancelEnd" :type="type" :max-date="max"
|
|
|
|
|
:formatter="formatter"></nut-date-picker>
|
|
|
|
|
</el-drawer>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div v-if="selectType == 'single'"
|
|
|
|
|
style="border: 1px solid #DCDFE6; padding-left: 10px; width: 100%;height: 97%;border-radius: 5px;"
|
|
|
|
|
@click="singleShow">
|
|
|
|
|
<div v-if="hasValue" class="wordColor">{{ displayText
|
|
|
|
|
}}</div>
|
|
|
|
|
<div v-if="!hasValue" class="wordColor1">{{ displayText
|
|
|
|
|
}}</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 区间 -->
|
|
|
|
|
<div v-if="selectType == 'range'"
|
|
|
|
|
style="border: 1px solid #DCDFE6; padding-left: 10px; width: 46.5%;height: 97%;border-radius: 5px;"
|
|
|
|
|
@click="rangeShowStart">
|
|
|
|
|
<div v-if="hasValue1" class="wordColor">{{ formatStart
|
|
|
|
|
}}</div>
|
|
|
|
|
<div v-if="!hasValue1" class="wordColor1">{{ formatStart
|
|
|
|
|
}}</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-if="selectType == 'range'"
|
|
|
|
|
style="border: 0px solid #DCDFE6; padding-left:1.5%; width: 7%;height: 97%;border-radius: 5px;">
|
|
|
|
|
<div class="wordColor">至</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-if="selectType == 'range'"
|
|
|
|
|
style="border: 1px solid #DCDFE6; padding-left: 10px; width: 46.5%;height: 97%;border-radius: 5px;"
|
|
|
|
|
@click="rangeShowEnd">
|
|
|
|
|
<div v-if="hasValue2" class="wordColor">{{ formatEnd
|
|
|
|
|
}}</div>
|
|
|
|
|
<div v-if="!hasValue2" class="wordColor1">{{ formatEnd
|
|
|
|
|
}}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- <div v-if="selectType == 'range'"
|
|
|
|
|
style="border: 0px solid #DCDFE6; padding-left: 8px; width: 10%;height: 97%;border-radius: 5px;">
|
|
|
|
|
<div class="wordColor">时长:23天</div>
|
|
|
|
|
</div> -->
|
|
|
|
|
<div v-if="selectType == 'range' && value[0] && value[1]"
|
|
|
|
|
style="float:right;border: black 0px solid;position: absolute; pointer-events: none;bottom: -26px;color:#A8ABB2 ;width: 100%; font-size: smaller;">
|
|
|
|
|
<div style="float:right">{{ shichang }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
<style lang='scss'>
|
|
|
|
|
.wordColor {
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.wordColor1 {
|
|
|
|
|
//color: #000000;
|
|
|
|
|
color: #A8ABB2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 全局覆盖NutUI部分样式 */
|
|
|
|
|
.nut-picker {
|
|
|
|
|
z-index: 3000 !important;
|
|
|
|
|
/* 确保高于Element弹窗 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.nut-date-picker__header {
|
|
|
|
|
background: var(--el-color-primary);
|
|
|
|
|
/* 同步Element主题色 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#1E5EFF
|
|
|
|
|
//#626AEF
|
|
|
|
|
:root {
|
|
|
|
|
--nut-primary-color: #626AEF;
|
|
|
|
|
--nut-picker-right: #626AEF;
|
|
|
|
|
--nut-picker-ok-color: #626AEF;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
</style>
|