优化项目管理

This commit is contained in:
2026-09-13 22:31:42 +08:00
parent 2f6cdbb3cd
commit a8c09c1db5
30 changed files with 1654 additions and 346 deletions
+48 -20
View File
@@ -64,6 +64,8 @@ func (c *BackendCrmBusinessController) List() {
tenantID := pipelineTenantID(claims)
cond := orm.NewCondition().And("tenant_id", tenantID).And("delete_time__isnull", true)
// 数据范围:平台/租户管理员可见全部,其他用户仅本人(负责人或创建人)
cond = crmApplyOwnerScope(cond, claims)
if keyword != "" {
kw := orm.NewCondition().
Or("business_name__contains", keyword).
@@ -195,6 +197,11 @@ func (c *BackendCrmBusinessController) Create() {
CreateTime: now,
UpdateTime: now,
}
// 唯一性校验:同租户内不允许重复创建同名商机(重复数据请联系管理员转移跟进)
if crmNameDuplicated(new(models.TenantCrmBusiness), tenantID, "business_name", biz.BusinessName) {
pipelineErr(&c.Controller, 409, 409, "该商机名称已存在(可能由其他同事创建),如需继续跟进请联系管理员转移")
return
}
id, err := models.Orm.Insert(&biz)
if err != nil {
pipelineErr(&c.Controller, 500, 500, "创建失败: "+err.Error())
@@ -230,6 +237,11 @@ func (c *BackendCrmBusinessController) Update() {
pipelineErr(&c.Controller, 404, 404, "商机未找到")
return
}
// 数据范围校验:非管理员仅能操作本人(负责人或创建人)的数据
if !canAccessCrmRecord(claims, biz.OwnerUserID, biz.CreateUserID) {
pipelineErr(&c.Controller, 403, 403, "无权操作该商机数据")
return
}
if biz.Locked == 1 {
pipelineErr(&c.Controller, 400, 400, "商机已转为项目并锁定,不能编辑")
return
@@ -306,6 +318,11 @@ func (c *BackendCrmBusinessController) Delete() {
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
@@ -359,6 +376,11 @@ func (c *BackendCrmBusinessController) Convert() {
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
@@ -375,27 +397,33 @@ func (c *BackendCrmBusinessController) Convert() {
now := time.Now()
bizIDVal := biz.ID
proj := models.TenantCrmProject{
TenantID: tenantID,
ProjectName: projectName,
ProjectNo: strings.TrimSpace(p.ProjectNo),
BusinessID: &bizIDVal,
CustomerID: biz.CustomerID,
CustomerName: biz.CustomerName,
OwnerUserID: biz.OwnerUserID,
OwnerUserName: biz.OwnerUserName,
Industry: biz.Industry,
Amount: amount,
Status: 1,
StartDate: parsePipelineDate(p.StartDate),
EndDate: parsePipelineDate(p.EndDate),
ContactPerson: biz.ContactPerson,
TenantID: tenantID,
ProjectName: projectName,
ProjectNo: strings.TrimSpace(p.ProjectNo),
// 商机转化默认按「单一项目」创建:金额与对接人先落到上游侧,
// 后续可在项目中选择「上下游项目」并补充下游供应商 / 金额 / 对接人
ProjectType: 1,
BusinessID: &bizIDVal,
CustomerID: biz.CustomerID,
CustomerName: biz.CustomerName,
OwnerUserID: biz.OwnerUserID,
OwnerUserName: biz.OwnerUserName,
Industry: biz.Industry,
UpstreamAmount: amount,
Amount: amount, // 兼容旧字段
Status: 1,
StartDate: parsePipelineDate(p.StartDate),
EndDate: parsePipelineDate(p.EndDate),
UpstreamContact: biz.ContactPerson,
UpstreamPhone: biz.ContactPhone,
ContactPerson: biz.ContactPerson,
ContactPosition: biz.ContactPosition,
ContactPhone: biz.ContactPhone,
Address: biz.Address,
Remark: p.Remark,
CreateUserID: pipelineUID(claims),
CreateTime: now,
UpdateTime: now,
ContactPhone: biz.ContactPhone,
Address: biz.Address,
Remark: p.Remark,
CreateUserID: pipelineUID(claims),
CreateTime: now,
UpdateTime: now,
}
projID, err := models.Orm.Insert(&proj)
if err != nil {