177 lines
5.6 KiB
TypeScript
177 lines
5.6 KiB
TypeScript
import { Response } from 'express';
|
|
import { AuthRequest } from '../middleware/auth.middleware';
|
|
import prisma from '../utils/prisma';
|
|
|
|
// 获取消息列表
|
|
export const getMessages = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const userId = req.userId;
|
|
if (!userId) return res.status(401).json({ error: 'Unauthorized' });
|
|
|
|
const messages = await prisma.message.findMany({
|
|
where: { userId },
|
|
orderBy: { createdAt: 'desc' }
|
|
});
|
|
|
|
res.json(messages);
|
|
} catch (error) {
|
|
console.error('Get messages error:', error);
|
|
res.status(500).json({ error: 'Failed to get messages' });
|
|
}
|
|
};
|
|
|
|
// 标记消息为已读
|
|
export const markMessageRead = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const userId = req.userId;
|
|
|
|
const message = await prisma.message.findUnique({ where: { id } });
|
|
if (!message) return res.status(404).json({ error: 'Message not found' });
|
|
if (message.userId !== userId) return res.status(403).json({ error: 'Forbidden' });
|
|
|
|
await prisma.message.update({
|
|
where: { id },
|
|
data: { isRead: true }
|
|
});
|
|
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
console.error('Mark message read error:', error);
|
|
res.status(500).json({ error: 'Failed to mark message read' });
|
|
}
|
|
};
|
|
|
|
// 创建消息
|
|
export const createMessage = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const userId = req.userId;
|
|
const { title, content, type } = req.body;
|
|
|
|
if (!userId) return res.status(401).json({ error: 'Unauthorized' });
|
|
if (!title || !content) {
|
|
return res.status(400).json({ error: 'Title and content are required' });
|
|
}
|
|
|
|
const message = await prisma.message.create({
|
|
data: {
|
|
userId,
|
|
title,
|
|
content,
|
|
type: type || 'System',
|
|
senderName: 'Me',
|
|
isRead: false
|
|
}
|
|
});
|
|
|
|
res.json(message);
|
|
} catch (error) {
|
|
console.error('Create message error:', error);
|
|
res.status(500).json({ error: 'Failed to create message' });
|
|
}
|
|
};
|
|
|
|
// 获取日程
|
|
export const getSchedule = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const userId = req.userId;
|
|
if (!userId) return res.status(401).json({ error: 'Unauthorized' });
|
|
|
|
// 获取用户关联的班级
|
|
const user = await prisma.applicationUser.findUnique({
|
|
where: { id: userId },
|
|
include: {
|
|
classMemberships: {
|
|
include: { class: true }
|
|
}
|
|
}
|
|
});
|
|
|
|
if (!user) return res.status(404).json({ error: 'User not found' });
|
|
|
|
const classIds = user.classMemberships.map(cm => cm.classId);
|
|
|
|
// 获取这些班级的日程
|
|
const schedules = await prisma.schedule.findMany({
|
|
where: { classId: { in: classIds } },
|
|
include: { class: true }
|
|
});
|
|
|
|
const scheduleDtos = schedules.map(s => ({
|
|
id: s.id,
|
|
startTime: s.startTime,
|
|
endTime: s.endTime,
|
|
className: s.class.name,
|
|
subject: s.subject,
|
|
room: s.room || '',
|
|
isToday: s.dayOfWeek === new Date().getDay(),
|
|
dayOfWeek: s.dayOfWeek,
|
|
period: s.period
|
|
}));
|
|
|
|
res.json(scheduleDtos);
|
|
} catch (error) {
|
|
console.error('Get schedule error:', error);
|
|
res.status(500).json({ error: 'Failed to get schedule' });
|
|
}
|
|
};
|
|
|
|
// 获取周日程
|
|
export const getWeekSchedule = async (req: AuthRequest, res: Response) => {
|
|
// 复用 getSchedule 逻辑,因为我们返回了所有日程
|
|
return getSchedule(req, res);
|
|
};
|
|
|
|
// 添加日程 (仅教师)
|
|
export const addEvent = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const userId = req.userId;
|
|
const { subject, className, classId, room, dayOfWeek, period, startTime, endTime } = req.body;
|
|
|
|
let resolvedClassId: string | null = null;
|
|
if (classId) {
|
|
const clsById = await prisma.class.findUnique({ where: { id: classId } });
|
|
if (!clsById) return res.status(404).json({ error: 'Class not found' });
|
|
resolvedClassId = clsById.id;
|
|
} else if (className) {
|
|
const clsByName = await prisma.class.findFirst({ where: { name: className } });
|
|
if (!clsByName) return res.status(404).json({ error: 'Class not found' });
|
|
resolvedClassId = clsByName.id;
|
|
} else {
|
|
return res.status(400).json({ error: 'classId or className is required' });
|
|
}
|
|
|
|
// 检查权限 (简化:假设所有教师都可以添加)
|
|
// 实际应检查是否是该班级的教师
|
|
|
|
await prisma.schedule.create({
|
|
data: {
|
|
classId: resolvedClassId!,
|
|
subject,
|
|
room,
|
|
dayOfWeek,
|
|
period,
|
|
startTime,
|
|
endTime
|
|
}
|
|
});
|
|
|
|
res.status(201).json({ success: true });
|
|
} catch (error) {
|
|
console.error('Add event error:', error);
|
|
res.status(500).json({ error: 'Failed to add event' });
|
|
}
|
|
};
|
|
|
|
// 删除日程
|
|
export const deleteEvent = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
const { id } = req.params;
|
|
await prisma.schedule.delete({ where: { id } });
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
console.error('Delete event error:', error);
|
|
res.status(500).json({ error: 'Failed to delete event' });
|
|
}
|
|
};
|