mirror of
https://github.com/goldenfishs/MRobot.git
synced 2026-03-31 21:07:14 +08:00
添加ioc和自动任务
This commit is contained in:
@@ -2,8 +2,11 @@ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QStackedWidget, QSizePolicy
|
||||
from PyQt5.QtCore import Qt
|
||||
from qfluentwidgets import PushSettingCard, FluentIcon, TabBar
|
||||
from qfluentwidgets import TitleLabel, BodyLabel, PushButton, FluentIcon
|
||||
from PyQt5.QtWidgets import QFileDialog
|
||||
from PyQt5.QtWidgets import QFileDialog, QDialog, QHBoxLayout
|
||||
from qfluentwidgets import ComboBox, PrimaryPushButton, SubtitleLabel
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from .function_fit_interface import FunctionFitInterface
|
||||
from .ai_interface import AIInterface
|
||||
from qfluentwidgets import InfoBar
|
||||
@@ -56,6 +59,10 @@ class CodeConfigurationInterface(QWidget):
|
||||
self.update_template_btn.setFixedWidth(200)
|
||||
mainLayout.addWidget(self.update_template_btn, alignment=Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.preset_ioc_btn = PushButton(FluentIcon.LIBRARY, "获取预设IOC")
|
||||
self.preset_ioc_btn.setFixedWidth(200)
|
||||
mainLayout.addWidget(self.preset_ioc_btn, alignment=Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
mainLayout.addSpacing(10)
|
||||
mainLayout.addStretch()
|
||||
|
||||
@@ -69,6 +76,7 @@ class CodeConfigurationInterface(QWidget):
|
||||
self.tabBar.tabCloseRequested.connect(self.onCloseTab)
|
||||
self.choose_btn.clicked.connect(self.choose_project_folder) # 启用选择项目路径按钮
|
||||
self.update_template_btn.clicked.connect(self.on_update_template)
|
||||
self.preset_ioc_btn.clicked.connect(self.use_preset_ioc) # 启用预设工程按钮
|
||||
|
||||
|
||||
def on_update_template(self):
|
||||
@@ -88,6 +96,170 @@ class CodeConfigurationInterface(QWidget):
|
||||
)
|
||||
update_code(parent=self, info_callback=info, error_callback=error)
|
||||
|
||||
def get_preset_ioc_files(self):
|
||||
"""获取预设的ioc文件列表"""
|
||||
try:
|
||||
preset_ioc_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "assets", "User_code", "ioc")
|
||||
if not os.path.exists(preset_ioc_dir):
|
||||
return []
|
||||
|
||||
ioc_files = []
|
||||
for filename in os.listdir(preset_ioc_dir):
|
||||
if filename.endswith('.ioc'):
|
||||
ioc_files.append({
|
||||
'name': os.path.splitext(filename)[0],
|
||||
'filename': filename,
|
||||
'path': os.path.join(preset_ioc_dir, filename)
|
||||
})
|
||||
return ioc_files
|
||||
except Exception as e:
|
||||
print(f"获取预设ioc文件失败: {e}")
|
||||
return []
|
||||
|
||||
def use_preset_ioc(self):
|
||||
"""使用预设ioc文件"""
|
||||
preset_files = self.get_preset_ioc_files()
|
||||
if not preset_files:
|
||||
InfoBar.warning(
|
||||
title="无预设工程",
|
||||
content="未找到可用的预设工程文件",
|
||||
parent=self,
|
||||
duration=2000
|
||||
)
|
||||
return
|
||||
|
||||
# 创建选择对话框
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle("获取预设IOC")
|
||||
dialog.resize(400, 200)
|
||||
dialog.setModal(True)
|
||||
|
||||
layout = QVBoxLayout(dialog)
|
||||
layout.setContentsMargins(24, 24, 24, 24)
|
||||
layout.setSpacing(16)
|
||||
|
||||
# 标题
|
||||
title_label = SubtitleLabel("选择要使用的IOC模版")
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 选择下拉框
|
||||
select_layout = QHBoxLayout()
|
||||
select_label = BodyLabel("预设IOC:")
|
||||
preset_combo = ComboBox()
|
||||
|
||||
# 修复ComboBox数据问题
|
||||
for i, preset in enumerate(preset_files):
|
||||
preset_combo.addItem(preset['name'])
|
||||
|
||||
select_layout.addWidget(select_label)
|
||||
select_layout.addWidget(preset_combo)
|
||||
layout.addLayout(select_layout)
|
||||
|
||||
layout.addSpacing(16)
|
||||
|
||||
# 按钮区域
|
||||
btn_layout = QHBoxLayout()
|
||||
btn_layout.addStretch()
|
||||
|
||||
cancel_btn = PushButton("取消")
|
||||
ok_btn = PrimaryPushButton("保存到")
|
||||
|
||||
cancel_btn.clicked.connect(dialog.reject)
|
||||
ok_btn.clicked.connect(dialog.accept)
|
||||
|
||||
btn_layout.addWidget(cancel_btn)
|
||||
btn_layout.addWidget(ok_btn)
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
# 显示对话框
|
||||
if dialog.exec() == QDialog.Accepted:
|
||||
selected_index = preset_combo.currentIndex()
|
||||
if selected_index >= 0 and selected_index < len(preset_files):
|
||||
selected_preset = preset_files[selected_index]
|
||||
self.save_preset_template(selected_preset)
|
||||
|
||||
def save_preset_template(self, preset_info):
|
||||
"""保存预设模板到用户指定位置"""
|
||||
try:
|
||||
# 让用户选择保存位置
|
||||
save_dir = QFileDialog.getExistingDirectory(
|
||||
self,
|
||||
f"选择保存 {preset_info['name']} 模板的位置",
|
||||
os.path.expanduser("~")
|
||||
)
|
||||
|
||||
if not save_dir:
|
||||
return
|
||||
|
||||
# 复制ioc文件到用户选择的目录
|
||||
target_path = os.path.join(save_dir, preset_info['filename'])
|
||||
|
||||
# 检查目标文件是否已存在
|
||||
if os.path.exists(target_path):
|
||||
from qfluentwidgets import Dialog
|
||||
dialog = Dialog("文件已存在", f"目标位置已存在 {preset_info['filename']},是否覆盖?", self)
|
||||
if dialog.exec() != Dialog.Accepted:
|
||||
return
|
||||
|
||||
# 复制文件
|
||||
shutil.copy2(preset_info['path'], target_path)
|
||||
|
||||
InfoBar.success(
|
||||
title="模板保存成功",
|
||||
content=f"预设模板 {preset_info['name']} 已保存到:\n{target_path}",
|
||||
parent=self,
|
||||
duration=3000
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
InfoBar.error(
|
||||
title="保存失败",
|
||||
content=f"保存预设模板失败: {str(e)}",
|
||||
parent=self,
|
||||
duration=3000
|
||||
)
|
||||
|
||||
def open_project_from_path(self, folder_path):
|
||||
"""从指定路径打开工程"""
|
||||
try:
|
||||
if not os.path.exists(folder_path):
|
||||
return
|
||||
|
||||
ioc_files = [f for f in os.listdir(folder_path) if f.endswith('.ioc')]
|
||||
if ioc_files:
|
||||
# 检查是否已存在 codeGenPage 标签页
|
||||
for i in range(self.stackedWidget.count()):
|
||||
widget = self.stackedWidget.widget(i)
|
||||
if widget is not None and widget.objectName() == "codeGenPage":
|
||||
# 如果已存在,则切换到该标签页,并更新路径显示
|
||||
if hasattr(widget, "project_path"):
|
||||
widget.project_path = folder_path
|
||||
if hasattr(widget, "refresh"):
|
||||
widget.refresh()
|
||||
self.stackedWidget.setCurrentWidget(widget)
|
||||
self.tabBar.setCurrentTab("codeGenPage")
|
||||
return
|
||||
|
||||
# 不存在则新建
|
||||
code_gen_page = CodeGenerateInterface(folder_path, self)
|
||||
self.addSubInterface(code_gen_page, "codeGenPage", "代码生成")
|
||||
self.stackedWidget.setCurrentWidget(code_gen_page)
|
||||
self.tabBar.setCurrentTab("codeGenPage")
|
||||
else:
|
||||
InfoBar.error(
|
||||
title="未找到.ioc文件",
|
||||
content="所选文件夹不是有效的CUBEMX工程目录",
|
||||
parent=self,
|
||||
duration=3000
|
||||
)
|
||||
except Exception as e:
|
||||
InfoBar.error(
|
||||
title="打开工程失败",
|
||||
content=f"打开工程失败: {str(e)}",
|
||||
parent=self,
|
||||
duration=3000
|
||||
)
|
||||
|
||||
def choose_project_folder(self):
|
||||
folder = QFileDialog.getExistingDirectory(self, "选择CUBEMX工程目录")
|
||||
if not folder:
|
||||
|
||||
@@ -637,6 +637,31 @@ class DataInterface(QWidget):
|
||||
for t in task_list:
|
||||
desc = t.get("description", "")
|
||||
desc_wrapped = "\n ".join(textwrap.wrap(desc, 20))
|
||||
|
||||
# 检查是否是预设任务
|
||||
if t.get("preset_task"):
|
||||
# 使用预设任务的代码
|
||||
preset_task_name = t["preset_task"]
|
||||
from app.tools.code_generator import CodeGenerator
|
||||
task_template_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
|
||||
preset_task_file = os.path.join(task_template_dir, f"{preset_task_name}.c")
|
||||
|
||||
if os.path.exists(preset_task_file):
|
||||
# 直接复制预设任务文件
|
||||
task_c_path = os.path.join(output_dir, f"{t['name']}.c")
|
||||
with open(preset_task_file, 'r', encoding='utf-8') as f:
|
||||
preset_code = f.read()
|
||||
|
||||
# 如果任务名称不同,需要替换函数名
|
||||
if preset_task_name != t["name"]:
|
||||
# 替换任务函数名
|
||||
preset_code = preset_code.replace(f"Task_{preset_task_name}", t["function"])
|
||||
preset_code = preset_code.replace(f" {preset_task_name} Task", f" {t['name']} Task")
|
||||
|
||||
save_with_preserve(task_c_path, preset_code)
|
||||
continue
|
||||
|
||||
# 使用默认模板生成任务代码
|
||||
context_task = {
|
||||
"task_name": t["name"],
|
||||
"task_function": t["function"],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QWidget, QScrollArea
|
||||
from qfluentwidgets import (
|
||||
BodyLabel, TitleLabel, HorizontalSeparator, PushButton, PrimaryPushButton,
|
||||
LineEdit, SpinBox, DoubleSpinBox, CheckBox, TextEdit
|
||||
LineEdit, SpinBox, DoubleSpinBox, CheckBox, TextEdit, ComboBox
|
||||
)
|
||||
from qfluentwidgets import theme, Theme
|
||||
import yaml
|
||||
@@ -76,12 +76,20 @@ class TaskConfigDialog(QDialog):
|
||||
self.add_btn = PrimaryPushButton("创建新任务")
|
||||
self.add_btn.setAutoDefault(False) # 禁止回车触发
|
||||
self.add_btn.setDefault(False)
|
||||
|
||||
# 新增:预设任务按钮
|
||||
self.preset_btn = PushButton("使用预设任务")
|
||||
self.preset_btn.setAutoDefault(False)
|
||||
self.preset_btn.setDefault(False)
|
||||
|
||||
self.del_btn = PushButton("删除当前任务")
|
||||
self.del_btn.setAutoDefault(False) # 禁止回车触发
|
||||
self.del_btn.setDefault(False)
|
||||
self.add_btn.clicked.connect(self.add_task)
|
||||
self.preset_btn.clicked.connect(self.add_preset_task)
|
||||
self.del_btn.clicked.connect(self.delete_current_task)
|
||||
btn_layout.addWidget(self.add_btn)
|
||||
btn_layout.addWidget(self.preset_btn)
|
||||
btn_layout.addWidget(self.del_btn)
|
||||
btn_layout.addStretch() # 添加/删除靠左,stretch在中间
|
||||
|
||||
@@ -135,6 +143,274 @@ class TaskConfigDialog(QDialog):
|
||||
self.task_btn_layout.addWidget(btn)
|
||||
self.task_btn_layout.addStretch()
|
||||
|
||||
def get_preset_tasks(self):
|
||||
"""获取所有可用的预设任务"""
|
||||
from app.tools.code_generator import CodeGenerator
|
||||
task_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
|
||||
preset_tasks = []
|
||||
|
||||
if not os.path.exists(task_dir):
|
||||
return preset_tasks
|
||||
|
||||
for filename in os.listdir(task_dir):
|
||||
if filename.endswith('.c') and not filename.endswith('.template'):
|
||||
task_name = os.path.splitext(filename)[0]
|
||||
preset_tasks.append(task_name)
|
||||
|
||||
return preset_tasks
|
||||
|
||||
def load_preset_task_config(self, task_name):
|
||||
"""从 yaml 配置文件中加载预设任务的配置"""
|
||||
try:
|
||||
from app.tools.code_generator import CodeGenerator
|
||||
template_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
|
||||
config_file = os.path.join(template_dir, "task.yaml")
|
||||
|
||||
if not os.path.exists(config_file):
|
||||
return None
|
||||
|
||||
with open(config_file, 'r', encoding='utf-8') as f:
|
||||
config_data = yaml.safe_load(f)
|
||||
|
||||
if config_data and task_name in config_data:
|
||||
return config_data[task_name]
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"加载预设任务配置失败: {e}")
|
||||
return None
|
||||
|
||||
def load_preset_task_code(self, task_name):
|
||||
"""加载预设任务的代码内容"""
|
||||
from app.tools.code_generator import CodeGenerator
|
||||
task_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
|
||||
task_file = os.path.join(task_dir, f"{task_name}.c")
|
||||
|
||||
if os.path.exists(task_file):
|
||||
with open(task_file, 'r', encoding='utf-8') as f:
|
||||
return f.read()
|
||||
return None
|
||||
|
||||
def add_preset_task(self):
|
||||
"""添加预设任务"""
|
||||
preset_tasks = self.get_preset_tasks()
|
||||
if not preset_tasks:
|
||||
InfoBar.warning(
|
||||
title="无预设任务",
|
||||
content="未找到可用的预设任务模板",
|
||||
parent=self,
|
||||
duration=2000
|
||||
)
|
||||
return
|
||||
|
||||
# 创建自适应主题的对话框
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle("选择预设任务")
|
||||
dialog.resize(600, 500)
|
||||
dialog.setModal(True)
|
||||
|
||||
layout = QVBoxLayout(dialog)
|
||||
layout.setContentsMargins(24, 24, 24, 24)
|
||||
layout.setSpacing(18)
|
||||
|
||||
# 固定内容区域
|
||||
fixed_content = QWidget()
|
||||
fixed_content.setFixedHeight(180) # 减少固定高度
|
||||
fixed_layout = QVBoxLayout(fixed_content)
|
||||
fixed_layout.setContentsMargins(0, 0, 0, 0)
|
||||
fixed_layout.setSpacing(18)
|
||||
|
||||
# 标题
|
||||
title_label = TitleLabel("选择预设任务模板")
|
||||
fixed_layout.addWidget(title_label)
|
||||
|
||||
# 说明文字
|
||||
desc_label = BodyLabel("选择一个预设任务模板,系统将自动复制相应的代码和配置")
|
||||
fixed_layout.addWidget(desc_label)
|
||||
|
||||
fixed_layout.addWidget(HorizontalSeparator())
|
||||
|
||||
# 任务选择
|
||||
select_layout = QHBoxLayout()
|
||||
select_layout.setSpacing(12)
|
||||
|
||||
select_label = BodyLabel("预设任务:")
|
||||
preset_combo = ComboBox()
|
||||
preset_combo.addItems(preset_tasks)
|
||||
preset_combo.setCurrentIndex(0)
|
||||
preset_combo.setMinimumWidth(160)
|
||||
|
||||
select_layout.addWidget(select_label)
|
||||
select_layout.addWidget(preset_combo)
|
||||
select_layout.addStretch()
|
||||
|
||||
fixed_layout.addLayout(select_layout)
|
||||
|
||||
# 参数信息 - 单行显示
|
||||
params_layout = QHBoxLayout()
|
||||
params_layout.setSpacing(24) # 适中的间距
|
||||
|
||||
self.info_freq = BodyLabel("")
|
||||
self.info_delay = BodyLabel("")
|
||||
self.info_stack = BodyLabel("")
|
||||
self.info_ctrl = BodyLabel("")
|
||||
|
||||
self.info_freq.setMinimumWidth(120)
|
||||
self.info_delay.setMinimumWidth(100)
|
||||
self.info_stack.setMinimumWidth(120)
|
||||
self.info_ctrl.setMinimumWidth(100)
|
||||
|
||||
params_layout.addWidget(self.info_freq)
|
||||
params_layout.addWidget(self.info_delay)
|
||||
params_layout.addWidget(self.info_stack)
|
||||
params_layout.addWidget(self.info_ctrl)
|
||||
params_layout.addStretch()
|
||||
|
||||
fixed_layout.addLayout(params_layout)
|
||||
fixed_layout.addStretch() # 在固定区域内保持紧凑
|
||||
|
||||
layout.addWidget(fixed_content)
|
||||
|
||||
# 弹性描述区域
|
||||
desc_layout = QVBoxLayout()
|
||||
desc_layout.setSpacing(8)
|
||||
|
||||
desc_title = BodyLabel("描述:")
|
||||
desc_title.setStyleSheet("font-weight: bold;")
|
||||
desc_layout.addWidget(desc_title)
|
||||
|
||||
self.preview_desc = TextEdit()
|
||||
self.preview_desc.setReadOnly(True)
|
||||
self.preview_desc.setMinimumHeight(60) # 最小高度
|
||||
desc_layout.addWidget(self.preview_desc)
|
||||
|
||||
layout.addLayout(desc_layout, stretch=1) # 弹性伸缩
|
||||
|
||||
# 按钮区域
|
||||
layout.addWidget(HorizontalSeparator())
|
||||
btn_layout = QHBoxLayout()
|
||||
btn_layout.addStretch()
|
||||
|
||||
cancel_btn = PushButton("取消")
|
||||
ok_btn = PrimaryPushButton("确定添加")
|
||||
|
||||
cancel_btn.clicked.connect(dialog.reject)
|
||||
ok_btn.clicked.connect(dialog.accept)
|
||||
|
||||
btn_layout.addWidget(cancel_btn)
|
||||
btn_layout.addWidget(ok_btn)
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
# 预览更新函数
|
||||
def update_preview():
|
||||
selected = preset_combo.currentText()
|
||||
self.update_preset_preview(selected)
|
||||
|
||||
preset_combo.currentTextChanged.connect(update_preview)
|
||||
|
||||
# 存储对话框状态
|
||||
self.current_preview_dialog = dialog
|
||||
self.preview_combo = preset_combo
|
||||
|
||||
# 初始化预览
|
||||
if preset_tasks:
|
||||
update_preview()
|
||||
|
||||
# 显示对话框
|
||||
if dialog.exec() == QDialog.Accepted:
|
||||
selected_task = preset_combo.currentText()
|
||||
self.save_form()
|
||||
new_idx = len(self.tasks)
|
||||
|
||||
# 从配置文件加载预设任务参数
|
||||
config = self.load_preset_task_config(selected_task)
|
||||
if config:
|
||||
new_task = self._make_task_obj({
|
||||
"name": config.get("name", selected_task),
|
||||
"frequency": config.get("frequency", 500),
|
||||
"delay": config.get("delay", 0),
|
||||
"stack": config.get("stack", 256),
|
||||
"description": config.get("description", ""),
|
||||
"freq_control": config.get("freq_control", True)
|
||||
})
|
||||
else:
|
||||
new_task = self._make_task_obj({"name": selected_task})
|
||||
|
||||
new_task["preset_task"] = selected_task
|
||||
|
||||
self.tasks.append(new_task)
|
||||
self.current_index = new_idx
|
||||
self.refresh_task_btns()
|
||||
self.show_task_form(self.tasks[self.current_index])
|
||||
|
||||
InfoBar.success(
|
||||
title="添加成功",
|
||||
content=f"已添加预设任务:{selected_task}",
|
||||
parent=self,
|
||||
duration=2000
|
||||
)
|
||||
|
||||
def update_preset_preview(self, task_name):
|
||||
"""更新预设任务预览信息"""
|
||||
# 从配置加载信息
|
||||
config = self.load_preset_task_config(task_name)
|
||||
if config:
|
||||
self.info_freq.setText(f"频率: {config.get('frequency', 500)} Hz")
|
||||
self.info_delay.setText(f"延时: {config.get('delay', 0)} ms")
|
||||
self.info_stack.setText(f"堆栈: {config.get('stack', 256)} Bytes")
|
||||
freq_ctrl = "启用" if config.get('freq_control', True) else "禁用"
|
||||
self.info_ctrl.setText(f"频率控制: {freq_ctrl}")
|
||||
|
||||
description = config.get('description', f'预设任务:{task_name}')
|
||||
self.preview_desc.setText(description)
|
||||
else:
|
||||
self.info_freq.setText("频率: 500 Hz")
|
||||
self.info_delay.setText("延时: 0 ms")
|
||||
self.info_stack.setText("堆栈: 256 Bytes")
|
||||
self.info_ctrl.setText("频率控制: 启用")
|
||||
self.preview_desc.setText(f"预设任务:{task_name}")
|
||||
|
||||
def on_preset_task_selected(self, task_name):
|
||||
"""预设任务选择事件(向后兼容)"""
|
||||
pass
|
||||
|
||||
def get_preset_task_description(self, task_name):
|
||||
"""获取预设任务的描述信息"""
|
||||
# 首先尝试从 yaml 配置中获取描述
|
||||
config = self.load_preset_task_config(task_name)
|
||||
if config and 'description' in config:
|
||||
return f"预设任务:{task_name}\n\n{config['description']}\n\n频率控制:{'启用' if config.get('freq_control', True) else '禁用'}\n运行频率:{config.get('frequency', 500)} Hz\n堆栈大小:{config.get('stack', 256)} Bytes\n初始延时:{config.get('delay', 0)} ms"
|
||||
|
||||
# 如果没有配置文件,则从代码注释中提取
|
||||
try:
|
||||
task_code = self.load_preset_task_code(task_name)
|
||||
if task_code:
|
||||
# 尝试从注释中提取描述
|
||||
lines = task_code.split('\n')
|
||||
description_lines = []
|
||||
in_comment = False
|
||||
|
||||
for line in lines[:20]: # 只检查前20行
|
||||
line = line.strip()
|
||||
if line.startswith('/*'):
|
||||
in_comment = True
|
||||
if 'Task' in line and line != '/*':
|
||||
description_lines.append(line.replace('/*', '').strip())
|
||||
continue
|
||||
elif line.endswith('*/'):
|
||||
in_comment = False
|
||||
break
|
||||
elif in_comment and line and not line.startswith('*'):
|
||||
description_lines.append(line)
|
||||
|
||||
if description_lines:
|
||||
return '\n'.join(description_lines)
|
||||
else:
|
||||
return f"预设任务:{task_name}\n这是一个预定义的任务模板,包含完整的实现代码。"
|
||||
else:
|
||||
return f"预设任务:{task_name}\n无法读取任务描述。"
|
||||
except Exception as e:
|
||||
return f"预设任务:{task_name}\n读取描述时出现错误:{str(e)}"
|
||||
|
||||
def add_task(self):
|
||||
self.save_form()
|
||||
new_idx = len(self.tasks)
|
||||
@@ -302,5 +578,10 @@ class TaskConfigDialog(QDialog):
|
||||
}
|
||||
if freq_ctrl:
|
||||
task["frequency"] = freq
|
||||
|
||||
# 保留预设任务信息
|
||||
if "preset_task" in t:
|
||||
task["preset_task"] = t["preset_task"]
|
||||
|
||||
tasks.append(task)
|
||||
return tasks
|
||||
Reference in New Issue
Block a user