chore: commit oxfmt formatting changes and verify artifacts

This commit is contained in:
2026-07-02 15:55:09 +08:00
parent 34726cc46d
commit 4f4cee157a
77 changed files with 5576 additions and 1400 deletions

View File

@@ -21,7 +21,12 @@ export class RoomsService {
* "3-301" → building:"3号楼", floor:3, roomType:"四人间"
* "8-102" → building:"8号楼", floor:1, roomType:"爆改房"
*/
static parseRoomNumber(roomNumber: string): { building?: string; floor?: number; roomType?: string; capacity?: number } {
static parseRoomNumber(roomNumber: string): {
building?: string;
floor?: number;
roomType?: string;
capacity?: number;
} {
const cleaned = roomNumber.replace(/[(].*?[)]/g, '').trim();
// 家庭房: X-Y-ZZZ 格式
const familyMatch = cleaned.match(/^(\d+)-(\d+)-(\d+)$/);
@@ -36,12 +41,18 @@ export class RoomsService {
if (stdMatch) {
const bldgNum = stdMatch[1];
const roomPart = stdMatch[2];
const floor = roomPart.length >= 3 ? parseInt(roomPart.charAt(0), 10) : parseInt(roomPart.charAt(0), 10);
const floor =
roomPart.length >= 3 ? parseInt(roomPart.charAt(0), 10) : parseInt(roomPart.charAt(0), 10);
const building = `${bldgNum}号楼`;
let roomType = '四人间';
let capacity = 4;
if (bldgNum === '2') { roomType = '单人间'; capacity = 1; }
else if (bldgNum === '8') { roomType = '爆改房'; capacity = 2; }
if (bldgNum === '2') {
roomType = '单人间';
capacity = 1;
} else if (bldgNum === '8') {
roomType = '爆改房';
capacity = 2;
}
return { building, floor, roomType, capacity };
}
return {};
@@ -76,7 +87,9 @@ export class RoomsService {
const rooms = await this.repo.find({ where, order: { building: 'ASC', roomNumber: 'ASC' } });
const result: any[] = [];
for (const room of rooms) {
const count = await this.occRepo.count({ where: { roomId: room.id, checkOutDate: IsNull() } });
const count = await this.occRepo.count({
where: { roomId: room.id, checkOutDate: IsNull() },
});
result.push({ ...room, currentCount: count });
}
return result;
@@ -113,7 +126,9 @@ export class RoomsService {
skipped.push(`${r.roomNumber}(已归档)`);
continue;
}
const activeCount = await this.occRepo.count({ where: { roomId: r.id, checkOutDate: IsNull() } });
const activeCount = await this.occRepo.count({
where: { roomId: r.id, checkOutDate: IsNull() },
});
if (activeCount > 0) {
skipped.push(`${r.roomNumber}(有在住人员)`);
continue;
@@ -122,16 +137,18 @@ export class RoomsService {
}
let affected = 0;
if (targetIds.length > 0) {
const result = await this.repo.createQueryBuilder()
const result = await this.repo
.createQueryBuilder()
.update()
.set({ status: 'archived' })
.where('id IN (:...ids)', { ids: targetIds })
.execute();
affected = result.affected || 0;
}
const message = skipped.length > 0
? `成功归档 ${affected} 间;${skipped.length} 间被跳过(${skipped.slice(0, 5).join('、')}${skipped.length > 5 ? '…' : ''}`
: `已批量归档 ${affected}宿舍(数据已保留,可随时恢复`;
const message =
skipped.length > 0
? `成功归档 ${affected}${skipped.length} 间被跳过(${skipped.slice(0, 5).join('、')}${skipped.length > 5 ? '…' : ''}`
: `已批量归档 ${affected} 间宿舍(数据已保留,可随时恢复)`;
return { message, archived: affected, skipped: skipped.length };
}
@@ -143,7 +160,10 @@ export class RoomsService {
}
async getRoomVisual() {
const rooms = await this.repo.find({ where: { status: Not('archived') }, order: { building: 'ASC', roomNumber: 'ASC' } });
const rooms = await this.repo.find({
where: { status: Not('archived') },
order: { building: 'ASC', roomNumber: 'ASC' },
});
const occupancies = await this.occRepo.find({
where: { checkOutDate: IsNull() },
relations: ['student'],
@@ -156,7 +176,10 @@ export class RoomsService {
if (!occMap.has(occ.roomId)) occMap.set(occ.roomId, []);
const now = new Date();
const checkIn = new Date(occ.checkInDate);
const days = Math.max(1, Math.ceil((now.getTime() - checkIn.getTime()) / (1000 * 60 * 60 * 24)));
const days = Math.max(
1,
Math.ceil((now.getTime() - checkIn.getTime()) / (1000 * 60 * 60 * 24)),
);
occMap.get(occ.roomId)!.push({
studentId: occ.studentId,
studentName: occ.student?.name || '未知',
@@ -201,24 +224,44 @@ export class RoomsService {
};
}
async batchImport(rows: { roomNumber: string; building?: string; floor?: number; capacity?: number; roomType?: string }[]) {
async batchImport(
rows: {
roomNumber: string;
building?: string;
floor?: number;
capacity?: number;
roomType?: string;
}[],
) {
let imported = 0;
let skipped = 0;
for (const row of rows) {
if (!row.roomNumber || !row.roomNumber.trim()) { skipped++; continue; }
if (!row.roomNumber || !row.roomNumber.trim()) {
skipped++;
continue;
}
const exists = await this.repo.findOne({ where: { roomNumber: row.roomNumber.trim() } });
if (exists) { skipped++; continue; }
if (exists) {
skipped++;
continue;
}
// 智能解析房间号
const parsed = RoomsService.parseRoomNumber(row.roomNumber.trim());
await this.repo.save(this.repo.create({
roomNumber: row.roomNumber.trim(),
building: row.building?.trim() || parsed.building || undefined,
floor: row.floor || parsed.floor || undefined,
capacity: row.capacity || parsed.capacity || 4,
roomType: row.roomType || parsed.roomType || undefined,
}));
await this.repo.save(
this.repo.create({
roomNumber: row.roomNumber.trim(),
building: row.building?.trim() || parsed.building || undefined,
floor: row.floor || parsed.floor || undefined,
capacity: row.capacity || parsed.capacity || 4,
roomType: row.roomType || parsed.roomType || undefined,
}),
);
imported++;
}
return { message: `成功导入 ${imported} 间宿舍,跳过 ${skipped} 条(重复或空行)`, imported, skipped };
return {
message: `成功导入 ${imported} 间宿舍,跳过 ${skipped} 条(重复或空行)`,
imported,
skipped,
};
}
}