批量更新功能

This commit is contained in:
2026-09-14 16:15:44 +08:00
parent 6f106e43af
commit a26c98b92b
79 changed files with 4529 additions and 724 deletions
+36
View File
@@ -9,6 +9,7 @@ import (
"time"
"server/models"
"server/services"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
@@ -269,6 +270,10 @@ func (c *BackendCrmPaybackController) Create() {
return
}
crmWriteLog(tenantID, 4, row.ID, "create", "创建回款计划:"+row.ContractName, claims)
// 回款逾期联动:新建的计划可能已含逾期节点,合同 / 项目状态即时生效
if row.ContractID != nil {
services.SyncPaybackOverdueForContract(tenantID, *row.ContractID)
}
pipelineOk(&c.Controller, map[string]interface{}{"id": row.ID})
}
@@ -351,6 +356,10 @@ func (c *BackendCrmPaybackController) Update() {
// 已回款金额一律以「回款记录」为准重新汇总:
// 明细里不承载实收数据,若此处按明细重算,编辑计划(如调整回款日期)会把已回款冲成 0。
refreshPlanReceived(tenantID, row.ID)
// 回款逾期联动:调整计划日期 / 金额后,合同 / 项目状态即时生效
if row.ContractID != nil {
services.SyncPaybackOverdueForContract(tenantID, *row.ContractID)
}
crmWriteLog(tenantID, 4, row.ID, "update", "更新回款计划:"+row.ContractName, claims)
pipelineOk(&c.Controller, map[string]interface{}{"id": row.ID})
}
@@ -539,6 +548,10 @@ func (c *BackendCrmPaybackController) Receive() {
return
}
crmWriteLog(tenantID, 4, row.ID, "receive", fmt.Sprintf("回款登记:%s 第 %d 期 %s 元", row.ContractName, p.Seq, formatAmount(p.ReceivedAmount)), claims)
// 回款逾期联动:登记金额变化后,合同 / 项目状态即时生效
if row.ContractID != nil {
services.SyncPaybackOverdueForContract(tenantID, *row.ContractID)
}
pipelineOk(&c.Controller, buildPaybackResp(&row))
}
@@ -759,6 +772,7 @@ func (c *BackendCrmPaybackController) CreateRecord() {
raw, _ := io.ReadAll(c.Ctx.Request.Body)
var p struct {
PaybackID uint64 `json:"payback_id"`
ItemSeq int `json:"item_seq"` // 对应计划明细序号(1-based),0=未指定(按整单登记)
Amount float64 `json:"amount"`
ReceivedDate string `json:"received_date"`
PayMethod int8 `json:"pay_method"`
@@ -791,6 +805,22 @@ func (c *BackendCrmPaybackController) CreateRecord() {
if payMethod <= 0 {
payMethod = plan.PayMethod
}
// 进度节点:指定 item_seq 时校验其在计划明细中存在,并留存节点名称快照
itemSeq := 0
itemName := ""
if p.ItemSeq > 0 {
for _, it := range parsePaybackItems(plan.Items) {
if it.Seq == p.ItemSeq {
itemSeq = it.Seq
itemName = it.Name
break
}
}
if itemSeq == 0 {
pipelineErr(&c.Controller, 400, 400, "计划明细节点不存在")
return
}
}
var contractID *uint64
if plan.ContractID != nil {
cid := *plan.ContractID
@@ -801,6 +831,8 @@ func (c *BackendCrmPaybackController) CreateRecord() {
TenantID: tenantID,
ContractID: contractID,
PaybackID: plan.ID,
ItemSeq: itemSeq,
ItemName: itemName,
Amount: round2(p.Amount),
ReceivedDate: strings.TrimSpace(p.ReceivedDate),
PayMethod: payMethod,
@@ -863,6 +895,10 @@ func (c *BackendCrmPaybackController) DeleteRecord() {
return
}
refreshPlanReceived(tenantID, row.PaybackID)
// 回款逾期联动:删除回款记录后可能转为逾期,合同 / 项目状态即时生效
if row.ContractID != nil {
services.SyncPaybackOverdueForContract(tenantID, *row.ContractID)
}
pipelineOk(&c.Controller, map[string]interface{}{"id": id})
}