备份:修复前完整项目快照 2026-04-19
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { status } = req.query;
|
||||
let query = 'SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances';
|
||||
const params = [];
|
||||
|
||||
if (status) {
|
||||
query += ' WHERE status = ?';
|
||||
params.push(status);
|
||||
}
|
||||
|
||||
query += ' ORDER BY created_at DESC';
|
||||
|
||||
const advancesResult = await db.query(query, params);
|
||||
const advances = advancesResult.rows;
|
||||
res.json({ success: true, data: advances, count: advances.length });
|
||||
} catch (error) {
|
||||
console.error('获取预支款列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取预支款列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const advanceResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances WHERE id = ?', [id]);
|
||||
|
||||
if (advanceResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '预支款不存在' });
|
||||
}
|
||||
|
||||
const advance = advanceResult.rows[0];
|
||||
res.json({ success: true, data: advance });
|
||||
} catch (error) {
|
||||
console.error('获取预支款详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取预支款详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { user_id, project_id, amount, description } = req.body;
|
||||
|
||||
if (!user_id || !project_id || !amount) {
|
||||
return res.status(400).json({ success: false,
|
||||
message: '用户ID、项目ID和金额为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO advances (user_id, project_id, amount, description, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[user_id, project_id, amount, description || '', 'pending']
|
||||
);
|
||||
|
||||
const newAdvanceResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances WHERE id = ?', [result.lastID]);
|
||||
const newAdvance = newAdvanceResult.rows[0];
|
||||
|
||||
console.log(`预支款创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newAdvance });
|
||||
} catch (error) {
|
||||
console.error('创建预支款失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建预支款失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { amount, description } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE advances SET amount = ?, description = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[amount, description, id]
|
||||
);
|
||||
|
||||
const updatedAdvanceResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances WHERE id = ?', [id]);
|
||||
const updatedAdvance = updatedAdvanceResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedAdvance });
|
||||
} catch (error) {
|
||||
console.error('更新预支款信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新预支款信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingAdvance = await db.query('SELECT id FROM advances WHERE id = ?', [id]);
|
||||
if (existingAdvance.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '预支款不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM advances WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '预支款删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除预支款失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除预支款失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/submit', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE advances SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['submitted', id]
|
||||
);
|
||||
|
||||
const updatedAdvanceResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances WHERE id = ?', [id]);
|
||||
const updatedAdvance = updatedAdvanceResult.rows[0];
|
||||
|
||||
console.log(`预支款 ${id} 提交成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedAdvance });
|
||||
} catch (error) {
|
||||
console.error('提交预支款失败:', error);
|
||||
res.status(500).json({ success: false, message: '提交预支款失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/withdraw', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE advances SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['pending', id]
|
||||
);
|
||||
|
||||
const updatedAdvanceResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances WHERE id = ?', [id]);
|
||||
const updatedAdvance = updatedAdvanceResult.rows[0];
|
||||
|
||||
console.log(`预支款 ${id} 撤回成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: { updatedAdvance, message: '预支款已撤回' } });
|
||||
} catch (error) {
|
||||
console.error('撤回预支款失败:', error);
|
||||
res.status(500).json({ success: false, message: '撤回预支款失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/approve', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE advances SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['approved', id]
|
||||
);
|
||||
|
||||
const updatedAdvanceResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances WHERE id = ?', [id]);
|
||||
const updatedAdvance = updatedAdvanceResult.rows[0];
|
||||
|
||||
console.log(`预支款 ${id} 审批通过成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedAdvance });
|
||||
} catch (error) {
|
||||
console.error('审批通过预支款失败:', error);
|
||||
res.status(500).json({ success: false, message: '审批通过预支款失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/reject', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE advances SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['rejected', id]
|
||||
);
|
||||
|
||||
const updatedAdvanceResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM advances WHERE id = ?', [id]);
|
||||
const updatedAdvance = updatedAdvanceResult.rows[0];
|
||||
|
||||
console.log(`预支款 ${id} 审批拒绝成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedAdvance });
|
||||
} catch (error) {
|
||||
console.error('审批拒绝预支款失败:', error);
|
||||
res.status(500).json({ success: false, message: '审批拒绝预支款失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/advances', router);
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const budgetProjectsResult = await db.query('SELECT id, name, contract_amount, status, created_at, updated_at FROM projects WHERE status = ? ORDER BY created_at DESC', ['budget']);
|
||||
const budgetProjects = budgetProjectsResult.rows;
|
||||
res.json({ success: true, data: budgetProjects, count: budgetProjects.length });
|
||||
} catch (error) {
|
||||
console.error('获取预算项目列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取预算项目列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const budgetProjectResult = await db.query('SELECT id, name, contract_amount, status, created_at, updated_at FROM projects WHERE id = ?', [id]);
|
||||
|
||||
if (budgetProjectResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '预算项目不存在' });
|
||||
}
|
||||
|
||||
const budgetProject = budgetProjectResult.rows[0];
|
||||
res.json({ success: true, data: budgetProject });
|
||||
} catch (error) {
|
||||
console.error('获取预算项目详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取预算项目详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { name, contract_amount } = req.body;
|
||||
|
||||
if (!name) {
|
||||
return res.status(400).json({ success: false, message: '项目名称为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO projects (name, contract_amount, status, created_at, updated_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[name, contract_amount, 'budget', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP]
|
||||
);
|
||||
|
||||
const newBudgetProjectResult = await db.query('SELECT id, name, contract_amount, status, created_at, updated_at FROM projects WHERE id = ?', [result.lastID]);
|
||||
const newBudgetProject = newBudgetProjectResult.rows[0];
|
||||
|
||||
console.log(`预算项目 ${name} 创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newBudgetProject });
|
||||
} catch (error) {
|
||||
console.error('创建预算项目失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建预算项目失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingProject = await db.query('SELECT id FROM projects WHERE id = ?', [id]);
|
||||
if (existingProject.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '预算项目不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM projects WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '预算项目删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除预算项目失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除预算项目失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/budget-projects', router);
|
||||
};
|
||||
@@ -0,0 +1,137 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const categoriesResult = await db.query('SELECT id, name, parent_id, created_at, updated_at FROM categories ORDER BY parent_id, name');
|
||||
const categories = categoriesResult.rows;
|
||||
res.json({ success: true, data: categories, count: categories.length });
|
||||
} catch (error) {
|
||||
console.error('获取分类列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取分类列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/tree', authenticate, async (req, res) => {
|
||||
try {
|
||||
const categoriesResult = await db.query('SELECT id, name, parent_id, created_at, updated_at FROM categories ORDER BY parent_id, name');
|
||||
const categories = categoriesResult.rows;
|
||||
|
||||
const categoryTree = buildCategoryTree(categories);
|
||||
res.json({ success: true, data: categoryTree });
|
||||
} catch (error) {
|
||||
console.error('获取分类树失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取分类树失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const categoryResult = await db.query('SELECT id, name, parent_id, created_at, updated_at FROM categories WHERE id = ?', [id]);
|
||||
|
||||
if (categoryResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '分类不存在' });
|
||||
}
|
||||
|
||||
const category = categoryResult.rows[0];
|
||||
res.json({ success: true, data: category });
|
||||
} catch (error) {
|
||||
console.error('获取分类详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取分类详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { name, parent_id } = req.body;
|
||||
|
||||
if (!name) {
|
||||
return res.status(400).json({ success: false, message: '分类名称为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO categories (name, parent_id, created_at, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[name, parent_id || null]
|
||||
);
|
||||
|
||||
const newCategoryResult = await db.query('SELECT id, name, parent_id, created_at, updated_at FROM categories WHERE id = ?', [result.lastID]);
|
||||
const newCategory = newCategoryResult.rows[0];
|
||||
|
||||
console.log(`分类 ${name} 创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newCategory });
|
||||
} catch (error) {
|
||||
console.error('创建分类失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建分类失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, parent_id } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE categories SET name = ?, parent_id = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[name, parent_id, id]
|
||||
);
|
||||
|
||||
const updatedCategoryResult = await db.query('SELECT id, name, parent_id, created_at, updated_at FROM categories WHERE id = ?', [id]);
|
||||
const updatedCategory = updatedCategoryResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedCategory });
|
||||
} catch (error) {
|
||||
console.error('更新分类信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新分类信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingCategory = await db.query('SELECT id FROM categories WHERE id = ?', [id]);
|
||||
if (existingCategory.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '分类不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM categories WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '分类删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除分类失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除分类失败' });
|
||||
}
|
||||
});
|
||||
|
||||
function buildCategoryTree(categories, parentId = null) {
|
||||
const tree = [];
|
||||
|
||||
categories.forEach(category => {
|
||||
if (category.parent_id === parentId) {
|
||||
tree.push({
|
||||
id: category.id,
|
||||
name: category.name,
|
||||
children: []
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const rootCategories = categories.filter(cat => !cat.parent_id);
|
||||
rootCategories.forEach(category => {
|
||||
tree.push({
|
||||
id: category.id,
|
||||
name: category.name,
|
||||
children: buildCategoryTree(categories, category.id)
|
||||
});
|
||||
});
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
app.use('/api/categories', router);
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const customersResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM customers');
|
||||
const customers = customersResult.rows;
|
||||
res.json({ success: true, data: customers, count: customers.length });
|
||||
} catch (error) {
|
||||
console.error('获取客户列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取客户列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const customerResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM customers WHERE id = ?', [id]);
|
||||
|
||||
if (customerResult.rows.length === 0) {
|
||||
return res.status(404).404.json({ success: false, message: '客户不存在' });
|
||||
}
|
||||
|
||||
const customer = customerResult.rows[0];
|
||||
res.json({ success: true, data: customer });
|
||||
} catch (error) {
|
||||
console.error('获取客户详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取客户详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { name, contact_person, contact_phone, address } = req.body;
|
||||
|
||||
if (!name) {
|
||||
return res.status(400).json({ success: false, message: '客户名称为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO customers (name, contact_person, contact_phone, address, created_at, updated_at) VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[name, contact_person || '', contact_phone || '', address || '']
|
||||
);
|
||||
|
||||
const newCustomerResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM customers WHERE id = ?', [result.lastID]);
|
||||
const newCustomer = newCustomerResult.rows[0];
|
||||
|
||||
console.log(`客户 ${name} 创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newCustomer });
|
||||
} catch (error) {
|
||||
console.error('创建客户失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建客户失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, contact_person, contact_phone, address } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE customers SET name = ?, contact_person = ?, contact_phone = ?, address = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[name, contact_person, contact_phone, address, id]
|
||||
);
|
||||
|
||||
const updatedCustomerResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM customers WHERE id = ?', [id]);
|
||||
const updatedCustomer = updatedCustomerResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedCustomer });
|
||||
} catch (error) {
|
||||
console.error('更新客户信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新客户信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingCustomer = await db.query('SELECT id FROM customers WHERE id = ?', [id]);
|
||||
if (existingCustomer.rows.length === 0) {
|
||||
return res.status(404).404.json({ success: false, message: '客户不存在' });
|
||||
});
|
||||
|
||||
await db.query('DELETE FROM customers WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '客户删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除客户失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除客户失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/customers', router);
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/latest', authenticate, async (req, res) => {
|
||||
try {
|
||||
const latestRateResult = await db.query('SELECT currency, rate, updated_at FROM exchange_rates ORDER BY updated_at DESC LIMIT 1');
|
||||
const latestRate = latestRateResult.rows[0];
|
||||
res.json({ success: true, data: latestRate });
|
||||
} catch (error) {
|
||||
console.error('获取最新汇率失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取最新汇率失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const ratesResult = await db.query('SELECT id, currency, rate, updated_at FROM exchange_rates ORDER BY updated_at DESC');
|
||||
const rates = ratesResult.rows;
|
||||
res.json({ success: true, data: rates, count: rates.length });
|
||||
} catch (error) {
|
||||
console.error('获取汇率列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取汇率列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/history', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { currency, startDate, endDate } = req.query;
|
||||
let query = 'SELECT id, currency, rate, updated_at FROM exchange_rates';
|
||||
const params = [];
|
||||
|
||||
if (currency) {
|
||||
query += ' WHERE currency = ?';
|
||||
params.push(currency);
|
||||
}
|
||||
|
||||
if (startDate) {
|
||||
query += (params.length > 0 ? ' AND' : ' WHERE') + ' updated_at >= ?';
|
||||
params.push(startDate);
|
||||
}
|
||||
|
||||
if (endDate) {
|
||||
query query += ' AND updated_at <= ?';
|
||||
params.push(endDate);
|
||||
}
|
||||
|
||||
query += ' ORDER BY updated_at DESC';
|
||||
|
||||
const historyResult = await db.query(query, params);
|
||||
const history = historyResult.rows;
|
||||
res.json({ success: true, data: history, count: history.length });
|
||||
} catch (error) {
|
||||
console.error('获取汇率历史失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取汇率历史失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { currency, rate } = req.body;
|
||||
|
||||
if (!currency || !rate) {
|
||||
return res.status(400).json({ success: false, message: '货币和汇率为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO exchange_rates (currency, rate, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP)',
|
||||
[currency, rate]
|
||||
);
|
||||
|
||||
const newRateResult = await db.query('SELECT id, currency, rate, updated_at FROM exchange_rates WHERE id = ?', [result.lastID]);
|
||||
const newRate = newRateResult.rows[0];
|
||||
|
||||
console.log(`汇率 ${currency} = ${rate} 更新成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newRate });
|
||||
} catch (error) {
|
||||
console.error('更新汇率失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新汇率失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/exchange-rates', router);
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { status } = req.query;
|
||||
let query = 'SELECT id, user_id, project_id, amount, description, status, created_at,
|
||||
updated_at FROM executions';
|
||||
const params = [];
|
||||
|
||||
if (status) {
|
||||
query += ' WHERE status = ?';
|
||||
params.push(status);
|
||||
}
|
||||
|
||||
query += ' ORDER BY created_at DESC';
|
||||
|
||||
const executionsResult = await db.query(query, params);
|
||||
const executions = executionsResult.rows;
|
||||
res.json({ success: true, data: executions, count: executions.length });
|
||||
} catch (error) {
|
||||
console.error('获取执行列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取执行列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/pending', authenticate, async (req, res) => {
|
||||
try {
|
||||
const pendingResult = await db.query(
|
||||
'SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM executions WHERE status = ? ORDER BY created_at DESC',
|
||||
['pending']
|
||||
);
|
||||
const pending = pendingResult.rows;
|
||||
res.json({ success: true, data: pending, count: pending.length });
|
||||
} catch (error) {
|
||||
console.error('获取待执行列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取待执行列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/executed', authenticate, async (req, res) => {
|
||||
try {
|
||||
const executedResult = await db.query(
|
||||
'SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM executions WHERE status = ? ORDER BY created_at DESC',
|
||||
['executed']
|
||||
);
|
||||
const executed = executedResult.rows;
|
||||
res.json({ success: true, data: executed, count: executed.length });
|
||||
} catch (error) {
|
||||
console.error('获取已执行列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取已执行列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { user_id, project_id, amount, description } = req.body;
|
||||
|
||||
if (!user_id || !project_id || !amount) {
|
||||
return res.status(400).json({ success: false,
|
||||
message: '用户ID、项目ID和金额为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO executions (user_id, project_id, amount, description, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[user_id, project_id, amount, description || '', 'pending']
|
||||
);
|
||||
|
||||
const newExecutionResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM executions WHERE id = ?', [result.lastID]);
|
||||
const newExecution = newExecutionResult.rows[0];
|
||||
|
||||
console.log(`执行创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newExecution });
|
||||
} catch (error) {
|
||||
console.error('创建执行失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建执行失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/executions', router);
|
||||
};
|
||||
@@ -0,0 +1,118 @@
|
||||
const express = require('express');
|
||||
const { body, validationResult } = require('express-validator');
|
||||
const db = require('../db-sqlite');
|
||||
const { hashPassword, verifyPassword, generateToken, verifyToken } = require('../utils/auth');
|
||||
const { authenticate, optionalAuth, requireRole, requireAdmin } = require('../middleware/auth');
|
||||
|
||||
const validate = (req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
errors: errors.array()
|
||||
});
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/login', async (req, res) => {
|
||||
try {
|
||||
const { username, password } = req.body;
|
||||
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '用户名和密码不能为空'
|
||||
});
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'SELECT id, username, name, email, phone, role, password_hash FROM users WHERE username = ?',
|
||||
[username]
|
||||
);
|
||||
|
||||
if (!result || result.rows.length === 0) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '用户名或密码错误'
|
||||
});
|
||||
}
|
||||
|
||||
const user = result.rows[0];
|
||||
|
||||
let isValidPassword = false;
|
||||
if (user.password_hash) {
|
||||
isValidPassword = verifyPassword(password, user.password_hash);
|
||||
} else {
|
||||
isValidPassword = (user.password === password);
|
||||
}
|
||||
|
||||
if (!isValidPassword) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
message: '用户名或密码错误'
|
||||
});
|
||||
}
|
||||
|
||||
const token = generateToken(user);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
token,
|
||||
user: {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
phone: user.phone,
|
||||
role: user.role
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('登录失败:', error);
|
||||
res.status(500).json({ success: false, message: '登录失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/verify', authenticate, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
|
||||
if (!user) {
|
||||
return res.status(401).json({ success: false, message: '未授权' });
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
user: {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
phone: user.phone,
|
||||
role: user.role
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('验证失败:', error);
|
||||
res.status(500).json({ success: false, message: '验证失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/logout', authenticate, async (req, res) => {
|
||||
try {
|
||||
res.json({
|
||||
success: true,
|
||||
message: '登出成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('登出失败:', error);
|
||||
res.status(500).json({ success: false, message: '登出失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/auth', router);
|
||||
};
|
||||
@@ -0,0 +1,191 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { status } = req.query;
|
||||
let query = 'SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests';
|
||||
const params = [];
|
||||
|
||||
if (status) {
|
||||
query += ' WHERE status = ?';
|
||||
params.push(status);
|
||||
}
|
||||
|
||||
query += ' ORDER BY created_at DESC';
|
||||
|
||||
const paymentsResult = await db.query(query, params);
|
||||
const payments = paymentsResult.rows;
|
||||
res.json({ success: true, data: payments, count: payments.length });
|
||||
} catch (error) {
|
||||
console.error('获取付款请求列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取付款请求列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const paymentResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests WHERE id = ?', [id]);
|
||||
|
||||
if (paymentResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '付款请求不存在' });
|
||||
}
|
||||
|
||||
const payment = paymentResult.rows[0];
|
||||
res.json({ success: true, data: payment });
|
||||
} catch (error) {
|
||||
console.error('获取付款请求详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取付款请求详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { user_id, project_id, amount, description } = req.body;
|
||||
|
||||
if (!user_id || !project_id || !amount) {
|
||||
return res.status(400).json({ success: false,
|
||||
message: '用户ID、项目ID和金额为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO payment_requests (user_id, project_id, amount, description, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[user_id, project_id, amount, description || '', 'pending']
|
||||
);
|
||||
|
||||
const newPaymentResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests WHERE id = ?', [result.lastID]);
|
||||
const newPayment = newPaymentResult.rows[0];
|
||||
|
||||
console.log(`付款请求创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newPayment });
|
||||
} catch (error) {
|
||||
console.error('创建付款请求失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建付款请求失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { amount, description } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE payment_requests SET amount = ?, description = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[amount, description, id]
|
||||
);
|
||||
|
||||
const updatedPaymentResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests WHERE id = ?', [id]);
|
||||
const updatedPayment = updatedPaymentResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedPayment });
|
||||
} catch (error) {
|
||||
console.error('更新付款请求信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新付款请求信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingPayment = await db.query('SELECT id FROM payment_requests WHERE id = ?', [id]);
|
||||
if (existingPayment.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '付款请求不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM payment_requests WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '付款请求删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除付款请求失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除付款请求失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/submit', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE payment_requests SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['submitted', id]
|
||||
);
|
||||
|
||||
const updatedPaymentResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests WHERE id = ?', [id]);
|
||||
const updatedPayment = updatedPaymentResult.rows[0];
|
||||
|
||||
console.log(`付款请求 ${id} 提交成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedPayment });
|
||||
} catch (error) {
|
||||
console.error('提交付款请求失败:', error);
|
||||
res.status(500).json({ success: false, message: '提交付款请求失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/withdraw', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE payment_requests SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['pending', id]
|
||||
);
|
||||
|
||||
const updatedPaymentResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests WHERE id = ?', [id]);
|
||||
const updatedPayment = updatedPaymentResult.rows[0];
|
||||
|
||||
console.log(`付款请求 ${id} 撤回成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedPayment, message: '付款请求已撤回' });
|
||||
} catch (error) {
|
||||
console.error('撤回付款请求失败:', error);
|
||||
res.status(500).json({ success: false, message: '撤回付款请求失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/approve', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE payment_requests SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['approved', id]
|
||||
);
|
||||
|
||||
const updatedPaymentResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests WHERE id = ?', [id]);
|
||||
const updatedPayment = updatedPaymentResult.rows[0];
|
||||
|
||||
console.log(`付款请求 ${id} 审批通过成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedPayment });
|
||||
} catch (error) {
|
||||
console.error('审批通过付款请求失败:', error);
|
||||
res.status(500).json({ success: false, message: '审批通过付款请求失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/reject', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE payment_requests SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['rejected', id]
|
||||
);
|
||||
|
||||
const updatedPaymentResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM payment_requests WHERE id = ?', [id]);
|
||||
const updatedPayment = updatedPaymentResult.rows[0];
|
||||
|
||||
console.log(`付款请求 ${id} 审批拒绝成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedPayment });
|
||||
} catch (error) {
|
||||
console.error('审批拒绝付款请求失败:', error);
|
||||
res.status(500).json({ success: false, message: '审批拒绝付款请求失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/payment-requests', router);
|
||||
};
|
||||
@@ -0,0 +1,111 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const productsResult = await db.query('SELECT id, name, category_id, unit, price, stock, min_stock, created_at, updated_at FROM products');
|
||||
const products = productsResult.rows;
|
||||
res.json({ success: true, data: products, count: products.length });
|
||||
} catch (error) {
|
||||
console.error('获取商品列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取商品列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/template', authenticate, async (req, res) => {
|
||||
try {
|
||||
const templateResult = await db.query('SELECT id, name, category_id, unit, price, stock, min_stock, created_at, updated_at FROM products WHERE id = 1');
|
||||
const template = templateResult.rows[0];
|
||||
res.json({ success: true, data: template });
|
||||
} catch (error) {
|
||||
console.error('获取商品模板失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取商品模板失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const productResult = await db.query('SELECT id, name, category_id, unit, price, stock, min_stock, created_at, updated_at FROM products WHERE id = ?', [id]);
|
||||
|
||||
if (productResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '商品不存在' });
|
||||
}
|
||||
|
||||
const product = productResult.rows[0];
|
||||
res.json({ success: true, data: product });
|
||||
} catch (error) {
|
||||
console.error('获取商品详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取商品详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { name, category_id, unit, price, stock, min_stock } = req.body;
|
||||
|
||||
if (!name) {
|
||||
return res.status(400).json({ success: false, message: '商品名称为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO products (name, category_id, unit, price, stock, min_stock,
|
||||
created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[name, category_id, unit, price, stock, min_stock]
|
||||
);
|
||||
|
||||
const newProductResult = await db.query('SELECT id, name, category_id, unit, price, stock, min_stock, created_at, updated_at FROM products WHERE id = ?', [result.lastID]);
|
||||
const newProduct = newProductResult.rows[0];
|
||||
|
||||
console.log(`商品 ${name} 创建成功后端,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newProduct });
|
||||
} catch (error) {
|
||||
console.error('创建商品失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建商品失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, category_id, unit, price, stock, min_stock } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE products SET name = ?, category_id = ?, unit = ?, price = ?, stock = ?, min_stock = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[name, category_id, unit, price, stock, min_stock, id]
|
||||
);
|
||||
|
||||
const updatedProductResult = await db.query('SELECT id, name, category_id, unit, price, stock, min_stock, created_at, updated_at FROM products WHERE id = ?', [id]);
|
||||
const updatedProduct = updatedProductResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedProduct });
|
||||
} catch (error) {
|
||||
console.error('更新商品信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新商品信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingProduct = await db.query('SELECT id FROM products WHERE id = ?', [id]);
|
||||
if (existingProduct.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '商品不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM products WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '商品删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除商品失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除商品失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/products', router);
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const projectsResult = await db.query('SELECT id, name, contract_amount, status, created_at, updated_at FROM projects');
|
||||
const projects = projectsResult.rows;
|
||||
res.json({ success: true, data: projects, count: projects.length });
|
||||
} catch (error) {
|
||||
console.error('获取项目列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取项目列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const projectResult = await db.query('SELECT id, name, contract_amount, status, created_at, updated_at FROM projects WHERE id = ?', [id]);
|
||||
|
||||
if (projectResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '项目不存在' });
|
||||
}
|
||||
|
||||
const project = projectResult.rows[0];
|
||||
res.json({ success: true, data: project });
|
||||
} catch (error) {
|
||||
console.error('获取项目详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取项目详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingProject = await db.query('SELECT id FROM projects WHERE id = ?', [id]);
|
||||
if (existingProject.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '项目不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM projects WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '项目删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除项目失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除项目失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, contract_amount, status } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE projects SET name = ?, contract_amount = ?, status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[name, contract_amount, status, id]
|
||||
);
|
||||
|
||||
const updatedProjectResult = await db.query('SELECT id, name, contract_amount, status, created_at, updated_at FROM projects WHERE id = ?', [id]);
|
||||
const updatedProject = updatedProjectResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedProject });
|
||||
} catch (error) {
|
||||
console.error('更新项目信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新项目信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id/contract', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { contract_amount } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE projects SET contract_amount = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[contract_amount, id]
|
||||
);
|
||||
|
||||
const updatedProjectResult = await db.query('SELECT id, name, contract_amount, status, created_at, updated_at FROM projects WHERE id = ?', [id]);
|
||||
const updatedProject = updatedProjectResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedProject });
|
||||
} catch (error) {
|
||||
console.error('更新项目合同失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新项目合同失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/projects', router);
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const reimbursementsResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM reimbursements');
|
||||
const reimbursements = reimbursementsResult.rows;
|
||||
res.json({ success: true, data: reimbursements, count: reimbursements.length });
|
||||
} catch (error) {
|
||||
console.error('获取报销列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取报销列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const reimbursementResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM reimbursements WHERE id = ?', [id]);
|
||||
|
||||
if (reimbursementResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '报销不存在' });
|
||||
}
|
||||
|
||||
const reimbursement = reimbursementResult.rows[0];
|
||||
res.json({ success: true, data: reimbursement });
|
||||
} catch (error) {
|
||||
console.error('获取报销详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取报销详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { user_id, project_id, amount, description } = req.body;
|
||||
|
||||
if (!user_id || !project_id || !amount) {
|
||||
return res.status(400).json({ success: false,
|
||||
message: '用户ID、项目ID和金额为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO reimbursements (user_id, project_id, amount, description, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[user_id, project_id, amount, description || '', 'pending']
|
||||
);
|
||||
|
||||
const newReimbursementResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM reimbursements WHERE id = ?', [result.lastID]);
|
||||
const newReimbursement = newReimbursementResult.rows[0];
|
||||
|
||||
console.log(`报销创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newReimbursement });
|
||||
} catch (error) {
|
||||
console.error('创建报销失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建报销失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/reimbursements', router);
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const subcontractorsResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM subcontractors');
|
||||
const subcontractors = subcontractorsResult.rows;
|
||||
res.json({ success: true, data: subcontractors, count: subcontractors.length });
|
||||
} catch (error) {
|
||||
console.error('获取子承包商列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取子承包商列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const subcontractorResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM subcontractors WHERE id = ?', [id]);
|
||||
|
||||
if (subcontractorResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '子承包商不存在' });
|
||||
}
|
||||
|
||||
const subcontractor = subcontractorResult.rows[0];
|
||||
res.json({ success: true, data: subcontractor });
|
||||
} catch (error) {
|
||||
console.error('获取子承包商详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取子承包商详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { name, contact_person, contact_phone, address } = req.body;
|
||||
|
||||
if (!name) {
|
||||
return res.status(400).json({ success: false, message: '子承包商名称为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO subcontractors (name, contact_person, contact_phone, address, created_at, updated_at) VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[name, contact_person || '', contact_phone || '', address || '']
|
||||
);
|
||||
|
||||
const newSubcontractorResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM subcontractors WHERE id = ?', [result.lastID]);
|
||||
const newSubcontractor = newSubcontractorResult.rows[0];
|
||||
|
||||
console.log(`子承包商 ${name} 创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newSubcontractor });
|
||||
} catch (error) {
|
||||
console.error('创建子承包商失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建子承包商失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, contact_person, contact_phone, address } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE subcontractors SET name = ?, contact_person = ?, contact_phone = ?, address = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[name, contact_person, contact_phone, address, id]
|
||||
);
|
||||
|
||||
const updatedSubcontractorResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM subcontractors WHERE id = ?', [id]);
|
||||
const updatedSubcontractor = updatedSubcontractorResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedSubcontractor });
|
||||
} catch (error) {
|
||||
console.error('更新子承包商信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新子承包商信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingSubcontractor = await db.query('SELECT id FROM subcontractors WHERE id = ?', [id]);
|
||||
if (existingSubcontractor.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '子承包商不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM subcontractors WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '子承包商删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除子承包商失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除子承包商失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/subcontractors', router);
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const suppliersResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM suppliers');
|
||||
const suppliers = suppliersResult.rows;
|
||||
res.json({ success: true, data: suppliers, count: suppliers.length });
|
||||
} catch (error) {
|
||||
console.error('获取供应商列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取供应商列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const supplierResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM suppliers WHERE id = ?', [id]);
|
||||
|
||||
if (supplierResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '供应商不存在' });
|
||||
}
|
||||
|
||||
const supplier = supplierResult.rows[0];
|
||||
res.json({ success: true, data: supplier });
|
||||
} catch (error) {
|
||||
console.error('获取供应商详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取供应商详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { name, contact_person, contact_phone, address } = req.body;
|
||||
|
||||
if (!name) {
|
||||
return res.status(400).json({ success: false, message: '供应商名称为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO suppliers (name, contact_person, contact_phone, address, created_at, updated_at) VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[name, contact_person || '', contact_phone || '', address || '']
|
||||
);
|
||||
|
||||
const newSupplierResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM suppliers WHERE id = ?', [result.lastID]);
|
||||
const newSupplier = newSupplierResult.rows[0];
|
||||
|
||||
console.log(`供应商 ${name} 创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newSupplier });
|
||||
} catch (error) {
|
||||
console.error(''创建供应商失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建供应商失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, contact_person, contact_phone, address } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE suppliers SET name = ?, contact_person = ?, contact_phone = ?, address = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[name, contact_person, contact_phone, address, id]
|
||||
);
|
||||
|
||||
const updatedSupplierResult = await db.query('SELECT id, name, contact_person, contact_phone, address, created_at, updated_at FROM suppliers WHERE id = ?', [id]);
|
||||
const updatedSupplier = updatedSupplierResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedSupplier });
|
||||
} catch (error) {
|
||||
console.error('更新供应商信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新供应商信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingSupplier = await db.query('SELECT id FROM suppliers WHERE id = ?', [id]);
|
||||
if (existingSupplier.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '供应商不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM suppliers WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '供应商删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除供应商失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除供应商失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/suppliers', router);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
const multer = require('multer');
|
||||
|
||||
const upload = multer({ dest: 'uploads/' });
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/single', authenticate, upload.single('file'), async (req, res) => {
|
||||
try {
|
||||
if (!req.file) {
|
||||
return res.status(400).json({ success: false, message: '没有上传文件' });
|
||||
}
|
||||
|
||||
const fileUrl = `/uploads/${req.file.filename}`;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '文件上传成功',
|
||||
data: {
|
||||
filename: req.file.filename,
|
||||
url: fileUrl,
|
||||
size: req.file.size
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`文件 ${req.file.filename} 上传成功,由 ${req.user.username} 操作`);
|
||||
} catch (error) {
|
||||
console.error('文件上传失败:', error);
|
||||
res.status(500).json({ success: false, message: '文件上传失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/upload', router);
|
||||
};
|
||||
@@ -0,0 +1,148 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { hashPassword, verifyPassword } = require('../utils/auth');
|
||||
const { authenticate, requireAdmin } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const usersResult = await db.query('SELECT id, username, name, email, phone, role, created_at, updated_at FROM users');
|
||||
const users = usersResult.rows;
|
||||
res.json({ success: true, data: users, count: users.length });
|
||||
} catch (error) {
|
||||
console.error('获取用户列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取用户列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const userResult = await db.query('SELECT id, username, name, email, phone, role, created_at, updated_at FROM users WHERE id = ?', [id]);
|
||||
|
||||
if (userResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '用户不存在' });
|
||||
}
|
||||
|
||||
const user = userResult.rows[0];
|
||||
res.json({ success: true, data: user });
|
||||
} catch (error) {
|
||||
console.error('获取用户详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取用户详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, email, phone, role } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE users SET name = ?, email = ?, phone = ?, role = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[name, email, phone, role, id]
|
||||
);
|
||||
|
||||
const updatedUserResult = await db.query('SELECT id, username, name, email, phone, role, created_at, updated_at FROM users WHERE id = ?', [id]);
|
||||
const updatedUser = updatedUserResult.rows[0];
|
||||
res.json({ success: true, data: updatedUser });
|
||||
} catch (error) {
|
||||
console.error('更新用户信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新用户信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id/password', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { currentPassword, newPassword } = req.body;
|
||||
|
||||
if (req.user.id !== parseInt(id) && req.user.role !== 'admin') {
|
||||
return res.status(403).json({ success: false, message: '只能修改自己的密码' });
|
||||
}
|
||||
|
||||
const userResult = await db.query('SELECT password, password_hash FROM users WHERE id = ?', [id]);
|
||||
if (userResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '用户不存在' });
|
||||
}
|
||||
|
||||
const user = userResult.rows[0];
|
||||
|
||||
let isValidPassword = false;
|
||||
if (user.password_hash) {
|
||||
isValidPassword = verifyPassword(currentPassword, user.password_hash);
|
||||
} else {
|
||||
isValidPassword = (user.password === currentPassword);
|
||||
}
|
||||
|
||||
if (!isValidPassword) {
|
||||
return res.status(400).json({ success: false, message: '当前密码错误' });
|
||||
}
|
||||
|
||||
const newPasswordHash = hashPassword(newPassword);
|
||||
|
||||
await db.query(
|
||||
'UPDATE users SET password = ?, password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[newPassword, newPasswordHash, id]
|
||||
);
|
||||
|
||||
console.log(`用户 ID ${id} 密码已更新`);
|
||||
res.json({ success: true, message: '密码更新成功' });
|
||||
} catch (error) {
|
||||
console.error('更新密码失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新密码失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { username, name, email, phone, role, password } = req.body;
|
||||
|
||||
if (!username || !name || !password) {
|
||||
return res.status(400).json({ success: false, message: '用户名、姓名和密码为必填项' });
|
||||
}
|
||||
|
||||
const existingUser = await db.query('SELECT id FROM users WHERE username = ?', [username]);
|
||||
if (existingUser.rows.length > 0) {
|
||||
return res.status(400).json({ success: false, message: '用户名已存在' });
|
||||
}
|
||||
|
||||
const passwordHash = hashPassword(password);
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO users (username, password, password_hash, name, email, phone, role, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[username, password, passwordHash, name, email || '', phone || '', role || 'user']
|
||||
);
|
||||
|
||||
const newUserResult = await db.query('SELECT id, username, name, email, phone, role, created_at, updated_at FROM users WHERE id = ?', [result.lastID]);
|
||||
const newUser = newUserResult.rows[0];
|
||||
|
||||
console.log(`用户 ${username} 创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newUser });
|
||||
} catch (error) {
|
||||
console.error('创建用户失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建用户失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingUser = await db.query('SELECT id FROM users WHERE id = ?', [id]);
|
||||
if (existingUser.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '用户不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM users WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '用户删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除用户失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除用户失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/users', router);
|
||||
};
|
||||
@@ -0,0 +1,191 @@
|
||||
const express = require('express');
|
||||
const db = require('../db-sqlite');
|
||||
const { authenticate } = require('../middleware/auth');
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { status } = req.query;
|
||||
let query = 'SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications';
|
||||
const params = [];
|
||||
|
||||
if (status) {
|
||||
query += ' WHERE status = ?';
|
||||
params.push(status);
|
||||
}
|
||||
|
||||
query += ' ORDER BY created_at DESC';
|
||||
|
||||
const verificationsResult = await db.query(query, params);
|
||||
const verifications = verificationsResult.rows;
|
||||
res.json({ success: true, data: verifications, count: verifications.length });
|
||||
} catch (error) {
|
||||
console.error('获取核销列表失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取核销列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const verificationResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications WHERE id = ?', [id]);
|
||||
|
||||
if (verificationResult.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '核销不存在' });
|
||||
}
|
||||
|
||||
const verification = verificationResult.rows[0];
|
||||
res.json({ success: true, data: verification });
|
||||
} catch (error) {
|
||||
console.error('获取核销详情失败:', error);
|
||||
res.status(500).json({ success: false, message: '获取核销详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { user_id, project_id, amount, description } = req.body;
|
||||
|
||||
if (!user_id || !project_id || !amount) {
|
||||
return res.status(400).json({ success: false,
|
||||
message: '用户ID、项目ID和金额为必填项' });
|
||||
}
|
||||
|
||||
const result = await db.query(
|
||||
'INSERT INTO verifications (user_id, project_id, amount, description, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)',
|
||||
[user_id, project_id, amount, description || '', 'pending']
|
||||
);
|
||||
|
||||
const newVerificationResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications WHERE id = ?', [result.lastID]);
|
||||
const newVerification = newVerificationResult.rows[0];
|
||||
|
||||
console.log(`核销创建成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: newVerification });
|
||||
} catch (error) {
|
||||
console.error('创建核销失败:', error);
|
||||
res.status(500).json({ success: false, message: '创建核销失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { amount, description } = req.body;
|
||||
|
||||
await db.query(
|
||||
'UPDATE verifications SET amount = ?, description = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[amount, description, id]
|
||||
);
|
||||
|
||||
const updatedVerificationResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications WHERE id = ?', [id]);
|
||||
const updatedVerification = updatedVerificationResult.rows[0];
|
||||
|
||||
res.json({ success: true, data: updatedVerification });
|
||||
} catch (error) {
|
||||
console.error('更新核销信息失败:', error);
|
||||
res.status(500).json({ success: false, message: '更新核销信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:id', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const existingVerification = await db.query('SELECT id FROM verifications WHERE id = ?', [id]);
|
||||
if (existingVerification.rows.length === 0) {
|
||||
return res.status(404).json({ success: false, message: '核销不存在' });
|
||||
}
|
||||
|
||||
await db.query('DELETE FROM verifications WHERE id = ?', [id]);
|
||||
|
||||
res.json({ success: true, message: '核销删除成功' });
|
||||
} catch (error) {
|
||||
console.error('删除核销失败:', error);
|
||||
res.status(500).json({ success: false, message: '删除核销失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/submit', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE verifications SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['submitted', id]
|
||||
);
|
||||
|
||||
const updatedVerificationResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications WHERE id = ?', [id]);
|
||||
const updatedVerification = updatedVerificationResult.rows[0];
|
||||
|
||||
console.log(`核销 ${id} 提交成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedVerification });
|
||||
} catch (error) {
|
||||
console.error('提交核销失败:', error);
|
||||
res.status(500).json({ success: false, message: '提交核销失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/withdraw', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE verifications SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['pending', id]
|
||||
);
|
||||
|
||||
const updatedVerificationResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications WHERE id = ?', [id]);
|
||||
const updatedVerification = updatedVerificationResult.rows[0];
|
||||
|
||||
console.log(`核销 ${id} 撤回成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedVerification });
|
||||
} catch (error) {
|
||||
console.error('撤回核销失败:', error);
|
||||
res.status(500).json({ success: false, message: '撤回核销失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/approve', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE verifications SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['approved', id]
|
||||
);
|
||||
|
||||
const updatedVerificationResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications WHERE id = ?', [id]);
|
||||
const updatedVerification = updatedVerificationResult.rows[0];
|
||||
|
||||
console.log(`核销 ${id} 审批通过成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedVerification });
|
||||
} catch (error) {
|
||||
console.error('审批通过核销失败:', error);
|
||||
res.status(500).json({ success: false, message: '审批通过核销失败' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:id/reject', authenticate, async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
await db.query(
|
||||
'UPDATE verifications SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
['rejected', id]
|
||||
);
|
||||
|
||||
const updatedVerificationResult = await db.query('SELECT id, user_id, project_id, amount, description, status, created_at, updated_at FROM verifications WHERE id = ?', [id]);
|
||||
const updatedVerification = updatedVerificationResult.rows[0];
|
||||
|
||||
console.log(`核销 ${id} 审批拒绝成功,由 ${req.user.username} 操作`);
|
||||
res.json({ success: true, data: updatedVerification });
|
||||
} catch (error) {
|
||||
console.error('审批拒绝核销失败:', error);
|
||||
res.status(500).json({ success: false, message: '审批拒绝核销失败' });
|
||||
}
|
||||
});
|
||||
|
||||
app.use('/api/verifications', router);
|
||||
};
|
||||
Reference in New Issue
Block a user