# -*- 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','跟进记录数组')] + [('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 个接口完成')