# service/GraphStyleService.py import json from util.mysql_utils import mysql_client class GraphStyleService: @staticmethod def save_config(canvas_name: str, current_label: str, styles_dict: dict, group_name: str = None) -> bool: """ 保存图谱样式配置(增强版:自动处理分组逻辑) :param canvas_name: 画布显示名称 :param current_label: 针对的标签名称 :param styles_dict: 样式字典 :param group_name: 分组名称(前端传来的字符串) """ # 1. 处理分组逻辑:查不到就建,查到了就用 if not group_name or group_name.strip() == "": group_name = "默认方案" # 检查组名是否已存在 check_group_sql = "SELECT id FROM graph_style_groups WHERE group_name = %s LIMIT 1" existing_group = mysql_client.execute_query(check_group_sql, (group_name,)) if existing_group: # 如果存在,直接使用已有 ID target_group_id = existing_group[0]['id'] else: # 如果不存在,新建一个组 create_group_sql = "INSERT INTO graph_style_groups (group_name) VALUES (%s)" mysql_client.execute_update(create_group_sql, (group_name,)) # 获取新生成的 ID get_id_sql = "SELECT LAST_INSERT_ID() as last_id" id_res = mysql_client.execute_query(get_id_sql) target_group_id = id_res[0]['last_id'] if id_res else 1 # 2. 转换样式 JSON config_json = json.dumps(styles_dict, ensure_ascii=False) # 3. 插入配置表(关联 target_group_id) sql = """ INSERT INTO graph_configs (canvas_name, current_label, config_json, group_id) VALUES (%s, %s, %s, %s) """ affected_rows = mysql_client.execute_update(sql, (canvas_name, current_label, config_json, target_group_id)) return affected_rows > 0 @staticmethod def get_grouped_configs() -> list: """ 核心优化:获取嵌套结构的方案列表 (Group -> Configs) 用于前端右侧折叠面板展示 """ # 1. 查询所有方案组 groups_sql = "SELECT id, group_name FROM graph_style_groups ORDER BY id ASC" groups = mysql_client.execute_query(groups_sql) or [] # 2. 查询所有配置项 configs_sql = "SELECT id, group_id, canvas_name, current_label, config_json, create_time FROM graph_configs" configs = mysql_client.execute_query(configs_sql) or [] # 3. 内存聚合:将配置项塞进对应的组 # 先处理配置项的 JSON 和 时间 for conf in configs: if conf.get('config_json'): try: conf['styles'] = json.loads(conf['config_json']) except: conf['styles'] = {} del conf['config_json'] if conf.get('create_time') and not isinstance(conf['create_time'], str): conf['create_time'] = conf['create_time'].strftime('%Y-%m-%d %H:%M:%S') # 组装数据结构 result = [] for g in groups: # 找到属于该组的所有配置 g_children = [c for c in configs if c['group_id'] == g['id']] g['configs'] = g_children # 增加一个前端控制开关用的字段 g['expanded'] = False result.append(g) return result @staticmethod def get_all_configs() -> list: """保持原有的扁平查询功能,仅增加 group_id 字段返回""" sql = "SELECT id, group_id, canvas_name, current_label, config_json, create_time FROM graph_configs ORDER BY create_time DESC" rows = mysql_client.execute_query(sql) if not rows: return [] for row in rows: if row.get('config_json'): try: row['styles'] = json.loads(row['config_json']) except: row['styles'] = {} del row['config_json'] if row.get('create_time') and not isinstance(row['create_time'], str): row['create_time'] = row['create_time'].strftime('%Y-%m-%d %H:%M:%S') return rows @staticmethod def delete_group(group_id: int) -> bool: """ 逻辑级联删除:删除方案组及其关联的所有配置 """ # 1. 删除组下的所有配置 del_configs_sql = "DELETE FROM graph_configs WHERE group_id = %s" mysql_client.execute_update(del_configs_sql, (group_id,)) # 2. 删除组本身 del_group_sql = "DELETE FROM graph_style_groups WHERE id = %s" affected_rows = mysql_client.execute_update(del_group_sql, (group_id,)) return affected_rows > 0 @staticmethod def delete_config(config_id: int) -> bool: """删除单个配置""" sql = "DELETE FROM graph_configs WHERE id = %s" affected_rows = mysql_client.execute_update(sql, (config_id,)) return affected_rows > 0 @staticmethod def batch_delete_configs(config_ids: list) -> int: """批量删除配置""" if not config_ids: return 0 try: clean_ids = [int(cid) for cid in config_ids if str(cid).isdigit()] except: return 0 if not clean_ids: return 0 placeholders = ', '.join(['%s'] * len(clean_ids)) sql = f"DELETE FROM graph_configs WHERE id IN ({placeholders})" return mysql_client.execute_update(sql, tuple(clean_ids)) @staticmethod def get_group_list() -> list: """单独获取方案名称列表,供前端下拉框使用""" sql = "SELECT id, group_name FROM graph_style_groups ORDER BY create_time DESC" return mysql_client.execute_query(sql) or []