自定义APP自定义App数据通讯
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.

696 lines
16 KiB

<!--
@ 作者: 秦东
@ 时间: 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(
3 months ago
defineProps<{
modelValue?: string
disabled?: boolean
3 months ago
data?: any
types?: number
}>(),
{}
)
3 months ago
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) {
3 months ago
// 将输入转换为数字类型的时间戳(毫秒)
const ms = Number(timestamp);
// 创建Date对象
const date = new Date(ms);
// Date对象的toString()方法恰好返回目标格式
return date;
3 months ago
}
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<{
3 months ago
(e: 'update:modelValue', value: string): void
}>()
3 months ago
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
3 months ago
/* console.log(val)
console.log(group)
console.log(type) */
if (val && value.value[0] && value.value[0] != "") {
3 months ago
//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
3 months ago
/* console.log(val)
console.log(group)
console.log(type) */
if (val && value.value[1] && value.value[1] != "") {
3 months ago
//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 "请选择时间";
}
});
3 months ago
const showPicker = ref(false);
const show = ref(false)
const showStart = ref(false)
const showEnd = ref(false)
const value = computed({
get: () => {
3 months ago
//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) => {
3 months ago
if (selectType.value == "range") {
emits('update:modelValue', newVal)
} else {
emits('update:modelValue', convertToTimestamp(newVal))
}
},
});
3 months ago
const confirm = () => {
flag.value = "single"
value.value = value1.value
show.value = false
}
const cancel = () => {
value1.value = timestampToTargetFormat(value.value)
3 months ago
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])
3 months ago
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])
3 months ago
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":
3 months ago
return "year-month";
case "month":
3 months ago
return "year-month";
case "date":
return "date";
case "datetime":
3 months ago
return "datetime";
case "week":
3 months ago
return "date";
case "datetimerange":
3 months ago
return "datetime";
case "daterange":
3 months ago
return "date";
case "monthrange":
3 months ago
return "year-month";
default:
3 months ago
return "date";
}
3 months ago
})
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)
3 months ago
return a
})
function calculateTimeDiff(startTimestamp: string, endTimestamp: string) {
// 解析时间戳为数字
const start = parseInt(startTimestamp, 10);
const end = parseInt(endTimestamp, 10);
// 计算时间差(毫秒)并取绝对值
const diffMs = Math.abs(end - start);
3 months ago
// 计算总分钟数并四舍五入
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} 小时`;
}
}
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;
}
3 months ago
</script>
<template>
3 months ago
<el-drawer v-model="show" :with-header="false" direction="btt" :append-to-body="true" size="37%">
3 months ago
<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="37%">
3 months ago
<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="37%">
3 months ago
<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: 0.5px solid #DCDFE6; padding-left: 10px; width: 100%;height: 97%;border-radius: 5px;"
@click="singleShow">
3 months ago
<el-text v-if="hasValue" class="wordColor">{{ valPrint(value, props.data.control.type,
props.data.control.valueFormat)
}}</el-text>
<el-text v-if="!hasValue" class="wordColor1">{{ valPrint(value, props.data.control.type,
props.data.control.valueFormat)
}}</el-text>
</div>
<!-- 区间 -->
<div v-if="selectType == 'range'"
style="border: 0.5px solid #DCDFE6; padding-left: 10px; width: 46.5%;height: 97%;border-radius: 5px;"
@click="rangeShowStart">
<el-text v-if="hasValue1" class="wordColor">{{ formatStart
3 months ago
}}</el-text>
<el-text v-if="!hasValue1" class="wordColor1">{{ formatStart
3 months ago
}}</el-text>
</div>
<div v-if="selectType == 'range'"
style="border: 0px solid #DCDFE6; padding-left:1.5%; width: 7%;height: 97%;border-radius: 5px;">
<el-text class="wordColor"></el-text>
</div>
<div v-if="selectType == 'range'"
style="border: 0.5px solid #DCDFE6; padding-left: 10px; width: 46.5%;height: 97%;border-radius: 5px;"
@click="rangeShowEnd">
<el-text v-if="hasValue2" class="wordColor">{{ formatEnd
3 months ago
}}</el-text>
<el-text v-if="!hasValue2" class="wordColor1">{{ formatEnd
3 months ago
}}</el-text>
</div>
<!-- <div v-if="selectType == 'range'"
style="border: 0px solid #DCDFE6; padding-left: 8px; width: 10%;height: 97%;border-radius: 5px;">
<el-text class="wordColor">时长:23</el-text>
</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>
3 months ago
</template>
3 months ago
<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>