编辑 | blame | 历史 | 原始文档

客户档案私海-合同记录

涉及页面

  • 客户档案(私海)详情页

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 管理

请求参数

新增/修改合同记录:

{
    "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"
            }
        ]
    }
}

前端修改点

1. 在客户档案(私海)详情页添加合同记录Tab

<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>

2. 新增/编辑合同记录弹窗(使用系统通用上传组件)

<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>

3. data 数据

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. 方法

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