feat(rbac): add @RequirePermission decorators to all business controllers

This commit is contained in:
2026-07-02 11:53:18 +08:00
parent f53b6c447c
commit 7a8df81e7b
11 changed files with 97 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ import { GenerateBillsDto, UpdateBillStatusDto } from './dto/bill.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import type { Response } from 'express';
@UseGuards(JwtAuthGuard)
@@ -13,6 +14,7 @@ export class BillsController {
constructor(private service: BillsService, private exportService: BillsExportService, private logService: OperationLogsService) {}
@Post('generate')
@RequirePermission('bill:generate')
async generateBills(@Body() dto: GenerateBillsDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.generateBills(dto);
@@ -21,6 +23,7 @@ export class BillsController {
}
@Get()
@RequirePermission('bill:view')
findAll(
@Query('periodStart') periodStart?: string,
@Query('periodEnd') periodEnd?: string,
@@ -35,11 +38,13 @@ export class BillsController {
}
@Get(':id')
@RequirePermission('bill:view')
findOne(@Param('id') id: string) {
return this.service.findOne(+id);
}
@Put(':id/status')
@RequirePermission('bill:confirm')
async updateStatus(@Param('id') id: string, @Body() dto: UpdateBillStatusDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.updateStatus(+id, dto);
@@ -48,6 +53,7 @@ export class BillsController {
}
@Put('batch/status')
@RequirePermission('bill:confirm')
async batchUpdateStatus(@Body() body: { ids: number[]; status: string }, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchUpdateStatus(body.ids, body.status);
@@ -56,6 +62,7 @@ export class BillsController {
}
@Delete(':id')
@RequirePermission('bill:delete')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);
@@ -64,6 +71,7 @@ export class BillsController {
}
@Post('batch/delete')
@RequirePermission('bill:delete')
async batchRemove(@Body() body: { ids: number[] }, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchRemove(body.ids);
@@ -72,6 +80,7 @@ export class BillsController {
}
@Get('export/excel')
@RequirePermission('bill:export-excel')
async exportExcel(
@Query('periodStart') periodStart?: string,
@Query('periodEnd') periodEnd?: string,
@@ -90,6 +99,7 @@ export class BillsController {
}
@Get('export/pdf/:id')
@RequirePermission('bill:export-pdf')
async exportPdf(@Param('id') id: string, @Res() res: Response, @Req() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
await this.logService.log({ userId: req?.user?.id, username: req?.user?.username, module: '账单', action: '导出PDF', targetId: +id, targetType: 'bill', ipAddress, userAgent });

View File

@@ -7,6 +7,7 @@ import { CreateRentalDto, UpdateRentalDto } from './dto/rental.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
@UseGuards(JwtAuthGuard)
@Controller('classroom-rentals')
@@ -14,6 +15,7 @@ export class ClassroomRentalsController {
constructor(private service: ClassroomRentalsService, private logService: OperationLogsService) {}
@Get()
@RequirePermission('rental:view')
findAll(
@Query('classroomId') classroomId?: string,
@Query('tenantId') tenantId?: string,
@@ -29,6 +31,7 @@ export class ClassroomRentalsController {
}
@Get('schedule')
@RequirePermission('rental:view')
getSchedule(@Query('year') year?: string, @Query('month') month?: string) {
const now = new Date();
const y = year ? +year : now.getFullYear();
@@ -38,11 +41,13 @@ export class ClassroomRentalsController {
}
@Get(':id')
@RequirePermission('rental:view')
findOne(@Param('id') id: string) {
return this.service.findOne(+id);
}
@Post()
@RequirePermission('rental:create')
async create(@Body() dto: CreateRentalDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.create(dto, req.user?.id);
@@ -56,6 +61,7 @@ export class ClassroomRentalsController {
}
@Put(':id')
@RequirePermission('rental:edit')
async update(@Param('id') id: string, @Body() dto: UpdateRentalDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.update(+id, dto);
@@ -68,6 +74,7 @@ export class ClassroomRentalsController {
}
@Delete(':id')
@RequirePermission('rental:delete')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);
@@ -81,6 +88,7 @@ export class ClassroomRentalsController {
// 合同上传multer 限制 10MB + 仅 PDF
@Post(':id/contract')
@RequirePermission('rental:edit')
@UseInterceptors(FileInterceptor('file', {
limits: { fileSize: 10 * 1024 * 1024 },
fileFilter: (_req, file, cb) => {
@@ -103,6 +111,7 @@ export class ClassroomRentalsController {
}
@Get(':id/contract')
@RequirePermission('rental:view')
async downloadContract(@Param('id') id: string, @Res() res: Response) {
const { fullPath, originalName } = await this.service.getContractPath(+id);
res.setHeader('Content-Type', 'application/pdf');
@@ -112,6 +121,7 @@ export class ClassroomRentalsController {
}
@Delete(':id/contract')
@RequirePermission('rental:edit')
async deleteContract(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.removeContract(+id);

View File

@@ -6,6 +6,7 @@ import { CreateClassroomDto, UpdateClassroomDto } from './dto/classroom.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import * as ExcelJS from 'exceljs';
@UseGuards(JwtAuthGuard)
@@ -14,6 +15,7 @@ export class ClassroomsController {
constructor(private service: ClassroomsService, private logService: OperationLogsService) {}
@Get()
@RequirePermission('classroom:view')
findAll(@Query('building') building?: string, @Query('roomType') roomType?: string, @Query('includeArchived') includeArchived?: string) {
return this.service.findAll({
building,
@@ -23,6 +25,7 @@ export class ClassroomsController {
}
@Get('template')
@RequirePermission('classroom:view')
async downloadTemplate(@Res() res: Response) {
const workbook = new ExcelJS.Workbook();
const ws = workbook.addWorksheet('教室导入模板');
@@ -60,11 +63,13 @@ export class ClassroomsController {
}
@Get(':id')
@RequirePermission('classroom:view')
findOne(@Param('id') id: string) {
return this.service.findOne(+id);
}
@Post()
@RequirePermission('classroom:create')
async create(@Body() dto: CreateClassroomDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.create(dto);
@@ -73,6 +78,7 @@ export class ClassroomsController {
}
@Put(':id')
@RequirePermission('classroom:edit')
async update(@Param('id') id: string, @Body() dto: UpdateClassroomDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.update(+id, dto);
@@ -81,6 +87,7 @@ export class ClassroomsController {
}
@Delete(':id')
@RequirePermission('classroom:delete')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);
@@ -89,6 +96,7 @@ export class ClassroomsController {
}
@Put(':id/restore')
@RequirePermission('classroom:edit')
async restore(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.restore(+id);
@@ -97,6 +105,7 @@ export class ClassroomsController {
}
@Post('import')
@RequirePermission('classroom:create')
@UseInterceptors(FileInterceptor('file'))
async importExcel(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);

View File

@@ -1,8 +1,10 @@
import { Controller, Get, Query, UseGuards } from '@nestjs/common';
import { DashboardService } from './dashboard.service';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RequirePermission } from '../auth/decorators/permission.decorator';
@UseGuards(JwtAuthGuard)
@RequirePermission('dashboard:view')
@Controller('dashboard')
export class DashboardController {
constructor(private service: DashboardService) {}

View File

@@ -4,6 +4,7 @@ import { CreateDepositDto, RefundDepositDto } from './dto/deposit.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
@UseGuards(JwtAuthGuard)
@Controller('deposits')
@@ -11,6 +12,7 @@ export class DepositsController {
constructor(private service: DepositsService, private logService: OperationLogsService) {}
@Get()
@RequirePermission('deposit:view')
findAll(@Query('studentId') studentId?: string, @Query('status') status?: string) {
return this.service.findAll({
studentId: studentId ? +studentId : undefined,
@@ -19,11 +21,13 @@ export class DepositsController {
}
@Get('stats')
@RequirePermission('deposit:view')
getStats() {
return this.service.getStats();
}
@Post()
@RequirePermission('deposit:create')
async create(@Body() dto: CreateDepositDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.create(dto, req.user?.id);
@@ -32,6 +36,7 @@ export class DepositsController {
}
@Put(':id/refund')
@RequirePermission('deposit:edit')
async refund(@Param('id') id: string, @Body() dto: RefundDepositDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.refund(+id, dto, req.user?.id);
@@ -40,6 +45,7 @@ export class DepositsController {
}
@Delete(':id')
@RequirePermission('deposit:delete')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);

View File

@@ -6,6 +6,7 @@ import { CreateRoomExpenseDto, CreatePersonalExpenseDto, BatchRoomExpenseDto } f
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import * as ExcelJS from 'exceljs';
/** 提取 ExcelJS 单元格的真实值,兼容公式、富文本、日期、超链接等情况 */
@@ -51,6 +52,7 @@ export class ExpensesController {
constructor(private service: ExpensesService, private logService: OperationLogsService) {}
@Post('room')
@RequirePermission('expense:create')
async createRoomExpense(@Body() dto: CreateRoomExpenseDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.createRoomExpense(dto, req.user?.id);
@@ -59,6 +61,7 @@ export class ExpensesController {
}
@Post('room/batch')
@RequirePermission('expense:create')
async batchCreateRoomExpenses(@Body() dto: BatchRoomExpenseDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchCreateRoomExpenses(dto, req.user?.id);
@@ -67,6 +70,7 @@ export class ExpensesController {
}
@Get('room')
@RequirePermission('expense:view')
findRoomExpenses(
@Query('roomId') roomId?: string,
@Query('periodStart') periodStart?: string,
@@ -79,6 +83,7 @@ export class ExpensesController {
}
@Delete('room/:id')
@RequirePermission('expense:delete')
async deleteRoomExpense(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.deleteRoomExpense(+id);
@@ -87,6 +92,7 @@ export class ExpensesController {
}
@Post('room/batch-delete')
@RequirePermission('expense:delete')
async batchDeleteRoomExpenses(@Body() body: { ids: number[] }, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchDeleteRoomExpenses(body.ids || []);
@@ -95,6 +101,7 @@ export class ExpensesController {
}
@Put('room/:id')
@RequirePermission('expense:edit')
async updateRoomExpense(@Param('id') id: string, @Body() dto: CreateRoomExpenseDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.updateRoomExpense(+id, dto);
@@ -103,6 +110,7 @@ export class ExpensesController {
}
@Post('personal')
@RequirePermission('expense:create')
async createPersonalExpense(@Body() dto: CreatePersonalExpenseDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.createPersonalExpense(dto, req.user?.id);
@@ -111,11 +119,13 @@ export class ExpensesController {
}
@Get('personal')
@RequirePermission('expense:view')
findPersonalExpenses(@Query('studentId') studentId?: string) {
return this.service.findPersonalExpenses({ studentId: studentId ? +studentId : undefined });
}
@Delete('personal/:id')
@RequirePermission('expense:delete')
async deletePersonalExpense(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.deletePersonalExpense(+id);
@@ -124,6 +134,7 @@ export class ExpensesController {
}
@Post('personal/batch-delete')
@RequirePermission('expense:delete')
async batchDeletePersonalExpenses(@Body() body: { ids: number[] }, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchDeletePersonalExpenses(body.ids || []);
@@ -132,6 +143,7 @@ export class ExpensesController {
}
@Put('personal/:id')
@RequirePermission('expense:edit')
async updatePersonalExpense(@Param('id') id: string, @Body() dto: CreatePersonalExpenseDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.updatePersonalExpense(+id, dto);
@@ -140,6 +152,7 @@ export class ExpensesController {
}
@Get('utility/template')
@RequirePermission('expense:view')
async downloadUtilityTemplate(@Res() res: Response) {
const workbook = new ExcelJS.Workbook();
const ws = workbook.addWorksheet('水电费导入模板');
@@ -163,6 +176,7 @@ export class ExpensesController {
}
@Post('utility/import')
@RequirePermission('expense:create')
@UseInterceptors(FileInterceptor('file'))
async importUtilityExpenses(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
@@ -190,6 +204,7 @@ export class ExpensesController {
}
@Get('personal/template')
@RequirePermission('expense:view')
async downloadPersonalTemplate(@Res() res: Response) {
const workbook = new ExcelJS.Workbook();
const ws = workbook.addWorksheet('个人附加费导入模板');
@@ -214,6 +229,7 @@ export class ExpensesController {
}
@Post('personal/import')
@RequirePermission('expense:create')
@UseInterceptors(FileInterceptor('file'))
async importPersonalExpenses(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
@@ -239,6 +255,7 @@ export class ExpensesController {
}
@Get('personal/export')
@RequirePermission('expense:view')
async exportPersonalExpenses(@Res() res: Response) {
const data = await this.service.findPersonalExpenses();
const typeMap: Record<string, string> = { damage: '物品损坏', cleaning: '保洁费', penalty: '罚款', key: '钥匙费', remote: '空调遥控器', deposit_deduction: '押金扣除', other: '其他' };

View File

@@ -6,6 +6,7 @@ import { CheckInDto, CheckOutDto, TransferRoomDto, BatchCheckOutDto } from './dt
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import * as ExcelJS from 'exceljs';
@UseGuards(JwtAuthGuard)
@@ -14,6 +15,7 @@ export class OccupanciesController {
constructor(private service: OccupanciesService, private logService: OperationLogsService) {}
@Get()
@RequirePermission('occupancy:view')
findAll(
@Query('roomId') roomId?: string,
@Query('studentId') studentId?: string,
@@ -27,6 +29,7 @@ export class OccupanciesController {
}
@Post('batch-check-out')
@RequirePermission('occupancy:checkout')
async batchCheckOut(@Body() dto: BatchCheckOutDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchCheckOut(dto);
@@ -35,6 +38,7 @@ export class OccupanciesController {
}
@Post('check-in')
@RequirePermission('occupancy:checkin')
async checkIn(@Body() dto: CheckInDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.checkIn(dto);
@@ -43,6 +47,7 @@ export class OccupanciesController {
}
@Put(':id/check-out')
@RequirePermission('occupancy:checkout')
async checkOut(@Param('id') id: string, @Body() dto: CheckOutDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.checkOut(+id, dto);
@@ -51,6 +56,7 @@ export class OccupanciesController {
}
@Put(':id/transfer')
@RequirePermission('occupancy:transfer')
async transferRoom(@Param('id') id: string, @Body() dto: TransferRoomDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.transferRoom(+id, dto);
@@ -59,6 +65,7 @@ export class OccupanciesController {
}
@Delete(':id')
@RequirePermission('occupancy:view')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);
@@ -67,6 +74,7 @@ export class OccupanciesController {
}
@Post('batch-delete')
@RequirePermission('occupancy:view')
async batchRemove(@Body() body: { ids: number[] }, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchRemove(body.ids || []);
@@ -75,6 +83,7 @@ export class OccupanciesController {
}
@Get('export')
@RequirePermission('occupancy:view')
async exportExcel(@Query('active') active?: string, @Res() res?: Response) {
const records = await this.service.findAll({ active: active === 'true' });
const workbook = new ExcelJS.Workbook();
@@ -120,6 +129,7 @@ export class OccupanciesController {
}
@Get('template')
@RequirePermission('occupancy:view')
async downloadTemplate(@Res() res: Response) {
const workbook = new ExcelJS.Workbook();
const ws = workbook.addWorksheet('入住名单导入模板');
@@ -163,6 +173,7 @@ export class OccupanciesController {
}
@Post('import')
@RequirePermission('occupancy:checkin')
@UseInterceptors(FileInterceptor('file'))
async importCheckIn(@UploadedFile() file: Express.Multer.File, @Request() req: any, @Query('autoDeposit') autoDeposit?: string, @Query('depositAmount') depositAmount?: string) {
const { ipAddress, userAgent } = extractRequestInfo(req);

View File

@@ -1,8 +1,10 @@
import { Controller, Get, Query, UseGuards } from '@nestjs/common';
import { OperationLogsService } from './operation-logs.service';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RequirePermission } from '../auth/decorators/permission.decorator';
@UseGuards(JwtAuthGuard)
@RequirePermission('log:view')
@Controller('operation-logs')
export class OperationLogsController {
constructor(private service: OperationLogsService) {}

View File

@@ -6,6 +6,7 @@ import { CreateRoomDto, UpdateRoomDto } from './dto/room.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import * as ExcelJS from 'exceljs';
@UseGuards(JwtAuthGuard)
@@ -14,21 +15,25 @@ export class RoomsController {
constructor(private service: RoomsService, private logService: OperationLogsService) {}
@Get()
@RequirePermission('room:view')
findAll(@Query('building') building?: string, @Query('includeArchived') includeArchived?: string) {
return this.service.findAll({ building, includeArchived: includeArchived === 'true' });
}
@Get('overview')
@RequirePermission('room:view')
getOverview(@Query('includeArchived') includeArchived?: string) {
return this.service.getRoomOverview({ includeArchived: includeArchived === 'true' });
}
@Get('visual')
@RequirePermission('room:view')
getVisual() {
return this.service.getRoomVisual();
}
@Get('template')
@RequirePermission('room:view')
async downloadTemplate(@Res() res: Response) {
const workbook = new ExcelJS.Workbook();
const ws = workbook.addWorksheet('宿舍导入模板');
@@ -50,6 +55,7 @@ export class RoomsController {
}
@Get('export')
@RequirePermission('room:view')
async exportExcel(@Query('includeArchived') includeArchived?: string, @Res() res?: Response) {
const rooms = await this.service.getRoomOverview({ includeArchived: includeArchived === 'true' });
const workbook = new ExcelJS.Workbook();
@@ -77,11 +83,13 @@ export class RoomsController {
}
@Get(':id')
@RequirePermission('room:view')
findOne(@Param('id') id: string) {
return this.service.findOneWithOccupants(+id);
}
@Post()
@RequirePermission('room:create')
async create(@Body() dto: CreateRoomDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.create(dto);
@@ -90,6 +98,7 @@ export class RoomsController {
}
@Put(':id')
@RequirePermission('room:edit')
async update(@Param('id') id: string, @Body() dto: UpdateRoomDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.update(+id, dto);
@@ -98,6 +107,7 @@ export class RoomsController {
}
@Delete(':id')
@RequirePermission('room:delete')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);
@@ -106,6 +116,7 @@ export class RoomsController {
}
@Post('batch-delete')
@RequirePermission('room:delete')
async batchRemove(@Body() body: { ids: number[] }, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchRemove(body.ids || []);
@@ -114,6 +125,7 @@ export class RoomsController {
}
@Put(':id/restore')
@RequirePermission('room:edit')
async restore(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.restore(+id);
@@ -122,6 +134,7 @@ export class RoomsController {
}
@Post('import')
@RequirePermission('room:create')
@UseInterceptors(FileInterceptor('file'))
async importExcel(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);

View File

@@ -6,6 +6,7 @@ import { CreateStudentDto, UpdateStudentDto } from './dto/student.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import * as ExcelJS from 'exceljs';
@UseGuards(JwtAuthGuard)
@@ -14,11 +15,13 @@ export class StudentsController {
constructor(private service: StudentsService, private logService: OperationLogsService) {}
@Get()
@RequirePermission('student:view')
findAll(@Query('name') name?: string, @Query('status') status?: string, @Query('includeArchived') includeArchived?: string) {
return this.service.findAll({ name, status, includeArchived: includeArchived === 'true' });
}
@Get('export')
@RequirePermission('student:export')
async exportExcel(@Query('includeArchived') includeArchived?: string, @Res() res?: Response) {
const students = await this.service.findAll({ includeArchived: includeArchived === 'true' });
const workbook = new ExcelJS.Workbook();
@@ -48,6 +51,7 @@ export class StudentsController {
}
@Get('template')
@RequirePermission('student:view')
async downloadTemplate(@Res() res: Response) {
const workbook = new ExcelJS.Workbook();
const ws = workbook.addWorksheet('学生导入模板');
@@ -72,11 +76,13 @@ export class StudentsController {
}
@Get(':id')
@RequirePermission('student:view')
findOne(@Param('id') id: string) {
return this.service.findOne(+id);
}
@Post()
@RequirePermission('student:create')
async create(@Body() dto: CreateStudentDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.create(dto);
@@ -85,6 +91,7 @@ export class StudentsController {
}
@Put(':id')
@RequirePermission('student:edit')
async update(@Param('id') id: string, @Body() dto: UpdateStudentDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.update(+id, dto);
@@ -93,6 +100,7 @@ export class StudentsController {
}
@Delete(':id')
@RequirePermission('student:delete')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);
@@ -101,6 +109,7 @@ export class StudentsController {
}
@Post('batch-delete')
@RequirePermission('student:delete')
async batchRemove(@Body() body: { ids: number[] }, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.batchRemove(body.ids || []);
@@ -109,6 +118,7 @@ export class StudentsController {
}
@Put(':id/restore')
@RequirePermission('student:edit')
async restore(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.restore(+id);
@@ -117,6 +127,7 @@ export class StudentsController {
}
@Post('import')
@RequirePermission('student:import')
@UseInterceptors(FileInterceptor('file'))
async importExcel(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);

View File

@@ -4,6 +4,7 @@ import { CreateTenantDto, UpdateTenantDto } from './dto/tenant.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
import { RequirePermission } from '../auth/decorators/permission.decorator';
@UseGuards(JwtAuthGuard)
@Controller('tenants')
@@ -11,16 +12,19 @@ export class TenantsController {
constructor(private service: TenantsService, private logService: OperationLogsService) {}
@Get()
@RequirePermission('tenant:view')
findAll(@Query('includeArchived') includeArchived?: string) {
return this.service.findAll({ includeArchived: includeArchived === 'true' });
}
@Get(':id')
@RequirePermission('tenant:view')
findOne(@Param('id') id: string) {
return this.service.findOne(+id);
}
@Post()
@RequirePermission('tenant:create')
async create(@Body() dto: CreateTenantDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.create(dto);
@@ -29,6 +33,7 @@ export class TenantsController {
}
@Put(':id')
@RequirePermission('tenant:edit')
async update(@Param('id') id: string, @Body() dto: UpdateTenantDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.update(+id, dto);
@@ -37,6 +42,7 @@ export class TenantsController {
}
@Delete(':id')
@RequirePermission('tenant:delete')
async remove(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.service.remove(+id);