feat:历史记录分享功能实现

This commit is contained in:
liailing1026
2026-03-12 13:35:04 +08:00
parent 26c42697e8
commit 130f78108f
9 changed files with 1500 additions and 80 deletions

View File

@@ -5,8 +5,8 @@ AgentCoord 数据库模块
"""
from .database import get_db, get_db_context, test_connection, engine, text
from .models import MultiAgentTask, UserAgent, ExportRecord, TaskStatus
from .crud import MultiAgentTaskCRUD, UserAgentCRUD, ExportRecordCRUD
from .models import MultiAgentTask, UserAgent, ExportRecord, PlanShare, TaskStatus
from .crud import MultiAgentTaskCRUD, UserAgentCRUD, ExportRecordCRUD, PlanShareCRUD
__all__ = [
# 连接管理
@@ -19,9 +19,11 @@ __all__ = [
"MultiAgentTask",
"UserAgent",
"ExportRecord",
"PlanShare",
"TaskStatus",
# CRUD
"MultiAgentTaskCRUD",
"UserAgentCRUD",
"ExportRecordCRUD",
"PlanShareCRUD",
]

View File

@@ -9,7 +9,7 @@ from datetime import datetime, timezone
from typing import List, Optional
from sqlalchemy.orm import Session
from .models import MultiAgentTask, UserAgent, ExportRecord
from .models import MultiAgentTask, UserAgent, ExportRecord, PlanShare
class MultiAgentTaskCRUD:
@@ -500,3 +500,78 @@ class ExportRecordCRUD:
db.commit()
return True
return False
class PlanShareCRUD:
"""任务分享 CRUD 操作"""
@staticmethod
def create(
db: Session,
share_token: str,
task_id: str,
task_data: dict,
expires_at: Optional[datetime] = None,
extraction_code: Optional[str] = None,
) -> PlanShare:
"""创建分享记录"""
share = PlanShare(
share_token=share_token,
extraction_code=extraction_code,
task_id=task_id,
task_data=task_data,
expires_at=expires_at,
)
db.add(share)
db.commit()
db.refresh(share)
return share
@staticmethod
def get_by_token(db: Session, share_token: str) -> Optional[PlanShare]:
"""根据 token 获取分享记录"""
return db.query(PlanShare).filter(PlanShare.share_token == share_token).first()
@staticmethod
def get_by_task_id(
db: Session, task_id: str, limit: int = 10
) -> List[PlanShare]:
"""根据任务 ID 获取分享记录列表"""
return (
db.query(PlanShare)
.filter(PlanShare.task_id == task_id)
.order_by(PlanShare.created_at.desc())
.limit(limit)
.all()
)
@staticmethod
def increment_view_count(db: Session, share_token: str) -> Optional[PlanShare]:
"""增加查看次数"""
share = db.query(PlanShare).filter(PlanShare.share_token == share_token).first()
if share:
share.view_count = (share.view_count or 0) + 1
db.commit()
db.refresh(share)
return share
@staticmethod
def delete(db: Session, share_token: str) -> bool:
"""删除分享记录"""
share = db.query(PlanShare).filter(PlanShare.share_token == share_token).first()
if share:
db.delete(share)
db.commit()
return True
return False
@staticmethod
def delete_by_task_id(db: Session, task_id: str) -> bool:
"""删除任务的所有分享记录"""
shares = db.query(PlanShare).filter(PlanShare.task_id == task_id).all()
if shares:
for share in shares:
db.delete(share)
db.commit()
return True
return False

View File

@@ -10,7 +10,7 @@ import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from db.database import engine, Base
from db.models import MultiAgentTask, UserAgent
from db.models import MultiAgentTask, UserAgent, PlanShare
def init_database():

View File

@@ -137,3 +137,34 @@ class UserAgent(Base):
"agent_config": self.agent_config,
"created_at": self.created_at.isoformat() if self.created_at else None,
}
class PlanShare(Base):
"""任务分享记录模型"""
__tablename__ = "plan_shares"
id = Column(Integer, primary_key=True, autoincrement=True)
share_token = Column(String(64), unique=True, index=True, nullable=False) # 唯一分享码
extraction_code = Column(String(8), nullable=True) # 提取码4位字母数字
task_id = Column(String(64), nullable=False, index=True) # 关联的任务ID
task_data = Column(JSONB, nullable=False) # 完整的任务数据(脱敏后)
created_at = Column(DateTime(timezone=True), default=utc_now)
expires_at = Column(DateTime(timezone=True), nullable=True) # 过期时间
view_count = Column(Integer, default=0) # 查看次数
__table_args__ = (
Index("idx_plan_shares_token", "share_token"),
)
def to_dict(self) -> dict:
"""转换为字典"""
return {
"id": self.id,
"share_token": self.share_token,
"extraction_code": self.extraction_code,
"task_id": self.task_id,
"task_data": self.task_data,
"created_at": self.created_at.isoformat() if self.created_at else None,
"expires_at": self.expires_at.isoformat() if self.expires_at else None,
"view_count": self.view_count,
}

View File

@@ -62,9 +62,45 @@ CREATE TRIGGER update_multi_agent_tasks_updated_at
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- =============================================================================
-- 表3: export_records (导出记录)
-- =============================================================================
CREATE TABLE IF NOT EXISTS export_records (
id SERIAL PRIMARY KEY,
task_id VARCHAR(64) NOT NULL,
user_id VARCHAR(64) NOT NULL,
export_type VARCHAR(32) NOT NULL,
file_name VARCHAR(256) NOT NULL,
file_path VARCHAR(512) NOT NULL,
file_url VARCHAR(512),
file_size INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_export_records_task_user ON export_records(task_id, user_id);
-- =============================================================================
-- 表4: plan_shares (任务分享记录)
-- =============================================================================
CREATE TABLE IF NOT EXISTS plan_shares (
id SERIAL PRIMARY KEY,
share_token VARCHAR(64) NOT NULL UNIQUE,
extraction_code VARCHAR(8),
task_id VARCHAR(64) NOT NULL,
task_data JSONB NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP WITH TIME ZONE,
view_count INTEGER DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_plan_shares_token ON plan_shares(share_token);
CREATE INDEX IF NOT EXISTS idx_plan_shares_task_id ON plan_shares(task_id);
DO $$
BEGIN
RAISE NOTICE '✅ PostgreSQL 数据库表结构创建完成!';
RAISE NOTICE '表: multi_agent_tasks (多智能体任务记录)';
RAISE NOTICE '表: user_agents (用户智能体配置)';
RAISE NOTICE '表: export_records (导出记录)';
RAISE NOTICE '表: plan_shares (任务分享记录)';
END $$;