fix: 部分UI在英文设置下未国际化

This commit is contained in:
digua
2026-02-21 14:23:18 +08:00
parent bc6c385c39
commit fe0a2ed010
12 changed files with 144 additions and 61 deletions
+2 -2
View File
@@ -78,7 +78,7 @@ const monthNames = computed(() => [
const typeChartData = computed<EChartPieData>(() => {
const sorted = [...messageTypes.value].sort((a, b) => b.count - a.count)
return {
labels: sorted.map((item) => getMessageTypeName(item.type)),
labels: sorted.map((item) => getMessageTypeName(item.type, t)),
values: sorted.map((item) => item.count),
}
})
@@ -89,7 +89,7 @@ const typeSummary = computed(() => {
const sorted = [...messageTypes.value].sort((a, b) => b.count - a.count)
return sorted.map((item) => ({
name: getMessageTypeName(item.type),
name: getMessageTypeName(item.type, t),
count: item.count,
percentage: total > 0 ? Math.round((item.count / total) * 100) : 0,
}))
+34 -24
View File
@@ -25,32 +25,42 @@ export enum MessageType {
OTHER = 99,
}
/** 消息类型名称映射 */
const MESSAGE_TYPE_NAMES: Record<number, string> = {
[MessageType.TEXT]: '文字',
[MessageType.IMAGE]: '图片',
[MessageType.VOICE]: '语音',
[MessageType.VIDEO]: '视频',
[MessageType.FILE]: '文件',
[MessageType.EMOJI]: '表情',
[MessageType.LINK]: '链接',
[MessageType.LOCATION]: '位置',
[MessageType.RED_PACKET]: '红包',
[MessageType.TRANSFER]: '转账',
[MessageType.POKE]: '拍一拍',
[MessageType.CALL]: '通话',
[MessageType.SHARE]: '分享',
[MessageType.REPLY]: '回复',
[MessageType.FORWARD]: '转发',
[MessageType.CONTACT]: '名片',
[MessageType.SYSTEM]: '系统',
[MessageType.RECALL]: '撤回',
[MessageType.OTHER]: '其他',
/** 消息类型 i18n key 映射 */
const MESSAGE_TYPE_KEYS: Record<number, string> = {
// 基础消息类型
[MessageType.TEXT]: 'text',
[MessageType.IMAGE]: 'image',
[MessageType.VOICE]: 'voice',
[MessageType.VIDEO]: 'video',
[MessageType.FILE]: 'file',
[MessageType.EMOJI]: 'emoji',
[MessageType.LINK]: 'link',
[MessageType.LOCATION]: 'location',
// 交互消息类型
[MessageType.RED_PACKET]: 'redPacket',
[MessageType.TRANSFER]: 'transfer',
[MessageType.POKE]: 'poke',
[MessageType.CALL]: 'call',
[MessageType.SHARE]: 'share',
[MessageType.REPLY]: 'reply',
[MessageType.FORWARD]: 'forward',
[MessageType.CONTACT]: 'contact',
// 系统消息类型
[MessageType.SYSTEM]: 'system',
[MessageType.RECALL]: 'recall',
// 其他
[MessageType.OTHER]: 'other',
}
/** 获取消息类型名称 */
export function getMessageTypeName(type: MessageType | number): string {
return MESSAGE_TYPE_NAMES[type] || '未知'
/**
* 获取消息类型名称
* @param type 消息类型
* @param t 可选的 i18n t 函数,传入时使用 common.messageType.* 键
*/
export function getMessageTypeName(type: MessageType | number, t?: (key: string) => string): string {
const key = MESSAGE_TYPE_KEYS[type]
if (t && key) return t(`common.messageType.${key}`)
return t ? t('common.messageType.unknown') : '未知'
}
/** 小时活跃度 */
+28 -4
View File
@@ -3,6 +3,7 @@
* ECharts 日历热力图组件(GitHub 贡献图风格)
*/
import { computed, ref, watch, onMounted, onUnmounted } from 'vue'
import { useI18n } from 'vue-i18n'
import * as echarts from 'echarts/core'
import { HeatmapChart } from 'echarts/charts'
import { CalendarComponent, TooltipComponent, VisualMapComponent } from 'echarts/components'
@@ -30,6 +31,7 @@ const props = withDefaults(defineProps<Props>(), {
height: 180,
})
const { t, locale } = useI18n()
const isDark = useDark()
const chartRef = ref<HTMLElement | null>(null)
let chartInstance: echarts.ECharts | null = null
@@ -70,7 +72,7 @@ const option = computed<ECOption>(() => ({
formatter: (params: any) => {
const date = params.data[0]
const value = params.data[1]
return `${date}<br/>消息: ${value}`
return `${date}<br/>${t('views.message.calendarTooltipMessages')}: ${value}`
},
},
visualMap: {
@@ -111,13 +113,35 @@ const option = computed<ECOption>(() => ({
show: true,
color: isDark.value ? '#9ca3af' : '#6b7280',
fontSize: 10,
nameMap: [
t('common.month.jan'),
t('common.month.feb'),
t('common.month.mar'),
t('common.month.apr'),
t('common.month.may'),
t('common.month.jun'),
t('common.month.jul'),
t('common.month.aug'),
t('common.month.sep'),
t('common.month.oct'),
t('common.month.nov'),
t('common.month.dec'),
],
},
dayLabel: {
show: true,
firstDay: 1, // 从周一开始
color: isDark.value ? '#6b7280' : '#9ca3af',
fontSize: 10,
nameMap: ['日', '一', '二', '三', '四', '五', '六'],
nameMap: [
t('common.weekday.sun'),
t('common.weekday.mon'),
t('common.weekday.tue'),
t('common.weekday.wed'),
t('common.weekday.thu'),
t('common.weekday.fri'),
t('common.weekday.sat'),
],
},
splitLine: {
show: false,
@@ -153,8 +177,8 @@ function handleResize() {
chartInstance?.resize()
}
// 监听数据主题变化
watch([() => props.data, isDark], () => {
// 监听数据主题、语言变化
watch([() => props.data, isDark, locale], () => {
updateChart()
})
+22
View File
@@ -40,6 +40,28 @@
"members": "members",
"days": "days"
},
"messageType": {
"text": "Text",
"image": "Image",
"voice": "Voice",
"video": "Video",
"file": "File",
"emoji": "Emoji",
"link": "Link",
"location": "Location",
"redPacket": "Red Packet",
"transfer": "Transfer",
"poke": "Poke",
"call": "Call",
"share": "Share",
"reply": "Reply",
"forward": "Forward",
"contact": "Contact",
"system": "System",
"recall": "Recalled",
"other": "Other",
"unknown": "Unknown"
},
"weekday": {
"mon": "Mon",
"tue": "Tue",
+1
View File
@@ -37,6 +37,7 @@
"heatmapHint": "Shows chat time patterns",
"calendarHeatmap": "Message Calendar",
"calendarHint": "Daily message distribution",
"calendarTooltipMessages": "Messages",
"lengthDetailTitle": "Short Messages (1-25 chars)",
"lengthDetailHint": "Per character",
"lengthGroupedTitle": "Length Range Distribution",
+22
View File
@@ -40,6 +40,28 @@
"members": "个成员",
"days": "天"
},
"messageType": {
"text": "文字",
"image": "图片",
"voice": "语音",
"video": "视频",
"file": "文件",
"emoji": "表情",
"link": "链接",
"location": "位置",
"redPacket": "红包",
"transfer": "转账",
"poke": "拍一拍",
"call": "通话",
"share": "分享",
"reply": "回复",
"forward": "转发",
"contact": "名片",
"system": "系统",
"recall": "撤回",
"other": "其他",
"unknown": "未知"
},
"weekday": {
"mon": "周一",
"tue": "周二",
+1
View File
@@ -37,6 +37,7 @@
"heatmapHint": "展示聊天时间规律",
"calendarHeatmap": "消息日历",
"calendarHint": "每日消息分布",
"calendarTooltipMessages": "消息",
"lengthDetailTitle": "短消息分布 (1-25字)",
"lengthDetailHint": "逐字统计",
"lengthGroupedTitle": "长度区间分布",
@@ -56,8 +56,8 @@ const { dailyChartData } = useDailyTrend(props.dailyActivity)
// 消息类型图表数据
const typeChartData = computed<EChartPieData>(() => {
return {
labels: props.messageTypes.map((t) => getMessageTypeName(t.type)),
values: props.messageTypes.map((t) => t.count),
labels: props.messageTypes.map((item) => getMessageTypeName(item.type, t)),
values: props.messageTypes.map((item) => item.count),
}
})
+2 -2
View File
@@ -208,7 +208,7 @@ onMounted(() => {
icon="i-heroicons-plus-circle"
@click="showIncrementalImportModal = true"
>
{{ t('analysis.incrementalImport', '增量导入') }}
{{ t('analysis.tooltip.incrementalImport') }}
</UButton>
<UButton
color="primary"
@@ -217,7 +217,7 @@ onMounted(() => {
icon="i-heroicons-chat-bubble-bottom-center-text"
@click="openChatRecordViewer"
>
{{ t('analysis.chatViewer', '聊天记录查看器') }}
{{ t('analysis.tooltip.chatViewer') }}
</UButton>
<UTooltip :text="t('analysis.tooltip.sessionIndex')">
<UButton
@@ -54,8 +54,8 @@ const { dailyChartData } = useDailyTrend(props.dailyActivity)
// 消息类型图表数据
const typeChartData = computed<EChartPieData>(() => {
return {
labels: props.messageTypes.map((t) => getMessageTypeName(t.type)),
values: props.messageTypes.map((t) => t.count),
labels: props.messageTypes.map((item) => getMessageTypeName(item.type, t)),
values: props.messageTypes.map((item) => item.count),
}
})
+2 -2
View File
@@ -220,7 +220,7 @@ onMounted(() => {
icon="i-heroicons-plus-circle"
@click="showIncrementalImportModal = true"
>
{{ t('analysis.incrementalImport', '增量导入') }}
{{ t('analysis.tooltip.incrementalImport') }}
</UButton>
<UButton
color="primary"
@@ -229,7 +229,7 @@ onMounted(() => {
icon="i-heroicons-chat-bubble-bottom-center-text"
@click="openChatRecordViewer"
>
{{ t('analysis.chatViewer', '聊天记录查看器') }}
{{ t('analysis.tooltip.chatViewer') }}
</UButton>
<UTooltip :text="t('analysis.tooltip.sessionIndex')">
<UButton
+26 -23
View File
@@ -44,40 +44,43 @@ export enum MessageType {
}
/**
* 消息类型名称映射
* 消息类型 i18n key 映射
*/
export const MESSAGE_TYPE_NAMES: Record<number, string> = {
const MESSAGE_TYPE_KEYS: Record<number, string> = {
// 基础消息类型
[MessageType.TEXT]: '文字',
[MessageType.IMAGE]: '图片',
[MessageType.VOICE]: '语音',
[MessageType.VIDEO]: '视频',
[MessageType.FILE]: '文件',
[MessageType.EMOJI]: '表情',
[MessageType.LINK]: '链接',
[MessageType.LOCATION]: '位置',
[MessageType.TEXT]: 'text',
[MessageType.IMAGE]: 'image',
[MessageType.VOICE]: 'voice',
[MessageType.VIDEO]: 'video',
[MessageType.FILE]: 'file',
[MessageType.EMOJI]: 'emoji',
[MessageType.LINK]: 'link',
[MessageType.LOCATION]: 'location',
// 交互消息类型
[MessageType.RED_PACKET]: '红包',
[MessageType.TRANSFER]: '转账',
[MessageType.POKE]: '拍一拍',
[MessageType.CALL]: '通话',
[MessageType.SHARE]: '分享',
[MessageType.REPLY]: '回复',
[MessageType.FORWARD]: '转发',
[MessageType.CONTACT]: '名片',
[MessageType.RED_PACKET]: 'redPacket',
[MessageType.TRANSFER]: 'transfer',
[MessageType.POKE]: 'poke',
[MessageType.CALL]: 'call',
[MessageType.SHARE]: 'share',
[MessageType.REPLY]: 'reply',
[MessageType.FORWARD]: 'forward',
[MessageType.CONTACT]: 'contact',
// 系统消息类型
[MessageType.SYSTEM]: '系统',
[MessageType.RECALL]: '撤回',
[MessageType.SYSTEM]: 'system',
[MessageType.RECALL]: 'recall',
// 其他
[MessageType.OTHER]: '其他',
[MessageType.OTHER]: 'other',
}
/**
* 获取消息类型名称
* @param type 消息类型
* @param t 可选的 i18n t 函数,传入时使用 common.messageType.* 键
*/
export function getMessageTypeName(type: MessageType | number): string {
return MESSAGE_TYPE_NAMES[type] || '未知'
export function getMessageTypeName(type: MessageType | number, t?: (key: string) => string): string {
const key = MESSAGE_TYPE_KEYS[type]
if (t && key) return t(`common.messageType.${key}`)
return t ? t('common.messageType.unknown') : '未知'
}
/**