feat: 重构类型系统

This commit is contained in:
digua
2025-12-21 17:20:06 +08:00
parent 25d23bfbc8
commit 2e51a5c70d
53 changed files with 553 additions and 536 deletions

View File

@@ -3,12 +3,12 @@
* 负责各种数据分析查询 * 负责各种数据分析查询
*/ */
import type { MessageType } from '../../../src/types/base'
import type { import type {
MemberActivity, MemberActivity,
HourlyActivity, HourlyActivity,
DailyActivity, DailyActivity,
WeekdayActivity, WeekdayActivity,
MessageType,
RepeatAnalysis, RepeatAnalysis,
RepeatStatItem, RepeatStatItem,
RepeatRateItem, RepeatRateItem,
@@ -28,7 +28,7 @@ import type {
MonologueAnalysis, MonologueAnalysis,
MonologueRankItem, MonologueRankItem,
MaxComboRecord, MaxComboRecord,
} from '../../../src/types/chat' } from '../../../src/types/analysis'
import { openDatabase } from './core' import { openDatabase } from './core'
/** /**

View File

@@ -7,7 +7,7 @@ import Database from 'better-sqlite3'
import { app } from 'electron' import { app } from 'electron'
import * as fs from 'fs' import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
import type { DbMeta, ParseResult, AnalysisSession } from '../../../src/types/chat' import type { DbMeta, ParseResult, AnalysisSession } from '../../../src/types/base'
// 数据库存储目录 // 数据库存储目录
let DB_DIR: string | null = null let DB_DIR: string | null = null

View File

@@ -7,7 +7,7 @@ import * as worker from '../worker/workerManager'
import * as merger from '../merger' import * as merger from '../merger'
import { deleteTempDatabase, cleanupAllTempDatabases } from '../merger/tempCache' import { deleteTempDatabase, cleanupAllTempDatabases } from '../merger/tempCache'
import type { ParseProgress } from '../parser' import type { ParseProgress } from '../parser'
import type { MergeParams } from '../../../src/types/chat' import type { MergeParams } from '../../../src/types/format'
import type { IpcContext } from './types' import type { IpcContext } from './types'
// ==================== 临时数据库缓存 ==================== // ==================== 临时数据库缓存 ====================

View File

@@ -17,16 +17,18 @@ import type {
ChatLabMessage, ChatLabMessage,
FileParseInfo, FileParseInfo,
MergeConflict, MergeConflict,
ChatPlatform,
ChatType,
ParsedMember,
} from '../../../src/types/base'
import type {
ConflictCheckResult, ConflictCheckResult,
ConflictResolution, ConflictResolution,
MergeParams, MergeParams,
MergeResult, MergeResult,
ChatPlatform,
ChatType,
MergeSource, MergeSource,
ParsedMeta, } from '../../../src/types/format'
ParsedMember, import type { ParsedMeta } from '../parser/types'
} from '../../../src/types/chat'
/** /**
* 获取默认输出目录 * 获取默认输出目录

View File

@@ -7,7 +7,8 @@ import Database from 'better-sqlite3'
import * as fs from 'fs' import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
import { app } from 'electron' import { app } from 'electron'
import type { ParseResult, ParsedMeta, ParsedMember, ParsedMessage } from '../../../src/types/chat' import type { ParsedMember, ParsedMessage } from '../../../src/types/base'
import type { ParseResult, ParsedMeta } from '../parser/types'
// 临时数据库目录 // 临时数据库目录
let tempDir: string | null = null let tempDir: string | null = null

View File

@@ -18,7 +18,7 @@
import * as fs from 'fs' import * as fs from 'fs'
import * as readline from 'readline' import * as readline from 'readline'
import * as path from 'path' import * as path from 'path'
import { KNOWN_PLATFORMS, ChatType, MessageType, type ChatPlatform } from '../../../../src/types/chat' import { KNOWN_PLATFORMS, ChatType, MessageType, type ChatPlatform } from '../../../../src/types/base'
import type { import type {
FormatFeature, FormatFeature,
FormatModule, FormatModule,

View File

@@ -13,7 +13,7 @@ import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick' import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues' import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain' import { chain } from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType } from '../../../../src/types/chat' import { KNOWN_PLATFORMS, ChatType } from '../../../../src/types/base'
import type { import type {
FormatFeature, FormatFeature,
FormatModule, FormatModule,

View File

@@ -17,7 +17,7 @@
import * as fs from 'fs' import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
import * as readline from 'readline' import * as readline from 'readline'
import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/chat' import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/base'
import type { import type {
FormatFeature, FormatFeature,
FormatModule, FormatModule,

View File

@@ -23,7 +23,7 @@ import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick' import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues' import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain' import { chain } from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/chat' import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/base'
import type { import type {
FormatFeature, FormatFeature,
FormatModule, FormatModule,

View File

@@ -18,7 +18,7 @@ import * as path from 'path'
import { parser } from 'stream-json' import { parser } from 'stream-json'
import { streamArray } from 'stream-json/streamers/StreamArray' import { streamArray } from 'stream-json/streamers/StreamArray'
import { chain } from 'stream-chain' import { chain } from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/chat' import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/base'
import type { import type {
FormatFeature, FormatFeature,
FormatModule, FormatModule,

View File

@@ -19,7 +19,7 @@ import { parser } from 'stream-json'
import { pick } from 'stream-json/filters/Pick' import { pick } from 'stream-json/filters/Pick'
import { streamValues } from 'stream-json/streamers/StreamValues' import { streamValues } from 'stream-json/streamers/StreamValues'
import { chain } from 'stream-chain' import { chain } from 'stream-chain'
import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/chat' import { KNOWN_PLATFORMS, ChatType, MessageType } from '../../../../src/types/base'
import type { import type {
FormatFeature, FormatFeature,
FormatModule, FormatModule,

View File

@@ -3,7 +3,7 @@
* 三层架构:标准层、嗅探层、解析层 * 三层架构:标准层、嗅探层、解析层
*/ */
import type { ChatPlatform, ChatType, ParsedMember, ParsedMessage } from '../../../src/types/chat' import type { ChatPlatform, ChatType, ParsedMember, ParsedMessage } from '../../../src/types/base'
// ==================== 标准层:统一输出结构 ==================== // ==================== 标准层:统一输出结构 ====================

View File

@@ -1,14 +1,12 @@
import { ElectronAPI } from '@electron-toolkit/preload' import { ElectronAPI } from '@electron-toolkit/preload'
import type { AnalysisSession, MessageType, ImportProgress } from '../../src/types/base'
import type { import type {
AnalysisSession,
MemberActivity, MemberActivity,
MemberNameHistory, MemberNameHistory,
HourlyActivity, HourlyActivity,
DailyActivity, DailyActivity,
WeekdayActivity, WeekdayActivity,
MonthlyActivity, MonthlyActivity,
MessageType,
ImportProgress,
RepeatAnalysis, RepeatAnalysis,
CatchphraseAnalysis, CatchphraseAnalysis,
NightOwlAnalysis, NightOwlAnalysis,
@@ -19,14 +17,15 @@ import type {
LaughAnalysis, LaughAnalysis,
MemeBattleAnalysis, MemeBattleAnalysis,
CheckInAnalysis, CheckInAnalysis,
MemberWithStats,
} from '../../src/types/analysis'
import type {
FileParseInfo, FileParseInfo,
ConflictCheckResult, ConflictCheckResult,
MergeParams, MergeParams,
MergeResult, MergeResult,
MemberWithStats, } from '../../src/types/format'
TableSchema, import type { TableSchema, SQLResult } from '../../src/components/analysis/SQLLab/types'
SQLResult,
} from '../../src/types/chat'
interface TimeFilter { interface TimeFilter {
startTs?: number startTs?: number

View File

@@ -1,15 +1,13 @@
import { contextBridge, ipcRenderer } from 'electron' import { contextBridge, ipcRenderer } from 'electron'
import { electronAPI } from '@electron-toolkit/preload' import { electronAPI } from '@electron-toolkit/preload'
import type { AnalysisSession, MessageType, ImportProgress } from '../../src/types/base'
import type { import type {
AnalysisSession,
MemberActivity, MemberActivity,
MemberNameHistory, MemberNameHistory,
HourlyActivity, HourlyActivity,
DailyActivity, DailyActivity,
WeekdayActivity, WeekdayActivity,
MonthlyActivity, MonthlyActivity,
MessageType,
ImportProgress,
RepeatAnalysis, RepeatAnalysis,
CatchphraseAnalysis, CatchphraseAnalysis,
NightOwlAnalysis, NightOwlAnalysis,
@@ -20,12 +18,14 @@ import type {
LaughAnalysis, LaughAnalysis,
CheckInAnalysis, CheckInAnalysis,
MemeBattleAnalysis, MemeBattleAnalysis,
MemberWithStats,
} from '../../src/types/analysis'
import type {
FileParseInfo, FileParseInfo,
ConflictCheckResult, ConflictCheckResult,
MergeParams, MergeParams,
MergeResult, MergeResult,
MemberWithStats, } from '../../src/types/format'
} from '../../src/types/chat'
// Custom APIs for renderer // Custom APIs for renderer
const api = { const api = {

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
import type { HourlyActivity, WeekdayActivity, MonthlyActivity } from '@/types/chat' import type { HourlyActivity, WeekdayActivity, MonthlyActivity } from '@/types/analysis'
import { BarChart } from '@/components/charts' import { BarChart } from '@/components/charts'
import type { BarChartData } from '@/components/charts' import type { BarChartData } from '@/components/charts'
import { SectionCard } from '@/components/UI' import { SectionCard } from '@/components/UI'

View File

@@ -2,7 +2,7 @@
import { SectionCard } from '@/components/UI' import { SectionCard } from '@/components/UI'
import { LineChart } from '@/components/charts' import { LineChart } from '@/components/charts'
import type { LineChartData } from '@/components/charts' import type { LineChartData } from '@/components/charts'
import type { DailyActivity } from '@/types/chat' import type { DailyActivity } from '@/types/analysis'
defineProps<{ defineProps<{
dailyActivity: DailyActivity[] dailyActivity: DailyActivity[]

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AnalysisSession } from '@/types/chat' import type { AnalysisSession } from '@/types/base'
defineProps<{ defineProps<{
session: AnalysisSession session: AnalysisSession

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { StatCard } from '@/components/UI' import { StatCard } from '@/components/UI'
import type { WeekdayActivity, DailyActivity, HourlyActivity } from '@/types/chat' import type { WeekdayActivity, DailyActivity, HourlyActivity } from '@/types/analysis'
import dayjs from 'dayjs' import dayjs from 'dayjs'
defineProps<{ defineProps<{

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import type { CatchphraseAnalysis } from '@/types/chat' import type { CatchphraseAnalysis } from '@/types/analysis'
import { ListPro } from '@/components/charts' import { ListPro } from '@/components/charts'
import { SectionCard, EmptyState, LoadingState } from '@/components/UI' import { SectionCard, EmptyState, LoadingState } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import type { RepeatAnalysis } from '@/types/chat' import type { RepeatAnalysis } from '@/types/analysis'
import { ListPro } from '@/components/charts' import { ListPro } from '@/components/charts'
import { LoadingState, EmptyState, SectionCard } from '@/components/UI' import { LoadingState, EmptyState, SectionCard } from '@/components/UI'
import { formatDate, getRankBadgeClass } from '@/utils' import { formatDate, getRankBadgeClass } from '@/utils'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { LaughAnalysis, KeywordTemplate as BaseKeywordTemplate } from '@/types/chat' import type { LaughAnalysis, KeywordTemplate as BaseKeywordTemplate } from '@/types/analysis'
import { ListPro } from '@/components/charts' import { ListPro } from '@/components/charts'
import type { RankItem } from '@/components/charts' import type { RankItem } from '@/components/charts'
import { LoadingState } from '@/components/UI' import { LoadingState } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
import type { MemberNameHistory } from '@/types/chat' import type { MemberNameHistory } from '@/types/analysis'
const props = defineProps<{ const props = defineProps<{
history: MemberNameHistory[] history: MemberNameHistory[]

View File

@@ -2,7 +2,7 @@
* 聊天记录查看器类型定义 * 聊天记录查看器类型定义
*/ */
import type { ChatRecordQuery, ChatRecordMessage } from '@/types/chat' import type { ChatRecordQuery, ChatRecordMessage } from '@/types/format'
// 重新导出类型 // 重新导出类型
export type { ChatRecordQuery, ChatRecordMessage } export type { ChatRecordQuery, ChatRecordMessage }

View File

@@ -2,7 +2,7 @@
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { ref, onMounted, nextTick } from 'vue' import { ref, onMounted, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import type { AnalysisSession } from '@/types/chat' import type { AnalysisSession } from '@/types/base'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn' import 'dayjs/locale/zh-cn'

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import type { PromptPreset } from '@/types/chat' import type { PromptPreset } from '@/types/ai'
import AIPromptEditModal from './AIPromptEditModal.vue' import AIPromptEditModal from './AIPromptEditModal.vue'
import { usePromptStore } from '@/stores/prompt' import { usePromptStore } from '@/stores/prompt'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue' import { ref, computed, watch } from 'vue'
import type { PromptPreset } from '@/types/chat' import type { PromptPreset } from '@/types/ai'
import { import {
getDefaultRoleDefinition, getDefaultRoleDefinition,
getDefaultResponseRules, getDefaultResponseRules,

View File

@@ -1,5 +1,5 @@
import { computed } from 'vue' import { computed } from 'vue'
import type { DailyActivity } from '@/types/chat' import type { DailyActivity } from '@/types/analysis'
import type { LineChartData } from '@/components/charts' import type { LineChartData } from '@/components/charts'
import dayjs from 'dayjs' import dayjs from 'dayjs'

View File

@@ -1,5 +1,6 @@
import { computed, type Ref } from 'vue' import { computed, type Ref } from 'vue'
import type { AnalysisSession, HourlyActivity, DailyActivity, MessageType, WeekdayActivity } from '@/types/chat' import type { AnalysisSession, MessageType } from '@/types/base'
import type { HourlyActivity, DailyActivity, WeekdayActivity } from '@/types/analysis'
import dayjs from 'dayjs' import dayjs from 'dayjs'
interface UseOverviewStatisticsProps { interface UseOverviewStatisticsProps {

View File

@@ -9,7 +9,7 @@
* 主进程 (agent.ts) 的锁定部分逻辑需要独立维护,因为包含动态日期 * 主进程 (agent.ts) 的锁定部分逻辑需要独立维护,因为包含动态日期
*/ */
import type { PromptPreset } from '@/types/chat' import type { PromptPreset } from '@/types/ai'
// ==================== 预设 ID 常量 ==================== // ==================== 预设 ID 常量 ====================

View File

@@ -1,15 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { AnalysisSession, MessageType } from '@/types/base'
import { getMessageTypeName } from '@/types/base'
import type { import type {
AnalysisSession,
MemberActivity, MemberActivity,
HourlyActivity, HourlyActivity,
DailyActivity, DailyActivity,
MessageType,
WeekdayActivity, WeekdayActivity,
MonthlyActivity, MonthlyActivity,
} from '@/types/chat' } from '@/types/analysis'
import { getMessageTypeName } from '@/types/chat'
import { DoughnutChart } from '@/components/charts' import { DoughnutChart } from '@/components/charts'
import type { DoughnutChartData } from '@/components/charts' import type { DoughnutChartData } from '@/components/charts'
import { SectionCard } from '@/components/UI' import { SectionCard } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
import type { MemberActivity } from '@/types/chat' import type { MemberActivity } from '@/types/analysis'
import { RankListPro } from '@/components/charts' import { RankListPro } from '@/components/charts'
import type { RankItem } from '@/components/charts' import type { RankItem } from '@/components/charts'
import { PageAnchorsNav } from '@/components/UI' import { PageAnchorsNav } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue' import { ref, computed, watch, onMounted } from 'vue'
import type { MemberWithStats } from '@/types/chat' import type { MemberWithStats } from '@/types/analysis'
// Props // Props
const props = defineProps<{ const props = defineProps<{

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, onMounted } from 'vue' import { ref, watch, onMounted } from 'vue'
import type { MemberWithStats, MemberNameHistory } from '@/types/chat' import type { MemberWithStats, MemberNameHistory } from '@/types/analysis'
import { SectionCard, EmptyState, LoadingState } from '@/components/UI' import { SectionCard, EmptyState, LoadingState } from '@/components/UI'
import { formatPeriod } from '@/utils' import { formatPeriod } from '@/utils'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { MentionAnalysis, MemberMentionDetail } from '@/types/chat' import type { MentionAnalysis, MemberMentionDetail } from '@/types/analysis'
import { RankListPro } from '@/components/charts' import { RankListPro } from '@/components/charts'
import type { RankItem } from '@/components/charts' import type { RankItem } from '@/components/charts'
import { SectionCard, EmptyState, LoadingState } from '@/components/UI' import { SectionCard, EmptyState, LoadingState } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import type { CheckInAnalysis } from '@/types/chat' import type { CheckInAnalysis } from '@/types/analysis'
import { RankListPro, ListPro } from '@/components/charts' import { RankListPro, ListPro } from '@/components/charts'
import type { RankItem } from '@/components/charts' import type { RankItem } from '@/components/charts'
import { SectionCard, LoadingState, EmptyState } from '@/components/UI' import { SectionCard, LoadingState, EmptyState } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import type { DivingAnalysis } from '@/types/chat' import type { DivingAnalysis } from '@/types/analysis'
import { ListPro } from '@/components/charts' import { ListPro } from '@/components/charts'
import { LoadingState } from '@/components/UI' import { LoadingState } from '@/components/UI'
import { formatFullDateTime, formatDaysSince, getRankBadgeClass } from '@/utils' import { formatFullDateTime, formatDaysSince, getRankBadgeClass } from '@/utils'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { DragonKingAnalysis } from '@/types/chat' import type { DragonKingAnalysis } from '@/types/analysis'
import { RankListPro } from '@/components/charts' import { RankListPro } from '@/components/charts'
import type { RankItem } from '@/components/charts' import type { RankItem } from '@/components/charts'
import { LoadingState } from '@/components/UI' import { LoadingState } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { MemeBattleAnalysis } from '@/types/chat' import type { MemeBattleAnalysis } from '@/types/analysis'
import { RankListPro, ListPro } from '@/components/charts' import { RankListPro, ListPro } from '@/components/charts'
import type { RankItem } from '@/components/charts' import type { RankItem } from '@/components/charts'
import { LoadingState, Tabs } from '@/components/UI' import { LoadingState, Tabs } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { MonologueAnalysis } from '@/types/chat' import type { MonologueAnalysis } from '@/types/analysis'
import { SectionCard, EmptyState, LoadingState } from '@/components/UI' import { SectionCard, EmptyState, LoadingState } from '@/components/UI'
import { formatDateTime, getRankBadgeClass } from '@/utils' import { formatDateTime, getRankBadgeClass } from '@/utils'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { NightOwlAnalysis } from '@/types/chat' import type { NightOwlAnalysis } from '@/types/analysis'
import { RankListPro } from '@/components/charts' import { RankListPro } from '@/components/charts'
import { SectionCard } from '@/components/UI' import { SectionCard } from '@/components/UI'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { RepeatAnalysis } from '@/types/chat' import type { RepeatAnalysis } from '@/types/analysis'
import { RankListPro, BarChart, ListPro } from '@/components/charts' import { RankListPro, BarChart, ListPro } from '@/components/charts'
import type { RankItem, BarChartData } from '@/components/charts' import type { RankItem, BarChartData } from '@/components/charts'
import { SectionCard, EmptyState, LoadingState } from '@/components/UI' import { SectionCard, EmptyState, LoadingState } from '@/components/UI'

View File

@@ -2,7 +2,8 @@
import { ref, onMounted, watch, computed } from 'vue' import { ref, onMounted, watch, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import type { AnalysisSession, MemberActivity, HourlyActivity, DailyActivity, MessageType } from '@/types/chat' import type { AnalysisSession, MessageType } from '@/types/base'
import type { MemberActivity, HourlyActivity, DailyActivity } from '@/types/analysis'
import { formatDateRange } from '@/utils' import { formatDateRange } from '@/utils'
import CaptureButton from '@/components/common/CaptureButton.vue' import CaptureButton from '@/components/common/CaptureButton.vue'
import UITabs from '@/components/UI/Tabs.vue' import UITabs from '@/components/UI/Tabs.vue'

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue' import { ref, computed, watch, onMounted } from 'vue'
import type { MemberWithStats } from '@/types/chat' import type { MemberWithStats } from '@/types/analysis'
// Props // Props
const props = defineProps<{ const props = defineProps<{

View File

@@ -1,15 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import type { AnalysisSession, MessageType } from '@/types/base'
import { getMessageTypeName } from '@/types/base'
import type { import type {
AnalysisSession,
MemberActivity, MemberActivity,
HourlyActivity, HourlyActivity,
DailyActivity, DailyActivity,
MessageType,
WeekdayActivity, WeekdayActivity,
MonthlyActivity, MonthlyActivity,
} from '@/types/chat' } from '@/types/analysis'
import { getMessageTypeName } from '@/types/chat'
import { DoughnutChart } from '@/components/charts' import { DoughnutChart } from '@/components/charts'
import type { DoughnutChartData } from '@/components/charts' import type { DoughnutChartData } from '@/components/charts'
import { SectionCard } from '@/components/UI' import { SectionCard } from '@/components/UI'

View File

@@ -2,7 +2,8 @@
import { ref, onMounted, watch, computed } from 'vue' import { ref, onMounted, watch, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import type { AnalysisSession, MemberActivity, HourlyActivity, DailyActivity, MessageType } from '@/types/chat' import type { AnalysisSession, MessageType } from '@/types/base'
import type { MemberActivity, HourlyActivity, DailyActivity } from '@/types/analysis'
import { formatDateRange } from '@/utils' import { formatDateRange } from '@/utils'
import CaptureButton from '@/components/common/CaptureButton.vue' import CaptureButton from '@/components/common/CaptureButton.vue'
import UITabs from '@/components/UI/Tabs.vue' import UITabs from '@/components/UI/Tabs.vue'

View File

@@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue' import { ref } from 'vue'
import type { ChatRecordQuery } from '@/types/chat' import type { ChatRecordQuery } from '@/types/format'
/** /**
* 全局界面状态(侧边栏、弹窗、聊天记录抽屉等) * 全局界面状态(侧边栏、弹窗、聊天记录抽屉等)

View File

@@ -1,6 +1,7 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import type { PromptPreset, KeywordTemplate, AIPromptSettings } from '@/types/chat' import type { PromptPreset, AIPromptSettings } from '@/types/ai'
import type { KeywordTemplate } from '@/types/analysis'
import { import {
BUILTIN_PRESETS, BUILTIN_PRESETS,
DEFAULT_GROUP_PRESET_ID, DEFAULT_GROUP_PRESET_ID,

View File

@@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import type { AnalysisSession, ImportProgress } from '@/types/chat' import type { AnalysisSession, ImportProgress } from '@/types/base'
/** /**
* 会话与导入相关的全局状态 * 会话与导入相关的全局状态

34
src/types/ai.ts Normal file
View File

@@ -0,0 +1,34 @@
/**
* ChatLab AI 相关类型定义
* 包含提示词预设、AI 配置
*/
// ==================== AI 提示词预设 ====================
/**
* 提示词预设适用的聊天类型
*/
export type PromptPresetChatType = 'group' | 'private'
/**
* AI 提示词预设
*/
export interface PromptPreset {
id: string
name: string // 预设名称
chatType: PromptPresetChatType // 适用类型
roleDefinition: string // 角色定义(可编辑)
responseRules: string // 回答要求(可编辑)
isBuiltIn: boolean // 是否内置(内置不可删除)
createdAt: number
updatedAt: number
}
/**
* AI 提示词配置(激活的预设)
*/
export interface AIPromptSettings {
activeGroupPresetId: string // 群聊激活的预设ID
activePrivatePresetId: string // 私聊激活的预设ID
}

View File

@@ -1,190 +1,9 @@
/** /**
* ChatLab * ChatLab
* *
*/ */
// ==================== 枚举定义 ==================== // ==================== 基础分析类型 ====================
/**
*
*
*
* - (0-19):
* - (20-39):
* - (80-89):
* - (99):
*/
export enum MessageType {
// ========== 基础消息类型 (0-19) ==========
TEXT = 0, // 文本消息
IMAGE = 1, // 图片
VOICE = 2, // 语音
VIDEO = 3, // 视频
FILE = 4, // 文件
EMOJI = 5, // 表情包/贴纸
LINK = 7, // 链接/卡片(分享的网页、文章等)
LOCATION = 8, // 位置/地理位置
// ========== 交互消息类型 (20-39) ==========
RED_PACKET = 20, // 红包
TRANSFER = 21, // 转账
POKE = 22, // 拍一拍/戳一戳
CALL = 23, // 语音/视频通话
SHARE = 24, // 分享(音乐、小程序等)
REPLY = 25, // 引用回复
FORWARD = 26, // 转发消息
CONTACT = 27, // 名片消息
// ========== 系统消息类型 (80-89) ==========
SYSTEM = 80, // 系统消息(入群/退群/群公告等)
RECALL = 81, // 撤回消息
// ========== 其他 (99) ==========
OTHER = 99, // 其他/未知
}
/**
*
*/
export 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]: '其他',
}
/**
*
* @param type
*/
export function getMessageTypeName(type: MessageType | number): string {
return MESSAGE_TYPE_NAMES[type] || '未知'
}
/**
*
* qq, weixin, discord, whatsapp
* 使 'mixed'
*/
export type ChatPlatform = string
/**
*
*/
export const KNOWN_PLATFORMS = {
QQ: 'qq',
WECHAT: 'weixin',
DISCORD: 'discord',
WHATSAPP: 'whatsapp',
UNKNOWN: 'unknown',
} as const
/**
*
*/
export enum ChatType {
GROUP = 'group', // 群聊
PRIVATE = 'private', // 私聊
}
// ==================== 数据库模型 ====================
/**
*
*/
export interface DbMeta {
name: string // 群名/对话名
platform: ChatPlatform // 平台
type: ChatType // 聊天类型
imported_at: number // 导入时间戳(秒)
group_id: string | null // 群ID群聊类型有值私聊为空
group_avatar: string | null // 群头像base64 Data URL
}
/**
*
*/
export interface DbMember {
id: number // 自增ID
platform_id: string // 平台标识QQ号等
account_name: string | null // 账号名称QQ原始昵称 sendNickName
group_nickname: string | null // 群昵称sendMemberName可为空
aliases: string // 用户自定义别名JSON数组格式
avatar: string | null // 头像base64 Data URL
}
/**
*
*/
export interface DbMessage {
id: number // 自增ID
sender_id: number // FK -> member.id
sender_account_name: string | null // 发送时的账号名称
sender_group_nickname: string | null // 发送时的群昵称
ts: number // 时间戳(秒)
type: MessageType // 消息类型
content: string | null // 纯文本内容
}
// ==================== Parser 解析结果 ====================
/**
*
*/
export interface ParsedMember {
platformId: string // 平台标识
accountName: string // 账号名称QQ原始昵称 sendNickName
groupNickname?: string // 群昵称sendMemberName可为空
avatar?: string // 头像base64 Data URL可为空
}
/**
*
*/
export interface ParsedMessage {
senderPlatformId: string // 发送者平台ID
senderAccountName: string // 发送时的账号名称
senderGroupNickname?: string // 发送时的群昵称(可为空)
timestamp: number // 时间戳(秒)
type: MessageType // 消息类型
content: string | null // 内容
}
/**
* Parser
*/
export interface ParseResult {
meta: {
name: string
platform: ChatPlatform
type: ChatType
groupId?: string // 群ID群聊类型有值
groupAvatar?: string // 群头像base64 Data URL
}
members: ParsedMember[]
messages: ParsedMessage[]
}
// ==================== 分析结果类型 ====================
/** /**
* *
@@ -243,6 +62,16 @@ export interface MonthlyActivity {
messageCount: number messageCount: number
} }
/**
*
*/
export interface MemberNameHistory {
nameType: 'account_name' | 'group_nickname' // 名称类型
name: string // 昵称
startTs: number // 开始使用时间戳(秒)
endTs: number | null // 停止使用时间戳null 表示当前昵称
}
// ==================== 夜猫分析类型 ==================== // ==================== 夜猫分析类型 ====================
/** /**
@@ -307,6 +136,24 @@ export interface NightOwlChampion {
consecutiveDays: number // 最长连续天数 consecutiveDays: number // 最长连续天数
} }
/**
*
*/
export interface NightOwlAnalysis {
/** 修仙排行榜 */
nightOwlRank: NightOwlRankItem[]
/** 最晚下班排名 */
lastSpeakerRank: TimeRankItem[]
/** 最早上班排名 */
firstSpeakerRank: TimeRankItem[]
/** 连续修仙记录 */
consecutiveRecords: ConsecutiveNightRecord[]
/** 修仙王者(综合排名) */
champions: NightOwlChampion[]
/** 统计的总天数 */
totalDays: number
}
// ==================== 自言自语分析类型 ==================== // ==================== 自言自语分析类型 ====================
/** /**
@@ -379,74 +226,6 @@ export interface DivingAnalysis {
rank: DivingRankItem[] rank: DivingRankItem[]
} }
/**
*
*/
export interface NightOwlAnalysis {
/** 修仙排行榜 */
nightOwlRank: NightOwlRankItem[]
/** 最晚下班排名 */
lastSpeakerRank: TimeRankItem[]
/** 最早上班排名 */
firstSpeakerRank: TimeRankItem[]
/** 连续修仙记录 */
consecutiveRecords: ConsecutiveNightRecord[]
/** 修仙王者(综合排名) */
champions: NightOwlChampion[]
/** 统计的总天数 */
totalDays: number
}
/**
*
*/
export interface AnalysisSession {
id: string // 数据库文件名(不含扩展名)
name: string // 群名/对话名
platform: ChatPlatform
type: ChatType
importedAt: number // 导入时间戳
messageCount: number // 消息总数
memberCount: number // 成员数
dbPath: string // 数据库文件完整路径
groupId: string | null // 群ID群聊类型有值私聊为空
groupAvatar: string | null // 群头像base64 Data URL
}
/**
*
*/
export interface MemberNameHistory {
nameType: 'account_name' | 'group_nickname' // 名称类型
name: string // 昵称
startTs: number // 开始使用时间戳(秒)
endTs: number | null // 停止使用时间戳null 表示当前昵称
}
// ==================== IPC 通信类型 ====================
/**
*
*/
export interface ImportProgress {
stage: 'detecting' | 'reading' | 'parsing' | 'saving' | 'done' | 'error'
progress: number // 0-100
message?: string
// 流式解析额外字段
bytesRead?: number
totalBytes?: number
messagesProcessed?: number
}
/**
*
*/
export interface ImportResult {
success: boolean
sessionId?: string // 成功时返回会话ID
error?: string // 失败时返回错误信息
}
// ==================== 复读分析类型 ==================== // ==================== 复读分析类型 ====================
/** /**
@@ -682,46 +461,6 @@ export interface LaughAnalysis {
groupLaughRate: number groupLaughRate: number
} }
// ==================== 关键词模板 ====================
/**
*
*/
export interface KeywordTemplate {
id: string
name: string
keywords: string[]
}
// ==================== AI 提示词预设 ====================
/**
*
*/
export type PromptPresetChatType = 'group' | 'private'
/**
* AI
*/
export interface PromptPreset {
id: string
name: string // 预设名称
chatType: PromptPresetChatType // 适用类型
roleDefinition: string // 角色定义(可编辑)
responseRules: string // 回答要求(可编辑)
isBuiltIn: boolean // 是否内置(内置不可删除)
createdAt: number
updatedAt: number
}
/**
* AI
*/
export interface AIPromptSettings {
activeGroupPresetId: string // 群聊激活的预设ID
activePrivatePresetId: string // 私聊激活的预设ID
}
// ==================== 斗图分析类型 ==================== // ==================== 斗图分析类型 ====================
/** /**
@@ -793,179 +532,14 @@ export interface CheckInAnalysis {
totalDays: number // 群聊总天数 totalDays: number // 群聊总天数
} }
// ==================== ChatLab 专属格式类型 ==================== // ==================== 关键词模板 ====================
/** /**
* ChatLab *
*/ */
export interface ChatLabHeader { export interface KeywordTemplate {
version: string // 格式版本,如 "0.0.1"
exportedAt: number // 导出时间戳(秒)
generator?: string // 生成工具名称(可选)
description?: string // 描述信息(可选,自定义内容)
}
/**
*
*/
export interface MergeSource {
filename: string // 原文件名
platform?: string // 原平台
messageCount: number // 消息数量
}
/**
* ChatLab
*/
export interface ChatLabMeta {
name: string // 群名/对话名
platform: ChatPlatform // 平台(合并时为 mixed
type: ChatType // 聊天类型
sources?: MergeSource[] // 合并来源(可选)
groupId?: string // 群ID可选仅群聊
groupAvatar?: string // 群头像base64 Data URL可选
}
/**
* ChatLab
*/
export interface ChatLabMember {
platformId: string // 平台标识
accountName: string // 账号名称
groupNickname?: string // 群昵称(可选)
aliases?: string[] // 用户自定义别名(可选)
avatar?: string // 头像base64 Data URL可选
}
/**
* ChatLab
*/
export interface ChatLabMessage {
sender: string // 发送者 platformId
accountName: string // 发送时的账号名称
groupNickname?: string // 发送时的群昵称(可选)
timestamp: number // 时间戳(秒)
type: MessageType // 消息类型
content: string | null // 内容
}
/**
* ChatLab
*/
export interface ChatLabFormat {
chatlab: ChatLabHeader
meta: ChatLabMeta
members: ChatLabMember[]
messages: ChatLabMessage[]
}
// ==================== 合并相关类型 ====================
/**
*
*/
export interface FileParseInfo {
name: string // 群名
format: string // 格式名称
platform: string // 平台
messageCount: number // 消息数量
memberCount: number // 成员数量
fileSize?: number // 文件大小(字节)
}
/**
*
*/
export interface MergeConflict {
id: string // 冲突ID
timestamp: number // 时间戳
sender: string // 发送者
contentLength1: number // 内容1长度
contentLength2: number // 内容2长度
content1: string // 内容1
content2: string // 内容2
}
/**
*
*/
export interface ConflictCheckResult {
conflicts: MergeConflict[]
totalMessages: number // 合并后预计消息数
}
/**
*
*/
export interface ConflictResolution {
id: string id: string
resolution: 'keep1' | 'keep2' | 'keepBoth' name: string
keywords: string[]
} }
/**
*
*/
export type OutputFormat = 'json' | 'jsonl'
/**
*
*/
export interface MergeParams {
filePaths: string[]
outputName: string
outputDir?: string
outputFormat?: OutputFormat // 输出格式,默认 'json'
conflictResolutions: ConflictResolution[]
andAnalyze: boolean
}
/**
*
*/
export interface MergeResult {
success: boolean
outputPath?: string
sessionId?: string // 如果选择了分析返回会话ID
error?: string
}
// ==================== 聊天记录查看器类型 ====================
/**
*
*
*/
export interface ChatRecordQuery {
/** 定位到指定消息(初始加载时以此消息为中心) */
scrollToMessageId?: number
/** 成员筛选:只显示该成员的消息 */
memberId?: number
/** 成员名称(用于显示) */
memberName?: string
/** 时间范围筛选:开始时间戳(秒) */
startTs?: number
/** 时间范围筛选:结束时间戳(秒) */
endTs?: number
/** 关键词搜索OR 逻辑) */
keywords?: string[]
/** 高亮关键词(用于 UI 高亮显示) */
highlightKeywords?: string[]
}
/**
*
*/
export interface ChatRecordMessage {
id: number
senderName: string
senderPlatformId: string
senderAliases: string[]
senderAvatar: string | null // 发送者头像
content: string
timestamp: number
type: number
}

226
src/types/base.ts Normal file
View File

@@ -0,0 +1,226 @@
/**
* ChatLab 基础类型定义
* 包含枚举、数据库模型、Parser 解析结果
*/
// ==================== 枚举定义 ====================
/**
* 消息类型枚举
*
* 分类说明:
* - 基础消息 (0-19): 常见的内容类型
* - 交互消息 (20-39): 涉及互动的消息类型
* - 系统消息 (80-89): 系统相关消息
* - 其他 (99): 未知或无法分类的消息
*/
export enum MessageType {
// ========== 基础消息类型 (0-19) ==========
TEXT = 0, // 文本消息
IMAGE = 1, // 图片
VOICE = 2, // 语音
VIDEO = 3, // 视频
FILE = 4, // 文件
EMOJI = 5, // 表情包/贴纸
LINK = 7, // 链接/卡片(分享的网页、文章等)
LOCATION = 8, // 位置/地理位置
// ========== 交互消息类型 (20-39) ==========
RED_PACKET = 20, // 红包
TRANSFER = 21, // 转账
POKE = 22, // 拍一拍/戳一戳
CALL = 23, // 语音/视频通话
SHARE = 24, // 分享(音乐、小程序等)
REPLY = 25, // 引用回复
FORWARD = 26, // 转发消息
CONTACT = 27, // 名片消息
// ========== 系统消息类型 (80-89) ==========
SYSTEM = 80, // 系统消息(入群/退群/群公告等)
RECALL = 81, // 撤回消息
// ========== 其他 (99) ==========
OTHER = 99, // 其他/未知
}
/**
* 消息类型名称映射
*/
export 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]: '其他',
}
/**
* 获取消息类型名称
* @param type 消息类型
*/
export function getMessageTypeName(type: MessageType | number): string {
return MESSAGE_TYPE_NAMES[type] || '未知'
}
/**
* 聊天平台类型(字符串,允许任意值)
* 常见平台示例qq, weixin, discord, whatsapp 等
* 合并多平台记录时使用 'mixed'
*/
export type ChatPlatform = string
/**
* 预定义的常用平台值
*/
export const KNOWN_PLATFORMS = {
QQ: 'qq',
WECHAT: 'weixin',
DISCORD: 'discord',
WHATSAPP: 'whatsapp',
UNKNOWN: 'unknown',
} as const
/**
* 聊天类型枚举
*/
export enum ChatType {
GROUP = 'group', // 群聊
PRIVATE = 'private', // 私聊
}
// ==================== 数据库模型 ====================
/**
* 元信息(数据库中存储的格式)
*/
export interface DbMeta {
name: string // 群名/对话名
platform: ChatPlatform // 平台
type: ChatType // 聊天类型
imported_at: number // 导入时间戳(秒)
group_id: string | null // 群ID群聊类型有值私聊为空
group_avatar: string | null // 群头像base64 Data URL
}
/**
* 成员(数据库中存储的格式)
*/
export interface DbMember {
id: number // 自增ID
platform_id: string // 平台标识QQ号等
account_name: string | null // 账号名称QQ原始昵称 sendNickName
group_nickname: string | null // 群昵称sendMemberName可为空
aliases: string // 用户自定义别名JSON数组格式
avatar: string | null // 头像base64 Data URL
}
/**
* 消息(数据库中存储的格式)
*/
export interface DbMessage {
id: number // 自增ID
sender_id: number // FK -> member.id
sender_account_name: string | null // 发送时的账号名称
sender_group_nickname: string | null // 发送时的群昵称
ts: number // 时间戳(秒)
type: MessageType // 消息类型
content: string | null // 纯文本内容
}
// ==================== Parser 解析结果 ====================
/**
* 解析后的成员信息
*/
export interface ParsedMember {
platformId: string // 平台标识
accountName: string // 账号名称QQ原始昵称 sendNickName
groupNickname?: string // 群昵称sendMemberName可为空
avatar?: string // 头像base64 Data URL可为空
}
/**
* 解析后的消息
*/
export interface ParsedMessage {
senderPlatformId: string // 发送者平台ID
senderAccountName: string // 发送时的账号名称
senderGroupNickname?: string // 发送时的群昵称(可为空)
timestamp: number // 时间戳(秒)
type: MessageType // 消息类型
content: string | null // 内容
}
/**
* Parser 解析结果
*/
export interface ParseResult {
meta: {
name: string
platform: ChatPlatform
type: ChatType
groupId?: string // 群ID群聊类型有值
groupAvatar?: string // 群头像base64 Data URL
}
members: ParsedMember[]
messages: ParsedMessage[]
}
// ==================== 会话与 IPC 类型 ====================
/**
* 分析会话信息(用于会话列表展示)
*/
export interface AnalysisSession {
id: string // 数据库文件名(不含扩展名)
name: string // 群名/对话名
platform: ChatPlatform
type: ChatType
importedAt: number // 导入时间戳
messageCount: number // 消息总数
memberCount: number // 成员数
dbPath: string // 数据库文件完整路径
groupId: string | null // 群ID群聊类型有值私聊为空
groupAvatar: string | null // 群头像base64 Data URL
}
/**
* 导入进度回调
*/
export interface ImportProgress {
stage: 'detecting' | 'reading' | 'parsing' | 'saving' | 'done' | 'error'
progress: number // 0-100
message?: string
// 流式解析额外字段
bytesRead?: number
totalBytes?: number
messagesProcessed?: number
}
/**
* 导入结果
*/
export interface ImportResult {
success: boolean
sessionId?: string // 成功时返回会话ID
error?: string // 失败时返回错误信息
}

184
src/types/format.ts Normal file
View File

@@ -0,0 +1,184 @@
/**
* ChatLab 格式类型定义
* 包含ChatLab 专属格式、合并相关、聊天记录查看器
*/
import type { ChatPlatform, ChatType, MessageType } from './base'
// ==================== ChatLab 专属格式类型 ====================
/**
* ChatLab 格式版本信息
*/
export interface ChatLabHeader {
version: string // 格式版本,如 "0.0.1"
exportedAt: number // 导出时间戳(秒)
generator?: string // 生成工具名称(可选)
description?: string // 描述信息(可选,自定义内容)
}
/**
* 合并来源信息
*/
export interface MergeSource {
filename: string // 原文件名
platform?: string // 原平台
messageCount: number // 消息数量
}
/**
* ChatLab 格式的元信息
*/
export interface ChatLabMeta {
name: string // 群名/对话名
platform: ChatPlatform // 平台(合并时为 mixed
type: ChatType // 聊天类型
sources?: MergeSource[] // 合并来源(可选)
groupId?: string // 群ID可选仅群聊
groupAvatar?: string // 群头像base64 Data URL可选
}
/**
* ChatLab 格式的成员
*/
export interface ChatLabMember {
platformId: string // 平台标识
accountName: string // 账号名称
groupNickname?: string // 群昵称(可选)
aliases?: string[] // 用户自定义别名(可选)
avatar?: string // 头像base64 Data URL可选
}
/**
* ChatLab 格式的消息
*/
export interface ChatLabMessage {
sender: string // 发送者 platformId
accountName: string // 发送时的账号名称
groupNickname?: string // 发送时的群昵称(可选)
timestamp: number // 时间戳(秒)
type: MessageType // 消息类型
content: string | null // 内容
}
/**
* ChatLab 专属格式文件结构
*/
export interface ChatLabFormat {
chatlab: ChatLabHeader
meta: ChatLabMeta
members: ChatLabMember[]
messages: ChatLabMessage[]
}
// ==================== 合并相关类型 ====================
/**
* 文件解析信息(用于合并前预览)
*/
export interface FileParseInfo {
name: string // 群名
format: string // 格式名称
platform: string // 平台
messageCount: number // 消息数量
memberCount: number // 成员数量
fileSize?: number // 文件大小(字节)
}
/**
* 合并冲突项
*/
export interface MergeConflict {
id: string // 冲突ID
timestamp: number // 时间戳
sender: string // 发送者
contentLength1: number // 内容1长度
contentLength2: number // 内容2长度
content1: string // 内容1
content2: string // 内容2
}
/**
* 冲突检测结果
*/
export interface ConflictCheckResult {
conflicts: MergeConflict[]
totalMessages: number // 合并后预计消息数
}
/**
* 冲突解决方案
*/
export interface ConflictResolution {
id: string
resolution: 'keep1' | 'keep2' | 'keepBoth'
}
/**
* 输出格式类型
*/
export type OutputFormat = 'json' | 'jsonl'
/**
* 合并参数
*/
export interface MergeParams {
filePaths: string[]
outputName: string
outputDir?: string
outputFormat?: OutputFormat // 输出格式,默认 'json'
conflictResolutions: ConflictResolution[]
andAnalyze: boolean
}
/**
* 合并结果
*/
export interface MergeResult {
success: boolean
outputPath?: string
sessionId?: string // 如果选择了分析返回会话ID
error?: string
}
// ==================== 聊天记录查看器类型 ====================
/**
* 聊天记录查看器查询参数
* 支持组合查询:多个条件可同时生效
*/
export interface ChatRecordQuery {
/** 定位到指定消息(初始加载时以此消息为中心) */
scrollToMessageId?: number
/** 成员筛选:只显示该成员的消息 */
memberId?: number
/** 成员名称(用于显示) */
memberName?: string
/** 时间范围筛选:开始时间戳(秒) */
startTs?: number
/** 时间范围筛选:结束时间戳(秒) */
endTs?: number
/** 关键词搜索OR 逻辑) */
keywords?: string[]
/** 高亮关键词(用于 UI 高亮显示) */
highlightKeywords?: string[]
}
/**
* 聊天记录查看器中的消息项
*/
export interface ChatRecordMessage {
id: number
senderName: string
senderPlatformId: string
senderAliases: string[]
senderAvatar: string | null // 发送者头像
content: string
timestamp: number
type: number
}

View File

@@ -1,5 +0,0 @@
/**
* 类型定义导出
*/
export * from './chat'