Files
hzhub/docs/crm-bug-fix-report.md
大壮 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

6.1 KiB
Raw Blame History

CRM线索管理功能问题修复报告

发现的问题

问题1新增线索时缺少手机号格式验证

问题描述

  • 后端CrmLeadBo缺少手机号格式校验注解
  • 前端:新建线索表单缺少手机号格式验证

影响

  • 用户可以输入任意格式的手机号,导致数据质量下降

问题2负责人显示为手机号而非姓名

问题描述

  • UserNameTranslationImpl翻译类调用userService.selectUserNameById返回userName登录账号
  • 应该调用userService.selectNicknameById返回nickName用户昵称/真实姓名)

影响

  • 线索列表负责人列显示登录账号如admin而不是用户真实姓名如管理员
  • 用户期望看到负责人姓名,而非登录账号

修复方案

问题1修复手机号格式验证

后端修复

修改文件hzhub-system/src/main/java/org/hzhub/crm/domain/bo/CrmLeadBo.java

修改内容

// 导入Pattern注解
import jakarta.validation.constraints.Pattern;

// mobile字段添加正则验证
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
@Size(min = 0, max = 50, message = "手机号长度不能超过{max}个字符")
private String mobile;

正则表达式说明

  • ^1 - 以1开头
  • [3-9] - 第二位为3-9
  • \d{9} - 后面9位为数字
  • $ - 结尾

验证中国手机号格式13x, 14x, 15x, 16x, 17x, 18x, 19x开头的11位数字


前端修复

修改文件hzhub-portal-employee/src/pages/crm/index.vue

修改内容

  1. 添加手机号验证函数
// 手机号验证规则
const mobileValidator = (value: string) => {
  if (!value) {
    return '请输入手机号';
  }
  const mobileRegex = /^1[3-9]\d{9}$/;
  if (!mobileRegex.test(value)) {
    return '手机号格式不正确';
  }
  return '';
};
  1. 修改submitLead方法添加验证
async function submitLead() {
  if (!leadForm.value.companyName || !leadForm.value.contactName || !leadForm.value.mobile) {
    ElMessage.warning('请填写必填信息');
    return;
  }

  // 验证手机号格式
  const mobileError = mobileValidator(leadForm.value.mobile);
  if (mobileError) {
    ElMessage.warning(mobileError);
    return;
  }

  try {
    await createLead(leadForm.value);
    ElMessage.success('线索创建成功');
    showAddLeadDialog.value = false;
    await loadLeads();
  }
  catch (error: any) {
    ElMessage.error(error?.message || '创建线索失败');
  }
}

问题2修复负责人显示姓名

后端修复

修改文件hzhub-ai/hzhub-common/hzhub-common-translation/src/main/java/org/hzhub/common/translation/core/impl/UserNameTranslationImpl.java

修改内容

@Override
public String translation(Object key, String other) {
    if (key instanceof Long id) {
        // 返回用户昵称而不是登录账号
        return userService.selectNicknameById(id);
    }
    return null;
}

修复说明

  • 从调用selectUserNameById改为调用selectNicknameById
  • selectNicknameById返回用户昵称(真实姓名),而不是登录账号
  • 使用缓存@Cacheable(cacheNames = CacheNames.SYS_NICKNAME),性能更好

影响范围

  • 所有使用USER_ID_TO_NAME翻译的地方都会显示用户昵称
  • 包括createBy, updateBy, ownerUserId, followUserId等字段

编译和部署

编译步骤

# 1. 编译hzhub-ai包含translation模块修改
cd /data/hzhub/hzhub-ai
mvn clean install -DskipTests

# 2. 编译hzhub-system包含CrmLeadBo修改
cd /data/hzhub/hzhub-system
mvn clean compile -DskipTests

# 3. 重启所有服务
cd /data/hzhub
./restart-all.sh

编译结果

  • hzhub-ai: BUILD SUCCESS (55.753s)
  • hzhub-system: BUILD SUCCESS (19.007s)

测试验证

测试1手机号格式验证

后端验证测试

使用Postman或curl测试

POST http://localhost:8080/crm/lead
Headers:
  Authorization: Bearer {token}
  ClientID: employee-portal
Body:
{
  "companyName": "测试公司",
  "contactName": "张三",
  "mobile": "12345678901",  // 错误格式
  "sourceType": "activity"
}

预期响应

{
  "code": 500,
  "msg": "手机号格式不正确"
}

前端验证测试

测试步骤

  1. 登录员工门户:http://localhost:5137
  2. 导航到"销售CRM" → "线索管理"
  3. 点击"新建线索"
  4. 输入错误手机号12345678901
  5. 点击"创建线索"

预期结果

  • 显示提示:"手机号格式不正确"
  • 表单不提交

测试2负责人显示姓名

测试步骤

  1. 创建线索并分配负责人
  2. 查看线索列表负责人列

预期结果

  • 负责人列显示用户真实姓名(如"管理员"
  • 不显示登录账号(如"admin")

后端验证

-- 查询用户数据
SELECT user_id, user_name, nick_name, phonenumber FROM sys_user WHERE user_id = 1;

-- 预期结果:
-- user_name: admin (登录账号)
-- nick_name: 管理员 (真实姓名)

修复影响范围

手机号验证

影响模块

  • CRM线索管理新建、编辑线索
  • 未来可能影响:经销商管理、客户管理

数据质量提升

  • 防止错误手机号数据进入系统
  • 提升线索数据质量

负责人显示

影响模块

  • CRM线索管理负责人显示
  • CRM经销商管理负责人显示
  • 系统通知管理(创建人、更新人显示)
  • OSS对象存储创建人显示
  • 跟进记录(跟进人显示)

用户体验提升

  • 显示真实姓名,更符合用户认知
  • 避免混淆登录账号和真实姓名

相关文档


总结

两个问题均已修复:

  1. 手机号格式验证后端Pattern注解 + 前端验证函数)
  2. 负责人显示姓名修改UserNameTranslationImpl返回昵称

请重新测试验证功能。