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:
@@ -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 BY:JOIN 带 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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user