fix: 档口入库码匹配自动恢复顺运宝会话 (#236)
This commit is contained in:
@@ -146,11 +146,11 @@ func (h *Handler) InnerCodeMatch(c *gin.Context) {
|
||||
h.innerCodeRedirect(c, businessDate, status, keyword, pageNumber, "顺运宝地址配置有误,没有执行匹配。")
|
||||
return
|
||||
}
|
||||
if err := service.EnsureSybSession(h.db, client, cfg.Syb.Username, time.Now()); err != nil {
|
||||
message := "校验顺运宝会话失败,没有执行匹配。"
|
||||
if errors.Is(err, service.ErrSybLoginRequired) {
|
||||
message = "顺运宝会话已过期,请先到“顺运宝数据”页面登录后再匹配。"
|
||||
}
|
||||
autoLoggedIn, message := ensureInnerCodeMatchSession(
|
||||
func() error { return service.EnsureSybSession(h.db, client, cfg.Syb.Username, time.Now()) },
|
||||
func() (string, bool) { return h.attemptSybAutoLogin(c, client, *cfg) },
|
||||
)
|
||||
if message != "" {
|
||||
h.innerCodeRedirect(c, businessDate, status, keyword, pageNumber, message)
|
||||
return
|
||||
}
|
||||
@@ -159,11 +159,35 @@ func (h *Handler) InnerCodeMatch(c *gin.Context) {
|
||||
h.innerCodeRedirect(c, businessDate, status, keyword, pageNumber, "匹配失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
message := fmt.Sprintf("匹配完成:处理 %d 条,可回写 %d 条,已存在 %d 条,跳过 %d 条,失败 %d 条。",
|
||||
message = fmt.Sprintf("匹配完成:处理 %d 条,可回写 %d 条,已存在 %d 条,跳过 %d 条,失败 %d 条。",
|
||||
result.Total, result.Ready, result.AlreadyFilled, result.Skipped, result.Failed)
|
||||
if autoLoggedIn {
|
||||
message = "顺运宝自动登录成功;" + message
|
||||
}
|
||||
h.innerCodeRedirect(c, businessDate, status, keyword, pageNumber, message)
|
||||
}
|
||||
|
||||
// ensureInnerCodeMatchSession 只负责“检查缓存 → 必要时自动登录”的编排。
|
||||
// 自动登录成功后调用方继续使用同一个 client;这里绝不启动顺运宝同步。
|
||||
func ensureInnerCodeMatchSession(checkSession func() error, autoLogin func() (string, bool)) (bool, string) {
|
||||
err := checkSession()
|
||||
if err == nil {
|
||||
return false, ""
|
||||
}
|
||||
if !errors.Is(err, service.ErrSybLoginRequired) {
|
||||
return false, "校验顺运宝会话失败,没有执行匹配。"
|
||||
}
|
||||
reason, ok := autoLogin()
|
||||
if ok {
|
||||
return true, ""
|
||||
}
|
||||
reason = strings.TrimSpace(reason)
|
||||
if reason == "" {
|
||||
reason = "未配置验证码识别服务,无法自动登录"
|
||||
}
|
||||
return false, "顺运宝自动登录未完成:" + reason + ";没有执行匹配,请到“顺运宝数据”页面完成登录。"
|
||||
}
|
||||
|
||||
// InnerCodeApply 在操作员确认后逐条执行安全回写。
|
||||
func (h *Handler) InnerCodeApply(c *gin.Context) {
|
||||
businessDate, status, keyword := c.PostForm("date"), c.PostForm("status"), c.PostForm("q")
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
package web
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"cmautobuy/admin/service"
|
||||
)
|
||||
|
||||
func TestParseInnerCodeIDs_过滤无效并保持首次选择顺序(t *testing.T) {
|
||||
got := parseInnerCodeIDs([]string{" 8 ", "bad", "0", "8", "3"})
|
||||
@@ -8,3 +14,57 @@ func TestParseInnerCodeIDs_过滤无效并保持首次选择顺序(t *testing.T)
|
||||
t.Fatalf("解析结果不正确: %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureInnerCodeMatchSession_有效会话不自动登录(t *testing.T) {
|
||||
loginCalls := 0
|
||||
autoLoggedIn, message := ensureInnerCodeMatchSession(
|
||||
func() error { return nil },
|
||||
func() (string, bool) { loginCalls++; return "", true },
|
||||
)
|
||||
if autoLoggedIn || message != "" || loginCalls != 0 {
|
||||
t.Fatalf("有效会话不应自动登录: auto=%v message=%q calls=%d", autoLoggedIn, message, loginCalls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureInnerCodeMatchSession_过期后自动登录成功(t *testing.T) {
|
||||
loginCalls := 0
|
||||
autoLoggedIn, message := ensureInnerCodeMatchSession(
|
||||
func() error { return service.ErrSybLoginRequired },
|
||||
func() (string, bool) { loginCalls++; return "", true },
|
||||
)
|
||||
if !autoLoggedIn || message != "" || loginCalls != 1 {
|
||||
t.Fatalf("过期会话应自动登录一次: auto=%v message=%q calls=%d", autoLoggedIn, message, loginCalls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureInnerCodeMatchSession_自动登录失败给出恢复路径(t *testing.T) {
|
||||
autoLoggedIn, message := ensureInnerCodeMatchSession(
|
||||
func() error { return service.ErrSybLoginRequired },
|
||||
func() (string, bool) { return "验证码识别服务不可达", false },
|
||||
)
|
||||
if autoLoggedIn || !strings.Contains(message, "验证码识别服务不可达") ||
|
||||
!strings.Contains(message, "顺运宝数据") || !strings.Contains(message, "没有执行匹配") {
|
||||
t.Fatalf("自动登录失败提示不完整: auto=%v message=%q", autoLoggedIn, message)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureInnerCodeMatchSession_未配置OCR给出明确原因(t *testing.T) {
|
||||
_, message := ensureInnerCodeMatchSession(
|
||||
func() error { return service.ErrSybLoginRequired },
|
||||
func() (string, bool) { return "", false },
|
||||
)
|
||||
if !strings.Contains(message, "未配置验证码识别服务") {
|
||||
t.Fatalf("未配置 OCR 的提示不明确: %q", message)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureInnerCodeMatchSession_普通错误不尝试登录(t *testing.T) {
|
||||
loginCalls := 0
|
||||
autoLoggedIn, message := ensureInnerCodeMatchSession(
|
||||
func() error { return errors.New("database unavailable") },
|
||||
func() (string, bool) { loginCalls++; return "", true },
|
||||
)
|
||||
if autoLoggedIn || message != "校验顺运宝会话失败,没有执行匹配。" || loginCalls != 0 {
|
||||
t.Fatalf("普通错误不应自动登录: auto=%v message=%q calls=%d", autoLoggedIn, message, loginCalls)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user