From e33212c99a830ba9239f6d9a372f09c3e5ef07f3 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Mon, 7 Sep 2026 09:29:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E5=BA=93=E5=AD=98=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E6=97=A5=E6=9C=9F=E6=90=9C=E7=B4=A2=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=8E=BB=E6=A8=AA=E6=9D=A0=E6=95=B0=E5=AD=97=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 两侧统一去掉分隔符按纯数字比对:2002 / 200202 / 20020226 / 2002-02-26 都能命中生产日期 2002-02-26,用户输入带不带横杠都行 - 仅当关键词含数字时才追加日期匹配条件,避免纯文字搜索命中全部日期 - 测试补充带/不带横杠两种格式断言 Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Bupi8Kdqkfx2N5acFsHTx5 --- backend/internal/handler/inventory.go | 20 ++++++++++++---- backend/internal/handler/inventory_test.go | 27 ++++++++++++---------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/backend/internal/handler/inventory.go b/backend/internal/handler/inventory.go index d3b1d1d..de0a72a 100644 --- a/backend/internal/handler/inventory.go +++ b/backend/internal/handler/inventory.go @@ -105,11 +105,23 @@ func (h *InventoryHandler) List(c *gin.Context) { specStr := c.Query("spec") if keyword != "" { - // 关键词匹配:商品名/拼音/首字母/编码 + 生产日期(对生产日期文本 LIKE,支持 "2010"/"2010-06"/"2010-06-04")。 - // 生产日期口径与 SELECT/排序一致:COALESCE(入库明细快照, 库存行快照)。 - baseWhere += " AND (COALESCE(NULLIF(p.name,''), NULLIF(sii.product_name,''), inv.product_name) LIKE ? OR COALESCE(NULLIF(p.code,''), NULLIF(sii.product_code,''), inv.product_code) LIKE ? OR p.name_pinyin LIKE ? OR p.name_initials LIKE ? OR CAST(COALESCE(DATE(sii.production_date), DATE(inv.production_date)) AS CHAR) LIKE ?)" + // 关键词匹配:商品名/拼音/首字母/编码。 + clause := "COALESCE(NULLIF(p.name,''), NULLIF(sii.product_name,''), inv.product_name) LIKE ? OR COALESCE(NULLIF(p.code,''), NULLIF(sii.product_code,''), inv.product_code) LIKE ? OR p.name_pinyin LIKE ? OR p.name_initials LIKE ?" like := "%" + keyword + "%" - args = append(args, like, like, like, like, like) + args = append(args, like, like, like, like) + // 生产日期匹配:两侧都去掉分隔符按纯数字比对,输入带不带横杠都行 + // (2002 / 200202 / 20020226 / 2002-02-26 均可命中 2002-02-26)。 + // 口径与 SELECT/排序一致:COALESCE(入库明细快照, 库存行快照)。仅当关键词含数字才加此条,避免纯文字搜索命中全部日期。 + if digits := strings.Map(func(r rune) rune { + if r >= '0' && r <= '9' { + return r + } + return -1 + }, keyword); digits != "" { + clause += " OR REPLACE(CAST(COALESCE(DATE(sii.production_date), DATE(inv.production_date)) AS CHAR), '-', '') LIKE ?" + args = append(args, "%"+digits+"%") + } + baseWhere += " AND (" + clause + ")" } // 商品编码独立筛选(库存屏工具栏第二个搜索框,对齐原型 codeInput) if code := c.Query("code"); code != "" { diff --git a/backend/internal/handler/inventory_test.go b/backend/internal/handler/inventory_test.go index c857ff8..066bf00 100644 --- a/backend/internal/handler/inventory_test.go +++ b/backend/internal/handler/inventory_test.go @@ -332,18 +332,21 @@ func TestInventoryHandler_List_SearchByProductionDate(t *testing.T) { require.NoError(t, db.Create(&model.Inventory{ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &p1.ID, Quantity: 10, ProductionDate: d2010}).Error) require.NoError(t, db.Create(&model.Inventory{ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &p2.ID, Quantity: 20, ProductionDate: d1999}).Error) - // 年份命中一条 - w := makeRequest(r, "GET", "/api/v1/inventory?keyword=2010", token, nil) - assert.Equal(t, float64(1), parseResponse(w)["total"].(float64)) - // 年-月命中一条 - w = makeRequest(r, "GET", "/api/v1/inventory?keyword=2010-06", token, nil) - assert.Equal(t, float64(1), parseResponse(w)["total"].(float64)) - // 完整日期命中一条 - w = makeRequest(r, "GET", "/api/v1/inventory?keyword=1999-12-16", token, nil) - assert.Equal(t, float64(1), parseResponse(w)["total"].(float64)) - // 不存在的日期零命中(同时验证不误伤名称/编码) - w = makeRequest(r, "GET", "/api/v1/inventory?keyword=2001", token, nil) - assert.Equal(t, float64(0), parseResponse(w)["total"].(float64)) + expectTotal := func(kw string, want float64) { + w := makeRequest(r, "GET", "/api/v1/inventory?keyword="+kw, token, nil) + assert.Equalf(t, want, parseResponse(w)["total"].(float64), "keyword=%s", kw) + } + // 年份 / 年月 命中一条 + expectTotal("2010", 1) + expectTotal("2010-06", 1) + expectTotal("201006", 1) // 无横杠年月 + // 完整日期:带横杠 与 无横杠 都命中 + expectTotal("2010-06-04", 1) + expectTotal("20100604", 1) + expectTotal("1999-12-16", 1) + expectTotal("19991216", 1) + // 不存在的日期零命中(同时验证纯数字不误伤,也不命中全部日期) + expectTotal("2001", 0) } // Summary 月初快照字段:月初数量 = 当前数量 − 本月净流水