Files
hzhub/hzhub-portal-employee/src/api/crm/index.ts
大壮 3f643ef31f feat: 完成CRM商机和线索管理模块开发
## 新增功能

### 商机中心 (/opportunity)
- Stats统计卡片(商机总数、金额、赢单、转化率)
- Pipeline商机管道(阶段Tab:全部/线索/谈判中/方案/赢单)
- 商机列表真实数据渲染(来自crm_opportunity表)
- 商机卡片详情(经销商、负责人、金额、概率)
- Pipeline计数实时更新

### 线索中心 (/lead)
- 线索列表完整功能(CRUD)
- 线索详情Drawer(基础信息 + 跟进记录Timeline)
- 新建线索(含ERP客户关联、手机号验证)
- 添加跟进记录(跟进方式、内容、下次时间)
- 分配负责人(用户选择器,显示真实姓名)
- 线索转经销商(自动创建商机)
- 删除线索(逻辑删除)

## 后端开发

### 数据库表
- crm_lead(线索表)
- crm_lead_follow(线索跟进记录表)
- crm_dealer(经销商表)
- crm_opportunity(商机表)
- crm_opportunity_follow(商机跟进记录表)
- 数据字典初始化

### API接口
- 线索管理:CRUD、详情、跟进、分配、转化
- 商机管理:列表查询
- 用户选择器:员工门户专用API

### 核心功能
- 线索转化自动创建经销商和商机
- 负责人翻译显示真实姓名(修复)
- 手机号前后端双重格式验证(修复)

## 前端开发

### 页面架构改进
- 商机中心:保留原CRM设计风格(Stats + Pipeline)
- 线索中心:独立页面(完整线索管理)
- 左侧菜单:独立菜单项(商机中心、线索中心)

### API模块
- src/api/crm/:线索和商机API类型定义和调用方法
- src/api/user/:用户选择器API

### 样式设计
- 商机中心:100%保持原CRM Pipeline设计风格
- 使用CSS变量系统(var(--radius-lg), var(--shadow-sm)等)
- Pipeline Tab白色圆角设计
- 商机卡片阴影和hover效果
- 头像堆叠显示

## 配置修改

- Gateway路由:添加CRM模块路由配置
- Gateway路由:添加system模块路由配置
- Aside菜单:拆分商机中心和线索中心

## Bug修复

- 修复负责人显示手机号问题(UserNameTranslationImpl返回昵称)
- 修复手机号格式验证缺失(前后端双重验证)
- 修复商机管道设计风格不一致(完整复制原CRM样式)

## 文档

- CRM销售模块详细设计说明书V3.md
- CRM线索转化API契约
- CRM线索转化开发计划
- CRM线索转化测试指引
- CRM线索管理测试指引
- CRM商机管理测试指引
- CRM架构改进报告
- CRM Bug修复报告

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 09:46:59 +00:00

142 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* CRM 线索管理模块 API 调用
* 服务归属hzhub-system (端口 8083)
* API前缀/crm/lead通过 Gateway 路由)
*/
import type {
CrmLeadBo,
CrmLeadFollowBo,
CrmLeadFollowVo,
CrmLeadVo,
CrmOpportunityBo,
CrmOpportunityVo,
LeadAssignRequest,
LeadConvertRequest,
LeadQueryParams,
OpportunityQueryParams,
R,
TableDataInfo,
} from './types';
// 导出类型供外部使用
export type {
CrmLeadBo,
CrmLeadFollowBo,
CrmLeadFollowVo,
CrmLeadVo,
CrmOpportunityBo,
CrmOpportunityVo,
LeadAssignRequest,
LeadConvertRequest,
LeadQueryParams,
OpportunityQueryParams,
R,
TableDataInfo,
} from './types';
import request from '@/utils/request';
/**
* 获取线索列表(分页)
*/
export function getLeadList(params: LeadQueryParams): Promise<TableDataInfo<CrmLeadVo>> {
return request.get('/crm/lead/list', params).json();
}
/**
* 获取线索详情
*/
export function getLeadDetail(leadId: number): Promise<R<CrmLeadVo>> {
return request.get(`/crm/lead/${leadId}`).json();
}
/**
* 新增线索
*/
export function createLead(data: CrmLeadBo): Promise<R<void>> {
return request.post('/crm/lead', data).json();
}
/**
* 编辑线索
*/
export function updateLead(data: CrmLeadBo): Promise<R<void>> {
return request.put('/crm/lead', data).json();
}
/**
* 删除线索(支持批量)
*/
export function deleteLead(leadIds: string): Promise<R<void>> {
return request.delete(`/crm/lead/${leadIds}`).json();
}
/**
* 分配线索
*/
export function assignLead(data: LeadAssignRequest): Promise<R<void>> {
return request.put('/crm/lead/assign', data).json();
}
/**
* 获取线索跟进记录列表
*/
export function getLeadFollowRecords(leadId: number): Promise<R<CrmLeadFollowVo[]>> {
return request.get(`/crm/lead/follow/${leadId}`).json();
}
/**
* 添加线索跟进记录
*/
export function addLeadFollow(data: CrmLeadFollowBo): Promise<R<void>> {
return request.post('/crm/lead/follow', data).json();
}
/**
* 线索转经销商(第二阶段实现)
*/
export function convertLeadToDealer(data: LeadConvertRequest): Promise<R<void>> {
return request.post('/crm/lead/convert', data).json();
}
/**
* ========================================
* CRM 商机管理模块 API 调用
* ========================================
*/
/**
* 获取商机列表(分页)
*/
export function getOpportunityList(params: OpportunityQueryParams): Promise<TableDataInfo<CrmOpportunityVo>> {
return request.get('/crm/opportunity/list', params).json();
}
/**
* 获取商机详情
*/
export function getOpportunityDetail(opportunityId: number): Promise<R<CrmOpportunityVo>> {
return request.get(`/crm/opportunity/${opportunityId}`).json();
}
/**
* 新增商机
*/
export function createOpportunity(data: CrmOpportunityBo): Promise<R<void>> {
return request.post('/crm/opportunity', data).json();
}
/**
* 编辑商机
*/
export function updateOpportunity(data: CrmOpportunityBo): Promise<R<void>> {
return request.put('/crm/opportunity', data).json();
}
/**
* 删除商机(支持批量)
*/
export function deleteOpportunity(opportunityIds: string): Promise<R<void>> {
return request.delete(`/crm/opportunity/${opportunityIds}`).json();
}