feat: 重构各业务模块管理页面与服务
This commit is contained in:
@@ -31,7 +31,7 @@ import {
|
||||
} from './dto/expense.dto';
|
||||
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
||||
import { OperationLogsService } from '../operation-logs/operation-logs.service';
|
||||
import { extractRequestInfo } from '../common/request-utils';
|
||||
import { logAudit } from '../common/with-audit-log';
|
||||
import { RequirePermission } from '../auth/decorators/permission.decorator';
|
||||
import { BatchIdsDto } from '../common/batch-ids.dto';
|
||||
import * as ExcelJS from 'exceljs';
|
||||
@@ -91,17 +91,8 @@ export class ExpensesController {
|
||||
@RequirePermission('expense:create')
|
||||
async createStudentUtilityBill(@Body() dto: CreateStudentUtilityBillDto, @Request() req: any) {
|
||||
const result = await this.service.createStudentUtilityBill(dto, req.user?.id);
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '录入学生水电费并出账',
|
||||
targetId: result.bill.id,
|
||||
targetType: 'bill',
|
||||
detail: `学生${dto.studentId} ${dto.expenseType} ¥${dto.amount},自动扣款 ¥${result.bill.paidAmount}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '录入学生水电费并出账', targetId: result.bill.id, targetType: 'bill', detail: `学生${dto.studentId} ${dto.expenseType} ¥${dto.amount},自动扣款 ¥${result.bill.paidAmount}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -109,18 +100,9 @@ export class ExpensesController {
|
||||
@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);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '录入费用',
|
||||
targetId: result.id,
|
||||
targetType: 'room_expense',
|
||||
detail: `房间${dto.roomId} ¥${dto.amount} ${dto.expenseType}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '录入费用', targetId: result.id, targetType: 'room_expense', detail: `房间${dto.roomId} ¥${dto.amount} ${dto.expenseType}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -128,16 +110,9 @@ 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);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '批量录入费用',
|
||||
detail: JSON.stringify(dto),
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '批量录入费用', detail: JSON.stringify(dto),
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -151,17 +126,9 @@ export class ExpensesController {
|
||||
@Delete('room/:id')
|
||||
@RequirePermission('expense:delete')
|
||||
async deleteRoomExpense(@Param('id', ParseIntPipe) id: number, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.deleteRoomExpense(id);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '归档费用',
|
||||
targetId: id,
|
||||
targetType: 'room_expense',
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '归档费用', targetId: id, targetType: 'room_expense',
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -169,16 +136,29 @@ 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 || []);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '批量归档宿舍费用',
|
||||
detail: `IDs: ${(body.ids || []).join(',')}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '批量归档宿舍费用', detail: `IDs: ${(body.ids || []).join(',')}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Delete('room/:id/permanent')
|
||||
@RequirePermission('expense:purge')
|
||||
async purgeRoomExpense(@Param('id', ParseIntPipe) id: number, @Request() req: any) {
|
||||
const result = await this.service.purgeRoomExpense(id);
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '永久删除宿舍费用', targetId: id, targetType: 'room_expense', detail: '物理删除,不可恢复',
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Post('room/batch-permanent-delete')
|
||||
@RequirePermission('expense:purge')
|
||||
async batchPurgeRoomExpenses(@Body() body: { ids: number[] }, @Request() req: any) {
|
||||
const result = await this.service.batchPurgeRoomExpenses(body.ids || []);
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '批量永久删除宿舍费用', detail: `IDs: ${(body.ids || []).join(',')}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -187,16 +167,9 @@ export class ExpensesController {
|
||||
@RequirePermission('expense:edit')
|
||||
@UsePipes(new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }))
|
||||
async batchRestoreRoomExpenses(@Body() dto: BatchIdsDto, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.batchRestoreRoomExpenses(dto.ids);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '批量恢复宿舍费用',
|
||||
detail: `IDs: ${dto.ids.join(',')}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '批量恢复宿舍费用', detail: `IDs: ${dto.ids.join(',')}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -208,18 +181,9 @@ export class ExpensesController {
|
||||
@Body() dto: UpdateRoomExpenseDto,
|
||||
@Request() req: any,
|
||||
) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.updateRoomExpense(id, dto);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '编辑费用',
|
||||
targetId: id,
|
||||
targetType: 'room_expense',
|
||||
detail: `¥${dto.amount} ${dto.expenseType}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '编辑费用', targetId: id, targetType: 'room_expense', detail: `¥${dto.amount} ${dto.expenseType}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -227,16 +191,9 @@ 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);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '录入费用',
|
||||
detail: `学生${dto.studentId} ¥${dto.amount} ${dto.expenseType}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '录入费用', detail: `学生${dto.studentId} ¥${dto.amount} ${dto.expenseType}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -250,16 +207,9 @@ export class ExpensesController {
|
||||
@Delete('personal/:id')
|
||||
@RequirePermission('expense:delete')
|
||||
async deletePersonalExpense(@Param('id', ParseIntPipe) id: number, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.deletePersonalExpense(id);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '归档费用',
|
||||
targetId: id,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '归档费用', targetId: id,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -267,16 +217,29 @@ 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 || []);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '批量归档个人费用',
|
||||
detail: `IDs: ${(body.ids || []).join(',')}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '批量归档个人费用', detail: `IDs: ${(body.ids || []).join(',')}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Delete('personal/:id/permanent')
|
||||
@RequirePermission('expense:purge')
|
||||
async purgePersonalExpense(@Param('id', ParseIntPipe) id: number, @Request() req: any) {
|
||||
const result = await this.service.purgePersonalExpense(id);
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '永久删除个人费用', targetId: id, targetType: 'personal_expense', detail: '物理删除,不可恢复',
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Post('personal/batch-permanent-delete')
|
||||
@RequirePermission('expense:purge')
|
||||
async batchPurgePersonalExpenses(@Body() body: { ids: number[] }, @Request() req: any) {
|
||||
const result = await this.service.batchPurgePersonalExpenses(body.ids || []);
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '批量永久删除个人费用', detail: `IDs: ${(body.ids || []).join(',')}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -285,16 +248,9 @@ export class ExpensesController {
|
||||
@RequirePermission('expense:edit')
|
||||
@UsePipes(new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }))
|
||||
async batchRestorePersonalExpenses(@Body() dto: BatchIdsDto, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.batchRestorePersonalExpenses(dto.ids);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '批量恢复个人费用',
|
||||
detail: `IDs: ${dto.ids.join(',')}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '批量恢复个人费用', detail: `IDs: ${dto.ids.join(',')}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -306,17 +262,9 @@ export class ExpensesController {
|
||||
@Body() dto: UpdatePersonalExpenseDto,
|
||||
@Request() req: any,
|
||||
) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const result = await this.service.updatePersonalExpense(id, dto);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '编辑费用',
|
||||
targetId: id,
|
||||
detail: `¥${dto.amount} ${dto.expenseType}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '编辑费用', targetId: id, detail: `¥${dto.amount} ${dto.expenseType}`,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -361,9 +309,8 @@ export class ExpensesController {
|
||||
@RequirePermission('expense:create')
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
async importUtilityExpenses(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer as any);
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
const ws = workbook.worksheets[0];
|
||||
const rows: any[] = [];
|
||||
ws.eachRow((row, idx) => {
|
||||
@@ -381,14 +328,8 @@ export class ExpensesController {
|
||||
});
|
||||
});
|
||||
const result = await this.service.batchImportUtilityExpenses(rows, req.user?.id);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '导入水电费',
|
||||
detail: result.message,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '导入水电费', detail: result.message,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -433,9 +374,8 @@ export class ExpensesController {
|
||||
@RequirePermission('expense:create')
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
async importPersonalExpenses(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer as any);
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
const ws = workbook.worksheets[0];
|
||||
const rows: any[] = [];
|
||||
ws.eachRow((row, idx) => {
|
||||
@@ -451,14 +391,8 @@ export class ExpensesController {
|
||||
});
|
||||
});
|
||||
const result = await this.service.batchImportPersonalExpenses(rows, req.user?.id);
|
||||
await this.logService.log({
|
||||
userId: req.user?.id,
|
||||
username: req.user?.username,
|
||||
module: '费用管理',
|
||||
action: '导入个人附加费',
|
||||
detail: result.message,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
await logAudit(this.logService, req, {
|
||||
module: '费用管理', action: '导入个人附加费', detail: result.message,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user