feat: 增加顺运宝店铺筛选 (#151)
This commit is contained in:
+45
-15
@@ -53,8 +53,9 @@ func sybLoginHint(ocrURL string) string {
|
||||
// 是配置错了还是服务挂了,不能弹一个空的手工输入框了事。
|
||||
func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw, msg, loginReason string) {
|
||||
pageNum := service.ParsePage(pageRaw)
|
||||
shop := strings.TrimSpace(c.Query("shop"))
|
||||
stage := service.ParseSybStage(c.Query("stage"))
|
||||
result, err := service.ListSybOrdersView(h.db, keyword, stage, pageNum)
|
||||
result, err := service.ListSybOrdersView(h.db, keyword, shop, stage, pageNum)
|
||||
if err != nil {
|
||||
fail(c, http.StatusInternalServerError,
|
||||
"读取顺运宝货运单列表失败,数据没有被改动。刷新页面重试;一直失败请把这句话报给维护者。")
|
||||
@@ -88,6 +89,9 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
|
||||
if stage != "" {
|
||||
values.Set("stage", stage)
|
||||
}
|
||||
if shop != "" {
|
||||
values.Set("shop", shop)
|
||||
}
|
||||
detailValues := url.Values{}
|
||||
if keyword != "" {
|
||||
detailValues.Set("order_no", keyword)
|
||||
@@ -95,6 +99,9 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
|
||||
if stage != "" {
|
||||
detailValues.Set("stage", stage)
|
||||
}
|
||||
if shop != "" {
|
||||
detailValues.Set("shop", shop)
|
||||
}
|
||||
detailValues.Set("page", strconv.Itoa(result.Page))
|
||||
|
||||
// `[必须]` 密码不读出来显示、也不回显到 HTML,见工单 #46。
|
||||
@@ -155,6 +162,7 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
|
||||
|
||||
c.HTML(http.StatusOK, "syb/list", page(c, "syb", "顺运宝数据", gin.H{
|
||||
"Keyword": keyword,
|
||||
"ShopFilter": shop,
|
||||
"StageFilter": stage,
|
||||
"StageOptions": service.SybStageOptions(),
|
||||
"CurrentPage": result.Page,
|
||||
@@ -176,11 +184,11 @@ func (h *Handler) renderSybListWithLoginReason(c *gin.Context, keyword, pageRaw,
|
||||
"SyncHistory": history,
|
||||
"NeedSyncHistory": c.Query("history") == "1",
|
||||
"HistoryFetchURL": sybHistoryPartialURL(history.Page,
|
||||
keyword, dateFrom, dateTo),
|
||||
keyword, shop, stage, dateFrom, dateTo),
|
||||
"HistoryPagination": sybHistoryPagination(history.Page, history.TotalPages,
|
||||
keyword, dateFrom, dateTo),
|
||||
keyword, shop, stage, dateFrom, dateTo),
|
||||
"HistoryFetchPagination": sybHistoryPartialPagination(history.Page, history.TotalPages,
|
||||
keyword, dateFrom, dateTo),
|
||||
keyword, shop, stage, dateFrom, dateTo),
|
||||
"Pagination": service.NewPaginationView(result.Page, result.TotalPages, values.Encode()),
|
||||
"DetailURL": "/syb/detail?" + detailValues.Encode(),
|
||||
"AssignableClients": purchaseClients.Rows,
|
||||
@@ -201,7 +209,7 @@ func (h *Handler) SybDetail(c *gin.Context) {
|
||||
}
|
||||
c.HTML(http.StatusOK, "syb/detail_modal", gin.H{
|
||||
"D": detail, "CSRFToken": csrfToken(c),
|
||||
"Keyword": c.Query("order_no"), "StageFilter": c.Query("stage"),
|
||||
"Keyword": c.Query("order_no"), "ShopFilter": c.Query("shop"), "StageFilter": c.Query("stage"),
|
||||
"CurrentPage": service.ParsePage(c.Query("page")),
|
||||
})
|
||||
}
|
||||
@@ -211,6 +219,8 @@ func (h *Handler) SybDetail(c *gin.Context) {
|
||||
func (h *Handler) SybSyncHistory(c *gin.Context) {
|
||||
c.Header("Cache-Control", "no-store")
|
||||
keyword := c.Query("order_no")
|
||||
shop := strings.TrimSpace(c.Query("shop"))
|
||||
stage := service.ParseSybStage(c.Query("stage"))
|
||||
dateFrom := c.Query("date_from")
|
||||
dateTo := c.Query("date_to")
|
||||
history, err := service.ListSybSyncHistory(h.db, service.ParsePage(c.Query("history_page")))
|
||||
@@ -221,16 +231,16 @@ func (h *Handler) SybSyncHistory(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "syb/history_partial", gin.H{
|
||||
"SyncHistory": history,
|
||||
"HistoryFetchURL": sybHistoryPartialURL(history.Page,
|
||||
keyword, dateFrom, dateTo),
|
||||
keyword, shop, stage, dateFrom, dateTo),
|
||||
"HistoryPagination": sybHistoryPagination(history.Page, history.TotalPages,
|
||||
keyword, dateFrom, dateTo),
|
||||
keyword, shop, stage, dateFrom, dateTo),
|
||||
"HistoryFetchPagination": sybHistoryPartialPagination(history.Page, history.TotalPages,
|
||||
keyword, dateFrom, dateTo),
|
||||
keyword, shop, stage, dateFrom, dateTo),
|
||||
})
|
||||
}
|
||||
|
||||
func sybHistoryPagination(pageNum, totalPages int, keyword, dateFrom, dateTo string) service.PaginationView {
|
||||
link := func(target int) string { return sybHistoryURL(target, keyword, dateFrom, dateTo) }
|
||||
func sybHistoryPagination(pageNum, totalPages int, keyword, shop, stage, dateFrom, dateTo string) service.PaginationView {
|
||||
link := func(target int) string { return sybHistoryURL(target, keyword, shop, stage, dateFrom, dateTo) }
|
||||
view := service.PaginationView{
|
||||
Page: pageNum, TotalPages: totalPages, HasPrev: pageNum > 1, HasNext: pageNum < totalPages,
|
||||
FirstURL: link(1), LastURL: link(totalPages),
|
||||
@@ -244,18 +254,24 @@ func sybHistoryPagination(pageNum, totalPages int, keyword, dateFrom, dateTo str
|
||||
return view
|
||||
}
|
||||
|
||||
func sybHistoryURL(pageNum int, keyword, dateFrom, dateTo string) string {
|
||||
func sybHistoryURL(pageNum int, keyword, shop, stage, dateFrom, dateTo string) string {
|
||||
values := url.Values{"history": {"1"}, "history_page": {strconv.Itoa(pageNum)}}
|
||||
if keyword != "" {
|
||||
values.Set("order_no", keyword)
|
||||
}
|
||||
if shop != "" {
|
||||
values.Set("shop", shop)
|
||||
}
|
||||
if stage != "" {
|
||||
values.Set("stage", stage)
|
||||
}
|
||||
values.Set("date_from", dateFrom)
|
||||
values.Set("date_to", dateTo)
|
||||
return "/syb?" + values.Encode()
|
||||
}
|
||||
|
||||
func sybHistoryPartialPagination(pageNum, totalPages int, keyword, dateFrom, dateTo string) service.PaginationView {
|
||||
link := func(target int) string { return sybHistoryPartialURL(target, keyword, dateFrom, dateTo) }
|
||||
func sybHistoryPartialPagination(pageNum, totalPages int, keyword, shop, stage, dateFrom, dateTo string) service.PaginationView {
|
||||
link := func(target int) string { return sybHistoryPartialURL(target, keyword, shop, stage, dateFrom, dateTo) }
|
||||
view := service.PaginationView{
|
||||
Page: pageNum, TotalPages: totalPages, HasPrev: pageNum > 1, HasNext: pageNum < totalPages,
|
||||
FirstURL: link(1), LastURL: link(totalPages),
|
||||
@@ -269,11 +285,17 @@ func sybHistoryPartialPagination(pageNum, totalPages int, keyword, dateFrom, dat
|
||||
return view
|
||||
}
|
||||
|
||||
func sybHistoryPartialURL(pageNum int, keyword, dateFrom, dateTo string) string {
|
||||
func sybHistoryPartialURL(pageNum int, keyword, shop, stage, dateFrom, dateTo string) string {
|
||||
values := url.Values{"history_page": {strconv.Itoa(pageNum)}}
|
||||
if keyword != "" {
|
||||
values.Set("order_no", keyword)
|
||||
}
|
||||
if shop != "" {
|
||||
values.Set("shop", shop)
|
||||
}
|
||||
if stage != "" {
|
||||
values.Set("stage", stage)
|
||||
}
|
||||
values.Set("date_from", dateFrom)
|
||||
values.Set("date_to", dateTo)
|
||||
return "/syb/sync-history?" + values.Encode()
|
||||
@@ -285,6 +307,8 @@ func sybStatusLine(result *service.SybListResult) string {
|
||||
prefix := fmt.Sprintf("共 %d 条货运单明细", result.Total)
|
||||
if label := service.SybStageLabel(result.Stage); label != "" {
|
||||
prefix = fmt.Sprintf("%s:%d 条", label, result.Total)
|
||||
} else if result.IsFiltered {
|
||||
prefix = fmt.Sprintf("筛选结果:%d 条货运单明细", result.Total)
|
||||
}
|
||||
if !result.HasAny {
|
||||
return "还没有货运单明细。点上方「同步」从顺运宝拉取。"
|
||||
@@ -521,6 +545,12 @@ func (h *Handler) sybRedirectAfterStart(c *gin.Context, msg string) {
|
||||
if keyword := strings.TrimSpace(c.PostForm("order_no")); keyword != "" {
|
||||
params.Set("order_no", keyword)
|
||||
}
|
||||
if shop := strings.TrimSpace(c.PostForm("shop")); shop != "" {
|
||||
params.Set("shop", shop)
|
||||
}
|
||||
if stage := strings.TrimSpace(c.PostForm("stage")); stage != "" {
|
||||
params.Set("stage", stage)
|
||||
}
|
||||
c.Redirect(http.StatusSeeOther, "/syb?"+params.Encode())
|
||||
}
|
||||
|
||||
@@ -553,7 +583,7 @@ func (h *Handler) sybRedirectRange(c *gin.Context, message string) {
|
||||
|
||||
// appendSybFormState 保存同步/登录跳转后仍需要的页面状态。
|
||||
func appendSybFormState(params url.Values, c *gin.Context) {
|
||||
for _, name := range []string{"order_no", "stage", "page", "date_from", "date_to"} {
|
||||
for _, name := range []string{"order_no", "shop", "stage", "page", "date_from", "date_to"} {
|
||||
if value := strings.TrimSpace(c.PostForm(name)); value != "" {
|
||||
params.Set(name, value)
|
||||
}
|
||||
|
||||
@@ -88,14 +88,14 @@ func TestSybRedirectAfterStart_清除本次日期范围(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSybHistoryPagination_保留筛选并重开弹窗(t *testing.T) {
|
||||
view := sybHistoryPagination(2, 3, "ORDER-1", "2026-08-01", "2026-08-09")
|
||||
view := sybHistoryPagination(2, 3, "ORDER-1", "店铺A", "pdd_missing", "2026-08-01", "2026-08-09")
|
||||
for _, raw := range []string{view.FirstURL, view.PrevURL, view.NextURL, view.LastURL} {
|
||||
location, err := url.Parse(raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
query := location.Query()
|
||||
if query.Get("history") != "1" || query.Get("order_no") != "ORDER-1" ||
|
||||
if query.Get("history") != "1" || query.Get("order_no") != "ORDER-1" || query.Get("shop") != "店铺A" || query.Get("stage") != "pdd_missing" ||
|
||||
query.Get("date_from") != "2026-08-01" || query.Get("date_to") != "2026-08-09" {
|
||||
t.Fatalf("同步记录翻页链接丢失页面状态: %s", raw)
|
||||
}
|
||||
@@ -103,13 +103,14 @@ func TestSybHistoryPagination_保留筛选并重开弹窗(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSybHistoryURL_刷新时保留当前页和筛选(t *testing.T) {
|
||||
location, err := url.Parse(sybHistoryURL(3, "ORDER-1", "2026-08-01", "2026-08-09"))
|
||||
location, err := url.Parse(sybHistoryURL(3, "ORDER-1", "店铺A", "pdd_missing", "2026-08-01", "2026-08-09"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
query := location.Query()
|
||||
for name, want := range map[string]string{
|
||||
"history": "1", "history_page": "3", "order_no": "ORDER-1",
|
||||
"shop": "店铺A", "stage": "pdd_missing",
|
||||
"date_from": "2026-08-01", "date_to": "2026-08-09",
|
||||
} {
|
||||
if got := query.Get(name); got != want {
|
||||
@@ -119,7 +120,7 @@ func TestSybHistoryURL_刷新时保留当前页和筛选(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSybHistoryPartialURL_只读片段保留当前页和筛选(t *testing.T) {
|
||||
location, err := url.Parse(sybHistoryPartialURL(3, "ORDER-1", "2026-08-01", "2026-08-09"))
|
||||
location, err := url.Parse(sybHistoryPartialURL(3, "ORDER-1", "店铺A", "pdd_missing", "2026-08-01", "2026-08-09"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -129,6 +130,7 @@ func TestSybHistoryPartialURL_只读片段保留当前页和筛选(t *testing.T)
|
||||
query := location.Query()
|
||||
for name, want := range map[string]string{
|
||||
"history_page": "3", "order_no": "ORDER-1",
|
||||
"shop": "店铺A", "stage": "pdd_missing",
|
||||
"date_from": "2026-08-01", "date_to": "2026-08-09",
|
||||
} {
|
||||
if got := query.Get(name); got != want {
|
||||
@@ -138,7 +140,7 @@ func TestSybHistoryPartialURL_只读片段保留当前页和筛选(t *testing.T)
|
||||
}
|
||||
|
||||
func TestSybHistoryPartialPagination_翻页继续使用片段路由(t *testing.T) {
|
||||
view := sybHistoryPartialPagination(2, 3, "ORDER-1", "2026-08-01", "2026-08-09")
|
||||
view := sybHistoryPartialPagination(2, 3, "ORDER-1", "店铺A", "pdd_missing", "2026-08-01", "2026-08-09")
|
||||
for _, raw := range []string{view.FirstURL, view.PrevURL, view.NextURL, view.LastURL} {
|
||||
location, err := url.Parse(raw)
|
||||
if err != nil {
|
||||
|
||||
@@ -52,11 +52,11 @@ func Test列表写操作跳转保留筛选和页码(t *testing.T) {
|
||||
})
|
||||
t.Run("顺运宝", func(t *testing.T) {
|
||||
context, recorder := listPostContext(t, "/syb/associate-pdd", url.Values{
|
||||
"order_no": {"SYB-1"}, "stage": {"pdd_missing"}, "page": {"3"},
|
||||
"order_no": {"SYB-1"}, "shop": {"测试店铺"}, "stage": {"pdd_missing"}, "page": {"3"},
|
||||
})
|
||||
(&Handler{}).sybRedirect(context, "完成")
|
||||
assertRedirectQuery(t, recorder, "/syb", map[string]string{
|
||||
"order_no": "SYB-1", "stage": "pdd_missing", "page": "3", "msg": "完成",
|
||||
"order_no": "SYB-1", "shop": "测试店铺", "stage": "pdd_missing", "page": "3", "msg": "完成",
|
||||
})
|
||||
})
|
||||
t.Run("PDD", func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user