feat: 创建 LobsterDiary 模型,支持数据库存储日记

- 创建 LobsterDiary 模型
  * 关联龙虾(ForeignKey)
  * 日期、标题、内容
  * 分类(成才之路/工作记忆/技术笔记)
  * 标签(JSONField)
  * Embedding 字段(预留 RAG 支持)
  * 数据库索引优化

- 数据库迁移
  * 添加 LobsterDiary 表
  * 添加索引:lobster+date, category+date, date

- 导入脚本
  * 创建 import_diaries 管理命令
  * 导入飞行侠的成才之路日记(3 篇)

- 更新 API
  * /api/lobsters/<id>/diary/dates/ - 从数据库查询
  * /api/lobsters/<id>/diary/<date>/ - 从数据库读取

- PostgreSQL 配置模板
  * settings_postgresql.py
  * 准备好 PostgreSQL 迁移

技术栈:SQLite(当前) → PostgreSQL(未来)
RAG 支持:预留 embedding 字段,未来可扩展

🗄️ 日记正式进入数据库时代!
This commit is contained in:
2026-04-03 17:38:18 +08:00
parent 689851e762
commit 24e4ca2c82
7 changed files with 330 additions and 28 deletions

View File

@@ -7,7 +7,7 @@ from datetime import datetime
import os
from pathlib import Path
import re
from lobsters.models import Lobster
from lobsters.models import Lobster, LobsterDiary
@api_view(['GET'])
def lobster_list(request):
@@ -121,38 +121,41 @@ def lobster_memory_detail(request, lobster_id, date):
@api_view(['GET'])
def lobster_diary_dates(request, lobster_id):
"""获取龙虾有日记(成才之路)的日期列表"""
# 日记文件目录
diary_dir = Path(f'/home/node/.openclaw/workspace/flying-hero/memory/成才之路')
"""获取龙虾有日记(成才之路)的日期列表 - 从数据库读取"""
try:
lobster = Lobster.objects.get(id=lobster_id)
except Lobster.DoesNotExist:
return Response({'error': '龙虾不存在'}, status=404)
# 获取所有日记文件
dates = []
if diary_dir.exists():
for file in diary_dir.glob('*.md'):
# 提取日期 (YYYY-MM-DD.md 或 YYYY-MM-DD-*.md)
match = re.match(r'(\d{4}-\d{2}-\d{2})(?:-.*)?\.md', file.name)
if match:
dates.append(match.group(1))
# 从数据库查询日记日期
diaries = LobsterDiary.objects.filter(
lobster=lobster,
category='chengcai'
).values_list('date', flat=True).distinct()
dates = list(set(dates)) # 去重
dates.sort(reverse=True)
dates = [str(date) for date in sorted(diaries, reverse=True)]
return Response({'dates': dates})
@api_view(['GET'])
def lobster_diary_detail(request, lobster_id, date):
"""获取指定日期的日记内容(成才之路)"""
# 优先查找故事版,其次技术版,再其次普通版
diary_file = Path(f'/home/node/.openclaw/workspace/flying-hero/memory/成才之路/{date}-故事版.md')
if not diary_file.exists():
diary_file = Path(f'/home/node/.openclaw/workspace/flying-hero/memory/成才之路/{date}-技术版.md')
if not diary_file.exists():
diary_file = Path(f'/home/node/.openclaw/workspace/flying-hero/memory/成才之路/{date}.md')
"""获取指定日期的日记内容(成才之路) - 从数据库读取"""
try:
lobster = Lobster.objects.get(id=lobster_id)
except Lobster.DoesNotExist:
return Response({'error': '龙虾不存在'}, status=404)
if not diary_file.exists():
# 从数据库查询日记
try:
diary = LobsterDiary.objects.get(
lobster=lobster,
date=date,
category='chengcai'
)
return Response({
'date': str(diary.date),
'content': diary.content,
'title': diary.title,
'tags': diary.tags,
})
except LobsterDiary.DoesNotExist:
return Response({'error': '该日期没有日记'}, status=404)
content = diary_file.read_text(encoding='utf-8')
return Response({
'date': date,
'content': content
})