# CRM 合同生成 ERP 销售订单 - 前端文档
## 概述
本次改造实现 CRM 合同审批通过后,可直接生成 ERP 销售订单,打通合同到订单的业务流程。
---
## 一、改造清单
### 后端改造(已完成)
| 文件 | 改动说明 |
|------|----------|
| `yudao-module-erp-api/` | 新增 ERP 销售订单 API 模块 |
| `ErpSaleOrderApi.java` | 销售订单 API 接口 |
| `ErpSaleOrderCreateReqDTO.java` | 销售订单创建请求 DTO |
| `ErpSaleOrderRespDTO.java` | 销售订单响应 DTO |
| `ErpSaleOrderApiImpl.java` | ERP 销售订单 API 实现 |
| `CrmContractDO.java` | 新增 orderId、orderNo 字段 |
| `ErpSaleOrderDO.java` | 新增 contractId、contractNo 字段 |
| `CrmContractService.java` | 新增 generateSaleOrder 方法 |
| `CrmContractServiceImpl.java` | 实现生成销售订单逻辑 |
| `CrmContractController.java` | 新增生成销售订单 API |
| `CrmContractRespVO.java` | 新增 orderId、orderNo 字段 |
---
## 二、涉及页面
### CRM 合同管理
| 页面 | 路径 | 改动说明 |
|------|------|----------|
| 合同列表 | `/crm/contract/index` | 添加"生成销售订单"按钮 |
| 合同详情 | `/crm/contract/detail` | 显示关联的销售订单信息 |
### ERP 销售订单管理
| 页面 | 路径 | 改动说明 |
|------|------|----------|
| 销售订单列表 | `/erp/sale/order/index` | 显示关联合同信息 |
| 销售订单详情 | `/erp/sale/order/detail` | 显示关联合同信息 |
---
## 三、API 接口
### CRM 合同 API
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /crm/contract/generate-sale-order | 根据合同生成销售订单 |
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 合同编号 |
**响应:**
```json
{
"code": 0,
"data": 12345,
"msg": "操作成功"
}
```
### ERP 销售订单 API(新增 RPC)
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /rpc-api/erp/sale-order/create | 创建销售订单 |
| GET | /rpc-api/erp/sale-order/get | 获取销售订单 |
| GET | /rpc-api/erp/sale-order/get-by-contract-id | 根据合同编号获取订单 |
---
## 四、前端修改点
### 4.1 合同列表页面
**文件路径:** `/src/views/crm/contract/index.vue`
**新增按钮:**
```html
生成销售订单
查看订单
```
**新增方法:**
```js
methods: {
// 生成销售订单
async handleGenerateOrder(row) {
try {
await this.$confirm('确认根据该合同生成销售订单?', '提示')
const { data } = await generateSaleOrder(row.id)
this.$message.success('生成销售订单成功,订单号:' + data)
this.getList() // 刷新列表
} catch (e) {
if (e !== 'cancel') {
this.$message.error(e.message || '生成失败')
}
}
},
// 查看销售订单
handleViewOrder(row) {
this.$router.push({
path: '/erp/sale/order/detail',
query: { id: row.orderId }
})
}
}
```
**新增 API:**
```js
// api/crm/contract.js
export function generateSaleOrder(id) {
return request({
url: '/crm/contract/generate-sale-order',
method: 'post',
params: { id }
})
}
```
### 4.2 合同详情页面
**文件路径:** `/src/views/crm/contract/detail.vue`
**新增显示字段:**
```html
{{ contract.orderNo }}
生成销售订单
未生成
```
### 4.3 销售订单列表页面
**文件路径:** `/src/views/erp/sale/order/index.vue`
**新增列显示:**
```html
{{ row.contractNo }}
-
```
### 4.4 销售订单详情页面
**文件路径:** `/src/views/erp/sale/order/detail.vue`
**新增显示字段:**
```html
{{ order.contractNo }}
-
```
---
## 五、数据模型变更
### CRM 合同表变更
```sql
ALTER TABLE `crm_contract`
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`;
```
### ERP 销售订单表变更
```sql
ALTER TABLE `erp_sale_order`
ADD COLUMN `contract_id` bigint DEFAULT NULL COMMENT '关联 CRM 合同编号' AFTER `customer_id`,
ADD COLUMN `contract_no` varchar(32) DEFAULT NULL COMMENT 'CRM 合同单号' AFTER `contract_id`;
```
---
## 六、业务规则
### 6.1 生成销售订单条件
- 合同必须审批通过(auditStatus = 20)
- 合同未关联销售订单(orderId 为空)
- 合同必须包含产品信息
### 6.2 销售订单数据来源
- 客户:合同客户
- 产品:合同产品列表
- 金额:合同金额(扣除折扣)
- 备注:自动添加"由合同【xxx】自动生成"
### 6.3 数据关联
- 销售订单创建后,自动回填合同 orderId、orderNo
- 销售订单记录 contractId、contractNo 用于反向查询
---
## 七、注意事项
1. **状态控制**:只有审批通过的合同才能生成订单
2. **唯一性**:一个合同只能生成一个销售订单
3. **数据同步**:生成订单后,合同与订单双向关联
4. **权限要求**:需要有合同编辑权限才能生成订单
5. **订单状态**:生成的销售订单默认为"未审核"状态,需要在 ERP 中审批
---
## 八、后续计划
| Phase | 内容 | 状态 |
|-------|------|------|
| Phase 1 | 客户数据统一 - ERP 使用 CRM 客户 | **已完成** |
| Phase 2 | 产品数据统一 - CRM/ERP 使用 MDM 物料 | **已完成** |
| Phase 3 | 合同生成销售订单 | **已完成** |
| Phase 4 | 销售全流程追溯 | 待开始 |
| Phase 5 | 营销数据报表 | 待开始 |
| Phase 6 | 数据迁移与清理 | 待开始 |