修复个人中心问题
This commit is contained in:
@@ -121,8 +121,9 @@ func (c *BackendCrmContractController) List() {
|
||||
cond = cond.And("project_id", pid)
|
||||
}
|
||||
}
|
||||
// 周期筛选:与顶部统计同口径(合同有效期 [生效日期, 结束日期] 与所选周期重叠),
|
||||
// period=month/quarter/year 取当期区间,period=custom 用 start_date / end_date
|
||||
// 周期筛选:按「签订日期」归类(与顶部统计同口径)——签订日期落在所选周期内即命中。
|
||||
// period=month/quarter/year 取当期区间,period=custom 用 start_date / end_date;
|
||||
// 签订日期为空的合同(草稿 / 尚未填写)不受周期限制,避免默认「本年」时被隐藏。
|
||||
period := strings.TrimSpace(c.GetString("period"))
|
||||
rangeStart := strings.TrimSpace(c.GetString("start_date"))
|
||||
rangeEnd := strings.TrimSpace(c.GetString("end_date"))
|
||||
@@ -130,67 +131,21 @@ func (c *BackendCrmContractController) List() {
|
||||
rangeStart, rangeEnd = periodRange(period)
|
||||
}
|
||||
if rangeStart != "" {
|
||||
cond = cond.AndCond(orm.NewCondition().Or("expire_date__isnull", true).Or("expire_date__gte", rangeStart))
|
||||
cond = cond.AndCond(orm.NewCondition().Or("sign_date__isnull", true).Or("sign_date__gte", rangeStart))
|
||||
}
|
||||
if rangeEnd != "" {
|
||||
cond = cond.AndCond(orm.NewCondition().Or("effective_date__isnull", true).Or("effective_date__lte", rangeEnd))
|
||||
cond = cond.AndCond(orm.NewCondition().Or("sign_date__isnull", true).Or("sign_date__lte", rangeEnd))
|
||||
}
|
||||
qs := models.Orm.QueryTable(new(models.TenantCrmContract)).SetCond(cond)
|
||||
|
||||
total, _ := qs.Count()
|
||||
var list []models.TenantCrmContract
|
||||
if total > 0 {
|
||||
offset := (page - 1) * pageSize
|
||||
if status != "" {
|
||||
// 已按状态筛选:结果只含单一状态,直接按新→旧分页
|
||||
if _, err := qs.OrderBy("-id").Offset(offset).Limit(pageSize).All(&list); err != nil {
|
||||
pipelineErr(&c.Controller, 500, 500, "查询失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// 列表排列:按状态分组展示 —— 草稿(1) → 异常(5) → 履约中(4) → 已完成(2) → 已作废(3),
|
||||
// 其余状态(NULL / 历史异常值)沉底;组内仍按新→旧。
|
||||
// 先统计各组数量,把当前页窗口换算成各组区间,再分别取数按序拼接,保证翻页后整体顺序一致。
|
||||
groupConds := []*orm.Condition{
|
||||
orm.NewCondition().And("status", 1),
|
||||
orm.NewCondition().And("status", 5),
|
||||
orm.NewCondition().And("status", 4),
|
||||
orm.NewCondition().And("status", 2),
|
||||
orm.NewCondition().And("status", 3),
|
||||
orm.NewCondition().AndNot("status__in", []int8{1, 5, 4, 2, 3}).Or("status__isnull", true),
|
||||
}
|
||||
end := offset + pageSize
|
||||
if end > int(total) {
|
||||
end = int(total)
|
||||
}
|
||||
cursor := 0
|
||||
for _, gc := range groupConds {
|
||||
if cursor >= end {
|
||||
break
|
||||
}
|
||||
// 注意:beego 的 AndCond 会修改接收者,这里用新条件对象包装,避免循环内条件累积
|
||||
groupCond := orm.NewCondition().AndCond(cond).AndCond(gc)
|
||||
cnt, _ := models.Orm.QueryTable(new(models.TenantCrmContract)).SetCond(groupCond).Count()
|
||||
groupTotal := int(cnt)
|
||||
if groupTotal == 0 {
|
||||
continue
|
||||
}
|
||||
groupStart := cursor
|
||||
groupEnd := cursor + groupTotal
|
||||
cursor = groupEnd
|
||||
// 当前页与本组区间的交集
|
||||
from, to := max(offset, groupStart), min(end, groupEnd)
|
||||
if to <= from {
|
||||
continue
|
||||
}
|
||||
var part []models.TenantCrmContract
|
||||
if _, err := models.Orm.QueryTable(new(models.TenantCrmContract)).SetCond(groupCond).
|
||||
OrderBy("-id").Offset(from - groupStart).Limit(to - from).All(&part); err != nil {
|
||||
pipelineErr(&c.Controller, 500, 500, "查询失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
list = append(list, part...)
|
||||
}
|
||||
// 列表排列:按「签订日期」倒序,最新签约的合同排最前。
|
||||
// 同日签约多份时按 id 倒序,保证翻页顺序稳定;签订日期为空的合同(草稿 / 尚未签约)沉底。
|
||||
if _, err := qs.OrderBy("-sign_date", "-id").Offset((page - 1) * pageSize).Limit(pageSize).All(&list); err != nil {
|
||||
pipelineErr(&c.Controller, 500, 500, "查询失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
// 回款逾期日期(取最早,未收齐且已过计划回款日期):合同「逾期」标签与结束日期口径一并参考
|
||||
@@ -216,7 +171,7 @@ func (c *BackendCrmContractController) List() {
|
||||
// Stats GET /backend/crm/contract/stats
|
||||
// 全租户合同统计(排除已作废),供列表页顶部汇总卡片使用。
|
||||
// 支持按周期筛选:period=month/quarter/year(当期)或 custom(start_date~end_date),
|
||||
// 按合同有效期 [生效日期, 结束日期] 与所选周期重叠统计。
|
||||
// 按合同「签订日期」落在所选周期内统计(与列表口径一致)。
|
||||
// 「合同总利润」仅统计非甲方(收款方)合同:我方为甲方的合同是采购付款,只有支出、不存在利润。
|
||||
func (c *BackendCrmContractController) Stats() {
|
||||
claims, err := pipelineClaims(&c.Controller)
|
||||
@@ -236,14 +191,14 @@ func (c *BackendCrmContractController) Stats() {
|
||||
// 我方不参与的合同(our_role=0,如上中游项目的链条合同)不属于我方经营合同,不计入经营统计
|
||||
where := "tenant_id = ? AND delete_time IS NULL AND status <> 3 AND our_role <> 0"
|
||||
args := []interface{}{tenantID}
|
||||
// 按合同有效期 [生效日期, 结束日期] 与所选周期 [start, end] 重叠来统计:
|
||||
// 合同生效日 <= 周期末 且 合同结束日 >= 周期初;日期为空视为不限制对应边界。
|
||||
// 按「签订日期」落在所选周期 [start, end] 内统计(与列表口径一致):
|
||||
// 签订日期为空的合同不受周期限制,视为不限制对应边界。
|
||||
if start != "" {
|
||||
where += " AND (expire_date IS NULL OR expire_date >= ?)"
|
||||
where += " AND (sign_date IS NULL OR sign_date >= ?)"
|
||||
args = append(args, start)
|
||||
}
|
||||
if end != "" {
|
||||
where += " AND (effective_date IS NULL OR effective_date <= ?)"
|
||||
where += " AND (sign_date IS NULL OR sign_date <= ?)"
|
||||
args = append(args, end)
|
||||
}
|
||||
// 「合同总利润」只汇总非甲方(收款方)合同:我方为甲方时是采购付款方,合同金额即支出,不存在利润
|
||||
@@ -268,7 +223,7 @@ func (c *BackendCrmContractController) Stats() {
|
||||
}
|
||||
|
||||
// periodRange 根据 period 返回当期区间 [start, end](YYYY-MM-DD):month/quarter/year。
|
||||
// 统计与列表均以该区间与合同有效期比较(有效期与周期重叠即命中)。
|
||||
// 统计与列表均以该区间与合同「签订日期」比较(签订日期落在区间内即命中)。
|
||||
func periodRange(period string) (string, string) {
|
||||
now := time.Now()
|
||||
loc := now.Location()
|
||||
|
||||
Reference in New Issue
Block a user