130 lines
3.7 KiB
TypeScript
130 lines
3.7 KiB
TypeScript
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { FormResult } from './entity/formResult.entity';
|
|
import { CreateFormResultDto } from './dto/create-formResult.dto';
|
|
import { UpdateFormResultDto } from './dto/update-formResult.dto';
|
|
import { Repository } from 'typeorm';
|
|
import { Queue } from 'bullmq';
|
|
import { Form } from '../form/entity/form.entity';
|
|
|
|
@Injectable()
|
|
export class FormResultService {
|
|
private readonly statisticsQueue: Queue;
|
|
|
|
constructor(
|
|
@InjectRepository(FormResult)
|
|
private readonly formResultRepo: Repository<FormResult>,
|
|
@InjectRepository(Form)
|
|
private readonly formRepo: Repository<Form>,
|
|
) {
|
|
this.statisticsQueue = new Queue('form-statistics', {
|
|
connection: {
|
|
host: 'localhost',
|
|
port: 6379,
|
|
},
|
|
});
|
|
}
|
|
|
|
async create(data: CreateFormResultDto): Promise<FormResult> {
|
|
const formResult = this.formResultRepo.create({
|
|
...data,
|
|
});
|
|
const savedFormResult = await this.formResultRepo.save(formResult);
|
|
// Schedule statistics update every 10 minutes
|
|
await this.scheduleFormStatistics(savedFormResult.formId);
|
|
return savedFormResult;
|
|
}
|
|
|
|
async findAll(
|
|
page = 1,
|
|
limit = 10,
|
|
): Promise<{
|
|
docs: FormResult[];
|
|
totalDocs: number;
|
|
limit: number;
|
|
page: number;
|
|
totalPages: number;
|
|
hasNextPage: boolean;
|
|
hasPrevPage: boolean;
|
|
nextPage: number | null;
|
|
prevPage: number | null;
|
|
}> {
|
|
const [docs, totalDocs] = await this.formResultRepo.findAndCount({
|
|
skip: (page - 1) * limit,
|
|
take: limit,
|
|
});
|
|
|
|
const totalPages = Math.ceil(totalDocs / limit);
|
|
return {
|
|
docs,
|
|
totalDocs,
|
|
limit,
|
|
page,
|
|
totalPages,
|
|
hasNextPage: page < totalPages,
|
|
hasPrevPage: page > 1,
|
|
nextPage: page < totalPages ? page + 1 : null,
|
|
prevPage: page > 1 ? page - 1 : null,
|
|
};
|
|
}
|
|
|
|
async findById(id: string): Promise<FormResult | null> {
|
|
const formResult = await this.formResultRepo.findOne({
|
|
where: { id },
|
|
});
|
|
if (!formResult) {
|
|
throw new NotFoundException(`FormResult with ID "${id}" not found`);
|
|
}
|
|
return formResult;
|
|
}
|
|
|
|
async update(
|
|
id: string,
|
|
data: UpdateFormResultDto,
|
|
): Promise<FormResult | null> {
|
|
const result = await this.formResultRepo.update(
|
|
{ id },
|
|
{ ...data, updatedAt: new Date() },
|
|
);
|
|
if (result.affected === 0) {
|
|
throw new NotFoundException(`FormResult with ID "${id}" not found`);
|
|
}
|
|
return await this.findById(id);
|
|
}
|
|
|
|
async remove(id: string): Promise<void> {
|
|
const result = await this.formResultRepo.delete({ id });
|
|
if (result.affected === 0) {
|
|
throw new NotFoundException(`FormResult with ID "${id}" not found`);
|
|
}
|
|
}
|
|
|
|
async getFormStatistics(formId: string): Promise<FormResult | null> {
|
|
const formResult = await this.formResultRepo.findOne({ where: { formId } });
|
|
if (!formResult) {
|
|
throw new NotFoundException(`FormResult with formId "${formId}" not found`);
|
|
}
|
|
return formResult;
|
|
}
|
|
|
|
async scheduleFormStatistics(formId: string): Promise<void> {
|
|
const form = await this.formRepo.findOne({ where: { id: formId } });
|
|
if (!form) {
|
|
throw new NotFoundException('Form with this ID not found');
|
|
}
|
|
if (form.isEnded) {
|
|
await this.statisticsQueue.remove(`form-statistics-${formId}`);
|
|
return; // Stop scheduler if form is ended
|
|
}
|
|
await this.statisticsQueue.upsertJobScheduler(
|
|
`form-statistics-${formId}`,
|
|
{
|
|
every: 10 * 60 * 1000, // 10 minutes in milliseconds
|
|
},
|
|
{
|
|
name: 'getFormStatistics',
|
|
data: { formId },
|
|
},
|
|
);
|
|
}
|
|
} |