更新政府端和银行端

This commit is contained in:
2025-09-17 18:04:28 +08:00
parent f35ceef31f
commit e4287b83fe
185 changed files with 78320 additions and 189 deletions

View File

@@ -0,0 +1,322 @@
const express = require('express');
const { verifyToken, requireRole, checkAccountOwnership } = require('../middleware/auth');
const {
validateAccountNumber,
validateAmount,
handleValidationErrors
} = require('../middleware/security');
const router = express.Router();
const accountController = require('../controllers/accountController');
/**
* @swagger
* tags:
* name: Accounts
* description: 账户管理
*/
/**
* @swagger
* components:
* schemas:
* Account:
* type: object
* required:
* - user_id
* - account_type
* properties:
* id:
* type: integer
* description: 账户ID
* account_number:
* type: string
* description: 账户号码
* user_id:
* type: integer
* description: 用户ID
* account_type:
* type: string
* enum: [savings, checking, credit, loan]
* description: 账户类型
* balance:
* type: integer
* description: 账户余额(分)
* available_balance:
* type: integer
* description: 可用余额(分)
* frozen_amount:
* type: integer
* description: 冻结金额(分)
* status:
* type: string
* enum: [active, inactive, frozen, closed]
* description: 账户状态
*/
/**
* @swagger
* /api/accounts:
* post:
* summary: 创建账户
* tags: [Accounts]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - user_id
* - account_type
* properties:
* user_id:
* type: integer
* description: 用户ID
* account_type:
* type: string
* enum: [savings, checking, credit, loan]
* description: 账户类型
* initial_balance:
* type: number
* description: 初始余额(元)
* responses:
* 201:
* description: 创建成功
* 400:
* description: 输入数据验证失败
* 401:
* description: 未授权
* 403:
* description: 权限不足
*/
router.post('/',
verifyToken,
requireRole(['admin', 'manager']),
accountController.createAccount
);
/**
* @swagger
* /api/accounts:
* get:
* summary: 获取账户列表
* tags: [Accounts]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: 页码
* - in: query
* name: limit
* schema:
* type: integer
* default: 10
* description: 每页数量
* - in: query
* name: user_id
* schema:
* type: integer
* description: 用户ID管理员
* - in: query
* name: account_type
* schema:
* type: string
* enum: [savings, checking, credit, loan]
* description: 账户类型
* - in: query
* name: status
* schema:
* type: string
* enum: [active, inactive, frozen, closed]
* description: 账户状态
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
*/
router.get('/',
verifyToken,
accountController.getAccounts
);
/**
* @swagger
* /api/accounts/{accountId}:
* get:
* summary: 获取账户详情
* tags: [Accounts]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: accountId
* required: true
* schema:
* type: integer
* description: 账户ID
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 账户不存在
*/
router.get('/:accountId',
verifyToken,
checkAccountOwnership,
accountController.getAccountDetail
);
/**
* @swagger
* /api/accounts/{accountId}/status:
* put:
* summary: 更新账户状态
* tags: [Accounts]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: accountId
* required: true
* schema:
* type: integer
* description: 账户ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - status
* properties:
* status:
* type: string
* enum: [active, inactive, frozen, closed]
* description: 账户状态
* responses:
* 200:
* description: 更新成功
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 账户不存在
*/
router.put('/:accountId/status',
verifyToken,
requireRole(['admin', 'manager']),
accountController.updateAccountStatus
);
/**
* @swagger
* /api/accounts/{accountId}/deposit:
* post:
* summary: 存款
* tags: [Accounts]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: accountId
* required: true
* schema:
* type: integer
* description: 账户ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - amount
* properties:
* amount:
* type: number
* description: 存款金额(元)
* description:
* type: string
* description: 交易描述
* responses:
* 200:
* description: 存款成功
* 400:
* description: 输入数据验证失败或账户状态异常
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 账户不存在
*/
router.post('/:accountId/deposit',
verifyToken,
requireRole(['admin', 'manager', 'teller']),
validateAmount,
accountController.deposit
);
/**
* @swagger
* /api/accounts/{accountId}/withdraw:
* post:
* summary: 取款
* tags: [Accounts]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: accountId
* required: true
* schema:
* type: integer
* description: 账户ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - amount
* properties:
* amount:
* type: number
* description: 取款金额(元)
* description:
* type: string
* description: 交易描述
* responses:
* 200:
* description: 取款成功
* 400:
* description: 输入数据验证失败、账户状态异常或余额不足
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 账户不存在
*/
router.post('/:accountId/withdraw',
verifyToken,
requireRole(['admin', 'manager', 'teller']),
validateAmount,
accountController.withdraw
);
module.exports = router;

View File

@@ -0,0 +1,287 @@
const express = require('express');
const { verifyToken, requireRole } = require('../middleware/auth');
const {
validateAmount,
validateAccountNumber,
handleValidationErrors
} = require('../middleware/security');
const router = express.Router();
const transactionController = require('../controllers/transactionController');
/**
* @swagger
* tags:
* name: Transactions
* description: 交易管理
*/
/**
* @swagger
* components:
* schemas:
* Transaction:
* type: object
* required:
* - account_id
* - transaction_type
* - amount
* properties:
* id:
* type: integer
* description: 交易ID
* transaction_number:
* type: string
* description: 交易流水号
* account_id:
* type: integer
* description: 账户ID
* transaction_type:
* type: string
* enum: [deposit, withdrawal, transfer_in, transfer_out, interest, fee, loan, repayment]
* description: 交易类型
* amount:
* type: integer
* description: 交易金额(分)
* balance_before:
* type: integer
* description: 交易前余额(分)
* balance_after:
* type: integer
* description: 交易后余额(分)
* counterparty_account:
* type: string
* description: 对方账户号
* counterparty_name:
* type: string
* description: 对方户名
* description:
* type: string
* description: 交易描述
* status:
* type: string
* enum: [pending, completed, failed, cancelled, reversed]
* description: 交易状态
*/
/**
* @swagger
* /api/transactions:
* get:
* summary: 获取交易记录列表
* tags: [Transactions]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: 页码
* - in: query
* name: limit
* schema:
* type: integer
* default: 20
* description: 每页数量
* - in: query
* name: account_id
* schema:
* type: integer
* description: 账户ID管理员
* - in: query
* name: transaction_type
* schema:
* type: string
* enum: [deposit, withdrawal, transfer_in, transfer_out, interest, fee, loan, repayment]
* description: 交易类型
* - in: query
* name: status
* schema:
* type: string
* enum: [pending, completed, failed, cancelled, reversed]
* description: 交易状态
* - in: query
* name: start_date
* schema:
* type: string
* format: date
* description: 开始日期
* - in: query
* name: end_date
* schema:
* type: string
* format: date
* description: 结束日期
* - in: query
* name: amount_min
* schema:
* type: number
* description: 最小金额(元)
* - in: query
* name: amount_max
* schema:
* type: number
* description: 最大金额(元)
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
*/
router.get('/',
verifyToken,
transactionController.getTransactions
);
/**
* @swagger
* /api/transactions/{transactionId}:
* get:
* summary: 获取交易详情
* tags: [Transactions]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: transactionId
* required: true
* schema:
* type: integer
* description: 交易ID
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 交易记录不存在
*/
router.get('/:transactionId',
verifyToken,
transactionController.getTransactionDetail
);
/**
* @swagger
* /api/transactions/transfer:
* post:
* summary: 转账
* tags: [Transactions]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - from_account_id
* - to_account_number
* - amount
* properties:
* from_account_id:
* type: integer
* description: 转出账户ID
* to_account_number:
* type: string
* description: 转入账户号码
* amount:
* type: number
* description: 转账金额(元)
* description:
* type: string
* description: 转账描述
* responses:
* 200:
* description: 转账成功
* 400:
* description: 输入数据验证失败、账户状态异常或余额不足
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 账户不存在
*/
router.post('/transfer',
verifyToken,
validateAmount,
validateAccountNumber,
transactionController.transfer
);
/**
* @swagger
* /api/transactions/{transactionId}/reverse:
* post:
* summary: 撤销交易
* tags: [Transactions]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: transactionId
* required: true
* schema:
* type: integer
* description: 交易ID
* responses:
* 200:
* description: 撤销成功
* 400:
* description: 该交易无法撤销
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 交易记录不存在
*/
router.post('/:transactionId/reverse',
verifyToken,
requireRole(['admin', 'manager']),
transactionController.reverseTransaction
);
/**
* @swagger
* /api/transactions/stats:
* get:
* summary: 获取交易统计
* tags: [Transactions]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: start_date
* schema:
* type: string
* format: date
* description: 开始日期
* - in: query
* name: end_date
* schema:
* type: string
* format: date
* description: 结束日期
* - in: query
* name: account_id
* schema:
* type: integer
* description: 账户ID管理员
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
*/
router.get('/stats',
verifyToken,
transactionController.getTransactionStats
);
module.exports = router;

View File

@@ -0,0 +1,348 @@
const express = require('express');
const { verifyToken, requireRole, requireLevel } = require('../middleware/auth');
const {
validatePhone,
validatePassword,
validateIdCard,
handleValidationErrors
} = require('../middleware/security');
const router = express.Router();
const userController = require('../controllers/userController');
/**
* @swagger
* tags:
* name: Users
* description: 用户管理
*/
/**
* @swagger
* components:
* schemas:
* User:
* type: object
* required:
* - username
* - email
* - password
* - real_name
* - id_card
* properties:
* id:
* type: integer
* description: 用户ID
* username:
* type: string
* description: 用户名
* email:
* type: string
* format: email
* description: 邮箱地址
* real_name:
* type: string
* description: 真实姓名
* id_card:
* type: string
* description: 身份证号
* phone:
* type: string
* description: 手机号
* status:
* type: string
* enum: [active, inactive, suspended, locked]
* description: 用户状态
*/
/**
* @swagger
* /api/users/register:
* post:
* summary: 用户注册
* tags: [Users]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - username
* - email
* - password
* - real_name
* - id_card
* properties:
* username:
* type: string
* description: 用户名
* email:
* type: string
* format: email
* description: 邮箱地址
* password:
* type: string
* description: 密码
* real_name:
* type: string
* description: 真实姓名
* id_card:
* type: string
* description: 身份证号
* phone:
* type: string
* description: 手机号
* responses:
* 201:
* description: 注册成功
* 400:
* description: 输入数据验证失败
* 500:
* description: 服务器内部错误
*/
router.post('/register',
validatePassword,
validateIdCard,
validatePhone,
userController.register
);
/**
* @swagger
* /api/users/login:
* post:
* summary: 用户登录
* tags: [Users]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - username
* - password
* properties:
* username:
* type: string
* description: 用户名
* password:
* type: string
* description: 密码
* responses:
* 200:
* description: 登录成功
* 401:
* description: 用户名或密码错误
* 500:
* description: 服务器内部错误
*/
router.post('/login', userController.login);
/**
* @swagger
* /api/users/profile:
* get:
* summary: 获取用户信息
* tags: [Users]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
* 404:
* description: 用户不存在
*/
router.get('/profile', verifyToken, userController.getProfile);
/**
* @swagger
* /api/users/profile:
* put:
* summary: 更新用户信息
* tags: [Users]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* phone:
* type: string
* description: 手机号
* real_name:
* type: string
* description: 真实姓名
* avatar:
* type: string
* description: 头像URL
* responses:
* 200:
* description: 更新成功
* 400:
* description: 输入数据验证失败
* 401:
* description: 未授权
*/
router.put('/profile',
verifyToken,
validatePhone,
userController.updateProfile
);
/**
* @swagger
* /api/users/change-password:
* put:
* summary: 修改密码
* tags: [Users]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - old_password
* - new_password
* properties:
* old_password:
* type: string
* description: 原密码
* new_password:
* type: string
* description: 新密码
* responses:
* 200:
* description: 修改成功
* 400:
* description: 原密码错误
* 401:
* description: 未授权
*/
router.put('/change-password',
verifyToken,
validatePassword,
userController.changePassword
);
/**
* @swagger
* /api/users:
* get:
* summary: 获取用户列表(管理员)
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: 页码
* - in: query
* name: limit
* schema:
* type: integer
* default: 10
* description: 每页数量
* - in: query
* name: search
* schema:
* type: string
* description: 搜索关键词
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
* 403:
* description: 权限不足
*/
router.get('/',
verifyToken,
requireRole('admin'),
userController.getUsers
);
/**
* @swagger
* /api/users/{userId}/status:
* put:
* summary: 更新用户状态(管理员)
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: integer
* description: 用户ID
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - status
* properties:
* status:
* type: string
* enum: [active, inactive, suspended, locked]
* description: 用户状态
* responses:
* 200:
* description: 更新成功
* 401:
* description: 未授权
* 403:
* description: 权限不足
* 404:
* description: 用户不存在
*/
router.put('/:userId/status',
verifyToken,
requireRole('admin'),
userController.updateUserStatus
);
/**
* @swagger
* /api/users/{userId}/accounts:
* get:
* summary: 获取用户账户列表
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: userId
* required: true
* schema:
* type: integer
* description: 用户ID
* responses:
* 200:
* description: 获取成功
* 401:
* description: 未授权
* 403:
* description: 权限不足
*/
router.get('/:userId/accounts',
verifyToken,
userController.getUserAccounts
);
module.exports = router;