视频会议保存

This commit is contained in:
duoaohui
2026-05-18 21:23:00 +08:00
parent fb965cc8c4
commit 5a5706c236
20 changed files with 1211 additions and 1 deletions

View File

@@ -0,0 +1,103 @@
// Package llm 映射外部 LLM 配置中心 MySQL 的三张表
//
// 严格只读:本服务永远不应该 INSERT / UPDATE / DELETE 这些表,
// DAO 中只用 Find / First / Where。所有写操作由配置中心自身负责。
package llm
import "time"
// 模型类型枚举(对应 t_llm_model.model_type
const (
ModelTypeChat = 1 // 文字对话
ModelTypeVision = 2 // 视觉(图文)
ModelTypeMultimodal = 3 // 多模态
ModelTypeASR = 4 // 语音识别(本服务转写功能用此类型)
)
// 通用状态枚举
const (
StatusDisabled = 0 // 停用
StatusEnabled = 1 // 启用
// t_llm_key 额外定义
KeyStatusAutoDisabled = 2 // 连续失败自动停用
)
// API 协议
const (
APIProtocolOpenAICompatible = "openai_compatible"
APIProtocolCustom = "custom"
)
// Provider 大模型提供商表 t_llm_provider只读
//
// 选择 provider 时使用deleted=0 AND status=1 ORDER BY sort ASC
type Provider struct {
ID int64 `gorm:"column:id;primaryKey"`
ProviderName string `gorm:"column:provider_name"`
ProviderCode string `gorm:"column:provider_code"`
BaseURL string `gorm:"column:base_url"`
APIProtocol string `gorm:"column:api_protocol"` // openai_compatible / custom
Status int `gorm:"column:status"`
Sort int `gorm:"column:sort"`
Remark string `gorm:"column:remark"`
CreateTime time.Time `gorm:"column:create_time"`
UpdateTime time.Time `gorm:"column:update_time"`
Deleted int `gorm:"column:deleted"`
}
// TableName 指定 MySQL 表名
func (Provider) TableName() string { return "t_llm_provider" }
// Model 大模型表 t_llm_model只读
//
// 选择 STT 模型时使用deleted=0 AND status=1 AND model_type=4 ORDER BY sort ASC
type Model struct {
ID int64 `gorm:"column:id;primaryKey"`
ProviderID int64 `gorm:"column:provider_id"`
ModelCode string `gorm:"column:model_code"`
ModelName string `gorm:"column:model_name"`
ModelType int `gorm:"column:model_type"`
MaxTokens int `gorm:"column:max_tokens"`
InputPrice float64 `gorm:"column:input_price"`
OutputPrice float64 `gorm:"column:output_price"`
Status int `gorm:"column:status"`
Sort int `gorm:"column:sort"`
Remark string `gorm:"column:remark"`
CreateTime time.Time `gorm:"column:create_time"`
UpdateTime time.Time `gorm:"column:update_time"`
Deleted int `gorm:"column:deleted"`
}
func (Model) TableName() string { return "t_llm_model" }
// Key 大模型 Key 池表 t_llm_key只读
//
// 选择策略DAO.PickKey
// - WHERE deleted=0 AND status=1 AND provider_id=?
// - AND (expire_time IS NULL OR expire_time > NOW())
// - AND (daily_limit = 0 OR today_count < daily_limit)
// - ORDER BY weight DESC, today_count ASC
// - LIMIT 1
//
// 注意:本服务不写回 today_count / total_count / fail_count
// 因为这些字段属于 LLM 网关自身的统计职责,由网关在调用时自增。
// 我们这边仅消费它们做选择权重。
type Key struct {
ID int64 `gorm:"column:id;primaryKey"`
ProviderID int64 `gorm:"column:provider_id"`
APIKey string `gorm:"column:api_key"`
KeyAlias string `gorm:"column:key_alias"`
Weight int `gorm:"column:weight"`
DailyLimit int `gorm:"column:daily_limit"`
TodayCount int `gorm:"column:today_count"`
TotalCount int64 `gorm:"column:total_count"`
FailCount int `gorm:"column:fail_count"`
Status int `gorm:"column:status"` // 0/1/2
LastUsedTime *time.Time `gorm:"column:last_used_time"`
ExpireTime *time.Time `gorm:"column:expire_time"`
CreateTime time.Time `gorm:"column:create_time"`
UpdateTime time.Time `gorm:"column:update_time"`
Deleted int `gorm:"column:deleted"`
}
func (Key) TableName() string { return "t_llm_key" }

View File

@@ -0,0 +1,48 @@
// Package model 提供 transcribe 模块的数据库模型
package model
import "time"
// Transcript 会议录制语音转写结果,对应 meeting_transcripts 表
//
// 一对一关联 meeting_recordings.idunique 索引),同一段录制只保留最新一份转写结果,
// 重新触发转写会就地更新保持状态机pending → running → ready/failed
//
// 字段设计:
// - Text拼接后的全文便于列表/搜索
// - SegmentsJSONB 数组 [{start,end,text}],便于按时间轴渲染字幕
// - Provider/ModelCode本次实际使用的 LLM 配置快照,调试/审计用
// - ErrorMsg失败原因HTTP 错误 / Key 不可用 / 文件下载失败等)
//
// PostgreSQL JSONB 字段在 GORM 里用 string 承载,由 service 层 json.Marshal/Unmarshal。
type Transcript struct {
ID int64 `json:"id" gorm:"primaryKey;autoIncrement"`
RecordingID int64 `json:"recording_id" gorm:"not null;uniqueIndex:uk_transcripts_recording"` // 唯一关联录制
RoomID int64 `json:"room_id" gorm:"not null;index:idx_transcripts_room"` // 冗余 room_id 便于按会议批量查
Status string `json:"status" gorm:"size:16;not null;default:pending"` // pending / running / ready / failed
Text string `json:"text" gorm:"type:text;not null;default:''"`
Segments string `json:"segments" gorm:"type:jsonb;not null;default:'[]'"` // JSON 数组字符串
Language string `json:"language" gorm:"size:16;not null;default:''"`
DurationSec int `json:"duration_sec" gorm:"not null;default:0"`
ProviderCode string `json:"provider_code" gorm:"size:32;not null;default:''"` // 来自 t_llm_provider.provider_code
ModelCode string `json:"model_code" gorm:"size:64;not null;default:''"` // 来自 t_llm_model.model_code
KeyID int64 `json:"key_id" gorm:"not null;default:0"` // 来自 t_llm_key.id便于追踪 key 用量
ErrorMsg string `json:"error_msg" gorm:"size:512;not null;default:''"`
StartedAt *time.Time `json:"started_at" gorm:"type:timestamp(0)"`
FinishedAt *time.Time `json:"finished_at" gorm:"type:timestamp(0)"`
CreatedAt time.Time `json:"created_at" gorm:"not null;autoCreateTime;type:timestamp(0)"`
UpdatedAt time.Time `json:"updated_at" gorm:"not null;autoUpdateTime;type:timestamp(0)"`
}
// TableName 指定数据库表名
func (Transcript) TableName() string {
return "meeting_transcripts"
}
// 状态常量
const (
TranscriptStatusPending = "pending"
TranscriptStatusRunning = "running"
TranscriptStatusReady = "ready"
TranscriptStatusFailed = "failed"
)