From dae5722945d100832167fe2d7786bbbd6e9979a1 Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Sun, 14 Jun 2026 17:52:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Phase=208.1=20=E2=80=94=20=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=20MessageRepository=20=E6=8E=A5=E5=8F=A3=E5=92=8C?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E8=A1=A8=E8=BF=81=E7=A7=BB=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/store/message.go | 40 ++++++++++++++++++++++++ backend/migrations/002_messages.down.sql | 1 + backend/migrations/002_messages.up.sql | 17 ++++++++++ 3 files changed, 58 insertions(+) create mode 100644 backend/internal/store/message.go create mode 100644 backend/migrations/002_messages.down.sql create mode 100644 backend/migrations/002_messages.up.sql diff --git a/backend/internal/store/message.go b/backend/internal/store/message.go new file mode 100644 index 0000000..629af20 --- /dev/null +++ b/backend/internal/store/message.go @@ -0,0 +1,40 @@ +package store + +import ( + "context" + "errors" + "time" + + "github.com/hhs/camtalk/internal/models" +) + +var ( + // ErrMessageNotFound 消息不存在。 + ErrMessageNotFound = errors.New("message not found") +) + +// MessageRepository 消息持久化接口。 +type MessageRepository interface { + // SaveMessage 保存一条消息。 + SaveMessage(ctx context.Context, sessionID string, msg models.Message, tokensUsed int) error + + // GetMessages 获取会话的消息列表(分页,按 created_at 升序)。 + // beforeID 为 0 时从最新开始查询。 + GetMessages(ctx context.Context, sessionID string, limit int, beforeID int64) ([]StoredMessage, error) + + // GetLastMessage 获取会话的最后一条消息。 + GetLastMessage(ctx context.Context, sessionID string) (*StoredMessage, error) + + // GetMessageCount 获取会话的消息总数。 + GetMessageCount(ctx context.Context, sessionID string) (int, error) +} + +// StoredMessage 持久化消息模型(store 层)。 +type StoredMessage struct { + ID int64 `json:"id"` + SessionID string `json:"-"` + Role string `json:"role"` + Content string `json:"content"` + TokensUsed int `json:"tokens_used"` + CreatedAt time.Time `json:"created_at"` +} diff --git a/backend/migrations/002_messages.down.sql b/backend/migrations/002_messages.down.sql new file mode 100644 index 0000000..cbe8189 --- /dev/null +++ b/backend/migrations/002_messages.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS messages; diff --git a/backend/migrations/002_messages.up.sql b/backend/migrations/002_messages.up.sql new file mode 100644 index 0000000..fe1e088 --- /dev/null +++ b/backend/migrations/002_messages.up.sql @@ -0,0 +1,17 @@ +-- 消息表 +CREATE TABLE IF NOT EXISTS messages ( + id BIGSERIAL PRIMARY KEY, + session_id UUID NOT NULL, + role VARCHAR(16) NOT NULL, -- "user" | "assistant" | "system" + content TEXT NOT NULL, + tokens_used INTEGER NOT NULL DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +-- 按会话查询消息(分页核心索引) +CREATE INDEX IF NOT EXISTS idx_messages_session_id_created_at + ON messages(session_id, created_at); + +-- 按会话查询最后一条消息 +CREATE INDEX IF NOT EXISTS idx_messages_session_id_id_desc + ON messages(session_id, id DESC);