mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-05-09 07:11:12 +08:00
fix: 部分UI在英文设置下未国际化
This commit is contained in:
@@ -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,
|
||||
}))
|
||||
|
||||
@@ -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') : '未知'
|
||||
}
|
||||
|
||||
/** 小时活跃度 */
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "周二",
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -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
@@ -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') : '未知'
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user