user
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@mikro-orm/nestjs';
|
||||
import { EntityRepository, FilterQuery } from '@mikro-orm/core';
|
||||
import { User, UserStatus } from './entities/user.entity';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
import { UpdateUserDto } from './dto/update-user.dto';
|
||||
import { FindUsersDto } from './dto/find-user.dto';
|
||||
import { PaginatedResult } from 'src/common/interfaces/pagination.interface';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(
|
||||
@InjectRepository(User)
|
||||
private readonly userRepository: EntityRepository<User>,
|
||||
private readonly em: EntityManager,
|
||||
) {}
|
||||
|
||||
async findOrCreateByPhone(phone: string): Promise<User> {
|
||||
let user = await this.userRepository.findOne({ phone });
|
||||
|
||||
if (!user) {
|
||||
user = this.userRepository.create({
|
||||
phone,
|
||||
});
|
||||
await this.em.persistAndFlush(user);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
async updateUser(userId: number, dto: UpdateUserDto): Promise<User> {
|
||||
const user = await this.em.findOneOrFail(User, userId, {}).catch(() => {
|
||||
throw new NotFoundException(`User with ID ${userId} not found.`);
|
||||
});
|
||||
|
||||
this.em.assign(user, { ...dto, status: UserStatus.finished });
|
||||
|
||||
await this.em.flush();
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
async findByPhone(phone: string): Promise<User | null> {
|
||||
return this.userRepository.findOne({ phone });
|
||||
}
|
||||
|
||||
async findById(id: number): Promise<User | null> {
|
||||
return this.userRepository.findOne({ id });
|
||||
}
|
||||
|
||||
async create(phone: string): Promise<User> {
|
||||
const user = this.userRepository.create({ phone });
|
||||
await this.em.persistAndFlush(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
async findAll(dto: FindUsersDto): Promise<PaginatedResult<User>> {
|
||||
const { page = 1, limit = 10, search, education, orderBy = 'createdAt', order = 'desc' } = dto;
|
||||
|
||||
// 1. Calculate pagination
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
// 2. Build the 'where' filter query
|
||||
const where: FilterQuery<User> = {};
|
||||
|
||||
if (education) {
|
||||
where.education = education;
|
||||
}
|
||||
|
||||
// 4. Add 'search' logic (case-insensitive)
|
||||
if (search) {
|
||||
const searchPattern = `%${search}%`;
|
||||
// $ilike is case-insensitive (PostgreSQL). Use $like for MySQL (often CI by default)
|
||||
where.$or = [
|
||||
{ firstName: { $ilike: searchPattern } },
|
||||
{ lastName: { $ilike: searchPattern } },
|
||||
{ phone: { $ilike: searchPattern } },
|
||||
{ nationalCode: { $ilike: searchPattern } },
|
||||
{ personalCode: { $ilike: searchPattern } },
|
||||
];
|
||||
}
|
||||
|
||||
// 5. Execute the query using findAndCount
|
||||
const [users, total] = await this.userRepository.findAndCount(where, {
|
||||
limit,
|
||||
offset,
|
||||
orderBy: { [orderBy]: order.toLowerCase() as 'asc' | 'desc' },
|
||||
});
|
||||
|
||||
// 6. Calculate total pages
|
||||
const totalPages = Math.ceil(total / limit);
|
||||
|
||||
// 7. Return the paginated result
|
||||
return {
|
||||
data: users,
|
||||
meta: {
|
||||
total,
|
||||
page,
|
||||
limit,
|
||||
totalPages,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user