Files
fad-dashboard/frontend/packages/BasicComponents/DateTimePicker/index.vue
2025-11-08 10:38:36 +08:00

586 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-date-picker
:key="config.customize.type"
v-model="value"
:picker-options="config.customize.pickerOptions"
:type="config.customize.type"
clearable
:class="['basic-component-date-picker', `date-picker-${config.code}`]"
:popper-class="'basic-component-date-picker date-picker-popper-' + config.code"
:value-format="config.customize.format"
:format="config.customize.format"
:default-value="value"
size="large"
@focus="focusEvent"
@change="changeValue"
@mouseenter.native="mouseenter"
/>
</template>
<script>
import moment from 'moment'
import cloneDeep from 'lodash/cloneDeep'
import commonMixins from 'data-room-ui/js/mixins/commonMixins'
import linkageMixins from 'data-room-ui/js/mixins/linkageMixins'
import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting'
import { mapState } from 'vuex'
window.dataSetFields = []
export default {
name: 'BasicComponentsDateTimePicker',
components: {},
mixins: [commonMixins, linkageMixins],
props: {
// 组件配置
config: {
type: Object,
default: () => ({})
}
},
data () {
return {
value: '',
innerConfig: {}
}
},
computed: {
...mapState({
chartList: state => state.bigScreen.pageInfo.chartList
}),
isPreview () {
return (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) || (this.$route.path === '/big-screen/preview')
}
},
watch: {
'config.customize.formatType': {
handler (val) {
const newFomat = this.config.customize.format.replace(/y/g, 'Y').replace(/d/g, 'D')
if (val === 'timestamp') {
// this.value = 0
if (['year', 'month', 'date', 'week', 'datetime'].includes(this.config.customize.type)) {
this.value = moment(new Date()).format(newFomat)
} else {
this.value = [
moment(new Date()).subtract(7, 'days').valueOf(),
moment(new Date()).valueOf()
]
}
} else if (val === 'custom') {
if (['year', 'month', 'date', 'week', 'datetime'].includes(this.config.customize.type)) {
this.value = moment(new Date()).format(newFomat)
} else {
this.value = [
moment(new Date()).subtract(7, 'days').format(newFomat),
moment(new Date()).format(newFomat)
]
}
}
},
immediate: true
},
'config.customize.type': {
handler (val) {
this.$nextTick(() => {
if (!this.isPreview) {
document.querySelector(`.date-picker-${this.config.code}`).style.pointerEvents = 'none'
}
})
const newFomat = this.config.customize.format.replace(/y/g, 'Y').replace(/d/g, 'D')
if (['year', 'month', 'date', 'week', 'datetime'].includes(val)) {
if (this.config.customize.formatType === 'timestamp') {
this.value = moment(new Date()).valueOf()
} else {
this.value = moment(new Date()).format(newFomat)
}
} else {
if (this.config.customize.formatType === 'timestamp') {
this.value = [
moment(new Date()).subtract(7, 'days').valueOf(),
moment(new Date()).valueOf()
]
} else {
this.value = [
moment(new Date()).subtract(7, 'days').format(newFomat),
moment(new Date()).format(newFomat)
]
}
}
},
immediate: true
},
'config.customize.format': {
handler (val) {
this.$nextTick(() => {
if (!this.isPreview) {
document.querySelector(`.date-picker-${this.config.code}`).style.pointerEvents = 'none'
}
})
const newFomat = val?.replace(/y/g, 'Y')?.replace(/d/g, 'D')
if (['year', 'month', 'date', 'week', 'datetime'].includes(this.config.customize.type)) {
this.value = moment(new Date()).format(newFomat)
if (this.config.customize.formatType === 'timestamp') {
this.value = moment(new Date()).valueOf()
} else {
this.value = moment(new Date()).format(newFomat)
}
} else {
if (this.config.customize.formatType === 'timestamp') {
this.value = [
moment(new Date()).subtract(7, 'days').valueOf(),
moment(new Date()).valueOf()
]
} else {
this.value = [
moment(new Date()).subtract(7, 'days').format(newFomat),
moment(new Date()).format(newFomat)
]
}
}
}
}
},
created () { },
mounted () {
if (!this.isPreview) {
document.querySelector(`.date-picker-${this.config.code}`).style.pointerEvents = 'none'
}
this.changeStyle(this.config)
if (this.value === '') {
const newFomat = this.config.customize.format.replace(/y/g, 'Y').replace(/d/g, 'D')
this.value = [
moment(new Date()).subtract(7, 'days').format(newFomat),
moment(new Date()).format(newFomat)
]
}
},
beforeDestroy () {
},
methods: {
dataFormatting (config, data) {
config.option.data = []
return config
},
changeStyle (config) {
config = { ...this.config, ...config }
// 样式改变时更新主题配置
config.theme = settingToTheme(cloneDeep(config), this.customTheme)
this.changeChartConfig(config)
this.innerConfig = config
// 时间选择器元素
const { bgColor, fontColor, fontSize } = config.customize
this.$nextTick(() => {
const timePickerEl = document.querySelector(`.date-picker-${config.code}`)
timePickerEl.style.backgroundColor = bgColor
// 时间选择器输入框元素
const timePickerInput = timePickerEl.querySelector('.el-input__inner')
if (timePickerInput) {
// 时间选择器输入框背景颜色
timePickerInput.style.backgroundColor = bgColor
// 时间选择器输入框字体颜色
timePickerInput.style.color = fontColor
// 时间选择器输入框字体大小
timePickerInput.style.fontSize = fontSize + 'px'
}
// 时间范围选择器输入框元素
const timePickerRangeInput = timePickerEl.querySelectorAll('.el-range-input')
if (timePickerRangeInput.length > 0) {
// 连接符
const timePickerRangeSeparator = timePickerEl.querySelector('.el-range-separator')
if (timePickerRangeSeparator) {
// 宽度和字体大小保持一致
timePickerRangeSeparator.style.width = fontSize + 'px'
timePickerRangeSeparator.style.color = fontColor
timePickerRangeSeparator.style.fontSize = fontSize + 'px'
}
timePickerRangeInput.forEach((el) => {
// 时间范围选择器输入框背景颜色
el.style.backgroundColor = bgColor
// 时间范围选择器输入框字体颜色
el.style.color = fontColor
// 时间范围选择器输入框字体大小
el.style.fontSize = fontSize + 'px'
})
}
// 时间选择器图标
const timePickerIcon = timePickerEl.querySelector('.el-input__icon')
if (timePickerIcon) {
timePickerIcon.style.width = fontSize + 'px'
timePickerIcon.style.fontSize = fontSize + 'px'
}
})
},
// 组件联动
changeValue (val) {
// 判断如果val是数组需要将它转成字符串
if (Array.isArray(val)) {
val = val.join(',')
}
this.linkage({ [this.config.code]: val })
},
focusEvent () {
this.$nextTick(() => {
const { code } = this.innerConfig
const { bgColor, fontColor, hoverFontColor, hoverBgColor, selectedFontColor, rangeBgColor, inputBgColor } = this.innerConfig.customize.dropDownBox
const timePickerPopper = document.querySelector(`.date-picker-popper-${code}`)
if (timePickerPopper) {
// 去除边框
timePickerPopper.style.border = 'none'
// 确保下拉项的箭头颜色与下拉框的背景颜色保持一致
timePickerPopper.style.color = bgColor
}
// 下拉项元素
const pickerDropdownPanleContent = document.querySelector(`.date-picker-popper-${code}`)
if (pickerDropdownPanleContent) {
// 文字颜色
pickerDropdownPanleContent.style.color = fontColor
// 背景颜色
pickerDropdownPanleContent.style.backgroundColor = bgColor
// 下拉项添加var变量
const dropdown = pickerDropdownPanleContent.style
dropdown.setProperty('--fontColor', fontColor)
dropdown.setProperty('--hoverFontColor', hoverFontColor)
dropdown.setProperty('--bgColor', bgColor)
dropdown.setProperty('--inputBgColor', inputBgColor)
dropdown.setProperty('--selectedFontColor', selectedFontColor)
dropdown.setProperty('--hoverBgColor', hoverBgColor)
dropdown.setProperty('--rangeBgColor', rangeBgColor)
// 选中项字体颜色
const selectedEl = pickerDropdownPanleContent.querySelector('.selected')
if (selectedEl) {
selectedEl.style.color = selectedFontColor
}
// 选择过的,需要将选中颜色重置
const pickerItemEl = document.querySelectorAll(`.date-picker-popper-${code} .el-time-spinner__item`)
pickerItemEl.forEach((el) => {
el.style.color = fontColor
})
}
})
},
mouseenter () {
if (this.value) {
setTimeout(() => {
// 清空图标
const timePickerCloseIcon = document.querySelector(`.date-picker-${this.innerConfig.code} .el-icon-circle-close`)
if (timePickerCloseIcon) {
timePickerCloseIcon.style.fontSize = this.innerConfig.customize.fontSize + 'px'
}
}, 25)
}
}
}
}
</script>
<style lang="scss">
.basic-component-date-picker {
color: '';
// 清空图标
.el-icon-circle-close {
display: flex;
align-items: center;
}
// 时间选择器
.el-icon-time {
display: flex;
align-items: center;
}
.el-time-panel {
border: none;
background-color: var(--bgColor);
}
// 选择日期 时间区域
.el-date-picker__time-header {
border-bottom: var(--bgColor);
.el-input__inner {
border: none;
// 添加一点阴影
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
color: var(--fontColor);
background-color: var(--inputBgColor);
}
}
// 头部,修改文字颜色和图标颜色
.el-date-picker__header {
color: var(--fontColor);
.el-date-picker__header-label {
color: var(--fontColor);
}
// 左右箭头图标颜色
.el-picker-panel__icon-btn {
color: var(--fontColor);
}
}
// datetimerange
.el-date-range-picker__time-header {
border-color: var(--fontColor);
// 中间箭头图标颜色
.el-icon-arrow-right {
color: var(--fontColor);
}
// 时间选择器输入框
.el-input__inner {
border: none;
color: var(--fontColor);
// 添加一点阴影
background-color: var(--inputBgColor);
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
}
}
// datetimerange
.el-picker-panel__content {
.el-icon-d-arrow-left {
color: var(--fontColor);
&:after {
color: var(--fontColor);
}
}
.el-icon-arrow-left {
color: var(--fontColor);
&:after {
color: var(--fontColor);
}
}
.el-icon-d-arrow-right {
color: var(--fontColor);
&:after {
color: var(--fontColor);
}
}
.el-icon-arrow-right {
color: var(--fontColor);
&:after {
color: var(--fontColor);
}
}
}
.el-date-range-picker__content.is-left {
border-color: var(--fontColor);
}
.el-date-table {
th {
border-color: var(--fontColor);
}
td {
div {
color: var(--fontColor);
&:hover {
color: var(--hoverFontColor);
}
}
}
}
// 范围选择器背景颜色
.in-range {
div {
// 下拉范围选中背景颜色
background-color: var(--rangeBgColor) !important;
}
}
.today {
span {
color: var(--selectedFontColor) !important;
}
}
.el-time-panel__content::before {
content: "";
top: 50%;
position: absolute;
margin-top: -15px;
height: 32px;
z-index: 1;
left: 0;
right: 0;
box-sizing: border-box;
padding-top: 6px;
text-align: left;
border-top: 1px solid var(--fontColor);
border-bottom: 1px solid var(--fontColor);
}
// 脚部
.el-picker-panel__footer {
border-color: var(--fontColor);
background-color: var(--bgColor);
// 清空按钮
.el-picker-panel__link-btn {
span {
color: var(--fontColor);
}
}
// 确定按钮
.el-button--default {
border: none;
color: var(--fontColor);
background-color: var(--bgColor);
}
.is-disabled {
span {
color: #999;
}
}
}
.el-time-spinner {
margin-bottom: 0px;
.el-time-spinner__item {
&:hover {
color: var(--hoverFontColor);
background-color: var(--hoverBgColor);
}
}
.active {
color: var(--selectedFontColor);
&:hover {
color: var(--selectedFontColor);
background-color: transparent;
}
}
}
.popper__arrow {
bottom: -6px;
border-bottom-color: var(--bgColor) !important;
border-top-color: var(--bgColor) !important;
&::after {
bottom: 0px;
border-bottom-color: var(--bgColor) !important;
border-top-color: var(--bgColor) !important;
}
}
.cancel {
color: var(--fontColor);
}
.confirm {
color: var(--selectedFontColor);
}
.el-time-panel__footer {
border-top: 1px solid var(--fontColor);
.cancel {
span {
color: var(--fontColor);
}
}
// 确定按钮
.confirm {
border: none;
color: var(--fontColor);
background-color: var(--bgColor);
}
}
// 年选择器
.el-year-table {
a {
color: var(--fontColor);
&:hover {
color: var(--hoverFontColor);
}
}
}
// 月选择器
.el-month-table {
a {
color: var(--fontColor);
&:hover {
color: var(--hoverFontColor);
}
}
}
// 上月 下月 字体颜色置灰
.prev-month {
span {
color: #999 !important;
&:hover {
color: var(--hoverFontColor) !important;
}
}
}
.next-month {
span {
color: #999 !important;
&:hover {
color: var(--hoverFontColor) !important;
}
}
}
}
</style>
<style lang="scss" scoped>
.basic-component-date-picker {
width: 100% !important;
height: 100% !important;
// 范围时间选择器连接符
::v-deep .el-range-separator {
display: flex !important;
align-items: center !important;
}
.el-input--mini ::v-deep .el-input__inner {
height: 100% !important;
line-height: 100% !important;
}
.el-tag.el-tag--info {
color: var(--bs-el-text) !important;
}
}
::v-deep .el-input__inner {
height: 100% !important;
line-height: 100% !important;
}
::v-deep .el-range-input {
width: 45% !important;
}</style>