refactor: improve date handling and timezone consistency

- Add timezone support to database module (+08:00)
- Extract date formatting utilities to shared modules
- Standardize timezone handling across frontend and backend
- Improve date formatting consistency in UI components
- Refactor crawler page.goto options for better readability
This commit is contained in:
dmy
2026-01-15 16:17:41 +08:00
parent eba5c7e5c5
commit 5edebd9d55
20 changed files with 219 additions and 57 deletions

View File

@@ -54,6 +54,7 @@ import { ref } from 'vue'
import api from '../utils/api'
import { ElMessage } from 'element-plus'
import { Paperclip } from '@element-plus/icons-vue'
import { formatDate } from '../utils/date.util'
interface Props {
bids: any[]
@@ -72,11 +73,6 @@ const selectedSource = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const formatDate = (dateString: string) => {
if (!dateString) return '-'
return new Date(dateString).toLocaleDateString()
}
const handleSourceChange = () => {
currentPage.value = 1
emit('fetch', currentPage.value, pageSize.value, selectedSource.value || undefined)

View File

@@ -16,12 +16,12 @@
<el-table-column prop="count" label="本次获取数量" width="120" sortable />
<el-table-column label="最近更新时间" width="180">
<template #default="{ row }">
{{ formatDate(row.latestUpdate) }}
{{ formatDateTime(row.latestUpdate) }}
</template>
</el-table-column>
<el-table-column label="最新工程时间" width="180">
<template #default="{ row }">
{{ formatDate(row.latestPublishDate) }}
{{ formatDateTime(row.latestPublishDate) }}
</template>
</el-table-column>
<el-table-column label="状态" width="100">
@@ -78,6 +78,7 @@ import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import api from '../utils/api'
import { ElMessage } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import { formatDateTime } from '../utils/date.util'
interface CrawlStat {
source: string
@@ -90,7 +91,6 @@ interface CrawlStat {
const crawlStats = ref<CrawlStat[]>([])
const loading = ref(false)
const crawlingSources = ref<Set<string>>(new Set())
const REFRESH_INTERVAL = 10000
let refreshTimer: number | null = null
const totalCount = computed(() => {
@@ -105,18 +105,6 @@ const errorSources = computed(() => {
return crawlStats.value.filter(item => item.error && item.error.trim()).length
})
const formatDate = (dateStr: string | null) => {
if (!dateStr) return '-'
const date = new Date(dateStr)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
})
}
const fetchCrawlStats = async () => {
loading.value = true
try {

View File

@@ -81,6 +81,7 @@ import api from '../utils/api'
import { ElMessage } from 'element-plus'
import { Refresh, Paperclip } from '@element-plus/icons-vue'
import PinnedProject from './PinnedProject.vue'
import { formatDate } from '../utils/date.util'
interface Props {
todayBids: any[]
@@ -160,11 +161,6 @@ watch(dateRange, () => {
}
})
const formatDate = (dateString: string) => {
if (!dateString) return '-'
return new Date(dateString).toLocaleDateString()
}
// 过滤 Today's Bids只显示包含所选关键字的项目并且在日期范围内
const filteredTodayBids = computed(() => {
let result = props.todayBids

View File

@@ -38,7 +38,7 @@
<el-table-column prop="source" label="来源" width="200" />
<el-table-column prop="publishDate" label="发布日期" width="180">
<template #default="scope">
{{ formatDate(scope.row.publishDate) }}
{{ formatSimpleDate(scope.row.publishDate) }}
</template>
</el-table-column>
</el-table>
@@ -51,6 +51,7 @@ import { ref, onMounted } from 'vue'
import api from '../utils/api'
import { ElMessage } from 'element-plus'
import { Loading, InfoFilled, Paperclip } from '@element-plus/icons-vue'
import { formatSimpleDate } from '../utils/date.util'
const emit = defineEmits<{
pinChanged: [title: string]
@@ -88,16 +89,6 @@ const togglePin = async (item: any) => {
}
}
// 格式化日期,只显示年月日
const formatDate = (dateStr: string) => {
if (!dateStr) return ''
const date = new Date(dateStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
// 初始化时加载置顶项目
onMounted(() => {
loadPinnedBids()

View File

@@ -0,0 +1,58 @@
/**
* 日期格式化工具函数
* 统一处理东八区(Asia/Shanghai)时间显示
*/
/**
* 格式化日期为 YYYY-MM-DD 格式
* @param dateStr 日期字符串或Date对象
* @returns 格式化后的日期字符串
*/
export function formatDate(dateStr: string | null | undefined): string {
if (!dateStr) return '-'
const date = new Date(dateStr)
if (isNaN(date.getTime())) return '-'
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
timeZone: 'Asia/Shanghai'
}).replace(/\//g, '-')
}
/**
* 格式化日期时间为 YYYY-MM-DD HH:mm 格式
* @param dateStr 日期字符串或Date对象
* @returns 格式化后的日期时间字符串
*/
export function formatDateTime(dateStr: string | null | undefined): string {
if (!dateStr) return '-'
const date = new Date(dateStr)
if (isNaN(date.getTime())) return '-'
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
timeZone: 'Asia/Shanghai'
}).replace(/\//g, '-')
}
/**
* 格式化日期为简洁的 YYYY-MM-DD 格式(用于置顶项目等)
* @param dateStr 日期字符串或Date对象
* @returns 格式化后的日期字符串
*/
export function formatSimpleDate(dateStr: string | null | undefined): string {
if (!dateStr) return ''
const date = new Date(dateStr)
if (isNaN(date.getTime())) return ''
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}