Files
EchoChat/backend/go-service/app/transcribe/dao/transcript_dao.go
2026-05-18 21:23:00 +08:00

113 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package dao 提供 transcribe 模块的数据库访问操作
package dao
import (
"context"
"errors"
"time"
"github.com/echochat/backend/app/transcribe/model"
"gorm.io/gorm"
)
// TranscriptDAO 转写记录数据访问对象PostgreSQL 主库)
type TranscriptDAO struct {
db *gorm.DB
}
// NewTranscriptDAO 创建实例
func NewTranscriptDAO(db *gorm.DB) *TranscriptDAO {
return &TranscriptDAO{db: db}
}
// GetByRecordingID 按 recording_id 获取转写记录(不存在返回 nil, nil
//
// 之所以 nil 不视为错误:调用方常见模式是"取不到 → 创建新行",避免 ErrRecordNotFound 包装
func (d *TranscriptDAO) GetByRecordingID(ctx context.Context, recordingID int64) (*model.Transcript, error) {
var t model.Transcript
err := d.db.WithContext(ctx).
Where("recording_id = ?", recordingID).
First(&t).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &t, nil
}
// ListByRoomID 拉取一场会议下所有转写(按 recording_id 升序)
// 用于会议详情页一次性带回多段录制的转写状态
func (d *TranscriptDAO) ListByRoomID(ctx context.Context, roomID int64) ([]model.Transcript, error) {
var list []model.Transcript
err := d.db.WithContext(ctx).
Where("room_id = ?", roomID).
Order("recording_id ASC").
Find(&list).Error
return list, err
}
// Upsert 插入或更新(按 recording_id unique 索引)
// 用于"重新转写"路径:保留同一行 ID状态/文本就地刷新
func (d *TranscriptDAO) Upsert(ctx context.Context, t *model.Transcript) error {
existing, err := d.GetByRecordingID(ctx, t.RecordingID)
if err != nil {
return err
}
if existing == nil {
return d.db.WithContext(ctx).Create(t).Error
}
t.ID = existing.ID
return d.db.WithContext(ctx).Save(t).Error
}
// MarkRunning 把指定 transcript 置为 running 状态,并填 started_at = now
//
// 用于异步任务起跑时的状态翻转,保证后端重启时 running 行不会卡死
// (配合 RescueStuckRunning 兜底)。
func (d *TranscriptDAO) MarkRunning(ctx context.Context, id int64) error {
now := time.Now()
return d.db.WithContext(ctx).
Model(&model.Transcript{}).
Where("id = ?", id).
Updates(map[string]any{
"status": model.TranscriptStatusRunning,
"started_at": now,
"error_msg": "",
}).Error
}
// MarkReady 转写成功
func (d *TranscriptDAO) MarkReady(ctx context.Context, id int64, text, segments, language string, durationSec int) error {
now := time.Now()
return d.db.WithContext(ctx).
Model(&model.Transcript{}).
Where("id = ?", id).
Updates(map[string]any{
"status": model.TranscriptStatusReady,
"text": text,
"segments": segments,
"language": language,
"duration_sec": durationSec,
"finished_at": now,
"error_msg": "",
}).Error
}
// MarkFailed 转写失败
func (d *TranscriptDAO) MarkFailed(ctx context.Context, id int64, errorMsg string) error {
now := time.Now()
if len(errorMsg) > 500 {
errorMsg = errorMsg[:500]
}
return d.db.WithContext(ctx).
Model(&model.Transcript{}).
Where("id = ?", id).
Updates(map[string]any{
"status": model.TranscriptStatusFailed,
"error_msg": errorMsg,
"finished_at": now,
}).Error
}