From 6e312c64c056acf479a6dd8393dd42a80b69b7d4 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 02 七月 2026 10:25:07 +0800
Subject: [PATCH] 1.新增销售报价 2.crm整合mdm
---
docs/crm_erp_integration_frontend.md | 986 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 927 insertions(+), 59 deletions(-)
diff --git a/docs/crm_erp_integration_frontend.md b/docs/crm_erp_integration_frontend.md
index 066a188..3a3afbc 100644
--- a/docs/crm_erp_integration_frontend.md
+++ b/docs/crm_erp_integration_frontend.md
@@ -1,46 +1,52 @@
-# CRM 涓� ERP 閿�鍞竴浣撳寲鏀归�� - 鍓嶇鏂囨。
+# CRM 涓� ERP 閿�鍞竴浣撳寲鏀归�� - 鍓嶇鏂囨。锛堝畬鏁寸増锛�
## 姒傝堪
-鏈鏀归�犲皢 CRM 瀹㈡埛浣滀负缁熶竴瀹㈡埛涓绘暟鎹紝ERP 閿�鍞ā鍧楋紙閿�鍞鍗曘�侀攢鍞嚭搴撱�侀攢鍞��璐с�佹敹娆惧崟锛夌粺涓�浣跨敤 CRM 瀹㈡埛銆�
+鏈鏀归�犲疄鐜� CRM 涓� ERP 閿�鍞ā鍧楃殑娣卞害闆嗘垚锛屽寘鎷細
+- **Phase 1**锛氬鎴锋暟鎹粺涓� - ERP 浣跨敤 CRM 瀹㈡埛
+- **Phase 2**锛氫骇鍝佹暟鎹粺涓� - CRM/ERP 浣跨敤 MDM 鐗╂枡
+- **Phase 3**锛氬悎鍚岀敓鎴愰攢鍞鍗�
+- **Phase 4**锛氶攢鍞叏娴佺▼杩芥函
+- **Phase 5**锛氳惀閿�鏁版嵁鎶ヨ〃
+- **Phase 6**锛氭暟鎹縼绉讳笌娓呯悊锛圫QL 閮ㄥ垎锛�
---
-## 涓�銆佹敼閫犳竻鍗�
+## 涓�銆佹敼閫犳竻鍗曟眹鎬�
-### 鍚庣鏀归�狅紙宸插畬鎴愶級
+### 1.1 鏂板妯″潡
+
+| 妯″潡 | 璇存槑 |
+|------|------|
+| `yudao-module-crm-api` | CRM API 妯″潡锛堝鎴� API銆佹姤琛� API銆佽拷婧� API锛� |
+| `yudao-module-erp-api` | ERP API 妯″潡锛堥攢鍞鍗� API锛� |
+| `yudao-module-mdm-api` | MDM API 妯″潡锛堢墿鏂� API锛� |
+
+### 1.2 鍚庣鏀归�犳枃浠�
| 鏂囦欢 | 鏀瑰姩璇存槑 |
|------|----------|
-| `yudao-module-crm-api/` | 鏂板 CRM 瀹㈡埛 API 妯″潡 |
-| `CrmCustomerApi.java` | 鏂板瀹㈡埛 API 鎺ュ彛 |
-| `CrmCustomerRespDTO.java` | 鏂板瀹㈡埛 DTO |
-| `CrmCustomerApiImpl.java` | 瀹炵幇 CRM 瀹㈡埛 API |
+| `CrmCustomerApi.java` | CRM 瀹㈡埛 API 鎺ュ彛 |
+| `CrmCustomerRespDTO.java` | 瀹㈡埛鍝嶅簲 DTO |
+| `CrmReportApi.java` | 钀ラ攢鎶ヨ〃 API 鎺ュ彛 |
+| `CrmSaleTraceApi.java` | 閿�鍞拷婧� API 鎺ュ彛 |
+| `ErpSaleOrderApi.java` | 閿�鍞鍗� API 鎺ュ彛 |
+| `MdmItemApi.java` | MDM 鐗╂枡 API 鎺ュ彛 |
| `ErpSaleOrderServiceImpl.java` | 浣跨敤 CRM 瀹㈡埛 API |
| `ErpFinanceReceiptServiceImpl.java` | 浣跨敤 CRM 瀹㈡埛 API |
-| `ErpSaleOrderController.java` | 浣跨敤 CRM 瀹㈡埛 API |
-| `ErpSaleOrderDO.java` | 鏇存柊娉ㄩ噴鍏宠仈 CRM 瀹㈡埛 |
-| `ErpSaleOutDO.java` | 鏇存柊娉ㄩ噴鍏宠仈 CRM 瀹㈡埛 |
-| `ErpSaleReturnDO.java` | 鏇存柊娉ㄩ噴鍏宠仈 CRM 瀹㈡埛 |
-| `ErpFinanceReceiptDO.java` | 鏇存柊娉ㄩ噴鍏宠仈 CRM 瀹㈡埛 |
-
-### 鍚庣鏀归�狅紙寰呭畬鎴愶級
-
-| 鏂囦欢 | 鏀瑰姩璇存槑 |
-|------|----------|
-| `ErpSaleOutController.java` | 浣跨敤 CRM 瀹㈡埛 API |
-| `ErpSaleReturnController.java` | 浣跨敤 CRM 瀹㈡埛 API |
-| `ErpFinanceReceiptController.java` | 浣跨敤 CRM 瀹㈡埛 API |
+| `CrmContractServiceImpl.java` | 鏂板鐢熸垚閿�鍞鍗曟柟娉� |
+| `CrmProductServiceImpl.java` | 浣跨敤 MDM 鐗╂枡 API |
+| `ErpProductServiceImpl.java` | 浣跨敤 MDM 鐗╂枡 API |
---
## 浜屻�佹秹鍙婇〉闈�
-### ERP 閿�鍞ā鍧�
+### 2.1 ERP 閿�鍞ā鍧�
| 椤甸潰 | 璺緞 | 鏀瑰姩璇存槑 |
|------|------|----------|
-| 閿�鍞鍗曞垪琛� | `/erp/sale/order/index` | 瀹㈡埛閫夋嫨鏀逛负 CRM 瀹㈡埛閫夋嫨缁勪欢 |
+| 閿�鍞鍗曞垪琛� | `/erp/sale/order/index` | 瀹㈡埛閫夋嫨鏀逛负 CRM 瀹㈡埛锛屾柊澧炲叧鑱斿悎鍚屽垪 |
| 閿�鍞鍗曡〃鍗� | `/erp/sale/order/form` | 瀹㈡埛閫夋嫨鏀逛负 CRM 瀹㈡埛閫夋嫨缁勪欢 |
| 閿�鍞嚭搴撳垪琛� | `/erp/sale/out/index` | 瀹㈡埛閫夋嫨鏀逛负 CRM 瀹㈡埛閫夋嫨缁勪欢 |
| 閿�鍞嚭搴撹〃鍗� | `/erp/sale/out/form` | 瀹㈡埛閫夋嫨鏀逛负 CRM 瀹㈡埛閫夋嫨缁勪欢 |
@@ -49,35 +55,43 @@
| 鏀舵鍗曞垪琛� | `/erp/finance/receipt/index` | 瀹㈡埛閫夋嫨鏀逛负 CRM 瀹㈡埛閫夋嫨缁勪欢 |
| 鏀舵鍗曡〃鍗� | `/erp/finance/receipt/form` | 瀹㈡埛閫夋嫨鏀逛负 CRM 瀹㈡埛閫夋嫨缁勪欢 |
+### 2.2 CRM 鍚堝悓妯″潡
+
+| 椤甸潰 | 璺緞 | 鏀瑰姩璇存槑 |
+|------|------|----------|
+| 鍚堝悓鍒楄〃 | `/crm/contract/index` | 娣诲姞"鐢熸垚閿�鍞鍗�"鎸夐挳 |
+| 鍚堝悓璇︽儏 | `/crm/contract/detail` | 鏄剧ず閿�鍞鍗曚俊鎭�侀攢鍞祦绋嬭拷婧� |
+
+### 2.3 CRM 鍟嗘満妯″潡
+
+| 椤甸潰 | 璺緞 | 鏀瑰姩璇存槑 |
+|------|------|----------|
+| 鍟嗘満璇︽儏 | `/crm/business/detail` | 娣诲姞閿�鍞祦绋嬭拷婧叆鍙� |
+
+### 2.4 CRM 瀹㈡埛妯″潡
+
+| 椤甸潰 | 璺緞 | 鏀瑰姩璇存槑 |
+|------|------|----------|
+| 瀹㈡埛璇︽儏 | `/crm/customer/detail` | 娣诲姞閿�鍞祦绋嬭拷婧垪琛� |
+
+### 2.5 CRM 鎶ヨ〃妯″潡锛堟柊澧烇級
+
+| 椤甸潰 | 璺緞 | 璇存槑 |
+|------|------|------|
+| 鎶ヨ〃姒傝 | `/crm/report/dashboard` | 鏁版嵁姒傝椤甸潰 |
+
---
-## 涓夈�佸鎴烽�夋嫨缁勪欢
+## 涓夈�丄PI 鎺ュ彛
-### 3.1 浣跨敤 CRM 瀹㈡埛閫夋嫨缁勪欢
-
-ERP 閿�鍞ā鍧楃殑瀹㈡埛閫夋嫨缁熶竴浣跨敤 CRM 瀹㈡埛閫夋嫨缁勪欢銆�
-
-```html
-<!-- 鍘熸潵锛欵RP 瀹㈡埛閫夋嫨 -->
-<el-select v-model="form.customerId" placeholder="璇烽�夋嫨瀹㈡埛">
- <el-option
- v-for="item in customerList"
- :key="item.id"
- :label="item.name"
- :value="item.id"
- />
-</el-select>
-
-<!-- 鏀逛负锛欳RM 瀹㈡埛閫夋嫨缁勪欢 -->
-<CrmCustomerSelect v-model="form.customerId" />
-```
-
-### 3.2 CRM 瀹㈡埛 API
+### 3.1 CRM 瀹㈡埛 API
| 鏂规硶 | 璺緞 | 璇存槑 |
|------|------|------|
| GET | /crm/customer/simple-list | 鑾峰彇瀹㈡埛绮剧畝鍒楄〃锛堢敤浜庝笅鎷夐�夋嫨锛� |
| GET | /crm/customer/list-by-ids | 鎵归噺鑾峰彇瀹㈡埛淇℃伅 |
+| GET | /rpc-api/crm/customer/get | 鑾峰彇鍗曚釜瀹㈡埛 |
+| POST | /rpc-api/crm/customer/validate | 鏍¢獙瀹㈡埛瀛樺湪 |
**瀹㈡埛绮剧畝鍒楄〃鍝嶅簲锛�**
@@ -96,26 +110,670 @@
}
```
----
+### 3.2 CRM 鍚堝悓 API锛堟柊澧烇級
-## 鍥涖�佸簾寮冪殑 ERP 瀹㈡埛绠$悊
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /crm/contract/generate-sale-order | 鏍规嵁鍚堝悓鐢熸垚閿�鍞鍗� |
-### 4.1 ERP 瀹㈡埛绠$悊椤甸潰搴熷純
+**璇锋眰鍙傛暟锛�**
-浠ヤ笅椤甸潰鏍囪涓哄簾寮冿紝寤鸿鍦ㄨ彍鍗曚腑闅愯棌鎴栧垹闄わ細
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鍚堝悓缂栧彿 |
-- `/erp/customer/index` - ERP 瀹㈡埛鍒楄〃
-- `/erp/customer/form` - ERP 瀹㈡埛琛ㄥ崟
+**鍝嶅簲锛�**
+
+```json
+{
+ "code": 0,
+ "data": 12345,
+ "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+### 3.3 CRM 閿�鍞拷婧� API锛堟柊澧烇級
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| 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 | 鏍规嵁瀹㈡埛缂栧彿鑾峰彇杩芥函鍒楄〃 |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "businessId": 1,
+ "businessName": "鍟嗘満A",
+ "businessPrice": 100000,
+ "customerId": 1,
+ "customerName": "瀹㈡埛A",
+ "contractId": 1,
+ "contractName": "鍚堝悓A",
+ "contractPrice": 95000,
+ "contractStatus": 20,
+ "orderId": 1,
+ "orderNo": "SO001",
+ "orderPrice": 95000,
+ "receivablePrice": 50000,
+ "receivableItems": [
+ { "receivableId": 1, "receivableNo": "RK001", "price": 30000 }
+ ]
+ }
+}
+```
+
+### 3.4 CRM 钀ラ攢鎶ヨ〃 API锛堟柊澧烇級
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /rpc-api/crm/report/get-customer-analyze | 鑾峰彇瀹㈡埛鍒嗘瀽缁熻 |
+| GET | /rpc-api/crm/report/get-business-analyze | 鑾峰彇鍟嗘満鍒嗘瀽缁熻 |
+| GET | /rpc-api/crm/report/get-contract-analyze | 鑾峰彇鍚堝悓鍒嗘瀽缁熻 |
+| GET | /rpc-api/crm/report/get-sales-funnel | 鑾峰彇閿�鍞紡鏂楃粺璁� |
+| GET | /rpc-api/crm/report/get-sales-performance | 鑾峰彇閿�鍞笟缁╃粺璁� |
+
+**瀹㈡埛鍒嗘瀽鍝嶅簲锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "totalCount": 1000,
+ "todayCount": 15,
+ "dealCount": 300,
+ "dealRate": 30.00,
+ "lockCount": 50,
+ "poolCount": 200
+ }
+}
+```
+
+**鍟嗘満鍒嗘瀽鍝嶅簲锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "totalCount": 500,
+ "todayCount": 8,
+ "totalPrice": 5000000.00,
+ "successCount": 150,
+ "successPrice": 2000000.00,
+ "successRate": 30.00,
+ "processingCount": 250,
+ "failCount": 100
+ }
+}
+```
+
+**鍚堝悓鍒嗘瀽鍝嶅簲锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "totalCount": 400,
+ "todayCount": 5,
+ "totalPrice": 3000000.00,
+ "approveCount": 300,
+ "approvePrice": 2500000.00,
+ "processCount": 20,
+ "receivablePrice": 1500000.00,
+ "receivableRate": 60.00
+ }
+}
+```
+
+**閿�鍞紡鏂楀搷搴旓細**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "stages": [
+ { "name": "瀹㈡埛", "count": 1000, "price": 0, "conversionRate": 100.00 },
+ { "name": "鍟嗘満", "count": 500, "price": 5000000.00, "conversionRate": 50.00 },
+ { "name": "鍚堝悓", "count": 300, "price": 2500000.00, "conversionRate": 30.00 },
+ { "name": "鍥炴", "count": null, "price": 1500000.00, "conversionRate": 15.00 }
+ ]
+ }
+}
+```
+
+**閿�鍞笟缁╁搷搴旓細**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "items": [
+ {
+ "userId": 1,
+ "userName": "寮犱笁",
+ "deptName": "閿�鍞竴閮�",
+ "contractCount": 50,
+ "contractPrice": 500000.00,
+ "receivablePrice": 300000.00,
+ "businessCount": 80,
+ "businessPrice": 800000.00
+ }
+ ]
+ }
+}
+```
+
+### 3.5 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 | 鏍规嵁鍚堝悓缂栧彿鑾峰彇璁㈠崟 |
+
+### 3.6 MDM 鐗╂枡 API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /rpc-api/mdm/item/create | 鍒涘缓鐗╂枡 |
+| PUT | /rpc-api/mdm/item/update | 鏇存柊鐗╂枡 |
+| GET | /rpc-api/mdm/item/get | 鑾峰彇鐗╂枡 |
+| POST | /rpc-api/mdm/item/list | 鑾峰彇鐗╂枡鍒楄〃 |
+| GET | /rpc-api/mdm/item/validate-exists | 鏍¢獙鐗╂枡瀛樺湪 |
---
-## 浜斻�丼QL 鎵ц
+## 鍥涖�佸墠绔慨鏀圭偣
-瑙� `docs/crm_erp_integration_sql.sql`
+### 4.1 瀹㈡埛閫夋嫨缁勪欢
+
+ERP 閿�鍞ā鍧楃殑瀹㈡埛閫夋嫨缁熶竴浣跨敤 CRM 瀹㈡埛閫夋嫨缁勪欢銆�
+
+```html
+<!-- 鍘熸潵锛欵RP 瀹㈡埛閫夋嫨 -->
+<el-select v-model="form.customerId" placeholder="璇烽�夋嫨瀹㈡埛">
+ <el-option
+ v-for="item in customerList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+</el-select>
+
+<!-- 鏀逛负锛欳RM 瀹㈡埛閫夋嫨缁勪欢 -->
+<CrmCustomerSelect v-model="form.customerId" />
+```
+
+**缁勪欢瀹炵幇锛�**
+
+```html
+<!-- CrmCustomerSelect.vue -->
+<template>
+ <el-select
+ v-model="selectedValue"
+ placeholder="璇烽�夋嫨瀹㈡埛"
+ filterable
+ remote
+ :remote-method="searchCustomer"
+ @focus="loadCustomers"
+ >
+ <el-option
+ v-for="item in customerList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ >
+ <span>{{ item.name }}</span>
+ <span style="color: #999; margin-left: 8px;">{{ item.mobile }}</span>
+ </el-option>
+ </el-select>
+</template>
+
+<script>
+import { getCustomerSimpleList } from '@/api/crm/customer'
+
+export default {
+ props: {
+ value: [Number, String]
+ },
+ data() {
+ return {
+ customerList: [],
+ selectedValue: this.value
+ }
+ },
+ watch: {
+ value(val) {
+ this.selectedValue = val
+ },
+ selectedValue(val) {
+ this.$emit('input', val)
+ }
+ },
+ methods: {
+ async loadCustomers() {
+ if (this.customerList.length === 0) {
+ const { data } = await getCustomerSimpleList()
+ this.customerList = data
+ }
+ },
+ async searchCustomer(query) {
+ if (query) {
+ // 鍙�夛細瀹炵幇杩滅▼鎼滅储
+ }
+ }
+ }
+}
+</script>
+```
+
+### 4.2 鍚堝悓鍒楄〃椤甸潰
+
+**鏂囦欢璺緞锛�** `/src/views/crm/contract/index.vue`
+
+**鏂板鎸夐挳锛�**
+
+```html
+<!-- 鍦ㄥ悎鍚屾搷浣滃垪娣诲姞 -->
+<el-table-column label="鎿嶄綔" width="200">
+ <template #default="{ row }">
+ <el-button
+ v-if="row.auditStatus === 20 && !row.orderId"
+ type="success"
+ size="small"
+ @click="handleGenerateOrder(row)"
+ >
+ 鐢熸垚閿�鍞鍗�
+ </el-button>
+ <el-button
+ v-if="row.orderId"
+ type="primary"
+ size="small"
+ @click="handleViewOrder(row)"
+ >
+ 鏌ョ湅璁㈠崟
+ </el-button>
+ </template>
+</el-table-column>
+```
+
+**鏂板鏂规硶锛�**
+
+```js
+import { generateSaleOrder } from '@/api/crm/contract'
+
+methods: {
+ async handleGenerateOrder(row) {
+ try {
+ await this.$confirm('纭鏍规嵁璇ュ悎鍚岀敓鎴愰攢鍞鍗曪紵', '鎻愮ず')
+ const { data } = await generateSaleOrder(row.id)
+ this.$message.success('鐢熸垚閿�鍞鍗曟垚鍔�')
+ 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 }
+ })
+ }
+}
+```
+
+### 4.3 閿�鍞鍗曞垪琛ㄩ〉闈�
+
+**鏂囦欢璺緞锛�** `/src/views/erp/sale/order/index.vue`
+
+**鏂板鍒楋細**
+
+```html
+<el-table-column label="鍏宠仈鍚堝悓" prop="contractNo" width="150">
+ <template #default="{ row }">
+ <el-link
+ v-if="row.contractId"
+ type="primary"
+ @click="handleViewContract(row)"
+ >
+ {{ row.contractNo }}
+ </el-link>
+ <span v-else>-</span>
+ </template>
+</el-table-column>
+```
+
+### 4.4 鍟嗘満璇︽儏椤甸潰 - 閿�鍞拷婧�
+
+**鏂囦欢璺緞锛�** `/src/views/crm/business/detail.vue`
+
+```html
+<el-card header="閿�鍞祦绋嬭拷婧�">
+ <el-timeline v-if="traceInfo">
+ <el-timeline-item
+ :timestamp="traceInfo.businessCreateTime"
+ 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"
+ color="#67C23A"
+ >
+ <el-card>
+ <h4>鍚堝悓绛捐</h4>
+ <p>鍚堝悓鍚嶇О锛歿{ traceInfo.contractName }}</p>
+ <p>鍚堝悓閲戦锛毬{ traceInfo.contractPrice }}</p>
+ </el-card>
+ </el-timeline-item>
+
+ <el-timeline-item
+ v-if="traceInfo.orderId"
+ :timestamp="traceInfo.orderCreateTime"
+ color="#E6A23C"
+ >
+ <el-card>
+ <h4>閿�鍞鍗�</h4>
+ <p>璁㈠崟鍙凤細
+ <el-link type="primary" @click="viewOrder(traceInfo.orderId)">
+ {{ traceInfo.orderNo }}
+ </el-link>
+ </p>
+ <p>璁㈠崟閲戦锛毬{ traceInfo.orderPrice }}</p>
+ </el-card>
+ </el-timeline-item>
+
+ <el-timeline-item v-if="traceInfo.receivablePrice > 0" color="#F56C6C">
+ <el-card>
+ <h4>鍥炴璁板綍</h4>
+ <p>宸插洖娆鹃噾棰濓細楼{{ traceInfo.receivablePrice }}</p>
+ </el-card>
+ </el-timeline-item>
+ </el-timeline>
+ <el-empty v-else description="鏆傛棤閿�鍞祦绋嬫暟鎹�" />
+</el-card>
+```
+
+### 4.5 鎶ヨ〃姒傝椤甸潰
+
+**鏂囦欢璺緞锛�** `/src/views/crm/report/dashboard.vue`
+
+```html
+<template>
+ <div class="report-dashboard">
+ <!-- 缁熻鍗$墖 -->
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-title">瀹㈡埛鎬绘暟</div>
+ <div class="stat-value">{{ customerAnalyze.totalCount }}</div>
+ <div class="stat-footer">浠婃棩鏂板锛歿{ customerAnalyze.todayCount }}</div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-title">鍟嗘満鎬绘暟</div>
+ <div class="stat-value">{{ businessAnalyze.totalCount }}</div>
+ <div class="stat-footer">杞寲鐜囷細{{ businessAnalyze.successRate }}%</div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-title">鍚堝悓閲戦</div>
+ <div class="stat-value">楼{{ contractAnalyze.totalPrice }}</div>
+ <div class="stat-footer">宸插洖娆撅細楼{{ contractAnalyze.receivablePrice }}</div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stat-card">
+ <div class="stat-title">鍥炴鐜�</div>
+ <div class="stat-value">{{ contractAnalyze.receivableRate }}%</div>
+ </el-card>
+ </el-col>
+ </el-row>
+
+ <!-- 閿�鍞笟缁╂帓琛� -->
+ <el-card header="閿�鍞笟缁╂帓琛�">
+ <el-table :data="performanceData.items" stripe>
+ <el-table-column prop="userName" label="閿�鍞汉鍛�" />
+ <el-table-column prop="deptName" label="閮ㄩ棬" />
+ <el-table-column prop="contractCount" label="鍚堝悓鏁伴噺" width="100" />
+ <el-table-column prop="contractPrice" label="鍚堝悓閲戦" width="150" />
+ <el-table-column prop="receivablePrice" label="鍥炴閲戦" width="150" />
+ </el-table>
+ </el-card>
+ </div>
+</template>
+
+<script>
+import {
+ getCustomerAnalyze,
+ getBusinessAnalyze,
+ getContractAnalyze,
+ getSalesPerformance
+} from '@/api/crm/report'
+
+export default {
+ data() {
+ return {
+ customerAnalyze: {},
+ businessAnalyze: {},
+ contractAnalyze: {},
+ performanceData: { items: [] }
+ }
+ },
+ created() {
+ this.loadData()
+ },
+ methods: {
+ async loadData() {
+ const [c, b, ct, p] = await Promise.all([
+ getCustomerAnalyze(),
+ getBusinessAnalyze(),
+ getContractAnalyze(),
+ getSalesPerformance()
+ ])
+ this.customerAnalyze = c.data
+ this.businessAnalyze = b.data
+ this.contractAnalyze = ct.data
+ this.performanceData = p.data
+ }
+ }
+}
+</script>
+```
+
+### 4.6 API 瀹氫箟鏂囦欢
+
+**鏂囦欢璺緞锛�** `/src/api/crm/contract.js`
+
+```js
+// 鐢熸垚閿�鍞鍗�
+export function generateSaleOrder(id) {
+ return request({
+ url: '/crm/contract/generate-sale-order',
+ method: 'post',
+ params: { id }
+ })
+}
+```
+
+**鏂囦欢璺緞锛�** `/src/api/crm/saleTrace.js`
+
+```js
+// 鏍规嵁鍟嗘満缂栧彿鑾峰彇閿�鍞祦绋嬭拷婧俊鎭�
+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 }
+ })
+}
+```
+
+**鏂囦欢璺緞锛�** `/src/api/crm/report.js`
+
+```js
+// 鑾峰彇瀹㈡埛鍒嗘瀽缁熻
+export function getCustomerAnalyze(startTime, endTime) {
+ return request({
+ url: '/crm/report/get-customer-analyze',
+ method: 'get',
+ params: { startTime, endTime }
+ })
+}
+
+// 鑾峰彇鍟嗘満鍒嗘瀽缁熻
+export function getBusinessAnalyze(startTime, endTime) {
+ return request({
+ url: '/crm/report/get-business-analyze',
+ method: 'get',
+ params: { startTime, endTime }
+ })
+}
+
+// 鑾峰彇鍚堝悓鍒嗘瀽缁熻
+export function getContractAnalyze(startTime, endTime) {
+ return request({
+ url: '/crm/report/get-contract-analyze',
+ method: 'get',
+ params: { startTime, endTime }
+ })
+}
+
+// 鑾峰彇閿�鍞紡鏂楃粺璁�
+export function getSalesFunnel() {
+ return request({
+ url: '/crm/report/get-sales-funnel',
+ method: 'get'
+ })
+}
+
+// 鑾峰彇閿�鍞笟缁╃粺璁�
+export function getSalesPerformance(startTime, endTime) {
+ return request({
+ url: '/crm/report/get-sales-performance',
+ method: 'get',
+ params: { startTime, endTime }
+ })
+}
+```
---
-## 鍏�佹敼閫犲畬鎴愮姸鎬�
+## 浜斻�佹暟鎹ā鍨嬪彉鏇�
+
+### 5.1 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`;
+```
+
+### 5.2 CRM 鍟嗘満琛�
+
+```sql
+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`;
+```
+
+### 5.3 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 鐢熸垚閿�鍞鍗曟潯浠�
+
+- 鍚堝悓蹇呴』瀹℃壒閫氳繃锛坅uditStatus = 20锛�
+- 鍚堝悓鏈叧鑱旈攢鍞鍗曪紙orderId 涓虹┖锛�
+- 鍚堝悓蹇呴』鍖呭惈浜у搧淇℃伅
+
+### 6.2 瀹㈡埛鏁版嵁瑙勫垯
+
+- ERP 閿�鍞ā鍧楃粺涓�浣跨敤 CRM 瀹㈡埛
+- 鍘� ERP 瀹㈡埛琛紙erp_customer锛夊簾寮�
+- 瀹㈡埛閫夋嫨閫氳繃 CRM 瀹㈡埛 API 鑾峰彇
+
+### 6.3 浜у搧鏁版嵁瑙勫垯
+
+- CRM 鍜� ERP 浜у搧缁熶竴浣跨敤 MDM 鐗╂枡锛坕temType=2锛�
+- MDM 鐗╂枡绫诲瀷锛�1-鐗╂枡锛�2-浜у搧锛�3-鍗婃垚鍝�
+
+---
+
+## 涓冦�佷笟鍔℃祦绋嬪浘
+
+```
+瀹㈡埛绠$悊(CRM) 鈫� 鍟嗘満璺熻繘(CRM) 鈫� 鍚堝悓绛捐(CRM) 鈫� 鍚堝悓瀹℃壒
+ 鈫�
+ 鐢熸垚閿�鍞鍗�(ERP)
+ 鈫�
+ 璁㈠崟瀹℃壒(ERP)
+ 鈫�
+ 閿�鍞嚭搴�(ERP)
+ 鈫�
+ 瀹㈡埛鍥炴(ERP)
+```
+
+**閿�鍞紡鏂楄浆鍖栵細**
+
+```
+瀹㈡埛(1000) 鈫� 鍟嗘満(500) 鈫� 鍚堝悓(300) 鈫� 鍥炴(150)
+ 鈫� 鈫� 鈫� 鈫�
+ 100% 50% 30% 15%
+```
+
+---
+
+## 鍏�佹敞鎰忎簨椤�
+
+1. **鏁版嵁鏉冮檺**锛氭姤琛ㄦ暟鎹渶瑕佹牴鎹敤鎴锋潈闄愯繃婊�
+2. **鐘舵�佹帶鍒�**锛氬彧鏈夊鎵归�氳繃鐨勫悎鍚屾墠鑳界敓鎴愯鍗�
+3. **鍞竴鎬�**锛氫竴涓悎鍚屽彧鑳界敓鎴愪竴涓攢鍞鍗�
+4. **鏁版嵁鍚屾**锛氱敓鎴愯鍗曞悗锛屽悎鍚屼笌璁㈠崟鍙屽悜鍏宠仈
+5. **搴熷純椤甸潰**锛欵RP 瀹㈡埛绠$悊椤甸潰锛�/erp/customer/index锛夊缓璁湪鑿滃崟涓殣钘�
+
+---
+
+## 涔濄�佸畬鎴愮姸鎬�
| Phase | 鍐呭 | 鐘舵�� |
|-------|------|------|
@@ -128,13 +786,223 @@
---
-## 涓冦�佷骇鍑烘枃妗f竻鍗�
+## 鍗佷竴銆侀攢鍞姤浠锋ā鍧楋紙鏂板锛�
+
+### 11.1 娑夊強椤甸潰
+
+| 椤甸潰 | 璺緞 | 璇存槑 |
+|------|------|------|
+| 鎶ヤ环鍗曞垪琛� | `/crm/sale-quotation/index` | 鎶ヤ环鍗曞垪琛ㄣ�佹搷浣滄寜閽� |
+| 鎶ヤ环鍗曡〃鍗� | `/crm/sale-quotation/form` | 鏂板缓/缂栬緫鎶ヤ环鍗� |
+| 鎶ヤ环鍗曡鎯� | `/crm/sale-quotation/detail` | 鏌ョ湅璇︽儏銆佸鎵硅繘搴� |
+
+### 11.2 API 鎺ュ彛
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /crm/sale-quotation/create | 鍒涘缓鎶ヤ环鍗� |
+| PUT | /crm/sale-quotation/update | 鏇存柊鎶ヤ环鍗� |
+| DELETE | /crm/sale-quotation/delete | 鍒犻櫎鎶ヤ环鍗� |
+| GET | /crm/sale-quotation/get | 鑾峰彇鎶ヤ环鍗曡鎯� |
+| GET | /crm/sale-quotation/page | 鍒嗛〉鏌ヨ |
+| GET | /crm/sale-quotation/page-by-customer | 鎸夊鎴峰垎椤� |
+| GET | /crm/sale-quotation/page-by-business | 鎸夊晢鏈哄垎椤� |
+| PUT | /crm/sale-quotation/submit | 鎻愪氦瀹℃壒锛堥渶浼� processDefinitionKey锛� |
+| GET | /crm/sale-quotation/approve-process-list | 鑾峰彇鍙�夊鎵规祦绋嬪垪琛� |
+| POST | /crm/sale-quotation/convert-contract | 杞负鍚堝悓 |
+
+**璇锋眰鍙傛暟绀轰緥**锛堝垱寤烘姤浠峰崟锛夛細
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| name | String | 鏄� | 鎶ヤ环鍗曞悕绉� |
+| customerId | Long | 鏄� | 瀹㈡埛缂栧彿 |
+| businessId | Long | 鍚� | 鍟嗘満缂栧彿 |
+| contactId | Long | 鍚� | 鑱旂郴浜虹紪鍙� |
+| quotationTime | LocalDateTime | 鍚� | 鎶ヤ环鏃ユ湡 |
+| validUntil | LocalDateTime | 鍚� | 鏈夋晥鏈熻嚦 |
+| discountPercent | BigDecimal | 鍚� | 鏁村崟鎶樻墸 |
+| taxRate | BigDecimal | 鍚� | 绋庣巼 |
+| fileUrl | String | 鍚� | 闄勪欢鍦板潃 |
+| remark | String | 鍚� | 澶囨敞 |
+| items | List | 鏄� | 鐗╂枡鏄庣粏鍒楄〃 |
+
+**鐗╂枡鏄庣粏 Item**锛�
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| itemId | Long | 鏄� | MDM 鐗╂枡缂栧彿 |
+| quotationPrice | BigDecimal | 鏄� | 鎶ヤ环鍗曚环 |
+| count | BigDecimal | 鏄� | 鏁伴噺 |
+| taxPercent | BigDecimal | 鍚� | 绋庣巼 |
+| remark | String | 鍚� | 澶囨敞 |
+
+### 11.3 鍓嶇淇敼鐐�
+
+#### 鎶ヤ环鍗曞垪琛ㄩ〉闈�
+
+**鏂囦欢璺緞锛�** `/src/views/crm/sale-quotation/index.vue`
+
+```html
+<!-- 鎿嶄綔鍒� -->
+<el-table-column label="鎿嶄綔" width="280">
+ <template #default="{ row }">
+ <el-button v-if="row.status === 0" type="primary" size="small" @click="handleUpdate(row)">缂栬緫</el-button>
+ <el-button v-if="row.status === 0" type="success" size="small" @click="handleSubmit(row)">鎻愪氦瀹℃壒</el-button>
+ <el-button v-if="row.status === 20 && !row.contractId" type="warning" size="small" @click="handleConvertContract(row)">杞悎鍚�</el-button>
+ <el-button v-if="row.contractId" type="primary" size="small" @click="handleViewContract(row)">鏌ョ湅鍚堝悓</el-button>
+ <el-button v-if="row.status === 0" type="danger" size="small" @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+</el-table-column>
+```
+
+**鎻愪氦瀹℃壒寮圭獥**锛�
+
+```html
+<el-dialog title="閫夋嫨瀹℃壒娴佺▼" v-model="submitDialogVisible" width="400px">
+ <el-form label-width="100px">
+ <el-form-item label="瀹℃壒娴佺▼" required>
+ <el-select v-model="selectedProcessKey" placeholder="璇烽�夋嫨" style="width: 100%">
+ <el-option v-for="item in processList" :key="item.key" :label="item.name" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <el-button @click="submitDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="confirmSubmit" :loading="submitLoading">纭畾</el-button>
+ </template>
+</el-dialog>
+```
+
+**JS 鏂规硶**锛�
+
+```js
+import { getSaleQuotationApproveProcessList, submitSaleQuotation, convertSaleQuotationToContract } from '@/api/crm/saleQuotation'
+
+methods: {
+ async handleSubmit(row) {
+ const { data } = await getSaleQuotationApproveProcessList()
+ this.processList = data
+ this.currentRow = row
+ this.submitDialogVisible = true
+ },
+ async confirmSubmit() {
+ if (!this.selectedProcessKey) {
+ this.$message.warning('璇烽�夋嫨瀹℃壒娴佺▼')
+ return
+ }
+ this.submitLoading = true
+ try {
+ await submitSaleQuotation(this.currentRow.id, this.selectedProcessKey)
+ this.$message.success('鎻愪氦鎴愬姛')
+ this.submitDialogVisible = false
+ this.getList()
+ } finally {
+ this.submitLoading = false
+ }
+ },
+ async handleConvertContract(row) {
+ try {
+ await this.$confirm('纭灏嗚鎶ヤ环鍗曡浆涓哄悎鍚岋紵', '鎻愮ず')
+ const { data } = await convertSaleQuotationToContract(row.id)
+ this.$message.success('杞悎鍚屾垚鍔�')
+ this.$router.push({ path: '/crm/contract/detail', query: { id: data } })
+ } catch (e) {
+ if (e !== 'cancel') this.$message.error(e.message || '杞悎鍚屽け璐�')
+ }
+ }
+}
+```
+
+#### 鎶ヤ环鍗曡〃鍗曢〉闈� - MDM 鐗╂枡閫夋嫨
+
+**鏂囦欢璺緞锛�** `/src/views/crm/sale-quotation/form.vue`
+
+鐢变簬鎶ヤ环鍗曚娇鐢� MDM 鐗╂枡锛岄渶瑕佷娇鐢� MDM 鐗╂枡閫夋嫨缁勪欢锛�
+
+```html
+<MdmItemSelect v-model="item.itemId" @change="handleItemChange" />
+```
+
+**API 瀹氫箟鏂囦欢**锛歚/src/api/crm/saleQuotation.js`
+
+```js
+import request from '@/utils/request'
+
+// 鍒涘缓鎶ヤ环鍗�
+export function createSaleQuotation(data) {
+ return request({ url: '/crm/sale-quotation/create', method: 'post', data })
+}
+
+// 鏇存柊鎶ヤ环鍗�
+export function updateSaleQuotation(data) {
+ return request({ url: '/crm/sale-quotation/update', method: 'put', data })
+}
+
+// 鍒犻櫎鎶ヤ环鍗�
+export function deleteSaleQuotation(ids) {
+ return request({ url: '/crm/sale-quotation/delete', method: 'delete', params: { ids } })
+}
+
+// 鑾峰彇鎶ヤ环鍗曡鎯�
+export function getSaleQuotation(id) {
+ return request({ url: '/crm/sale-quotation/get', method: 'get', params: { id } })
+}
+
+// 鍒嗛〉鏌ヨ
+export function getSaleQuotationPage(params) {
+ return request({ url: '/crm/sale-quotation/page', method: 'get', params })
+}
+
+// 鎻愪氦瀹℃壒
+export function submitSaleQuotation(id, processDefinitionKey) {
+ return request({ url: '/crm/sale-quotation/submit', method: 'put', params: { id, processDefinitionKey } })
+}
+
+// 鑾峰彇瀹℃壒娴佺▼鍒楄〃
+export function getSaleQuotationApproveProcessList() {
+ return request({ url: '/crm/sale-quotation/approve-process-list', method: 'get' })
+}
+
+// 杞悎鍚�
+export function convertSaleQuotationToContract(id) {
+ return request({ url: '/crm/sale-quotation/convert-contract', method: 'post', params: { id } })
+}
+```
+
+### 11.4 涓氬姟娴佺▼
+
+```
+鍟嗘満(鍙��) 鈫� 閿�鍞姤浠�(鑽夌) 鈫� 鎻愪氦瀹℃壒 鈫� 瀹℃壒涓� 鈫� 瀹℃壒閫氳繃 鈫� 杞悎鍚�
+ 鈫�
+ 瀹℃壒鎷掔粷 鈫� 閲嶆柊鎻愪氦鎴栦慨鏀�
+```
+
+### 11.5 娉ㄦ剰浜嬮」
+
+1. 鎶ヤ环鍗曞拰鍚堝悓缁熶竴浣跨敤 **MDM 鐗╂枡**锛坄MdmItemApi`锛夛紝涓� ERP 閿�鍞鍗曚竴鑷�
+2. BPM 鍒嗙被缂栫爜 `sale_quotation_approve` 闇�瑕佸湪 BPM 绠$悊鍚庡彴鍒涘缓
+3. 鎶ヤ环鍗曡浆鍚堝悓鏃讹紝鐗╂枡鏄庣粏鐩存帴澶嶅埗鍒板悎鍚屼骇鍝佽〃锛堝瓧娈典竴鑷达級
+4. 鎶ヤ环鍗曞彿鍓嶇紑涓� `QT`锛屾牸寮忥細QT + yyyyMMdd + 6浣嶈嚜澧炲簭鍙�
+5. 鍟嗘満鍏宠仈涓哄彲閫夛紝鎶ヤ环鍗曞彲浠ョ嫭绔嬪垱寤轰笉渚濊禆鍟嗘満
+
+### 11.6 鍚堝悓浜у搧瀛楁鍙樻洿璇存槑
+
+鍚堝悓浜у搧琛� `crm_contract_product` 宸叉敼涓轰娇鐢� MDM 鐗╂枡锛�
+
+| 鍘熷瓧娈� | 鏂板瓧娈� | 璇存槑 |
+|--------|--------|------|
+| `product_id` | `item_id` | MDM 鐗╂枡缂栧彿 |
+| `product_price` | `item_price` | 鐗╂枡鍘熶环 |
+| - | `item_unit_id` | 璁¢噺鍗曚綅缂栧彿 |
+
+鍓嶇琛ㄥ崟闇�瑕佷娇鐢� MDM 鐗╂枡閫夋嫨缁勪欢鏇夸唬 CRM 浜у搧閫夋嫨缁勪欢銆�
+
+---
+
+## 鍗併�佷骇鍑烘枃妗f竻鍗�
| 鏂囨。 | 璇存槑 |
|------|------|
-| `docs/crm_erp_integration_frontend.md` | CRM 瀹㈡埛涓�浣撳寲鍓嶇鏂囨。 |
+| `docs/crm_erp_integration_frontend.md` | 鏈枃妗� |
| `docs/crm_erp_integration_sql.sql` | SQL 鍙樻洿鑴氭湰 |
-| `docs/mdm_product_integration_frontend.md` | MDM 浜у搧涓�浣撳寲鍓嶇鏂囨。 |
-| `docs/contract_generate_order_frontend.md` | 鍚堝悓鐢熸垚璁㈠崟鍓嶇鏂囨。 |
-| `docs/sales_traceability_frontend.md` | 閿�鍞拷婧墠绔枃妗� |
-| `docs/marketing_report_frontend.md` | 钀ラ攢鎶ヨ〃鍓嶇鏂囨。 |
--
Gitblit v1.9.3