tianfeng_task_modules/data/models/task_edit_history.py

159 lines
5.5 KiB
Python
Raw Permalink Normal View History

2025-03-17 14:58:05 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
任务编辑历史模型模块
包含任务编辑历史相关的数据模型用于支持撤销/重做功能
"""
import enum
from sqlalchemy import Column, Integer, String, Text, DateTime, Enum, ForeignKey, JSON, Boolean
from sqlalchemy.orm import relationship
from data.models.base import BaseModel
class EditActionType(enum.Enum):
"""
编辑操作类型枚举
"""
ADD_NODE = 'add_node' # 添加节点
DELETE_NODE = 'delete_node' # 删除节点
MOVE_NODE = 'move_node' # 移动节点
RESIZE_NODE = 'resize_node' # 调整节点大小
UPDATE_NODE = 'update_node' # 更新节点属性
ADD_CONNECTION = 'add_connection' # 添加连接
DELETE_CONNECTION = 'delete_connection' # 删除连接
UPDATE_CONNECTION = 'update_connection' # 更新连接属性
ADD_VARIABLE = 'add_variable' # 添加变量
DELETE_VARIABLE = 'delete_variable' # 删除变量
UPDATE_VARIABLE = 'update_variable' # 更新变量
BATCH_OPERATION = 'batch_operation' # 批量操作
PASTE = 'paste' # 粘贴操作
OTHER = 'other' # 其他操作
class TaskEditHistory(BaseModel):
"""
任务编辑历史模型
记录任务编辑过程中的操作历史用于支持撤销/重做功能
"""
__tablename__ = 'task_edit_histories'
task_id = Column(Integer, ForeignKey('tasks.id'), nullable=False, comment='任务ID')
session_id = Column(String(100), nullable=False, comment='编辑会话ID')
action_type = Column(Enum(EditActionType), nullable=False, comment='操作类型')
action_time = Column(DateTime, nullable=False, comment='操作时间')
user_id = Column(String(100), nullable=True, comment='操作用户ID')
sequence = Column(Integer, nullable=False, comment='操作序号(同一会话中的顺序)')
before_state = Column(JSON, nullable=True, comment='操作前状态JSON格式')
after_state = Column(JSON, nullable=True, comment='操作后状态JSON格式')
affected_ids = Column(JSON, nullable=True, comment='受影响的对象ID列表JSON数组')
description = Column(String(500), nullable=True, comment='操作描述')
is_undoable = Column(Boolean, default=True, comment='是否可撤销')
is_redoable = Column(Boolean, default=True, comment='是否可重做')
def __repr__(self):
return f"<TaskEditHistory(id={self.id}, task_id={self.task_id}, action_type='{self.action_type}', sequence={self.sequence})>"
@classmethod
def get_by_session(cls, session_id, limit=50):
"""
获取编辑会话的操作历史
"""
return cls.query.filter(
cls.session_id == session_id,
cls.is_deleted == False
).order_by(cls.sequence.desc()).limit(limit).all()
@classmethod
def get_by_task(cls, task_id, limit=100):
"""
获取任务的操作历史
"""
return cls.query.filter(
cls.task_id == task_id,
cls.is_deleted == False
).order_by(cls.action_time.desc()).limit(limit).all()
@classmethod
def get_last_action(cls, session_id):
"""
获取编辑会话的最后一个操作
"""
return cls.query.filter(
cls.session_id == session_id,
cls.is_deleted == False
).order_by(cls.sequence.desc()).first()
@classmethod
def record_action(cls, task_id, session_id, action_type, user_id=None, before_state=None,
after_state=None, affected_ids=None, description=None):
"""
记录编辑操作
"""
import datetime
from config.database import db_session
# 获取当前会话的最大序号
last_action = cls.get_last_action(session_id)
sequence = (last_action.sequence + 1) if last_action else 1
# 创建新的操作记录
action = cls(
task_id=task_id,
session_id=session_id,
action_type=action_type,
action_time=datetime.datetime.now(),
user_id=user_id,
sequence=sequence,
before_state=before_state,
after_state=after_state,
affected_ids=affected_ids,
description=description,
is_undoable=True,
is_redoable=False # 新操作默认不可重做
)
db_session.add(action)
db_session.commit()
return action
@classmethod
def mark_as_undone(cls, action_id):
"""
标记操作为已撤销
"""
from config.database import db_session
action = cls.query.get(action_id)
if action:
action.is_undoable = False
action.is_redoable = True
db_session.commit()
return action
@classmethod
def mark_as_redone(cls, action_id):
"""
标记操作为已重做
"""
from config.database import db_session
action = cls.query.get(action_id)
if action:
action.is_undoable = True
action.is_redoable = False
db_session.commit()
return action
@classmethod
def clear_session_history(cls, session_id):
"""
清除编辑会话的操作历史
"""
from config.database import db_session
actions = cls.query.filter(cls.session_id == session_id).all()
for action in actions:
action.is_deleted = True
db_session.commit()
return len(actions)