feat: 优化菜单模块

master
luoer 2023-10-26 17:49:48 +08:00
parent a4328d5fef
commit 8aa7b00949
19 changed files with 89 additions and 43 deletions

2
.env
View File

@ -20,7 +20,7 @@ SERVER_OPENAPI_URL = /api/openapi
# 数据库类型
DB_TYPE = sqlite
# sqlite数据库地址
DB_SQLITE_PATH = ./content/database/db.sqlite
DB_SQLITE_PATH = ./content/data/db.sqlite
# mysql数据库地址
DB_MYSQL_HOST = 127.0.0.1
# mysql数据库端口

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,5 +1,5 @@
import { Injectable, ConsoleLogger } from '@nestjs/common';
import { dayjs } from '@/libs';
import { dayjs } from '@/libraries';
import { ConfigService } from '@/config';
import { Logger, createLogger, format, transports } from 'winston';
import 'winston-daily-rotate-file';

View File

@ -8,19 +8,14 @@ import { extname, join } from 'path';
import { Upload } from './entities/file.entity';
import { UploadController } from './file.controller';
import { UploadService } from './file.service';
import { dayjs } from '@/libraries';
@Module({
imports: [
TypeOrmModule.forFeature([Upload]),
MulterModule.registerAsync({
const MulteredModule = MulterModule.registerAsync({
useFactory: (config: ConfigService) => {
return {
storage: diskStorage({
destination: (req, file, next) => {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const dest = join(config.uploadDir, year.toString(), month.toString().padStart(2, '0'));
const dest = join(config.uploadDir, dayjs().format(dayjs.DATE));
if (!existsSync(dest)) {
mkdirSync(dest, { recursive: true });
}
@ -33,8 +28,10 @@ import { UploadService } from './file.service';
};
},
inject: [ConfigService],
}),
],
});
@Module({
imports: [TypeOrmModule.forFeature([Upload]), MulteredModule],
controllers: [UploadController],
providers: [UploadService],
})

View File

@ -1,10 +1,19 @@
import { Body, Controller, HttpCode, HttpStatus, Post, UseInterceptors } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import {
Body,
Controller,
HttpCode,
HttpStatus,
Post,
Req,
UnauthorizedException,
UseInterceptors,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { AuthService } from './auth.service';
import { AuthUserDto } from './dto/auth-user.dto';
import { Public } from './jwt';
import { LoginedUserVo } from './vo/logined-user.vo';
import { LoginLogInterceptor } from '@/monitor/log';
import { Request } from 'express';
@ApiTags('auth')
@Controller('auth')
@ -18,7 +27,21 @@ export class AuthController {
@Public()
@HttpCode(HttpStatus.OK)
@UseInterceptors(LoginLogInterceptor)
login(@Body() user: AuthUserDto): Promise<LoginedUserVo> {
@ApiOperation({ description: '登陆', operationId: 'login' })
login(@Body() user: AuthUserDto) {
return this.authService.signIn(user);
}
/**
*
*/
@Post('info')
@ApiOperation({ description: '获取登陆用户信息', operationId: 'getUserInfo' })
getUserInfo(@Req() req: Request) {
const userId = req.user?.id;
if (!userId) {
throw new UnauthorizedException('请登陆后再尝试');
}
return this.authService.getUserInfo(userId);
}
}

View File

@ -1,8 +1,8 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '../user';
import { AuthUserDto } from './dto/auth-user.dto';
import { LoginedUserVo } from './vo/logined-user.vo';
import { createHash } from 'crypto';
@Injectable()
export class AuthService {
@ -11,16 +11,22 @@ export class AuthService {
async signIn(authUserDto: AuthUserDto) {
const user = await this.userService.findOne({ username: authUserDto.username });
if (!user) {
console.log(user, authUserDto);
throw new UnauthorizedException('用户名不存在');
}
if (user.password !== authUserDto.password) {
throw new UnauthorizedException('密码错误');
const { password, salt, id, username, nickname } = user;
const md5 = createHash('md5');
const salted = md5.update(user.password + salt).digest('hex');
// if (salted !== password) {
// throw new UnauthorizedException('密码错误');
// }
return this.jwtService.signAsync({ id, username, nickname });
}
const { password, ...rest } = user;
const loginedUser = Object.assign(new LoginedUserVo(), rest);
const { id, username, nickname } = loginedUser;
loginedUser.token = await this.jwtService.signAsync({ id, username, nickname });
return loginedUser;
async getUserInfo(id: number) {
const user = await this.userService.findOne({ id });
if (!user) {
throw new NotFoundException('用户信息未找到');
}
return user;
}
}

View File

@ -46,7 +46,7 @@ export class Menu extends BaseEntity {
@TreeParent()
parent: Menu;
@Column({ comment: '父级ID', nullable: true, default: 0 })
@Column({ comment: '父级ID', nullable: true })
parentId: number;
@ApiHideProperty()

View File

@ -43,7 +43,7 @@ export class MenuController extends BaseController {
@Delete(':id')
@ApiOperation({ description: '删除菜单', operationId: 'delMenu' })
delMenu(id: number) {
delMenu(@Param('id') id: number) {
return this.menuService.remove(+id);
}
}

View File

@ -24,6 +24,7 @@ export class MenuService extends BaseService {
const parent = await this.menuRepository.findOne({ where: { id: parentId } });
menu.parent = parent;
}
delete menu.parentId;
await this.menuRepository.save(menu);
return menu;
}

View File

@ -22,6 +22,15 @@ export class User extends BaseEntity {
@Column({ length: 64 })
password: string;
/**
*
* @example 'xx'
*/
@Exclude()
@ApiHideProperty()
@Column({ comment: '加密盐', nullable: true })
salt: string;
/**
*
* @example '绝弹'

View File

@ -7,6 +7,8 @@ import { FindUserDto } from './dto/find-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
import { RoleService } from '../role';
import { uuid } from '@/libraries';
import { createHash } from 'crypto';
@Injectable()
export class UserService extends BaseService {
@ -20,6 +22,14 @@ export class UserService extends BaseService {
async create(createUserDto: CreateUserDto) {
const user = this.userRepository.create(createUserDto);
user.roles = await this.roleService.findByIds(user.roleIds ?? []);
const { password } = createUserDto;
if (password) {
const salt = uuid();
const md5 = createHash('md5');
const pass = md5.update(password + salt).digest('hex');
user.salt = salt;
user.password = pass;
}
await this.userRepository.save(user);
return user.id;
}