Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 支持 NestJS 后端 #139

Merged
merged 21 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
253feab
feat: 修复package.json拼写错误
Muyu-art May 16, 2024
96f3b4b
feat: nestJs first commit
Muyu-art Jul 2, 2024
bdf0c62
feat: 添加mysql && auth.guard配置文件
Muyu-art Jul 3, 2024
686050c
fix: 修复初始化password显示为undefined问题
Muyu-art Jul 4, 2024
c8e62f9
feat: 新增删除用户和密码修改
Muyu-art Jul 4, 2024
95afe88
feat: redis实现登录和登出
Muyu-art Jul 4, 2024
3855295
fix: 更改删除用户和修改密码抛出异常
Muyu-art Jul 4, 2024
0f2a142
fix: 修改密码后删除token,修复退出登录参数异常
Muyu-art Jul 4, 2024
239acb2
fix: 修改Redis为Module,使用注入的service;软删除字段调整为getTime
Muyu-art Jul 5, 2024
fcef580
fix: redis配置注入ConfigService配置文件
Muyu-art Jul 5, 2024
5d1c139
fix: 删除config模块,使用process.env获取env配置
Muyu-art Jul 5, 2024
bfb34f3
fix: 补充登录情况下用户不存在的判定
Muyu-art Jul 6, 2024
e407373
feat: 新增权限删除
Muyu-art Jul 6, 2024
471ee4a
feat: 新增role删除,修复role更新冲突问题
Muyu-art Jul 6, 2024
3855ae1
feat: 新增menu删除,修复getMenus错误
Muyu-art Jul 7, 2024
ccccdb1
fix: 修复.gitignore忽略.env文件
Muyu-art Jul 7, 2024
f60ab9c
fix: 删除app.controller和app.service
Muyu-art Jul 7, 2024
82b67b4
fix: 删除auth.controller中test接口
Muyu-art Jul 7, 2024
87d4b38
fix: 修复auth.module
Muyu-art Jul 7, 2024
1d07db3
fix: 删除auth/constant文件
Muyu-art Jul 7, 2024
6081a3f
fix: 删除package.json中pg依赖
Muyu-art Jul 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/commands/src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default async function () {
if (toolkitName) {
try {
const pkgPath = path.join(home.getModulesPath(), toolkitName, 'package.json');
log.debug(`${toolkitName} pacage.json path = ${pkgPath}`);
log.debug(`${toolkitName} package.json path = ${pkgPath}`);
const pkg = require(pkgPath);
console.log(chalk.magenta(`${toolkitName} v${pkg.version}`));
} catch (e) {
Expand Down
9 changes: 9 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DATABASE_HOST = 'localhost'
DATABASE_PORT = 3306
DATABASE_USERNAME = 'root'
DATABASE_PASSWORD = 'root'
DATABASE_NAME = 'ospp-nest'
DATABASE_SYNCHRONIZE = 'true'
DATABASE_AUTOLOADENTITIES = 'true'

AUTH_SECRET = 'secret'
2 changes: 1 addition & 1 deletion packages/toolkits/pro/template/server/nestJs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ npm-debug.log
/.nyc_output

# dist
/dist
/dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({
providers: [
{
provide: ConfigService,
// 刚刚的ConfigService要传入.env路径及文件名
useValue: new ConfigService(`.env`),
},
],
exports: [ConfigService],
})
export class ConfigModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from './config.service';

describe('ConfigService', () => {
let service: ConfigService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ConfigService],
}).compile();

service = module.get<ConfigService>(ConfigService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Injectable, Logger } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';

@Injectable()
export class ConfigService {
private envConfig: { [key: string]: string };

constructor(filePath: string) {
// 读取.env文件,通过dotenv.parse方法形成key-value pairs
// 存在envConfig变量里
this.envConfig = dotenv.parse(fs.readFileSync(filePath));
}

get(key: string) {
return this.envConfig[key];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Module } from '@nestjs/common';
import { DbService } from './db.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigService } from '../../config/config.service';
import { ConfigModule } from '../../config/config.module';

@Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useClass: DbService,
}),
ConfigModule,
],
providers: [DbService],
exports: [DbService],
})
export class DbModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { DbService } from './db.service';

describe('DbService', () => {
let service: DbService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [DbService],
}).compile();

service = module.get<DbService>(DbService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Injectable } from '@nestjs/common';
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
import { ConfigService } from '../../config/config.service';

@Injectable()
export class DbService implements TypeOrmOptionsFactory {
// 注入config service取得env变量
constructor(private readonly configService: ConfigService) {}
// 回传TypeOrmOptions对象
createTypeOrmOptions(): TypeOrmModuleOptions {
return {
type: 'mysql',
host: this.configService.get('DATABASE_HOST'),
port: parseInt(this.configService.get('DATABASE_PORT')),
username: this.configService.get('DATABASE_USERNAME'),
password: this.configService.get('DATABASE_PASSWORD'),
database: this.configService.get('DATABASE_NAME'),
synchronize: this.configService.get('DATABASE_SYNCHRONIZE') === 'true',
autoLoadEntities:
this.configService.get('DATABASE_AUTOLOADENTITIES') === 'true',
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './db.module';
export * from './db.service';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": true,
"outDir": "../../dist/libs/db"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './user';
export * from './permission';
export * from './role';
export * from './menu';
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity('menu')
export class Menu {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
order: number;
@Column({ nullable: true })
parentId: number;
@Column()
menuType: string;
@Column({ nullable: true })
icon: string;
@Column()
component: string;
@Column()
path: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity('permission')
export class Permission {
@PrimaryGeneratedColumn()
id: number;
@Column()
desc: string;
@Column()
name: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
Column,
Entity,
JoinTable,
ManyToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
import { Permission } from './permission';
import { Menu } from './menu';

@Entity('role')
export class Role {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Permission, {
onUpdate: 'CASCADE',
})
@JoinTable({ name: 'role_permission' })
permission: Permission[];

@ManyToMany(() => Menu)
@JoinTable({ name: 'role_menu' })
menus: Menu[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {
BeforeInsert,
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
JoinTable,
ManyToMany,
PrimaryColumn,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { Role } from './role';
import * as crypto from 'crypto';

export const encry = (value: string, salt: string) =>
crypto.pbkdf2Sync(value, salt, 1000, 18, 'sha256').toString('hex');

@Entity('user')
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
@Column()
password: string;
@ManyToMany(() => Role)
@JoinTable({ name: 'user_role' })
role: Role[];
@CreateDateColumn()
createTime: Date;
@UpdateDateColumn()
updateTime: Date;
@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
create_time: Date;
@Column({ nullable: true })
salt: string;
@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
update_time: Date;
@DeleteDateColumn()
deleteAt: Date;
@BeforeInsert()
beforeInsert() {
this.salt = crypto.randomBytes(4).toString('base64');
this.password = encry(this.password, this.salt);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": true,
"outDir": "../../dist/libs/models"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}
29 changes: 29 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/nest-cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"webpack": true
},
"projects": {
"db": {
"type": "library",
"root": "libs/db",
"entryFile": "index",
"sourceRoot": "libs/db/src",
"compilerOptions": {
"tsConfigPath": "libs/db/tsconfig.lib.json"
}
},
"models": {
"type": "library",
"root": "libs/models",
"entryFile": "index",
"sourceRoot": "libs/models/src",
"compilerOptions": {
"tsConfigPath": "libs/models/tsconfig.lib.json"
}
}
}
}
10 changes: 10 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,24 @@
},
"dependencies": {
"@nestjs/common": "10.0.3",
"@nestjs/config": "^3.2.3",
"@nestjs/core": "10.0.3",
"@nestjs/jwt": "^10.2.0",
"@nestjs/mapped-types": "*",
"@nestjs/platform-express": "10.0.3",
"@nestjs/sequelize": "10.0.0",
"@nestjs/typeorm": "^10.0.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.5",
"mysql2": "3.4.3",
"pg": "^8.12.0",
"reflect-metadata": "0.1.13",
"rimraf": "5.0.1",
"rxjs": "7.8.1",
"sequelize": "6.32.1",
"sequelize-typescript": "2.1.5",
"typeorm": "^0.3.20",
"typescript": "5.1.6"
},
"devDependencies": {
Expand All @@ -46,6 +55,7 @@
"eslint-plugin-import": "2.27.5",
"jest": "29.6.1",
"prettier": "2.8.8",
"source-map-support": "^0.5.20",
"supertest": "6.3.3",
"ts-jest": "29.1.1",
"ts-loader": "9.4.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
let appController: AppController;

beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();

appController = app.get<AppController>(AppController);
});

describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});
12 changes: 12 additions & 0 deletions packages/toolkits/pro/template/server/nestJs/src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}

@Get()
getHello(): string {
return this.appService.getHello();
}
}
Loading