diff --git a/web/admin-spa/dist/assets/ApiKeysView-TPhICvaG.css b/web/admin-spa/dist/assets/ApiKeysView-TPhICvaG.css
deleted file mode 100644
index 6b914cc9..00000000
--- a/web/admin-spa/dist/assets/ApiKeysView-TPhICvaG.css
+++ /dev/null
@@ -1 +0,0 @@
-pre[data-v-3d91f349]{white-space:pre-wrap;word-wrap:break-word}.tab-content[data-v-518dfd83]{min-height:calc(100vh - 300px)}.table-container[data-v-518dfd83]{overflow-x:auto;border-radius:12px;border:1px solid rgba(0,0,0,.05)}.table-row[data-v-518dfd83]{transition:all .2s ease}.table-row[data-v-518dfd83]:hover{background-color:#00000005}.loading-spinner[data-v-518dfd83]{width:24px;height:24px;border:2px solid #e5e7eb;border-top:2px solid #3b82f6;border-radius:50%;animation:spin-518dfd83 1s linear infinite}@keyframes spin-518dfd83{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.api-key-date-picker[data-v-518dfd83] .el-input__inner{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.api-key-date-picker[data-v-518dfd83] .el-input__inner:focus{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1));--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.api-key-date-picker[data-v-518dfd83] .el-range-separator{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}
diff --git a/web/admin-spa/dist/index.html b/web/admin-spa/dist/index.html
index fe670ac7..656f0c25 100644
--- a/web/admin-spa/dist/index.html
+++ b/web/admin-spa/dist/index.html
@@ -18,7 +18,7 @@
-
+
diff --git a/web/admin-spa/src/stores/dashboard.js b/web/admin-spa/src/stores/dashboard.js
index 787ac6f8..f0ddd08e 100644
--- a/web/admin-spa/src/stores/dashboard.js
+++ b/web/admin-spa/src/stores/dashboard.js
@@ -91,29 +91,27 @@ export const useDashboardStore = defineStore('dashboard', () => {
}
// 辅助函数:获取系统时区某一天的起止UTC时间
- // 输入:一个日期(以用户本地时间表示)
+ // 输入:一个系统时区的日期对象
// 输出:该日期在系统时区的0点/23:59对应的UTC时间
- function getSystemTimezoneDay(localDate, startOfDay = true) {
+ function getSystemTimezoneDay(systemTzDate, startOfDay = true) {
const offset = dashboardData.value.systemTimezone || 8
- // 获取用户本地日期的年月日
- const year = localDate.getFullYear()
- const month = localDate.getMonth()
- const day = localDate.getDate()
+ // 获取系统时区日期的年月日
+ const year = systemTzDate.getFullYear()
+ const month = systemTzDate.getMonth()
+ const day = systemTzDate.getDate()
- // 创建UTC时间,表示系统时区的该日期
+ // 创建系统时区的日期时间
if (startOfDay) {
- // 系统时区YYYY-MM-DD 00:00:00 对应的UTC时间
- const utcDate = new Date(Date.UTC(year, month, day, 0, 0, 0, 0))
- // 减去系统时区偏移得到UTC时间
- utcDate.setUTCHours(utcDate.getUTCHours() - offset)
- return utcDate
+ // 系统时区 YYYY-MM-DD 00:00:00
+ const systemDateTime = new Date(year, month, day, 0, 0, 0, 0)
+ // 转换为UTC时间:减去时区偏移
+ return new Date(systemDateTime.getTime() - offset * 3600000)
} else {
- // 系统时区YYYY-MM-DD 23:59:59.999 对应的UTC时间
- const utcDate = new Date(Date.UTC(year, month, day, 23, 59, 59, 999))
- // 减去系统时区偏移得到UTC时间
- utcDate.setUTCHours(utcDate.getUTCHours() - offset)
- return utcDate
+ // 系统时区 YYYY-MM-DD 23:59:59.999
+ const systemDateTime = new Date(year, month, day, 23, 59, 59, 999)
+ // 转换为UTC时间:减去时区偏移
+ return new Date(systemDateTime.getTime() - offset * 3600000)
}
}
@@ -182,9 +180,24 @@ export const useDashboardStore = defineStore('dashboard', () => {
url += `granularity=hour`
if (dateFilter.value.customRange && dateFilter.value.customRange.length === 2) {
- // 使用自定义时间范围
- url += `&startDate=${encodeURIComponent(dateFilter.value.customRange[0])}`
- url += `&endDate=${encodeURIComponent(dateFilter.value.customRange[1])}`
+ // 使用自定义时间范围 - 需要将系统时区时间转换为UTC
+ const convertToUTC = (systemTzTimeStr) => {
+ const systemTz = dashboardData.value.systemTimezone || 8
+ // 解析系统时区时间字符串
+ const [datePart, timePart] = systemTzTimeStr.split(' ')
+ const [year, month, day] = datePart.split('-').map(Number)
+ const [hours, minutes, seconds] = timePart.split(':').map(Number)
+
+ // 创建系统时区的Date对象
+ const systemDate = new Date(year, month - 1, day, hours, minutes, seconds)
+
+ // 转换为UTC
+ const utcTime = systemDate.getTime() - (systemTz * 3600000)
+ return new Date(utcTime).toISOString()
+ }
+
+ url += `&startDate=${encodeURIComponent(convertToUTC(dateFilter.value.customRange[0]))}`
+ url += `&endDate=${encodeURIComponent(convertToUTC(dateFilter.value.customRange[1]))}`
} else {
// 使用预设计算时间范围,与loadApiKeysTrend保持一致
const now = new Date()
@@ -199,14 +212,14 @@ export const useDashboardStore = defineStore('dashboard', () => {
break
case 'yesterday':
// 昨天:基于系统时区的昨天
- const yesterday = new Date(now)
+ const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
startTime = getSystemTimezoneDay(yesterday, true)
endTime = getSystemTimezoneDay(yesterday, false)
break
case 'dayBefore':
// 前天:基于系统时区的前天
- const dayBefore = new Date(now)
+ const dayBefore = new Date()
dayBefore.setDate(dayBefore.getDate() - 2)
startTime = getSystemTimezoneDay(dayBefore, true)
endTime = getSystemTimezoneDay(dayBefore, false)
@@ -260,9 +273,24 @@ export const useDashboardStore = defineStore('dashboard', () => {
url += `granularity=hour`
if (dateFilter.value.customRange && dateFilter.value.customRange.length === 2) {
- // 使用自定义时间范围
- url += `&startDate=${encodeURIComponent(dateFilter.value.customRange[0])}`
- url += `&endDate=${encodeURIComponent(dateFilter.value.customRange[1])}`
+ // 使用自定义时间范围 - 需要将系统时区时间转换为UTC
+ const convertToUTC = (systemTzTimeStr) => {
+ const systemTz = dashboardData.value.systemTimezone || 8
+ // 解析系统时区时间字符串
+ const [datePart, timePart] = systemTzTimeStr.split(' ')
+ const [year, month, day] = datePart.split('-').map(Number)
+ const [hours, minutes, seconds] = timePart.split(':').map(Number)
+
+ // 创建系统时区的Date对象
+ const systemDate = new Date(year, month - 1, day, hours, minutes, seconds)
+
+ // 转换为UTC
+ const utcTime = systemDate.getTime() - (systemTz * 3600000)
+ return new Date(utcTime).toISOString()
+ }
+
+ url += `&startDate=${encodeURIComponent(convertToUTC(dateFilter.value.customRange[0]))}`
+ url += `&endDate=${encodeURIComponent(convertToUTC(dateFilter.value.customRange[1]))}`
} else {
// 使用预设计算时间范围,与setDateFilterPreset保持一致
const now = new Date()
@@ -277,14 +305,14 @@ export const useDashboardStore = defineStore('dashboard', () => {
break
case 'yesterday':
// 昨天:基于系统时区的昨天
- const yesterday = new Date(now)
+ const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
startTime = getSystemTimezoneDay(yesterday, true)
endTime = getSystemTimezoneDay(yesterday, false)
break
case 'dayBefore':
// 前天:基于系统时区的前天
- const dayBefore = new Date(now)
+ const dayBefore = new Date()
dayBefore.setDate(dayBefore.getDate() - 2)
startTime = getSystemTimezoneDay(dayBefore, true)
endTime = getSystemTimezoneDay(dayBefore, false)
@@ -346,18 +374,20 @@ export const useDashboardStore = defineStore('dashboard', () => {
startDate = new Date(now.getTime() - 24 * 60 * 60 * 1000)
break
case 'yesterday':
- // 昨天:基于系统时区的昨天
- const yesterday2 = new Date(now)
- yesterday2.setDate(yesterday2.getDate() - 1)
- startDate = getSystemTimezoneDay(yesterday2, true)
- endDate = getSystemTimezoneDay(yesterday2, false)
+ // 昨天:获取本地时间的昨天
+ const yesterday = new Date()
+ yesterday.setDate(yesterday.getDate() - 1)
+ // 转换为系统时区的昨天0点和23:59
+ startDate = getSystemTimezoneDay(yesterday, true)
+ endDate = getSystemTimezoneDay(yesterday, false)
break
case 'dayBefore':
- // 前天:基于系统时区的前天
- const dayBefore2 = new Date(now)
- dayBefore2.setDate(dayBefore2.getDate() - 2)
- startDate = getSystemTimezoneDay(dayBefore2, true)
- endDate = getSystemTimezoneDay(dayBefore2, false)
+ // 前天:获取本地时间的前天
+ const dayBefore = new Date()
+ dayBefore.setDate(dayBefore.getDate() - 2)
+ // 转换为系统时区的前天0点和23:59
+ startDate = getSystemTimezoneDay(dayBefore, true)
+ endDate = getSystemTimezoneDay(dayBefore, false)
break
}
} else {
@@ -381,19 +411,21 @@ export const useDashboardStore = defineStore('dashboard', () => {
dateFilter.value.customEnd = endDate.toISOString().split('T')[0]
// 设置 customRange 为 Element Plus 需要的格式
- const formatDate = (date) => {
- const year = date.getFullYear()
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- const hours = String(date.getHours()).padStart(2, '0')
- const minutes = String(date.getMinutes()).padStart(2, '0')
- const seconds = String(date.getSeconds()).padStart(2, '0')
+ // 显示系统时区的时间
+ const formatDateForDisplay = (utcDate) => {
+ const systemTzDate = getDateInSystemTimezone(utcDate)
+ const year = systemTzDate.getUTCFullYear()
+ const month = String(systemTzDate.getUTCMonth() + 1).padStart(2, '0')
+ const day = String(systemTzDate.getUTCDate()).padStart(2, '0')
+ const hours = String(systemTzDate.getUTCHours()).padStart(2, '0')
+ const minutes = String(systemTzDate.getUTCMinutes()).padStart(2, '0')
+ const seconds = String(systemTzDate.getUTCSeconds()).padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
dateFilter.value.customRange = [
- formatDate(startDate),
- formatDate(endDate)
+ formatDateForDisplay(startDate),
+ formatDateForDisplay(endDate)
]
}
@@ -409,9 +441,19 @@ export const useDashboardStore = defineStore('dashboard', () => {
dateFilter.value.customStart = value[0].split(' ')[0]
dateFilter.value.customEnd = value[1].split(' ')[0]
- // 检查日期范围限制
- const start = new Date(value[0])
- const end = new Date(value[1])
+ // 检查日期范围限制 - value中的时间已经是系统时区时间
+ const systemTz = dashboardData.value.systemTimezone || 8
+
+ // 解析系统时区时间
+ const parseSystemTime = (timeStr) => {
+ const [datePart, timePart] = timeStr.split(' ')
+ const [year, month, day] = datePart.split('-').map(Number)
+ const [hours, minutes, seconds] = timePart.split(':').map(Number)
+ return new Date(year, month - 1, day, hours, minutes, seconds)
+ }
+
+ const start = parseSystemTime(value[0])
+ const end = parseSystemTime(value[1])
if (trendGranularity.value === 'hour') {
// 小时粒度:限制 24 小时
@@ -433,7 +475,7 @@ export const useDashboardStore = defineStore('dashboard', () => {
refreshChartsData()
} else if (value === null) {
// 清空时恢复默认
- setDateFilterPreset(trendGranularity.value === 'hour' ? '7days' : '7days')
+ setDateFilterPreset(trendGranularity.value === 'hour' ? 'last24h' : '7days')
}
}