Skip to content

Instantly share code, notes, and snippets.

@engalar
Last active July 3, 2025 04:32
Show Gist options
  • Save engalar/78de2f5683e9b46232dc8ae96574a58a to your computer and use it in GitHub Desktop.
Save engalar/78de2f5683e9b46232dc8ae96574a58a to your computer and use it in GitHub Desktop.
# 1. 初始化与导入
import json
import clr
clr.AddReference("Mendix.StudioPro.ExtensionsAPI")
# 导入关键模型类型
from Mendix.StudioPro.ExtensionsAPI.Model.Projects import IProject, IModule, IFolder
from Mendix.StudioPro.ExtensionsAPI.Model.Microflows import IMicroflow
# 假设 currentApp 已在环境中可用
PostMessage("backend:clear", '') # 可选,清空输出
# --- 定义目标路径和名称 ---
TARGET_MODULE_NAME = "HelloModule"
FOLDER_PATH = ["Microflows", "DS"] # 文件夹层级
TARGET_MICROFLOW_NAME = "MyFirstMicroflow"
# --- 2. 查找或创建模块 ---
def ensure_module_exists(project: IProject, module_name: str) -> IModule | None:
"""检查模块是否存在,不存在则创建。返回模块对象。"""
module = None
for m in project.GetModules():
if m.Name == module_name:
module = m
PostMessage("backend:info", f"Module '{module_name}' already exists.")
return module
# 模块不存在,开始创建事务
transaction = currentApp.StartTransaction(f"Create Module: {module_name}")
try:
new_module = currentApp.Create[IModule]()
new_module.Name = module_name
project.AddModule(new_module) # 将新模块添加到项目中
transaction.Commit()
PostMessage("backend:info", f"Module '{module_name}' created successfully.")
return new_module
except Exception as e:
transaction.Rollback()
PostMessage("backend:error", f"Failed to create module '{module_name}': {e}")
return None
finally:
transaction.Dispose()
# --- 3. 查找或创建文件夹 ---
def ensure_folders_exist(module: IModule, folder_path: list[str]) -> IFolder | None:
"""
在给定模块中递归查找或创建文件夹路径。
返回最后一级文件夹的对象,如果路径创建失败则返回 None。
"""
current_folder = module # 从模块开始
for i, folder_name in enumerate(folder_path):
found_folder = None
# 检查当前层级的文件夹是否存在
for f in current_folder.GetFolders():
if f.Name == folder_name:
found_folder = f
PostMessage("backend:info", f"Folder '{folder_name}' in path '{'/'.join(folder_path[:i+1])}' already exists.")
break
if found_folder is None:
# 文件夹不存在,创建它
transaction = currentApp.StartTransaction(f"Create Folder: {'/'.join(folder_path[:i+1])}")
try:
new_folder = currentApp.Create[IFolder]()
new_folder.Name = folder_name
# 将新文件夹添加到当前层级(模块或父文件夹)
if isinstance(current_folder, IModule):
current_folder.AddFolder(new_folder)
elif isinstance(current_folder, IFolder):
current_folder.AddFolder(new_folder) # 注意:IFolder.AddFolder() 可能不存在,需要查证API
# 如果IFolder没有直接AddFolder,可能需要通过Model.AddFolder()并指定父级
# 假设这里有 AddFolder 方法或者可以通过其他方式关联
PostMessage("backend:info", f"Folder '{folder_name}' created successfully in path '{'/'.join(folder_path[:i+1])}'.")
found_folder = new_folder # 设置为刚刚创建的
else:
raise TypeError("Invalid parent for folder creation.")
transaction.Commit()
except Exception as e:
transaction.Rollback()
PostMessage("backend:error", f"Failed to create folder '{folder_name}' in path '{'/'.join(folder_path[:i+1])}': {e}")
return None # 创建失败,返回None
finally:
transaction.Dispose()
else:
found_folder = found_folder # 使用已存在的文件夹
current_folder = found_folder # 移动到下一层级
# 返回最后一级文件夹
return current_folder if isinstance(current_folder, IFolder) else None # 如果最后一级是模块本身 (空路径),则返回None
# --- 4. 查找或创建微流 ---
def ensure_microflow_exists(parent_folder: IFolder, microflow_name: str) -> IMicroflow | None:
"""检查微流是否存在于指定文件夹,不存在则创建。返回微流对象。"""
if parent_folder is None:
PostMessage("backend:error", "Parent folder is invalid, cannot create microflow.")
return None
# 检查微流是否已存在
for doc in parent_folder.GetDocuments():
if doc.Name == microflow_name:
PostMessage("backend:info", f"Microflow '{microflow_name}' already exists in folder '{parent_folder.Name}'.")
return doc # 返回已存在的微流对象
# 微流不存在,开始创建事务
transaction = currentApp.StartTransaction(f"Create Microflow: {microflow_name}")
try:
new_microflow = currentApp.Create[IMicroflow]()
new_microflow.Name = microflow_name
# 将新微流添加到目标文件夹
parent_folder.AddDocument(new_microflow) # 假设 IFolder.AddDocument() 存在
transaction.Commit()
PostMessage("backend:info", f"Microflow '{microflow_name}' created successfully in folder '{parent_folder.Name}'.")
return new_microflow
except Exception as e:
transaction.Rollback()
PostMessage("backend:error", f"Failed to create microflow '{microflow_name}' in folder '{parent_folder.Name}': {e}")
return None
finally:
transaction.Dispose()
# --- 主执行逻辑 ---
def create_target_microflow():
project = currentApp.Root # 获取项目对象
# 1. 确保模块存在
hello_module = ensure_module_exists(project, TARGET_MODULE_NAME)
if hello_module is None:
return # 模块创建失败,终止操作
# 2. 确保文件夹路径存在
# 注意: 确保文件夹创建逻辑正确处理了路径中的每一级。
# 这里假定 IFolder 接口提供 AddFolder() 方法来嵌套文件夹,
# 如果不是这样,需要查阅 Mendix API 文档确认如何在项目模型中添加嵌套文件夹。
# 通常,添加文件夹是添加到 module.DomainModel 或其他父级,
# 而文档是添加到 Folder.GetDocuments() 的父级。
# 对文件夹的嵌套创建可能需要一个更通用的工具函数来处理。
# 如果 Folder 没有直接 AddFolder 方法,可能需要使用 Model.AddFolder(new_folder, parent_folder)
# 或类似机制来处理层级关系。
# 以下是一个简化的文件夹创建思路,可能需要根据实际API调整:
current_folder = hello_module
for i, folder_name in enumerate(FOLDER_PATH):
next_folder_obj = None
# 检查当前层级是否存在同名文件夹
for item in current_folder.GetFolders(): # 假设 current_folder 实现了 GetFolders()
if item.Name == folder_name:
next_folder_obj = item
PostMessage("backend:info", f"Folder '{folder_name}' already exists.")
break
if next_folder_obj is None:
# 创建新文件夹
transaction = currentApp.StartTransaction(f"Create Folder '{folder_name}'")
try:
new_folder = currentApp.Create[IFolder]()
new_folder.Name = folder_name
# 关键:将新文件夹添加到当前层级的父级
if current_folder is not None:
current_folder.AddFolder(new_folder)
PostMessage("backend:info", f"Folder '{folder_name}' created inside '{current_folder.Name}'.")
transaction.Commit()
next_folder_obj = new_folder
else:
raise TypeError(f"Unexpected current_folder type: {type(current_folder)}")
except Exception as e:
transaction.Rollback()
PostMessage("backend:error", f"Failed to create folder '{folder_name}': {e}")
return # 文件夹创建失败,终止
current_folder = next_folder_obj # 移动到下一个文件夹层级
# 最终的 current_folder 应该是 DS 文件夹
if not isinstance(current_folder, IFolder):
PostMessage("backend:error", f"Could not find or create the target folder '{'/'.join(FOLDER_PATH)}'.")
return
# 3. 确保微流存在于最后的文件夹中
created_microflow = ensure_microflow_exists(current_folder, TARGET_MICROFLOW_NAME)
if created_microflow:
PostMessage("backend:info", f"Successfully created or found microflow '{TARGET_MICROFLOW_NAME}'.")
else:
PostMessage("backend:error", f"Failed to ensure microflow '{TARGET_MICROFLOW_NAME}' exists.")
create_target_microflow()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment