diff --git a/server/src/app.ts b/server/src/app.ts index 3eb0280..1e9b06e 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -12,6 +12,12 @@ const app = express(); // 连接数据库 connectDB(); +// 添加请求日志中间件 (放在最前面) +app.use((req, res, next) => { + console.log(`收到请求: ${req.method} ${req.url}`); + next(); +}); + // 中间件 app.use(cors({ origin: 'http://localhost:5173', @@ -20,8 +26,8 @@ app.use(cors({ app.use(express.json()); // 路由 -app.use('/api/todos', todoRoutes); -app.use('/api/auth', authRoutes); +app.use('/todos', todoRoutes); +app.use('/auth', authRoutes); // 错误处理中间件 app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => { diff --git a/server/src/controllers/todoController.ts b/server/src/controllers/todoController.ts index 37edb94..93f96ba 100644 --- a/server/src/controllers/todoController.ts +++ b/server/src/controllers/todoController.ts @@ -1,6 +1,7 @@ import { Request, Response, NextFunction } from 'express'; import Todo, { ITodo } from '../models/Todo'; import jwt from 'jsonwebtoken'; +import mongoose from 'mongoose'; // 导入 mongoose const JWT_SECRET = process.env.JWT_SECRET || 'secret_key'; @@ -22,62 +23,100 @@ export const authMiddleware = (req: any, res: Response, next: NextFunction): voi }; // 获取所有待办事项(只返回当前用户的) -export const getAllTodos = async (req: Request & { user?: any }, res: Response) => { +export const getAllTodos = async (req: Request & { user?: any }, res: Response): Promise => { try { const todos = await Todo.find({ user: req.user.userId }).sort({ createdAt: -1 }); - res.status(200).json(todos); + return res.status(200).json(todos); } catch (error) { - res.status(500).json({ message: '获取待办事项失败', error }); + console.error("Error in getAllTodos:", error); + return res.status(500).json({ message: '获取待办事项失败', error }); } }; // 创建新的待办事项(自动绑定 user) -export const createTodo = async (req: Request & { user?: any }, res: Response) => { +export const createTodo = async (req: Request & { user?: any }, res: Response): Promise => { try { - const { title, priority = 'medium' } = req.body; + const { title, description = '', priority = 'medium' } = req.body; const todo = new Todo({ title, + description, priority, user: req.user.userId }); const savedTodo = await todo.save(); - res.status(201).json(savedTodo); + return res.status(201).json(savedTodo); } catch (error) { - res.status(400).json({ message: '创建待办事项失败', error }); + console.error("Error in createTodo:", error); + return res.status(400).json({ message: '创建待办事项失败', error }); } }; // 更新待办事项 -export const updateTodo = async (req: Request & { user?: any }, res: Response) => { +export const updateTodo = async (req: Request & { user?: any }, res: Response): Promise => { try { - const todo = await Todo.findOne({ _id: req.params.id, user: req.user.userId }); + const { id } = req.params; // 使用 id 作为参数名,便于匹配 + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).json({ message: '无效的待办事项 ID' }); + } + + const todo = await Todo.findOne({ _id: id, user: req.user.userId }); if (!todo) { - return res.status(404).json({ message: '待办事项不存在' }); + return res.status(404).json({ message: '待办事项不存在或无权访问' }); } const updatedTodo = await Todo.findByIdAndUpdate( - req.params.id, + id, { ...req.body }, { new: true, runValidators: true } ); - res.status(200).json(updatedTodo); + return res.status(200).json(updatedTodo); } catch (error) { - res.status(400).json({ message: '更新待办事项失败', error }); + console.error("Error in updateTodo:", error); + return res.status(400).json({ message: '更新待办事项失败', error }); + } +}; + +// 切换待办事项完成状态 +export const toggleTodoStatus = async (req: Request & { user?: any }, res: Response): Promise => { + try { + const { id } = req.params; + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).json({ message: '无效的待办事项 ID' }); + } + + const todo = await Todo.findOne({ _id: id, user: req.user.userId }); + if (!todo) { + return res.status(404).json({ message: '待办事项不存在或无权访问' }); + } + + todo.completed = !todo.completed; // 切换完成状态 + const updatedTodo = await todo.save(); + + return res.status(200).json(updatedTodo); + } catch (error) { + console.error("Error in toggleTodoStatus:", error); + return res.status(400).json({ message: '切换状态失败', error }); } }; // 删除待办事项 -export const deleteTodo = async (req: Request & { user?: any }, res: Response) => { +export const deleteTodo = async (req: Request & { user?: any }, res: Response): Promise => { try { - const todo = await Todo.findOne({ _id: req.params.id, user: req.user.userId }); - if (!todo) { - return res.status(404).json({ message: '待办事项不存在' }); + const { id } = req.params; + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).json({ message: '无效的待办事项 ID' }); } - await Todo.findByIdAndDelete(req.params.id); - res.status(200).json({ message: '待办事项已删除' }); + const todo = await Todo.findOne({ _id: id, user: req.user.userId }); + if (!todo) { + return res.status(404).json({ message: '待办事项不存在或无权访问' }); + } + + await Todo.findByIdAndDelete(id); + return res.status(200).json({ message: '待办事项已删除' }); } catch (error) { - res.status(400).json({ message: '删除待办事项失败', error }); + console.error("Error in deleteTodo:", error); + return res.status(400).json({ message: '删除待办事项失败', error }); } }; \ No newline at end of file diff --git a/server/src/routes/todoRoutes.ts b/server/src/routes/todoRoutes.ts index 04aa88d..6d333f7 100644 --- a/server/src/routes/todoRoutes.ts +++ b/server/src/routes/todoRoutes.ts @@ -4,6 +4,7 @@ import { createTodo, updateTodo, deleteTodo, + toggleTodoStatus, authMiddleware } from '../controllers/todoController'; @@ -12,6 +13,7 @@ const router = Router(); router.get('/', authMiddleware, getAllTodos); router.post('/', authMiddleware, createTodo); router.put('/:id', authMiddleware, updateTodo); +router.patch('/:id/toggle', authMiddleware, toggleTodoStatus); router.delete('/:id', authMiddleware, deleteTodo); export default router; \ No newline at end of file