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.

153 lines
6.5 KiB

1 week ago
# -*- coding: utf-8 -*-
"""详情子域 - 客户 + 跟进 (4 个接口)."""
import io, os, 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,
)
# ---------- 客户 Tab ----------
print('== 详情子域 / 客户 ==')
CUSTOMER_ROWS = [
('id', 'string', '关联客户行ID'),
('createTime', 'string', '创建时间'),
('updateTime', 'string', '更新时间'),
('opportunityId', 'string', '所属商机ID'),
('customerId', 'string', '客户ID(引用 A4 客户模块)'),
('customerNameSnapshot', 'string', '客户名快照'),
('customerRole', 'string', '客户角色字典 code(机电总包/工程商/集成商等)'),
('isPrimaryIntended', 'number', '是否主要意向客户:1是 0普通关联'),
]
CUSTOMER_ONE = (
'{\n'
' "id": "1",\n'
' "createTime": "2024-01-01 12:00:00",\n'
' "updateTime": "2024-01-01 12:00:00",\n'
' "opportunityId": "1",\n'
' "customerId": "1",\n'
' "customerNameSnapshot": "示例客户",\n'
' "customerRole": "role_01",\n'
' "isPrimaryIntended": 1\n'
' }'
)
docs = build_docs(
'客户列表', 'GET', '/api/opportunity/customer/list',
'商机详情「客户」Tab:返回该商机的全部关联客户,其中恰好一个 `isPrimaryIntended=1` 为主要意向客户。',
[('oppId','string','','-','商机ID')],
req_query_example('GET','/api/opportunity/customer/list',[('oppId','1')]),
CUSTOMER_ROWS,
env_json(f'[\n{CUSTOMER_ONE}\n ]'),
)
write_bru('商机管理/详情子域', '客户列表.bru',
bru_form(1, '客户列表', 'get', '/api/opportunity/customer/list',
[('oppId','1')], docs))
# ---------- 跟进 Tab ----------
print('== 详情子域 / 跟进 ==')
FOLLOW_ROWS = [
('id','string','跟进记录ID'),
('createTime','string','创建时间(=写入时间)'),
('updateTime','string','更新时间'),
('oppId','string','所属商机ID'),
('followContent','string','跟进内容'),
('followTime','string','跟进时间'),
('followWay','string','跟进方式字典 code(电话沟通/上门拜访/微信对接/线上会议/展会沟通)'),
('customerId','string','关联客户ID'),
('contactId','string','客户联系人ID(可空)'),
('resultTag','string','跟进结果标签字典 code(可空)'),
('nextFollowTime','string','计划下次跟进时间(可空)'),
]
FOLLOW_ONE = (
'{\n'
' "id": "1",\n'
' "createTime": "2024-01-01 12:00:00",\n'
' "updateTime": "2024-01-01 12:00:00",\n'
' "oppId": "1",\n'
' "followContent": "已电话沟通客户预算与决策链",\n'
' "followTime": "2024-01-01 12:00:00",\n'
' "followWay": "way_01",\n'
' "customerId": "1",\n'
' "contactId": "1",\n'
' "resultTag": "tag_01",\n'
' "nextFollowTime": "2024-01-05 12:00:00"\n'
' }'
)
FOLLOW_PAGE_JSON = (
'{\n'
f' "content": [\n{FOLLOW_ONE}\n ],\n'
' "total": 1,\n'
' "size": 10,\n'
' "current": 1,\n'
' "pages": 1,\n'
' "empty": false\n'
' }'
)
# 跟进分页
docs = build_docs(
'跟进分页', 'POST', '/api/opportunity/follow/page',
'商机详情「跟进」Tab:分页拉取该商机的跟进记录,默认按创建时间倒序。',
[('oppId','string','','-','商机ID'),
('pageNum','number','','1','页码,从 1 开始'),
('pageSize','number','','10','每页条数')],
req_form_example('POST','/api/opportunity/follow/page',
[('oppId','1'),('pageNum','1'),('pageSize','10')]),
[('content','array<object>','跟进记录数组')] + [('content[].'+r[0], r[1], r[2]) for r in FOLLOW_ROWS] + [
('total','number','总条数'),
('size','number','每页条数'),
('current','number','当前页码'),
('pages','number','总页数'),
('empty','boolean','是否为空结果'),
],
env_json(FOLLOW_PAGE_JSON),
)
write_bru('商机管理/详情子域', '跟进分页.bru',
bru_form(2, '跟进分页', 'post', '/api/opportunity/follow/page',
[('oppId','1'),('pageNum','1'),('pageSize','10')], docs))
# 新增跟进
add_follow_params = [
('oppId','string','','-','商机ID'),
('followContent','string','','-','跟进内容'),
('followTime','string','','-','跟进时间 yyyy-MM-dd HH:mm:ss'),
('followWay','string','','-','跟进方式字典 code'),
('customerId','string','','-','关联客户ID(默认带出商机主要意向客户)'),
('contactId','string','','-','客户联系人ID'),
('resultTag','string','','-','跟进结果标签字典 code'),
('nextFollowTime','string','','-','计划下次跟进时间 yyyy-MM-dd HH:mm:ss(不得早于本次跟进时间)'),
]
add_follow_kv = [
('oppId','1'),('followContent','已电话沟通客户预算与决策链'),
('followTime','2024-01-01 12:00:00'),('followWay','way_01'),
('customerId','1'),('contactId','1'),('resultTag','tag_01'),
('nextFollowTime','2024-01-05 12:00:00'),
]
docs = build_docs(
'新增跟进', 'POST', '/api/opportunity/follow/add',
'写跟进弹窗「确认」→ 校验 + 提交,无草稿态。保存后刷新商机「最近跟进」与 `lastValidFollowTime`(回收锚点刷新点之一)。与阶段推进不联动(写跟进不自动推阶段)。',
add_follow_params,
req_form_example('POST','/api/opportunity/follow/add', add_follow_kv),
'新增跟进记录ID(Long,序列化为 string)',
env_json('"1"'),
)
write_bru('商机管理/详情子域', '新增跟进.bru',
bru_form(3, '新增跟进', 'post', '/api/opportunity/follow/add', add_follow_kv, docs))
# 删除跟进
docs = build_docs(
'删除跟进', 'POST', '/api/opportunity/follow/delete',
'删除跟进记录(记一条 ROW_DELETE oplog)。`lastValidFollowTime` 删除后保持不变(不回退重算,防「写了又删」刷锚点);「最近跟进」计算列按删除后最新留存行自然变化。',
[('id','string','','-','跟进记录ID')],
req_form_example('POST','/api/opportunity/follow/delete',[('id','1')]),
None, env_json('null'),
)
write_bru('商机管理/详情子域', '删除跟进.bru',
bru_form(4, '删除跟进', 'post', '/api/opportunity/follow/delete',
[('id','1')], docs))
print('part3a done — 客户 + 跟进 4 个接口完成')