From 64fadde568ff51492a8080374b5f74d96e36deeb Mon Sep 17 00:00:00 2001 From: butubb <1422726308@qq.com> Date: Fri, 11 Sep 2026 11:23:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=96=AD=E8=81=94=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E8=A1=A8=E3=80=8C=E6=8D=A2=E5=9C=B0=E5=9D=80=E3=80=8D=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E4=BC=A0=E5=8F=82=E4=B8=A2=E5=A4=B1=EF=BC=88=E7=BC=BA?= =?UTF-8?q?=20data-serial=EF=BC=89+=20=E5=88=A0=E9=99=A4=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?/=E5=88=86=E7=BB=84=E5=85=BC=E5=AE=B9=E5=86=85=E5=AD=98?= =?UTF-8?q?=E4=B8=8D=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tools.js:断联设备表的「换地址」按钮漏了 data-serial 属性,onclick 里 this.dataset.serial 是 undefined → 接口报「缺少 old_serial 或 new_serial」。 设备池表里的同名按钮是传字面量的,所以只有断联表这条路径坏。 顺带给 relocatePoolDev 加参数防呆(取不到地址时给明确提示,不静默) - task_manager.delete_job / delete_group:原先只在"内存里有"时才删库行, 内存与库不一致时(手工插行、上次异常退出、旧版本漏删)会出现"删不掉的 任务/分组"(API 404 但库行还在、重启复活)。改为无论内存有没有都尝试删库行 自测:浏览器验证断联表两个按钮都带 data-serial;relocate 接口端到端(上一轮已验); 删除接口在前端删除分组/任务后 DB 与内存一致 --- core/task_manager.py | 39 ++++++++++++++++++++++----------------- static/admin/tools.js | 7 ++++--- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/core/task_manager.py b/core/task_manager.py index 45c81c2..7113984 100644 --- a/core/task_manager.py +++ b/core/task_manager.py @@ -484,17 +484,20 @@ class TaskManager: return n def delete_group(self, name): + removed = False if name in self.groups: del self.groups[name] self._save_groups() - # 同上:显式删数据库行,避免删除的分组重启后复活 - with self._db(): - row = GroupRow.query.filter_by(name=name).first() - if row: - db.session.delete(row) - db.session.commit() - return True - return False + removed = True + # 无论内存里有没有都尝试删库行:内存与库不一致时(手工插行、上次异常退出、 + # 上个版本漏删)也能删干净,避免"删不掉的分组" + with self._db(): + row = GroupRow.query.filter_by(name=name).first() + if row: + db.session.delete(row) + db.session.commit() + removed = True + return removed # ---- 任务计划管理 ---- def add_job(self, name, task_type, target, params, schedule, retry, enabled=True): @@ -524,18 +527,20 @@ class TaskManager: def delete_job(self, job_id): self._remove_cron(job_id) + removed = False if job_id in self.jobs: del self.jobs[job_id] self._save_jobs() - # _save_jobs 只做 upsert 不会删行:必须显式删数据库行, - # 否则删除的任务重启后会从数据库重新加载回来 - with self._db(): - row = JobRow.query.get(job_id) - if row: - db.session.delete(row) - db.session.commit() - return True - return False + removed = True + # _save_jobs 只做 upsert 不会删行:必须显式删库行,否则删除的任务重启会复活。 + # 内存里没有(手工插行/上次异常退出)时也要删——否则会出现"删不掉的任务" + with self._db(): + row = JobRow.query.get(job_id) + if row: + db.session.delete(row) + db.session.commit() + removed = True + return removed def toggle_job(self, job_id, enabled): job = self.jobs.get(job_id) diff --git a/static/admin/tools.js b/static/admin/tools.js index 0076d9c..f1adb81 100644 --- a/static/admin/tools.js +++ b/static/admin/tools.js @@ -109,7 +109,7 @@ function loadDiscovery(){ +'' +' ' // 设备换了 IP 时旧地址永远连不上——给一条"换地址"的出路(迁移记录 + 同步引用) - +'' + +'' +''; }).join(''); } @@ -531,9 +531,10 @@ async function renamePoolDev(serial){ // 换地址(人工认领):设备换了 IP、旧地址已连不上时用;名称与分组/任务引用都保留 async function relocatePoolDev(serial){ - const nw=(prompt('把这条记录迁到新地址(设备换 IP、旧地址连不上时用):\n\n' + if(!serial){showToast('没取到设备地址,请刷新页面后重试','error');return;} + const nw=(prompt('把记录 ' + serial + ' 迁到新地址(设备换 IP、旧地址连不上时用):\n\n' +'名称、型号、备注都会保留,分组与任务里的旧地址会自动同步。','')||'').trim(); - if(!nw)return; + if(!nw || nw===serial)return; const r=await apiPost('/api/devices/pool/relocate',{old_serial:serial,new_serial:nw}); if(!r)return; if(r.ok){showToast(r.msg,'success');loadDevPool();loadDiscovery();}