329 lines
9.0 KiB
Markdown
329 lines
9.0 KiB
Markdown
# 采购付款分离改造修复方案
|
||||
|
|
|
|||
|
|
## 问题分析
|
|||
|
|
|
|||
|
|
经过代码分析,发现以下问题:
|
|||
|
|
|
|||
|
|
1. **数据库表结构**:db-sqlite.js 文件中已经包含了所有必要的表创建语句,包括:
|
|||
|
|
- purchase_orders(采购订单表)
|
|||
|
|
- purchase_order_items(采购订单明细表)
|
|||
|
|
- payment_plans(付款计划表)
|
|||
|
|
- inventory_records(库存记录表)
|
|||
|
|
|
|||
|
|
2. **API端点实现**:final-backend.js 文件中已经包含了所有必要的API端点:
|
|||
|
|
- 采购订单API:GET /api/purchase-orders, POST /api/purchase-orders, GET /api/purchase-orders/:id
|
|||
|
|
- 付款计划API:GET /api/payment-plans, POST /api/payment-plans, GET /api/payment-plans/:id, PUT /api/payment-plans/:id
|
|||
|
|
- 库存管理API:GET /api/inventory, GET /api/inventory/summary, POST /api/inventory/out
|
|||
|
|
|
|||
|
|
3. **前端配置**:前端代码中已经正确配置了API调用,使用相对路径 /api/...
|
|||
|
|
|
|||
|
|
## 修复方案
|
|||
|
|
|
|||
|
|
### 步骤1:初始化数据库
|
|||
|
|
|
|||
|
|
1. **运行数据库初始化脚本**:
|
|||
|
|
```bash
|
|||
|
|
node db-sqlite.js
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **验证数据库表结构**:
|
|||
|
|
- 运行数据库表结构检查脚本
|
|||
|
|
- 确保所有必要的表都已创建
|
|||
|
|
|
|||
|
|
### 步骤2:启动后端服务器
|
|||
|
|
|
|||
|
|
1. **安装依赖项**:
|
|||
|
|
```bash
|
|||
|
|
npm install
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **启动后端服务器**:
|
|||
|
|
```bash
|
|||
|
|
npm start
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **验证服务器启动**:
|
|||
|
|
- 检查服务器是否在端口3002上运行
|
|||
|
|
- 访问 http://localhost:3002/api/health 验证健康检查端点
|
|||
|
|
|
|||
|
|
### 步骤3:测试API端点
|
|||
|
|
|
|||
|
|
1. **运行API端点测试脚本**:
|
|||
|
|
```bash
|
|||
|
|
node test-api-endpoints.js
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **验证API响应**:
|
|||
|
|
- 确保所有API端点返回 200 状态码
|
|||
|
|
- 确保响应数据符合预期格式
|
|||
|
|
|
|||
|
|
### 步骤4:测试前端连接
|
|||
|
|
|
|||
|
|
1. **启动前端服务器**:
|
|||
|
|
```bash
|
|||
|
|
cd ../frontend
|
|||
|
|
npm install
|
|||
|
|
npm run dev
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **验证前端连接**:
|
|||
|
|
- 访问 http://localhost:3006
|
|||
|
|
- 导航到采购订单、付款计划和库存管理页面
|
|||
|
|
- 验证数据加载是否正常
|
|||
|
|
|
|||
|
|
## 具体修复措施
|
|||
|
|
|
|||
|
|
### 1. 数据库表结构修复
|
|||
|
|
|
|||
|
|
确保以下表都已创建:
|
|||
|
|
|
|||
|
|
**purchase_orders表**:
|
|||
|
|
- id (INTEGER PRIMARY KEY AUTOINCREMENT)
|
|||
|
|
- code (TEXT NOT NULL)
|
|||
|
|
- purchase_request_id (INTEGER)
|
|||
|
|
- supplier_id (INTEGER)
|
|||
|
|
- supplier_name (TEXT)
|
|||
|
|
- total_amount (REAL DEFAULT 0)
|
|||
|
|
- currency (TEXT DEFAULT 'CNY')
|
|||
|
|
- order_date (TEXT)
|
|||
|
|
- delivery_date (TEXT)
|
|||
|
|
- status (TEXT DEFAULT 'pending')
|
|||
|
|
- created_by (TEXT)
|
|||
|
|
- created_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
|
|||
|
|
- updated_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
|
|||
|
|
|
|||
|
|
**purchase_order_items表**:
|
|||
|
|
- id (INTEGER PRIMARY KEY AUTOINCREMENT)
|
|||
|
|
- purchase_order_id (INTEGER NOT NULL)
|
|||
|
|
- product_id (INTEGER)
|
|||
|
|
- product_name (TEXT NOT NULL)
|
|||
|
|
- specification (TEXT)
|
|||
|
|
- quantity (REAL NOT NULL)
|
|||
|
|
- unit (TEXT NOT NULL)
|
|||
|
|
- unit_price (REAL NOT NULL)
|
|||
|
|
- total_price (REAL NOT NULL)
|
|||
|
|
- remark (TEXT)
|
|||
|
|
- created_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
|
|||
|
|
- updated_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
|
|||
|
|
|
|||
|
|
**payment_plans表**:
|
|||
|
|
- id (INTEGER PRIMARY KEY AUTOINCREMENT)
|
|||
|
|
- purchase_order_id (INTEGER NOT NULL)
|
|||
|
|
- code (TEXT NOT NULL)
|
|||
|
|
- payment_date (TEXT)
|
|||
|
|
- amount (REAL NOT NULL)
|
|||
|
|
- currency (TEXT DEFAULT 'CNY')
|
|||
|
|
- payment_type (TEXT DEFAULT 'partial')
|
|||
|
|
- status (TEXT DEFAULT 'pending')
|
|||
|
|
- description (TEXT)
|
|||
|
|
- created_by (TEXT)
|
|||
|
|
- created_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
|
|||
|
|
- updated_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
|
|||
|
|
|
|||
|
|
**inventory_records表**:
|
|||
|
|
- id (INTEGER PRIMARY KEY AUTOINCREMENT)
|
|||
|
|
- record_type (TEXT NOT NULL)
|
|||
|
|
- purchase_request_id (INTEGER)
|
|||
|
|
- project_id (INTEGER)
|
|||
|
|
- product_id (INTEGER)
|
|||
|
|
- quantity (REAL NOT NULL)
|
|||
|
|
- unit_price (REAL)
|
|||
|
|
- total_amount (REAL)
|
|||
|
|
- record_date (TEXT)
|
|||
|
|
- operator (TEXT)
|
|||
|
|
- remark (TEXT)
|
|||
|
|
- created_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
|
|||
|
|
|
|||
|
|
### 2. API端点修复
|
|||
|
|
|
|||
|
|
确保以下API端点正确实现:
|
|||
|
|
|
|||
|
|
**采购订单API**:
|
|||
|
|
- `GET /api/purchase-orders` - 获取采购订单列表
|
|||
|
|
- `POST /api/purchase-orders` - 创建采购订单
|
|||
|
|
- `GET /api/purchase-orders/:id` - 获取采购订单详情
|
|||
|
|
|
|||
|
|
**付款计划API**:
|
|||
|
|
- `GET /api/payment-plans` - 获取付款计划列表
|
|||
|
|
- `POST /api/payment-plans` - 创建付款计划
|
|||
|
|
- `GET /api/payment-plans/:id` - 获取付款计划详情
|
|||
|
|
- `PUT /api/payment-plans/:id` - 更新付款计划
|
|||
|
|
|
|||
|
|
**库存管理API**:
|
|||
|
|
- `GET /api/inventory` - 获取库存记录
|
|||
|
|
- `GET /api/inventory/summary` - 获取库存汇总
|
|||
|
|
- `POST /api/inventory/out` - 出库操作
|
|||
|
|
|
|||
|
|
### 3. 前端连接修复
|
|||
|
|
|
|||
|
|
确保前端代码正确调用API端点:
|
|||
|
|
|
|||
|
|
- 采购订单页面:使用 `/api/purchase-orders` 端点
|
|||
|
|
- 付款计划页面:使用 `/api/payment-plans` 端点
|
|||
|
|
- 库存管理页面:使用 `/api/inventory` 端点
|
|||
|
|
|
|||
|
|
## 验证测试
|
|||
|
|
|
|||
|
|
### 1. 数据库表结构验证
|
|||
|
|
|
|||
|
|
运行数据库表结构检查脚本,确保所有必要的表都已创建:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const sqlite3 = require('sqlite3').verbose();
|
|||
|
|
const path = require('path');
|
|||
|
|
|
|||
|
|
const dbPath = path.join(__dirname, 'company_finance.db');
|
|||
|
|
const db = new sqlite3.Database(dbPath, (err) => {
|
|||
|
|
if (err) {
|
|||
|
|
console.error('数据库连接失败:', err.message);
|
|||
|
|
process.exit(1);
|
|||
|
|
} else {
|
|||
|
|
console.log('数据库连接成功');
|
|||
|
|
checkTables();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function checkTables() {
|
|||
|
|
console.log('正在检查数据库表结构...');
|
|||
|
|
|
|||
|
|
const tables = [
|
|||
|
|
'purchase_orders',
|
|||
|
|
'purchase_order_items',
|
|||
|
|
'payment_plans',
|
|||
|
|
'inventory_records'
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
let checked = 0;
|
|||
|
|
|
|||
|
|
tables.forEach(table => {
|
|||
|
|
db.get(`SELECT name FROM sqlite_master WHERE type='table' AND name='${table}'`, (err, row) => {
|
|||
|
|
checked++;
|
|||
|
|
if (err) {
|
|||
|
|
console.error(`检查表 ${table} 失败:`, err.message);
|
|||
|
|
} else if (row) {
|
|||
|
|
console.log(`✅ 表 ${table} 存在`);
|
|||
|
|
} else {
|
|||
|
|
console.log(`❌ 表 ${table} 不存在`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (checked === tables.length) {
|
|||
|
|
console.log('检查完成');
|
|||
|
|
db.close();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. API端点验证
|
|||
|
|
|
|||
|
|
运行API端点测试脚本,确保所有API端点正常响应:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const http = require('http');
|
|||
|
|
|
|||
|
|
const options = {
|
|||
|
|
hostname: 'localhost',
|
|||
|
|
port: 3002,
|
|||
|
|
timeout: 5000
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function testApi(endpoint, method = 'GET', data = null) {
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
const reqOptions = {
|
|||
|
|
...options,
|
|||
|
|
path: endpoint,
|
|||
|
|
method,
|
|||
|
|
headers: {
|
|||
|
|
'Content-Type': 'application/json'
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const req = http.request(reqOptions, (res) => {
|
|||
|
|
let data = '';
|
|||
|
|
res.on('data', (chunk) => {
|
|||
|
|
data += chunk;
|
|||
|
|
});
|
|||
|
|
res.on('end', () => {
|
|||
|
|
try {
|
|||
|
|
const result = JSON.parse(data);
|
|||
|
|
resolve({ status: res.statusCode, data: result });
|
|||
|
|
} catch (error) {
|
|||
|
|
resolve({ status: res.statusCode, data: data });
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
req.on('error', (error) => {
|
|||
|
|
reject(error);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
req.on('timeout', () => {
|
|||
|
|
req.destroy();
|
|||
|
|
reject(new Error('请求超时'));
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (data) {
|
|||
|
|
req.write(JSON.stringify(data));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
req.end();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function runTests() {
|
|||
|
|
console.log('开始测试API端点...');
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// 测试采购订单API
|
|||
|
|
console.log('\n测试采购订单API:');
|
|||
|
|
const purchaseOrders = await testApi('/api/purchase-orders');
|
|||
|
|
console.log('GET /api/purchase-orders:', purchaseOrders.status);
|
|||
|
|
console.log('响应:', purchaseOrders.data);
|
|||
|
|
|
|||
|
|
// 测试付款计划API
|
|||
|
|
console.log('\n测试付款计划API:');
|
|||
|
|
const paymentPlans = await testApi('/api/payment-plans');
|
|||
|
|
console.log('GET /api/payment-plans:', paymentPlans.status);
|
|||
|
|
console.log('响应:', paymentPlans.data);
|
|||
|
|
|
|||
|
|
// 测试库存管理API
|
|||
|
|
console.log('\n测试库存管理API:');
|
|||
|
|
const inventory = await testApi('/api/inventory');
|
|||
|
|
console.log('GET /api/inventory:', inventory.status);
|
|||
|
|
console.log('响应:', inventory.data);
|
|||
|
|
|
|||
|
|
console.log('\n测试完成');
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('测试失败:', error.message);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
runTests();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 前端功能验证
|
|||
|
|
|
|||
|
|
1. **访问前端应用**:http://localhost:3006
|
|||
|
|
2. **导航到采购订单页面**:验证采购订单列表加载正常
|
|||
|
|
3. **导航到付款计划页面**:验证付款计划列表加载正常
|
|||
|
|
4. **导航到库存管理页面**:验证库存管理列表加载正常
|
|||
|
|
5. **测试创建功能**:尝试创建采购订单和付款计划
|
|||
|
|
6. **测试编辑功能**:尝试编辑采购订单和付款计划
|
|||
|
|
7. **测试库存操作**:尝试出库操作
|
|||
|
|
|
|||
|
|
## 预期结果
|
|||
|
|
|
|||
|
|
1. **数据库表结构**:所有必要的表都已创建
|
|||
|
|
2. **API端点**:所有API端点返回 200 状态码,响应数据符合预期格式
|
|||
|
|
3. **前端功能**:所有页面加载正常,功能操作正常
|
|||
|
|
|
|||
|
|
## 修复总结
|
|||
|
|
|
|||
|
|
1. **数据库初始化**:运行 db-sqlite.js 初始化数据库,确保所有必要的表都已创建
|
|||
|
|
2. **后端服务器**:启动后端服务器,确保API端点正常响应
|
|||
|
|
3. **前端连接**:启动前端服务器,确保前端正确调用API端点
|
|||
|
|
4. **功能验证**:测试所有功能,确保采购付款分离改造方案的需求能够实现
|
|||
|
|
|
|||
|
|
通过以上修复步骤,应该能够解决获取采购订单列表失败、获取付款计划列表失败和库存管理列表失败的问题。
|