288 lines
9.1 KiB
Python
288 lines
9.1 KiB
Python
"""
|
|
映射管理服务
|
|
提供映射模型管理的业务逻辑
|
|
"""
|
|
from typing import List, Optional, Tuple
|
|
|
|
from database.repositories.mapping_repository import MappingRepository
|
|
from models.mapping import OperatorMapping, CodeMapping, CompositeMapping, Mapping, MappingType
|
|
from models.mapping_graph import MappingGraph, GraphNode, GraphEdge
|
|
from utils.validator import Validator
|
|
from utils.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class MappingService:
|
|
"""映射管理服务类"""
|
|
|
|
def __init__(self):
|
|
self.repository = MappingRepository()
|
|
self.validator = Validator()
|
|
|
|
def create_operator_mapping(self, mapping: OperatorMapping) -> tuple[bool, str, Optional[int]]:
|
|
"""
|
|
创建操作符映射
|
|
|
|
Args:
|
|
mapping: 操作符映射对象
|
|
|
|
Returns:
|
|
(是否成功, 消息, 映射ID)
|
|
"""
|
|
# 验证映射数据
|
|
is_valid, error_msg = mapping.validate()
|
|
if not is_valid:
|
|
logger.warning(f"Operator mapping validation failed: {error_msg}")
|
|
return False, error_msg, None
|
|
|
|
try:
|
|
mapping_id = self.repository.create_operator_mapping(mapping)
|
|
logger.info(f"Operator mapping created successfully: ID {mapping_id}")
|
|
return True, "操作符映射创建成功", mapping_id
|
|
except Exception as e:
|
|
logger.error(f"Failed to create operator mapping: {e}")
|
|
return False, f"创建操作符映射失败: {str(e)}", None
|
|
|
|
def create_code_mapping(self, mapping: CodeMapping) -> tuple[bool, str, Optional[int]]:
|
|
"""
|
|
创建代码映射
|
|
|
|
Args:
|
|
mapping: 代码映射对象
|
|
|
|
Returns:
|
|
(是否成功, 消息, 映射ID)
|
|
"""
|
|
# 验证映射数据
|
|
is_valid, error_msg = mapping.validate()
|
|
if not is_valid:
|
|
logger.warning(f"Code mapping validation failed: {error_msg}")
|
|
return False, error_msg, None
|
|
|
|
# 验证代码语法
|
|
is_valid, error_msg = self.validator.validate_code(
|
|
mapping.code, mapping.language.value
|
|
)
|
|
if not is_valid:
|
|
return False, error_msg, None
|
|
|
|
try:
|
|
mapping_id = self.repository.create_code_mapping(mapping)
|
|
logger.info(f"Code mapping created successfully: ID {mapping_id}")
|
|
return True, "代码映射创建成功", mapping_id
|
|
except Exception as e:
|
|
logger.error(f"Failed to create code mapping: {e}")
|
|
return False, f"创建代码映射失败: {str(e)}", None
|
|
|
|
def create_composite_mapping(self, mapping: CompositeMapping) -> tuple[bool, str, Optional[int]]:
|
|
"""
|
|
创建复合映射
|
|
|
|
Args:
|
|
mapping: 复合映射对象
|
|
|
|
Returns:
|
|
(是否成功, 消息, 映射ID)
|
|
"""
|
|
# 验证映射数据
|
|
is_valid, error_msg = mapping.validate()
|
|
if not is_valid:
|
|
logger.warning(f"Composite mapping validation failed: {error_msg}")
|
|
return False, error_msg, None
|
|
|
|
try:
|
|
mapping_id = self.repository.create_composite_mapping(mapping)
|
|
logger.info(f"Composite mapping created successfully: ID {mapping_id}")
|
|
return True, "复合映射创建成功", mapping_id
|
|
except Exception as e:
|
|
logger.error(f"Failed to create composite mapping: {e}")
|
|
return False, f"创建复合映射失败: {str(e)}", None
|
|
|
|
def update_operator_mapping(self, mapping: OperatorMapping) -> tuple[bool, str]:
|
|
"""
|
|
更新操作符映射
|
|
|
|
Args:
|
|
mapping: 操作符映射对象
|
|
|
|
Returns:
|
|
(是否成功, 消息)
|
|
"""
|
|
if not mapping.id:
|
|
return False, "映射ID不能为空"
|
|
|
|
# 验证映射数据
|
|
is_valid, error_msg = mapping.validate()
|
|
if not is_valid:
|
|
return False, error_msg
|
|
|
|
try:
|
|
success = self.repository.update_operator_mapping(mapping)
|
|
if success:
|
|
logger.info(f"Operator mapping updated successfully: ID {mapping.id}")
|
|
return True, "操作符映射更新成功"
|
|
else:
|
|
return False, "映射不存在"
|
|
except Exception as e:
|
|
logger.error(f"Failed to update operator mapping: {e}")
|
|
return False, f"更新操作符映射失败: {str(e)}"
|
|
|
|
def delete_mapping(self, mapping_id: int) -> tuple[bool, str]:
|
|
"""
|
|
删除映射
|
|
|
|
Args:
|
|
mapping_id: 映射ID
|
|
|
|
Returns:
|
|
(是否成功, 消息)
|
|
"""
|
|
try:
|
|
success = self.repository.delete(mapping_id)
|
|
if success:
|
|
logger.info(f"Mapping deleted successfully: ID {mapping_id}")
|
|
return True, "映射删除成功"
|
|
else:
|
|
return False, "映射不存在"
|
|
except Exception as e:
|
|
logger.error(f"Failed to delete mapping: {e}")
|
|
return False, f"删除映射失败: {str(e)}"
|
|
|
|
def get_mapping_by_id(self, mapping_id: int) -> Optional[Mapping]:
|
|
"""
|
|
根据ID获取映射
|
|
|
|
Args:
|
|
mapping_id: 映射ID
|
|
|
|
Returns:
|
|
映射对象或None
|
|
"""
|
|
try:
|
|
return self.repository.get_by_id(mapping_id)
|
|
except Exception as e:
|
|
logger.error(f"Failed to get mapping by id: {e}")
|
|
return None
|
|
|
|
def search_mappings(self, mapping_type: Optional[MappingType] = None,
|
|
target_field_id: Optional[int] = None,
|
|
page: int = 1, page_size: int = 50) -> tuple[List[Mapping], int]:
|
|
"""
|
|
搜索映射
|
|
|
|
Args:
|
|
mapping_type: 映射类型
|
|
target_field_id: 目标字段ID
|
|
page: 页码
|
|
page_size: 每页数量
|
|
|
|
Returns:
|
|
(映射列表, 总数量)
|
|
"""
|
|
try:
|
|
offset = (page - 1) * page_size
|
|
mappings = self.repository.search(mapping_type, target_field_id, page_size, offset)
|
|
# 简化的总数统计
|
|
total = len(mappings)
|
|
return mappings, total
|
|
except Exception as e:
|
|
logger.error(f"Failed to search mappings: {e}")
|
|
return [], 0
|
|
|
|
# 映射图相关方法
|
|
|
|
def add_node_to_graph(self, node: GraphNode) -> tuple[bool, str]:
|
|
"""
|
|
向映射图添加节点
|
|
|
|
Args:
|
|
node: 图节点
|
|
|
|
Returns:
|
|
(是否成功, 消息)
|
|
"""
|
|
try:
|
|
success = self.repository.add_graph_node(node)
|
|
if success:
|
|
logger.info(f"Node added to graph: field ID {node.field.id}")
|
|
return True, "节点添加成功"
|
|
else:
|
|
return False, "添加节点失败"
|
|
except Exception as e:
|
|
logger.error(f"Failed to add node to graph: {e}")
|
|
return False, f"添加节点失败: {str(e)}"
|
|
|
|
def remove_node_from_graph(self, field_id: int) -> tuple[bool, str]:
|
|
"""
|
|
从映射图移除节点
|
|
|
|
Args:
|
|
field_id: 字段ID
|
|
|
|
Returns:
|
|
(是否成功, 消息)
|
|
"""
|
|
try:
|
|
success = self.repository.remove_graph_node(field_id)
|
|
if success:
|
|
logger.info(f"Node removed from graph: field ID {field_id}")
|
|
return True, "节点移除成功"
|
|
else:
|
|
return False, "节点不存在"
|
|
except Exception as e:
|
|
logger.error(f"Failed to remove node from graph: {e}")
|
|
return False, f"移除节点失败: {str(e)}"
|
|
|
|
def add_edge_to_graph(self, edge: GraphEdge) -> tuple[bool, str, Optional[int]]:
|
|
"""
|
|
向映射图添加边
|
|
|
|
Args:
|
|
edge: 图边
|
|
|
|
Returns:
|
|
(是否成功, 消息, 边ID)
|
|
"""
|
|
try:
|
|
edge_id = self.repository.add_graph_edge(edge)
|
|
logger.info(f"Edge added to graph: ID {edge_id}")
|
|
return True, "边添加成功", edge_id
|
|
except Exception as e:
|
|
logger.error(f"Failed to add edge to graph: {e}")
|
|
return False, f"添加边失败: {str(e)}", None
|
|
|
|
def remove_edge_from_graph(self, edge_id: int) -> tuple[bool, str]:
|
|
"""
|
|
从映射图移除边
|
|
|
|
Args:
|
|
edge_id: 边ID
|
|
|
|
Returns:
|
|
(是否成功, 消息)
|
|
"""
|
|
try:
|
|
success = self.repository.remove_graph_edge(edge_id)
|
|
if success:
|
|
logger.info(f"Edge removed from graph: ID {edge_id}")
|
|
return True, "边移除成功"
|
|
else:
|
|
return False, "边不存在"
|
|
except Exception as e:
|
|
logger.error(f"Failed to remove edge from graph: {e}")
|
|
return False, f"移除边失败: {str(e)}"
|
|
|
|
def get_mapping_graph(self) -> Optional[MappingGraph]:
|
|
"""
|
|
获取映射图
|
|
|
|
Returns:
|
|
映射图对象或None
|
|
"""
|
|
try:
|
|
return self.repository.get_mapping_graph()
|
|
except Exception as e:
|
|
logger.error(f"Failed to get mapping graph: {e}")
|
|
return None
|