更新若干功能
This commit is contained in:
1 parent
892ba5886d
commit
79d5ae6b66
45 files changed
+6755
-38
No files matched your search
@@ -348,6 +348,10 @@ func (c *BackendCrmBusinessController) ChangeStage() {
|
||||
pipelineErr(&c.Controller, 400, 400, "商机已转化并锁定,不能流转阶段")
|
||||
return
|
||||
}
|
||||
if biz.Status == 3 {
|
||||
pipelineErr(&c.Controller, 400, 400, "商机已废弃,请先恢复为「跟进中」再流转阶段")
|
||||
return
|
||||
}
|
||||
// 阶段未变化:直接幂等返回,不写日志
|
||||
if strings.TrimSpace(biz.Stage) == stage {
|
||||
pipelineOk(&c.Controller, map[string]interface{}{"id": biz.ID, "stage": biz.Stage})
|
||||
@@ -364,6 +368,78 @@ func (c *BackendCrmBusinessController) ChangeStage() {
|
||||
pipelineOk(&c.Controller, map[string]interface{}{"id": biz.ID, "stage": stage})
|
||||
}
|
||||
|
||||
// ChangeStatus POST /backend/crm/business/:id/status
|
||||
// 商机状态流转:1跟进中 / 3已废弃。
|
||||
// 「已转化项目(2)」不走本接口,须用「转项目」完成(会锁定商机)。
|
||||
func (c *BackendCrmBusinessController) ChangeStatus() {
|
||||
claims, err := pipelineClaims(&c.Controller)
|
||||
if err != nil {
|
||||
code := identity.Status(err)
|
||||
pipelineErr(&c.Controller, code, code, err.Error())
|
||||
return
|
||||
}
|
||||
id, _ := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||
if id == 0 {
|
||||
pipelineErr(&c.Controller, 400, 400, "无效的ID")
|
||||
return
|
||||
}
|
||||
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
||||
var p struct {
|
||||
Status int8 `json:"status"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &p); err != nil {
|
||||
pipelineErr(&c.Controller, 400, 400, "参数错误")
|
||||
return
|
||||
}
|
||||
if p.Status != 1 && p.Status != 3 {
|
||||
pipelineErr(&c.Controller, 400, 400, "仅支持流转为「跟进中 / 已废弃」,转为已转化项目请使用「转项目」")
|
||||
return
|
||||
}
|
||||
tenantID := pipelineTenantID(claims)
|
||||
var biz models.TenantCrmBusiness
|
||||
if err := models.Orm.QueryTable(new(models.TenantCrmBusiness)).
|
||||
Filter("id", id).Filter("tenant_id", tenantID).
|
||||
Filter("delete_time__isnull", true).One(&biz); err != nil {
|
||||
pipelineErr(&c.Controller, 404, 404, "商机未找到")
|
||||
return
|
||||
}
|
||||
// 数据范围校验:非管理员仅能操作本人(负责人或创建人)的数据
|
||||
if !canAccessCrmRecord(claims, biz.OwnerUserID, biz.CreateUserID) {
|
||||
pipelineErr(&c.Controller, 403, 403, "无权操作该商机数据")
|
||||
return
|
||||
}
|
||||
if biz.Locked == 1 || biz.Status == 2 {
|
||||
pipelineErr(&c.Controller, 400, 400, "商机已转化并锁定,不能流转状态")
|
||||
return
|
||||
}
|
||||
// 状态未变化:直接幂等返回,不写日志
|
||||
if biz.Status == p.Status {
|
||||
pipelineOk(&c.Controller, map[string]interface{}{"id": biz.ID, "status": biz.Status})
|
||||
return
|
||||
}
|
||||
if _, err := models.Orm.QueryTable(new(models.TenantCrmBusiness)).
|
||||
Filter("id", id).Filter("tenant_id", tenantID).
|
||||
Update(map[string]interface{}{"status": p.Status, "update_time": time.Now()}); err != nil {
|
||||
pipelineErr(&c.Controller, 500, 500, "状态更新失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
crmWriteLog(tenantID, 2, biz.ID, "status",
|
||||
fmt.Sprintf("商机状态:%s → %s", businessStatusName(biz.Status), businessStatusName(p.Status)), claims)
|
||||
pipelineOk(&c.Controller, map[string]interface{}{"id": biz.ID, "status": p.Status})
|
||||
}
|
||||
|
||||
// businessStatusName 商机状态文案(用于操作日志):1跟进中 / 2已转化项目 / 3已废弃
|
||||
func businessStatusName(s int8) string {
|
||||
switch s {
|
||||
case 2:
|
||||
return "已转化项目"
|
||||
case 3:
|
||||
return "已废弃"
|
||||
default:
|
||||
return "跟进中"
|
||||
}
|
||||
}
|
||||
|
||||
// businessStageName 商机阶段文案(用于操作日志):1初步接洽 … 5赢单 / 6输单
|
||||
func businessStageName(s string) string {
|
||||
switch strings.TrimSpace(s) {
|
||||
@@ -480,6 +556,10 @@ func (c *BackendCrmBusinessController) Convert() {
|
||||
pipelineErr(&c.Controller, 400, 400, "商机已转化,不能重复转化")
|
||||
return
|
||||
}
|
||||
if biz.Status == 3 {
|
||||
pipelineErr(&c.Controller, 400, 400, "商机已废弃,请先恢复为「跟进中」再转项目")
|
||||
return
|
||||
}
|
||||
|
||||
projectName := strings.TrimSpace(p.ProjectName)
|
||||
if projectName == "" {
|
||||
|
||||
Reference in new issue
Block a user