You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
10 KiB
229 lines
10 KiB
|
2 weeks ago
|
# -*- coding: utf-8 -*-
|
||
|
|
"""第4批:商机详情/主体(9 个)"""
|
||
|
|
import io, sys
|
||
|
|
sys.path.insert(0, 'D:/code/crm-backend-matt/.scratch')
|
||
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
||
|
|
from bru_lib import write_bru, bru_form, build_docs, env_json, req_form_example, req_query_example
|
||
|
|
|
||
|
|
F = '商机模块/商机详情/主体'
|
||
|
|
|
||
|
|
OPP_DETAIL_RESP = [
|
||
|
|
('id','string','商机 ID'),
|
||
|
|
('createTime','string','创建时间'),
|
||
|
|
('updateTime','string','更新时间'),
|
||
|
|
('oppName','string','商机名称'),
|
||
|
|
('oppStatus','number','状态:1待领取 2推进中 3暂缓中 4已关闭 5已转项目'),
|
||
|
|
('oppSource','string','商机来源字典 code'),
|
||
|
|
('oppType','string','商机类型字典 code'),
|
||
|
|
('industryCode','string','行业字典 code'),
|
||
|
|
('industryName','string','行业名称(出参回显)'),
|
||
|
|
('bidForm','string','招标形式字典 code'),
|
||
|
|
('localityType','string','项目属地字典 code'),
|
||
|
|
('partyAClear','number','甲方是否明确'),
|
||
|
|
('partyA','string','甲方名称'),
|
||
|
|
('provinceCode','string','省份国标 code'),
|
||
|
|
('provinceName','string','省份名称(出参回显)'),
|
||
|
|
('cityCode','string','市/区国标 code'),
|
||
|
|
('cityName','string','市/区名称(出参回显)'),
|
||
|
|
('projectAmount','number','项目金额'),
|
||
|
|
('ownerUserId','string','负责人 ID'),
|
||
|
|
('ownerNameSnapshot','string','负责人姓名快照'),
|
||
|
|
('ownerDeptId','string','负责人部门 ID'),
|
||
|
|
('ownerDeptName','string','负责人部门名称(出参回显)'),
|
||
|
|
('currentStageId','string','当前阶段节点 ID'),
|
||
|
|
('currentStageName','string','当前阶段名称(出参回显)'),
|
||
|
|
('stageStayDays','number','节点停留天数(出参回显)'),
|
||
|
|
('nextStageName','string','下一节点名称(出参回显)'),
|
||
|
|
('sourceLeadId','string','来源线索 ID'),
|
||
|
|
('primaryCustomerId','string','主要意向客户 ID'),
|
||
|
|
('primaryCustomerNameSnapshot','string','主客户名快照'),
|
||
|
|
('lastFollowTime','string','最近跟进时间(出参回显)'),
|
||
|
|
('schemeCardStatus','number','方案卡状态(出参回显)'),
|
||
|
|
('schemeBudget','number','方案预算(出参回显)'),
|
||
|
|
('followed','boolean','当前用户是否已关注(出参回显)'),
|
||
|
|
('remark','string','备注'),
|
||
|
|
]
|
||
|
|
|
||
|
|
OPP_DETAIL_JSON = env_json('''{
|
||
|
|
"id": "1",
|
||
|
|
"createTime": "2024-01-01 12:00:00",
|
||
|
|
"updateTime": "2024-01-01 12:00:00",
|
||
|
|
"oppName": "示例商机",
|
||
|
|
"oppStatus": 2,
|
||
|
|
"oppSource": "source_01",
|
||
|
|
"oppType": "type_01",
|
||
|
|
"industryCode": "ind_01",
|
||
|
|
"industryName": "示例行业",
|
||
|
|
"projectAmount": 1000000,
|
||
|
|
"ownerUserId": "1",
|
||
|
|
"ownerNameSnapshot": "张三",
|
||
|
|
"ownerDeptName": "华北大区",
|
||
|
|
"currentStageName": "需求确认",
|
||
|
|
"stageStayDays": 3,
|
||
|
|
"nextStageName": "方案报价",
|
||
|
|
"followed": true,
|
||
|
|
"remark": "备注示例"
|
||
|
|
}''')
|
||
|
|
|
||
|
|
# 商机详情
|
||
|
|
docs = build_docs(
|
||
|
|
'商机详情', 'GET', '/api/opportunity/detail',
|
||
|
|
'详情页顶部主体信息。打开详情页时与「上报访问」同步调用(前端可并行发起)。',
|
||
|
|
[('id','string','是','-','商机 ID')],
|
||
|
|
req_query_example('GET', '/api/opportunity/detail', [('id','1')]),
|
||
|
|
OPP_DETAIL_RESP, OPP_DETAIL_JSON,
|
||
|
|
)
|
||
|
|
write_bru(F, '商机详情.bru', bru_form(1, '商机详情', 'get', '/api/opportunity/detail', [('id','1')], docs))
|
||
|
|
|
||
|
|
# 编辑商机
|
||
|
|
EDIT_PARAMS = [
|
||
|
|
('id','string','是','-','商机 ID'),
|
||
|
|
('oppName','string','否','-','商机名称'),
|
||
|
|
('oppSource','string','否','-','商机来源字典 code'),
|
||
|
|
('oppType','string','否','-','商机类型字典 code'),
|
||
|
|
('industryCode','string','否','-','行业字典 code'),
|
||
|
|
('bidForm','string','否','-','招标形式字典 code'),
|
||
|
|
('localityType','string','否','-','项目属地字典 code'),
|
||
|
|
('partyAClear','number','否','-','甲方是否明确:1是 0否'),
|
||
|
|
('partyA','string','否','-','甲方名称'),
|
||
|
|
('provinceCode','string','否','-','省份国标 code'),
|
||
|
|
('cityCode','string','否','-','市/区国标 code'),
|
||
|
|
('projectAmount','number','否','-','项目金额'),
|
||
|
|
('primaryCustomerId','string','否','-','主要意向客户 ID'),
|
||
|
|
('remark','string','否','-','备注'),
|
||
|
|
]
|
||
|
|
docs = build_docs(
|
||
|
|
'编辑商机', 'POST', '/api/opportunity/edit',
|
||
|
|
'详情页「编辑」保存。仅传需变更的字段(null 不更新),字段级 oplog 自动记录变更前后值。',
|
||
|
|
EDIT_PARAMS,
|
||
|
|
req_form_example('POST', '/api/opportunity/edit',
|
||
|
|
[('id','1'),('oppName','更新后商机名称'),('projectAmount','1200000')]),
|
||
|
|
None, env_json('null'),
|
||
|
|
)
|
||
|
|
write_bru(F, '编辑商机.bru', bru_form(2, '编辑商机', 'post', '/api/opportunity/edit',
|
||
|
|
[('id','1'),('oppName','更新后商机名称'),('projectAmount','1200000')], docs))
|
||
|
|
|
||
|
|
# 阶段推进指引
|
||
|
|
STAGE_NODE_RESP = [
|
||
|
|
('oppId','string','商机 ID'),
|
||
|
|
('currentStageId','string','当前阶段节点 ID'),
|
||
|
|
('currentWorkGoal','string','当前节点工作目标(推进指引区展示)'),
|
||
|
|
('nodes','array<object>','有序节点列表'),
|
||
|
|
('nodes[].nodeId','string','节点 ID'),
|
||
|
|
('nodes[].seqNo','number','阶段序号'),
|
||
|
|
('nodes[].stageDictCode','string','阶段字典值'),
|
||
|
|
('nodes[].customNodeName','string','自定义节点名称(空则用字典名)'),
|
||
|
|
('nodes[].workGoal','string','阶段工作目标'),
|
||
|
|
('nodes[].isFixed','number','固定节点:1已转项目固定节点 0普通'),
|
||
|
|
('nodes[].nodeState','string','进度:COMPLETED已完成 / CURRENT当前 / PENDING未到达'),
|
||
|
|
]
|
||
|
|
STAGE_PROGRESS_JSON = env_json('''{
|
||
|
|
"oppId": "1",
|
||
|
|
"currentStageId": "2",
|
||
|
|
"currentWorkGoal": "确认客户预算与决策链",
|
||
|
|
"nodes": [
|
||
|
|
{
|
||
|
|
"nodeId": "1",
|
||
|
|
"seqNo": 1,
|
||
|
|
"stageDictCode": "stage_01",
|
||
|
|
"customNodeName": null,
|
||
|
|
"workGoal": "初步接触",
|
||
|
|
"isFixed": 0,
|
||
|
|
"nodeState": "COMPLETED"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"nodeId": "2",
|
||
|
|
"seqNo": 2,
|
||
|
|
"stageDictCode": "stage_02",
|
||
|
|
"customNodeName": null,
|
||
|
|
"workGoal": "确认客户预算与决策链",
|
||
|
|
"isFixed": 0,
|
||
|
|
"nodeState": "CURRENT"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}''')
|
||
|
|
docs = build_docs(
|
||
|
|
'阶段推进指引', 'GET', '/api/opportunity/stage/progress',
|
||
|
|
'详情页阶段进度组件:展示三态(已完成/当前/未到达)+ 当前节点工作目标。按商机绑定的模板版本展开(锁版本,发新版不迁移)。',
|
||
|
|
[('oppId','string','是','-','商机 ID')],
|
||
|
|
req_query_example('GET', '/api/opportunity/stage/progress', [('oppId','1')]),
|
||
|
|
STAGE_NODE_RESP, STAGE_PROGRESS_JSON,
|
||
|
|
)
|
||
|
|
write_bru(F, '阶段推进指引.bru', bru_form(3, '阶段推进指引', 'get', '/api/opportunity/stage/progress', [('oppId','1')], docs))
|
||
|
|
|
||
|
|
# 阶段推进历史
|
||
|
|
STAGE_HIST_RESP = [
|
||
|
|
('id','string','历史记录 ID'),
|
||
|
|
('oppId','string','商机 ID'),
|
||
|
|
('fromStageId','string','原阶段节点 ID'),
|
||
|
|
('toStageId','string','目标阶段节点 ID'),
|
||
|
|
('operatorUserId','string','操作人 ID(系统动作为 0)'),
|
||
|
|
('operateTime','string','操作时间'),
|
||
|
|
('remark','string','推进说明'),
|
||
|
|
]
|
||
|
|
docs = build_docs(
|
||
|
|
'阶段推进历史', 'GET', '/api/opportunity/stage/history',
|
||
|
|
'按操作时间倒序返回该商机全部阶段推进记录(人工推进 + 系统动作合并展示)。',
|
||
|
|
[('oppId','string','是','-','商机 ID')],
|
||
|
|
req_query_example('GET', '/api/opportunity/stage/history', [('oppId','1')]),
|
||
|
|
STAGE_HIST_RESP,
|
||
|
|
env_json('[\n {\n "id":"1","oppId":"1","fromStageId":"1","toStageId":"2","operatorUserId":"1","operateTime":"2024-01-01 12:00:00","remark":"推进示例"\n }\n ]'),
|
||
|
|
)
|
||
|
|
write_bru(F, '阶段推进历史.bru', bru_form(4, '阶段推进历史', 'get', '/api/opportunity/stage/history', [('oppId','1')], docs))
|
||
|
|
|
||
|
|
# 切换阶段
|
||
|
|
docs = build_docs(
|
||
|
|
'切换阶段', 'POST', '/api/opportunity/stage/switch',
|
||
|
|
'自由切换阶段:允许连跳/回退。「已转项目」固定节点不可手动切(由业务流程触发)。',
|
||
|
|
[('oppId','string','是','-','商机 ID'),
|
||
|
|
('toStageId','string','是','-','目标阶段节点 ID(须属商机绑定的模板版本)'),
|
||
|
|
('remark','string','否','-','推进说明')],
|
||
|
|
req_form_example('POST', '/api/opportunity/stage/switch',
|
||
|
|
[('oppId','1'),('toStageId','3'),('remark','客户已确认预算')]),
|
||
|
|
None, env_json('null'),
|
||
|
|
)
|
||
|
|
write_bru(F, '切换阶段.bru', bru_form(5, '切换阶段', 'post', '/api/opportunity/stage/switch',
|
||
|
|
[('oppId','1'),('toStageId','3'),('remark','客户已确认预算')], docs))
|
||
|
|
|
||
|
|
# 关注商机
|
||
|
|
docs = build_docs(
|
||
|
|
'关注商机', 'POST', '/api/opportunity/focus',
|
||
|
|
'当前登录人关注该商机(详情页/列表关注按钮)。已关注再次调用幂等无副作用。',
|
||
|
|
[('oppId','string','是','-','商机 ID')],
|
||
|
|
req_form_example('POST', '/api/opportunity/focus', [('oppId','1')]),
|
||
|
|
None, env_json('null'),
|
||
|
|
)
|
||
|
|
write_bru(F, '关注商机.bru', bru_form(6, '关注商机', 'post', '/api/opportunity/focus', [('oppId','1')], docs))
|
||
|
|
|
||
|
|
# 取关商机
|
||
|
|
docs = build_docs(
|
||
|
|
'取关商机', 'POST', '/api/opportunity/unfocus',
|
||
|
|
'取消关注。未关注时调用幂等。',
|
||
|
|
[('oppId','string','是','-','商机 ID')],
|
||
|
|
req_form_example('POST', '/api/opportunity/unfocus', [('oppId','1')]),
|
||
|
|
None, env_json('null'),
|
||
|
|
)
|
||
|
|
write_bru(F, '取关商机.bru', bru_form(7, '取关商机', 'post', '/api/opportunity/unfocus', [('oppId','1')], docs))
|
||
|
|
|
||
|
|
# 批量关注
|
||
|
|
docs = build_docs(
|
||
|
|
'批量关注', 'POST', '/api/opportunity/focus-batch',
|
||
|
|
'列表多选后批量关注,每条幂等。',
|
||
|
|
[('ids','string','是','-','商机 ID 列表,逗号分隔')],
|
||
|
|
req_form_example('POST', '/api/opportunity/focus-batch', [('ids','1,2,3')]),
|
||
|
|
None, env_json('null'),
|
||
|
|
)
|
||
|
|
write_bru(F, '批量关注.bru', bru_form(8, '批量关注', 'post', '/api/opportunity/focus-batch', [('ids','1,2,3')], docs))
|
||
|
|
|
||
|
|
# 上报访问
|
||
|
|
docs = build_docs(
|
||
|
|
'上报访问', 'POST', '/api/opportunity/view-touch',
|
||
|
|
'打开商机详情页时前端自动调用一次(与「商机详情」并行发起),写入访问记录用于「最近访问」子菜单排序。无需等待响应影响页面渲染。',
|
||
|
|
[('oppId','string','是','-','商机 ID')],
|
||
|
|
req_form_example('POST', '/api/opportunity/view-touch', [('oppId','1')]),
|
||
|
|
None, env_json('null'),
|
||
|
|
)
|
||
|
|
write_bru(F, '上报访问.bru', bru_form(9, '上报访问', 'post', '/api/opportunity/view-touch', [('oppId','1')], docs))
|
||
|
|
|
||
|
|
print('batch4 done')
|