Files
sgxt_web/src/views/home/model/calendar.vue
2026-01-16 12:40:42 +08:00

505 lines
12 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>
<div style="height: 100%;">
<div class="comom-title" >
<span class="title" @click="calendarPush">敏感节点</span><span class="title switchover " @click="getFestival">直通区厅</span>
</div>
<el-calendar ref="calendar" v-model="currentDate">
<template #header="{ date }">
<div>
<el-select size="small" @change="goToSelectedMonth" v-model="selectedYear"
style="width: 80px; margin-right: 10px;">
<el-option v-for="year in years" :key="year" :label="year + '年'" :value="year" />
</el-select>
<el-select size="small" @change="goToSelectedMonth" v-model="selectedMonth" style="width: 80px;">
<el-option v-for="month in months" :key="month.value" :label="month.label" :value="month.value" />
</el-select>
</div>
<div>
<el-button size="small" @click="selectDate('today')">今天</el-button>
</div>
</template>
<template #dateCell="{ data }">
<el-popover trigger="click" :width="400" title="敏感事件" popper-class="custom-sensitive-popover">
<!-- 日期信息区域 -->
<div class="date-info-section">
<div class="gan-date-item">
<span class="date-label">公历日期</span>
<span class="date-value">{{ getYearInGanDate(data) }}</span>
</div>
<div class="lunar-date-item">
<span class="date-label">农历日期</span>
<span class="date-value">农历 {{ getLunarMonthDay(data.date, true) }}({{ getYearInGanZhis(data) }})</span>
</div>
<div class="jieqi-date-item">
<span class="date-label">节气信息</span>
<span class="date-value jieqi-highlight">{{ getYearInGanjq(data) || '无' }}</span>
</div>
<div class="jieqi-date-item">
<span class="date-label">节日信息</span>
<span class="date-value jieqi-highlight">
<span>
{{ getAllFestivals(data.date,true).join('、') || '无' }}
</span>
</span>
</div>
</div>
<!-- 敏感时间节点内容 -->
<div v-if="sensitiveNodes.length > 0" class="sensitive-content-popover">
<div v-for="(item, index) in sensitiveNodes" :key="index" class="sensitive-item-popover">
<div class="sensitive-date-popover">{{ item.jdrq }}</div>
<div class="sensitive-title-popover">{{ item.jdbt }}</div>
<div class="sensitive-desc-popover">{{ item.jdnr }}</div>
</div>
</div>
<div v-else class="sensitive-empty-popover">
暂无敏感事件
</div>
<template #reference>
<div @click="chooseDay(data)" class="dayonChage" :class="{
'day': dateVal == data.day,
'special': dataIntegration.includes(data.day),
'model': getAllFestivals(data.date).length > 0
}">
<span> {{ data.day.split("-")[2] }}</span>
<span style="font-size: 8px;"> {{ getLunarMonthDay(data.date) }}</span>
</div>
</template>
</el-popover>
</template>
</el-calendar>
</div>
</template>
<script setup>
import { ref, computed, onMounted, watch } from "vue";
import { Solar, Lunar } from 'lunar-javascript'
import { timeValidate } from "@/utils/tools";
import { useRouter } from 'vue-router'
import { tbGsxtMgjdSave, tbGsxtMgjdSelectList, tbGsxtMgjdUpdate, tbGsxtMgjdDelete } from "@/api/tbGsxtMgjd";
const dateVal = ref();
const router = useRouter()
// 获取农历月日
const getLunarMonthDay = (date, pd) => {
if (!date) return ''
const solar = Solar.fromDate(date)
const lunar = solar.getLunar()
if (pd) {
return `${lunar.getMonthInChinese()}${lunar.getDayInChinese()}`
} else {
return lunar.getJieQi() ? lunar.getJieQi() : lunar.getDayInChinese()
}
}
// 获取生效年
const getYearInGanZhis = (data) => {
const solar = Solar.fromDate(data.date)
const lunar = solar.getLunar()
return `${lunar.getYearInGanZhi()}${lunar.getMonthInGanZhiExact()}${lunar.getDayInGanZhi()}`
}
// 获取日期
const getYearInGanDate = (data) => {
const solar = Solar.fromDate(data.date)
return `${solar.getYear()}${solar.getMonth()}${solar.getDay()}日 星期${solar.getWeekInChinese()}`
}
// 获取节气
const getYearInGanjq = (data) => {
const solar = Solar.fromDate(data.date)
const lunar = solar.getLunar()
return lunar.getJieQi()
}
const selectedYear = ref();
const selectedMonth = ref('');
const calendar = ref(null)
// 生成年份选项前后10年
const years = computed(() => {
const currentYear = new Date().getFullYear();
const years = [];
for (let i = currentYear - 10; i <= currentYear + 10; i++) {
years.push(i);
}
return years;
});
// 月份选项
const months = ref([
{ label: '1月', value: 0 },
{ label: '2月', value: 1 },
{ label: '3月', value: 2 },
{ label: '4月', value: 3 },
{ label: '5月', value: 4 },
{ label: '6月', value: 5 },
{ label: '7月', value: 6 },
{ label: '8月', value: 7 },
{ label: '9月', value: 8 },
{ label: '10月', value: 9 },
{ label: '11月', value: 10 },
{ label: '12月', value: 11 }
]);
const chooseDay = (data) => {
dateVal.value = data.day
querySensitiveNodes()
}
// 敏感时间节点数据
const sensitiveNodes = ref([]);
// 查询敏感事件
const querySensitiveNodes = () => {
tbGsxtMgjdSelectList({ jdrq: dateVal.value }).then((res) => {
sensitiveNodes.value = res && res.length > 0 ? res : []
})
}
const currentDate = ref(new Date());
onMounted(() => {
initialize()
})
// 监听currentDate变化同步更新下拉选择器的值
watch(currentDate, (newDate) => {
const year = timeValidate(newDate, 'yd')
const month = timeValidate(newDate, 'ym')
selectedYear.value = parseFloat(year)
selectedMonth.value = parseFloat(month) - 1
dateVal.value = timeValidate(newDate, 'ymd')
gettingData()
})
const goToSelectedMonth = () => {
if (selectedYear.value && selectedMonth.value !== '') {
const newDate = new Date(selectedYear.value, selectedMonth.value, 1);
currentDate.value = newDate;
dateVal.value = timeValidate(currentDate.value, 'ymd')
}
};
const selectDate = (val) => {
if (!calendar.value) return
dateVal.value = timeValidate(currentDate.value, 'ymd')
calendar.value.selectDate(val)
initialize()
}
// 获取当前时间
const initialize = () => {
const year = timeValidate(currentDate.value, 'yd')
const month = timeValidate(currentDate.value, 'ym')
dateVal.value = timeValidate(currentDate.value, 'ymd')
selectedYear.value = parseFloat(year)
selectedMonth.value = parseFloat(month) - 1
gettingData()
}
const dataIntegration = ref([])
// 获取当前月份的所有信息
const gettingData = () => {
const date = new Date(dateVal.value);
date.setDate(1)
const startTime = timeValidate(date.toLocaleDateString(), 'ymd')
date.setMonth(date.getMonth() + 1);
date.setDate(0);
const endTime = timeValidate(date.toLocaleDateString(), 'ymd')
const params = { startTime, endTime }
tbGsxtMgjdSelectList(params).then(res => {
if (res && res.length > 0) {
dataIntegration.value = [...new Set(res.map(item => item.jdrq))] ? [...new Set(res.map(item => item.jdrq))] : []
}
})
}
// 获取农历月日
// const getLunarMonthDay = (date) => {
// if (!date) return ''
// const solar = Solar.fromDate(date)
// const lunar = solar.getLunar()
// return `${lunar.getMonthInChinese()}${lunar.getDayInChinese()}`
// }
const getAllFestivals = (date,boolean=false) => {
const time = new Date(date)
const solar = Solar.fromDate(time)
const lunar = solar.getLunar()
const result = []
// 获取农历节日
const lunarFestivals = lunar.getFestivals()
lunarFestivals.forEach(festival => {
result.push({
type: '农历节日',
name: festival,
})
})
// 获取公历节日
const solarFestivals = solar.getFestivals()
solarFestivals.forEach(festival => {
result.push({
type: '公历节日',
name: festival,
})
})
// 获取其他纪念日
const otherFestivals = solar.getOtherFestivals()
otherFestivals.forEach(festival => {
result.push({
type: '纪念日',
name: festival,
})
})
if (boolean) {
return result.filter(item => item.type != '纪念日').map(item => item.name)
} else {
return result.filter(item => item.type != '纪念日')
}
}
const getFestival = () => {
window.open('http://10.188.45.108:8081/uaac-server/login', '_blank');
// window.location.href = '';
}
const calendarPush = () => {
router.push('/calendar')
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/homeScreen.scss";
.zdryBox {
background: #052249;
height: 100%;
padding: 10px;
.ryBox {
height: 100%;
overflow: hidden;
overflow-y: auto;
}
}
::-webkit-scrollbar {
background-color: #263b70;
}
::-webkit-scrollbar-thumb {
background-color: #146bbe;
}
::-webkit-scrollbar-track {
background-color: #263b70;
}
::-webkit-scrollbar-corner {
background-color: #142141;
}
::v-deep .el-calendar__header {
padding: 4px 20px !important;
color: #fff;
}
::v-deep .el-calendar__body {
padding: 3px 20px 35px !important;
}
::v-deep .el-calendar-table thead th {
padding: 4px 0 !important;
color: #fff;
}
::v-deep .el-calendar-table td.is-today {
color: #35ff02;
}
/* 敏感事件列表容器 */
.sensitive-content-popover {
padding: 12px;
overflow: auto;
max-height: 350px;
background-color: #fff;
}
/* 敏感事件项 */
.sensitive-item-popover {
margin-bottom: 16px;
padding: 12px;
background-color: #fafafa;
border-radius: 6px;
border-left: 4px solid #f56c6c;
transition: all 0.3s ease;
}
.sensitive-item-popover:hover {
background-color: #f5f7fa;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.sensitive-item-popover:last-child {
margin-bottom: 0;
}
/* 敏感事件日期 */
.sensitive-date-popover {
color: #909399;
font-size: 12px;
margin-bottom: 6px;
font-family: 'Courier New', monospace;
}
/* 敏感事件标题 */
.sensitive-title-popover {
font-weight: 600;
color: #303133;
margin-bottom: 8px;
font-size: 14px;
line-height: 1.4;
}
/* 敏感事件描述 */
.sensitive-desc-popover {
color: #606266;
font-size: 13px;
line-height: 1.6;
word-break: break-word;
}
/* 无敏感事件提示 */
.sensitive-empty-popover {
text-align: center;
padding: 30px 20px;
color: #909399;
font-size: 13px;
}
.sensitive-empty-popover:before {
content: "📅";
display: block;
font-size: 32px;
margin-bottom: 12px;
opacity: 0.5;
}
/* 日期信息区域样式 */
.date-info-section {
padding: 12px;
background-color: #f8f9fa;
border-radius: 6px;
margin-bottom: 10px;
border-left: 4px solid #409eff;
}
.gan-date-item,
.lunar-date-item,
.jieqi-date-item {
line-height: 28px;
display: flex;
margin-bottom: 4px;
}
.gan-date-item:last-child,
.lunar-date-item:last-child,
.jieqi-date-item:last-child {
margin-bottom: 0;
}
.date-label {
color: #606266;
font-size: 13px;
font-weight: 500;
min-width: 70px;
}
.date-value {
color: #303133;
font-size: 13px;
}
.jieqi-highlight {
color: #f56c6c;
font-weight: 500;
}
/* 自定义el-popover标题样式 */
.custom-sensitive-popover .el-popover__title {
background-color: #409eff;
color: white;
padding: 10px 15px;
margin: -1px -1px 0 -1px;
border-radius: 4px 4px 0 0;
font-size: 14px;
font-weight: 500;
}
/* 优化el-popover内容区域 */
.custom-sensitive-popover .el-popover__content {
padding: 0;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* 优化日历单元格样式 */
.dayonChage {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
}
.dayonChage:hover {
background-color: #ecf5ff;
}
.dayonChage.day {
background-color: #409eff;
color: white;
border-radius: 4px;
}
.dayonChage.special {
// background-color: #fef0f0;
border-radius: 4px;
}
.dayonChage.special.day {
background-color: #e6a23c;
color: white;
}
/* 修复日历单元格高度 */
::v-deep .el-calendar-day {
height: 35px !important;
padding: 5px !important;
text-align: center !important;
padding: 0 !important;
}
::v-deep .el-calendar-table:not(.is-range) td.prev,
::v-deep .el-calendar-table:not(.is-range) td.next {
color: #646464;
}
.day {
background-color: rgb(76, 134, 243);
color: #35ff02;
}
.special {
background-color: rgba(253, 112, 112, 0.856);
color: #ffffff;
}
.model{
background-color: rgb(76, 243, 93);
color: #ffffff;
}
.switchover{
cursor: pointer;
font-size: 14px !important;
margin-left: 20%;
color: rgb(255, 146, 4);
}
</style>