fix(backend): 财务汇总 500(only_full_group_by 预处理协议回归)+ summary 加 draft_count

- /finance/summary:SEC-001 给 JOIN 加 shop_id 条件后,MySQL 预处理协议推导不出
  p.name 函数依赖 → 1055(文本协议可过,CLI 无法复现)。GROUP BY 补 p.name 修复,
  并给该 handler 加错误日志(此前吞错致排查困难)。v1.0.85 起全店受影响。
- 出入库 summary 新增 draft_count(草稿单数 KPI 卡数据源)。

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-03 14:31:50 +08:00
parent cd3cc0d8fe
commit 4d1d69595b
3 changed files with 11 additions and 1 deletions
+6 -1
View File
@@ -1,6 +1,7 @@
package handler
import (
"log"
"net/http"
"strconv"
"time"
@@ -246,9 +247,13 @@ func (h *FinanceHandler) Summary(c *gin.Context) {
WHERE f.shop_id = ? AND f.deleted_at IS NULL
AND f.type IN ('payable','receivable')
AND f.status = 'open'
GROUP BY f.partner_id, f.type
GROUP BY f.partner_id, f.type, p.name
ORDER BY total_amount DESC
`, shopID).Scan(&rows).Error; err != nil {
// p.name 必须入 GROUP BYJOIN 带 shop_id 条件后,MySQL 预处理协议
// 推导不出 p.name 的函数依赖 → only_full_group_by 1055(文本协议却能过,
// 故 CLI 直跑无法复现)。p.name 由 partner_id 唯一决定,加入不改分组粒度。
log.Printf("finance summary query failed (shop %d): %v", shopID, err)
util.RespondError(c, http.StatusInternalServerError, "QUERY_ERROR", "查询失败")
return
}
+3
View File
@@ -154,6 +154,7 @@ type stockSummary struct {
MonthCount int64 `json:"month_count"`
MonthAmount float64 `json:"month_amount"`
PendingCount int64 `json:"pending_count"`
DraftCount int64 `json:"draft_count"`
LastMonthCount int64 `json:"last_month_count"`
LastMonthAmount float64 `json:"last_month_amount"`
}
@@ -201,6 +202,8 @@ func (h *StockInHandler) Summary(c *gin.Context) {
s.LastMonthCount, s.LastMonthAmount = agg(prevFrom, prevTo)
h.db.Model(&model.StockInOrder{}).
Where("shop_id = ? AND status = ? AND deleted_at IS NULL", shopID, "pending").Count(&s.PendingCount)
h.db.Model(&model.StockInOrder{}).
Where("shop_id = ? AND status = ? AND deleted_at IS NULL", shopID, "draft").Count(&s.DraftCount)
c.JSON(http.StatusOK, s)
}
+2
View File
@@ -117,6 +117,8 @@ func (h *StockOutHandler) Summary(c *gin.Context) {
s.LastMonthCount, s.LastMonthAmount = agg(prevFrom, prevTo)
h.db.Model(&model.StockOutOrder{}).
Where("shop_id = ? AND status = ? AND deleted_at IS NULL", shopID, "pending").Count(&s.PendingCount)
h.db.Model(&model.StockOutOrder{}).
Where("shop_id = ? AND status = ? AND deleted_at IS NULL", shopID, "draft").Count(&s.DraftCount)
c.JSON(http.StatusOK, s)
}