修改小程序,前端,官网跳转路径
This commit is contained in:
@@ -50,6 +50,9 @@ app.use('/api/files', require('./routes/files'));
|
||||
app.use('/api/government', require('./routes/government'));
|
||||
app.use('/api/smart-earmark', require('./routes/smartEarmark'));
|
||||
app.use('/api/smart-host', require('./routes/smartHost'));
|
||||
app.use('/api/slaughter', require('./routes/slaughter'));
|
||||
app.use('/api/harmless', require('./routes/harmless'));
|
||||
app.use('/api/harmless-place', require('./routes/harmlessPlace'));
|
||||
|
||||
// 健康检查
|
||||
app.get('/health', (req, res) => {
|
||||
|
||||
77
government-backend/check-controller-model.js
Normal file
77
government-backend/check-controller-model.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// 清除模块缓存
|
||||
function clearModuleCache() {
|
||||
const modulesToClear = Object.keys(require.cache).filter(key =>
|
||||
key.includes('HarmlessPlace') || key.includes('database') || key.includes('controller')
|
||||
);
|
||||
|
||||
console.log('清除以下模块的缓存:', modulesToClear.length, '个模块');
|
||||
modulesToClear.forEach(key => {
|
||||
console.log('-', key);
|
||||
delete require.cache[key];
|
||||
});
|
||||
}
|
||||
|
||||
// 清除缓存后再导入
|
||||
clearModuleCache();
|
||||
|
||||
// 直接导入HarmlessPlace模型和控制器
|
||||
const HarmlessPlace = require('./models/HarmlessPlace');
|
||||
const harmlessPlaceController = require('./controllers/HarmlessPlaceController');
|
||||
|
||||
// 检查直接导入的HarmlessPlace模型
|
||||
console.log('=== 直接导入的HarmlessPlace模型 ===');
|
||||
console.log('类型:', typeof HarmlessPlace);
|
||||
console.log('是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
|
||||
if (HarmlessPlace.findAndCountAll) {
|
||||
console.log('findAndCountAll的类型:', typeof HarmlessPlace.findAndCountAll);
|
||||
}
|
||||
|
||||
// 检查控制器中的getList函数
|
||||
console.log('\n=== 检查控制器的getList函数 ===');
|
||||
console.log('getList的类型:', typeof harmlessPlaceController.getList);
|
||||
|
||||
// 分析控制器中如何使用HarmlessPlace模型
|
||||
// 我们需要查看控制器的源代码
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
console.log('\n=== 查看控制器的源代码 ===');
|
||||
const controllerPath = path.join(__dirname, 'controllers', 'HarmlessPlaceController.js');
|
||||
const controllerContent = fs.readFileSync(controllerPath, 'utf8');
|
||||
|
||||
// 查找导入语句
|
||||
const importStatementMatch = controllerContent.match(/require\(['"]\.\.?\/models\/[^'"]+['"]\)/g);
|
||||
console.log('控制器中的导入语句:', importStatementMatch || '未找到');
|
||||
|
||||
// 查找HarmlessPlace的使用
|
||||
const harmlessPlaceUsage = controllerContent.match(/HarmlessPlace\.\w+/g);
|
||||
console.log('控制器中HarmlessPlace的使用:', harmlessPlaceUsage || '未找到');
|
||||
|
||||
console.log('\n=== 检查控制器中实际使用的HarmlessPlace ===');
|
||||
// 创建一个模拟的req和res对象
|
||||
const mockReq = {
|
||||
query: {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
};
|
||||
|
||||
const mockRes = {
|
||||
json: function(data) {
|
||||
console.log('res.json被调用:', data);
|
||||
},
|
||||
status: function(code) {
|
||||
console.log('res.status被调用:', code);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// 尝试从控制器中获取实际使用的HarmlessPlace模型
|
||||
// 我们需要查看控制器的导入方式
|
||||
const controllerModule = require('./controllers/HarmlessPlaceController');
|
||||
|
||||
// 如果控制器导出了其使用的模型,我们可以检查
|
||||
// 但通常控制器不会导出这种依赖
|
||||
console.log('控制器模块导出:', Object.keys(controllerModule));
|
||||
|
||||
console.log('\n所有检查完成!');
|
||||
18
government-backend/check-export.js
Normal file
18
government-backend/check-export.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// 直接检查slaughter路由模块的导出内容
|
||||
const slaughterRoutes = require('./routes/slaughter');
|
||||
|
||||
console.log('模块类型:', typeof slaughterRoutes);
|
||||
console.log('是否为Express Router:', slaughterRoutes && slaughterRoutes.constructor && slaughterRoutes.constructor.name);
|
||||
console.log('是否有stack属性:', 'stack' in slaughterRoutes);
|
||||
|
||||
if (slaughterRoutes && slaughterRoutes.stack) {
|
||||
console.log('stack长度:', slaughterRoutes.stack.length);
|
||||
slaughterRoutes.stack.forEach((layer, index) => {
|
||||
console.log(`Layer ${index}:`, layer);
|
||||
});
|
||||
}
|
||||
|
||||
// 也检查另一个已知正常的路由模块,比如auth.js
|
||||
const authRoutes = require('./routes/auth');
|
||||
console.log('\nauth路由模块类型:', typeof authRoutes);
|
||||
console.log('auth路由模块构造函数:', authRoutes && authRoutes.constructor && authRoutes.constructor.name);
|
||||
31
government-backend/check-harmless-place-model.js
Normal file
31
government-backend/check-harmless-place-model.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// 测试HarmlessPlace模型的导出和方法
|
||||
const HarmlessPlace = require('./models/HarmlessPlace');
|
||||
const User = require('./models/User');
|
||||
|
||||
console.log('=== 检查HarmlessPlace模型 ===');
|
||||
console.log('HarmlessPlace的类型:', typeof HarmlessPlace);
|
||||
console.log('HarmlessPlace是否为对象:', typeof HarmlessPlace === 'object' && HarmlessPlace !== null);
|
||||
console.log('HarmlessPlace是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
|
||||
if (HarmlessPlace.findAndCountAll) {
|
||||
console.log('findAndCountAll的类型:', typeof HarmlessPlace.findAndCountAll);
|
||||
}
|
||||
console.log('\nHarmlessPlace对象的所有属性和方法:');
|
||||
console.log(Object.keys(HarmlessPlace));
|
||||
|
||||
console.log('\n=== 检查User模型(作为对比)===');
|
||||
console.log('User的类型:', typeof User);
|
||||
console.log('User是否为对象:', typeof User === 'object' && User !== null);
|
||||
console.log('User是否有findAndCountAll方法:', typeof User.findAndCountAll !== 'undefined');
|
||||
if (User.findAndCountAll) {
|
||||
console.log('findAndCountAll的类型:', typeof User.findAndCountAll);
|
||||
}
|
||||
console.log('\nUser对象的所有属性和方法:');
|
||||
console.log(Object.keys(User));
|
||||
|
||||
// 检查是否存在循环引用或其他问题
|
||||
console.log('\n=== 检查模型实例化 ===');
|
||||
try {
|
||||
console.log('尝试实例化HarmlessPlace:', new HarmlessPlace());
|
||||
} catch (error) {
|
||||
console.log('实例化HarmlessPlace错误:', error.message);
|
||||
}
|
||||
@@ -38,7 +38,10 @@ async function testConnection() {
|
||||
}
|
||||
}
|
||||
|
||||
// 导出连接测试函数,但不自动执行
|
||||
module.exports.testConnection = testConnection;
|
||||
// 先导出sequelize实例
|
||||
const db = sequelize;
|
||||
|
||||
module.exports = sequelize;
|
||||
// 再添加测试连接方法
|
||||
db.testConnection = testConnection;
|
||||
|
||||
module.exports = db;
|
||||
@@ -4,6 +4,7 @@ const DB_NAME = process.env.DB_NAME || 'ningxia_zhengfu';
|
||||
const DB_USER = process.env.DB_USER || 'root';
|
||||
const DB_PASSWORD = process.env.DB_PASSWORD || 'aiotAiot123!';
|
||||
const DB_DIALECT = process.env.DB_DIALECT || 'mysql';
|
||||
// const DB_HOST = process.env.DB_HOST || '129.211.213.226';
|
||||
|
||||
module.exports = {
|
||||
JWT_SECRET: 'your-secret-key-here', // 请在生产环境中替换为强密钥
|
||||
|
||||
199
government-backend/controllers/HarmlessPlaceController.js
Normal file
199
government-backend/controllers/HarmlessPlaceController.js
Normal file
@@ -0,0 +1,199 @@
|
||||
const { validationResult } = require('express-validator');
|
||||
const { Op } = require('sequelize');
|
||||
const HarmlessPlace = require('../models/HarmlessPlace');
|
||||
|
||||
// 获取无害化场所列表
|
||||
exports.getList = async (req, res) => {
|
||||
try {
|
||||
const { page = 1, pageSize = 10, keyword = '', status = '' } = req.query;
|
||||
const offset = (page - 1) * pageSize;
|
||||
|
||||
const where = {};
|
||||
|
||||
if (keyword) {
|
||||
where[Op.or] = [
|
||||
{ name: { [Op.like]: `%${keyword}%` } },
|
||||
{ licenseNumber: { [Op.like]: `%${keyword}%` } }
|
||||
];
|
||||
}
|
||||
|
||||
if (status) {
|
||||
where.status = status;
|
||||
}
|
||||
|
||||
// 移除排序部分,避免使用不存在的created_at字段
|
||||
const result = await HarmlessPlace.findAndCountAll({
|
||||
where,
|
||||
attributes: ['id', 'name', 'address', 'contactPerson', 'contactPhone', 'licenseNumber', 'status'],
|
||||
limit: parseInt(pageSize),
|
||||
offset: parseInt(offset)
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: {
|
||||
list: result.rows,
|
||||
total: result.count
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取无害化场所列表失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 获取无害化场所详情
|
||||
exports.getDetail = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const place = await HarmlessPlace.findByPk(id);
|
||||
|
||||
if (!place) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '无害化场所不存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: place
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取无害化场所详情失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 创建无害化场所
|
||||
exports.create = async (req, res) => {
|
||||
try {
|
||||
// 验证请求数据
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '参数错误',
|
||||
errors: errors.array()
|
||||
});
|
||||
}
|
||||
|
||||
const { name, address, contactPerson, contactPhone, licenseNumber, status } = req.body;
|
||||
|
||||
// 创建无害化场所
|
||||
const place = await HarmlessPlace.create({
|
||||
name,
|
||||
address,
|
||||
contactPerson,
|
||||
contactPhone,
|
||||
licenseNumber,
|
||||
status: status || '正常'
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '创建成功',
|
||||
data: place
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('创建无害化场所失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '创建失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 更新无害化场所
|
||||
exports.update = async (req, res) => {
|
||||
try {
|
||||
// 验证请求数据
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '参数错误',
|
||||
errors: errors.array()
|
||||
});
|
||||
}
|
||||
|
||||
const { id } = req.params;
|
||||
const { name, address, contactPerson, contactPhone, licenseNumber, status } = req.body;
|
||||
|
||||
// 查找无害化场所
|
||||
const place = await HarmlessPlace.findByPk(id);
|
||||
|
||||
if (!place) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '无害化场所不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 更新无害化场所
|
||||
await place.update({
|
||||
name,
|
||||
address,
|
||||
contactPerson,
|
||||
contactPhone,
|
||||
licenseNumber,
|
||||
status
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '更新成功',
|
||||
data: place
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新无害化场所失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '更新失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 删除无害化场所
|
||||
exports.delete = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
// 查找无害化场所
|
||||
const place = await HarmlessPlace.findByPk(id);
|
||||
|
||||
if (!place) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '无害化场所不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 删除无害化场所
|
||||
await place.destroy();
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '删除成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('删除无害化场所失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '删除失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
235
government-backend/controllers/HarmlessRegistrationController.js
Normal file
235
government-backend/controllers/HarmlessRegistrationController.js
Normal file
@@ -0,0 +1,235 @@
|
||||
const { validationResult } = require('express-validator');
|
||||
const { Op } = require('sequelize');
|
||||
const HarmlessRegistration = require('../models/HarmlessRegistration');
|
||||
|
||||
// 获取无害化登记列表
|
||||
exports.getList = async (req, res) => {
|
||||
try {
|
||||
const { page = 1, pageSize = 10, keyword = '', startDate = '', endDate = '' } = req.query;
|
||||
const offset = (page - 1) * pageSize;
|
||||
|
||||
const where = {};
|
||||
|
||||
if (keyword) {
|
||||
where.registrationNumber = { [Op.like]: `%${keyword}%` };
|
||||
}
|
||||
|
||||
if (startDate) {
|
||||
where.processingDate = where.processingDate || {};
|
||||
where.processingDate[Op.gte] = startDate;
|
||||
}
|
||||
|
||||
if (endDate) {
|
||||
where.processingDate = where.processingDate || {};
|
||||
where.processingDate[Op.lte] = endDate;
|
||||
}
|
||||
|
||||
const result = await HarmlessRegistration.findAndCountAll({
|
||||
where,
|
||||
limit: parseInt(pageSize),
|
||||
offset: parseInt(offset),
|
||||
order: [['createTime', 'DESC']]
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: {
|
||||
list: result.rows,
|
||||
total: result.count
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取无害化登记列表失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 获取无害化登记详情
|
||||
exports.getDetail = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const registration = await HarmlessRegistration.findByPk(id);
|
||||
|
||||
if (!registration) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '无害化登记不存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: registration
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取无害化登记详情失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 创建无害化登记
|
||||
exports.create = async (req, res) => {
|
||||
try {
|
||||
// 验证请求参数
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '参数验证失败',
|
||||
errors: errors.array()
|
||||
});
|
||||
}
|
||||
|
||||
const { registrationNumber, animalType, quantity, reason,
|
||||
processingMethod, processingPlace, processingDate, registrant, status } = req.body;
|
||||
|
||||
// 检查登记编号是否已存在
|
||||
const existingRegistration = await HarmlessRegistration.findOne({
|
||||
where: { registrationNumber }
|
||||
});
|
||||
|
||||
if (existingRegistration) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '登记编号已存在'
|
||||
});
|
||||
}
|
||||
|
||||
const registration = await HarmlessRegistration.create({
|
||||
registrationNumber,
|
||||
animalType,
|
||||
quantity: parseInt(quantity),
|
||||
reason,
|
||||
processingMethod,
|
||||
processingPlace,
|
||||
processingDate,
|
||||
registrant,
|
||||
status: status || '待处理',
|
||||
createTime: new Date(),
|
||||
updateTime: new Date()
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '创建成功',
|
||||
data: registration
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('创建无害化登记失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '创建失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 更新无害化登记
|
||||
exports.update = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const errors = validationResult(req);
|
||||
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '参数验证失败',
|
||||
errors: errors.array()
|
||||
});
|
||||
}
|
||||
|
||||
const registration = await HarmlessRegistration.findByPk(id);
|
||||
|
||||
if (!registration) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '无害化登记不存在'
|
||||
});
|
||||
}
|
||||
|
||||
const { registrationNumber, animalType, quantity, reason,
|
||||
processingMethod, processingPlace, processingDate, registrant, status } = req.body;
|
||||
|
||||
// 检查登记编号是否已被其他记录使用
|
||||
if (registrationNumber && registrationNumber !== registration.registrationNumber) {
|
||||
const existingRegistration = await HarmlessRegistration.findOne({
|
||||
where: {
|
||||
registrationNumber,
|
||||
id: { [Op.ne]: id }
|
||||
}
|
||||
});
|
||||
|
||||
if (existingRegistration) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '登记编号已存在'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await registration.update({
|
||||
registrationNumber: registrationNumber || registration.registrationNumber,
|
||||
animalType: animalType || registration.animalType,
|
||||
quantity: quantity !== undefined ? parseInt(quantity) : registration.quantity,
|
||||
reason: reason || registration.reason,
|
||||
processingMethod: processingMethod || registration.processingMethod,
|
||||
processingPlace: processingPlace || registration.processingPlace,
|
||||
processingDate: processingDate || registration.processingDate,
|
||||
registrant: registrant || registration.registrant,
|
||||
status: status !== undefined ? status : registration.status,
|
||||
updateTime: new Date()
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '更新成功',
|
||||
data: registration
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新无害化登记失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '更新失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 删除无害化登记
|
||||
exports.delete = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const registration = await HarmlessRegistration.findByPk(id);
|
||||
|
||||
if (!registration) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '无害化登记不存在'
|
||||
});
|
||||
}
|
||||
|
||||
await registration.destroy();
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '删除成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('删除无害化登记失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '删除失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
268
government-backend/controllers/SlaughterhouseController.js
Normal file
268
government-backend/controllers/SlaughterhouseController.js
Normal file
@@ -0,0 +1,268 @@
|
||||
const { Op } = require('sequelize');
|
||||
const Slaughterhouse = require('../models/Slaughterhouse');
|
||||
|
||||
// 查询屠宰场列表
|
||||
exports.getSlaughterhouses = async (req, res) => {
|
||||
try {
|
||||
const { keyword, status, page = 1, pageSize = 10 } = req.query;
|
||||
|
||||
const where = {};
|
||||
|
||||
if (keyword) {
|
||||
where[Op.or] = [
|
||||
{ name: { [Op.like]: `%${keyword}%` } },
|
||||
{ contactPerson: { [Op.like]: `%${keyword}%` } },
|
||||
{ contactPhone: { [Op.like]: `%${keyword}%` } },
|
||||
{ licenseNumber: { [Op.like]: `%${keyword}%` } }
|
||||
];
|
||||
}
|
||||
|
||||
if (status) {
|
||||
where.status = status;
|
||||
}
|
||||
|
||||
const { count, rows } = await Slaughterhouse.findAndCountAll({
|
||||
where,
|
||||
offset: (page - 1) * pageSize,
|
||||
limit: parseInt(pageSize),
|
||||
order: [['created_at', 'DESC']]
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
data: {
|
||||
list: rows,
|
||||
total: count,
|
||||
page: parseInt(page),
|
||||
pageSize: parseInt(pageSize)
|
||||
},
|
||||
message: '查询成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('查询屠宰场列表失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 查询单个屠宰场详情
|
||||
exports.getSlaughterhouseById = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const slaughterhouse = await Slaughterhouse.findByPk(id);
|
||||
|
||||
if (!slaughterhouse) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '屠宰场不存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
data: slaughterhouse,
|
||||
message: '查询成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('查询屠宰场详情失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 新增屠宰场
|
||||
exports.createSlaughterhouse = async (req, res) => {
|
||||
try {
|
||||
const { name, address, contactPerson, contactPhone, licenseNumber, status } = req.body;
|
||||
|
||||
// 检查名称是否重复
|
||||
const existingSlaughterhouse = await Slaughterhouse.findOne({
|
||||
where: { name }
|
||||
});
|
||||
|
||||
if (existingSlaughterhouse) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '该屠宰场名称已存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查许可证号是否重复
|
||||
const existingLicense = await Slaughterhouse.findOne({
|
||||
where: { licenseNumber }
|
||||
});
|
||||
|
||||
if (existingLicense) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '该许可证号已存在'
|
||||
});
|
||||
}
|
||||
|
||||
const slaughterhouse = await Slaughterhouse.create({
|
||||
name,
|
||||
address,
|
||||
contactPerson,
|
||||
contactPhone,
|
||||
licenseNumber,
|
||||
status,
|
||||
createTime: new Date(),
|
||||
created_by: req.user?.id || null,
|
||||
updated_by: req.user?.id || null
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 201,
|
||||
data: slaughterhouse,
|
||||
message: '新增成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('新增屠宰场失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 更新屠宰场
|
||||
exports.updateSlaughterhouse = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, address, contactPerson, contactPhone, licenseNumber, status } = req.body;
|
||||
|
||||
const slaughterhouse = await Slaughterhouse.findByPk(id);
|
||||
|
||||
if (!slaughterhouse) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '屠宰场不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查名称是否重复(排除当前屠宰场)
|
||||
if (name && name !== slaughterhouse.name) {
|
||||
const existingSlaughterhouse = await Slaughterhouse.findOne({
|
||||
where: {
|
||||
name,
|
||||
id: { [Op.ne]: id }
|
||||
}
|
||||
});
|
||||
|
||||
if (existingSlaughterhouse) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '该屠宰场名称已存在'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 检查许可证号是否重复(排除当前屠宰场)
|
||||
if (licenseNumber && licenseNumber !== slaughterhouse.licenseNumber) {
|
||||
const existingLicense = await Slaughterhouse.findOne({
|
||||
where: {
|
||||
licenseNumber,
|
||||
id: { [Op.ne]: id }
|
||||
}
|
||||
});
|
||||
|
||||
if (existingLicense) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '该许可证号已存在'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await slaughterhouse.update({
|
||||
name,
|
||||
address,
|
||||
contactPerson,
|
||||
contactPhone,
|
||||
licenseNumber,
|
||||
status,
|
||||
updated_by: req.user?.id || null
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
data: slaughterhouse,
|
||||
message: '更新成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新屠宰场失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 删除屠宰场
|
||||
exports.deleteSlaughterhouse = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const slaughterhouse = await Slaughterhouse.findByPk(id);
|
||||
|
||||
if (!slaughterhouse) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '屠宰场不存在'
|
||||
});
|
||||
}
|
||||
|
||||
await slaughterhouse.destroy();
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '删除成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('删除屠宰场失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 切换屠宰场状态
|
||||
exports.toggleSlaughterhouseStatus = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const slaughterhouse = await Slaughterhouse.findByPk(id);
|
||||
|
||||
if (!slaughterhouse) {
|
||||
return res.status(404).json({
|
||||
code: 404,
|
||||
message: '屠宰场不存在'
|
||||
});
|
||||
}
|
||||
|
||||
const newStatus = slaughterhouse.status === 'active' ? 'inactive' : 'active';
|
||||
|
||||
await slaughterhouse.update({
|
||||
status: newStatus,
|
||||
updated_by: req.user?.id || null
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
data: slaughterhouse,
|
||||
message: '状态切换成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('切换屠宰场状态失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误'
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
const EpidemicAgency = require('../models/EpidemicAgency');
|
||||
const { Op } = require('sequelize');
|
||||
const EpidemicAgency = require('../models/EpidemicAgency');
|
||||
|
||||
// 查询防疫机构列表
|
||||
exports.getEpidemicAgencies = async (req, res) => {
|
||||
@@ -28,7 +28,7 @@ exports.getEpidemicAgencies = async (req, res) => {
|
||||
where,
|
||||
offset: (page - 1) * pageSize,
|
||||
limit: parseInt(pageSize),
|
||||
order: [['created_at', 'DESC']]
|
||||
attributes: ['id', 'name', 'director', 'phone', 'address', 'email', 'type', 'status', 'establishmentDate', 'epidemicScope', 'description']
|
||||
});
|
||||
|
||||
res.json({
|
||||
@@ -81,7 +81,7 @@ exports.getEpidemicAgencyById = async (req, res) => {
|
||||
// 新增防疫机构
|
||||
exports.createEpidemicAgency = async (req, res) => {
|
||||
try {
|
||||
const { name, director, phone, address, email, type, status, establishmentDate, description } = req.body;
|
||||
const { name, director, phone, address, email, type, status, establishmentDate, epidemicScope, description } = req.body;
|
||||
|
||||
const existingAgency = await EpidemicAgency.findOne({
|
||||
where: { name }
|
||||
@@ -103,6 +103,7 @@ exports.createEpidemicAgency = async (req, res) => {
|
||||
type,
|
||||
status,
|
||||
establishmentDate,
|
||||
epidemicScope,
|
||||
description,
|
||||
created_by: req.user?.id || null,
|
||||
updated_by: req.user?.id || null
|
||||
@@ -126,7 +127,7 @@ exports.createEpidemicAgency = async (req, res) => {
|
||||
exports.updateEpidemicAgency = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { name, director, phone, address, email, type, status, establishmentDate, description } = req.body;
|
||||
const { name, director, phone, address, email, type, status, establishmentDate, epidemicScope, description } = req.body;
|
||||
|
||||
const agency = await EpidemicAgency.findByPk(id);
|
||||
|
||||
@@ -163,6 +164,7 @@ exports.updateEpidemicAgency = async (req, res) => {
|
||||
type,
|
||||
status,
|
||||
establishmentDate,
|
||||
epidemicScope,
|
||||
description,
|
||||
updated_by: req.user?.id || null
|
||||
});
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
const { promisify } = require('util');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const db = require('../config/database');
|
||||
const util = require('util');
|
||||
const User = require('../models/User');
|
||||
|
||||
// JWT配置
|
||||
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production';
|
||||
@@ -22,7 +20,7 @@ module.exports = async (req, res, next) => {
|
||||
if (token.startsWith('mock-jwt-token-')) {
|
||||
// 模拟用户数据,避免数据库查询
|
||||
req.user = {
|
||||
id: '1',
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
role: 'admin'
|
||||
};
|
||||
@@ -31,15 +29,18 @@ module.exports = async (req, res, next) => {
|
||||
}
|
||||
|
||||
// 验证token
|
||||
const decoded = await util.promisify(jwt.verify)(token, JWT_SECRET);
|
||||
const decoded = jwt.verify(token, JWT_SECRET);
|
||||
|
||||
// 检查用户是否存在
|
||||
const [user] = await db.query(
|
||||
'SELECT id, username, role FROM users WHERE id = ?',
|
||||
[decoded.id]
|
||||
);
|
||||
// 使用Sequelize模型检查用户是否存在
|
||||
const user = await User.findOne({
|
||||
where: {
|
||||
id: decoded.id,
|
||||
status: 'active'
|
||||
},
|
||||
attributes: ['id', 'username', 'role']
|
||||
});
|
||||
|
||||
if (!user || user.length === 0) {
|
||||
if (!user) {
|
||||
return res.status(401).json({
|
||||
code: 401,
|
||||
message: '用户不存在或已被删除'
|
||||
@@ -47,7 +48,7 @@ module.exports = async (req, res, next) => {
|
||||
}
|
||||
|
||||
// 将用户信息添加到请求对象
|
||||
req.user = user[0];
|
||||
req.user = user;
|
||||
next();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const sequelize = require('../config/database');
|
||||
const { DataTypes } = require('sequelize');
|
||||
const sequelize = require('../config/database.js');
|
||||
|
||||
const EpidemicAgency = sequelize.define('EpidemicAgency', {
|
||||
id: {
|
||||
@@ -49,6 +49,11 @@ const EpidemicAgency = sequelize.define('EpidemicAgency', {
|
||||
allowNull: false,
|
||||
comment: '成立日期'
|
||||
},
|
||||
epidemicScope: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: '防疫范围'
|
||||
},
|
||||
description: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
|
||||
67
government-backend/models/HarmlessPlace.js
Normal file
67
government-backend/models/HarmlessPlace.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const sequelize = require('../config/database');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
const HarmlessPlace = sequelize.define('HarmlessPlace', {
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
primaryKey: true,
|
||||
allowNull: false
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
comment: '场所名称'
|
||||
},
|
||||
address: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: false,
|
||||
comment: '地址'
|
||||
},
|
||||
contactPerson: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
comment: '联系人'
|
||||
},
|
||||
contactPhone: {
|
||||
type: DataTypes.STRING(20),
|
||||
allowNull: false,
|
||||
comment: '联系电话'
|
||||
},
|
||||
licenseNumber: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
comment: '许可证号'
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('正常', '维护中', '停用'),
|
||||
allowNull: false,
|
||||
defaultValue: '正常',
|
||||
comment: '状态'
|
||||
}
|
||||
}, {
|
||||
tableName: 'government_harmless_places',
|
||||
timestamps: true,
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at',
|
||||
paranoid: false,
|
||||
indexes: [
|
||||
{
|
||||
name: 'idx_name',
|
||||
fields: ['name']
|
||||
},
|
||||
{
|
||||
name: 'idx_status',
|
||||
fields: ['status']
|
||||
},
|
||||
{
|
||||
name: 'idx_license_number',
|
||||
fields: ['licenseNumber'],
|
||||
unique: true
|
||||
}
|
||||
],
|
||||
comment: '无害化场所管理表'
|
||||
});
|
||||
|
||||
module.exports = HarmlessPlace;
|
||||
85
government-backend/models/HarmlessRegistration.js
Normal file
85
government-backend/models/HarmlessRegistration.js
Normal file
@@ -0,0 +1,85 @@
|
||||
const { DataTypes, Sequelize } = require('sequelize');
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
const HarmlessRegistration = sequelize.define('HarmlessRegistration', {
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
primaryKey: true,
|
||||
allowNull: false
|
||||
},
|
||||
registrationNumber: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
comment: '登记编号'
|
||||
},
|
||||
animalType: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
comment: '动物类型'
|
||||
},
|
||||
quantity: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '数量',
|
||||
validate: {
|
||||
min: 1
|
||||
}
|
||||
},
|
||||
reason: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false,
|
||||
comment: '无害化处理原因'
|
||||
},
|
||||
processingMethod: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
comment: '处理方式'
|
||||
},
|
||||
processingPlace: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
comment: '处理场所'
|
||||
},
|
||||
processingDate: {
|
||||
type: DataTypes.DATEONLY,
|
||||
allowNull: false,
|
||||
comment: '处理日期'
|
||||
},
|
||||
registrant: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
comment: '登记人'
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('待处理', '处理中', '已完成', '已取消'),
|
||||
allowNull: false,
|
||||
defaultValue: '待处理',
|
||||
comment: '状态'
|
||||
},
|
||||
createTime: {
|
||||
type: DataTypes.DATE,
|
||||
defaultValue: Sequelize.fn('NOW'),
|
||||
allowNull: false,
|
||||
comment: '创建时间'
|
||||
},
|
||||
updateTime: {
|
||||
type: DataTypes.DATE,
|
||||
defaultValue: Sequelize.fn('NOW'),
|
||||
allowNull: false,
|
||||
comment: '更新时间'
|
||||
}
|
||||
}, {
|
||||
tableName: 'government_harmless_registrations',
|
||||
timestamps: false,
|
||||
indexes: [
|
||||
{ name: 'idx_registrationNumber', fields: ['registrationNumber'] },
|
||||
{ name: 'idx_status', fields: ['status'] },
|
||||
{ name: 'idx_processingDate', fields: ['processingDate'] }
|
||||
],
|
||||
comment: '无害化登记管理表'
|
||||
});
|
||||
|
||||
return HarmlessRegistration;
|
||||
};
|
||||
78
government-backend/models/Slaughterhouse.js
Normal file
78
government-backend/models/Slaughterhouse.js
Normal file
@@ -0,0 +1,78 @@
|
||||
// 导入sequelize
|
||||
const sequelize = require('../config/database');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
// 屠宰场数据模型
|
||||
const Slaughterhouse = sequelize.define('Slaughterhouse', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
comment: '屠宰场ID'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
comment: '屠宰场名称'
|
||||
},
|
||||
address: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: false,
|
||||
comment: '地址'
|
||||
},
|
||||
contactPerson: {
|
||||
field: 'contactPerson',
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
comment: '联系人'
|
||||
},
|
||||
contactPhone: {
|
||||
field: 'contactPhone',
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
comment: '联系电话'
|
||||
},
|
||||
licenseNumber: {
|
||||
field: 'licenseNumber',
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
comment: '许可证号'
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('active', 'inactive'),
|
||||
allowNull: false,
|
||||
defaultValue: 'active',
|
||||
comment: '状态(active: 正常, inactive: 停用)'
|
||||
},
|
||||
createTime: {
|
||||
field: 'createTime',
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
defaultValue: DataTypes.NOW,
|
||||
comment: '创建时间'
|
||||
},
|
||||
created_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '创建人ID'
|
||||
},
|
||||
updated_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '更新人ID'
|
||||
}
|
||||
}, {
|
||||
tableName: 'government_slaughterhouses',
|
||||
timestamps: true,
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at',
|
||||
paranoid: false,
|
||||
indexes: [
|
||||
{ name: 'idx_name', fields: ['name'] },
|
||||
{ name: 'idx_licenseNumber', fields: ['licenseNumber'] },
|
||||
{ name: 'idx_status', fields: ['status'] }
|
||||
]
|
||||
});
|
||||
|
||||
module.exports = Slaughterhouse;
|
||||
100
government-backend/models/index.js
Normal file
100
government-backend/models/index.js
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 政府后端模型索引文件
|
||||
* @file index.js
|
||||
* @description 导出所有模型并建立关联关系
|
||||
*/
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
// 导入所有模型
|
||||
const User = require('./User');
|
||||
const AdminStaff = require('./AdminStaff');
|
||||
const Department = require('./Department');
|
||||
const Position = require('./Position');
|
||||
const Farmer = require('./Farmer');
|
||||
const HarmlessPlace = require('./HarmlessPlace');
|
||||
const HarmlessRegistration = require('./HarmlessRegistration');
|
||||
const Material = require('./Material');
|
||||
const Slaughterhouse = require('./Slaughterhouse');
|
||||
const EpidemicAgency = require('./EpidemicAgency');
|
||||
const SmartCollar = require('./SmartCollar');
|
||||
const SmartEarmark = require('./SmartEarmark');
|
||||
const SmartHost = require('./SmartHost');
|
||||
const WarehouseTransaction = require('./WarehouseTransaction');
|
||||
|
||||
// 初始化所有模型
|
||||
const initModels = () => {
|
||||
try {
|
||||
// 处理直接导出的模型
|
||||
if (User && typeof User !== 'function') {
|
||||
// User模型已经直接导出,不需要额外处理
|
||||
}
|
||||
|
||||
// 处理需要sequelize参数的模型
|
||||
const modelsToInit = [
|
||||
AdminStaff,
|
||||
Department,
|
||||
Position,
|
||||
Farmer,
|
||||
HarmlessPlace,
|
||||
HarmlessRegistration,
|
||||
Material,
|
||||
Slaughterhouse,
|
||||
EpidemicAgency,
|
||||
SmartCollar,
|
||||
SmartEarmark,
|
||||
SmartHost,
|
||||
WarehouseTransaction
|
||||
];
|
||||
|
||||
// 初始化模型
|
||||
modelsToInit.forEach(modelFactory => {
|
||||
if (typeof modelFactory === 'function') {
|
||||
// 调用函数获取模型实例
|
||||
const model = modelFactory(sequelize);
|
||||
// 将初始化后的模型赋值回原来的变量
|
||||
Object.assign(module.exports, { [model.name]: model });
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ 所有政府后端模型初始化完成');
|
||||
} catch (error) {
|
||||
console.error('❌ 政府后端模型初始化失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化模型
|
||||
initModels();
|
||||
|
||||
// 导出sequelize和所有模型
|
||||
module.exports = {
|
||||
sequelize,
|
||||
User,
|
||||
AdminStaff,
|
||||
Department,
|
||||
Position,
|
||||
Farmer,
|
||||
HarmlessPlace,
|
||||
HarmlessRegistration,
|
||||
Material,
|
||||
Slaughterhouse,
|
||||
EpidemicAgency,
|
||||
SmartCollar,
|
||||
SmartEarmark,
|
||||
SmartHost,
|
||||
WarehouseTransaction
|
||||
};
|
||||
|
||||
// 同步所有模型到数据库(可选)
|
||||
const syncModels = async (options = {}) => {
|
||||
try {
|
||||
await sequelize.sync(options);
|
||||
console.log('✅ 政府后端所有模型已同步到数据库');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ 政府后端模型同步失败:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 添加syncModels到导出
|
||||
module.exports.syncModels = syncModels;
|
||||
23
government-backend/package-lock.json
generated
23
government-backend/package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"express-validator": "^7.2.1",
|
||||
"helmet": "^7.1.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"morgan": "^1.10.0",
|
||||
@@ -567,6 +568,28 @@
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/express-validator": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/express-validator/-/express-validator-7.2.1.tgz",
|
||||
"integrity": "sha512-CjNE6aakfpuwGaHQZ3m8ltCG2Qvivd7RHtVMS/6nVxOM7xVGqr4bhflsm4+N5FP5zI7Zxp+Hae+9RE+o8e3ZOQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21",
|
||||
"validator": "~13.12.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express-validator/node_modules/validator": {
|
||||
"version": "13.12.0",
|
||||
"resolved": "https://registry.npmmirror.com/validator/-/validator-13.12.0.tgz",
|
||||
"integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"express-validator": "^7.2.1",
|
||||
"helmet": "^7.1.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"morgan": "^1.10.0",
|
||||
|
||||
44
government-backend/routes/harmless.js
Normal file
44
government-backend/routes/harmless.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { body } = require('express-validator');
|
||||
const harmlessRegistrationController = require('../controllers/HarmlessRegistrationController');
|
||||
const authMiddleware = require('../middleware/auth');
|
||||
|
||||
// 应用身份验证中间件
|
||||
router.use(authMiddleware);
|
||||
|
||||
// 获取无害化登记列表
|
||||
router.get('/list', harmlessRegistrationController.getList);
|
||||
|
||||
// 获取无害化登记详情
|
||||
router.get('/detail/:id', harmlessRegistrationController.getDetail);
|
||||
|
||||
// 创建无害化登记
|
||||
router.post('/create', [
|
||||
body('registrationNumber').notEmpty().withMessage('登记编号不能为空'),
|
||||
body('animalType').notEmpty().withMessage('动物类型不能为空'),
|
||||
body('quantity').isInt({ min: 1 }).withMessage('数量必须大于0'),
|
||||
body('reason').notEmpty().withMessage('原因不能为空'),
|
||||
body('processingMethod').notEmpty().withMessage('处理方式不能为空'),
|
||||
body('processingPlace').notEmpty().withMessage('处理场所不能为空'),
|
||||
body('processingDate').notEmpty().withMessage('处理日期不能为空'),
|
||||
body('registrant').notEmpty().withMessage('登记人不能为空')
|
||||
], harmlessRegistrationController.create);
|
||||
|
||||
// 更新无害化登记
|
||||
router.put('/update/:id', [
|
||||
body('registrationNumber').optional().notEmpty().withMessage('登记编号不能为空'),
|
||||
body('animalType').optional().notEmpty().withMessage('动物类型不能为空'),
|
||||
body('quantity').optional().isInt({ min: 1 }).withMessage('数量必须大于0'),
|
||||
body('reason').optional().notEmpty().withMessage('原因不能为空'),
|
||||
body('processingMethod').optional().notEmpty().withMessage('处理方式不能为空'),
|
||||
body('processingPlace').optional().notEmpty().withMessage('处理场所不能为空'),
|
||||
body('processingDate').optional().notEmpty().withMessage('处理日期不能为空'),
|
||||
body('registrant').optional().notEmpty().withMessage('登记人不能为空'),
|
||||
body('status').optional().isIn(['待处理', '处理中', '已完成', '已取消']).withMessage('状态必须是待处理、处理中、已完成或已取消')
|
||||
], harmlessRegistrationController.update);
|
||||
|
||||
// 删除无害化登记
|
||||
router.delete('/delete/:id', harmlessRegistrationController.delete);
|
||||
|
||||
module.exports = router;
|
||||
38
government-backend/routes/harmlessPlace.js
Normal file
38
government-backend/routes/harmlessPlace.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { body } = require('express-validator');
|
||||
const harmlessPlaceController = require('../controllers/HarmlessPlaceController');
|
||||
const authMiddleware = require('../middleware/auth');
|
||||
|
||||
// 应用身份验证中间件
|
||||
router.use(authMiddleware);
|
||||
|
||||
// 获取无害化场所列表
|
||||
router.get('/list', harmlessPlaceController.getList);
|
||||
|
||||
// 获取无害化场所详情
|
||||
router.get('/detail/:id', harmlessPlaceController.getDetail);
|
||||
|
||||
// 创建无害化场所
|
||||
router.post('/create', [
|
||||
body('name').notEmpty().withMessage('场所名称不能为空'),
|
||||
body('address').notEmpty().withMessage('地址不能为空'),
|
||||
body('contactPerson').notEmpty().withMessage('联系人不能为空'),
|
||||
body('contactPhone').notEmpty().withMessage('联系电话不能为空'),
|
||||
body('licenseNumber').notEmpty().withMessage('许可证号不能为空')
|
||||
], harmlessPlaceController.create);
|
||||
|
||||
// 更新无害化场所
|
||||
router.put('/update/:id', [
|
||||
body('name').optional().notEmpty().withMessage('场所名称不能为空'),
|
||||
body('address').optional().notEmpty().withMessage('地址不能为空'),
|
||||
body('contactPerson').optional().notEmpty().withMessage('联系人不能为空'),
|
||||
body('contactPhone').optional().notEmpty().withMessage('联系电话不能为空'),
|
||||
body('licenseNumber').optional().notEmpty().withMessage('许可证号不能为空'),
|
||||
body('status').optional().isIn(['正常', '维护中', '停用']).withMessage('状态必须是正常、维护中或停用')
|
||||
], harmlessPlaceController.update);
|
||||
|
||||
// 删除无害化场所
|
||||
router.delete('/delete/:id', harmlessPlaceController.delete);
|
||||
|
||||
module.exports = router;
|
||||
17
government-backend/routes/slaughter.js
Normal file
17
government-backend/routes/slaughter.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const slaughterhouseController = require('../controllers/SlaughterhouseController');
|
||||
const authMiddleware = require('../middleware/auth');
|
||||
|
||||
// 应用认证中间件
|
||||
router.use(authMiddleware);
|
||||
|
||||
// 屠宰场管理路由
|
||||
router.get('/slaughterhouses', slaughterhouseController.getSlaughterhouses);
|
||||
router.get('/slaughterhouses/:id', slaughterhouseController.getSlaughterhouseById);
|
||||
router.post('/slaughterhouses', slaughterhouseController.createSlaughterhouse);
|
||||
router.put('/slaughterhouses/:id', slaughterhouseController.updateSlaughterhouse);
|
||||
router.delete('/slaughterhouses/:id', slaughterhouseController.deleteSlaughterhouse);
|
||||
router.patch('/slaughterhouses/:id/status', slaughterhouseController.toggleSlaughterhouseStatus);
|
||||
|
||||
module.exports = router;
|
||||
13
government-backend/routes/test-route.js
Normal file
13
government-backend/routes/test-route.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
// 简单的测试路由
|
||||
router.get('/test', (req, res) => {
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '测试路由工作正常',
|
||||
timestamp: new Date()
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
150
government-backend/scripts/createSlaughterhouseTable.js
Normal file
150
government-backend/scripts/createSlaughterhouseTable.js
Normal file
@@ -0,0 +1,150 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
|
||||
const createSlaughterhouseTable = async () => {
|
||||
let connection = null;
|
||||
try {
|
||||
// 创建数据库连接
|
||||
connection = await mysql.createConnection({
|
||||
host: '129.211.213.226',
|
||||
port: 9527,
|
||||
user: 'root',
|
||||
password: 'aiotAiot123!',
|
||||
database: 'ningxia_zhengfu',
|
||||
charset: 'utf8mb4'
|
||||
});
|
||||
|
||||
console.log('数据库连接成功');
|
||||
|
||||
// SQL语句数组
|
||||
const sqlStatements = [
|
||||
// 删除旧表(如果存在)
|
||||
'DROP TABLE IF EXISTS government_slaughterhouses;',
|
||||
|
||||
// 创建新表
|
||||
`CREATE TABLE government_slaughterhouses (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '屠宰场ID',
|
||||
name VARCHAR(100) NOT NULL UNIQUE COMMENT '屠宰场名称',
|
||||
address VARCHAR(255) NOT NULL COMMENT '地址',
|
||||
contactPerson VARCHAR(50) NOT NULL COMMENT '联系人',
|
||||
contactPhone VARCHAR(20) NOT NULL COMMENT '联系电话',
|
||||
licenseNumber VARCHAR(50) NOT NULL UNIQUE COMMENT '许可证号',
|
||||
status ENUM('active', 'inactive') NOT NULL DEFAULT 'active' COMMENT '状态(active: 正常, inactive: 停用)',
|
||||
createTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
created_by INT NULL COMMENT '创建人ID',
|
||||
updated_by INT NULL COMMENT '更新人ID',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at DATETIME NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='政府系统屠宰场表';`,
|
||||
|
||||
// 添加索引
|
||||
'CREATE INDEX idx_name ON government_slaughterhouses (name);',
|
||||
'CREATE INDEX idx_licenseNumber ON government_slaughterhouses (licenseNumber);',
|
||||
'CREATE INDEX idx_status ON government_slaughterhouses (status);'
|
||||
];
|
||||
|
||||
// 执行表创建相关SQL
|
||||
for (const sql of sqlStatements) {
|
||||
await connection.execute(sql);
|
||||
console.log(`执行SQL成功: ${sql.substring(0, 50)}...`);
|
||||
}
|
||||
|
||||
// 准备测试数据(使用参数化查询避免字符编码问题)
|
||||
const testData = [
|
||||
[
|
||||
'宁夏银川市第一屠宰场',
|
||||
'宁夏回族自治区银川市金凤区良田镇植物园路',
|
||||
'张明',
|
||||
'13800138001',
|
||||
'SC1234567890123',
|
||||
'active',
|
||||
'2023-01-15 00:00:00',
|
||||
1,
|
||||
1
|
||||
],
|
||||
[
|
||||
'宁夏石嘴山市肉类加工厂',
|
||||
'宁夏回族自治区石嘴山市大武口区星海镇',
|
||||
'李强',
|
||||
'13900139002',
|
||||
'SC1234567890124',
|
||||
'active',
|
||||
'2023-02-10 00:00:00',
|
||||
1,
|
||||
1
|
||||
],
|
||||
[
|
||||
'宁夏吴忠市清真屠宰场',
|
||||
'宁夏回族自治区吴忠市利通区金银滩镇',
|
||||
'王芳',
|
||||
'13700137003',
|
||||
'SC1234567890125',
|
||||
'active',
|
||||
'2023-03-05 00:00:00',
|
||||
1,
|
||||
1
|
||||
],
|
||||
[
|
||||
'宁夏固原市牲畜屠宰场',
|
||||
'宁夏回族自治区固原市原州区官厅镇',
|
||||
'赵伟',
|
||||
'13600136004',
|
||||
'SC1234567890126',
|
||||
'inactive',
|
||||
'2023-04-20 00:00:00',
|
||||
1,
|
||||
1
|
||||
],
|
||||
[
|
||||
'宁夏中卫市肉类屠宰加工中心',
|
||||
'宁夏回族自治区中卫市沙坡头区迎水桥镇',
|
||||
'陈静',
|
||||
'13500135005',
|
||||
'SC1234567890127',
|
||||
'active',
|
||||
'2023-05-15 00:00:00',
|
||||
1,
|
||||
1
|
||||
]
|
||||
];
|
||||
|
||||
// 插入测试数据
|
||||
const insertSql = `
|
||||
INSERT INTO government_slaughterhouses (
|
||||
name,
|
||||
address,
|
||||
contactPerson,
|
||||
contactPhone,
|
||||
licenseNumber,
|
||||
status,
|
||||
createTime,
|
||||
created_by,
|
||||
updated_by
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`;
|
||||
|
||||
let insertedCount = 0;
|
||||
for (const data of testData) {
|
||||
await connection.execute(insertSql, data);
|
||||
insertedCount++;
|
||||
console.log(`插入测试数据成功: ${data[0]}`);
|
||||
}
|
||||
|
||||
// 查询插入的记录数
|
||||
const [result] = await connection.execute('SELECT COUNT(*) AS total_records FROM government_slaughterhouses;');
|
||||
console.log(`
|
||||
成功创建屠宰场表并插入 ${result[0].total_records} 条测试数据!`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('创建屠宰场表或插入测试数据失败:', error);
|
||||
} finally {
|
||||
// 关闭数据库连接
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
console.log('数据库连接已关闭');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 执行函数
|
||||
createSlaughterhouseTable();
|
||||
98
government-backend/scripts/createSlaughterhouseTable.sql
Normal file
98
government-backend/scripts/createSlaughterhouseTable.sql
Normal file
@@ -0,0 +1,98 @@
|
||||
-- 直接使用SQL创建屠宰场表并添加测试数据
|
||||
USE ningxia_zhengfu;
|
||||
|
||||
-- 删除旧表(如果存在)
|
||||
DROP TABLE IF EXISTS government_slaughterhouses;
|
||||
|
||||
-- 创建新表,指定字符集支持中文
|
||||
CREATE TABLE government_slaughterhouses (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '屠宰场ID',
|
||||
name VARCHAR(100) NOT NULL UNIQUE COMMENT '屠宰场名称',
|
||||
address VARCHAR(255) NOT NULL COMMENT '地址',
|
||||
contactPerson VARCHAR(50) NOT NULL COMMENT '联系人',
|
||||
contactPhone VARCHAR(20) NOT NULL COMMENT '联系电话',
|
||||
licenseNumber VARCHAR(50) NOT NULL UNIQUE COMMENT '许可证号',
|
||||
status ENUM('active', 'inactive') NOT NULL DEFAULT 'active' COMMENT '状态(active: 正常, inactive: 停用)',
|
||||
createTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
created_by INT NULL COMMENT '创建人ID',
|
||||
updated_by INT NULL COMMENT '更新人ID',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at DATETIME NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='政府系统屠宰场表';
|
||||
|
||||
-- 添加索引
|
||||
CREATE INDEX idx_name ON government_slaughterhouses (name);
|
||||
CREATE INDEX idx_licenseNumber ON government_slaughterhouses (licenseNumber);
|
||||
CREATE INDEX idx_status ON government_slaughterhouses (status);
|
||||
|
||||
-- 插入测试数据
|
||||
INSERT INTO government_slaughterhouses (
|
||||
name,
|
||||
address,
|
||||
contactPerson,
|
||||
contactPhone,
|
||||
licenseNumber,
|
||||
status,
|
||||
createTime,
|
||||
created_by,
|
||||
updated_by
|
||||
) VALUES
|
||||
(
|
||||
'宁夏银川市第一屠宰场',
|
||||
'宁夏回族自治区银川市金凤区良田镇植物园路',
|
||||
'张明',
|
||||
'13800138001',
|
||||
'SC1234567890123',
|
||||
'active',
|
||||
'2023-01-15 00:00:00',
|
||||
1,
|
||||
1
|
||||
),
|
||||
(
|
||||
'宁夏石嘴山市肉类加工厂',
|
||||
'宁夏回族自治区石嘴山市大武口区星海镇',
|
||||
'李强',
|
||||
'13900139002',
|
||||
'SC1234567890124',
|
||||
'active',
|
||||
'2023-02-10 00:00:00',
|
||||
1,
|
||||
1
|
||||
),
|
||||
(
|
||||
'宁夏吴忠市清真屠宰场',
|
||||
'宁夏回族自治区吴忠市利通区金银滩镇',
|
||||
'王芳',
|
||||
'13700137003',
|
||||
'SC1234567890125',
|
||||
'active',
|
||||
'2023-03-05 00:00:00',
|
||||
1,
|
||||
1
|
||||
),
|
||||
(
|
||||
'宁夏固原市牲畜屠宰场',
|
||||
'宁夏回族自治区固原市原州区官厅镇',
|
||||
'赵伟',
|
||||
'13600136004',
|
||||
'SC1234567890126',
|
||||
'inactive',
|
||||
'2023-04-20 00:00:00',
|
||||
1,
|
||||
1
|
||||
),
|
||||
(
|
||||
'宁夏中卫市肉类屠宰加工中心',
|
||||
'宁夏回族自治区中卫市沙坡头区迎水桥镇',
|
||||
'陈静',
|
||||
'13500135005',
|
||||
'SC1234567890127',
|
||||
'active',
|
||||
'2023-05-15 00:00:00',
|
||||
1,
|
||||
1
|
||||
);
|
||||
|
||||
-- 查询插入的记录数
|
||||
SELECT COUNT(*) AS total_records FROM government_slaughterhouses;
|
||||
@@ -1,4 +1,4 @@
|
||||
const sequelize = require('../config/database');
|
||||
const sequelize = require('../config/database.js');
|
||||
const EpidemicAgency = require('../models/EpidemicAgency');
|
||||
|
||||
async function initEpidemicAgencyTable() {
|
||||
@@ -33,6 +33,7 @@ async function initEpidemicAgencyTable() {
|
||||
type: 'center',
|
||||
status: 'active',
|
||||
establishmentDate: '2010-01-15',
|
||||
epidemicScope: '负责全市所有区域的动物防疫工作统筹管理和技术指导',
|
||||
description: '负责全市动物防疫工作的统筹管理和技术指导'
|
||||
},
|
||||
{
|
||||
@@ -44,6 +45,7 @@ async function initEpidemicAgencyTable() {
|
||||
type: 'branch',
|
||||
status: 'active',
|
||||
establishmentDate: '2012-05-20',
|
||||
epidemicScope: '负责东区所有街道、乡镇的动物防疫工作',
|
||||
description: '负责东区范围内的动物防疫工作'
|
||||
},
|
||||
{
|
||||
@@ -55,6 +57,7 @@ async function initEpidemicAgencyTable() {
|
||||
type: 'branch',
|
||||
status: 'active',
|
||||
establishmentDate: '2013-03-10',
|
||||
epidemicScope: '负责西区所有街道、乡镇的动物防疫工作',
|
||||
description: '负责西区范围内的动物防疫工作'
|
||||
},
|
||||
{
|
||||
@@ -66,6 +69,7 @@ async function initEpidemicAgencyTable() {
|
||||
type: 'branch',
|
||||
status: 'active',
|
||||
establishmentDate: '2014-07-05',
|
||||
epidemicScope: '负责北区所有街道、乡镇的动物防疫工作',
|
||||
description: '负责北区范围内的动物防疫工作'
|
||||
},
|
||||
{
|
||||
@@ -77,6 +81,7 @@ async function initEpidemicAgencyTable() {
|
||||
type: 'branch',
|
||||
status: 'active',
|
||||
establishmentDate: '2015-02-28',
|
||||
epidemicScope: '负责南区所有街道、乡镇的动物防疫工作',
|
||||
description: '负责南区范围内的动物防疫工作'
|
||||
},
|
||||
{
|
||||
@@ -88,6 +93,7 @@ async function initEpidemicAgencyTable() {
|
||||
type: 'mobile',
|
||||
status: 'active',
|
||||
establishmentDate: '2016-09-15',
|
||||
epidemicScope: '负责全市偏远地区、山区及突发事件的动物防疫工作',
|
||||
description: '负责偏远地区和突发事件的动物防疫工作'
|
||||
}
|
||||
];
|
||||
|
||||
115
government-backend/scripts/initHarmlessPlaceTable.js
Normal file
115
government-backend/scripts/initHarmlessPlaceTable.js
Normal file
@@ -0,0 +1,115 @@
|
||||
const config = require('../config/index');
|
||||
const mysql = require('mysql2/promise');
|
||||
|
||||
// 初始化无害化场所表
|
||||
async function initHarmlessPlaceTable() {
|
||||
let connection = null;
|
||||
try {
|
||||
// 创建数据库连接
|
||||
console.log('测试数据库连接...');
|
||||
connection = await mysql.createConnection({
|
||||
host: config.DB_CONFIG.host,
|
||||
port: config.DB_CONFIG.port,
|
||||
user: config.DB_CONFIG.user,
|
||||
password: config.DB_CONFIG.password,
|
||||
database: config.DB_CONFIG.database
|
||||
});
|
||||
console.log('数据库连接成功');
|
||||
|
||||
// 检查表是否存在
|
||||
console.log('检查无害化场所表是否存在...');
|
||||
const [tables] = await connection.execute(
|
||||
"SHOW TABLES LIKE 'government_harmless_places'"
|
||||
);
|
||||
|
||||
// 如果表存在,删除它
|
||||
if (tables.length > 0) {
|
||||
console.log('无害化场所表已存在,删除它...');
|
||||
await connection.execute('DROP TABLE government_harmless_places');
|
||||
console.log('无害化场所表删除成功');
|
||||
}
|
||||
|
||||
// 创建无害化场所表
|
||||
console.log('创建无害化场所表...');
|
||||
await connection.execute(`
|
||||
CREATE TABLE government_harmless_places (
|
||||
id VARCHAR(36) PRIMARY KEY NOT NULL,
|
||||
name VARCHAR(100) NOT NULL COMMENT '场所名称',
|
||||
address VARCHAR(255) NOT NULL COMMENT '地址',
|
||||
contact_person VARCHAR(50) NOT NULL COMMENT '联系人',
|
||||
contact_phone VARCHAR(20) NOT NULL COMMENT '联系电话',
|
||||
license_number VARCHAR(50) NOT NULL UNIQUE COMMENT '许可证号',
|
||||
status ENUM('正常', '维护中', '停用') NOT NULL DEFAULT '正常' COMMENT '状态',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX idx_name (name),
|
||||
INDEX idx_license_number (license_number),
|
||||
INDEX idx_status (status)
|
||||
) COMMENT '无害化场所管理表'
|
||||
`);
|
||||
|
||||
console.log('无害化场所表创建成功!');
|
||||
|
||||
// 添加测试数据
|
||||
console.log('开始添加测试数据...');
|
||||
const testData = [
|
||||
[
|
||||
'1', '银川市无害化处理中心', '宁夏银川市金凤区科技园路88号',
|
||||
'张经理', '13895112345', 'HP20240001', '正常',
|
||||
'2024-06-01 10:00:00', '2024-06-01 10:00:00'
|
||||
],
|
||||
[
|
||||
'2', '石嘴山市无害化处理站', '宁夏石嘴山市大武口区环保路56号',
|
||||
'李站长', '13995123456', 'HP20240002', '正常',
|
||||
'2024-06-02 11:30:00', '2024-06-02 11:30:00'
|
||||
],
|
||||
[
|
||||
'3', '吴忠市无害化处理厂', '宁夏吴忠市利通区产业路34号',
|
||||
'王厂长', '13795134567', 'HP20240003', '维护中',
|
||||
'2024-06-03 09:15:00', '2024-06-10 14:20:00'
|
||||
],
|
||||
[
|
||||
'4', '固原市无害化处理中心', '宁夏固原市原州区生态路12号',
|
||||
'赵主任', '13695145678', 'HP20240004', '正常',
|
||||
'2024-06-04 14:45:00', '2024-06-04 14:45:00'
|
||||
],
|
||||
[
|
||||
'5', '中卫市无害化处理站', '宁夏中卫市沙坡头区环卫路23号',
|
||||
'孙主任', '13595156789', 'HP20240005', '停用',
|
||||
'2024-06-05 16:20:00', '2024-06-15 09:30:00'
|
||||
]
|
||||
];
|
||||
|
||||
// 批量插入数据
|
||||
for (const row of testData) {
|
||||
await connection.execute(
|
||||
`INSERT INTO government_harmless_places
|
||||
(id, name, address, contact_person, contact_phone, license_number, status, create_time, update_time)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
row
|
||||
);
|
||||
}
|
||||
|
||||
console.log('测试数据添加成功!');
|
||||
console.log('无害化场所表初始化完成!');
|
||||
} catch (error) {
|
||||
console.error('初始化无害化场所表失败:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
// 关闭数据库连接
|
||||
if (connection) {
|
||||
await connection.end();
|
||||
console.log('数据库连接已关闭');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行初始化
|
||||
if (require.main === module) {
|
||||
initHarmlessPlaceTable().catch(err => {
|
||||
console.error('程序执行失败:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = initHarmlessPlaceTable;
|
||||
110
government-backend/scripts/initHarmlessRegistrationTable.js
Normal file
110
government-backend/scripts/initHarmlessRegistrationTable.js
Normal file
@@ -0,0 +1,110 @@
|
||||
const config = require('../config');
|
||||
const mysql = require('mysql2/promise');
|
||||
|
||||
// 初始化无害化登记表
|
||||
async function initHarmlessRegistrationTable() {
|
||||
let connection = null;
|
||||
try {
|
||||
// 创建数据库连接
|
||||
console.log('测试数据库连接...');
|
||||
connection = await mysql.createConnection({
|
||||
host: config.DB_CONFIG.host,
|
||||
port: config.DB_CONFIG.port,
|
||||
user: config.DB_CONFIG.user,
|
||||
password: config.DB_CONFIG.password,
|
||||
database: config.DB_CONFIG.database
|
||||
});
|
||||
console.log('数据库连接成功');
|
||||
|
||||
// 检查表是否存在
|
||||
console.log('检查无害化登记表是否存在...');
|
||||
const [tables] = await connection.execute(
|
||||
"SHOW TABLES LIKE 'government_harmless_registrations'"
|
||||
);
|
||||
|
||||
// 如果表存在,删除它
|
||||
if (tables.length > 0) {
|
||||
console.log('无害化登记表已存在,删除它...');
|
||||
await connection.execute('DROP TABLE government_harmless_registrations');
|
||||
console.log('无害化登记表删除成功');
|
||||
}
|
||||
|
||||
// 创建无害化登记表
|
||||
console.log('创建无害化登记表...');
|
||||
await connection.execute(`
|
||||
CREATE TABLE government_harmless_registrations (
|
||||
id VARCHAR(36) PRIMARY KEY NOT NULL,
|
||||
registrationNumber VARCHAR(50) NOT NULL UNIQUE COMMENT '登记编号',
|
||||
animalType VARCHAR(50) NOT NULL COMMENT '动物类型',
|
||||
quantity INT NOT NULL COMMENT '数量',
|
||||
reason TEXT NOT NULL COMMENT '无害化处理原因',
|
||||
processingMethod VARCHAR(100) NOT NULL COMMENT '处理方式',
|
||||
processingPlace VARCHAR(100) NOT NULL COMMENT '处理场所',
|
||||
processingDate DATE NOT NULL COMMENT '处理日期',
|
||||
registrant VARCHAR(50) NOT NULL COMMENT '登记人',
|
||||
status ENUM('待处理', '处理中', '已完成', '已取消') NOT NULL DEFAULT '待处理' COMMENT '状态',
|
||||
createTime DATETIME NOT NULL COMMENT '创建时间',
|
||||
updateTime DATETIME NOT NULL COMMENT '更新时间',
|
||||
INDEX idx_registrationNumber (registrationNumber),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_processingDate (processingDate)
|
||||
) COMMENT '无害化登记管理表'
|
||||
`);
|
||||
|
||||
console.log('无害化登记表创建成功!');
|
||||
|
||||
// 添加测试数据
|
||||
console.log('开始添加测试数据...');
|
||||
const testData = [
|
||||
[
|
||||
'1', 'WH20240601001', '牛', 5, '疾病死亡', '焚烧处理',
|
||||
'银川市无害化处理中心', '2024-06-01', '张兽医', '已完成',
|
||||
'2024-06-01 08:30:00', '2024-06-02 14:20:00'
|
||||
],
|
||||
[
|
||||
'2', 'WH20240602002', '羊', 10, '自然灾害', '深埋处理',
|
||||
'中卫市无害化处理中心', '2024-06-02', '李技术员', '处理中',
|
||||
'2024-06-02 09:15:00', '2024-06-02 16:45:00'
|
||||
],
|
||||
[
|
||||
'3', 'WH20240603003', '猪', 8, '检疫不合格', '化制处理',
|
||||
'吴忠市无害化处理中心', '2024-06-03', '王检疫员', '待处理',
|
||||
'2024-06-03 10:00:00', '2024-06-03 10:00:00'
|
||||
],
|
||||
[
|
||||
'4', 'WH20240604004', '牛', 3, '意外死亡', '焚烧处理',
|
||||
'石嘴山市无害化处理中心', '2024-06-04', '赵管理员', '已取消',
|
||||
'2024-06-04 11:20:00', '2024-06-04 15:30:00'
|
||||
],
|
||||
[
|
||||
'5', 'WH20240605005', '羊', 12, '疫情防控', '深埋处理',
|
||||
'固原市无害化处理中心', '2024-06-05', '陈兽医', '已完成',
|
||||
'2024-06-05 09:45:00', '2024-06-06 11:15:00'
|
||||
]
|
||||
];
|
||||
|
||||
// 批量插入数据
|
||||
for (const row of testData) {
|
||||
await connection.execute(
|
||||
`INSERT INTO government_harmless_registrations
|
||||
(id, registrationNumber, animalType, quantity, reason, processingMethod,
|
||||
processingPlace, processingDate, registrant, status, createTime, updateTime)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
row
|
||||
);
|
||||
}
|
||||
|
||||
console.log('测试数据添加成功!添加了', testData.length, '条数据。');
|
||||
|
||||
} catch (error) {
|
||||
console.error('初始化无害化登记表失败:', error);
|
||||
} finally {
|
||||
// 关闭数据库连接
|
||||
if (connection) {
|
||||
await connection.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行初始化
|
||||
initHarmlessRegistrationTable();
|
||||
92
government-backend/scripts/initSlaughterhouseData.js
Normal file
92
government-backend/scripts/initSlaughterhouseData.js
Normal file
@@ -0,0 +1,92 @@
|
||||
const sequelize = require('../config/database');
|
||||
const Slaughterhouse = require('../models/Slaughterhouse');
|
||||
|
||||
// 初始化屠宰场表并添加测试数据
|
||||
const initSlaughterhouseData = async () => {
|
||||
try {
|
||||
// 先删除旧表,再重新创建
|
||||
await Slaughterhouse.drop().catch(() => console.log('旧表不存在,跳过删除'));
|
||||
await sequelize.sync({ force: true });
|
||||
console.log('数据库同步成功,表已重新创建');
|
||||
|
||||
// 检查是否已有数据
|
||||
const existingCount = await Slaughterhouse.count();
|
||||
if (existingCount > 0) {
|
||||
console.log(`已存在 ${existingCount} 条屠宰场数据,跳过初始化`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 准备测试数据
|
||||
const testData = [
|
||||
{
|
||||
name: '宁夏银川市第一屠宰场',
|
||||
address: '宁夏回族自治区银川市金凤区良田镇植物园路',
|
||||
contactPerson: '张明',
|
||||
contactPhone: '13800138001',
|
||||
licenseNumber: 'SC1234567890123',
|
||||
status: 'active',
|
||||
createTime: new Date('2023-01-15'),
|
||||
created_by: 1,
|
||||
updated_by: 1
|
||||
},
|
||||
{
|
||||
name: '宁夏石嘴山市肉类加工厂',
|
||||
address: '宁夏回族自治区石嘴山市大武口区星海镇',
|
||||
contactPerson: '李强',
|
||||
contactPhone: '13900139002',
|
||||
licenseNumber: 'SC1234567890124',
|
||||
status: 'active',
|
||||
createTime: new Date('2023-02-10'),
|
||||
created_by: 1,
|
||||
updated_by: 1
|
||||
},
|
||||
{
|
||||
name: '宁夏吴忠市清真屠宰场',
|
||||
address: '宁夏回族自治区吴忠市利通区金银滩镇',
|
||||
contactPerson: '王芳',
|
||||
contactPhone: '13700137003',
|
||||
licenseNumber: 'SC1234567890125',
|
||||
status: 'active',
|
||||
createTime: new Date('2023-03-05'),
|
||||
created_by: 1,
|
||||
updated_by: 1
|
||||
},
|
||||
{
|
||||
name: '宁夏固原市牲畜屠宰场',
|
||||
address: '宁夏回族自治区固原市原州区官厅镇',
|
||||
contactPerson: '赵伟',
|
||||
contactPhone: '13600136004',
|
||||
licenseNumber: 'SC1234567890126',
|
||||
status: 'inactive',
|
||||
createTime: new Date('2023-04-20'),
|
||||
created_by: 1,
|
||||
updated_by: 1
|
||||
},
|
||||
{
|
||||
name: '宁夏中卫市肉类屠宰加工中心',
|
||||
address: '宁夏回族自治区中卫市沙坡头区迎水桥镇',
|
||||
contactPerson: '陈静',
|
||||
contactPhone: '13500135005',
|
||||
licenseNumber: 'SC1234567890127',
|
||||
status: 'active',
|
||||
createTime: new Date('2023-05-15'),
|
||||
created_by: 1,
|
||||
updated_by: 1
|
||||
}
|
||||
];
|
||||
|
||||
// 批量创建测试数据
|
||||
const createdSlaughterhouses = await Slaughterhouse.bulkCreate(testData);
|
||||
console.log(`成功创建 ${createdSlaughterhouses.length} 条屠宰场测试数据`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('初始化屠宰场数据失败:', error);
|
||||
} finally {
|
||||
// 关闭数据库连接
|
||||
await sequelize.close();
|
||||
console.log('数据库连接已关闭');
|
||||
}
|
||||
};
|
||||
|
||||
// 执行初始化函数
|
||||
initSlaughterhouseData();
|
||||
24
government-backend/simple-check.js
Normal file
24
government-backend/simple-check.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// 简洁地检查路由模块的基本信息
|
||||
const express = require('express');
|
||||
const slaughterRoutes = require('./routes/slaughter');
|
||||
const authRoutes = require('./routes/auth');
|
||||
|
||||
console.log('=== slaughter路由模块 ===');
|
||||
console.log('类型:', typeof slaughterRoutes);
|
||||
console.log('构造函数:', slaughterRoutes && slaughterRoutes.constructor && slaughterRoutes.constructor.name);
|
||||
console.log('是否有stack:', 'stack' in slaughterRoutes);
|
||||
console.log('是否有get方法:', 'get' in slaughterRoutes);
|
||||
|
||||
console.log('\n=== auth路由模块 ===');
|
||||
console.log('类型:', typeof authRoutes);
|
||||
console.log('构造函数:', authRoutes && authRoutes.constructor && authRoutes.constructor.name);
|
||||
console.log('是否有stack:', 'stack' in authRoutes);
|
||||
console.log('是否有get方法:', 'get' in authRoutes);
|
||||
|
||||
// 创建一个新的Router实例进行比较
|
||||
const newRouter = express.Router();
|
||||
console.log('\n=== 新创建的Router实例 ===');
|
||||
console.log('类型:', typeof newRouter);
|
||||
console.log('构造函数:', newRouter && newRouter.constructor && newRouter.constructor.name);
|
||||
console.log('是否有stack:', 'stack' in newRouter);
|
||||
console.log('是否有get方法:', 'get' in newRouter);
|
||||
103
government-backend/simulate-server-startup.js
Normal file
103
government-backend/simulate-server-startup.js
Normal file
@@ -0,0 +1,103 @@
|
||||
// 清除指定模块的缓存
|
||||
function clearModuleCache() {
|
||||
const modulesToClear = Object.keys(require.cache).filter(key =>
|
||||
key.includes('HarmlessPlace') || key.includes('database') || key.includes('controller')
|
||||
);
|
||||
|
||||
console.log('清除以下模块的缓存:', modulesToClear.length, '个模块');
|
||||
modulesToClear.forEach(key => {
|
||||
console.log('-', key);
|
||||
delete require.cache[key];
|
||||
});
|
||||
}
|
||||
|
||||
// 模拟服务器启动过程
|
||||
async function simulateServerStartup() {
|
||||
try {
|
||||
// 1. 首先清除模块缓存
|
||||
clearModuleCache();
|
||||
|
||||
// 2. 记录加载顺序
|
||||
console.log('\n=== 开始模拟服务器启动过程 ===');
|
||||
|
||||
// 3. 先加载数据库配置 - 注意这里使用正确的路径
|
||||
console.log('\n1. 加载数据库配置...');
|
||||
const sequelize = require('./config/database');
|
||||
console.log('数据库实例加载完成');
|
||||
console.log('sequelize的类型:', typeof sequelize);
|
||||
|
||||
// 4. 测试数据库连接
|
||||
console.log('\n2. 测试数据库连接...');
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
console.log('数据库连接成功');
|
||||
} catch (error) {
|
||||
console.error('数据库连接失败:', error.message);
|
||||
}
|
||||
|
||||
// 5. 加载HarmlessPlace模型
|
||||
console.log('\n3. 加载HarmlessPlace模型...');
|
||||
const HarmlessPlace = require('./models/HarmlessPlace');
|
||||
console.log('HarmlessPlace模型加载完成');
|
||||
console.log('HarmlessPlace的类型:', typeof HarmlessPlace);
|
||||
console.log('HarmlessPlace是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
|
||||
if (HarmlessPlace.findAndCountAll) {
|
||||
console.log('findAndCountAll的类型:', typeof HarmlessPlace.findAndCountAll);
|
||||
}
|
||||
|
||||
// 6. 尝试调用findAndCountAll方法
|
||||
console.log('\n4. 尝试调用findAndCountAll方法...');
|
||||
try {
|
||||
const result = await HarmlessPlace.findAndCountAll({
|
||||
limit: 10,
|
||||
offset: 0
|
||||
});
|
||||
console.log('findAndCountAll调用成功,结果:', result);
|
||||
} catch (error) {
|
||||
console.error('findAndCountAll调用失败:', error.message);
|
||||
}
|
||||
|
||||
// 7. 加载控制器
|
||||
console.log('\n5. 加载HarmlessPlaceController控制器...');
|
||||
const harmlessPlaceController = require('./controllers/HarmlessPlaceController');
|
||||
console.log('控制器加载完成');
|
||||
|
||||
// 8. 创建模拟的req和res对象
|
||||
const mockReq = {
|
||||
query: {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
};
|
||||
|
||||
const mockRes = {
|
||||
json: function(data) {
|
||||
console.log('res.json被调用:', data);
|
||||
},
|
||||
status: function(code) {
|
||||
console.log('res.status被调用:', code);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// 9. 尝试调用控制器的getList方法
|
||||
console.log('\n6. 尝试调用控制器的getList方法...');
|
||||
try {
|
||||
await harmlessPlaceController.getList(mockReq, mockRes);
|
||||
console.log('控制器getList方法调用成功');
|
||||
} catch (error) {
|
||||
console.error('控制器getList方法调用失败:', error.message);
|
||||
console.error('错误堆栈:', error.stack);
|
||||
}
|
||||
|
||||
console.log('\n=== 服务器启动模拟完成 ===');
|
||||
|
||||
} catch (error) {
|
||||
console.error('模拟服务器启动过程中发生错误:', error.message);
|
||||
console.error('错误堆栈:', error.stack);
|
||||
}
|
||||
}
|
||||
|
||||
// 运行模拟
|
||||
console.log('开始执行服务器启动模拟测试...');
|
||||
simulateServerStartup().catch(err => console.error('测试过程中出错:', err));
|
||||
27
government-backend/test-api.js
Normal file
27
government-backend/test-api.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const http = require('http');
|
||||
|
||||
const options = {
|
||||
hostname: 'localhost',
|
||||
port: 5352,
|
||||
path: '/api/slaughter/slaughterhouses',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': 'Bearer mock-jwt-token-test',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
const req = http.request(options, (res) => {
|
||||
console.log(`状态码: ${res.statusCode}`);
|
||||
console.log(`响应头: ${JSON.stringify(res.headers)}`);
|
||||
|
||||
res.on('data', (d) => {
|
||||
process.stdout.write(d);
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', (error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
req.end();
|
||||
84
government-backend/test-client.js
Normal file
84
government-backend/test-client.js
Normal file
@@ -0,0 +1,84 @@
|
||||
const http = require('http');
|
||||
|
||||
// 测试函数
|
||||
function testRoute(path, description) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const options = {
|
||||
hostname: 'localhost',
|
||||
port: 5353,
|
||||
path: path,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': 'Bearer mock-jwt-token-test',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
const req = http.request(options, (res) => {
|
||||
let data = '';
|
||||
res.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
resolve({
|
||||
path: path,
|
||||
description: description,
|
||||
statusCode: res.statusCode,
|
||||
headers: res.headers,
|
||||
body: data
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', (error) => {
|
||||
reject({
|
||||
path: path,
|
||||
description: description,
|
||||
error: error.message
|
||||
});
|
||||
});
|
||||
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
// 运行所有测试
|
||||
async function runTests() {
|
||||
console.log('开始测试路由...\n');
|
||||
|
||||
try {
|
||||
// 测试健康检查路由
|
||||
const healthResult = await testRoute('/health', '健康检查');
|
||||
console.log(`${healthResult.description} - 状态码: ${healthResult.statusCode}`);
|
||||
console.log(`响应: ${healthResult.body}\n`);
|
||||
|
||||
// 测试测试路由
|
||||
const testResult = await testRoute('/api/test/test', '测试路由');
|
||||
console.log(`${testResult.description} - 状态码: ${testResult.statusCode}`);
|
||||
console.log(`响应: ${testResult.body}\n`);
|
||||
|
||||
// 测试slaughter路由
|
||||
const slaughterResult = await testRoute('/api/slaughter/slaughterhouses', 'Slaughter路由');
|
||||
console.log(`${slaughterResult.description} - 状态码: ${slaughterResult.statusCode}`);
|
||||
console.log(`响应: ${slaughterResult.body}\n`);
|
||||
|
||||
// 测试不存在的路由
|
||||
const notFoundResult = await testRoute('/api/not-exist', '不存在的路由');
|
||||
console.log(`${notFoundResult.description} - 状态码: ${notFoundResult.statusCode}`);
|
||||
console.log(`响应: ${notFoundResult.body}\n`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 等待一会儿再运行测试,给服务器启动时间
|
||||
sleep(2000).then(() => {
|
||||
runTests();
|
||||
});
|
||||
|
||||
// 简单的sleep函数
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
95
government-backend/test-harmless-place-api.js
Normal file
95
government-backend/test-harmless-place-api.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// 测试无害化场所API
|
||||
const axios = require('axios');
|
||||
|
||||
// 政府后端服务地址
|
||||
const BASE_URL = 'http://localhost:5352/api';
|
||||
|
||||
// 登录获取token
|
||||
async function login() {
|
||||
try {
|
||||
console.log('开始登录...');
|
||||
const response = await axios.post(`${BASE_URL}/auth/login`, {
|
||||
username: 'admin',
|
||||
password: '123456'
|
||||
});
|
||||
|
||||
console.log('登录响应:', response.data);
|
||||
|
||||
if (response.data.code === 200 && response.data.data && response.data.data.token) {
|
||||
console.log('登录成功,获取到token');
|
||||
return response.data.data.token;
|
||||
} else {
|
||||
console.log('登录失败,未获取到token');
|
||||
console.log('错误信息:', response.data.message || '未知错误');
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('登录请求失败:', error.message);
|
||||
if (error.response) {
|
||||
console.error('错误状态码:', error.response.status);
|
||||
console.error('错误数据:', error.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试无害化场所列表API
|
||||
async function testHarmlessPlaceList(token) {
|
||||
try {
|
||||
console.log('\n测试无害化场所列表API...');
|
||||
const response = await axios.get(`${BASE_URL}/harmless-place/list`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
params: {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
});
|
||||
|
||||
console.log('API调用成功,状态码:', response.status);
|
||||
console.log('返回数据结构:', Object.keys(response.data));
|
||||
console.log('无害化场所总数:', response.data.total || '未知');
|
||||
|
||||
if (response.data.data && Array.isArray(response.data.data)) {
|
||||
console.log('返回的无害化场所列表长度:', response.data.data.length);
|
||||
if (response.data.data.length > 0) {
|
||||
console.log('第一条无害化场所数据:');
|
||||
console.log(response.data.data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('无害化场所列表API调用失败:', error.message);
|
||||
if (error.response) {
|
||||
console.error('错误状态码:', error.response.status);
|
||||
console.error('错误数据:', error.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 主测试函数
|
||||
const runTests = async () => {
|
||||
console.log('开始测试无害化场所管理API...');
|
||||
try {
|
||||
// 1. 登录获取token
|
||||
const token = await login();
|
||||
|
||||
if (!token) {
|
||||
console.error('无法继续测试,因为未获取到有效的token');
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 测试获取无害化场所列表
|
||||
await testHarmlessPlaceList(token);
|
||||
|
||||
console.log('\n所有测试完成!');
|
||||
} catch (error) {
|
||||
console.error('测试过程中发生错误:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 运行测试
|
||||
runTests();
|
||||
89
government-backend/test-harmless-place-cached.js
Normal file
89
government-backend/test-harmless-place-cached.js
Normal file
@@ -0,0 +1,89 @@
|
||||
// 清除模块缓存
|
||||
function clearModuleCache() {
|
||||
const modulesToClear = Object.keys(require.cache).filter(key =>
|
||||
key.includes('HarmlessPlace') || key.includes('database')
|
||||
);
|
||||
|
||||
console.log('清除以下模块的缓存:', modulesToClear.length, '个模块');
|
||||
modulesToClear.forEach(key => {
|
||||
console.log('-', key);
|
||||
delete require.cache[key];
|
||||
});
|
||||
}
|
||||
|
||||
// 清除缓存后再导入
|
||||
clearModuleCache();
|
||||
|
||||
const axios = require('axios');
|
||||
const HarmlessPlace = require('./models/HarmlessPlace');
|
||||
|
||||
console.log('=== 检查HarmlessPlace模型 ===');
|
||||
console.log('HarmlessPlace的类型:', typeof HarmlessPlace);
|
||||
console.log('HarmlessPlace是否为对象:', typeof HarmlessPlace === 'object' && HarmlessPlace !== null);
|
||||
console.log('HarmlessPlace是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
|
||||
if (HarmlessPlace.findAndCountAll) {
|
||||
console.log('findAndCountAll的类型:', typeof HarmlessPlace.findAndCountAll);
|
||||
}
|
||||
|
||||
// 登录函数
|
||||
async function login() {
|
||||
try {
|
||||
const response = await axios.post('http://localhost:3000/api/auth/login', {
|
||||
username: 'admin',
|
||||
password: '123456'
|
||||
});
|
||||
console.log('登录成功,token:', response.data.data.token);
|
||||
return response.data.data.token;
|
||||
} catch (error) {
|
||||
console.error('登录失败:', error.response ? error.response.data : error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试无害化场所列表API
|
||||
async function testHarmlessPlaceList(token) {
|
||||
try {
|
||||
const response = await axios.get('http://localhost:3000/api/harmless-place/list', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
params: {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
});
|
||||
console.log('无害化场所列表API调用成功:', response.data);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('无害化场所列表API调用失败:', error.message);
|
||||
if (error.response) {
|
||||
console.error('错误数据:', error.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
console.log('开始测试无害化场所管理API...');
|
||||
|
||||
// 登录获取token
|
||||
const token = await login();
|
||||
if (!token) {
|
||||
console.log('登录失败,无法继续测试');
|
||||
return;
|
||||
}
|
||||
|
||||
// 再次检查模型类型,确保在API调用前没有被修改
|
||||
console.log('\n=== API调用前再次检查HarmlessPlace模型 ===');
|
||||
console.log('HarmlessPlace的类型:', typeof HarmlessPlace);
|
||||
console.log('HarmlessPlace是否有findAndCountAll方法:', typeof HarmlessPlace.findAndCountAll !== 'undefined');
|
||||
|
||||
// 测试API
|
||||
await testHarmlessPlaceList(token);
|
||||
|
||||
console.log('\n所有测试完成!');
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
main().catch(err => console.error('测试过程中出错:', err));
|
||||
51
government-backend/test-routes.js
Normal file
51
government-backend/test-routes.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// 测试Express应用的路由注册情况
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
|
||||
// 创建一个简单的Express应用来测试路由
|
||||
const app = express();
|
||||
|
||||
// 尝试加载slaughter路由
|
||||
try {
|
||||
const slaughterRoutes = require('./routes/slaughter');
|
||||
console.log('成功加载slaughter路由模块');
|
||||
|
||||
// 检查路由模块的内容
|
||||
console.log('路由模块导出:', typeof slaughterRoutes);
|
||||
|
||||
// 模拟注册路由
|
||||
app.use('/api/slaughter', slaughterRoutes);
|
||||
console.log('成功注册slaughter路由到/api/slaughter');
|
||||
|
||||
// 检查路由是否有方法
|
||||
if (slaughterRoutes && slaughterRoutes.stack) {
|
||||
console.log('路由处理程序数量:', slaughterRoutes.stack.length);
|
||||
slaughterRoutes.stack.forEach((layer, index) => {
|
||||
if (layer.route) {
|
||||
console.log(`路由${index + 1}:`, layer.route.path, Object.keys(layer.route.methods));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log('路由模块没有stack属性,可能不是Express Router实例');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载slaughter路由失败:', error);
|
||||
}
|
||||
|
||||
// 检查routes目录下的文件
|
||||
const fs = require('fs');
|
||||
const routesDir = path.join(__dirname, 'routes');
|
||||
fs.readdir(routesDir, (err, files) => {
|
||||
if (err) {
|
||||
console.error('读取routes目录失败:', err);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('\nroutes目录下的文件:');
|
||||
files.forEach(file => {
|
||||
console.log('-', file);
|
||||
// 检查文件大小,确认文件不为空
|
||||
const stats = fs.statSync(path.join(routesDir, file));
|
||||
console.log(` 大小: ${stats.size} 字节`);
|
||||
});
|
||||
});
|
||||
44
government-backend/test-server.js
Normal file
44
government-backend/test-server.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
const app = express();
|
||||
|
||||
// 中间件
|
||||
app.use(cors());
|
||||
app.use(bodyParser.json());
|
||||
|
||||
// 简单的认证中间件,允许所有请求通过
|
||||
app.use((req, res, next) => {
|
||||
console.log(`接收到请求: ${req.method} ${req.path}`);
|
||||
// 模拟用户数据
|
||||
req.user = {
|
||||
id: '1',
|
||||
username: 'admin',
|
||||
role: 'admin'
|
||||
};
|
||||
next();
|
||||
});
|
||||
|
||||
// 加载测试路由
|
||||
app.use('/api/test', require('./routes/test-route'));
|
||||
|
||||
// 加载slaughter路由
|
||||
app.use('/api/slaughter', require('./routes/slaughter'));
|
||||
|
||||
// 简单的健康检查路由
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok' });
|
||||
});
|
||||
|
||||
// 错误处理
|
||||
app.use((err, req, res, next) => {
|
||||
console.error('错误:', err);
|
||||
res.status(500).json({ error: '服务器错误' });
|
||||
});
|
||||
|
||||
// 启动服务器在不同端口
|
||||
const PORT = 5353;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`测试服务器已启动在端口 ${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user