# 客户档案私海-合同记录
## 涉及页面
- 客户档案(私海)详情页
## API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /basic/customer-contract/list/{customerId} | 查询合同记录列表 |
| GET | /basic/customer-contract/{id} | 获取合同记录详情 |
| POST | /basic/customer-contract | 新增合同记录 |
| PUT | /basic/customer-contract | 修改合同记录 |
| DELETE | /basic/customer-contract/{id} | 删除合同记录 |
**注意:附件使用系统通用接口 `/basic/storage-attachment` 管理**
### 请求参数
**新增/修改合同记录:**
```json
{
"id": null, // 修改时必传
"customerId": 1, // 客户档案ID(必填)
"masterContractNo": "HT202606240001", // 总合同号(必填)
"entryDate": "2026-06-24 10:30:00", // 录入日期(必填)
"entryPerson": "张三", // 录入人姓名
"entryPersonId": 1, // 录入人ID
"remark": "备注信息", // 备注
"storageBlobDTOs": [ // 附件列表
{ "id": 1 },
{ "id": 2 }
]
}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 否 | 修改时必传 |
| customerId | Long | 是 | 客户档案ID |
| masterContractNo | String | 是 | 总合同号 |
| entryDate | String | 是 | 录入日期(yyyy-MM-dd HH:mm:ss) |
| entryPerson | String | 否 | 录入人姓名 |
| entryPersonId | Long | 否 | 录入人ID |
| remark | String | 否 | 备注 |
| storageBlobDTOs | List | 否 | 附件ID列表 |
**响应:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"customerId": 1,
"masterContractNo": "HT202606240001",
"entryDate": "2026-06-24 10:30:00",
"entryPerson": "张三",
"entryPersonId": 1,
"remark": "备注信息",
"fileList": [
{
"id": 1,
"name": "合同扫描件.pdf",
"previewURL": "xxx",
"downloadURL": "xxx",
"byteSize": 102400,
"contentType": "application/pdf"
}
]
}
}
```
## 前端修改点
### 1. 在客户档案(私海)详情页添加合同记录Tab
```html
新增合同记录
查看({{ row.fileList.length }})
-
编辑
删除
```
### 2. 新增/编辑合同记录弹窗(使用系统通用上传组件)
```html
取消
确定
```
### 3. data 数据
```js
data() {
return {
// 合同记录相关
contractList: [],
contractDialogVisible: false,
contractDialogTitle: '',
contractForm: {
id: null,
customerId: null,
masterContractNo: '',
entryDate: '',
entryPerson: '',
entryPersonId: null,
remark: '',
storageBlobDTOs: [] // 附件列表,使用系统通用格式
},
contractRules: {
masterContractNo: [{ required: true, message: '请输入总合同号', trigger: 'blur' }],
entryDate: [{ required: true, message: '请选择录入日期', trigger: 'change' }]
}
}
}
```
### 4. 方法
```js
methods: {
// 获取合同记录列表(含附件)
async getContractList(customerId) {
const res = await this.$http.get(`/basic/customer-contract/list/${customerId}`)
if (res.code === 200) {
this.contractList = res.data
}
},
// 新增合同记录
handleAddContract() {
this.contractDialogTitle = '新增合同记录'
this.contractForm = {
id: null,
customerId: this.customerId,
masterContractNo: '',
entryDate: '',
entryPerson: '',
entryPersonId: null,
remark: '',
storageBlobDTOs: []
}
this.contractDialogVisible = true
},
// 编辑合同记录
async handleEditContract(row) {
this.contractDialogTitle = '编辑合同记录'
const res = await this.$http.get(`/basic/customer-contract/${row.id}`)
if (res.code === 200) {
this.contractForm = {
...res.data,
storageBlobDTOs: res.data.fileList ? res.data.fileList.map(f => ({ id: f.id })) : []
}
this.contractDialogVisible = true
}
},
// 删除合同记录
async handleDeleteContract(row) {
await this.$confirm('确定删除该合同记录吗?', '提示', { type: 'warning' })
const res = await this.$http.delete(`/basic/customer-contract/${row.id}`)
if (res.code === 200) {
this.$message.success('删除成功')
this.getContractList(this.customerId)
}
},
// 提交合同记录表单
async submitContractForm() {
await this.$refs.contractFormRef.validate()
const res = await this.$http.post('/basic/customer-contract', this.contractForm)
if (res.code === 200) {
this.$message.success('操作成功')
this.contractDialogVisible = false
this.getContractList(this.customerId)
}
},
// 查看附件列表
handleViewFiles(row) {
// 弹窗展示附件列表,使用 row.fileList
}
}
```
## 后端文件清单
| 文件路径 | 说明 |
|---------|------|
| `src/main/java/com/ruoyi/basic/pojo/CustomerContractRecord.java` | 实体类 |
| `src/main/java/com/ruoyi/basic/dto/CustomerContractRecordDto.java` | DTO(含附件列表) |
| `src/main/java/com/ruoyi/basic/mapper/CustomerContractRecordMapper.java` | Mapper接口 |
| `src/main/resources/mapper/basic/CustomerContractRecordMapper.xml` | Mapper XML |
| `src/main/java/com/ruoyi/basic/service/CustomerContractRecordService.java` | Service接口 |
| `src/main/java/com/ruoyi/basic/service/impl/CustomerContractRecordServiceImpl.java` | Service实现 |
| `src/main/java/com/ruoyi/basic/controller/CustomerContractRecordController.java` | Controller |
| `src/main/java/com/ruoyi/basic/enums/RecordTypeEnum.java` | 添加枚举值 `CUSTOMER_CONTRACT_RECORD` |
## 注意事项
- 附件上传使用系统封装的 `StorageAttachment` 服务,通过 `record_type='customer_contract_record'` 和 `record_id` 关联
- 前端可使用项目封装的 `file-upload` 组件,组件内部调用 `/basic/storage-attachment` 接口
- 删除合同记录时,后端会自动同步删除关联的附件
- 新增合同记录成功后,返回的 `data.id` 为新增记录的ID