分支
用户 tuqin <tuqin@tuqin.cn>
星期四, 十一月 5, 2026 16:34 +0800
提交者 tuqin <tuqin@tuqin.cn>
星期四, 十一月 5, 2026 16:34 +0800
提交da1328913c8bfbb5bbab83c834556a09cad07d9f
目录 a6db756b46c8179ce2f19472a10b9da863da8d2c 目录 | zip | gz
上一版本 5e2501496943a7991eb11b1e9bccbf64631719f6 查看 | 对比
fix(hrm): 考勤规则打开定位后点确认报 Cannot read properties of null (reading Map)

两个叠加的 bug:

一、百度地图 SDK 根本没加载上(主因)
loadBaiduMapSdk 用的是 api?v=1.0&type=webgl&ak=xxx&callback=xxx 这个地址,
它返回的是一段 document.write 包装的 getscript 引用。
而脚本是通过 document.body.append(script) 动态插入的,
浏览器会拦截动态脚本里的 document.write(Chrome 会提示
A parser-blocking cross site script invoked via document.write was NOT executed),
于是真正的 SDK 从未执行、window.BMapGL 一直是空。
但 api 的 callback 依然会被调用,调用方误判为加载成功,接着 new BMapGL.Map 就抛
Cannot read properties of null (reading Map)。
修复:直连 api.map.baidu.com/getscript 地址,用 script 的 load 事件判断就绪,
并额外校验 window.BMapGL 是否真的挂载。

二、异步初始化与组件卸载竞态
用户打开定位开关后立刻点确认,弹窗关闭导致 LocationMapPicker 卸载、地图容器从 DOM 移除,
但 await loadBaiduMapSdk 之后仍会执行 new BMapGL.Map(mapContainer.value),
此时容器已是 null,同样报该错误。
修复:新增 disposed 标志,每次 await 后检查组件是否已卸载、容器是否存在;
卸载时先置标志再销毁实例,并把 destroy 包在 try/catch 里。

顺带修正:script 的事件名写成 onerror 永远不会触发,改为 error。

实测:getscript 直连返回 HTTP 200、875KB 真实 SDK 且含 BMapGL 定义;
构建产物已无 api?v=1.0 地址,地图 chunk 仅含 getscript。
已修改2个文件
97 ■■■■■ 文件已修改
src/components/map/src/utils.ts 57 ●●●●● 对比 | 查看 | 原始文档 | blame | 历史
src/views/hrm/attendance/rule/modules/location-map-picker.vue 40 ●●●●● 对比 | 查看 | 原始文档 | blame | 历史