569 lines
17 KiB
JavaScript
569 lines
17 KiB
JavaScript
|
|
/**
|
|||
|
|
* 贷款合同路由
|
|||
|
|
* @file loanContracts.js
|
|||
|
|
* @description 银行系统贷款合同相关路由配置
|
|||
|
|
*/
|
|||
|
|
const express = require('express');
|
|||
|
|
const router = express.Router();
|
|||
|
|
const { body } = require('express-validator');
|
|||
|
|
const loanContractController = require('../controllers/loanContractController');
|
|||
|
|
const { authMiddleware } = require('../middleware/auth');
|
|||
|
|
|
|||
|
|
// 所有路由都需要认证
|
|||
|
|
router.use(authMiddleware);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* /api/loan-contracts:
|
|||
|
|
* get:
|
|||
|
|
* summary: 获取贷款合同列表
|
|||
|
|
* tags: [贷款合同]
|
|||
|
|
* security:
|
|||
|
|
* - bearerAuth: []
|
|||
|
|
* parameters:
|
|||
|
|
* - in: query
|
|||
|
|
* name: page
|
|||
|
|
* schema:
|
|||
|
|
* type: integer
|
|||
|
|
* default: 1
|
|||
|
|
* description: 页码
|
|||
|
|
* - in: query
|
|||
|
|
* name: pageSize
|
|||
|
|
* schema:
|
|||
|
|
* type: integer
|
|||
|
|
* default: 10
|
|||
|
|
* description: 每页数量
|
|||
|
|
* - in: query
|
|||
|
|
* name: searchField
|
|||
|
|
* schema:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [contractNumber, applicationNumber, borrowerName, farmerName, productName]
|
|||
|
|
* default: contractNumber
|
|||
|
|
* description: 搜索字段
|
|||
|
|
* - in: query
|
|||
|
|
* name: searchValue
|
|||
|
|
* schema:
|
|||
|
|
* type: string
|
|||
|
|
* description: 搜索值
|
|||
|
|
* - in: query
|
|||
|
|
* name: status
|
|||
|
|
* schema:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [active, pending, completed, defaulted, cancelled]
|
|||
|
|
* description: 合同状态筛选
|
|||
|
|
* - in: query
|
|||
|
|
* name: sortField
|
|||
|
|
* schema:
|
|||
|
|
* type: string
|
|||
|
|
* default: createdAt
|
|||
|
|
* description: 排序字段
|
|||
|
|
* - in: query
|
|||
|
|
* name: sortOrder
|
|||
|
|
* schema:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [ASC, DESC]
|
|||
|
|
* default: DESC
|
|||
|
|
* description: 排序方向
|
|||
|
|
* responses:
|
|||
|
|
* 200:
|
|||
|
|
* description: 获取成功
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* success:
|
|||
|
|
* type: boolean
|
|||
|
|
* data:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* contracts:
|
|||
|
|
* type: array
|
|||
|
|
* items:
|
|||
|
|
* $ref: '#/components/schemas/LoanContract'
|
|||
|
|
* pagination:
|
|||
|
|
* $ref: '#/components/schemas/Pagination'
|
|||
|
|
*/
|
|||
|
|
router.get('/', loanContractController.getContracts);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* /api/loan-contracts/{id}:
|
|||
|
|
* get:
|
|||
|
|
* summary: 获取贷款合同详情
|
|||
|
|
* tags: [贷款合同]
|
|||
|
|
* security:
|
|||
|
|
* - bearerAuth: []
|
|||
|
|
* parameters:
|
|||
|
|
* - in: path
|
|||
|
|
* name: id
|
|||
|
|
* required: true
|
|||
|
|
* schema:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同ID
|
|||
|
|
* responses:
|
|||
|
|
* 200:
|
|||
|
|
* description: 获取成功
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* success:
|
|||
|
|
* type: boolean
|
|||
|
|
* data:
|
|||
|
|
* $ref: '#/components/schemas/LoanContract'
|
|||
|
|
* 404:
|
|||
|
|
* description: 合同不存在
|
|||
|
|
*/
|
|||
|
|
router.get('/:id', loanContractController.getContractById);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* /api/loan-contracts:
|
|||
|
|
* post:
|
|||
|
|
* summary: 创建贷款合同
|
|||
|
|
* tags: [贷款合同]
|
|||
|
|
* security:
|
|||
|
|
* - bearerAuth: []
|
|||
|
|
* requestBody:
|
|||
|
|
* required: true
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* required:
|
|||
|
|
* - applicationNumber
|
|||
|
|
* - productName
|
|||
|
|
* - farmerName
|
|||
|
|
* - borrowerName
|
|||
|
|
* - borrowerIdNumber
|
|||
|
|
* - assetType
|
|||
|
|
* - applicationQuantity
|
|||
|
|
* - amount
|
|||
|
|
* - type
|
|||
|
|
* - term
|
|||
|
|
* - interestRate
|
|||
|
|
* - phone
|
|||
|
|
* properties:
|
|||
|
|
* applicationNumber:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请单号
|
|||
|
|
* productName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款产品名称
|
|||
|
|
* farmerName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请养殖户姓名
|
|||
|
|
* borrowerName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款人姓名
|
|||
|
|
* borrowerIdNumber:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款人身份证号
|
|||
|
|
* assetType:
|
|||
|
|
* type: string
|
|||
|
|
* description: 生资种类
|
|||
|
|
* applicationQuantity:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请数量
|
|||
|
|
* amount:
|
|||
|
|
* type: number
|
|||
|
|
* description: 合同金额
|
|||
|
|
* type:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [livestock_collateral, farmer_loan, business_loan, personal_loan]
|
|||
|
|
* description: 合同类型
|
|||
|
|
* term:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同期限(月)
|
|||
|
|
* interestRate:
|
|||
|
|
* type: number
|
|||
|
|
* description: 利率
|
|||
|
|
* phone:
|
|||
|
|
* type: string
|
|||
|
|
* description: 联系电话
|
|||
|
|
* purpose:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款用途
|
|||
|
|
* remark:
|
|||
|
|
* type: string
|
|||
|
|
* description: 备注
|
|||
|
|
* responses:
|
|||
|
|
* 201:
|
|||
|
|
* description: 创建成功
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* success:
|
|||
|
|
* type: boolean
|
|||
|
|
* message:
|
|||
|
|
* type: string
|
|||
|
|
* data:
|
|||
|
|
* $ref: '#/components/schemas/LoanContract'
|
|||
|
|
* 400:
|
|||
|
|
* description: 请求参数错误
|
|||
|
|
*/
|
|||
|
|
router.post('/', [
|
|||
|
|
body('applicationNumber').notEmpty().withMessage('申请单号不能为空'),
|
|||
|
|
body('productName').notEmpty().withMessage('贷款产品名称不能为空'),
|
|||
|
|
body('farmerName').notEmpty().withMessage('申请养殖户姓名不能为空'),
|
|||
|
|
body('borrowerName').notEmpty().withMessage('贷款人姓名不能为空'),
|
|||
|
|
body('borrowerIdNumber').notEmpty().withMessage('贷款人身份证号不能为空'),
|
|||
|
|
body('assetType').notEmpty().withMessage('生资种类不能为空'),
|
|||
|
|
body('applicationQuantity').notEmpty().withMessage('申请数量不能为空'),
|
|||
|
|
body('amount').isNumeric().withMessage('合同金额必须是数字'),
|
|||
|
|
body('type').isIn(['livestock_collateral', 'farmer_loan', 'business_loan', 'personal_loan']).withMessage('合同类型无效'),
|
|||
|
|
body('term').isInt({ min: 1 }).withMessage('合同期限必须大于0'),
|
|||
|
|
body('interestRate').isNumeric().withMessage('利率必须是数字'),
|
|||
|
|
body('phone').notEmpty().withMessage('联系电话不能为空')
|
|||
|
|
], loanContractController.createContract);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* /api/loan-contracts/{id}:
|
|||
|
|
* put:
|
|||
|
|
* summary: 更新贷款合同
|
|||
|
|
* tags: [贷款合同]
|
|||
|
|
* security:
|
|||
|
|
* - bearerAuth: []
|
|||
|
|
* parameters:
|
|||
|
|
* - in: path
|
|||
|
|
* name: id
|
|||
|
|
* required: true
|
|||
|
|
* schema:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同ID
|
|||
|
|
* requestBody:
|
|||
|
|
* required: true
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* productName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款产品名称
|
|||
|
|
* farmerName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请养殖户姓名
|
|||
|
|
* borrowerName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款人姓名
|
|||
|
|
* borrowerIdNumber:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款人身份证号
|
|||
|
|
* assetType:
|
|||
|
|
* type: string
|
|||
|
|
* description: 生资种类
|
|||
|
|
* applicationQuantity:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请数量
|
|||
|
|
* amount:
|
|||
|
|
* type: number
|
|||
|
|
* description: 合同金额
|
|||
|
|
* paidAmount:
|
|||
|
|
* type: number
|
|||
|
|
* description: 已还款金额
|
|||
|
|
* status:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [active, pending, completed, defaulted, cancelled]
|
|||
|
|
* description: 合同状态
|
|||
|
|
* type:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [livestock_collateral, farmer_loan, business_loan, personal_loan]
|
|||
|
|
* description: 合同类型
|
|||
|
|
* term:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同期限(月)
|
|||
|
|
* interestRate:
|
|||
|
|
* type: number
|
|||
|
|
* description: 利率
|
|||
|
|
* phone:
|
|||
|
|
* type: string
|
|||
|
|
* description: 联系电话
|
|||
|
|
* purpose:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款用途
|
|||
|
|
* remark:
|
|||
|
|
* type: string
|
|||
|
|
* description: 备注
|
|||
|
|
* responses:
|
|||
|
|
* 200:
|
|||
|
|
* description: 更新成功
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* success:
|
|||
|
|
* type: boolean
|
|||
|
|
* message:
|
|||
|
|
* type: string
|
|||
|
|
* data:
|
|||
|
|
* $ref: '#/components/schemas/LoanContract'
|
|||
|
|
* 400:
|
|||
|
|
* description: 请求参数错误
|
|||
|
|
* 404:
|
|||
|
|
* description: 合同不存在
|
|||
|
|
*/
|
|||
|
|
router.put('/:id', loanContractController.updateContract);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* /api/loan-contracts/{id}:
|
|||
|
|
* delete:
|
|||
|
|
* summary: 删除贷款合同
|
|||
|
|
* tags: [贷款合同]
|
|||
|
|
* security:
|
|||
|
|
* - bearerAuth: []
|
|||
|
|
* parameters:
|
|||
|
|
* - in: path
|
|||
|
|
* name: id
|
|||
|
|
* required: true
|
|||
|
|
* schema:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同ID
|
|||
|
|
* responses:
|
|||
|
|
* 200:
|
|||
|
|
* description: 删除成功
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* success:
|
|||
|
|
* type: boolean
|
|||
|
|
* message:
|
|||
|
|
* type: string
|
|||
|
|
* 404:
|
|||
|
|
* description: 合同不存在
|
|||
|
|
*/
|
|||
|
|
router.delete('/:id', loanContractController.deleteContract);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* /api/loan-contracts/stats:
|
|||
|
|
* get:
|
|||
|
|
* summary: 获取合同统计信息
|
|||
|
|
* tags: [贷款合同]
|
|||
|
|
* security:
|
|||
|
|
* - bearerAuth: []
|
|||
|
|
* responses:
|
|||
|
|
* 200:
|
|||
|
|
* description: 获取成功
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* success:
|
|||
|
|
* type: boolean
|
|||
|
|
* data:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* total:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* contracts:
|
|||
|
|
* type: integer
|
|||
|
|
* amount:
|
|||
|
|
* type: number
|
|||
|
|
* paidAmount:
|
|||
|
|
* type: number
|
|||
|
|
* remainingAmount:
|
|||
|
|
* type: number
|
|||
|
|
* byStatus:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* counts:
|
|||
|
|
* type: object
|
|||
|
|
* amounts:
|
|||
|
|
* type: object
|
|||
|
|
* paidAmounts:
|
|||
|
|
* type: object
|
|||
|
|
*/
|
|||
|
|
router.get('/stats', loanContractController.getContractStats);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* /api/loan-contracts/batch/status:
|
|||
|
|
* put:
|
|||
|
|
* summary: 批量更新合同状态
|
|||
|
|
* tags: [贷款合同]
|
|||
|
|
* security:
|
|||
|
|
* - bearerAuth: []
|
|||
|
|
* requestBody:
|
|||
|
|
* required: true
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* required:
|
|||
|
|
* - ids
|
|||
|
|
* - status
|
|||
|
|
* properties:
|
|||
|
|
* ids:
|
|||
|
|
* type: array
|
|||
|
|
* items:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同ID数组
|
|||
|
|
* status:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [active, pending, completed, defaulted, cancelled]
|
|||
|
|
* description: 目标状态
|
|||
|
|
* responses:
|
|||
|
|
* 200:
|
|||
|
|
* description: 更新成功
|
|||
|
|
* content:
|
|||
|
|
* application/json:
|
|||
|
|
* schema:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* success:
|
|||
|
|
* type: boolean
|
|||
|
|
* message:
|
|||
|
|
* type: string
|
|||
|
|
* data:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* updatedCount:
|
|||
|
|
* type: integer
|
|||
|
|
* status:
|
|||
|
|
* type: string
|
|||
|
|
* 400:
|
|||
|
|
* description: 请求参数错误
|
|||
|
|
*/
|
|||
|
|
router.put('/batch/status', [
|
|||
|
|
body('ids').isArray({ min: 1 }).withMessage('请选择要操作的合同'),
|
|||
|
|
body('status').isIn(['active', 'pending', 'completed', 'defaulted', 'cancelled']).withMessage('状态无效')
|
|||
|
|
], loanContractController.batchUpdateStatus);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @swagger
|
|||
|
|
* components:
|
|||
|
|
* schemas:
|
|||
|
|
* LoanContract:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* id:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同ID
|
|||
|
|
* contractNumber:
|
|||
|
|
* type: string
|
|||
|
|
* description: 合同编号
|
|||
|
|
* applicationNumber:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请单号
|
|||
|
|
* productName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款产品名称
|
|||
|
|
* farmerName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请养殖户姓名
|
|||
|
|
* borrowerName:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款人姓名
|
|||
|
|
* borrowerIdNumber:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款人身份证号
|
|||
|
|
* assetType:
|
|||
|
|
* type: string
|
|||
|
|
* description: 生资种类
|
|||
|
|
* applicationQuantity:
|
|||
|
|
* type: string
|
|||
|
|
* description: 申请数量
|
|||
|
|
* amount:
|
|||
|
|
* type: number
|
|||
|
|
* description: 合同金额
|
|||
|
|
* paidAmount:
|
|||
|
|
* type: number
|
|||
|
|
* description: 已还款金额
|
|||
|
|
* status:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [active, pending, completed, defaulted, cancelled]
|
|||
|
|
* description: 合同状态
|
|||
|
|
* type:
|
|||
|
|
* type: string
|
|||
|
|
* enum: [livestock_collateral, farmer_loan, business_loan, personal_loan]
|
|||
|
|
* description: 合同类型
|
|||
|
|
* term:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 合同期限(月)
|
|||
|
|
* interestRate:
|
|||
|
|
* type: number
|
|||
|
|
* description: 利率
|
|||
|
|
* phone:
|
|||
|
|
* type: string
|
|||
|
|
* description: 联系电话
|
|||
|
|
* purpose:
|
|||
|
|
* type: string
|
|||
|
|
* description: 贷款用途
|
|||
|
|
* remark:
|
|||
|
|
* type: string
|
|||
|
|
* description: 备注
|
|||
|
|
* contractTime:
|
|||
|
|
* type: string
|
|||
|
|
* format: date-time
|
|||
|
|
* description: 合同签订时间
|
|||
|
|
* disbursementTime:
|
|||
|
|
* type: string
|
|||
|
|
* format: date-time
|
|||
|
|
* description: 放款时间
|
|||
|
|
* maturityTime:
|
|||
|
|
* type: string
|
|||
|
|
* format: date-time
|
|||
|
|
* description: 到期时间
|
|||
|
|
* completedTime:
|
|||
|
|
* type: string
|
|||
|
|
* format: date-time
|
|||
|
|
* description: 完成时间
|
|||
|
|
* remainingAmount:
|
|||
|
|
* type: number
|
|||
|
|
* description: 剩余还款金额
|
|||
|
|
* repaymentProgress:
|
|||
|
|
* type: number
|
|||
|
|
* description: 还款进度百分比
|
|||
|
|
* creator:
|
|||
|
|
* $ref: '#/components/schemas/User'
|
|||
|
|
* updater:
|
|||
|
|
* $ref: '#/components/schemas/User'
|
|||
|
|
* User:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* id:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 用户ID
|
|||
|
|
* username:
|
|||
|
|
* type: string
|
|||
|
|
* description: 用户名
|
|||
|
|
* real_name:
|
|||
|
|
* type: string
|
|||
|
|
* description: 真实姓名
|
|||
|
|
* email:
|
|||
|
|
* type: string
|
|||
|
|
* description: 邮箱
|
|||
|
|
* phone:
|
|||
|
|
* type: string
|
|||
|
|
* description: 电话
|
|||
|
|
* Pagination:
|
|||
|
|
* type: object
|
|||
|
|
* properties:
|
|||
|
|
* current:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 当前页码
|
|||
|
|
* pageSize:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 每页数量
|
|||
|
|
* total:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 总记录数
|
|||
|
|
* totalPages:
|
|||
|
|
* type: integer
|
|||
|
|
* description: 总页数
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
module.exports = router;
|