#!/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"" @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)