course_web01 / backend /src /orders /orders.service.ts
trae-bot
Update project
426f2a4
import {
Injectable,
NotFoundException,
BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Order, OrderStatus, OrderType } from '../entities/order.entity';
import { Course } from '../entities/course.entity';
import { CreateOrderDto } from './dto/create-order.dto';
import { ConfigService } from '../config/config.service';
@Injectable()
export class OrdersService {
constructor(
@InjectRepository(Order)
private orderRepository: Repository<Order>,
@InjectRepository(Course)
private courseRepository: Repository<Course>,
private configService: ConfigService,
) {}
async create(userId: number, createOrderDto: CreateOrderDto) {
let amount = 0;
let orderType = OrderType.PURCHASE;
let courseId = null;
if (createOrderDto.isVip) {
const config = await this.configService.getUiConfig();
amount = config.memberFee || 99;
orderType = OrderType.VIP;
} else {
if (!createOrderDto.courseId) {
throw new BadRequestException('Course ID is required for non-VIP orders');
}
const course = await this.courseRepository.findOne({
where: { id: createOrderDto.courseId },
});
if (!course) {
throw new NotFoundException('Course not found');
}
if (!createOrderDto.isDonation && Number(course.price) !== Number(createOrderDto.price)) {
throw new BadRequestException('Price mismatch');
}
amount = createOrderDto.isDonation ? (createOrderDto.price || 0) : course.price;
orderType = createOrderDto.isDonation ? OrderType.DONATION : OrderType.PURCHASE;
courseId = course.id;
}
// Generate simple order number with timestamp to avoid collision under high concurrency
const timestamp = Date.now().toString().slice(-6);
const orderNo = `${new Date().getFullYear()}${(new Date().getMonth() + 1).toString().padStart(2, '0')}${new Date().getDate().toString().padStart(2, '0')}${timestamp}${Math.floor(
Math.random() * 10000,
)
.toString()
.padStart(4, '0')}`;
const order = this.orderRepository.create({
orderNo,
userId,
courseId,
amount,
status: OrderStatus.PENDING,
orderType,
message: createOrderDto.message,
});
await this.orderRepository.save(order);
return {
orderId: order.id,
orderNo: order.orderNo,
amount: order.amount,
};
}
async findUserOrders(userId: number) {
return this.orderRepository.find({
where: { userId },
relations: ['course'],
order: { createdAt: 'DESC' },
});
}
async findOne(id: number, userId: number) {
const order = await this.orderRepository.findOne({
where: { id, userId },
relations: ['course'],
});
if (!order) {
throw new NotFoundException('Order not found');
}
return order;
}
}