599 lines
17 KiB
JavaScript
599 lines
17 KiB
JavaScript
|
|
const { Op } = require('sequelize');
|
||
|
|
const Department = require('../models/Department');
|
||
|
|
const Position = require('../models/Position');
|
||
|
|
const AdminStaff = require('../models/AdminStaff');
|
||
|
|
|
||
|
|
// 获取数据中心统计数据
|
||
|
|
const getDataCenterStats = async (req, res) => {
|
||
|
|
try {
|
||
|
|
// Mock data based on frontend analysis
|
||
|
|
const stats = {
|
||
|
|
totalFarmers: 128,
|
||
|
|
totalAnimals: 8056,
|
||
|
|
totalTransactions: 61,
|
||
|
|
activeUsers: 1,
|
||
|
|
monthlyTrends: [
|
||
|
|
{ month: '1月', value: 120 },
|
||
|
|
{ month: '2月', value: 180 },
|
||
|
|
{ month: '3月', value: 150 },
|
||
|
|
{ month: '4月', value: 200 },
|
||
|
|
{ month: '5月', value: 250 },
|
||
|
|
{ month: '6月', value: 220 },
|
||
|
|
{ month: '7月', value: 300 },
|
||
|
|
{ month: '8月', value: 280 },
|
||
|
|
{ month: '9月', value: 350 },
|
||
|
|
{ month: '10月', value: 400 },
|
||
|
|
{ month: '11月', value: 380 },
|
||
|
|
{ month: '12月', value: 450 }
|
||
|
|
],
|
||
|
|
categoryDistribution: [
|
||
|
|
{ value: 335, name: '西门塔尔牛' },
|
||
|
|
{ value: 310, name: '夏洛莱牛' },
|
||
|
|
{ value: 234, name: '安格斯牛' },
|
||
|
|
{ value: 135, name: '利木赞牛' },
|
||
|
|
{ value: 548, name: '其他' }
|
||
|
|
],
|
||
|
|
regionDistribution: [
|
||
|
|
{ value: 1548, name: '扎鲁特旗' },
|
||
|
|
{ value: 735, name: '科尔沁区' },
|
||
|
|
{ value: 510, name: '霍林郭勒市' },
|
||
|
|
{ value: 434, name: '开鲁县' },
|
||
|
|
{ value: 335, name: '库伦旗' }
|
||
|
|
],
|
||
|
|
scaleDistribution: [
|
||
|
|
{ value: 40, name: '1-10头' },
|
||
|
|
{ value: 30, name: '11-50头' },
|
||
|
|
{ value: 20, name: '51-100头' },
|
||
|
|
{ value: 10, name: '100头以上' }
|
||
|
|
],
|
||
|
|
updates: [
|
||
|
|
{ time: '2023-10-27 10:30', content: '数据更新-养殖户数据' },
|
||
|
|
{ time: '2023-10-27 10:30', content: '数据更新-存栏数据' },
|
||
|
|
{ time: '2023-10-27 10:30', content: '数据更新-交易数据' },
|
||
|
|
{ time: '2023-10-27 10:30', content: '数据更新-用户数据' }
|
||
|
|
]
|
||
|
|
};
|
||
|
|
res.json(stats);
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 获取市场价格信息
|
||
|
|
const getMarketPrice = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { type = 'beef' } = req.query;
|
||
|
|
let priceData = {};
|
||
|
|
|
||
|
|
// 繁殖牛数据
|
||
|
|
if (type === 'beef') {
|
||
|
|
priceData = {
|
||
|
|
type: 'beef',
|
||
|
|
typeText: '繁殖牛',
|
||
|
|
currentPrice: '38.50',
|
||
|
|
priceChange: '-0.20',
|
||
|
|
priceChangePercent: '-0.52%',
|
||
|
|
priceDate: '2025-01-01',
|
||
|
|
priceTrend: [
|
||
|
|
{ date: '2024-12-19', price: 38.50 },
|
||
|
|
{ date: '2024-12-20', price: 36.90 },
|
||
|
|
{ date: '2024-12-21', price: 39.50 },
|
||
|
|
{ date: '2024-12-22', price: 37.80 },
|
||
|
|
{ date: '2024-12-23', price: 38.40 },
|
||
|
|
{ date: '2024-12-24', price: 40.20 },
|
||
|
|
{ date: '2024-12-25', price: 39.10 },
|
||
|
|
{ date: '2024-12-26', price: 37.50 },
|
||
|
|
{ date: '2024-12-27', price: 36.20 },
|
||
|
|
{ date: '2024-12-28', price: 39.90 },
|
||
|
|
{ date: '2024-12-29', price: 39.30 },
|
||
|
|
{ date: '2024-12-30', price: 36.60 },
|
||
|
|
{ date: '2024-12-31', price: 38.70 },
|
||
|
|
{ date: '2025-01-01', price: 38.30 }
|
||
|
|
],
|
||
|
|
provincePrices: [
|
||
|
|
{ province: '上海市', price: 40 },
|
||
|
|
{ province: '云南省', price: 38.85 },
|
||
|
|
{ province: '内蒙古自治区', price: 38.85 },
|
||
|
|
{ province: '北京市', price: 40.7 },
|
||
|
|
{ province: '吉林省', price: 38.26 },
|
||
|
|
{ province: '四川省', price: 39.9 },
|
||
|
|
{ province: '天津市', price: 40.4 },
|
||
|
|
{ province: '宁夏回族自治区', price: 41.51 },
|
||
|
|
{ province: '安徽省', price: 38.5 },
|
||
|
|
{ province: '山东省', price: 40.4 },
|
||
|
|
{ province: '山西省', price: 40.8 },
|
||
|
|
{ province: '广东省', price: 40.3 },
|
||
|
|
{ province: '广西壮族自治区', price: 37.6 },
|
||
|
|
{ province: '新疆维吾尔自治区', price: 40.8 },
|
||
|
|
{ province: '江苏省', price: 39.1 },
|
||
|
|
{ province: '江西省', price: 40.2 },
|
||
|
|
{ province: '河北省', price: 38.2 },
|
||
|
|
{ province: '河南省', price: 41 },
|
||
|
|
{ province: '浙江省', price: 40 },
|
||
|
|
{ province: '海南省', price: 40.4 },
|
||
|
|
{ province: '湖北省', price: 37 },
|
||
|
|
{ province: '湖南省', price: 38.2 },
|
||
|
|
{ province: '甘肃省', price: 39.8 },
|
||
|
|
{ province: '福建省', price: 37.86 },
|
||
|
|
{ province: '贵州省', price: 37.7 },
|
||
|
|
{ province: '辽宁省', price: 38 },
|
||
|
|
{ province: '重庆市', price: 37.8 },
|
||
|
|
{ province: '陕西省', price: 38.4 },
|
||
|
|
{ province: '青海省', price: 38 },
|
||
|
|
{ province: '黑龙江省', price: 40.4 }
|
||
|
|
]
|
||
|
|
};
|
||
|
|
}
|
||
|
|
// 奶牛数据
|
||
|
|
else if (type === 'milk') {
|
||
|
|
priceData = {
|
||
|
|
type: 'milk',
|
||
|
|
typeText: '奶牛',
|
||
|
|
currentPrice: '32.80',
|
||
|
|
priceChange: '+0.15',
|
||
|
|
priceChangePercent: '+0.46%',
|
||
|
|
priceDate: '2025-01-01',
|
||
|
|
priceTrend: [
|
||
|
|
{ date: '2024-12-19', price: 32.80 },
|
||
|
|
{ date: '2024-12-20', price: 30.90 },
|
||
|
|
{ date: '2024-12-21', price: 33.50 },
|
||
|
|
{ date: '2024-12-22', price: 31.80 },
|
||
|
|
{ date: '2024-12-23', price: 32.40 },
|
||
|
|
{ date: '2024-12-24', price: 34.20 },
|
||
|
|
{ date: '2024-12-25', price: 33.10 },
|
||
|
|
{ date: '2024-12-26', price: 31.50 },
|
||
|
|
{ date: '2024-12-27', price: 30.20 },
|
||
|
|
{ date: '2024-12-28', price: 33.90 },
|
||
|
|
{ date: '2024-12-29', price: 33.30 },
|
||
|
|
{ date: '2024-12-30', price: 30.60 },
|
||
|
|
{ date: '2024-12-31', price: 32.70 },
|
||
|
|
{ date: '2025-01-01', price: 32.30 }
|
||
|
|
],
|
||
|
|
provincePrices: [
|
||
|
|
{ province: '上海市', price: 45 },
|
||
|
|
{ province: '云南省', price: 43.85 },
|
||
|
|
{ province: '内蒙古自治区', price: 43.85 },
|
||
|
|
{ province: '北京市', price: 44.7 },
|
||
|
|
{ province: '吉林省', price: 42.26 },
|
||
|
|
{ province: '四川省', price: 43.9 },
|
||
|
|
{ province: '天津市', price: 44.4 },
|
||
|
|
{ province: '宁夏回族自治区', price: 45.51 },
|
||
|
|
{ province: '安徽省', price: 42.5 },
|
||
|
|
{ province: '山东省', price: 44.4 },
|
||
|
|
{ province: '山西省', price: 44.8 },
|
||
|
|
{ province: '广东省', price: 44.3 },
|
||
|
|
{ province: '广西壮族自治区', price: 41.6 },
|
||
|
|
{ province: '新疆维吾尔自治区', price: 44.8 },
|
||
|
|
{ province: '江苏省', price: 43.1 },
|
||
|
|
{ province: '江西省', price: 44.2 },
|
||
|
|
{ province: '河北省', price: 42.2 },
|
||
|
|
{ province: '河南省', price: 45 },
|
||
|
|
{ province: '浙江省', price: 44 },
|
||
|
|
{ province: '海南省', price: 44.4 },
|
||
|
|
{ province: '湖北省', price: 41 },
|
||
|
|
{ province: '湖南省', price: 42.2 },
|
||
|
|
{ province: '甘肃省', price: 43.8 },
|
||
|
|
{ province: '福建省', price: 41.86 },
|
||
|
|
{ province: '贵州省', price: 41.7 },
|
||
|
|
{ province: '辽宁省', price: 42 },
|
||
|
|
{ province: '重庆市', price: 41.8 },
|
||
|
|
{ province: '陕西省', price: 42.4 },
|
||
|
|
{ province: '青海省', price: 42 },
|
||
|
|
{ province: '黑龙江省', price: 44.4 }
|
||
|
|
]
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
res.json(priceData);
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 获取所有部门及其岗位
|
||
|
|
const getDepartments = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const departments = await Department.findAll({
|
||
|
|
include: [
|
||
|
|
{
|
||
|
|
model: Position,
|
||
|
|
as: 'positions'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
});
|
||
|
|
|
||
|
|
// 转换数据格式以便前端使用
|
||
|
|
const formattedData = departments.map(dept => ({
|
||
|
|
id: dept.id,
|
||
|
|
name: dept.name,
|
||
|
|
description: dept.description,
|
||
|
|
positions: dept.positions.map(pos => ({
|
||
|
|
id: pos.id,
|
||
|
|
name: pos.name,
|
||
|
|
permission: pos.has_permission ? '已设置权限' : '未设置权限',
|
||
|
|
permission_details: pos.permission_details
|
||
|
|
}))
|
||
|
|
}));
|
||
|
|
|
||
|
|
res.json(formattedData);
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 新增部门
|
||
|
|
const createDepartment = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { name, description } = req.body;
|
||
|
|
|
||
|
|
const department = await Department.create({
|
||
|
|
name,
|
||
|
|
description,
|
||
|
|
created_by: req.user?.id || null,
|
||
|
|
updated_by: req.user?.id || null
|
||
|
|
});
|
||
|
|
|
||
|
|
res.status(201).json(department);
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 编辑部门
|
||
|
|
const updateDepartment = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
const { name, description } = req.body;
|
||
|
|
|
||
|
|
const department = await Department.findByPk(id);
|
||
|
|
if (!department) {
|
||
|
|
return res.status(404).json({ message: '部门不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
department.name = name;
|
||
|
|
department.description = description;
|
||
|
|
department.updated_by = req.user?.id || null;
|
||
|
|
|
||
|
|
await department.save();
|
||
|
|
|
||
|
|
res.json(department);
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 删除部门
|
||
|
|
const deleteDepartment = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
|
||
|
|
const department = await Department.findByPk(id);
|
||
|
|
if (!department) {
|
||
|
|
return res.status(404).json({ message: '部门不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
// 先删除该部门下的所有岗位
|
||
|
|
await Position.destroy({
|
||
|
|
where: { department_id: id }
|
||
|
|
});
|
||
|
|
|
||
|
|
// 再删除部门
|
||
|
|
await department.destroy();
|
||
|
|
|
||
|
|
res.json({ message: '部门删除成功' });
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 新增岗位
|
||
|
|
const createPosition = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { department_id } = req.params;
|
||
|
|
const { name } = req.body;
|
||
|
|
|
||
|
|
// 检查部门是否存在
|
||
|
|
const department = await Department.findByPk(department_id);
|
||
|
|
if (!department) {
|
||
|
|
return res.status(404).json({ message: '部门不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
const position = await Position.create({
|
||
|
|
department_id,
|
||
|
|
name,
|
||
|
|
has_permission: false,
|
||
|
|
created_by: req.user?.id || null,
|
||
|
|
updated_by: req.user?.id || null
|
||
|
|
});
|
||
|
|
|
||
|
|
res.status(201).json({
|
||
|
|
id: position.id,
|
||
|
|
name: position.name,
|
||
|
|
permission: '未设置权限',
|
||
|
|
permission_details: position.permission_details
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 编辑岗位
|
||
|
|
const updatePosition = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
const { name } = req.body;
|
||
|
|
|
||
|
|
const position = await Position.findByPk(id);
|
||
|
|
if (!position) {
|
||
|
|
return res.status(404).json({ message: '岗位不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
position.name = name;
|
||
|
|
position.updated_by = req.user?.id || null;
|
||
|
|
|
||
|
|
await position.save();
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
id: position.id,
|
||
|
|
name: position.name,
|
||
|
|
permission: position.has_permission ? '已设置权限' : '未设置权限',
|
||
|
|
permission_details: position.permission_details
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 删除岗位
|
||
|
|
const deletePosition = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
|
||
|
|
const position = await Position.findByPk(id);
|
||
|
|
if (!position) {
|
||
|
|
return res.status(404).json({ message: '岗位不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
await position.destroy();
|
||
|
|
|
||
|
|
res.json({ message: '岗位删除成功' });
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 设置岗位权限
|
||
|
|
const setPositionPermission = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
const { permission_details } = req.body;
|
||
|
|
|
||
|
|
const position = await Position.findByPk(id);
|
||
|
|
if (!position) {
|
||
|
|
return res.status(404).json({ message: '岗位不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
position.has_permission = true;
|
||
|
|
position.permission_details = permission_details;
|
||
|
|
position.updated_by = req.user?.id || null;
|
||
|
|
|
||
|
|
await position.save();
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
id: position.id,
|
||
|
|
name: position.name,
|
||
|
|
permission: '已设置权限',
|
||
|
|
permission_details: position.permission_details
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 行政人员相关接口
|
||
|
|
|
||
|
|
// 获取行政人员列表
|
||
|
|
const getAdminStaff = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { page = 1, pageSize = 10, search = '' } = req.query;
|
||
|
|
|
||
|
|
const whereCondition = {};
|
||
|
|
if (search) {
|
||
|
|
whereCondition.name = {
|
||
|
|
[Op.like]: `%${search}%`
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
const offset = (page - 1) * pageSize;
|
||
|
|
|
||
|
|
const { count, rows } = await AdminStaff.findAndCountAll({
|
||
|
|
where: whereCondition,
|
||
|
|
include: [
|
||
|
|
{
|
||
|
|
model: Department,
|
||
|
|
as: 'department',
|
||
|
|
attributes: ['name']
|
||
|
|
},
|
||
|
|
{
|
||
|
|
model: Position,
|
||
|
|
as: 'position',
|
||
|
|
attributes: ['name']
|
||
|
|
}
|
||
|
|
],
|
||
|
|
offset,
|
||
|
|
limit: parseInt(pageSize),
|
||
|
|
order: [['createdAt', 'DESC']]
|
||
|
|
});
|
||
|
|
|
||
|
|
// 格式化数据以便前端使用
|
||
|
|
const formattedData = rows.map(staff => ({
|
||
|
|
id: staff.id,
|
||
|
|
key: staff.id.toString(),
|
||
|
|
name: staff.name,
|
||
|
|
department: staff.department?.name || '',
|
||
|
|
position: staff.position?.name || '',
|
||
|
|
phone: staff.phone,
|
||
|
|
idCard: staff.id_card || '--',
|
||
|
|
status: staff.status,
|
||
|
|
createdAt: staff.createdAt.toLocaleString('zh-CN')
|
||
|
|
}));
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
data: formattedData,
|
||
|
|
total: count,
|
||
|
|
page: parseInt(page),
|
||
|
|
pageSize: parseInt(pageSize)
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('获取行政人员列表失败:', error);
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 新增行政人员
|
||
|
|
const createAdminStaff = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { name, department_id, position_id, phone, id_card, status } = req.body;
|
||
|
|
|
||
|
|
const staff = await AdminStaff.create({
|
||
|
|
name,
|
||
|
|
department_id,
|
||
|
|
position_id,
|
||
|
|
phone,
|
||
|
|
id_card,
|
||
|
|
status: status !== undefined ? status : true
|
||
|
|
});
|
||
|
|
|
||
|
|
res.status(201).json({
|
||
|
|
success: true,
|
||
|
|
message: '行政人员创建成功',
|
||
|
|
data: staff
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('创建行政人员失败:', error);
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 编辑行政人员
|
||
|
|
const updateAdminStaff = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
const { name, department_id, position_id, phone, id_card, status } = req.body;
|
||
|
|
|
||
|
|
const staff = await AdminStaff.findByPk(id);
|
||
|
|
if (!staff) {
|
||
|
|
return res.status(404).json({ message: '行政人员不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
await staff.update({
|
||
|
|
name,
|
||
|
|
department_id,
|
||
|
|
position_id,
|
||
|
|
phone,
|
||
|
|
id_card,
|
||
|
|
status
|
||
|
|
});
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
success: true,
|
||
|
|
message: '行政人员更新成功',
|
||
|
|
data: staff
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('更新行政人员失败:', error);
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 删除行政人员
|
||
|
|
const deleteAdminStaff = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
|
||
|
|
const staff = await AdminStaff.findByPk(id);
|
||
|
|
if (!staff) {
|
||
|
|
return res.status(404).json({ message: '行政人员不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
await staff.destroy();
|
||
|
|
|
||
|
|
res.json({
|
||
|
|
success: true,
|
||
|
|
message: '行政人员删除成功'
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('删除行政人员失败:', error);
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 重置行政人员密码
|
||
|
|
const resetAdminStaffPassword = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const { id } = req.params;
|
||
|
|
|
||
|
|
const staff = await AdminStaff.findByPk(id);
|
||
|
|
if (!staff) {
|
||
|
|
return res.status(404).json({ message: '行政人员不存在' });
|
||
|
|
}
|
||
|
|
|
||
|
|
// 在实际应用中,这里应该生成一个临时密码并发送给用户
|
||
|
|
// 为了演示,我们只返回成功信息
|
||
|
|
res.json({
|
||
|
|
success: true,
|
||
|
|
message: '密码重置成功,新密码已发送到用户手机'
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
console.error('重置密码失败:', error);
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 获取所有岗位列表
|
||
|
|
const getPositions = async (req, res) => {
|
||
|
|
try {
|
||
|
|
const positions = await Position.findAll({
|
||
|
|
include: [
|
||
|
|
{
|
||
|
|
model: Department,
|
||
|
|
as: 'department'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
});
|
||
|
|
|
||
|
|
// 转换数据格式以便前端使用
|
||
|
|
const formattedData = positions.map(pos => ({
|
||
|
|
id: pos.id,
|
||
|
|
name: pos.name,
|
||
|
|
department_id: pos.department_id,
|
||
|
|
department_name: pos.department?.name || '',
|
||
|
|
permission: pos.has_permission ? '已设置权限' : '未设置权限',
|
||
|
|
permission_details: pos.permission_details
|
||
|
|
}));
|
||
|
|
|
||
|
|
res.json(formattedData);
|
||
|
|
} catch (error) {
|
||
|
|
res.status(500).json({ message: error.message });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 导出模块
|
||
|
|
module.exports = {
|
||
|
|
getDataCenterStats,
|
||
|
|
getMarketPrice,
|
||
|
|
getDepartments,
|
||
|
|
getPositions,
|
||
|
|
createDepartment,
|
||
|
|
updateDepartment,
|
||
|
|
deleteDepartment,
|
||
|
|
createPosition,
|
||
|
|
updatePosition,
|
||
|
|
deletePosition,
|
||
|
|
setPositionPermission,
|
||
|
|
getAdminStaff,
|
||
|
|
createAdminStaff,
|
||
|
|
updateAdminStaff,
|
||
|
|
deleteAdminStaff,
|
||
|
|
resetAdminStaffPassword
|
||
|
|
};
|