Merge branch 'user'
This commit is contained in:
commit
610747a8d6
|
@ -24,6 +24,9 @@
|
|||
"@nestjs/core": "^6.0.0",
|
||||
"@nestjs/platform-express": "^6.0.0",
|
||||
"@nestjs/typeorm": "^6.1.2",
|
||||
"@types/bcrypt": "^3.0.0",
|
||||
"bcrypt": "^3.0.6",
|
||||
"class-transformer": "^0.2.3",
|
||||
"mysql": "^2.17.1",
|
||||
"reflect-metadata": "^0.1.12",
|
||||
"rimraf": "^2.6.2",
|
||||
|
|
|
@ -3,6 +3,7 @@ import { AppController } from './app.controller';
|
|||
import { AppService } from './app.service';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { PostModule } from './modules/post/post.module';
|
||||
import { UserModule } from './modules/user/user.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
@ -17,6 +18,7 @@ import { PostModule } from './modules/post/post.module';
|
|||
entities: [__dirname + '/**/*.entity{.ts,.js}'],
|
||||
}),
|
||||
PostModule,
|
||||
UserModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UserController } from './user.controller';
|
||||
|
||||
describe('User Controller', () => {
|
||||
let controller: UserController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [UserController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<UserController>(UserController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,27 @@
|
|||
import { Controller, Post, Body, Get, Param, UseInterceptors, ClassSerializerInterceptor, Put } from '@nestjs/common';
|
||||
import { UserService } from './user.service';
|
||||
import { UserDto, UpdatePasswordDto } from './user.dto';
|
||||
|
||||
@Controller('users')
|
||||
export class UserController {
|
||||
constructor(
|
||||
private readonly userService: UserService,
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
async store(@Body() data: UserDto) {
|
||||
return await this.userService.store(data);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@UseInterceptors(ClassSerializerInterceptor)
|
||||
async show(@Param('id') id: string) {
|
||||
return await this.userService.show(id);
|
||||
}
|
||||
|
||||
@Put(':id/password')
|
||||
@UseInterceptors(ClassSerializerInterceptor)
|
||||
async updatePassword(@Param('id') id: string, @Body() data: UpdatePasswordDto) {
|
||||
return await this.userService.updatePassword(id, data)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export class UserDto {
|
||||
readonly username: string;
|
||||
readonly password: string;
|
||||
}
|
||||
|
||||
export class UpdatePasswordDto {
|
||||
readonly password: string;
|
||||
readonly newPassword: string;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, BeforeInsert, BeforeUpdate } from 'typeorm';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { Exclude } from 'class-transformer';
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column('varchar', { unique: true })
|
||||
username: string;
|
||||
|
||||
@Column('longtext', { nullable: true })
|
||||
@Exclude()
|
||||
password: string;
|
||||
|
||||
@CreateDateColumn()
|
||||
created: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated: Date;
|
||||
|
||||
@BeforeInsert()
|
||||
@BeforeUpdate()
|
||||
async hashPassword() {
|
||||
this.password = await bcrypt.hash(this.password, 10);
|
||||
}
|
||||
|
||||
async comparePassword(password: string) {
|
||||
return await bcrypt.compare(password, this.password);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { UserController } from './user.controller';
|
||||
import { UserService } from './user.service';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { User } from './user.entity';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([User]),
|
||||
],
|
||||
controllers: [UserController],
|
||||
providers: [UserService]
|
||||
})
|
||||
export class UserModule {}
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
describe('UserService', () => {
|
||||
let service: UserService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UserService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<UserService>(UserService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
import { Injectable, BadRequestException, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { User } from './user.entity';
|
||||
import { UserDto, UpdatePasswordDto } from './user.dto';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(
|
||||
@InjectRepository(User)
|
||||
private readonly userRepository: Repository<User>,
|
||||
) { }
|
||||
|
||||
async store(data: UserDto) {
|
||||
const { username } = data;
|
||||
const user = await this.userRepository.findOne({ username });
|
||||
if (user) {
|
||||
throw new BadRequestException('用户已经存在');
|
||||
}
|
||||
const entity = await this.userRepository.create(data);
|
||||
await this.userRepository.save(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
async show(id: string) {
|
||||
const entity = await this.userRepository.findOne(id);
|
||||
if (!entity) {
|
||||
throw new NotFoundException('没有找到用户');
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
async updatePassword(id: string, data: UpdatePasswordDto) {
|
||||
const { password, newPassword } = data;
|
||||
const entity = await this.userRepository.findOne(id)
|
||||
if (!entity) {
|
||||
throw new NotFoundException('没有找到用户')
|
||||
}
|
||||
const match = await entity.comparePassword(password)
|
||||
if (!match) {
|
||||
throw new BadRequestException('密码错误')
|
||||
}
|
||||
entity.password = newPassword
|
||||
return await this.userRepository.save(entity)
|
||||
}
|
||||
}
|
25
yarn.lock
25
yarn.lock
|
@ -72,6 +72,11 @@
|
|||
consola "^2.3.0"
|
||||
node-fetch "^2.3.0"
|
||||
|
||||
"@types/bcrypt@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npm.taobao.org/@types/bcrypt/download/@types/bcrypt-3.0.0.tgz#851489a9065a067cb7f3c9cbe4ce9bed8bba0876"
|
||||
integrity sha1-hRSJqQZaBny388nL5M6b7Yu6CHY=
|
||||
|
||||
"@types/body-parser@*":
|
||||
version "1.17.0"
|
||||
resolved "https://registry.npm.taobao.org/@types/body-parser/download/@types/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c"
|
||||
|
@ -612,6 +617,14 @@ bcrypt-pbkdf@^1.0.0:
|
|||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
bcrypt@^3.0.6:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.npm.taobao.org/bcrypt/download/bcrypt-3.0.6.tgz#f607846df62d27e60d5e795612c4f67d70206eb2"
|
||||
integrity sha1-9geEbfYtJ+YNXnlWEsT2fXAgbrI=
|
||||
dependencies:
|
||||
nan "2.13.2"
|
||||
node-pre-gyp "0.12.0"
|
||||
|
||||
bignumber.js@7.2.1:
|
||||
version "7.2.1"
|
||||
resolved "https://registry.npm.taobao.org/bignumber.js/download/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f"
|
||||
|
@ -837,6 +850,11 @@ ci-info@^1.5.0:
|
|||
resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
|
||||
integrity sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc=
|
||||
|
||||
class-transformer@^0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.npm.taobao.org/class-transformer/download/class-transformer-0.2.3.tgz#598c92ca71dcca73f91ccb875d74a3847ccfa32d"
|
||||
integrity sha1-WYySynHcynP5HMuHXXSjhHzPoy0=
|
||||
|
||||
class-utils@^0.3.5:
|
||||
version "0.3.6"
|
||||
resolved "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
|
||||
|
@ -3371,6 +3389,11 @@ mz@^2.4.0:
|
|||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
nan@2.13.2:
|
||||
version "2.13.2"
|
||||
resolved "https://registry.npm.taobao.org/nan/download/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7"
|
||||
integrity sha1-9R3Hrma6fV1V4ebU2AkugCya7+c=
|
||||
|
||||
nan@^2.12.1:
|
||||
version "2.14.0"
|
||||
resolved "https://registry.npm.taobao.org/nan/download/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
||||
|
@ -3448,7 +3471,7 @@ node-notifier@^5.2.1:
|
|||
shellwords "^0.1.1"
|
||||
which "^1.3.0"
|
||||
|
||||
node-pre-gyp@^0.12.0:
|
||||
node-pre-gyp@0.12.0, node-pre-gyp@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.npm.taobao.org/node-pre-gyp/download/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149"
|
||||
integrity sha1-ObpLsUOdoDApX4meO1ILd4V2YUk=
|
||||
|
|
Loading…
Reference in New Issue