add user module and jwt

This commit is contained in:
liuyi 2025-06-22 23:00:33 +08:00
parent 85b2062a2a
commit ac80ecaf4b
6 changed files with 247 additions and 0 deletions

View File

@ -0,0 +1,105 @@
import {
Body,
Controller,
Get,
Patch,
Post,
Request,
SerializeOptions,
UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { pick } from 'lodash';
import { Depends } from '@/modules/restful/decorators/depend.decorator';
import { Guest } from '../decorators/guest.decorator';
import { RequestUser } from '../decorators/user.request.decorator';
import { UpdateAccountDto, UpdatePasswordDto } from '../dtos/account.dto';
import { CredentialDto, RegisterDto } from '../dtos/auth.dto';
import { UserEntity } from '../entities/UserEntity';
import { LocalAuthGuard } from '../guards/local.auth.guard';
import { AuthService } from '../services/auth.service';
import { UserService } from '../services/user.service';
import { UserModule } from '../user.module';
@ApiTags('账户操作')
@Depends(UserModule)
@Controller('account')
export class AccountController {
constructor(
protected authService: AuthService,
protected userService: UserService,
) {}
/**
* 使
* @param data
*/
@Post('register')
@Guest()
async register(@Body() data: RegisterDto) {
return this.authService.register(data);
}
/**
* [(,,)+]
* @param user
* @param _data
*/
@Post('login')
@Guest()
@UseGuards(LocalAuthGuard)
async login(@RequestUser() user: ClassToPlain<UserEntity>, @Body() _data: CredentialDto) {
return { token: await this.authService.createToken(user.id) };
}
/**
*
* @param req
*/
@Post('logout')
@ApiBearerAuth()
async logout(@Request() req: any) {
return this.authService.logout(req);
}
/**
* []
* @param user
*/
@Get('profile')
@ApiBearerAuth()
@SerializeOptions({ groups: ['user-detail'] })
async profile(@RequestUser() user: ClassToPlain<UserEntity>) {
return this.userService.detail(user.id);
}
/**
*
* @param user
* @param data
*/
@Patch()
@ApiBearerAuth()
@SerializeOptions({ groups: ['user-detail'] })
async update(@RequestUser() user: ClassToPlain<UserEntity>, @Body() data: UpdateAccountDto) {
return this.userService.update({ id: user.id, ...pick(data, ['username', 'nickname']) });
}
/**
* []
* @param user
* @param data
*/
@Patch('change-password')
@ApiBearerAuth()
@SerializeOptions({ groups: ['user-detail'] })
async changePassword(
@RequestUser() user: ClassToPlain<UserEntity>,
@Body() data: UpdatePasswordDto,
) {
return this.authService.changePassword(user, data);
}
}

View File

@ -0,0 +1,2 @@
export * from './account.controller';
export * from './user.controller';

View File

@ -0,0 +1,95 @@
import {
Body,
Controller,
Delete,
Get,
Param,
ParseUUIDPipe,
Patch,
Post,
SerializeOptions,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { DeleteWithTrashDto, RestoreDto } from '@/modules/content/dtos/delete.with.trash.dto';
import { Depends } from '@/modules/restful/decorators/depend.decorator';
import { UserModule } from '@/modules/user/user.module';
import { Guest } from '../decorators/guest.decorator';
import { CreateUserDto, UpdateUserDto } from '../dtos/user.dto';
import { UserService } from '../services/user.service';
@ApiTags('用户管理')
@Depends(UserModule)
@Controller('users')
export class UserController {
constructor(protected service: UserService) {}
/**
*
*/
@Get()
@Guest()
@SerializeOptions({ groups: ['user-list'] })
async list() {
return this.service.list();
}
/**
*
* @param id
*/
@Get(':id')
@Guest()
@SerializeOptions({ groups: ['user-detail'] })
async detail(@Param('id', new ParseUUIDPipe()) id: string) {
return this.service.detail(id);
}
/**
*
* @param data
*/
@Post()
@ApiBearerAuth()
@SerializeOptions({ groups: ['user-detail'] })
async store(@Body() data: CreateUserDto) {
return this.service.create(data);
}
/**
*
* @param data
*/
@Patch()
@ApiBearerAuth()
@SerializeOptions({ groups: ['user-detail'] })
async update(@Body() data: UpdateUserDto) {
return this.service.update(data);
}
/**
*
* @param data
*/
@Delete()
@ApiBearerAuth()
@SerializeOptions({ groups: ['user-list'] })
async delete(@Body() data: DeleteWithTrashDto) {
const { ids, trash } = data;
return this.service.delete(ids, trash);
}
/**
*
* @param data
*/
@Patch('restore')
@ApiBearerAuth()
@SerializeOptions({ groups: ['user-list'] })
async restore(@Body() data: RestoreDto) {
const { ids } = data;
return this.service.restore(ids);
}
}

View File

@ -0,0 +1,17 @@
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
import { isNil } from 'lodash';
import { Observable } from 'rxjs';
export class UserInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> {
const request: any = context.switchToHttp().getRequest();
if (!isNil(request.user?.id)) {
if (isNil(request.body)) {
request.body = { userId: request.user.id };
} else {
request.body.userId = request.user.id;
}
}
return next.handle();
}
}

View File

@ -0,0 +1,24 @@
import { RouteOption, TagOption } from '../restful/types';
import * as controllers from './controllers';
export function createUserApi() {
const routes: Record<'app', RouteOption[]> = {
app: [
{
name: 'app.user',
path: 'user',
controllers: Object.values(controllers),
},
],
};
const tags: Record<'app', (string | TagOption)[]> = {
app: [
{ name: '用户管理', description: '对用户进行CRUD操作' },
{ name: '账户操作', description: '注册登录、查看修改账户信息、修改密码等' },
],
};
return { routes, tags };
}

View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class UserModule {}