备份:修复前完整项目快照 2026-04-19

This commit is contained in:
root
2026-04-19 19:15:01 +08:00
parent 5266d7732b
commit d00f41a120
449 changed files with 89577 additions and 23251 deletions
+191
View File
@@ -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);
};
+79
View File
@@ -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);
};
+137
View File
@@ -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);
};
+99
View File
@@ -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);
};
+87
View File
@@ -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);
};
+85
View File
@@ -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);
};
+118
View File
@@ -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);
};
+191
View File
@@ -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);
};
+111
View File
@@ -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);
};
+95
View File
@@ -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);
};
+62
View File
@@ -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);
};
+99
View File
@@ -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);
};
+99
View File
@@ -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);
};
+37
View File
@@ -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);
};
+148
View File
@@ -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);
};
+191
View File
@@ -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);
};