fix: 进入顺运宝页面不再自动弹验证码框 (#48)
配了 ocr_url 也会在进入页面时被拦一次输验证码。根因是 OCR 自动登录 只接在「点同步」那条路径上,而进入页面走的是另一条: SybList → 本地会话过期 → NeedLogin=true → 模板直接弹手工输入框, 压根不调 OCR。 改成 NeedLogin 只由 login_reason 驱动——也就是操作员主动点过同步、 且自动登录确实失败时才弹。这时弹框是他预期的。 打开页面现在纯粹是看数据,不触发任何对外部系统的动作;真正会登录的 只有「同步」一个按钮。这与 Client 侧「『获取任务』是唯一会产生外部 后果的命令」是同一条原则。 会话无效时改成顶部一行提示,按 ocr_url 配没配分两种文案:配了却提示 "需要手工输入"会让人以为配置没生效;没配却提示"会自动登录",点下去 弹出验证码框会让人莫名其妙。用 .hint 不用 .missing——这是状态说明 不是错误,红色留给「PDD 链接未填写」那种要立刻处理的。 EnsureSybSession 未改动:它只读 SQLite 缓存、本地判过期,不发外部 请求,页面渲染不会因此变慢。审查时我一度说它每次渲染都探测顺运宝, 那是错的,已核实。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,21 @@ func (h *Handler) renderSybList(c *gin.Context, keyword, pageRaw, msg string) {
|
|||||||
h.renderSybListWithLoginReason(c, keyword, pageRaw, msg, c.Query("login_reason"))
|
h.renderSybListWithLoginReason(c, keyword, pageRaw, msg, c.Query("login_reason"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sybLoginHint 是会话无效时顶部那行提示。
|
||||||
|
//
|
||||||
|
// `[必须]` 配了 OCR 和没配 OCR 的文案要分开(工单 #48):
|
||||||
|
// 配了却提示"需要手工输入"会让人以为配置没生效;没配却提示"会自动登录",
|
||||||
|
// 点下去弹出验证码框会让人莫名其妙。
|
||||||
|
//
|
||||||
|
// `[必须]` 这不是错误,是状态说明,用 .hint 不用 .missing——
|
||||||
|
// 红色留给「PDD 链接未填写」那种需要立刻处理的。
|
||||||
|
func sybLoginHint(ocrURL string) string {
|
||||||
|
if strings.TrimSpace(ocrURL) != "" {
|
||||||
|
return "顺运宝未登录。点「同步」时会自动识别验证码并登录。"
|
||||||
|
}
|
||||||
|
return "顺运宝未登录。点「同步」时需要手工输入验证码。"
|
||||||
|
}
|
||||||
|
|
||||||
// renderSybListWithLoginReason 同 renderSybList,额外带一条"登录弹窗里要
|
// renderSybListWithLoginReason 同 renderSybList,额外带一条"登录弹窗里要
|
||||||
// 显示的原因"——工单 #47:自动识别验证码失败或降级时,操作员需要知道
|
// 显示的原因"——工单 #47:自动识别验证码失败或降级时,操作员需要知道
|
||||||
// 是配置错了还是服务挂了,不能弹一个空的手工输入框了事。
|
// 是配置错了还是服务挂了,不能弹一个空的手工输入框了事。
|
||||||
@@ -61,7 +76,18 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
|
|||||||
// 这里只取 username(只读展示)和 base_url 是否配置正确。
|
// 这里只取 username(只读展示)和 base_url 是否配置正确。
|
||||||
username := ""
|
username := ""
|
||||||
configProblem := ""
|
configProblem := ""
|
||||||
needLogin := false
|
loginHint := ""
|
||||||
|
|
||||||
|
// `[必须]` 登录弹窗**只在自动登录失败后跳回来时才弹**(工单 #48)。
|
||||||
|
//
|
||||||
|
// 改之前是"本地会话过期就弹",导致配了 ocr_url 也会在**进入页面**时
|
||||||
|
// 被拦一次——因为 OCR 自动登录只接在「点同步」那条路径上。
|
||||||
|
//
|
||||||
|
// 现在「打开页面」纯粹是看数据,不触发任何对外部系统的动作;
|
||||||
|
// 真正会登录的只有「同步」这一个按钮。这与 Client 侧
|
||||||
|
// 「『获取任务』是唯一会产生外部后果的命令」是同一条原则。
|
||||||
|
needLogin := loginReason != ""
|
||||||
|
|
||||||
cfg, cfgErr := config.Load()
|
cfg, cfgErr := config.Load()
|
||||||
switch {
|
switch {
|
||||||
case cfgErr != nil:
|
case cfgErr != nil:
|
||||||
@@ -72,8 +98,13 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
configProblem = "顺运宝 base_url 配置有误: " + err.Error()
|
configProblem = "顺运宝 base_url 配置有误: " + err.Error()
|
||||||
} else {
|
} else {
|
||||||
|
// 这里仍然要判会话,但结果只用来决定"要不要给一行提示",
|
||||||
|
// 不再用来决定"弹不弹窗"。EnsureSybSession 只读本地缓存、
|
||||||
|
// 本地判过期,不发外部请求,页面渲染不会因此变慢。
|
||||||
sessErr := service.EnsureSybSession(h.db, client, cfg.Syb.Username, time.Now())
|
sessErr := service.EnsureSybSession(h.db, client, cfg.Syb.Username, time.Now())
|
||||||
needLogin = errors.Is(sessErr, service.ErrSybLoginRequired)
|
if errors.Is(sessErr, service.ErrSybLoginRequired) {
|
||||||
|
loginHint = sybLoginHint(cfg.Syb.OcrURL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +116,7 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
|
|||||||
"IsFiltered": result.IsFiltered,
|
"IsFiltered": result.IsFiltered,
|
||||||
"NeedLogin": needLogin,
|
"NeedLogin": needLogin,
|
||||||
"NeedLoginReason": loginReason,
|
"NeedLoginReason": loginReason,
|
||||||
|
"LoginHint": loginHint,
|
||||||
"Username": username,
|
"Username": username,
|
||||||
"ConfigProblem": configProblem,
|
"ConfigProblem": configProblem,
|
||||||
"Pagination": service.NewPaginationView(result.Page, result.TotalPages, values.Encode()),
|
"Pagination": service.NewPaginationView(result.Page, result.TotalPages, values.Encode()),
|
||||||
|
|||||||
@@ -34,6 +34,15 @@
|
|||||||
</p>
|
</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{/* 未登录只给一行提示,**不弹窗**(工单 #48)。
|
||||||
|
打开页面纯粹是看数据,不该触发任何对外部系统的动作;
|
||||||
|
真正会登录的只有「同步」那一个按钮。
|
||||||
|
用 .hint 不用 .missing——这是状态说明不是错误,
|
||||||
|
红色留给「PDD 链接未填写」那种要立刻处理的。 */}}
|
||||||
|
{{if .LoginHint}}
|
||||||
|
<p class="hint">{{.LoginHint}}</p>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<div class="table-wrap">
|
<div class="table-wrap">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user