Admin:修复拖选密码时弹窗意外关闭 #56

Closed
opened 2026-08-09 16:29:52 +08:00 by ila · 2 comments
Owner

基本信息

  • 状态:已完成
  • 类型:缺陷
  • 父级大工单:#14
  • 所属 MVP / 版本:#15 Admin 四模块可用闭环
  • 阶段:Admin 登录与最小账号管理

要解决什么

在用户管理的创建/重置密码弹窗中,从密码输入框内按住鼠标拖选文字,指针移到弹窗外的灰色遮罩后松开,弹窗会意外关闭,已输入内容丢失。

复现步骤:

  1. 管理员进入用户管理,打开新增采购员或重置密码弹窗。
  2. 在密码框输入内容。
  3. 从输入框内按住鼠标拖选,移动到弹窗外灰色区域后松开。
  4. 实际:浏览器把合成的 click 目标设为遮罩,公共弹窗逻辑关闭弹窗。
  5. 期望:拖选不关闭弹窗;只有真正从遮罩开始并在遮罩结束的点击才关闭。

根因位于 admin/static/js/app.js 的公共弹窗逻辑:只判断 click.target === modal,没有判断手势从哪里开始。该问题会影响所有复用公共遮罩逻辑的弹窗。

做什么 / 不做什么

  • 做:记录 pointerdown 是否发生在遮罩本身;只有按下和最终 click 都在遮罩时关闭。
  • 做:保留点击关闭按钮、取消按钮、Esc 和直接点击遮罩关闭。
  • 做:用真实浏览器覆盖输入框拖选、直接点击遮罩、显式按钮和 Esc。
  • 做:更新 Admin UI 规范,记录遮罩拖选不得误关闭。
  • 不做:不改变表单校验、密码规则、提交行为或服务端接口。
  • 不做:不引入前端框架、npm 或新依赖。
  • 不做:不增加未保存内容确认弹窗。

怎么做

  1. 在每个 .modal-backdrop 上监听 pointerdown,记录本次指针手势是否从遮罩开始。
  2. click 时:
    • data-modal-close 仍无条件关闭;
    • 只有 e.target === modal 且本次手势从遮罩开始才关闭;
    • 从输入框/弹窗内容开始拖到遮罩的 click 不关闭。
  3. pointercancel 清理状态,避免取消的手势污染下一次操作。
  4. 用 Chrome 最小交互测试验证四类关闭行为,并运行 Go 全量回归与 Go 1.23.0 验证。

预计修改:

  • admin/static/js/app.js
  • admin/main_test.go(静态回归守卫)
  • docs/admin/05-ui-specification.md

验收标准

  • 从密码输入框拖选到遮罩松开时,弹窗保持打开且输入内容保留。
  • 直接点击灰色遮罩仍关闭弹窗。
  • 关闭按钮、取消按钮和 Esc 仍关闭弹窗。
  • 修复对新增用户、重置密码及其他公共弹窗一致生效。
  • 不改变密码校验、表单提交和服务端行为。
  • Chrome 真实指针事件回归通过。
  • go vet ./...、go test ./... 通过。
  • Go 1.23.0 构建和无缓存测试通过。

怎么验证

从 admin/ 执行:

gofmt -w .
go vet ./...
go test ./...
$env:GOTOOLCHAIN="go1.23.0"
go build ./...
go test ./... -count=1
Remove-Item Env:GOTOOLCHAIN

浏览器验证:

  • 输入框内 pointerdown → 拖到遮罩 → pointerup:弹窗不关闭。
  • 遮罩内 pointerdown → pointerup:弹窗关闭。
  • 点击关闭/取消、按 Esc:弹窗关闭。

风险和回退

  • 风险:错误保存指针状态会让直接点遮罩失效。用四种浏览器交互分别验证。
  • 回退:恢复原公共遮罩 click 判断;无数据和接口变更。
## 基本信息 - 状态:已完成 - 类型:缺陷 - 父级大工单:#14 - 所属 MVP / 版本:#15 Admin 四模块可用闭环 - 阶段:Admin 登录与最小账号管理 ## 要解决什么 在用户管理的创建/重置密码弹窗中,从密码输入框内按住鼠标拖选文字,指针移到弹窗外的灰色遮罩后松开,弹窗会意外关闭,已输入内容丢失。 复现步骤: 1. 管理员进入用户管理,打开新增采购员或重置密码弹窗。 2. 在密码框输入内容。 3. 从输入框内按住鼠标拖选,移动到弹窗外灰色区域后松开。 4. 实际:浏览器把合成的 `click` 目标设为遮罩,公共弹窗逻辑关闭弹窗。 5. 期望:拖选不关闭弹窗;只有真正从遮罩开始并在遮罩结束的点击才关闭。 根因位于 `admin/static/js/app.js` 的公共弹窗逻辑:只判断 `click.target === modal`,没有判断手势从哪里开始。该问题会影响所有复用公共遮罩逻辑的弹窗。 ## 做什么 / 不做什么 - 做:记录 `pointerdown` 是否发生在遮罩本身;只有按下和最终 click 都在遮罩时关闭。 - 做:保留点击关闭按钮、取消按钮、Esc 和直接点击遮罩关闭。 - 做:用真实浏览器覆盖输入框拖选、直接点击遮罩、显式按钮和 Esc。 - 做:更新 Admin UI 规范,记录遮罩拖选不得误关闭。 - 不做:不改变表单校验、密码规则、提交行为或服务端接口。 - 不做:不引入前端框架、npm 或新依赖。 - 不做:不增加未保存内容确认弹窗。 ## 怎么做 1. 在每个 `.modal-backdrop` 上监听 `pointerdown`,记录本次指针手势是否从遮罩开始。 2. `click` 时: - `data-modal-close` 仍无条件关闭; - 只有 `e.target === modal` 且本次手势从遮罩开始才关闭; - 从输入框/弹窗内容开始拖到遮罩的 click 不关闭。 3. `pointercancel` 清理状态,避免取消的手势污染下一次操作。 4. 用 Chrome 最小交互测试验证四类关闭行为,并运行 Go 全量回归与 Go 1.23.0 验证。 预计修改: - `admin/static/js/app.js` - `admin/main_test.go`(静态回归守卫) - `docs/admin/05-ui-specification.md` ## 验收标准 - [x] 从密码输入框拖选到遮罩松开时,弹窗保持打开且输入内容保留。 - [x] 直接点击灰色遮罩仍关闭弹窗。 - [x] 关闭按钮、取消按钮和 Esc 仍关闭弹窗。 - [x] 修复对新增用户、重置密码及其他公共弹窗一致生效。 - [x] 不改变密码校验、表单提交和服务端行为。 - [x] Chrome 真实指针事件回归通过。 - [x] `go vet ./...`、`go test ./...` 通过。 - [x] Go 1.23.0 构建和无缓存测试通过。 ## 怎么验证 从 `admin/` 执行: ```powershell gofmt -w . go vet ./... go test ./... $env:GOTOOLCHAIN="go1.23.0" go build ./... go test ./... -count=1 Remove-Item Env:GOTOOLCHAIN ``` 浏览器验证: - 输入框内 `pointerdown` → 拖到遮罩 → `pointerup`:弹窗不关闭。 - 遮罩内 `pointerdown` → `pointerup`:弹窗关闭。 - 点击关闭/取消、按 Esc:弹窗关闭。 ## 风险和回退 - 风险:错误保存指针状态会让直接点遮罩失效。用四种浏览器交互分别验证。 - 回退:恢复原公共遮罩 click 判断;无数据和接口变更。
Author
Owner

实施完成,待用户验收

修复结果

  • 公共弹窗记录 pointerdown 是否从遮罩本身开始。
  • 只有“按下在遮罩 + 最终 click 也在遮罩”才关闭。
  • 从密码框或其他弹窗内容拖到遮罩松开时,弹窗和输入内容均保留。
  • 取消、叉号、Esc、直接点遮罩均保持原行为。
  • pointercancel 会清理手势状态。

Chrome 真实事件回归

使用项目实际 admin/static/js/app.js:

  • 拖选到遮罩:弹窗保持打开 ✅
  • 拖选后密码值保留 ✅
  • 直接点击遮罩关闭 ✅
  • 取消按钮关闭 ✅
  • 叉号关闭 ✅
  • Esc 关闭 ✅

Go 验证

cd admin
go vet ./...
go test ./...
$env:GOTOOLCHAIN="go1.23.0"
go build ./...
go test ./... -count=1
Remove-Item Env:GOTOOLCHAIN

结果:go version go1.23.0 windows/amd64,构建和全部测试通过。

未验证:尚未在用户当前浏览器和实际数据环境人工操作。

提交与归档

  • 实现提交:ff75b27
  • 归档提交:2cbb98f
  • 归档:docs/task/56-修复拖选密码时弹窗意外关闭.md

工单保持打开,等待用户验收后再关闭并同步 #15、#14。

## 实施完成,待用户验收 ### 修复结果 - 公共弹窗记录 `pointerdown` 是否从遮罩本身开始。 - 只有“按下在遮罩 + 最终 click 也在遮罩”才关闭。 - 从密码框或其他弹窗内容拖到遮罩松开时,弹窗和输入内容均保留。 - 取消、叉号、Esc、直接点遮罩均保持原行为。 - `pointercancel` 会清理手势状态。 ### Chrome 真实事件回归 使用项目实际 `admin/static/js/app.js`: - 拖选到遮罩:弹窗保持打开 ✅ - 拖选后密码值保留 ✅ - 直接点击遮罩关闭 ✅ - 取消按钮关闭 ✅ - 叉号关闭 ✅ - Esc 关闭 ✅ ### Go 验证 ```powershell cd admin go vet ./... go test ./... $env:GOTOOLCHAIN="go1.23.0" go build ./... go test ./... -count=1 Remove-Item Env:GOTOOLCHAIN ``` 结果:`go version go1.23.0 windows/amd64`,构建和全部测试通过。 未验证:尚未在用户当前浏览器和实际数据环境人工操作。 ### 提交与归档 - 实现提交:`ff75b27` - 归档提交:`2cbb98f` - 归档:`docs/task/56-修复拖选密码时弹窗意外关闭.md` 工单保持打开,等待用户验收后再关闭并同步 #15、#14。
Author
Owner

用户已于 2026-08-09 明确通过全部 Admin 待验收工单。本工单验收通过,现关闭,并同步父级 #15、#14 的任务清单。

用户已于 2026-08-09 明确通过全部 Admin 待验收工单。本工单验收通过,现关闭,并同步父级 #15、#14 的任务清单。
ila closed this issue 2026-08-09 21:16:21 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#56