refactor: 抽取 BugCollect 公共辅助函数

新增:
- utils/bugCollect.ts - levelTag/statusTag/statusLabel/formatTime/platformTagType

重构:
- BugCollectOverview.vue - 使用公共 levelTag
- BugCollectIssues.vue - 使用公共辅助函数
- BugCollectEvents.vue - 使用公共 formatTime
- BugCollectSourcemaps.vue - 使用公共辅助函数
- BugCollectRankFreq.vue - 使用公共辅助函数
- BugCollectRankRisk.vue - 使用公共辅助函数
- BugCollectIssueDetail.vue - 使用公共辅助函数

Co-Authored-By: Claude <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-06-19 19:26:36 +08:00
父节点 34b12781c3
当前提交 2c4dcaf130
共有 8 个文件被更改,包括 81 次插入123 次删除

查看文件

@ -0,0 +1,75 @@
/**
* BugCollect
*/
/**
*
*/
export function levelTag(level: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
fatal: 'danger',
error: 'warning',
warning: '',
info: 'info',
}
return map[level?.toLowerCase()] ?? ''
}
/**
*
*/
export function statusTag(status: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
open: 'danger',
resolved: 'success',
ignored: 'info',
}
return map[status] ?? ''
}
/**
*
*/
export function statusLabel(status: string): string {
const map: Record<string, string> = {
open: '未解决',
resolved: '已解决',
ignored: '已忽略',
}
return map[status] ?? status
}
/**
* UTC
*/
export function formatTime(ts: string | null | undefined): string {
if (!ts) return '-'
// 服务端返回 UTC 时间(无时区标识),需追加 Z 表示 UTC
const date = ts.includes('Z') || ts.includes('+') ? new Date(ts) : new Date(ts + 'Z')
return date.toLocaleString('zh-CN')
}
/**
*
*/
export function platformTagType(platform: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
android: 'success',
ios: '',
harmony: 'warning',
}
return map[platform?.toLowerCase()] ?? 'info'
}
/**
* Issue
*/
export function issueTypeTag(type: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
CRASH: 'danger',
ERROR: 'warning',
ANR: 'danger',
WARNING: '',
}
return map[type] ?? ''
}

查看文件

@ -106,6 +106,7 @@
import { ref, onMounted, watch } from 'vue'
import { bugCollectApi, type BugCollectEventItem } from '@/api/bugcollect'
import { useBugCollectApp } from '@/composables/useBugCollectApp'
import { formatTime } from '@/utils/bugCollect'
const { apps, loadingApps, appKey, setApp, gateStatus, applyDialogVisible, applyReason, applyLoading, submitActivation } = useBugCollectApp()
@ -121,13 +122,6 @@ const filters = ref({
dateRange: null as [string, string] | null,
})
function formatTime(ts: string) {
if (!ts) return '-'
// UTC Z UTC
const date = ts.includes('Z') || ts.includes('+') ? new Date(ts) : new Date(ts + 'Z')
return date.toLocaleString('zh-CN')
}
async function loadData() {
if (!appKey.value || gateStatus.value !== 'enabled') return
loading.value = true

查看文件

@ -156,24 +156,8 @@ function levelTag(level: string): '' | 'success' | 'warning' | 'info' | 'danger'
return map[level?.toLowerCase()] ?? ''
}
function statusTag(status: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
open: 'danger', resolved: 'success', ignored: 'info',
}
return map[status] ?? ''
}
function statusLabel(status: string): string {
const map: Record<string, string> = { open: '未解决', resolved: '已解决', ignored: '已忽略' }
return map[status] ?? status
}
function formatTime(ts: string): string {
if (!ts) return '-'
// UTC Z UTC
const date = ts.includes('Z') || ts.includes('+') ? new Date(ts) : new Date(ts + 'Z')
return date.toLocaleString('zh-CN')
}
async function handleResolve() {
if (!detail.value) return

查看文件

@ -102,6 +102,7 @@
import { ref, onMounted, watch } from 'vue'
import { bugCollectApi, type BugCollectIssue } from '@/api/bugcollect'
import { useBugCollectApp } from '@/composables/useBugCollectApp'
import { levelTag, statusTag, statusLabel, formatTime } from '@/utils/bugCollect'
const { apps, loadingApps, appKey, setApp, gateStatus, applyDialogVisible, applyReason, applyLoading, submitActivation } = useBugCollectApp()
@ -117,37 +118,6 @@ const filters = ref({
dateRange: null as [string, string] | null,
})
function levelTag(level: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
fatal: 'danger',
error: 'warning',
warning: '',
info: 'info',
}
return map[level?.toLowerCase()] ?? ''
}
function statusTag(status: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
open: 'danger',
resolved: 'success',
ignored: 'info',
}
return map[status] ?? ''
}
function statusLabel(status: string): string {
const map: Record<string, string> = { open: '未解决', resolved: '已解决', ignored: '已忽略' }
return map[status] ?? status
}
function formatTime(ts: string) {
if (!ts) return '-'
// UTC Z UTC
const date = ts.includes('Z') || ts.includes('+') ? new Date(ts) : new Date(ts + 'Z')
return date.toLocaleString('zh-CN')
}
async function loadData() {
if (!appKey.value || gateStatus.value !== 'enabled') return
loading.value = true

查看文件

@ -133,6 +133,7 @@ import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { bugCollectApi, type BugCollectOverview, type BugCollectStatistics } from '@/api/bugcollect'
import { Warning, Plus, User, WarningFilled } from '@element-plus/icons-vue'
import { useBugCollectApp } from '@/composables/useBugCollectApp'
import { levelTag } from '@/utils/bugCollect'
import * as echarts from 'echarts'
const { apps, loadingApps, appKey, setApp, gateStatus, applyDialogVisible, applyReason, applyLoading, submitActivation } = useBugCollectApp()
@ -172,16 +173,6 @@ let statusChart: echarts.ECharts | null = null
let platformChart: echarts.ECharts | null = null
let versionChart: echarts.ECharts | null = null
function levelTag(level: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
fatal: 'danger',
error: 'warning',
warning: '',
info: 'info',
}
return map[level?.toLowerCase()] ?? ''
}
function getDaysAgo(days: number): string {
const d = new Date()
d.setDate(d.getDate() - days)

查看文件

@ -70,6 +70,7 @@
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { bugCollectApi, type BugCollectIssueRanking } from '@/api/bugcollect'
import { useBugCollectApp } from '@/composables/useBugCollectApp'
import { levelTag, statusTag, statusLabel, formatTime } from '@/utils/bugCollect'
import * as echarts from 'echarts'
const { apps, loadingApps, appKey, setApp, gateStatus, applyDialogVisible, applyReason, applyLoading, submitActivation } = useBugCollectApp()
@ -85,36 +86,9 @@ const LEVEL_COLORS: Record<string, string> = {
warning: '#409EFF',
}
function levelTag(level: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
fatal: 'danger',
error: 'warning',
warning: '',
info: 'info',
}
return map[level?.toLowerCase()] ?? ''
}
function statusTag(status: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
open: 'danger',
resolved: 'success',
ignored: 'info',
}
return map[status] ?? ''
}
function statusLabel(status: string): string {
const map: Record<string, string> = { open: '未解决', resolved: '已解决', ignored: '已忽略' }
return map[status] ?? status
}
function formatTime(ts: string) {
if (!ts) return '-'
// UTC Z UTC
const date = ts.includes('Z') || ts.includes('+') ? new Date(ts) : new Date(ts + 'Z')
return date.toLocaleString('zh-CN')
}
function truncateTitle(title: string, maxLen = 30): string {
if (!title) return ''

查看文件

@ -75,6 +75,7 @@
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { bugCollectApi, type BugCollectIssueRanking } from '@/api/bugcollect'
import { useBugCollectApp } from '@/composables/useBugCollectApp'
import { levelTag, statusTag, statusLabel, formatTime } from '@/utils/bugCollect'
import * as echarts from 'echarts'
const { apps, loadingApps, appKey, setApp, gateStatus, applyDialogVisible, applyReason, applyLoading, submitActivation } = useBugCollectApp()
@ -90,29 +91,8 @@ const LEVEL_COLORS: Record<string, string> = {
warning: '#409EFF',
}
function levelTag(level: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
fatal: 'danger',
error: 'warning',
warning: '',
info: 'info',
}
return map[level?.toLowerCase()] ?? ''
}
function statusTag(status: string): '' | 'success' | 'warning' | 'info' | 'danger' {
const map: Record<string, '' | 'success' | 'warning' | 'info' | 'danger'> = {
open: 'danger',
resolved: 'success',
ignored: 'info',
}
return map[status] ?? ''
}
function statusLabel(status: string): string {
const map: Record<string, string> = { open: '未解决', resolved: '已解决', ignored: '已忽略' }
return map[status] ?? status
}
function riskTagType(score?: number) {
if (!score) return 'info'
@ -121,12 +101,6 @@ function riskTagType(score?: number) {
return 'success'
}
function formatTime(ts: string) {
if (!ts) return '-'
// UTC Z UTC
const date = ts.includes('Z') || ts.includes('+') ? new Date(ts) : new Date(ts + 'Z')
return date.toLocaleString('zh-CN')
}
function truncateTitle(title: string, maxLen = 30): string {
if (!title) return ''

查看文件

@ -96,6 +96,7 @@ npx react-native bundle --platform android --dev false</pre>
import { ref, onMounted, watch } from 'vue'
import { bugCollectApi, type BugCollectSourcemap } from '@/api/bugcollect'
import { useBugCollectApp } from '@/composables/useBugCollectApp'
import { levelTag, statusTag, statusLabel, formatTime } from '@/utils/bugCollect'
const { apps, loadingApps, appKey, setApp, gateStatus, applyDialogVisible, applyReason, applyLoading, submitActivation } = useBugCollectApp()
@ -111,11 +112,6 @@ function platformTagType(platform: string): '' | 'success' | 'warning' | 'info'
return map[platform?.toLowerCase()] ?? 'info'
}
function formatTime(ts: string) {
if (!ts) return '-'
const date = ts.includes('Z') || ts.includes('+') ? new Date(ts) : new Date(ts + 'Z')
return date.toLocaleString('zh-CN')
}
async function loadData() {
if (!appKey.value || gateStatus.value !== 'enabled') return