fix(admin): 修复日期选择器与选曲日期的 UTC 时差错位
根本原因: 使用 toISOString().split('T')[0] 会按 UTC 时区截断日期,
在 UTC+8 时区下,本地 00:00~07:59 期间会少 1 天,导致:
- AdminDatePicker/AdminMultiDatePicker 横向条、月历选中值错位
- ScheduleManager selectedDate 今日初始化与今日排期过滤错位
- 月历今日高亮与实际日期不匹配
修复方法: 所有 YYYY-MM-DD 格式化统一使用本地时区的
getFullYear/getMonth/getDate + pad, addDays 前先 setHours(0,0,0,0) 归零
避免 DST 与时区偏移导致的跨天误差
This commit is contained in:
@@ -172,16 +172,17 @@ const isLastDateVisible = ref(false)
|
||||
const dateRange = ref({ start: -15, end: 15 })
|
||||
const showCalendar = ref(false)
|
||||
|
||||
const today = new Date()
|
||||
const pad = (n) => n.toString().padStart(2, '0')
|
||||
const formatDateStr = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
|
||||
const addDays = (d, n) => { const x = new Date(d); x.setHours(0, 0, 0, 0); x.setDate(x.getDate() + n); return x }
|
||||
const sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()
|
||||
|
||||
const today = new Date(); today.setHours(0, 0, 0, 0)
|
||||
const calendarYear = ref(today.getFullYear())
|
||||
const calendarMonth = ref(today.getMonth())
|
||||
|
||||
const weekdayNames = ['日', '一', '二', '三', '四', '五', '六']
|
||||
|
||||
const formatDateStr = (d) => d.toISOString().split('T')[0]
|
||||
const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate() + n); return x }
|
||||
const sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()
|
||||
|
||||
const availableDates = computed(() => {
|
||||
const dates = []
|
||||
for (let i = dateRange.value.start; i <= dateRange.value.end; i++) {
|
||||
|
||||
@@ -195,17 +195,18 @@ const dateRange = ref({ start: 0, end: 45 })
|
||||
const showCalendar = ref(false)
|
||||
const lastClickedDate = ref('')
|
||||
|
||||
const today = new Date()
|
||||
const pad = (n) => n.toString().padStart(2, '0')
|
||||
const formatDateStr = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
|
||||
const addDays = (d, n) => { const x = new Date(d); x.setHours(0, 0, 0, 0); x.setDate(x.getDate() + n); return x }
|
||||
const sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()
|
||||
const sortDates = (arr) => [...new Set(arr)].sort()
|
||||
|
||||
const today = new Date(); today.setHours(0, 0, 0, 0)
|
||||
const calendarYear = ref(today.getFullYear())
|
||||
const calendarMonth = ref(today.getMonth())
|
||||
|
||||
const weekdayNames = ['日', '一', '二', '三', '四', '五', '六']
|
||||
|
||||
const formatDateStr = (d) => d.toISOString().split('T')[0]
|
||||
const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate() + n); return x }
|
||||
const sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()
|
||||
const sortDates = (arr) => [...new Set(arr)].sort()
|
||||
|
||||
const availableDates = computed(() => {
|
||||
const dates = []
|
||||
for (let i = dateRange.value.start; i <= dateRange.value.end; i++) {
|
||||
|
||||
@@ -974,7 +974,9 @@ const defaultAutoConfig: AutoConfig = {
|
||||
|
||||
// 响应式数据
|
||||
const showCardGenerator = ref(false)
|
||||
const selectedDate = ref(new Date().toISOString().split('T')[0])
|
||||
const _pad = (n) => n.toString().padStart(2, '0')
|
||||
const _today = new Date(); _today.setHours(0, 0, 0, 0)
|
||||
const selectedDate = ref(`${_today.getFullYear()}-${_pad(_today.getMonth() + 1)}-${_pad(_today.getDate())}`)
|
||||
const loading = ref(false)
|
||||
const songSortOption = ref<AutoConfig['songSortOption']>('votes-desc')
|
||||
const hasChanges = ref(false)
|
||||
@@ -1695,17 +1697,22 @@ const updateLocalScheduledSongs = () => {
|
||||
console.log('公开排期数量:', publicSchedules.value.length)
|
||||
console.log('草稿数量:', drafts.value.length)
|
||||
|
||||
const _fmtLocal = (d) => {
|
||||
const x = new Date(d)
|
||||
return `${x.getFullYear()}-${_pad(x.getMonth() + 1)}-${_pad(x.getDate())}`
|
||||
}
|
||||
|
||||
// 获取已发布的排期
|
||||
const todaySchedules = publicSchedules.value.filter((s) => {
|
||||
if (!s.playDate) return false
|
||||
const scheduleDateStr = new Date(s.playDate).toISOString().split('T')[0]
|
||||
const scheduleDateStr = _fmtLocal(s.playDate)
|
||||
return scheduleDateStr === selectedDate.value
|
||||
})
|
||||
|
||||
// 获取草稿排期
|
||||
const todayDrafts = drafts.value.filter((draft) => {
|
||||
if (!draft.playDate) return false
|
||||
const draftDateStr = new Date(draft.playDate).toISOString().split('T')[0]
|
||||
const draftDateStr = _fmtLocal(draft.playDate)
|
||||
return draftDateStr === selectedDate.value
|
||||
})
|
||||
|
||||
@@ -2210,7 +2217,7 @@ const confirmMoveDate = async () => {
|
||||
const sourceDate = selectedDate.value
|
||||
const sourceSchedules = [...publicSchedules.value, ...drafts.value].filter((schedule) => {
|
||||
if (!schedule.playDate) return false
|
||||
return new Date(schedule.playDate).toISOString().split('T')[0] === sourceDate
|
||||
return _fmtLocal(schedule.playDate) === sourceDate
|
||||
})
|
||||
|
||||
if (sourceSchedules.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user