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
+29 -15
View File
@@ -36,7 +36,11 @@ func (h *PartnerHandler) List(c *gin.Context) {
query = query.Where("FIND_IN_SET(?, type)", t)
}
if kw := c.Query("keyword"); kw != "" {
query = query.Where("name LIKE ? OR phone LIKE ?", "%"+kw+"%", "%"+kw+"%")
// 原型搜索口径:名称 / 拼音(全拼+首字母)/ 联系人;phone 保留兼容
like := "%" + kw + "%"
query = query.Where(
"name LIKE ? OR contact LIKE ? OR phone LIKE ? OR name_pinyin LIKE ? OR name_initials LIKE ?",
like, like, like, like, like)
}
var total int64
@@ -56,6 +60,7 @@ func (h *PartnerHandler) Create(c *gin.Context) {
return
}
p.ShopID = shopID
p.NamePinyin, p.NameInitials = util.ToPinyin(p.Name)
// 编码未提供时自动生成:供应商 S001/S002…,客户 C001/C002…
if p.Code == "" {
prefix := "S"
@@ -92,25 +97,34 @@ func (h *PartnerHandler) Update(c *gin.Context) {
Address string `json:"address"`
BankAccount string `json:"bank_account"`
CreditLimit float64 `json:"credit_limit"`
Status string `json:"status"`
Remark string `json:"remark"`
// 期初余额:指针区分「未传」与 0,旧客户端不传时不清零
Balance *float64 `json:"balance"`
Status string `json:"status"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := h.db.Model(&p).Where("shop_id = ?", shopID).Updates(map[string]interface{}{
"name": req.Name,
"type": req.Type,
"code": req.Code,
"contact": req.Contact,
"phone": req.Phone,
"address": req.Address,
"bank_account": req.BankAccount,
"credit_limit": req.CreditLimit,
"status": req.Status,
"remark": req.Remark,
}).Error; err != nil {
pinyin, initials := util.ToPinyin(req.Name)
updates := map[string]interface{}{
"name": req.Name,
"name_pinyin": pinyin,
"name_initials": initials,
"type": req.Type,
"code": req.Code,
"contact": req.Contact,
"phone": req.Phone,
"address": req.Address,
"bank_account": req.BankAccount,
"credit_limit": req.CreditLimit,
"status": req.Status,
"remark": req.Remark,
}
if req.Balance != nil {
updates["balance"] = *req.Balance
}
if err := h.db.Model(&p).Where("shop_id = ?", shopID).Updates(updates).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}