| 方法 | 路径 | 说明 |
|---|---|---|
| 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 管理
新增/修改合同记录:
{
"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列表 |
响应:
{
"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"
}
]
}
}
<el-tabs v-model="activeTab">
<!-- 其他Tab -->
<el-tab-pane label="合同记录" name="contract">
<el-button type="primary" size="small" @click="handleAddContract">新增合同记录</el-button>
<el-table :data="contractList" style="width: 100%; margin-top: 15px">
<el-table-column prop="masterContractNo" label="总合同号" />
<el-table-column prop="entryDate" label="录入日期" width="180" />
<el-table-column prop="entryPerson" label="录入人" width="120" />
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
<el-table-column label="附件" width="100">
<template #default="{ row }">
<el-link type="primary" v-if="row.fileList && row.fileList.length" @click="handleViewFiles(row)">
查看({{ row.fileList.length }})
</el-link>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template #default="{ row }">
<el-button type="text" size="small" @click="handleEditContract(row)">编辑</el-button>
<el-button type="text" size="small" style="color: #f56c6c" @click="handleDeleteContract(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<el-dialog :title="contractDialogTitle" v-model="contractDialogVisible" width="600px">
<el-form :model="contractForm" :rules="contractRules" ref="contractFormRef" label-width="100px">
<el-form-item label="总合同号" prop="masterContractNo">
<el-input v-model="contractForm.masterContractNo" placeholder="请输入总合同号" />
</el-form-item>
<el-form-item label="录入日期" prop="entryDate">
<el-date-picker
v-model="contractForm.entryDate"
type="datetime"
placeholder="选择日期时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="录入人" prop="entryPerson">
<el-input v-model="contractForm.entryPerson" placeholder="请输入录入人" />
</el-form-item>
<el-form-item label="附件">
<!-- 使用系统封装的文件上传组件 -->
<file-upload
v-model="contractForm.storageBlobDTOs"
:record-type="'customer_contract_record'"
:record-id="contractForm.id"
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="contractForm.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="contractDialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitContractForm">确定</el-button>
</template>
</el-dialog>
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' }]
}
}
}
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