Hotfix release available: 2026-07-14c "Mort".
upgrade now! [57.3] (what's this?)
研发任务管理系统h5:冷启动文件
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| 研发任务管理系统h5:冷启动文件 [2026/10/14 04:09] – 4.64 修复弹窗被导航遮挡 172.17.0.1 | 研发任务管理系统h5:冷启动文件 [2026/10/23 02:08] (current) – 4.72 评审会四按钮失效根因 172.17.0.1 | ||
|---|---|---|---|
| Line 155: | Line 155: | ||
| **验证**:服务端与页面均已生效(`.modal{z-index: | **验证**:服务端与页面均已生效(`.modal{z-index: | ||
| + | |||
| + | ====== 4.65 修复:提示条 toast 被底部导航遮挡(2026-10-10) ====== | ||
| + | |||
| + | **问题**(用户截图):页面底部弹的深色圆角提示条**只露出上半截**,下半截被白色底部导航栏吃掉。 | ||
| + | |||
| + | **根因(层叠 + 定位双重问题)** | ||
| + | | 属性 | 原值 | 问题 | | ||
| + | |---|---|---| | ||
| + | | `.toast` z-index | **200** | ❌ 低于 `.tabbar` 的 **999** → 被压在导航栏之下 | | ||
| + | | `.toast` bottom | **24px** | ❌ 正好落在导航栏占据的区域内(导航栏高约 33~53px)| | ||
| + | |||
| + | 两个问题叠加 → 重叠部分被不透明导航栏盖住,看起来就是" | ||
| + | |||
| + | **修复(`rd_h5.html`)** | ||
| + | < | ||
| + | .toast{ ... bottom: | ||
| + | </ | ||
| + | - bottom 86px > 导航栏高度(约 33~53px)→ 提示条整体位于导航栏之上 | ||
| + | - z-index 1200 > 999 → 即使重叠也显示在导航之上 | ||
| + | |||
| + | **实测验证(浏览器真实渲染)** | ||
| + | | 项 | 数值 | | ||
| + | |---|---| | ||
| + | | 视口高 / 导航栏高 | 577px / 33px(测试页同款导航;研发页导航含 20px 图标更高,约 53px)| | ||
| + | | 提示条高度 | 39px | | ||
| + | | **修复后**(bottom 86px)| 提示条底边距视口 **86px**,与导航栏顶边**零重叠** → 完整可见 ✅ | | ||
| + | | **修复前**(bottom 24px)| 底边 y=553,导航顶边 y=544 → **被覆盖 9px**(研发页导航更高 → 覆盖约 29px,接近整条)❌ | | ||
| + | | 截图对比 | 上方(新值)完整;下方(旧值)被导航截断 —— 与用户截图一致 ✅ | | ||
| + | |||
| + | **其他页面排查**:test/ | ||
| + | |||
| + | ====== 4.66 修复:项目下拉缺新增项目(银穗Y1 等)(2026-10-10) ====== | ||
| + | |||
| + | **问题**:项目「银穗Y1」在项目管理面板显示" | ||
| + | |||
| + | **排查** | ||
| + | | 检查项 | 结果 | | ||
| + | |---|---| | ||
| + | | `projects.json` | ✅ 已有「银穗Y1」(共 19 项)| | ||
| + | | `GET / | ||
| + | | `/rd/` 缓存头 | ✅ no-store(不是缓存问题)| | ||
| + | | **`loadProjects()` 调用点** | ❌ **只在 `addOwnerMore()` 里被调用;页面初始化流程从未调用** | | ||
| + | |||
| + | **根因**:`PROJ_LIST` 的默认值是**硬编码的 13 项**(不含 M10/ | ||
| + | |||
| + | **修复(`rd_h5.html`)** | ||
| + | < | ||
| + | function load(){ | ||
| + | loadProjects(true); | ||
| + | ... | ||
| + | } | ||
| + | function loadProjects(noRefresh){ | ||
| + | fetch('/ | ||
| + | if(d&& | ||
| + | PROJ_LIST=d.projects; | ||
| + | renderProj(); | ||
| + | refreshProjSelects(); | ||
| + | if(!noRefresh){ projRefreshUI(); | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | function refreshProjSelects(){ ... } // 新增 | ||
| + | </ | ||
| + | |||
| + | **行为验证(Node 里跑 rd_h5.html 的真实函数 + stub DOM/ | ||
| + | | 场景 | 结果 | | ||
| + | |---|---| | ||
| + | | 修复前(硬编码默认列表)| 下拉 **13 项**,含「银穗Y1」:**❌ 没有** ← 复现用户问题 | | ||
| + | | 修复后(初始化调 `loadProjects(true)`)| PROJ_LIST = **19 项**(末尾 云枢AV1, 云联LR1, **银穗Y1**)| | ||
| + | | 筛选框 `projDL` | ✅ 含「银穗Y1」(19 项)| | ||
| + | | 新增任务表单 `#aProj` | ✅ 含「银穗Y1」| | ||
| + | | 编辑任务表单 `#mProj` | ✅ 含「银穗Y1」| | ||
| + | |||
| + | **同类排查**:`test.html`(初始化顶层调用 `loadProjects()` ✅)、`review.html`(line 137 初始化调用 ✅)、`rd_store.py`(不使用该下拉)→ 仅 `rd_h5.html` 有此问题。 | ||
| + | |||
| + | ====== 4.67 修复:添加附件后" | ||
| + | |||
| + | **现象**(用户报):在任务详情里上传附件后点保存,任务修改没有保存 / 附件不见了。 | ||
| + | |||
| + | **排查**:后端全部正常(`/ | ||
| + | |||
| + | ===== 缺陷① 更新内容留空时,附件与耗时被静默丢弃(主因) ===== | ||
| + | `saveTask()` 里判断是 `if(noteText){ ...POST note(带附件)... } else { 只保存任务字段 }` —— | ||
| + | **只有填了" | ||
| + | - 附件已上传成功(UI 也显示了文件名)→ 但**不落库** ❌ | ||
| + | - 耗时也不记录 ❌ | ||
| + | 用户截图正是这个状态:`更新 [空] | 耗时(时) [空] | 添加文件 📎 | 📎 YQ销售产品…` | ||
| + | |||
| + | ===== 缺陷② 上传中点保存会丢附件 ===== | ||
| + | 上传是异步的,`mAttUrl` 还没赋值就点保存 → 附件同样丢失。 | ||
| + | |||
| + | **修复(`rd_h5.html`)** | ||
| + | < | ||
| + | var mAttNameCur=''; | ||
| + | var mAttPending=null; | ||
| + | function waitAtt(cb){ if(!mAttPending) return false; toast(' | ||
| + | |||
| + | // saveTask:① 上传中先等待 ② 只要 文本/ | ||
| + | if(waitAtt(function(){ saveTask(id); | ||
| + | var hasExtra=!!(mAttUrl||(!isNaN(dur2)&& | ||
| + | if(noteText||hasExtra){ | ||
| + | var nb={text: noteText||(mAttUrl? | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | - `uploadAtt()`:上传中显示「📎 文件名(上传中…)」、成功记录 `mAttUrl+mAttNameCur`、失败给 toast、用 `.catch` 兜底 | ||
| + | - `markDone()`(标记完成)同步应用相同的等待与判定 | ||
| + | |||
| + | **浏览器实测(真实页面 + 真实文件上传)** | ||
| + | | 场景 | 修复前 | 修复后 | | ||
| + | |---|---|---| | ||
| + | | 填了更新内容 + 附件 → 保存 | ✅ 正常 | ✅ 正常(未回归)| | ||
| + | | **只加附件、更新留空 → 保存** | ❌ 无 `/note` 请求,附件丢失 | ✅ `/note` 200,附件落库,记录文案「📎 附件:文件名」| | ||
| + | | **上传中点保存** | ❌ 附件丢失 | ✅ 提示" | ||
| + | | 只填耗时不填文字 | ❌ 耗时丢失 | ✅ 记录「(记录耗时)」+ 耗时 ✅ | | ||
| + | |||
| + | **清理**:验证用的临时任务与测试附件已删除(任务数回到 106);用户自己上传的 3 个 xlsx 保留未动。 | ||
| + | |||
| + | ====== 4.68 评审会:新增「会议现场照片」+ 去掉「记录员」(2026-10-22) ====== | ||
| + | |||
| + | ===== ① 会议现场照片 ===== | ||
| + | **数据**:`meetings` 表新增 `photos TEXT DEFAULT '' | ||
| + | **接口**:`POST / | ||
| + | 上传复用已有 `POST / | ||
| + | |||
| + | **前端**(`review.html` 会议编辑表单,签名行下方): | ||
| + | < | ||
| + | 会议现场照片 | ||
| + | [缩略图 74×74] × N ← 点图可放大,右上角 ✕ 单张删除 | ||
| + | </ | ||
| + | - `upMeetPhoto()` 上传后写入 `CUR.photos` 并即时刷新缩略图(提示" | ||
| + | - `delMeetPhoto()` 从列表移除 | ||
| + | - `collectForm()` 带上 `photos` → 新建/ | ||
| + | |||
| + | ===== ② 去掉「记录员」 ===== | ||
| + | - 要点记录表单里 **删除「记录人员」输入行**(原 `p_user` + 👥 选择器) | ||
| + | - **数据库 `points.p_user` 字段保留**,保存时沿用旧值(`collectPoints()` 里若无输入框则取 `p.p_user`)→ **历史数据不丢** | ||
| + | - 清理无用的 `pickPointUser()` 选择器;把共用的选择辅助函数改名 **`pickIntoBtn()`** 供「记录负责人」使用(重要:原 `pickOwner` 依赖它,改名时必须同步) | ||
| + | - 保留:记录时间 / 记录内容 / 记录负责人 / 记录图片 / 附件 / 状态 | ||
| + | |||
| + | ===== 验证 ===== | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | `photos` 列迁移 | ✅ 自动加列成功 | | ||
| + | | 上传 2 张 → 保存 → 回读 | ✅ `photos` 两个 URL、顺序正确、文件真实落盘 | | ||
| + | | 要点 `p_user` 历史值 | ✅ 保留(前端不再显示)| | ||
| + | | 浏览器表单 | ✅ 含「会议现场照片」+ 拍照/ | ||
| + | | 要点区 | ✅ 记录时间/ | ||
| + | | JS 报错 | ✅ 无 | | ||
| + | | 真实数据 | ✅ 14 个真实会议完好;临时验证会议与测试图片已清理 | | ||
| + | |||
| + | ⚠️ **踩坑记录**:改 UPDATE 语句时先加了 `photos=?` 占位符但参数没同步插入 → `sqlite3.ProgrammingError: | ||
| + | **教训(已在纪律中)**:改 SQL 必须核对**占位符数量 = 参数个数**,改完立即用临时数据跑一次保存。 | ||
| + | |||
| + | ====== 4.69 修复:评审会「无法导出报告」(2026-10-22) ====== | ||
| + | |||
| + | **现象**:评审会点「网页报告 / Word版 / PDF版」没有反应,导不出来。 | ||
| + | |||
| + | **排查**:服务端三种格式都正常 —— `GET / | ||
| + | |||
| + | **根因(两个)** | ||
| + | 1. **弹窗被拦截**:导出流程是 `fetch(保存) → .then(() => window.open(url))`。 | ||
| + | | ||
| + | 2. **失败无提示**:保存失败时 `.then(d => { if(d.ok) window.open(...) })` 没有 else → | ||
| + | | ||
| + | |||
| + | **修复(`review.html`)** | ||
| + | < | ||
| + | function _reportFlow(fmt){ | ||
| + | // 点击瞬间同步开占位窗口(同步调用不算弹窗) | ||
| + | var w = window.open(' | ||
| + | fetch(保存会议).then(d => { | ||
| + | if(!d.ok){ w.close(); toast(' | ||
| + | w.location.href = url; // 让占位窗口跳转 | ||
| + | // 开不出窗(微信)→ location.href 当前页兜底 | ||
| + | }).catch(() => { w.close(); toast(' | ||
| + | } | ||
| + | function genReport(){ _reportFlow('' | ||
| + | function genExport(fmt){ _reportFlow(fmt); | ||
| + | </ | ||
| + | - 微信环境导出 Word/PDF 会额外提示:**「若打不开请点右上角「⋯」→「在浏览器打开」」** | ||
| + | - 网页报告 / Word / PDF 三条路径统一走 `_reportFlow()` | ||
| + | |||
| + | **验证** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 服务端 Web 报告 | ✅ 200,4091 字节 HTML | | ||
| + | | 服务端 Word | ✅ 200,2.5 MB,`Microsoft Word 2007+` | | ||
| + | | 服务端 PDF | ✅ 200,143 KB,6 页 | | ||
| + | | 前端三种格式 | ✅ 跳转 URL 正确(`/ | ||
| + | | 失败路径(会议不存在)| ✅ toast「导出失败:不存在」+ 占位窗口关闭 + **不误跳转** | | ||
| + | | JS 错误 | ✅ 无 | | ||
| + | | 真实数据 | ✅ 14 个真实会议完好;临时验证会议已删 | | ||
| + | |||
| + | ⚠️ **同源教训**:凡" | ||
| + | |||
| + | ====== 4.70 评审会:去签名 + 修「照片没保存/ | ||
| + | |||
| + | 用户反馈三症状:**上传的现场照片没保存住**、**三种报告都导不出**、签名功能要去掉。 | ||
| + | |||
| + | ===== ★ 根因:`/ | ||
| + | < | ||
| + | 修复前 / | ||
| + | 修复后 / | ||
| + | pragma: no-cache | expires: 0 | ||
| + | </ | ||
| + | `no-cache` 只是" | ||
| + | 所以:照片" | ||
| + | |||
| + | ===== ① 去掉手写签名 ===== | ||
| + | - 表单去掉「与会人员签名」行;`collectForm()` 不再提交 `signatures` | ||
| + | - Web / Word / PDF 报告去掉 `_sig_block()` / `_sig_docx()` 签名块 | ||
| + | - **数据库 `meetings.signatures` 字段保留**(历史数据不删,不再显示) | ||
| + | |||
| + | ===== ② 导出加固 ===== | ||
| + | - **微信内不再 `window.open`**(必被拦截)→ 保存成功后当前页 `location.href` 跳转 | ||
| + | - 非微信:点击时同步开占位窗口,保存成功后让该窗口跳转(避免异步弹窗被拦) | ||
| + | - 保存失败 → 明确 toast「导出失败:原因」并关闭占位窗口 | ||
| + | |||
| + | ===== 完整实测(临时会议,全流程真实操作) ===== | ||
| + | | 步骤 | 结果 | | ||
| + | |---|---| | ||
| + | | 表单含「会议现场照片」 | ✅ | | ||
| + | | 签名行已消失 | ✅ | | ||
| + | | 真实 file input 上传照片 | ✅ `CUR.photos` 有值、缩略图渲染 1 张 | | ||
| + | | 点保存 | ✅ toast「✅ 已保存」,5 个写请求 0 错误 | | ||
| + | | 回读数据库 | ✅ **photos 已落库**、议题/ | ||
| + | | 三种报告 | ✅ Web 1854B / Word 35KB / PDF 38KB,全部 200 | | ||
| + | | 真实会议 # | ||
| + | | JS 错误 | ✅ 无 | | ||
| + | | 收尾 | 临时会议 #28 + 测试图片已删除,14 个真实会议完好 | | ||
| + | |||
| + | ⚠️ **教训**:新增功能后如果用户" | ||
| + | `/test/` `/rd/` `/store/` `/family/` `/ | ||
| + | |||
| + | ====== 4.71 评审会导出:彻底去掉弹窗(修 Windows「获取打开此' | ||
| + | |||
| + | **现象**(用户截图):**电脑**上点「网页报告/ | ||
| + | > 获取打开此' | ||
| + | |||
| + | **原因**:4.69 为了绕开" | ||
| + | `about: | ||
| + | |||
| + | **定稿方案:完全不用弹窗** | ||
| + | < | ||
| + | // 保存会议 → 成功后当前页跳转 | ||
| + | fetch(保存).then(d => { if(!d.ok){toast(' | ||
| + | </ | ||
| + | | 格式 | 行为 | | ||
| + | |---|---| | ||
| + | | 网页报告(text/ | ||
| + | | Word/ | ||
| + | |||
| + | - 微信环境保留提示:导 Word/PDF 若无下载 →「点右上角「⋯」→「在浏览器打开」」 | ||
| + | - 缩略图的 `window.open(this.src)`(看大图)是 http 地址,不受影响,保留 | ||
| + | |||
| + | **实测** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 网页报告 | ✅ `window.open` 调用 **0 次**,页面成功跳到 `/ | ||
| + | | Word | ✅ `window.open` 0 次、下载触发、页面停留原地址 | | ||
| + | | PDF | ✅ 同上 | | ||
| + | | 失败路径 | ✅ toast「导出失败:原因」| | ||
| + | | JS 错误 | ✅ 无 | | ||
| + | |||
| + | ⚠️ **教训**:不要再为了" | ||
| + | Windows 会当外部链接处理。**同页跳转(`location.href`)+ 服务端 attachment 头** 是跨平台最稳的做法。 | ||
| + | |||
| + | ====== 4.72 ★评审会「四个按钮全部失效」根因(我引入的 bug)+ 三处加固(2026-10-23) ====== | ||
| + | |||
| + | **现象**:会议里 💾保存 / 📄网页报告 / 📝Word版 / 📕PDF版 **全部点了没反应**; | ||
| + | 手机端更是「没有任何提示,就是不生成报告」。 | ||
| + | |||
| + | **★ 真根因(自查出的自造 bug)** | ||
| + | 4.70 去掉「记录人员」输入框时,`collectPoints()` 里写成了: | ||
| + | < | ||
| + | p_user: | ||
| + | // ↑ 这个 p 在 forEach(function(el){}) 里根本不存在 | ||
| + | </ | ||
| + | → 点任一按钮 → `Uncaught ReferenceError: | ||
| + | **连 fetch 都没发出、toast 也没弹** → 四个按钮静默全废(保存/ | ||
| + | |||
| + | **修复** | ||
| + | < | ||
| + | document.querySelectorAll('# | ||
| + | var _pu=(CUR_POINTS[i]&& | ||
| + | ... | ||
| + | }); | ||
| + | </ | ||
| + | |||
| + | **为什么上一轮测试没抓到**:测试用的是**空会议**(要点 0 条)→ `forEach` 根本没执行 → 没报错。 | ||
| + | 教训:**测保存/ | ||
| + | |||
| + | **顺带修的三处** | ||
| + | 1. `new_meeting`(继承会议)500:`p.get(" | ||
| + | 2. 页面顶部显示版本号 **v2026-10-23** → 一眼确认手机是否加载新版本 | ||
| + | 3. 新增**全局 error 监听** → JS 报错时明确 toast「⚠️ 页面脚本错误:…」,不再静默失效 | ||
| + | |||
| + | **实测(继承真实会议 #3 的临时会议,3 条真实要点,真点击按钮)** | ||
| + | | 按钮 | 结果 | | ||
| + | |---|---| | ||
| + | | 💾 保存 | ✅ toast「✅ 已保存」,`POST / | ||
| + | | 📝 Word版 | ✅ toast「📝 正在生成 Word…」+ 200,页面停留(下载)| | ||
| + | | 📕 PDF版 | ✅ toast「📕 正在生成 PDF…」+ 200,页面停留 | | ||
| + | | 📄 网页报告 | ✅ 当前页跳到 `/ | ||
| + | | JS 错误 | ✅ 0 个 | | ||
| + | | 数据 | ✅ 3 条要点内容与库内记录人员全部保留 | | ||
| + | | 真实会议 # | ||
| + | |||
| + | ⚠️ **手机端 Word/PDF 说明**:微信内置浏览器**不支持下载 docx/ | ||
| + | 请在微信里点右上角「⋯」→「在浏览器打开」,再导出即可;网页报告在微信用可以直接看。 | ||
| ====== 5. 钉钉请假同步(2026-08-31) ====== | ====== 5. 钉钉请假同步(2026-08-31) ====== | ||
研发任务管理系统h5/冷启动文件.1791950963.txt.gz · Last modified: by 172.17.0.1
