添加银行端后端接口
This commit is contained in:
@@ -1,12 +1,390 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const Material = require('../models/Material');
|
||||
const WarehouseTransaction = require('../models/WarehouseTransaction');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
// 仓库物资列表
|
||||
router.get('/', (req, res) => {
|
||||
res.json({
|
||||
code: 200,
|
||||
data: []
|
||||
});
|
||||
// 仓库物资列表(支持分页、搜索和筛选)
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
keyword = '',
|
||||
category = '',
|
||||
status = '',
|
||||
page = 1,
|
||||
pageSize = 10
|
||||
} = req.query;
|
||||
|
||||
const where = {};
|
||||
|
||||
// 搜索条件
|
||||
if (keyword) {
|
||||
where[Op.or] = [
|
||||
{ code: { [Op.like]: `%${keyword}%` } },
|
||||
{ name: { [Op.like]: `%${keyword}%` } }
|
||||
];
|
||||
}
|
||||
|
||||
// 类别筛选
|
||||
if (category) {
|
||||
where.category = category;
|
||||
}
|
||||
|
||||
// 状态筛选
|
||||
if (status) {
|
||||
where.status = status;
|
||||
}
|
||||
|
||||
const offset = (parseInt(page) - 1) * parseInt(pageSize);
|
||||
const limit = parseInt(pageSize);
|
||||
|
||||
const { count, rows } = await Material.findAndCountAll({
|
||||
where,
|
||||
offset,
|
||||
limit,
|
||||
order: [['update_time', 'DESC']]
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
data: rows,
|
||||
total: count,
|
||||
page: parseInt(page),
|
||||
pageSize: limit,
|
||||
totalPages: Math.ceil(count / limit)
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取物资列表失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 获取单个物资详情
|
||||
router.get('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const material = await Material.findByPk(id);
|
||||
|
||||
if (!material) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '物资不存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
data: material
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取物资详情失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 创建新物资
|
||||
router.post('/', async (req, res) => {
|
||||
try {
|
||||
const { code, name, category, unit, stockQuantity, warningQuantity, supplier, remark } = req.body;
|
||||
|
||||
// 检查物资编号是否已存在
|
||||
const existingMaterial = await Material.findOne({ where: { code } });
|
||||
if (existingMaterial) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '物资编号已存在'
|
||||
});
|
||||
}
|
||||
|
||||
const material = await Material.create({
|
||||
code,
|
||||
name,
|
||||
category,
|
||||
unit,
|
||||
stockQuantity,
|
||||
warningQuantity,
|
||||
supplier,
|
||||
remark
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '创建物资成功',
|
||||
data: material
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '创建物资失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 更新物资信息
|
||||
router.put('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { code, name, category, unit, stockQuantity, warningQuantity, supplier, remark } = req.body;
|
||||
|
||||
const material = await Material.findByPk(id);
|
||||
if (!material) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '物资不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查物资编号是否已存在(排除当前物资)
|
||||
if (code && code !== material.code) {
|
||||
const existingMaterial = await Material.findOne({ where: { code } });
|
||||
if (existingMaterial) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '物资编号已存在'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await material.update({
|
||||
code,
|
||||
name,
|
||||
category,
|
||||
unit,
|
||||
stockQuantity,
|
||||
warningQuantity,
|
||||
supplier,
|
||||
remark
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '更新物资成功',
|
||||
data: material
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '更新物资失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 删除物资
|
||||
router.delete('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const material = await Material.findByPk(id);
|
||||
|
||||
if (!material) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '物资不存在'
|
||||
});
|
||||
}
|
||||
|
||||
await material.destroy();
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '删除物资成功'
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '删除物资失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 物资入库
|
||||
router.post('/in', async (req, res) => {
|
||||
try {
|
||||
const { materialId, quantity, operator, remark } = req.body;
|
||||
|
||||
// 开始事务
|
||||
const transaction = await Material.sequelize.transaction();
|
||||
|
||||
try {
|
||||
// 查找物资
|
||||
const material = await Material.findByPk(materialId, { transaction });
|
||||
if (!material) {
|
||||
await transaction.rollback();
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '物资不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 更新库存
|
||||
material.stockQuantity += parseInt(quantity);
|
||||
await material.save({ transaction });
|
||||
|
||||
// 记录入库记录
|
||||
await WarehouseTransaction.create({
|
||||
materialId,
|
||||
type: 'in',
|
||||
quantity,
|
||||
operator,
|
||||
remark
|
||||
}, { transaction });
|
||||
|
||||
// 提交事务
|
||||
await transaction.commit();
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '入库成功',
|
||||
data: {
|
||||
materialId,
|
||||
quantity,
|
||||
newStock: material.stockQuantity
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
// 回滚事务
|
||||
await transaction.rollback();
|
||||
throw err;
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '入库失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 物资出库
|
||||
router.post('/out', async (req, res) => {
|
||||
try {
|
||||
const { materialId, quantity, operator, remark } = req.body;
|
||||
|
||||
// 开始事务
|
||||
const transaction = await Material.sequelize.transaction();
|
||||
|
||||
try {
|
||||
// 查找物资
|
||||
const material = await Material.findByPk(materialId, { transaction });
|
||||
if (!material) {
|
||||
await transaction.rollback();
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '物资不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查库存是否足够
|
||||
if (material.stockQuantity < parseInt(quantity)) {
|
||||
await transaction.rollback();
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '库存不足'
|
||||
});
|
||||
}
|
||||
|
||||
// 更新库存
|
||||
material.stockQuantity -= parseInt(quantity);
|
||||
await material.save({ transaction });
|
||||
|
||||
// 记录出库记录
|
||||
await WarehouseTransaction.create({
|
||||
materialId,
|
||||
type: 'out',
|
||||
quantity,
|
||||
operator,
|
||||
remark
|
||||
}, { transaction });
|
||||
|
||||
// 提交事务
|
||||
await transaction.commit();
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '出库成功',
|
||||
data: {
|
||||
materialId,
|
||||
quantity,
|
||||
newStock: material.stockQuantity
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
// 回滚事务
|
||||
await transaction.rollback();
|
||||
throw err;
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '出库失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 获取库存统计信息
|
||||
router.get('/stats', async (req, res) => {
|
||||
try {
|
||||
// 统计总类别数
|
||||
const totalCategories = await Material.count({
|
||||
distinct: true,
|
||||
col: 'category'
|
||||
});
|
||||
|
||||
// 统计库存总量
|
||||
const totalQuantityResult = await Material.sum('stockQuantity');
|
||||
const totalQuantity = totalQuantityResult || 0;
|
||||
|
||||
// 统计低库存物资数
|
||||
const lowStockCount = await Material.count({
|
||||
where: {
|
||||
status: 'low'
|
||||
}
|
||||
});
|
||||
|
||||
// 统计缺货物资数
|
||||
const outOfStockCount = await Material.count({
|
||||
where: {
|
||||
status: 'out'
|
||||
}
|
||||
});
|
||||
|
||||
// 统计各类别物资数量
|
||||
const categoryStats = await Material.findAll({
|
||||
attributes: [
|
||||
'category',
|
||||
[Material.sequelize.fn('COUNT', Material.sequelize.col('id')), 'count'],
|
||||
[Material.sequelize.fn('SUM', Material.sequelize.col('stockQuantity')), 'totalQuantity']
|
||||
],
|
||||
group: ['category'],
|
||||
raw: true
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
data: {
|
||||
totalCategories,
|
||||
totalQuantity,
|
||||
lowStockCount,
|
||||
outOfStockCount,
|
||||
categoryStats
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取统计信息失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user