feat: 添加模板生成器
parent
ee9cb2c81d
commit
a8952831ab
|
|
@ -6,10 +6,7 @@ module.exports = {
|
|||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||
extends: [
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
|
|
@ -20,6 +17,7 @@ module.exports = {
|
|||
'@typescript-eslint/interface-name-prefix': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off'
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
},
|
||||
eslintIgnores: ['scripts/**/*.js'],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@
|
|||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0",
|
||||
"plop": "^3.1.2",
|
||||
"prettier": "^2.3.2",
|
||||
"redis": "^4.6.7",
|
||||
"source-map-support": "^0.5.20",
|
||||
|
|
|
|||
644
pnpm-lock.yaml
644
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,35 @@
|
|||
const { join } = require('path');
|
||||
|
||||
module.exports = function main(/** @type { import('plop').NodePlopAPI } */ plop) {
|
||||
plop.setHelper('fileName', function fileName(name) {
|
||||
return name.split('/').pop();
|
||||
});
|
||||
|
||||
plop.setHelper('upcaseName', function upcaseName(name) {
|
||||
const filename = plop.getHelper('fileName')(name);
|
||||
return filename.charAt(0).toUpperCase() + filename.slice(1);
|
||||
});
|
||||
|
||||
plop.setGenerator('module', {
|
||||
prompts: [
|
||||
{
|
||||
name: 'name',
|
||||
message: '请输入模块名称',
|
||||
type: 'input',
|
||||
},
|
||||
{
|
||||
name: 'cnName',
|
||||
message: '请输入模块中文名称',
|
||||
type: 'input',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'addMany',
|
||||
destination: join(process.cwd(), 'src/{{name}}'),
|
||||
base: 'module',
|
||||
templateFiles: 'module/**/*.ts',
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { Role } from '@/modules/role/entities/role.entity';
|
||||
import { IsInt, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class CreateUserDto {
|
||||
/**
|
||||
* 登录账号
|
||||
* @example 'juetan'
|
||||
*/
|
||||
@IsString()
|
||||
username: string;
|
||||
/**
|
||||
* 用户密码
|
||||
* @example 'password'
|
||||
*/
|
||||
@IsString()
|
||||
password: string;
|
||||
/**
|
||||
* 用户昵称
|
||||
* @example '绝弹'
|
||||
*/
|
||||
@IsString()
|
||||
nickname: string;
|
||||
/**
|
||||
* 用户头像
|
||||
* @example './assets/222421415123.png '
|
||||
*/
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
avatar: string;
|
||||
/**
|
||||
* 用户角色
|
||||
* @example [1, 2, 3]
|
||||
*/
|
||||
@IsOptional()
|
||||
@IsInt({ each: true })
|
||||
roles: Role[];
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { PaginationDto } from '@/common/response';
|
||||
import { IntersectionType } from '@nestjs/swagger';
|
||||
import { IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class FindUserDto extends IntersectionType(PaginationDto) {
|
||||
/**
|
||||
* 用户昵称
|
||||
* @example '绝弹'
|
||||
*/
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
nickname?: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { PartialType } from '@nestjs/swagger';
|
||||
import { CreateUserDto } from './create-{{fileName name}}.dto';
|
||||
|
||||
export class UpdateUserDto extends PartialType(CreateUserDto) {}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import { ApiHideProperty } from '@nestjs/swagger';
|
||||
import { Exclude } from 'class-transformer';
|
||||
import { BaseEntity } from '@/database';
|
||||
import { Post } from '@/modules/post';
|
||||
import { Role } from '@/modules/role';
|
||||
import { Column, Entity, JoinTable, ManyToMany, RelationId } from 'typeorm';
|
||||
|
||||
@Entity({ orderBy: { id: 'DESC' } })
|
||||
export class User extends BaseEntity {
|
||||
/**
|
||||
* 登录账号
|
||||
* @example 'juetan'
|
||||
*/
|
||||
@Column({ length: 48 })
|
||||
username: string;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
* @example '绝弹'
|
||||
*/
|
||||
@Column({ length: 48 })
|
||||
nickname: string;
|
||||
|
||||
/**
|
||||
* 用户介绍
|
||||
* @example '这个人很懒, 什么也没有留下!'
|
||||
*/
|
||||
@Column({ default: '这个人很懒, 什么也没有留下!' })
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* 用户头像(URL)
|
||||
* @example './assets/222421415123.png '
|
||||
*/
|
||||
@Column({ nullable: true })
|
||||
avatar: string;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
* @example 'password'
|
||||
*/
|
||||
@Exclude()
|
||||
@Column({ length: 64 })
|
||||
password: string;
|
||||
|
||||
/**
|
||||
* 用户邮箱
|
||||
* @example 'example@mail.com'
|
||||
*/
|
||||
@Column({ length: 64, nullable: true })
|
||||
email: string;
|
||||
|
||||
/**
|
||||
* 用户文章
|
||||
*/
|
||||
@ApiHideProperty()
|
||||
@ManyToMany(() => Post, (post) => post.author)
|
||||
@JoinTable()
|
||||
posts: Post[];
|
||||
|
||||
/**
|
||||
* 用户角色
|
||||
*/
|
||||
@ApiHideProperty()
|
||||
@ManyToMany(() => Role, (role) => role.user)
|
||||
@JoinTable()
|
||||
roles: Role[];
|
||||
|
||||
@RelationId('roles')
|
||||
roleIds: number[];
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export * from './dto/create-{{fileName name}}.dto';
|
||||
export * from './dto/update-{{fileName name}}.dto';
|
||||
export * from './entities/{{fileName name}}.entity';
|
||||
export * from './{{fileName name}}.controller';
|
||||
export * from './{{fileName name}}.module';
|
||||
export * from './{{fileName name}}.service';
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { BaseController } from '@/common/base';
|
||||
import { Respond, RespondType } from '@/common/response';
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, Version } from '@nestjs/common';
|
||||
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { CreateUserDto } from './dto/create-{{fileName name}}.dto';
|
||||
import { FindUserDto } from './dto/find-{{fileName name}}.dto';
|
||||
import { UpdateUserDto } from './dto/update-{{fileName name}}.dto';
|
||||
import { User } from './entities/{{fileName name}}.entity';
|
||||
import { UserService } from './{{fileName name}}.service';
|
||||
|
||||
@ApiTags('{{fileName name}}')
|
||||
@Controller('users')
|
||||
export class UserController extends BaseController {
|
||||
constructor(private userService: UserService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ description: '创建{{fileName cnName}}', operationId: 'addUser' })
|
||||
create(@Body() createUserDto: CreateUserDto) {
|
||||
return this.userService.create(createUserDto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@Respond(RespondType.PAGINATION)
|
||||
@ApiOkResponse({ isArray: true, type: User })
|
||||
@ApiOperation({ description: '批量查询{{fileName cnName}}', operationId: 'getUsers' })
|
||||
async findMany(@Query() query: FindUserDto) {
|
||||
return this.userService.findMany(query);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@Version('2')
|
||||
@ApiOperation({ deprecated: true, description: '查询{{fileName cnName}}', operationId: 'getUserv2' })
|
||||
findOne(@Param('id') id: number) {
|
||||
return this.userService.findOne(+id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@ApiOperation({ description: '更新{{fileName cnName}}', operationId: 'updateUser' })
|
||||
update(@Param('id') id: number, @Body() updateUserDto: UpdateUserDto) {
|
||||
return this.userService.update(+id, updateUserDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@ApiOperation({ description: '删除{{fileName cnName}}', operationId: 'deleteUser' })
|
||||
remove(@Param('id') id: number) {
|
||||
return this.userService.remove(+id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { User } from './entities/{{fileName name}}.entity';
|
||||
import { UserController } from './{{fileName name}}.controller';
|
||||
import { UserService } from './{{fileName name}}.service';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([User])],
|
||||
controllers: [UserController],
|
||||
providers: [UserService],
|
||||
exports: [UserService],
|
||||
})
|
||||
export class UserModule {}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
import { BaseService } from '@/common/base';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Like, Repository } from 'typeorm';
|
||||
import { CreateUserDto } from './dto/create-{{fileName name}}.dto';
|
||||
import { FindUserDto } from './dto/find-{{fileName name}}.dto';
|
||||
import { UpdateUserDto } from './dto/update-{{fileName name}}.dto';
|
||||
import { User } from './entities/{{fileName name}}.entity';
|
||||
|
||||
@Injectable()
|
||||
export class UserService extends BaseService {
|
||||
constructor(@InjectRepository(User) private userRepository: Repository<User>) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
*/
|
||||
async create(createUserDto: CreateUserDto) {
|
||||
const user = this.userRepository.create(createUserDto);
|
||||
if (createUserDto.roles) {
|
||||
user.roles = createUserDto.roles.map((id) => ({ id })) as any;
|
||||
}
|
||||
await this.userRepository.save(user);
|
||||
return user.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找所有用户
|
||||
*/
|
||||
async findMany(findUserdto: FindUserDto) {
|
||||
const { nickname: _nickname, page, size } = findUserdto;
|
||||
const nickname = _nickname && Like(`%${_nickname}%`);
|
||||
const { skip, take } = this.formatPagination(page, size, true);
|
||||
return this.userRepository.findAndCount({ skip, take, where: { nickname } });
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查找用户
|
||||
*/
|
||||
findOne(idOrOptions: number | Partial<User>) {
|
||||
const where = typeof idOrOptions === 'number' ? { id: idOrOptions } : (idOrOptions as any);
|
||||
return this.userRepository.findOne({ where });
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id
|
||||
*/
|
||||
update(id: number, updateUserDto: UpdateUserDto) {
|
||||
return this.userRepository.update(id, updateUserDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id删除用户
|
||||
*/
|
||||
remove(id: number) {
|
||||
return this.userRepository.softDelete(id);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,5 +21,6 @@
|
|||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"exclude": ["scripts", "dist"]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue