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

@@ -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: '其他' };