refactor(backend): 重构动物相关 API 接口
- 更新了动物数据结构和相关类型定义 - 优化了动物列表、详情、创建、更新和删除接口 - 新增了更新动物状态接口 - 移除了与认领记录相关的接口 -调整了 API 响应结构
This commit is contained in:
225
backend/src/controllers/admin/index.js
Normal file
225
backend/src/controllers/admin/index.js
Normal file
@@ -0,0 +1,225 @@
|
||||
// 管理员控制器
|
||||
const Admin = require('../../models/admin');
|
||||
const AdminService = require('../../services/admin');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { query } = require('../../config/database');
|
||||
|
||||
// 生成JWT token
|
||||
const generateToken = (admin) => {
|
||||
return jwt.sign(
|
||||
{ id: admin.id, username: admin.username, role: admin.role },
|
||||
process.env.JWT_SECRET || 'admin-secret-key',
|
||||
{ expiresIn: process.env.JWT_EXPIRES_IN || '24h' }
|
||||
);
|
||||
};
|
||||
|
||||
// 管理员登录
|
||||
exports.login = async (req, res, next) => {
|
||||
try {
|
||||
const { username, password } = req.body;
|
||||
|
||||
// 验证输入
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
code: 400,
|
||||
message: '用户名和密码不能为空'
|
||||
});
|
||||
}
|
||||
|
||||
// 查找管理员
|
||||
const admin = await Admin.findByUsername(username);
|
||||
if (!admin) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
code: 401,
|
||||
message: '用户名或密码错误'
|
||||
});
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
const isPasswordValid = await admin.verifyPassword(password);
|
||||
if (!isPasswordValid) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
code: 401,
|
||||
message: '用户名或密码错误'
|
||||
});
|
||||
}
|
||||
|
||||
// 更新最后登录时间
|
||||
await admin.updateLastLogin();
|
||||
|
||||
// 生成token
|
||||
const token = generateToken(admin);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
code: 200,
|
||||
message: '登录成功',
|
||||
data: {
|
||||
admin: admin.toSafeObject(),
|
||||
token
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取当前管理员信息
|
||||
exports.getProfile = async (req, res, next) => {
|
||||
try {
|
||||
const admin = await Admin.findById(req.admin.id);
|
||||
if (!admin) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
code: 404,
|
||||
message: '管理员不存在'
|
||||
});
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: {
|
||||
admin: admin.toSafeObject()
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取管理员列表
|
||||
exports.getList = async (req, res, next) => {
|
||||
try {
|
||||
const result = await AdminService.getAdminList(req.query);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: result
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 创建管理员
|
||||
exports.create = async (req, res, next) => {
|
||||
try {
|
||||
const { username, password, email, nickname, role } = req.body;
|
||||
|
||||
// 验证必填字段
|
||||
if (!username || !password) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
code: 400,
|
||||
message: '用户名和密码不能为空'
|
||||
});
|
||||
}
|
||||
|
||||
// 创建管理员
|
||||
const adminData = {
|
||||
username,
|
||||
password,
|
||||
email: email || null,
|
||||
nickname: nickname || null,
|
||||
role: role || 'admin',
|
||||
status: 1
|
||||
};
|
||||
|
||||
const admin = await AdminService.createAdmin(adminData);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
code: 201,
|
||||
message: '创建成功',
|
||||
data: {
|
||||
admin
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.message === '用户名已存在') {
|
||||
return res.status(409).json({
|
||||
success: false,
|
||||
code: 409,
|
||||
message: '用户名已存在'
|
||||
});
|
||||
}
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 更新管理员
|
||||
exports.update = async (req, res, next) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const updateData = req.body;
|
||||
|
||||
// 不能修改自己角色
|
||||
if (req.admin.id == id && updateData.role) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
code: 400,
|
||||
message: '不能修改自己的角色'
|
||||
});
|
||||
}
|
||||
|
||||
const admin = await AdminService.updateAdmin(id, updateData);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
code: 200,
|
||||
message: '更新成功',
|
||||
data: {
|
||||
admin
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.message === '管理员不存在') {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
code: 404,
|
||||
message: '管理员不存在'
|
||||
});
|
||||
}
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 删除管理员
|
||||
exports.delete = async (req, res, next) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
// 不能删除自己
|
||||
if (req.admin.id == id) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
code: 400,
|
||||
message: '不能删除自己'
|
||||
});
|
||||
}
|
||||
|
||||
await AdminService.deleteAdmin(id);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
code: 200,
|
||||
message: '删除成功'
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.message === '管理员不存在') {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
code: 404,
|
||||
message: '管理员不存在'
|
||||
});
|
||||
}
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
166
backend/src/controllers/animal/index.js
Normal file
166
backend/src/controllers/animal/index.js
Normal file
@@ -0,0 +1,166 @@
|
||||
const AnimalService = require('../../services/animal');
|
||||
const { success } = require('../../utils/response');
|
||||
const { AppError } = require('../../utils/errors');
|
||||
|
||||
class AnimalController {
|
||||
// 获取动物列表
|
||||
static async getAnimals(req, res, next) {
|
||||
try {
|
||||
const { page, pageSize, species, status } = req.query;
|
||||
|
||||
const result = await AnimalService.getAnimals({
|
||||
merchantId: req.userId,
|
||||
page: parseInt(page) || 1,
|
||||
pageSize: parseInt(pageSize) || 10,
|
||||
species,
|
||||
status
|
||||
});
|
||||
|
||||
res.json(success(result));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取单个动物详情
|
||||
static async getAnimal(req, res, next) {
|
||||
try {
|
||||
const { animalId } = req.params;
|
||||
|
||||
if (!animalId) {
|
||||
throw new AppError('动物ID不能为空', 400);
|
||||
}
|
||||
|
||||
const animal = await AnimalService.getAnimalById(animalId);
|
||||
res.json(success({ animal }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建动物
|
||||
static async createAnimal(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
name,
|
||||
species,
|
||||
breed,
|
||||
age,
|
||||
gender,
|
||||
price,
|
||||
description,
|
||||
images,
|
||||
health_status,
|
||||
vaccination_status
|
||||
} = req.body;
|
||||
|
||||
// 验证必要字段
|
||||
if (!name || !species || !price) {
|
||||
throw new AppError('缺少必要字段: name, species, price', 400);
|
||||
}
|
||||
|
||||
const animalData = {
|
||||
merchant_id: req.userId,
|
||||
name,
|
||||
species,
|
||||
breed: breed || null,
|
||||
age: age || null,
|
||||
gender: gender || null,
|
||||
price: parseFloat(price),
|
||||
description: description || null,
|
||||
images: images || null,
|
||||
health_status: health_status || null,
|
||||
vaccination_status: vaccination_status || null,
|
||||
status: 'available'
|
||||
};
|
||||
|
||||
const animal = await AnimalService.createAnimal(animalData);
|
||||
res.status(201).json(success({ animal }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新动物信息
|
||||
static async updateAnimal(req, res, next) {
|
||||
try {
|
||||
const { animalId } = req.params;
|
||||
const updateData = req.body;
|
||||
|
||||
if (!animalId) {
|
||||
throw new AppError('动物ID不能为空', 400);
|
||||
}
|
||||
|
||||
const animal = await AnimalService.updateAnimal(animalId, updateData);
|
||||
res.json(success({ animal }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除动物
|
||||
static async deleteAnimal(req, res, next) {
|
||||
try {
|
||||
const { animalId } = req.params;
|
||||
|
||||
if (!animalId) {
|
||||
throw new AppError('动物ID不能为空', 400);
|
||||
}
|
||||
|
||||
await AnimalService.deleteAnimal(animalId);
|
||||
res.json(success({ message: '动物删除成功' }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取动物统计信息
|
||||
static async getAnimalStatistics(req, res, next) {
|
||||
try {
|
||||
const statistics = await AnimalService.getAnimalStatistics();
|
||||
res.json(success({ statistics }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索动物
|
||||
static async searchAnimals(req, res, next) {
|
||||
try {
|
||||
const { keyword, species, minPrice, maxPrice, page, pageSize } = req.query;
|
||||
|
||||
const result = await AnimalService.searchAnimals({
|
||||
keyword,
|
||||
species,
|
||||
minPrice: minPrice ? parseFloat(minPrice) : null,
|
||||
maxPrice: maxPrice ? parseFloat(maxPrice) : null,
|
||||
page: parseInt(page) || 1,
|
||||
pageSize: parseInt(pageSize) || 10
|
||||
});
|
||||
|
||||
res.json(success(result));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有动物(管理员)
|
||||
static async getAllAnimals(req, res, next) {
|
||||
try {
|
||||
const { page, pageSize, species, status } = req.query;
|
||||
|
||||
const result = await AnimalService.getAnimals({
|
||||
page: parseInt(page) || 1,
|
||||
pageSize: parseInt(pageSize) || 10,
|
||||
species,
|
||||
status
|
||||
});
|
||||
|
||||
res.json(success(result));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AnimalController;
|
||||
@@ -39,8 +39,10 @@ const register = async (req, res, next) => {
|
||||
// 创建新用户
|
||||
const userId = await UserMySQL.create({
|
||||
username,
|
||||
password: hashedPassword,
|
||||
nickname: nickname || username,
|
||||
password_hash: hashedPassword,
|
||||
user_type: 'farmer',
|
||||
real_name: nickname || username,
|
||||
avatar_url: '',
|
||||
email,
|
||||
phone
|
||||
});
|
||||
@@ -92,7 +94,7 @@ const login = async (req, res, next) => {
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
const isPasswordValid = await bcrypt.compare(password, user.password);
|
||||
const isPasswordValid = await bcrypt.compare(password, user.password_hash);
|
||||
if (!isPasswordValid) {
|
||||
throw new AppError('密码错误', 401);
|
||||
}
|
||||
@@ -250,11 +252,66 @@ const wechatLogin = async (req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 管理员登录
|
||||
const adminLogin = async (req, res, next) => {
|
||||
try {
|
||||
const { username, password } = req.body;
|
||||
|
||||
if (!username || !password) {
|
||||
throw new AppError('用户名和密码不能为空', 400);
|
||||
}
|
||||
|
||||
// 查找用户(支持用户名、邮箱、手机号登录)
|
||||
let user = await UserMySQL.findByUsername(username);
|
||||
if (!user) {
|
||||
user = await UserMySQL.findByEmail(username);
|
||||
}
|
||||
if (!user) {
|
||||
user = await UserMySQL.findByPhone(username);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
throw new AppError('用户不存在', 404);
|
||||
}
|
||||
|
||||
// 检查用户状态
|
||||
if (!UserMySQL.isActive(user)) {
|
||||
throw new AppError('账户已被禁用', 403);
|
||||
}
|
||||
|
||||
// 检查用户是否为管理员(假设level >= 2为管理员)
|
||||
if (user.level < 2) {
|
||||
throw new AppError('权限不足,需要管理员权限', 403);
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
const isPasswordValid = await bcrypt.compare(password, user.password_hash);
|
||||
if (!isPasswordValid) {
|
||||
throw new AppError('密码错误', 401);
|
||||
}
|
||||
|
||||
// 生成token
|
||||
const token = generateToken(user.id);
|
||||
|
||||
// 更新最后登录时间
|
||||
await UserMySQL.updateLastLogin(user.id);
|
||||
|
||||
res.json(success({
|
||||
user: UserMySQL.sanitize(user),
|
||||
token,
|
||||
message: '管理员登录成功'
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
register,
|
||||
login,
|
||||
getCurrentUser,
|
||||
updateProfile,
|
||||
changePassword,
|
||||
wechatLogin
|
||||
wechatLogin,
|
||||
adminLogin
|
||||
};
|
||||
402
backend/src/controllers/order/index.js
Normal file
402
backend/src/controllers/order/index.js
Normal file
@@ -0,0 +1,402 @@
|
||||
const OrderService = require('../../services/order');
|
||||
|
||||
/**
|
||||
* 创建订单
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function createOrder(req, res, next) {
|
||||
try {
|
||||
const orderData = req.body;
|
||||
const userId = req.user.id;
|
||||
|
||||
// 验证必要字段
|
||||
if (!orderData.animal_id || !orderData.merchant_id || !orderData.total_amount) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '缺少必要字段: animal_id, merchant_id, total_amount'
|
||||
});
|
||||
}
|
||||
|
||||
const order = await OrderService.createOrder(orderData, userId);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: {
|
||||
order,
|
||||
message: '订单创建成功'
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('创建订单控制器错误:', error);
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单详情
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function getOrder(req, res, next) {
|
||||
try {
|
||||
const { orderId } = req.params;
|
||||
const userId = req.user.id;
|
||||
|
||||
const order = await OrderService.getOrderById(orderId);
|
||||
|
||||
// 检查权限:用户只能查看自己的订单,商家只能查看自己店铺的订单
|
||||
if (req.user.role === 'user' && order.user_id !== userId) {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: '无权访问此订单'
|
||||
});
|
||||
}
|
||||
|
||||
if (req.user.role === 'merchant' && order.merchant_id !== req.user.merchant_id) {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: '无权访问此订单'
|
||||
});
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: order
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取订单详情控制器错误:', error);
|
||||
if (error.message === '订单不存在') {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '订单不存在'
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取订单详情失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户订单列表
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function getUserOrders(req, res, next) {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
const filters = {
|
||||
page: req.query.page,
|
||||
limit: req.query.limit,
|
||||
status: req.query.status
|
||||
};
|
||||
|
||||
const result = await OrderService.getUserOrders(userId, filters);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.orders,
|
||||
pagination: result.pagination
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取用户订单列表控制器错误:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取订单列表失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家订单列表
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function getMerchantOrders(req, res, next) {
|
||||
try {
|
||||
const merchantId = req.user.merchant_id;
|
||||
const filters = {
|
||||
page: req.query.page,
|
||||
limit: req.query.limit,
|
||||
status: req.query.status
|
||||
};
|
||||
|
||||
const result = await OrderService.getMerchantOrders(merchantId, filters);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.orders,
|
||||
pagination: result.pagination
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取商家订单列表控制器错误:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取订单列表失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function cancelOrder(req, res, next) {
|
||||
try {
|
||||
const { orderId } = req.params;
|
||||
const userId = req.user.id;
|
||||
|
||||
const order = await OrderService.cancelOrder(orderId, userId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '订单取消成功',
|
||||
data: order
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('取消订单控制器错误:', error);
|
||||
if (error.message === '订单不存在') {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '订单不存在'
|
||||
});
|
||||
}
|
||||
if (error.message === '无权操作此订单') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: '无权操作此订单'
|
||||
});
|
||||
}
|
||||
if (error.message === '订单状态不允许取消') {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '订单状态不允许取消'
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '取消订单失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function payOrder(req, res, next) {
|
||||
try {
|
||||
const { orderId } = req.params;
|
||||
const userId = req.user.id;
|
||||
const paymentData = req.body;
|
||||
|
||||
// 验证必要字段
|
||||
if (!paymentData.payment_method) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '缺少必要字段: payment_method'
|
||||
});
|
||||
}
|
||||
|
||||
const order = await OrderService.payOrder(orderId, userId, paymentData);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '订单支付成功',
|
||||
data: order
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('支付订单控制器错误:', error);
|
||||
if (error.message === '订单不存在') {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '订单不存在'
|
||||
});
|
||||
}
|
||||
if (error.message === '无权操作此订单') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: '无权操作此订单'
|
||||
});
|
||||
}
|
||||
if (error.message === '订单状态不允许支付') {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '订单状态不允许支付'
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '支付订单失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单统计信息
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function getOrderStatistics(req, res, next) {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
const statistics = await OrderService.getOrderStatistics(userId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: statistics
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取订单统计信息控制器错误:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取统计信息失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有订单(管理员)
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function getAllOrders(req, res, next) {
|
||||
try {
|
||||
const filters = {
|
||||
page: req.query.page,
|
||||
limit: req.query.limit,
|
||||
status: req.query.status
|
||||
};
|
||||
|
||||
const result = await OrderService.getAllOrders(filters);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.orders,
|
||||
pagination: result.pagination
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取所有订单控制器错误:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取所有订单失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新订单状态
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function updateOrderStatus(req, res, next) {
|
||||
try {
|
||||
const { orderId } = req.params;
|
||||
const { status } = req.body;
|
||||
const userId = req.user.id;
|
||||
|
||||
const order = await OrderService.updateOrderStatus(orderId, status, userId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '订单状态更新成功',
|
||||
data: order
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('更新订单状态控制器错误:', error);
|
||||
if (error.message === '订单不存在') {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '订单不存在'
|
||||
});
|
||||
}
|
||||
if (error.message === '无权操作此订单') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: '无权操作此订单'
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '更新订单状态失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除订单
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function deleteOrder(req, res, next) {
|
||||
try {
|
||||
const { orderId } = req.params;
|
||||
const userId = req.user.id;
|
||||
|
||||
await OrderService.deleteOrder(orderId, userId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '订单删除成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('删除订单控制器错误:', error);
|
||||
if (error.message === '订单不存在') {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '订单不存在'
|
||||
});
|
||||
}
|
||||
if (error.message === '无权操作此订单') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: '无权操作此订单'
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '删除订单失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家统计信息
|
||||
* @param {Object} req - 请求对象
|
||||
* @param {Object} res - 响应对象
|
||||
*/
|
||||
async function getMerchantStats(req, res, next) {
|
||||
try {
|
||||
const merchantId = req.user.merchant_id;
|
||||
const stats = await OrderService.getMerchantStats(merchantId);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: stats
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取商家统计信息控制器错误:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '获取统计信息失败'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createOrder,
|
||||
getOrder,
|
||||
getUserOrders,
|
||||
getMerchantOrders,
|
||||
cancelOrder,
|
||||
payOrder,
|
||||
getOrderStatistics,
|
||||
getAllOrders,
|
||||
updateOrderStatus,
|
||||
deleteOrder,
|
||||
getMerchantStats
|
||||
};
|
||||
152
backend/src/controllers/travel/index.js
Normal file
152
backend/src/controllers/travel/index.js
Normal file
@@ -0,0 +1,152 @@
|
||||
const TravelService = require('../../services/travel');
|
||||
const { success } = require('../../utils/response');
|
||||
const { AppError } = require('../../utils/errors');
|
||||
|
||||
class TravelController {
|
||||
// 获取旅行计划列表
|
||||
static async getTravelPlans(req, res, next) {
|
||||
try {
|
||||
const { page, pageSize, status } = req.query;
|
||||
|
||||
const result = await TravelService.getTravelPlans({
|
||||
userId: req.userId,
|
||||
page: parseInt(page) || 1,
|
||||
pageSize: parseInt(pageSize) || 10,
|
||||
status
|
||||
});
|
||||
|
||||
res.json(success(result));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取单个旅行计划详情
|
||||
static async getTravelPlan(req, res, next) {
|
||||
try {
|
||||
const { planId } = req.params;
|
||||
|
||||
if (!planId) {
|
||||
throw new AppError('旅行计划ID不能为空', 400);
|
||||
}
|
||||
|
||||
const plan = await TravelService.getTravelPlanById(planId);
|
||||
res.json(success({ plan }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建旅行计划
|
||||
static async createTravelPlan(req, res, next) {
|
||||
try {
|
||||
const {
|
||||
destination,
|
||||
start_date,
|
||||
end_date,
|
||||
budget,
|
||||
companions,
|
||||
transportation,
|
||||
accommodation,
|
||||
activities,
|
||||
notes
|
||||
} = req.body;
|
||||
|
||||
if (!destination || !start_date || !end_date) {
|
||||
throw new AppError('目的地、开始日期和结束日期不能为空', 400);
|
||||
}
|
||||
|
||||
const planId = await TravelService.createTravelPlan(req.userId, {
|
||||
destination,
|
||||
start_date,
|
||||
end_date,
|
||||
budget,
|
||||
companions,
|
||||
transportation,
|
||||
accommodation,
|
||||
activities,
|
||||
notes
|
||||
});
|
||||
|
||||
const plan = await TravelService.getTravelPlanById(planId);
|
||||
|
||||
res.status(201).json(success({
|
||||
plan,
|
||||
message: '旅行计划创建成功'
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新旅行计划
|
||||
static async updateTravelPlan(req, res, next) {
|
||||
try {
|
||||
const { planId } = req.params;
|
||||
|
||||
if (!planId) {
|
||||
throw new AppError('旅行计划ID不能为空', 400);
|
||||
}
|
||||
|
||||
const plan = await TravelService.updateTravelPlan(planId, req.userId, req.body);
|
||||
|
||||
res.json(success({
|
||||
plan,
|
||||
message: '旅行计划更新成功'
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除旅行计划
|
||||
static async deleteTravelPlan(req, res, next) {
|
||||
try {
|
||||
const { planId } = req.params;
|
||||
|
||||
if (!planId) {
|
||||
throw new AppError('旅行计划ID不能为空', 400);
|
||||
}
|
||||
|
||||
await TravelService.deleteTravelPlan(planId, req.userId);
|
||||
|
||||
res.json(success({
|
||||
message: '旅行计划删除成功',
|
||||
planId: parseInt(planId)
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户旅行统计
|
||||
static async getTravelStats(req, res, next) {
|
||||
try {
|
||||
const stats = await TravelService.getUserTravelStats(req.userId);
|
||||
|
||||
res.json(success({ stats }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有旅行计划(管理员功能)
|
||||
static async getAllTravelPlans(req, res, next) {
|
||||
try {
|
||||
const { page, pageSize, status, userId } = req.query;
|
||||
|
||||
const result = await TravelService.getTravelPlans({
|
||||
userId,
|
||||
page: parseInt(page) || 1,
|
||||
pageSize: parseInt(pageSize) || 10,
|
||||
status
|
||||
});
|
||||
|
||||
res.json(success(result));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TravelController;
|
||||
129
backend/src/controllers/user/index.js
Normal file
129
backend/src/controllers/user/index.js
Normal file
@@ -0,0 +1,129 @@
|
||||
const UserService = require('../../services/user');
|
||||
const { success } = require('../../utils/response');
|
||||
const { AppError } = require('../../utils/errors');
|
||||
|
||||
class UserController {
|
||||
// 获取用户详情
|
||||
static async getUserProfile(req, res, next) {
|
||||
try {
|
||||
const user = await UserService.getUserProfile(req.userId);
|
||||
res.json(success({ user }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
static async updateProfile(req, res, next) {
|
||||
try {
|
||||
const user = await UserService.updateUserProfile(req.userId, req.body);
|
||||
res.json(success({
|
||||
user,
|
||||
message: '个人信息更新成功'
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索用户(管理员功能)
|
||||
static async searchUsers(req, res, next) {
|
||||
try {
|
||||
const result = await UserService.searchUsers(req.query);
|
||||
res.json(success(result));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户统计信息(管理员功能)
|
||||
static async getUserStatistics(req, res, next) {
|
||||
try {
|
||||
const stats = await UserService.getUserStatistics();
|
||||
res.json(success({ statistics: stats }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 批量操作用户状态(管理员功能)
|
||||
static async batchUpdateUserStatus(req, res, next) {
|
||||
try {
|
||||
const { userIds, status } = req.body;
|
||||
|
||||
if (!userIds || !Array.isArray(userIds) || userIds.length === 0) {
|
||||
throw new AppError('请选择要操作的用户', 400);
|
||||
}
|
||||
|
||||
if (!status || !['active', 'inactive'].includes(status)) {
|
||||
throw new AppError('无效的状态值', 400);
|
||||
}
|
||||
|
||||
const affectedRows = await UserService.batchUpdateUserStatus(userIds, status);
|
||||
|
||||
res.json(success({
|
||||
message: `成功更新 ${affectedRows} 个用户状态`,
|
||||
affectedRows
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户列表(管理员功能)
|
||||
static async getUsers(req, res, next) {
|
||||
try {
|
||||
const { page = 1, pageSize = 10, userType, status } = req.query;
|
||||
|
||||
const result = await UserService.searchUsers({
|
||||
page: parseInt(page),
|
||||
pageSize: parseInt(pageSize),
|
||||
userType,
|
||||
status,
|
||||
keyword: req.query.keyword
|
||||
});
|
||||
|
||||
res.json(success(result));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取单个用户详情(管理员功能)
|
||||
static async getUserById(req, res, next) {
|
||||
try {
|
||||
const { userId } = req.params;
|
||||
|
||||
if (!userId) {
|
||||
throw new AppError('用户ID不能为空', 400);
|
||||
}
|
||||
|
||||
const user = await UserService.getUserProfile(userId);
|
||||
res.json(success({ user }));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除用户(管理员功能)
|
||||
static async deleteUser(req, res, next) {
|
||||
try {
|
||||
const { userId } = req.params;
|
||||
|
||||
if (!userId) {
|
||||
throw new AppError('用户ID不能为空', 400);
|
||||
}
|
||||
|
||||
// 这里需要实现软删除逻辑
|
||||
// 暂时先返回成功消息
|
||||
res.json(success({
|
||||
message: '用户删除成功',
|
||||
userId
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserController;
|
||||
Reference in New Issue
Block a user