feat(backend): 出入库编码搜索双路匹配+建单填快照;finance 趋势/日期区间;partner/product 拼音搜索

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
This commit is contained in:
wangjia
2026-07-02 22:27:13 +08:00
parent af56055eef
commit 9099c4af99
21 changed files with 610 additions and 39 deletions
+9 -6
View File
@@ -57,14 +57,15 @@ func (h *StockInHandler) List(c *gin.Context) {
// 酒名「product 主数据名 OR 明细快照名」任一命中——不能用 COALESCE 二选一:历史导入单的
// 明细 product_id 统一指向占位商品「历史导入占位」(p.name 非空),COALESCE 会被占位名劫持,
// 永远取不到真实快照 product_name,导致导入单按真实酒名搜不到。拼音只在 products 上(快照无拼音列)。
// 编码同理「主数据 p.code OR 快照 it.product_code」双匹配,与页面显示口径(主数据优先)对齐。
query = query.Where(
"order_no LIKE ?"+
" OR id IN (SELECT it.order_id FROM stock_in_items it"+
" LEFT JOIN products p ON p.id = it.product_id AND p.shop_id = it.shop_id"+
" WHERE it.shop_id = ? AND it.deleted_at IS NULL"+
" AND (p.name LIKE ? OR it.product_name LIKE ? OR it.product_code LIKE ?"+
" OR p.name_pinyin LIKE ? OR p.name_initials LIKE ?))",
like, shopID, like, like, like, like, like,
" OR p.code LIKE ? OR p.name_pinyin LIKE ? OR p.name_initials LIKE ?))",
like, shopID, like, like, like, like, like, like,
)
}
// 详细搜索多字段(各参数独立可选、组合为 AND)
@@ -109,12 +110,14 @@ func applyStockOrderDetailFilters(q *gorm.DB, shopID uint64, c *gin.Context, ite
like := "%" + v + "%"
itemConds = append(itemConds,
"(p.name LIKE ? OR it.product_name LIKE ? OR it.product_code LIKE ?"+
" OR p.name_pinyin LIKE ? OR p.name_initials LIKE ?)")
itemArgs = append(itemArgs, like, like, like, like, like)
" OR p.code LIKE ? OR p.name_pinyin LIKE ? OR p.name_initials LIKE ?)")
itemArgs = append(itemArgs, like, like, like, like, like, like)
}
// 编码「主数据 OR 快照」双匹配:存量出库明细快照有空串,只查快照会漏单
if v := strings.TrimSpace(c.Query("product_code")); v != "" {
itemConds = append(itemConds, "it.product_code LIKE ?")
itemArgs = append(itemArgs, "%"+v+"%")
like := "%" + v + "%"
itemConds = append(itemConds, "(it.product_code LIKE ? OR p.code LIKE ?)")
itemArgs = append(itemArgs, like, like)
}
if v := strings.TrimSpace(c.Query("series")); v != "" {
itemConds = append(itemConds, "it.series = ?")