本次改造实现销售全流程追溯功能,可从商机、合同、客户等多个维度查看完整的销售流程信息,包括商机 -> 合同 -> 销售订单 -> 出库 -> 回款 -> 退货的全链路数据。
| 文件 | 改动说明 |
|---|---|
CrmSaleTraceApi.java |
销售追溯 API 接口 |
CrmSaleTraceRespDTO.java |
销售追溯响应 DTO |
CrmSaleTraceApiImpl.java |
销售追溯 API 实现 |
CrmBusinessDO.java |
新增 orderId、orderNo 字段 |
CrmBusinessRespVO.java |
新增 orderId、orderNo 字段 |
CrmContractMapper.java |
新增 selectByBusinessId、selectListByCustomerId 方法 |
CrmReceivableService.java |
新增 getReceivablePriceByContractId 方法 |
| 页面 | 路径 | 改动说明 |
|---|---|---|
| 商机详情 | /crm/business/detail |
添加销售流程追溯入口 |
| 合同详情 | /crm/contract/detail |
添加销售流程追溯入口 |
| 客户详情 | /crm/customer/detail |
添加销售流程追溯列表 |
| 页面 | 路径 | 说明 |
|---|---|---|
| 销售追溯详情 | /crm/sale-trace/detail |
销售流程追溯详情页 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /rpc-api/crm/sale-trace/get-by-business-id | 根据商机编号获取追溯信息 |
| GET | /rpc-api/crm/sale-trace/get-by-contract-id | 根据合同编号获取追溯信息 |
| GET | /rpc-api/crm/sale-trace/get-list-by-customer-id | 根据客户编号获取追溯列表 |
响应示例:
{
"code": 0,
"data": {
"businessId": 1,
"businessName": "商机A",
"businessPrice": 100000,
"businessStatus": "进行中",
"businessCreateTime": "2024-01-01 10:00:00",
"customerId": 1,
"customerName": "客户A",
"contractId": 1,
"contractName": "合同A",
"contractPrice": 95000,
"contractStatus": 20,
"contractCreateTime": "2024-01-15 10:00:00",
"orderId": 1,
"orderNo": "SO001",
"orderPrice": 95000,
"orderStatus": 0,
"orderCreateTime": "2024-01-16 10:00:00",
"receivablePrice": 50000,
"receivableItems": [
{
"receivableId": 1,
"receivableNo": "RK001",
"price": 30000,
"receivableTime": "2024-02-01"
},
{
"receivableId": 2,
"receivableNo": "RK002",
"price": 20000,
"receivableTime": "2024-03-01"
}
]
}
}
文件路径: /src/views/crm/business/detail.vue
新增组件:
<!-- 销售流程追溯卡片 -->
<el-card class="sale-trace-card" header="销售流程追溯">
<div v-if="traceInfo">
<!-- 流程时间线 -->
<el-timeline>
<el-timeline-item
:timestamp="traceInfo.businessCreateTime"
placement="top"
color="#409EFF"
>
<el-card>
<h4>商机创建</h4>
<p>商机名称:{{ traceInfo.businessName }}</p>
<p>商机金额:¥{{ traceInfo.businessPrice }}</p>
</el-card>
</el-timeline-item>
<el-timeline-item
v-if="traceInfo.contractId"
:timestamp="traceInfo.contractCreateTime"
placement="top"
color="#67C23A"
>
<el-card>
<h4>合同签订</h4>
<p>合同名称:{{ traceInfo.contractName }}</p>
<p>合同金额:¥{{ traceInfo.contractPrice }}</p>
<p>合同状态:{{ getContractStatusText(traceInfo.contractStatus) }}</p>
</el-card>
</el-timeline-item>
<el-timeline-item
v-if="traceInfo.orderId"
:timestamp="traceInfo.orderCreateTime"
placement="top"
color="#E6A23C"
>
<el-card>
<h4>销售订单</h4>
<p>订单号:<el-link type="primary" @click="viewOrder(traceInfo.orderId)">{{ traceInfo.orderNo }}</el-link></p>
<p>订单金额:¥{{ traceInfo.orderPrice }}</p>
<p>订单状态:{{ getOrderStatusText(traceInfo.orderStatus) }}</p>
</el-card>
</el-timeline-item>
<el-timeline-item
v-if="traceInfo.receivablePrice > 0"
placement="top"
color="#F56C6C"
>
<el-card>
<h4>回款记录</h4>
<p>已回款金额:¥{{ traceInfo.receivablePrice }}</p>
<el-table v-if="traceInfo.receivableItems" :data="traceInfo.receivableItems" size="small">
<el-table-column prop="receivableNo" label="回款单号" />
<el-table-column prop="price" label="回款金额" />
<el-table-column prop="receivableTime" label="回款时间" />
</el-table>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
<div v-else>
<el-empty description="暂无销售流程数据" />
</div>
</el-card>
新增方法:
import { getTraceByBusinessId } from '@/api/crm/saleTrace'
data() {
return {
traceInfo: null
}
},
methods: {
async loadTraceInfo() {
const { data } = await getTraceByBusinessId(this.businessId)
this.traceInfo = data
},
getContractStatusText(status) {
const statusMap = { 0: '草稿', 10: '审批中', 20: '审批通过', 30: '审批不通过' }
return statusMap[status] || '未知'
},
getOrderStatusText(status) {
const statusMap = { 0: '未审核', 10: '已审核' }
return statusMap[status] || '未知'
},
viewOrder(orderId) {
this.$router.push({ path: '/erp/sale/order/detail', query: { id: orderId } })
}
}
文件路径: /src/views/crm/contract/detail.vue
新增方法:
import { getTraceByContractId } from '@/api/crm/saleTrace'
methods: {
async loadTraceInfo() {
const { data } = await getTraceByContractId(this.contractId)
this.traceInfo = data
}
}
文件路径: /src/views/crm/customer/detail.vue
新增列表:
<el-card header="销售流程追溯">
<el-table :data="traceList" size="small">
<el-table-column prop="businessName" label="商机名称">
<template #default="{ row }">
<el-link v-if="row.businessId" type="primary" @click="viewBusiness(row.businessId)">
{{ row.businessName }}
</el-link>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column prop="contractName" label="合同名称">
<template #default="{ row }">
<el-link v-if="row.contractId" type="primary" @click="viewContract(row.contractId)">
{{ row.contractName }}
</el-link>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column prop="contractPrice" label="合同金额" width="120" />
<el-table-column prop="orderNo" label="销售订单">
<template #default="{ row }">
<el-link v-if="row.orderId" type="primary" @click="viewOrder(row.orderId)">
{{ row.orderNo }}
</el-link>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column prop="receivablePrice" label="已回款" width="120" />
<el-table-column label="回款率" width="100">
<template #default="{ row }">
<span v-if="row.contractPrice > 0">
{{ ((row.receivablePrice / row.contractPrice) * 100).toFixed(1) }}%
</span>
<span v-else>-</span>
</template>
</el-table-column>
</el-table>
</el-card>
文件路径: /src/api/crm/saleTrace.js
import request from '@/utils/request'
// 根据商机编号获取销售流程追溯信息
export function getTraceByBusinessId(businessId) {
return request({
url: '/crm/sale-trace/get-by-business-id',
method: 'get',
params: { businessId }
})
}
// 根据合同编号获取销售流程追溯信息
export function getTraceByContractId(contractId) {
return request({
url: '/crm/sale-trace/get-by-contract-id',
method: 'get',
params: { contractId }
})
}
// 根据客户编号获取销售流程追溯列表
export function getTraceListByCustomerId(customerId) {
return request({
url: '/crm/sale-trace/get-list-by-customer-id',
method: 'get',
params: { customerId }
})
}
ALTER TABLE `crm_business`
ADD COLUMN `order_id` bigint DEFAULT NULL COMMENT '关联 ERP 销售订单编号' AFTER `total_price`,
ADD COLUMN `order_no` varchar(32) DEFAULT NULL COMMENT 'ERP 销售订单单号' AFTER `order_id`;
商机创建 → 商机跟进 → 合同签订 → 合同审批 → 生成订单 → 订单审批 → 销售出库 → 客户回款
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
10:00 12:00 15:00 16:00 17:00 18:00 20:00 25:00
(金额变化追踪)
商机金额(100K) → 合同金额(95K) → 订单金额(95K) → 出库金额(95K) → 回款金额(50K)
| Phase | 内容 | 状态 |
|---|---|---|
| Phase 1 | 客户数据统一 - ERP 使用 CRM 客户 | 已完成 |
| Phase 2 | 产品数据统一 - CRM/ERP 使用 MDM 物料 | 已完成 |
| Phase 3 | 合同生成销售订单 | 已完成 |
| Phase 4 | 销售全流程追溯 | 已完成 |
| Phase 5 | 营销数据报表 | 待开始 |
| Phase 6 | 数据迁移与清理 | 待开始 |