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:
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
58
frontend/src/utils/date.util.ts
Normal file
58
frontend/src/utils/date.util.ts
Normal 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}`
|
||||
}
|
||||
Reference in New Issue
Block a user