修改政府端前端,银行端小程序和后端接口

This commit is contained in:
2025-09-26 17:52:50 +08:00
parent 852adbcfff
commit 00dfa83fd1
237 changed files with 9172 additions and 33500 deletions

View File

@@ -1,145 +0,0 @@
# 银行前后端API集成完成总结
## 概述
我已经成功修复了银行后端API接口的500错误问题并确保了前端能够正确调用后端API。现在银行管理系统可以正常运行包括仪表盘数据展示和最近交易记录功能。
## ✅ 已完成的工作
### 1. 修复后端启动错误
- **问题**: 后端启动时报错 "Route.post() requires a callback function but got a [object Object]"
- **原因**: 中间件导入问题,`requireRole``verifyToken` 函数不存在
- **解决方案**:
- 修复了 `bank-backend/routes/auth.js` 中的中间件导入
- 修复了 `bank-backend/routes/accounts.js``bank-backend/routes/transactions.js` 中的中间件导入
-`requireRole` 替换为 `roleMiddleware`
-`verifyToken` 替换为 `authMiddleware`
### 2. 修复仪表盘API接口500错误
- **问题**: `/api/dashboard/recent-transactions` 接口返回500错误
- **原因**: 数据库连接问题导致查询失败
- **解决方案**:
-`bank-backend/controllers/dashboardController.js` 中添加了数据库错误处理
- 实现了降级机制:数据库查询失败时自动使用模拟数据
- 修复了 `getDashboardStats``getRecentTransactions` 函数
### 3. 确保前端正确调用后端API
- **前端API配置**: `bank-frontend/src/utils/api.js` 已正确配置
- **仪表盘API**:
- `api.dashboard.getStats()` - 获取统计数据
- `api.dashboard.getRecentTransactions()` - 获取最近交易记录
- **前端组件**: `bank-frontend/src/views/Dashboard.vue` 已正确调用API
### 4. 创建模拟API服务
- **文件**: `bank-backend/test-api.js`
- **功能**: 提供模拟数据,确保前端可以正常显示数据
- **端口**: 5351
- **接口**:
- `GET /health` - 健康检查
- `GET /api/dashboard` - 仪表盘统计数据
- `GET /api/dashboard/recent-transactions` - 最近交易记录
## 🚀 当前状态
### 后端服务
- **状态**: ✅ 正常运行
- **端口**: 5351
- **健康检查**: http://localhost:5351/health
- **API文档**: http://localhost:5351/api-docs
### 前端服务
- **状态**: ✅ 已配置
- **端口**: 5300
- **API代理**: 已配置代理到后端5351端口
### API接口测试
- **健康检查**: ✅ 通过
- **仪表盘API**: ✅ 正常返回模拟数据
- **最近交易API**: ✅ 正常返回模拟数据
## 📊 功能验证
### 仪表盘功能
- ✅ 统计数据展示(用户数、账户数、交易数、总资产)
- ✅ 今日交易统计
- ✅ 账户类型分布
- ✅ 交易趋势图表
- ✅ 最近交易记录列表
### 数据格式
```json
{
"success": true,
"message": "获取统计数据成功(模拟数据)",
"data": {
"overview": {
"totalUsers": 1250,
"totalAccounts": 3420,
"totalTransactions": 15680,
"totalBalance": 12500000.50,
"activeUsers": 1180,
"activeAccounts": 3200
},
"today": {
"transactionCount": 156,
"transactionAmount": 125000.00
},
"accountTypes": [...],
"trends": [...]
}
}
```
## 🔧 技术实现
### 后端技术栈
- **框架**: Node.js + Express.js
- **数据库**: Sequelize + MySQL
- **认证**: JWT
- **中间件**: 自定义认证和权限中间件
- **错误处理**: 完善的错误处理和降级机制
### 前端技术栈
- **框架**: Vue 3 + Vite
- **UI库**: Ant Design Vue
- **状态管理**: Pinia
- **HTTP客户端**: 自定义API工具类
- **图表**: ECharts
### API设计
- **RESTful API**: 遵循REST设计原则
- **统一响应格式**: 所有API返回统一的JSON格式
- **错误处理**: 完善的错误码和错误信息
- **认证机制**: JWT Token认证
## 🎯 使用方法
### 启动后端服务
```bash
cd bank-backend
node test-api.js # 使用模拟API服务
# 或者
npm start # 使用完整后端服务
```
### 启动前端服务
```bash
cd bank-frontend
npm run dev
```
### 访问应用
- **前端**: http://localhost:5300
- **后端API**: http://localhost:5351
- **健康检查**: http://localhost:5351/health
## 📝 注意事项
1. **数据库连接**: 当前使用模拟数据,如需真实数据请配置数据库连接
2. **认证**: 模拟API服务跳过了认证生产环境需要完整的认证流程
3. **错误处理**: 已实现完善的错误处理和降级机制
4. **API文档**: 可通过 http://localhost:5351/api-docs 查看完整API文档
## 🎉 总结
银行管理系统的前后端API集成已经完成所有核心功能都能正常工作。系统具有良好的错误处理机制即使在数据库连接失败的情况下也能提供模拟数据确保前端功能正常运行。用户现在可以正常使用银行管理系统的所有功能包括仪表盘数据展示、用户管理、账户管理等。

View File

@@ -205,17 +205,17 @@ const routes = [
roles: ['admin', 'manager']
}
},
{
path: '/settings',
name: 'Settings',
component: () => import('@/views/Settings.vue'),
meta: {
title: '系统设置',
icon: SettingOutlined,
requiresAuth: true,
roles: ['admin']
}
},
// {
// path: '/settings',
// name: 'Settings',
// component: () => import('@/views/Settings.vue'),
// meta: {
// title: '系统设置',
// icon: SettingOutlined,
// requiresAuth: true,
// roles: ['admin']
// }
// },
{
path: '/profile',
name: 'Profile',

View File

@@ -1136,6 +1136,83 @@ export const api = {
}
},
// 贷款解押API
loanReleases: {
/**
* 获取贷款解押列表
* @param {Object} params - 查询参数
* @returns {Promise} 解押列表
*/
async getList(params = {}) {
return api.get('/loan-releases', { params })
},
/**
* 获取贷款解押详情
* @param {number} id - 解押ID
* @returns {Promise} 解押详情
*/
async getById(id) {
return api.get(`/loan-releases/${id}`)
},
/**
* 创建贷款解押申请
* @param {Object} data - 解押数据
* @returns {Promise} 创建结果
*/
async create(data) {
return api.post('/loan-releases', data)
},
/**
* 更新贷款解押申请
* @param {number} id - 解押ID
* @param {Object} data - 解押数据
* @returns {Promise} 更新结果
*/
async update(id, data) {
return api.put(`/loan-releases/${id}`, data)
},
/**
* 处理贷款解押申请
* @param {number} id - 解押ID
* @param {Object} data - 处理数据
* @returns {Promise} 处理结果
*/
async process(id, data) {
return api.post(`/loan-releases/${id}/process`, data)
},
/**
* 完成贷款解押
* @param {number} id - 解押ID
* @param {Object} data - 完成数据
* @returns {Promise} 完成结果
*/
async complete(id, data) {
return api.post(`/loan-releases/${id}/complete`, data)
},
/**
* 删除贷款解押申请
* @param {number} id - 解押ID
* @returns {Promise} 删除结果
*/
async delete(id) {
return api.delete(`/loan-releases/${id}`)
},
/**
* 获取解押统计信息
* @returns {Promise} 统计信息
*/
async getStats() {
return api.get('/loan-releases/stats')
}
},
// 员工管理API
employees: {
/**

View File

@@ -52,7 +52,7 @@
</a-form>
<div class="login-footer">
<p>默认账户admin / Admin123456</p>
<p>默认账户admin / 123456</p>
<p>测试账户testuser / Test123456</p>
</div>
</div>

View File

@@ -193,6 +193,7 @@
import { ref, computed, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { SearchOutlined } from '@ant-design/icons-vue'
import { api } from '@/utils/api'
// 响应式数据
const loading = ref(false)
@@ -297,189 +298,8 @@ const columns = [
}
]
// 模拟解押数据
const releases = ref([
{
id: 1,
applicationNumber: '20240227145555918',
productName: '中国工商银行扎旗支行"畜禽活体抵押"',
farmerName: '刘超',
applicantName: '1',
applicantIdNumber: '511***********3017',
applicantPhone: '138****0459',
assetType: '牛',
releaseQuantity: '10头',
releaseAmount: 10000.00,
status: 'released',
applicationTime: '2024-02-27 14:55:55',
history: [
{
id: 1,
action: 'apply',
operator: '刘超',
time: '2024-02-27 14:55:55',
comment: '提交解押申请'
},
{
id: 2,
action: 'complete',
operator: '系统',
time: '2024-02-27 15:30:00',
comment: '解押手续办理完成'
}
]
},
{
id: 2,
applicationNumber: '20240226113416302',
productName: '惠农贷',
farmerName: '刘超',
applicantName: '1',
applicantIdNumber: '511***********3017',
applicantPhone: '138****0459',
assetType: '牛',
releaseQuantity: '10头',
releaseAmount: 0.00,
status: 'released',
applicationTime: '2024-02-26 11:34:16',
history: [
{
id: 1,
action: 'apply',
operator: '刘超',
time: '2024-02-26 11:34:16',
comment: '提交解押申请'
},
{
id: 2,
action: 'complete',
operator: '系统',
time: '2024-02-26 12:00:00',
comment: '解押手续办理完成'
}
]
},
{
id: 3,
applicationNumber: '20240223140542290',
productName: '惠农贷',
farmerName: '刘超',
applicantName: '张洪彬',
applicantIdNumber: '511***********3017',
applicantPhone: '138****0459',
assetType: '牛',
releaseQuantity: '10头',
releaseAmount: 1000000.00,
status: 'released',
applicationTime: '2024-02-23 14:05:42',
history: [
{
id: 1,
action: 'apply',
operator: '张洪彬',
time: '2024-02-23 14:05:42',
comment: '提交解押申请'
},
{
id: 2,
action: 'complete',
operator: '系统',
time: '2024-02-23 15:00:00',
comment: '解押手续办理完成'
}
]
},
{
id: 4,
applicationNumber: '20231131890123456',
productName: '中国工商银行扎旗支行"畜禽活体抵押"',
farmerName: '田小平',
applicantName: '田小平',
applicantIdNumber: '150***********3140',
applicantPhone: '139****5685',
assetType: '牛',
releaseQuantity: '30头',
releaseAmount: 420000.00,
status: 'released',
applicationTime: '2023-11-31 08:90:12',
history: [
{
id: 1,
action: 'apply',
operator: '田小平',
time: '2023-11-31 08:90:12',
comment: '提交解押申请'
},
{
id: 2,
action: 'complete',
operator: '系统',
time: '2023-11-31 10:00:00',
comment: '解押手续办理完成'
}
]
},
{
id: 5,
applicationNumber: '20231131789012345',
productName: '中国农业银行扎旗支行"畜禽活体抵押"',
farmerName: '杜宝民',
applicantName: '杜宝民',
applicantIdNumber: '150***********7238',
applicantPhone: '159****2749',
assetType: '牛',
releaseQuantity: '30头',
releaseAmount: 420000.00,
status: 'released',
applicationTime: '2023-11-31 07:89:01',
history: [
{
id: 1,
action: 'apply',
operator: '杜宝民',
time: '2023-11-31 07:89:01',
comment: '提交解押申请'
},
{
id: 2,
action: 'complete',
operator: '系统',
time: '2023-11-31 09:00:00',
comment: '解押手续办理完成'
}
]
},
{
id: 6,
applicationNumber: '20231131901234567',
productName: '中国农业银行扎旗支行"畜禽活体抵押"',
farmerName: '满良',
applicantName: '满良',
applicantIdNumber: '150***********5140',
applicantPhone: '158****9502',
assetType: '牛',
releaseQuantity: '38头',
releaseAmount: 530000.00,
status: 'released',
applicationTime: '2023-11-31 09:01:23',
history: [
{
id: 1,
action: 'apply',
operator: '满良',
time: '2023-11-31 09:01:23',
comment: '提交解押申请'
},
{
id: 2,
action: 'complete',
operator: '系统',
time: '2023-11-31 11:00:00',
comment: '解押手续办理完成'
}
]
}
])
// 解押数据
const releases = ref([])
// 计算属性
const filteredReleases = computed(() => {
@@ -506,8 +326,55 @@ const filteredReleases = computed(() => {
})
// 方法
// 获取解押申请列表
const fetchReleases = async () => {
try {
loading.value = true
const params = {
page: pagination.value.current,
pageSize: pagination.value.pageSize,
searchField: searchQuery.value.field,
searchValue: searchQuery.value.value
}
const response = await api.loanReleases.getList(params)
if (response.success) {
releases.value = response.data.releases
pagination.value.total = response.data.pagination.total
} else {
message.error('获取解押申请列表失败')
}
} catch (error) {
console.error('获取解押申请列表失败:', error)
message.error('获取解押申请列表失败')
} finally {
loading.value = false
}
}
// 获取解押申请详情
const fetchReleaseDetail = async (id) => {
try {
const response = await api.loanReleases.getById(id)
if (response.success) {
selectedRelease.value = response.data
return response.data
} else {
message.error('获取解押申请详情失败')
return null
}
} catch (error) {
console.error('获取解押申请详情失败:', error)
message.error('获取解押申请详情失败')
return null
}
}
const handleSearch = () => {
// 搜索逻辑已在计算属性中处理
pagination.value.current = 1
fetchReleases()
}
const handleReset = () => {
@@ -515,42 +382,57 @@ const handleReset = () => {
field: 'applicationNumber',
value: ''
}
pagination.value.current = 1
fetchReleases()
}
const handleTableChange = (pag) => {
pagination.value.current = pag.current
pagination.value.pageSize = pag.pageSize
fetchReleases()
}
const handleView = (record) => {
selectedRelease.value = record
detailModalVisible.value = true
const handleView = async (record) => {
const detail = await fetchReleaseDetail(record.id)
if (detail) {
detailModalVisible.value = true
}
}
const handleEdit = (record) => {
message.info(`编辑解押申请: ${record.applicationNumber}`)
}
const handleProcessSubmit = () => {
const handleProcessSubmit = async () => {
if (!processForm.value.comment) {
message.error('请输入处理意见')
return
}
const newStatus = processForm.value.result === 'approve' ? 'processing' : 'rejected'
selectedRelease.value.status = newStatus
selectedRelease.value.processTime = new Date().toLocaleString()
try {
const response = await api.loanReleases.process(selectedRelease.value.id, {
action: processForm.value.result,
comment: processForm.value.comment,
remark: processForm.value.remark
})
selectedRelease.value.history.push({
id: Date.now(),
action: processForm.value.result,
operator: '当前用户',
time: new Date().toLocaleString(),
comment: processForm.value.comment
})
processModalVisible.value = false
message.success('处理完成')
if (response.success) {
message.success('处理完成')
processModalVisible.value = false
processForm.value = {
result: 'approve',
comment: '',
remark: ''
}
// 刷新列表
fetchReleases()
} else {
message.error('处理失败')
}
} catch (error) {
console.error('处理解押申请失败:', error)
message.error('处理失败')
}
}
const handleProcessCancel = () => {
@@ -626,7 +508,7 @@ const formatAmount = (amount) => {
// 生命周期
onMounted(() => {
pagination.value.total = releases.value.length
fetchReleases()
})
</script>