feat(task1): restructure directories for turborepo monorepo

- Move backend/ to apps/server/ via git mv
- Move frontend/ to apps/admin/ via git mv
- Create packages/typescript-config/ with base, nestjs, and react-vite presets
This commit is contained in:
2026-07-02 15:05:12 +08:00
parent 4704adcba1
commit 46a817503e
137 changed files with 52 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Deposit } from '../entities/deposit.entity';
import { CreateDepositDto, RefundDepositDto } from './dto/deposit.dto';
@Injectable()
export class DepositsService {
constructor(@InjectRepository(Deposit) private repo: Repository<Deposit>) {}
async findAll(query?: { studentId?: number; status?: string }) {
const qb = this.repo.createQueryBuilder('d')
.leftJoinAndSelect('d.student', 'student')
.orderBy('d.createdAt', 'DESC');
if (query?.studentId) qb.andWhere('d.studentId = :studentId', { studentId: query.studentId });
if (query?.status) qb.andWhere('d.status = :status', { status: query.status });
return qb.getMany();
}
async create(dto: CreateDepositDto, userId?: number) {
return this.repo.save(this.repo.create({
studentId: dto.studentId,
amount: dto.amount,
paidDate: dto.paidDate,
notes: dto.notes,
status: 'paid',
recordedBy: userId,
}));
}
async refund(id: number, dto: RefundDepositDto, userId?: number) {
const deposit = await this.repo.findOne({ where: { id } });
if (!deposit) throw new NotFoundException('押金记录不存在');
if (deposit.status !== 'paid') throw new BadRequestException('该押金已处理');
const deduction = dto.deductionAmount || 0;
const refundAmount = Number(deposit.amount) - deduction;
if (refundAmount < 0) throw new BadRequestException('扣除金额不能大于押金金额');
deposit.refundDate = dto.refundDate;
deposit.deductionAmount = deduction;
deposit.deductionReason = dto.deductionReason || '';
deposit.refundAmount = refundAmount;
deposit.status = deduction > 0 ? (refundAmount > 0 ? 'partial_refund' : 'deducted') : 'refunded';
if (dto.notes) deposit.notes = dto.notes;
return this.repo.save(deposit);
}
async remove(id: number) {
const deposit = await this.repo.findOne({ where: { id } });
if (!deposit) throw new NotFoundException('押金记录不存在');
await this.repo.delete(id);
return { message: '删除成功' };
}
async getStats() {
const result = await this.repo.createQueryBuilder('d')
.select('d.status', 'status')
.addSelect('COUNT(*)', 'count')
.addSelect('SUM(d.amount)', 'totalAmount')
.groupBy('d.status')
.getRawMany();
return result;
}
}