01-线索管理API接口.md 31 KB

线索管理模块 - API接口文档

模块: 01-线索管理
版本: v1.0
日期: 2025-10-03
关联文档:

  • 需求文档: docs/01-线索管理模块需求.md
  • 原型图: yuanxing/01-线索管理原型图.md
  • 数据库: sql/crm/01-crm_clue.sql

📋 目录


1. 线索管理接口

1.1 查询线索列表(分页)

接口地址: GET /crm/clue/list

接口描述: 分页查询线索列表,支持多条件筛选和视图切换

权限标识: crm:clue:list

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | pageNum | Integer | 否 | 页码,默认1 | | pageSize | Integer | 否 | 每页条数,默认10 | | clueName | String | 否 | 线索姓名(模糊查询) | | mobile | String | 否 | 手机号(模糊查询) | | company | String | 否 | 公司名称(模糊查询) | | source | String | 否 | 线索来源:website/phone/exhibition/activity/referral/ads/social_media/other | | level | String | 否 | 线索等级:A/B/C/unrated | | status | String | 否 | 线索状态:new/follow/invalid/converted | | industry | String | 否 | 所属行业 | | province | String | 否 | 省份 | | city | String | 否 | 城市 | | ownerUserId | Long | 否 | 负责人ID | | budget | String | 否 | 预算范围 | | isConverted | Boolean | 否 | 是否已转化:0-否 1-是 | | beginTime | String | 否 | 开始时间 yyyy-MM-dd HH:mm:ss | | endTime | String | 否 | 结束时间 yyyy-MM-dd HH:mm:ss | | lastTimeBegin | String | 否 | 最后跟进开始时间 | | lastTimeEnd | String | 否 | 最后跟进结束时间 | | nextTimeBegin | String | 否 | 下次联系开始时间 | | nextTimeEnd | String | 否 | 下次联系结束时间 |

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "rows": [
    {
      "id": 1,
      "clueName": "张伟",
      "mobile": "13900001234",
      "company": "华为技术有限公司",
      "telephone": "0571-12345678",
      "email": "zhangwei@huawei.com",
      "title": "先生",
      "position": "技术总监",
      "source": "website",
      "level": "A",
      "industry": "互联网/IT",
      "province": "浙江省",
      "city": "杭州市",
      "district": "西湖区",
      "address": "文三路XXX号",
      "website": "https://www.huawei.com",
      "intentProducts": "CRM系统,ERP系统",
      "expectTime": "2025-03-01",
      "budget": "100k_500k",
      "requirement": "需要一套完整的企业管理系统",
      "status": "follow",
      "ownerUserId": 1,
      "ownerUserName": "张三",
      "lastTime": "2025-01-02 10:30:00",
      "nextTime": "2025-01-05 14:00:00",
      "followCount": 3,
      "isConverted": 0,
      "createTime": "2025-01-01 09:00:00",
      "createBy": 1,
      "remark": ""
    }
  ],
  "total": 156
}

1.2 查询线索详情

接口地址: GET /crm/clue/{id}

接口描述: 根据ID查询线索详细信息

权限标识: crm:clue:query

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 线索ID |

返回示例:

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "id": 1,
    "clueName": "张伟",
    "mobile": "13900001234",
    "company": "华为技术有限公司",
    "telephone": "0571-12345678",
    "email": "zhangwei@huawei.com",
    "title": "先生",
    "position": "技术总监",
    "source": "website",
    "level": "A",
    "industry": "互联网/IT",
    "province": "浙江省",
    "city": "杭州市",
    "district": "西湖区",
    "address": "文三路XXX号",
    "website": "https://www.huawei.com",
    "intentProducts": "CRM系统,ERP系统",
    "expectTime": "2025-03-01",
    "budget": "100k_500k",
    "requirement": "需要一套完整的企业管理系统",
    "status": "follow",
    "ownerUserId": 1,
    "ownerUserName": "张三",
    "lastTime": "2025-01-02 10:30:00",
    "nextTime": "2025-01-05 14:00:00",
    "followCount": 3,
    "isConverted": 0,
    "convertedTime": null,
    "customerId": null,
    "convertedBy": null,
    "assignTime": "2025-01-01 09:30:00",
    "assignBy": 1,
    "createTime": "2025-01-01 09:00:00",
    "createBy": 1,
    "updateTime": "2025-01-02 10:30:00",
    "updateBy": 1,
    "remark": ""
  }
}

1.3 新增线索

接口地址: POST /crm/clue

接口描述: 新增线索信息

权限标识: crm:clue:add

请求体:

{
  "clueName": "张伟",
  "mobile": "13900001234",
  "company": "华为技术有限公司",
  "telephone": "0571-12345678",
  "email": "zhangwei@huawei.com",
  "title": "先生",
  "position": "技术总监",
  "source": "website",
  "level": "A",
  "industry": "互联网/IT",
  "province": "浙江省",
  "city": "杭州市",
  "district": "西湖区",
  "address": "文三路XXX号",
  "website": "https://www.huawei.com",
  "intentProducts": "CRM系统,ERP系统",
  "expectTime": "2025-03-01",
  "budget": "100k_500k",
  "requirement": "需要一套完整的企业管理系统",
  "ownerUserId": 1,
  "nextTime": "2025-01-05 14:00:00",
  "remark": ""
}

请求参数说明: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | clueName | String | 是 | 线索姓名,最大100字符 | | mobile | String | 是 | 手机号,11位,需唯一校验 | | source | String | 是 | 线索来源 | | company | String | 否 | 公司名称,最大200字符 | | telephone | String | 否 | 固定电话,最大30字符 | | email | String | 否 | 邮箱,最大100字符 | | title | String | 否 | 称呼:先生/女士/其他 | | position | String | 否 | 职位,最大50字符 | | level | String | 否 | 线索等级:A/B/C/unrated,默认unrated | | industry | String | 否 | 所属行业,最大50字符 | | province | String | 否 | 省份,最大50字符 | | city | String | 否 | 城市,最大50字符 | | district | String | 否 | 区县,最大50字符 | | address | String | 否 | 详细地址,最大255字符 | | website | String | 否 | 客户网站,最大500字符 | | intentProducts | String | 否 | 意向产品,多个用逗号分隔 | | expectTime | String | 否 | 预计购买时间,格式yyyy-MM-dd | | budget | String | 否 | 预算范围 | | requirement | String | 否 | 需求描述,文本类型 | | ownerUserId | Long | 否 | 负责人ID,默认为当前用户 | | nextTime | String | 否 | 下次联系时间 yyyy-MM-dd HH:mm:ss | | remark | String | 否 | 备注,最大500字符 |

校验规则:

  • 手机号必须为11位数字
  • 手机号在同一租户下必须唯一
  • 邮箱需符合邮箱格式
  • 负责人ID必须存在

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

1.4 修改线索

接口地址: PUT /crm/clue

接口描述: 修改线索信息

权限标识: crm:clue:edit

请求体: 同新增接口,但需要传入id

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

1.5 删除线索

接口地址: DELETE /crm/clue/{ids}

接口描述: 删除线索(支持批量)

权限标识: crm:clue:remove

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 线索ID数组,多个用逗号分隔 |

业务规则:

  • 已转化的线索不允许删除
  • 删除线索时同时删除关联的跟进记录

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

1.6 批量分配线索

接口地址: PUT /crm/clue/assign

接口描述: 批量分配线索给指定负责人

权限标识: crm:clue:assign

请求体:

{
  "ids": [1, 2, 3],
  "ownerUserId": 5,
  "remark": "分配原因"
}

请求参数说明: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 线索ID数组 | | ownerUserId | Long | 是 | 新负责人ID | | remark | String | 否 | 分配说明 |

业务规则:

  • 只能分配未转化的线索
  • 记录分配时间和分配人

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

1.7 修改线索状态

接口地址: PUT /crm/clue/status

接口描述: 修改线索状态(批量标记为无效等)

权限标识: crm:clue:edit

请求体:

{
  "ids": [1, 2, 3],
  "status": "invalid",
  "remark": "客户无购买意向"
}

请求参数说明: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 线索ID数组 | | status | String | 是 | 新状态:new/follow/invalid | | remark | String | 否 | 状态变更说明 |

业务规则:

  • 已转化的线索不允许修改状态

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

1.8 修改线索等级

接口地址: PUT /crm/clue/level

接口描述: 修改线索等级

权限标识: crm:clue:edit

请求体:

{
  "id": 1,
  "level": "A",
  "remark": "客户预算充足,意向强烈"
}

请求参数说明: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 线索ID | | level | String | 是 | 线索等级:A/B/C/unrated | | remark | String | 否 | 等级评定说明 |

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

1.9 导出线索

接口地址: POST /crm/clue/export

接口描述: 导出线索数据到Excel

权限标识: crm:clue:export

请求体: 查询参数同1.1列表查询接口

返回: Excel文件流


1.10 导入线索

接口地址: POST /crm/clue/import

接口描述: 批量导入线索数据

权限标识: crm:clue:import

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | file | MultipartFile | 是 | Excel文件 | | updateSupport | Boolean | 否 | 是否更新已存在的线索,默认false |

返回示例:

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "total": 100,
    "success": 95,
    "fail": 5,
    "errors": [
      {
        "row": 3,
        "error": "手机号已存在"
      },
      {
        "row": 7,
        "error": "手机号格式错误"
      }
    ]
  }
}

1.11 下载导入模板

接口地址: POST /crm/clue/importTemplate

接口描述: 下载线索导入Excel模板

权限标识: crm:clue:import

请求参数: 无

返回: Excel文件流


1.12 查询待跟进线索

接口地址: GET /crm/clue/toFollow

接口描述: 查询需要跟进的线索列表(下次联系时间已到)

权限标识: crm:clue:list

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | pageNum | Integer | 否 | 页码,默认1 | | pageSize | Integer | 否 | 每页条数,默认10 | | ownerUserId | Long | 否 | 负责人ID,默认查询当前用户 |

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "rows": [
    {
      "id": 1,
      "clueName": "张伟",
      "mobile": "13900001234",
      "company": "华为技术有限公司",
      "level": "A",
      "status": "follow",
      "nextTime": "2025-01-03 10:00:00",
      "lastTime": "2025-01-01 14:00:00",
      "followCount": 2
    }
  ],
  "total": 15
}

1.13 查询我的线索

接口地址: GET /crm/clue/mine

接口描述: 查询当前用户负责的线索列表

权限标识: crm:clue:list

请求参数: 同1.1列表查询接口

返回示例: 同1.1列表查询接口


2. 线索跟进记录接口

2.1 查询跟进记录列表

接口地址: GET /crm/clue/follow/list

接口描述: 查询指定线索的跟进记录列表

权限标识: crm:clue:query

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | clueId | Long | 是 | 线索ID | | pageNum | Integer | 否 | 页码,默认1 | | pageSize | Integer | 否 | 每页条数,默认10 |

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "rows": [
    {
      "id": 1,
      "clueId": 1,
      "clueName": "张伟",
      "followType": "phone",
      "followContent": "电话沟通了客户需求,客户对CRM系统很感兴趣,希望能够演示一下产品功能",
      "nextTime": "2025-01-05 14:00:00",
      "attachments": "/upload/2025/01/file1.pdf,/upload/2025/01/file2.jpg",
      "createBy": 1,
      "createByName": "张三",
      "createTime": "2025-01-03 10:30:00",
      "remark": ""
    }
  ],
  "total": 5
}

2.2 新增跟进记录

接口地址: POST /crm/clue/follow

接口描述: 新增线索跟进记录

权限标识: crm:clue:follow

请求体:

{
  "clueId": 1,
  "followType": "phone",
  "followContent": "电话沟通了客户需求,客户对CRM系统很感兴趣",
  "nextTime": "2025-01-05 14:00:00",
  "attachments": "/upload/2025/01/file1.pdf",
  "remark": ""
}

请求参数说明: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | clueId | Long | 是 | 线索ID | | followType | String | 是 | 跟进方式:phone/wechat/email/visit/other | | followContent | String | 是 | 跟进内容,文本类型 | | nextTime | String | 否 | 下次联系时间 yyyy-MM-dd HH:mm:ss | | attachments | String | 否 | 附件路径,多个用逗号分隔 | | remark | String | 否 | 备注,最大500字符 |

业务规则:

  • 新增跟进记录后,自动更新线索的lastTime和followCount
  • 如果设置了nextTime,同步更新线索的nextTime
  • 如果线索状态为new,自动更新为follow

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

2.3 修改跟进记录

接口地址: PUT /crm/clue/follow

接口描述: 修改跟进记录信息

权限标识: crm:clue:follow

请求体:

{
  "id": 1,
  "followType": "phone",
  "followContent": "电话沟通了客户需求,客户对CRM系统很感兴趣",
  "nextTime": "2025-01-05 14:00:00",
  "attachments": "/upload/2025/01/file1.pdf",
  "remark": ""
}

业务规则:

  • 只能修改自己创建的跟进记录
  • 修改nextTime时同步更新线索的nextTime

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

2.4 删除跟进记录

接口地址: DELETE /crm/clue/follow/{ids}

接口描述: 删除跟进记录(支持批量)

权限标识: crm:clue:follow

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 跟进记录ID数组 |

业务规则:

  • 只能删除自己创建的跟进记录
  • 删除后需要重新计算线索的followCount

返回示例:

{
  "code": 200,
  "msg": "操作成功"
}

2.5 查询跟进记录详情

接口地址: GET /crm/clue/follow/{id}

接口描述: 根据ID查询跟进记录详情

权限标识: crm:clue:query

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 跟进记录ID |

返回示例:

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "id": 1,
    "clueId": 1,
    "clueName": "张伟",
    "followType": "phone",
    "followContent": "电话沟通了客户需求,客户对CRM系统很感兴趣",
    "nextTime": "2025-01-05 14:00:00",
    "attachments": "/upload/2025/01/file1.pdf",
    "createBy": 1,
    "createByName": "张三",
    "createTime": "2025-01-03 10:30:00",
    "remark": ""
  }
}

3. 线索转化接口

3.1 转化为客户

接口地址: POST /crm/clue/convert

接口描述: 将线索转化为客户

权限标识: crm:clue:convert

请求体:

{
  "clueId": 1,
  "createCustomer": true,
  "createContact": true,
  "customerName": "华为技术有限公司",
  "contactName": "张伟",
  "remark": "线索转化备注"
}

请求参数说明: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | clueId | Long | 是 | 线索ID | | createCustomer | Boolean | 是 | 是否创建客户 | | createContact | Boolean | 是 | 是否创建联系人 | | customerName | String | 否 | 客户名称(如果创建客户) | | contactName | String | 否 | 联系人姓名(如果创建联系人) | | remark | String | 否 | 转化说明 |

业务规则:

  • 只能转化未转化的线索
  • 转化后线索状态变为converted,isConverted=1
  • 记录转化时间、转化人、客户ID
  • 根据线索信息自动创建客户和/或联系人
  • 线索的跟进记录可关联到客户

返回示例:

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "customerId": 10,
    "contactId": 20
  }
}

3.2 校验是否可转化

接口地址: GET /crm/clue/checkConvert/{id}

接口描述: 校验线索是否可以转化

权限标识: crm:clue:query

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 线索ID |

返回示例:

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "canConvert": true,
    "reason": "",
    "existCustomer": false,
    "existContact": false
  }
}

4. 统计分析接口

4.1 线索统计概览

接口地址: GET /crm/clue/statistics/overview

接口描述: 获取线索统计概览数据

权限标识: crm:clue:list

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ownerUserId | Long | 否 | 负责人ID,不传则查询当前用户 | | beginTime | String | 否 | 开始时间 | | endTime | String | 否 | 结束时间 |

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "data": {
    "totalCount": 156,
    "newCount": 23,
    "followCount": 98,
    "invalidCount": 15,
    "convertedCount": 20,
    "weekAddCount": 23,
    "toFollowCount": 15,
    "weekConvertCount": 8,
    "convertRate": 12.82,
    "avgFollowCount": 3.5
  }
}

4.2 线索来源统计

接口地址: GET /crm/clue/statistics/source

接口描述: 按线索来源统计数量和转化率

权限标识: crm:clue:list

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | beginTime | String | 否 | 开始时间 | | endTime | String | 否 | 结束时间 |

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "data": [
    {
      "source": "website",
      "sourceName": "网站留言",
      "count": 45,
      "convertedCount": 12,
      "convertRate": 26.67
    },
    {
      "source": "phone",
      "sourceName": "电话咨询",
      "count": 32,
      "convertedCount": 8,
      "convertRate": 25.00
    }
  ]
}

4.3 线索等级分布

接口地址: GET /crm/clue/statistics/level

接口描述: 按线索等级统计分布情况

权限标识: crm:clue:list

请求参数: 无

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "data": [
    {
      "level": "A",
      "levelName": "A级(高)",
      "count": 35,
      "percent": 22.44
    },
    {
      "level": "B",
      "levelName": "B级(中)",
      "count": 58,
      "percent": 37.18
    },
    {
      "level": "C",
      "levelName": "C级(低)",
      "count": 43,
      "percent": 27.56
    },
    {
      "level": "unrated",
      "levelName": "未评级",
      "count": 20,
      "percent": 12.82
    }
  ]
}

4.4 线索转化趋势

接口地址: GET /crm/clue/statistics/trend

接口描述: 查询线索新增和转化趋势(按天/周/月)

权限标识: crm:clue:list

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | type | String | 否 | 统计类型:day/week/month,默认day | | beginTime | String | 否 | 开始时间 | | endTime | String | 否 | 结束时间 |

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "data": [
    {
      "date": "2025-01-01",
      "addCount": 12,
      "convertCount": 3
    },
    {
      "date": "2025-01-02",
      "addCount": 8,
      "convertCount": 2
    }
  ]
}

4.5 负责人线索统计

接口地址: GET /crm/clue/statistics/owner

接口描述: 按负责人统计线索数量和转化情况

权限标识: crm:clue:list

请求参数: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | beginTime | String | 否 | 开始时间 | | endTime | String | 否 | 结束时间 |

返回示例:

{
  "code": 200,
  "msg": "查询成功",
  "data": [
    {
      "ownerUserId": 1,
      "ownerUserName": "张三",
      "totalCount": 45,
      "newCount": 12,
      "followCount": 25,
      "convertedCount": 8,
      "convertRate": 17.78,
      "avgFollowCount": 3.2
    }
  ]
}

5. 数据模型

5.1 ClueBo(线索业务对象)

public class CrmClueBo extends BaseEntity {
    /** 主键ID */
    @NotNull(message = "主键不能为空", groups = { EditGroup.class })
    private Long id;

    /** 线索姓名 */
    @NotBlank(message = "线索姓名不能为空", groups = { AddGroup.class, EditGroup.class })
    private String clueName;

    /** 手机号 */
    @NotBlank(message = "手机号不能为空", groups = { AddGroup.class, EditGroup.class })
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式错误")
    private String mobile;

    /** 公司名称 */
    private String company;

    /** 固定电话 */
    private String telephone;

    /** 邮箱 */
    @Email(message = "邮箱格式错误")
    private String email;

    /** 称呼 */
    private String title;

    /** 职位 */
    private String position;

    /** 线索来源 */
    @NotBlank(message = "线索来源不能为空", groups = { AddGroup.class, EditGroup.class })
    private String source;

    /** 线索等级 */
    private String level;

    /** 所属行业 */
    private String industry;

    /** 省 */
    private String province;

    /** 市 */
    private String city;

    /** 区 */
    private String district;

    /** 详细地址 */
    private String address;

    /** 客户网站 */
    private String website;

    /** 意向产品 */
    private String intentProducts;

    /** 预计购买时间 */
    private String expectTime;

    /** 预算范围 */
    private String budget;

    /** 需求描述 */
    private String requirement;

    /** 线索状态 */
    private String status;

    /** 负责人ID */
    private Long ownerUserId;

    /** 下次联系时间 */
    private LocalDateTime nextTime;

    /** 备注 */
    private String remark;
}

5.2 ClueVo(线索视图对象)

public class CrmClueVo implements Serializable {
    /** 主键ID */
    @ExcelProperty(value = "ID")
    private Long id;

    /** 线索姓名 */
    @ExcelProperty(value = "线索姓名")
    private String clueName;

    /** 手机号 */
    @ExcelProperty(value = "手机号")
    private String mobile;

    /** 公司名称 */
    @ExcelProperty(value = "公司名称")
    private String company;

    /** 固定电话 */
    @ExcelProperty(value = "固定电话")
    private String telephone;

    /** 邮箱 */
    @ExcelProperty(value = "邮箱")
    private String email;

    /** 称呼 */
    @ExcelProperty(value = "称呼", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "crm_title")
    private String title;

    /** 职位 */
    @ExcelProperty(value = "职位")
    private String position;

    /** 线索来源 */
    @ExcelProperty(value = "线索来源", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "crm_clue_source")
    private String source;

    /** 线索等级 */
    @ExcelProperty(value = "线索等级", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "crm_clue_level")
    private String level;

    /** 所属行业 */
    @ExcelProperty(value = "所属行业")
    private String industry;

    /** 省 */
    @ExcelProperty(value = "省")
    private String province;

    /** 市 */
    @ExcelProperty(value = "市")
    private String city;

    /** 区 */
    @ExcelProperty(value = "区")
    private String district;

    /** 详细地址 */
    @ExcelProperty(value = "详细地址")
    private String address;

    /** 客户网站 */
    @ExcelProperty(value = "客户网站")
    private String website;

    /** 意向产品 */
    @ExcelProperty(value = "意向产品")
    private String intentProducts;

    /** 预计购买时间 */
    @ExcelProperty(value = "预计购买时间")
    private String expectTime;

    /** 预算范围 */
    @ExcelProperty(value = "预算范围", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "crm_budget")
    private String budget;

    /** 需求描述 */
    private String requirement;

    /** 线索状态 */
    @ExcelProperty(value = "线索状态", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "crm_clue_status")
    private String status;

    /** 负责人ID */
    private Long ownerUserId;

    /** 负责人姓名 */
    @ExcelProperty(value = "负责人")
    private String ownerUserName;

    /** 最后跟进时间 */
    @ExcelProperty(value = "最后跟进时间")
    private LocalDateTime lastTime;

    /** 下次联系时间 */
    @ExcelProperty(value = "下次联系时间")
    private LocalDateTime nextTime;

    /** 跟进次数 */
    @ExcelProperty(value = "跟进次数")
    private Integer followCount;

    /** 是否已转化 */
    private Integer isConverted;

    /** 转化时间 */
    @ExcelProperty(value = "转化时间")
    private LocalDateTime convertedTime;

    /** 客户ID */
    private Long customerId;

    /** 转化操作人 */
    private Long convertedBy;

    /** 分配时间 */
    private LocalDateTime assignTime;

    /** 分配人 */
    private Long assignBy;

    /** 创建时间 */
    @ExcelProperty(value = "创建时间")
    private LocalDateTime createTime;

    /** 更新时间 */
    @ExcelProperty(value = "更新时间")
    private LocalDateTime updateTime;

    /** 备注 */
    @ExcelProperty(value = "备注")
    private String remark;
}

5.3 ClueFollowBo(跟进记录业务对象)

public class CrmClueFollowBo extends BaseEntity {
    /** 主键ID */
    @NotNull(message = "主键不能为空", groups = { EditGroup.class })
    private Long id;

    /** 线索ID */
    @NotNull(message = "线索ID不能为空", groups = { AddGroup.class })
    private Long clueId;

    /** 跟进方式 */
    @NotBlank(message = "跟进方式不能为空", groups = { AddGroup.class, EditGroup.class })
    private String followType;

    /** 跟进内容 */
    @NotBlank(message = "跟进内容不能为空", groups = { AddGroup.class, EditGroup.class })
    private String followContent;

    /** 下次联系时间 */
    private LocalDateTime nextTime;

    /** 附件 */
    private String attachments;

    /** 备注 */
    private String remark;
}

5.4 ClueFollowVo(跟进记录视图对象)

public class CrmClueFollowVo implements Serializable {
    /** 主键ID */
    private Long id;

    /** 线索ID */
    private Long clueId;

    /** 线索姓名 */
    private String clueName;

    /** 跟进方式 */
    @ExcelProperty(value = "跟进方式", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "crm_follow_type")
    private String followType;

    /** 跟进内容 */
    @ExcelProperty(value = "跟进内容")
    private String followContent;

    /** 下次联系时间 */
    @ExcelProperty(value = "下次联系时间")
    private LocalDateTime nextTime;

    /** 附件 */
    private String attachments;

    /** 跟进人ID */
    private Long createBy;

    /** 跟进人姓名 */
    @ExcelProperty(value = "跟进人")
    private String createByName;

    /** 跟进时间 */
    @ExcelProperty(value = "跟进时间")
    private LocalDateTime createTime;

    /** 备注 */
    @ExcelProperty(value = "备注")
    private String remark;
}

6. 数据字典

6.1 线索来源 (crm_clue_source)

字典值 字典标签 说明
website 网站留言 官网表单提交
phone 电话咨询 主动来电咨询
exhibition 展会 展会获取
activity 市场活动 线下活动
referral 老客户推荐 客户推荐
ads 广告投放 广告渠道
social_media 社交媒体 微信、微博等
other 其他 其他渠道

6.2 线索等级 (crm_clue_level)

字典值 字典标签 说明
A A级(高) 高意向线索
B B级(中) 中意向线索
C C级(低) 低意向线索
unrated 未评级 尚未评级

6.3 线索状态 (crm_clue_status)

字典值 字典标签 说明
new 新线索 刚创建的线索
follow 跟进中 正在跟进
invalid 无效 无效线索
converted 已转化 已转化为客户

6.4 预算范围 (crm_budget)

字典值 字典标签 说明
below_10k 1万以下 预算1万以下
10k_50k 1-5万 预算1-5万
50k_100k 5-10万 预算5-10万
100k_500k 10-50万 预算10-50万
above_500k 50万以上 预算50万以上
unknown 未知 预算未知

6.5 跟进方式 (crm_follow_type)

字典值 字典标签 说明
phone 电话 电话沟通
wechat 微信 微信沟通
email 邮件 邮件沟通
visit 拜访 上门拜访
other 其他 其他方式

7. 权限标识汇总

权限标识 说明
crm:clue:list 线索列表查询
crm:clue:query 线索详情查询
crm:clue:add 线索新增
crm:clue:edit 线索修改
crm:clue:remove 线索删除
crm:clue:export 线索导出
crm:clue:import 线索导入
crm:clue:assign 线索分配
crm:clue:follow 添加跟进记录
crm:clue:convert 线索转化

8. 注意事项

  1. 手机号唯一性: 同一租户下手机号必须唯一
  2. 数据权限: 需要根据负责人字段实现数据权限控制
  3. 跟进记录关联: 新增跟进记录时自动更新线索的跟进统计信息
  4. 状态自动变更: 首次跟进时自动将状态从new变更为follow
  5. 转化限制: 已转化的线索不允许删除和修改关键信息
  6. 附件存储: 附件路径存储相对路径,多个用逗号分隔
  7. 时间提醒: nextTime字段用于生成待办任务和提醒
  8. 数据脱敏: 手机号和邮箱需要根据权限进行脱敏显示
  9. 批量操作: 批量操作需要注意事务一致性
  10. 删除关联: 删除线索时需要同时删除关联的跟进记录

文档结束