|
|
@@ -2204,12 +2204,14 @@ async def opportunity_list(
|
|
|
"""商机分页列表"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
list_body = body or OpportunityListBody()
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
rows, total = list_opportunities(
|
|
|
db,
|
|
|
tenant_no,
|
|
|
user_id,
|
|
|
+ user_info=user_info,
|
|
|
**_opp_list_kwargs(list_body, user_id),
|
|
|
)
|
|
|
return success_response({
|
|
|
@@ -2235,12 +2237,14 @@ async def opportunity_mine_list(
|
|
|
"""我的商机列表"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
list_body = body or OpportunityListBody()
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
rows, total = list_opportunities(
|
|
|
db,
|
|
|
tenant_no,
|
|
|
user_id,
|
|
|
+ user_info=user_info,
|
|
|
**_opp_list_kwargs(list_body, user_id, view_type="mine"),
|
|
|
)
|
|
|
return success_response({
|
|
|
@@ -2266,6 +2270,17 @@ async def opportunity_detail(
|
|
|
"""商机详情"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
+ from app.models.crm_models import CrmOpportunity
|
|
|
+
|
|
|
+ row = db.query(CrmOpportunity).filter(
|
|
|
+ CrmOpportunity.id == body.id,
|
|
|
+ CrmOpportunity.del_flag == 0,
|
|
|
+ CrmOpportunity.tenant_no == tenant_no,
|
|
|
+ ).first()
|
|
|
+ if not row:
|
|
|
+ return error_response(404, "商机不存在")
|
|
|
+ ensure_crm_owner_row_in_scope(db, row, user_info, tenant_no, message="无权访问该商机")
|
|
|
detail = get_opportunity(db, body.id, tenant_no=tenant_no)
|
|
|
if not detail:
|
|
|
return error_response(404, "商机不存在")
|
|
|
@@ -2285,6 +2300,7 @@ async def opportunity_add(
|
|
|
"""新增商机"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
row = create_opportunity(
|
|
|
db,
|
|
|
@@ -2308,10 +2324,11 @@ async def opportunity_update(
|
|
|
"""编辑商机"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
data = body.model_dump(by_alias=False, exclude_unset=True)
|
|
|
oid = data.pop("id")
|
|
|
- row = update_opportunity(db, oid, data, user_id=user_id, tenant_no=tenant_no)
|
|
|
+ row = update_opportunity(db, oid, data, user_id=user_id, tenant_no=tenant_no, user_info=user_info)
|
|
|
return success_response(row, message="更新成功")
|
|
|
except ValueError as e:
|
|
|
return error_response(400, str(e))
|
|
|
@@ -2328,9 +2345,10 @@ async def opportunity_delete(
|
|
|
"""删除商机(软删)"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
count = soft_delete_opportunities(
|
|
|
- db, body.ids, user_id=user_id, tenant_no=tenant_no
|
|
|
+ db, body.ids, user_id=user_id, tenant_no=tenant_no, user_info=user_info
|
|
|
)
|
|
|
return success_response({"count": count}, message="删除成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2348,6 +2366,7 @@ async def opportunity_assign(
|
|
|
"""分配商机"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
count = assign_opportunities(
|
|
|
db,
|
|
|
@@ -2356,6 +2375,7 @@ async def opportunity_assign(
|
|
|
user_id=user_id,
|
|
|
remark=body.remark,
|
|
|
tenant_no=tenant_no,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response({"count": count}, message="分配成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2373,6 +2393,7 @@ async def opportunity_change_stage(
|
|
|
"""变更商机阶段"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
row = change_stage(
|
|
|
db,
|
|
|
@@ -2384,6 +2405,7 @@ async def opportunity_change_stage(
|
|
|
remark=body.remark,
|
|
|
user_id=user_id,
|
|
|
tenant_no=tenant_no,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(row, message="阶段已更新")
|
|
|
except ValueError as e:
|
|
|
@@ -2401,6 +2423,7 @@ async def opportunity_mark_won(
|
|
|
"""标记赢单"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
row = mark_won(
|
|
|
db,
|
|
|
@@ -2410,6 +2433,7 @@ async def opportunity_mark_won(
|
|
|
remark=body.remark,
|
|
|
user_id=user_id,
|
|
|
tenant_no=tenant_no,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(row, message="已标记赢单")
|
|
|
except ValueError as e:
|
|
|
@@ -2427,6 +2451,7 @@ async def opportunity_mark_lost(
|
|
|
"""标记输单"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
row = mark_lost(
|
|
|
db,
|
|
|
@@ -2437,6 +2462,7 @@ async def opportunity_mark_lost(
|
|
|
improvement=body.improvement,
|
|
|
user_id=user_id,
|
|
|
tenant_no=tenant_no,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(row, message="已标记输单")
|
|
|
except ValueError as e:
|
|
|
@@ -2454,6 +2480,7 @@ async def opportunity_batch_update_stage(
|
|
|
"""批量变更阶段"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
result = batch_update_stage(
|
|
|
db,
|
|
|
@@ -2464,6 +2491,7 @@ async def opportunity_batch_update_stage(
|
|
|
body.change_reason,
|
|
|
tenant_no=tenant_no,
|
|
|
user_id=user_id,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(result)
|
|
|
except ValueError as e:
|
|
|
@@ -2481,6 +2509,7 @@ async def opportunity_batch_update_expect_date(
|
|
|
"""批量修改预计成交日期"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
result = batch_update_expect_date(
|
|
|
db,
|
|
|
@@ -2490,6 +2519,7 @@ async def opportunity_batch_update_expect_date(
|
|
|
days=body.days,
|
|
|
tenant_no=tenant_no,
|
|
|
user_id=user_id,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(result)
|
|
|
except ValueError as e:
|
|
|
@@ -2507,7 +2537,8 @@ async def opportunity_stage_log_list(
|
|
|
"""商机阶段变更日志"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
- logs = get_stage_log_list(db, body.opportunity_id, tenant_no=tenant_no)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
+ logs = get_stage_log_list(db, body.opportunity_id, tenant_no=tenant_no, user_info=user_info)
|
|
|
return success_response(logs)
|
|
|
except ValueError as e:
|
|
|
return error_response(400, str(e))
|
|
|
@@ -2524,6 +2555,7 @@ async def opportunity_kanban(
|
|
|
"""看板数据"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
list_body = body or OpportunityKanbanBody()
|
|
|
list_kwargs = _opp_list_kwargs(list_body, "")
|
|
|
data = get_kanban_data(
|
|
|
@@ -2536,6 +2568,7 @@ async def opportunity_kanban(
|
|
|
"create_time_start": list_kwargs["create_time_start"],
|
|
|
"create_time_end": list_kwargs["create_time_end"],
|
|
|
},
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(data)
|
|
|
except ValueError as e:
|
|
|
@@ -2553,10 +2586,12 @@ async def opportunity_statistics_overview(
|
|
|
"""商机统计概览"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
stat_body = body or OpportunityStatisticsBody()
|
|
|
data = get_statistics_overview(
|
|
|
db,
|
|
|
tenant_no,
|
|
|
+ user_info=user_info,
|
|
|
owner_user_id=stat_body.owner_user_id,
|
|
|
begin_time=stat_body.begin_time,
|
|
|
end_time=stat_body.end_time,
|
|
|
@@ -2576,7 +2611,8 @@ async def opportunity_statistics_stage(
|
|
|
"""按阶段统计"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
- return success_response(get_statistics_by_stage(db, tenant_no))
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
+ return success_response(get_statistics_by_stage(db, tenant_no, user_info=user_info))
|
|
|
except ValueError as e:
|
|
|
return error_response(400, str(e))
|
|
|
except Exception as e:
|
|
|
@@ -2592,6 +2628,7 @@ async def opportunity_statistics_win_rate(
|
|
|
"""赢单率趋势"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
stat_body = body or OpportunityStatisticsBody()
|
|
|
data = get_win_rate_statistics(
|
|
|
db,
|
|
|
@@ -2599,6 +2636,7 @@ async def opportunity_statistics_win_rate(
|
|
|
stat_type=stat_body.type or "month",
|
|
|
begin_time=stat_body.begin_time,
|
|
|
end_time=stat_body.end_time,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(data)
|
|
|
except ValueError as e:
|
|
|
@@ -2616,12 +2654,14 @@ async def opportunity_statistics_owner(
|
|
|
"""按负责人统计"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
stat_body = body or OpportunityStatisticsBody()
|
|
|
data = get_statistics_by_owner(
|
|
|
db,
|
|
|
tenant_no,
|
|
|
begin_time=stat_body.begin_time,
|
|
|
end_time=stat_body.end_time,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(data)
|
|
|
except ValueError as e:
|
|
|
@@ -2639,6 +2679,7 @@ async def opportunity_statistics_funnel(
|
|
|
"""销售漏斗"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
stat_body = body or OpportunityStatisticsBody()
|
|
|
data = get_sales_funnel(
|
|
|
db,
|
|
|
@@ -2646,6 +2687,7 @@ async def opportunity_statistics_funnel(
|
|
|
owner_user_id=stat_body.owner_user_id,
|
|
|
begin_time=stat_body.begin_time,
|
|
|
end_time=stat_body.end_time,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(data)
|
|
|
except ValueError as e:
|
|
|
@@ -2663,12 +2705,14 @@ async def opportunity_follow_list(
|
|
|
"""商机跟进列表"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
rows, total = list_opportunity_follows(
|
|
|
db,
|
|
|
opportunity_id=body.opportunity_id,
|
|
|
page=body.page,
|
|
|
page_size=body.pageSize,
|
|
|
tenant_no=tenant_no,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response({
|
|
|
"list": rows,
|
|
|
@@ -2693,12 +2737,14 @@ async def opportunity_follow_add(
|
|
|
"""新增商机跟进"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
row = create_opportunity_follow(
|
|
|
db,
|
|
|
tenant_no,
|
|
|
body.model_dump(by_alias=False, exclude_unset=True),
|
|
|
user_id=user_id,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(row, message="创建成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2716,11 +2762,12 @@ async def opportunity_follow_update(
|
|
|
"""编辑商机跟进"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
data = body.model_dump(by_alias=False, exclude_unset=True)
|
|
|
fid = data.pop("id")
|
|
|
row = update_opportunity_follow(
|
|
|
- db, fid, data, user_id=user_id, tenant_no=tenant_no
|
|
|
+ db, fid, data, user_id=user_id, tenant_no=tenant_no, user_info=user_info
|
|
|
)
|
|
|
return success_response(row, message="更新成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2738,11 +2785,12 @@ async def opportunity_follow_delete(
|
|
|
"""删除商机跟进"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
count = 0
|
|
|
for fid in body.ids:
|
|
|
if soft_delete_opportunity_follow(
|
|
|
- db, fid, user_id=user_id, tenant_no=tenant_no
|
|
|
+ db, fid, user_id=user_id, tenant_no=tenant_no, user_info=user_info
|
|
|
):
|
|
|
count += 1
|
|
|
return success_response({"count": count}, message="删除成功")
|
|
|
@@ -2761,7 +2809,8 @@ async def opportunity_follow_detail(
|
|
|
"""商机跟进详情"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
- row = get_opportunity_follow(db, body.id, tenant_no=tenant_no)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
+ row = get_opportunity_follow(db, body.id, tenant_no=tenant_no, user_info=user_info)
|
|
|
if not row:
|
|
|
return error_response(404, "跟进记录不存在")
|
|
|
return success_response(row)
|
|
|
@@ -2780,6 +2829,7 @@ async def opportunity_product_list(
|
|
|
"""商机产品列表"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
rows, total = list_opportunity_products(
|
|
|
db,
|
|
|
opportunity_id=body.opportunity_id,
|
|
|
@@ -2787,6 +2837,7 @@ async def opportunity_product_list(
|
|
|
page=body.page,
|
|
|
page_size=body.pageSize,
|
|
|
tenant_no=tenant_no,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response({
|
|
|
"list": rows,
|
|
|
@@ -2811,10 +2862,11 @@ async def opportunity_product_list_by_opportunity(
|
|
|
"""按商机查询产品列表"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
opp_id = (body.opportunity_id or body.id) if body else None
|
|
|
if not opp_id:
|
|
|
return error_response(400, "缺少商机ID")
|
|
|
- rows = list_products_by_opportunity(db, opp_id, tenant_no=tenant_no)
|
|
|
+ rows = list_products_by_opportunity(db, opp_id, tenant_no=tenant_no, user_info=user_info)
|
|
|
return success_response(rows)
|
|
|
except ValueError as e:
|
|
|
return error_response(400, str(e))
|
|
|
@@ -2831,12 +2883,14 @@ async def opportunity_product_add(
|
|
|
"""新增商机产品"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
row = create_opportunity_product(
|
|
|
db,
|
|
|
tenant_no,
|
|
|
body.model_dump(by_alias=False, exclude_unset=True),
|
|
|
user_id=user_id,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response(row, message="创建成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2854,6 +2908,7 @@ async def opportunity_product_batch_add(
|
|
|
"""批量添加商机产品"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
product_list = [
|
|
|
p.model_dump(by_alias=False, exclude_unset=True)
|
|
|
@@ -2865,6 +2920,7 @@ async def opportunity_product_batch_add(
|
|
|
body.opportunity_id,
|
|
|
product_list,
|
|
|
user_id=user_id,
|
|
|
+ user_info=user_info,
|
|
|
)
|
|
|
return success_response({"count": count}, message="批量添加成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2882,11 +2938,12 @@ async def opportunity_product_update(
|
|
|
"""编辑商机产品"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
data = body.model_dump(by_alias=False, exclude_unset=True)
|
|
|
pid = data.pop("id")
|
|
|
row = update_opportunity_product(
|
|
|
- db, pid, data, user_id=user_id, tenant_no=tenant_no
|
|
|
+ db, pid, data, user_id=user_id, tenant_no=tenant_no, user_info=user_info
|
|
|
)
|
|
|
return success_response(row, message="更新成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2904,9 +2961,10 @@ async def opportunity_product_delete(
|
|
|
"""删除商机产品"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
count = soft_delete_opportunity_products(
|
|
|
- db, body.ids, user_id=user_id, tenant_no=tenant_no
|
|
|
+ db, body.ids, user_id=user_id, tenant_no=tenant_no, user_info=user_info
|
|
|
)
|
|
|
return success_response({"count": count}, message="删除成功")
|
|
|
except ValueError as e:
|
|
|
@@ -2924,7 +2982,8 @@ async def opportunity_product_detail(
|
|
|
"""商机产品详情"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
- row = get_opportunity_product(db, body.id, tenant_no=tenant_no)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
+ row = get_opportunity_product(db, body.id, tenant_no=tenant_no, user_info=user_info)
|
|
|
if not row:
|
|
|
return error_response(404, "商机产品不存在")
|
|
|
return success_response(row)
|
|
|
@@ -2943,12 +3002,14 @@ async def opportunity_export(
|
|
|
"""导出商机列表"""
|
|
|
try:
|
|
|
tenant_no = get_tenant_no(db, _user)
|
|
|
+ user_info = crm_user_info(_user)
|
|
|
list_body = body or OpportunityListBody()
|
|
|
user_id = _user.get("user_id", "") or _user.get("id", "")
|
|
|
rows, _ = list_opportunities(
|
|
|
db,
|
|
|
tenant_no,
|
|
|
user_id,
|
|
|
+ user_info=user_info,
|
|
|
**_opp_list_kwargs(list_body, user_id),
|
|
|
page=1,
|
|
|
page_size=10000,
|