- 在CreditMpCustomer实体类中添加七个跟进步骤相关字段 - 实现跟进步骤审核功能,包括单个和批量审核接口 - 添加待审核步骤查询接口和客户跟进统计功能 - 实现流程结束功能和详细的步骤状态管理 - 创建相应的DTO和VO数据传输对象 - 在Mapper层添加待审核步骤查询SQL实现
16 KiB
16 KiB
客户跟进7步骤后端实现指南
📋 概述
本指南详细说明如何实现客户跟进7个步骤功能的后端代码,包括数据库设计、Java后端实现和API接口。
🗄️ 数据库设计
1. 修改 credit_mp_customer 表结构
-- 为第5-7步添加字段(第1-4步字段已存在)
-- 第5步:合同签订
ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_submitted TINYINT DEFAULT 0 COMMENT '是否已提交';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_submitted_at VARCHAR(255) COMMENT '提交时间';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_contracts TEXT COMMENT '合同信息JSON数组';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_need_approval TINYINT DEFAULT 1 COMMENT '是否需要审核';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_approved TINYINT DEFAULT 0 COMMENT '是否审核通过';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_approved_at VARCHAR(255) COMMENT '审核时间';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_approved_by BIGINT COMMENT '审核人ID';
-- 第6步:订单回款
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_submitted TINYINT DEFAULT 0 COMMENT '是否已提交';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_submitted_at VARCHAR(255) COMMENT '提交时间';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_payment_records TEXT COMMENT '财务录入的回款记录JSON数组';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_expected_payments TEXT COMMENT '预计回款JSON数组';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_need_approval TINYINT DEFAULT 1 COMMENT '是否需要审核';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_approved TINYINT DEFAULT 0 COMMENT '是否审核通过';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_approved_at VARCHAR(255) COMMENT '审核时间';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step6_approved_by BIGINT COMMENT '审核人ID';
-- 第7步:电话回访
ALTER TABLE credit_mp_customer ADD COLUMN follow_step7_submitted TINYINT DEFAULT 0 COMMENT '是否已提交';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step7_submitted_at VARCHAR(255) COMMENT '提交时间';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step7_visit_records TEXT COMMENT '回访记录JSON数组';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step7_need_approval TINYINT DEFAULT 1 COMMENT '是否需要审核';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step7_approved TINYINT DEFAULT 0 COMMENT '是否审核通过';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step7_approved_at VARCHAR(255) COMMENT '审核时间';
ALTER TABLE credit_mp_customer ADD COLUMN follow_step7_approved_by BIGINT COMMENT '审核人ID';
-- 添加流程结束相关字段
ALTER TABLE credit_mp_customer ADD COLUMN follow_process_ended TINYINT DEFAULT 0 COMMENT '流程是否已结束';
ALTER TABLE credit_mp_customer ADD COLUMN follow_process_end_time VARCHAR(255) COMMENT '流程结束时间';
ALTER TABLE credit_mp_customer ADD COLUMN follow_process_end_reason TEXT COMMENT '流程结束原因';
2. 创建审核记录表(可选)
CREATE TABLE credit_follow_approval (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
customer_id BIGINT NOT NULL COMMENT '客户ID',
step TINYINT NOT NULL COMMENT '步骤号',
approved TINYINT NOT NULL COMMENT '是否通过',
remark TEXT COMMENT '审核备注',
approved_by BIGINT COMMENT '审核人ID',
approved_at VARCHAR(255) COMMENT '审核时间',
created_at VARCHAR(255) COMMENT '创建时间',
INDEX idx_customer_step (customer_id, step),
INDEX idx_approved_by (approved_by)
) COMMENT='跟进步骤审核记录';
☕ Java后端实现
1. 实体类修改
// CreditMpCustomer.java 添加字段
public class CreditMpCustomer {
// ... 现有字段
// 第5步字段
private Integer followStep5Submitted;
private String followStep5SubmittedAt;
private String followStep5Contracts;
private Integer followStep5NeedApproval;
private Integer followStep5Approved;
private String followStep5ApprovedAt;
private Long followStep5ApprovedBy;
// 第6步字段
private Integer followStep6Submitted;
private String followStep6SubmittedAt;
private String followStep6PaymentRecords;
private String followStep6ExpectedPayments;
private Integer followStep6NeedApproval;
private Integer followStep6Approved;
private String followStep6ApprovedAt;
private Long followStep6ApprovedBy;
// 第7步字段
private Integer followStep7Submitted;
private String followStep7SubmittedAt;
private String followStep7VisitRecords;
private Integer followStep7NeedApproval;
private Integer followStep7Approved;
private String followStep7ApprovedAt;
private Long followStep7ApprovedBy;
// 流程结束字段
private Integer followProcessEnded;
private String followProcessEndTime;
private String followProcessEndReason;
// getter/setter 方法...
}
2. DTO类创建
// FollowStepApprovalDTO.java
@Data
public class FollowStepApprovalDTO {
private Long customerId;
private Integer step;
private Boolean approved;
private String remark;
}
// BatchFollowStepApprovalDTO.java
@Data
public class BatchFollowStepApprovalDTO {
private List<FollowStepApprovalDTO> approvals;
}
// FollowStatisticsDTO.java
@Data
public class FollowStatisticsDTO {
private Integer totalSteps;
private Integer completedSteps;
private Integer currentStep;
private Double progress;
private List<FollowStepDetailDTO> stepDetails;
}
// FollowStepDetailDTO.java
@Data
public class FollowStepDetailDTO {
private Integer step;
private String title;
private String status; // pending, submitted, approved, rejected
private String submittedAt;
private String approvedAt;
}
3. Service层实现
// CreditMpCustomerServiceImpl.java 添加方法
@Service
public class CreditMpCustomerServiceImpl implements CreditMpCustomerService {
/**
* 审核跟进步骤
*/
@Override
@Transactional
public void approveFollowStep(FollowStepApprovalDTO dto) {
CreditMpCustomer customer = getById(dto.getCustomerId());
if (customer == null) {
throw new ServiceException("客户不存在");
}
// 验证步骤是否已提交
if (!isStepSubmitted(customer, dto.getStep())) {
throw new ServiceException("该步骤尚未提交,无法审核");
}
// 更新审核状态
updateStepApproval(customer, dto);
// 记录审核日志
saveApprovalLog(dto);
// 如果审核通过,更新客户步骤状态
if (dto.getApproved()) {
updateCustomerStep(customer, dto.getStep());
}
}
/**
* 批量审核跟进步骤
*/
@Override
@Transactional
public void batchApproveFollowSteps(BatchFollowStepApprovalDTO dto) {
for (FollowStepApprovalDTO approval : dto.getApprovals()) {
approveFollowStep(approval);
}
}
/**
* 获取待审核的跟进步骤列表
*/
@Override
public List<PendingApprovalStepVO> getPendingApprovalSteps(FollowStepQueryDTO query) {
return baseMapper.selectPendingApprovalSteps(query);
}
/**
* 获取客户跟进统计
*/
@Override
public FollowStatisticsDTO getFollowStatistics(Long customerId) {
CreditMpCustomer customer = getById(customerId);
if (customer == null) {
throw new ServiceException("客户不存在");
}
FollowStatisticsDTO statistics = new FollowStatisticsDTO();
statistics.setTotalSteps(7);
List<FollowStepDetailDTO> stepDetails = new ArrayList<>();
int completedSteps = 0;
int currentStep = 1;
for (int i = 1; i <= 7; i++) {
FollowStepDetailDTO detail = getStepDetail(customer, i);
stepDetails.add(detail);
if ("approved".equals(detail.getStatus())) {
completedSteps++;
currentStep = i + 1;
} else if ("submitted".equals(detail.getStatus()) && currentStep == 1) {
currentStep = i;
}
}
statistics.setCompletedSteps(completedSteps);
statistics.setCurrentStep(Math.min(currentStep, 7));
statistics.setProgress((double) completedSteps / 7 * 100);
statistics.setStepDetails(stepDetails);
return statistics;
}
/**
* 结束客户跟进流程
*/
@Override
@Transactional
public void endFollowProcess(Long customerId, String reason) {
CreditMpCustomer customer = getById(customerId);
if (customer == null) {
throw new ServiceException("客户不存在");
}
customer.setFollowProcessEnded(1);
customer.setFollowProcessEndTime(DateUtil.formatDateTime(new Date()));
customer.setFollowProcessEndReason(reason);
updateById(customer);
}
// 私有辅助方法...
private boolean isStepSubmitted(CreditMpCustomer customer, Integer step) {
switch (step) {
case 1: return customer.getFollowStep1Submitted() == 1;
case 2: return customer.getFollowStep2Submitted() == 1;
// ... 其他步骤
case 7: return customer.getFollowStep7Submitted() == 1;
default: return false;
}
}
private void updateStepApproval(CreditMpCustomer customer, FollowStepApprovalDTO dto) {
String currentTime = DateUtil.formatDateTime(new Date());
Long currentUserId = SecurityFrameworkUtils.getLoginUserId();
switch (dto.getStep()) {
case 5:
customer.setFollowStep5Approved(dto.getApproved() ? 1 : 0);
customer.setFollowStep5ApprovedAt(currentTime);
customer.setFollowStep5ApprovedBy(currentUserId);
break;
case 6:
customer.setFollowStep6Approved(dto.getApproved() ? 1 : 0);
customer.setFollowStep6ApprovedAt(currentTime);
customer.setFollowStep6ApprovedBy(currentUserId);
break;
case 7:
customer.setFollowStep7Approved(dto.getApproved() ? 1 : 0);
customer.setFollowStep7ApprovedAt(currentTime);
customer.setFollowStep7ApprovedBy(currentUserId);
break;
}
updateById(customer);
}
}
4. Controller层实现
// CreditMpCustomerController.java 添加接口
@RestController
@RequestMapping("/credit/credit-mp-customer")
public class CreditMpCustomerController {
@PostMapping("/approve-follow-step")
@OperLog(title = "审核跟进步骤", businessType = BusinessType.UPDATE)
public R<Void> approveFollowStep(@RequestBody FollowStepApprovalDTO dto) {
creditMpCustomerService.approveFollowStep(dto);
return R.ok();
}
@PostMapping("/batch-approve-follow-steps")
@OperLog(title = "批量审核跟进步骤", businessType = BusinessType.UPDATE)
public R<Void> batchApproveFollowSteps(@RequestBody BatchFollowStepApprovalDTO dto) {
creditMpCustomerService.batchApproveFollowSteps(dto);
return R.ok();
}
@GetMapping("/pending-approval-steps")
@OperLog(title = "获取待审核跟进步骤", businessType = BusinessType.SELECT)
public R<List<PendingApprovalStepVO>> getPendingApprovalSteps(FollowStepQueryDTO query) {
List<PendingApprovalStepVO> list = creditMpCustomerService.getPendingApprovalSteps(query);
return R.ok(list);
}
@GetMapping("/follow-statistics/{customerId}")
@OperLog(title = "获取客户跟进统计", businessType = BusinessType.SELECT)
public R<FollowStatisticsDTO> getFollowStatistics(@PathVariable Long customerId) {
FollowStatisticsDTO statistics = creditMpCustomerService.getFollowStatistics(customerId);
return R.ok(statistics);
}
@PostMapping("/end-follow-process")
@OperLog(title = "结束客户跟进流程", businessType = BusinessType.UPDATE)
public R<Void> endFollowProcess(@RequestBody EndFollowProcessDTO dto) {
creditMpCustomerService.endFollowProcess(dto.getCustomerId(), dto.getReason());
return R.ok();
}
}
5. Mapper层SQL
<!-- CreditMpCustomerMapper.xml 添加查询方法 -->
<select id="selectPendingApprovalSteps" resultType="com.your.package.PendingApprovalStepVO">
SELECT
c.id as customerId,
c.to_user as customerName,
5 as step,
'合同签订' as stepTitle,
c.follow_step5_submitted_at as submittedAt,
u.real_name as submittedBy,
c.follow_step5_contracts as content
FROM credit_mp_customer c
LEFT JOIN sys_user u ON c.user_id = u.user_id
WHERE c.follow_step5_submitted = 1
AND c.follow_step5_approved = 0
AND c.deleted = 0
UNION ALL
SELECT
c.id as customerId,
c.to_user as customerName,
6 as step,
'订单回款' as stepTitle,
c.follow_step6_submitted_at as submittedAt,
u.real_name as submittedBy,
c.follow_step6_expected_payments as content
FROM credit_mp_customer c
LEFT JOIN sys_user u ON c.user_id = u.user_id
WHERE c.follow_step6_submitted = 1
AND c.follow_step6_approved = 0
AND c.deleted = 0
UNION ALL
SELECT
c.id as customerId,
c.to_user as customerName,
7 as step,
'电话回访' as stepTitle,
c.follow_step7_submitted_at as submittedAt,
u.real_name as submittedBy,
c.follow_step7_visit_records as content
FROM credit_mp_customer c
LEFT JOIN sys_user u ON c.user_id = u.user_id
WHERE c.follow_step7_submitted = 1
AND c.follow_step7_approved = 0
AND c.deleted = 0
<if test="step != null">
HAVING step = #{step}
</if>
<if test="customerId != null">
HAVING customerId = #{customerId}
</if>
ORDER BY submittedAt DESC
</select>
🔧 业务逻辑说明
1. 步骤解锁机制
- 第一步始终可用
- 后续步骤需要前一步审核通过才能进行
- 前端通过
canEnterStep逻辑控制
2. 审核流程
- 步骤提交后设置
needApproval = 1 - 管理员在后台审核
- 审核通过后设置
approved = 1并更新时间
3. 数据格式
- 所有复杂数据使用JSON格式存储
- 文件上传返回URL,存储在JSON数组中
- 时间统一使用
YYYY-MM-DD HH:mm:ss格式
4. 权限控制
- 销售只能提交和查看自己的客户
- 管理员可以审核所有步骤
- 财务人员可以录入第6步回款数据
📱 前端集成
前端代码已经完成,包括:
- 7个步骤的完整页面
- 步骤状态显示和跳转逻辑
- 数据提交和验证
- 客户详情页面的汇总显示
🚀 部署步骤
- 执行数据库迁移脚本
- 部署Java后端代码
- 更新前端API调用
- 测试完整流程
- 配置权限和审核流程
📝 注意事项
- 数据备份:执行数据库变更前请备份
- 权限配置:确保各角色权限正确配置
- 文件上传:确认文件上传服务正常
- 审核流程:测试审核流程的完整性
- 性能优化:大量数据时考虑分页和索引优化
🔄 后续扩展
可以考虑的功能:
- 跟进模板和标准化流程
- 自动提醒和通知
- 数据统计和报表
- 跟进效率分析
- 客户满意度评估