chore: remove sqlite
parent
9572d1a1c5
commit
692225cfff
|
@ -3,7 +3,7 @@
|
||||||
"collection": "@nestjs/schematics",
|
"collection": "@nestjs/schematics",
|
||||||
"sourceRoot": "src",
|
"sourceRoot": "src",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"assets": ["**/*.yml"],
|
"assets": ["**/*.yml", "**/*.json"],
|
||||||
"watchAssets": true,
|
"watchAssets": true,
|
||||||
"deleteOutDir": true
|
"deleteOutDir": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
"@nestjs/jwt": "^10.2.0",
|
"@nestjs/jwt": "^10.2.0",
|
||||||
"@nestjs/passport": "^10.0.3",
|
"@nestjs/passport": "^10.0.3",
|
||||||
"@nestjs/platform-express": "^10.3.10",
|
"@nestjs/platform-express": "^10.3.10",
|
||||||
"@nestjs/typeorm": "^10.0.2",
|
|
||||||
"@types/js-yaml": "^4.0.9",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
|
@ -31,9 +30,7 @@
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1"
|
||||||
"sqlite3": "^5.1.7",
|
|
||||||
"typeorm": "^0.3.20"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^10.4.0",
|
"@nestjs/cli": "^10.4.0",
|
||||||
|
|
|
@ -1,23 +1,16 @@
|
||||||
import configuration from '@/config/index';
|
import configuration from '@/config/index';
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
import Joi from 'joi';
|
import Joi from 'joi';
|
||||||
|
|
||||||
import { AuthModule } from './modules/auth/auth.module';
|
import { AuthModule } from './modules/auth/auth.module';
|
||||||
import { DatabaseModule } from './modules/database/database.module';
|
|
||||||
import { HealthModule } from './modules/health/health.module';
|
import { HealthModule } from './modules/health/health.module';
|
||||||
import { MenuModule } from './modules/menu/menu.module';
|
import { MenuModule } from './modules/menu/menu.module';
|
||||||
|
import { MockModule } from './modules/mock/mock.module';
|
||||||
import { UsersModule } from './modules/users/users.module';
|
import { UsersModule } from './modules/users/users.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forRoot({
|
|
||||||
autoLoadEntities: true,
|
|
||||||
database: 'data/db.sqlite',
|
|
||||||
synchronize: true,
|
|
||||||
type: 'sqlite',
|
|
||||||
}),
|
|
||||||
ConfigModule.forRoot({
|
ConfigModule.forRoot({
|
||||||
cache: true,
|
cache: true,
|
||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
|
@ -34,8 +27,8 @@ import { UsersModule } from './modules/users/users.module';
|
||||||
HealthModule,
|
HealthModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
UsersModule,
|
UsersModule,
|
||||||
DatabaseModule,
|
|
||||||
MenuModule,
|
MenuModule,
|
||||||
|
MockModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|
|
@ -1,33 +1,20 @@
|
||||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
|
||||||
|
|
||||||
@Entity()
|
|
||||||
class UserEntity {
|
class UserEntity {
|
||||||
@PrimaryGeneratedColumn()
|
|
||||||
id: number;
|
id: number;
|
||||||
/**
|
/**
|
||||||
* 密码
|
* 密码
|
||||||
*/
|
*/
|
||||||
@Column()
|
|
||||||
password: string;
|
password: string;
|
||||||
/**
|
/**
|
||||||
* 真实姓名
|
* 真实姓名
|
||||||
*/
|
*/
|
||||||
@Column()
|
|
||||||
realName: string;
|
realName: string;
|
||||||
/**
|
/**
|
||||||
* 角色
|
* 角色
|
||||||
*/
|
*/
|
||||||
@Column('text', {
|
|
||||||
transformer: {
|
|
||||||
from: (value: string) => JSON.parse(value),
|
|
||||||
to: (value: string[]) => JSON.stringify(value),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
roles: string[];
|
roles: string[];
|
||||||
/**
|
/**
|
||||||
* 用户名
|
* 用户名
|
||||||
*/
|
*/
|
||||||
@Column({ unique: true })
|
|
||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
import { UserEntity } from '@/models/entity/user.entity';
|
|
||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
|
|
||||||
import { UsersModule } from '../users/users.module';
|
|
||||||
import { DatabaseService } from './database.service';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports: [UsersModule, TypeOrmModule.forFeature([UserEntity])],
|
|
||||||
providers: [DatabaseService],
|
|
||||||
})
|
|
||||||
export class DatabaseModule {}
|
|
|
@ -1,19 +0,0 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
|
|
||||||
import { DatabaseService } from './database.service';
|
|
||||||
|
|
||||||
describe('databaseService', () => {
|
|
||||||
let service: DatabaseService;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [DatabaseService],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
service = module.get<DatabaseService>(DatabaseService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(service).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,40 +0,0 @@
|
||||||
import type { Repository } from 'typeorm';
|
|
||||||
|
|
||||||
import { UserEntity } from '@/models/entity/user.entity';
|
|
||||||
import { Injectable, type OnModuleInit } from '@nestjs/common';
|
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
|
||||||
|
|
||||||
import { UsersService } from '../users/users.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class DatabaseService implements OnModuleInit {
|
|
||||||
constructor(
|
|
||||||
@InjectRepository(UserEntity)
|
|
||||||
private usersRepository: Repository<UserEntity>,
|
|
||||||
private userService: UsersService,
|
|
||||||
) {}
|
|
||||||
async onModuleInit() {
|
|
||||||
// data/db.sqlite会被git忽略,方式数据库文件被提交到git
|
|
||||||
// 清空表,并初始化两条数据
|
|
||||||
await this.usersRepository.clear();
|
|
||||||
|
|
||||||
await this.userService.create({
|
|
||||||
id: 0,
|
|
||||||
password: '123456',
|
|
||||||
realName: 'Administrator',
|
|
||||||
roles: ['admin'],
|
|
||||||
username: 'vben',
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.userService.create({
|
|
||||||
id: 1,
|
|
||||||
password: '123456',
|
|
||||||
realName: 'Jack',
|
|
||||||
roles: ['user'],
|
|
||||||
username: 'jack',
|
|
||||||
});
|
|
||||||
|
|
||||||
const count = await this.usersRepository.count();
|
|
||||||
console.log('Database has been initialized with seed data, count:', count);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -0,0 +1,13 @@
|
||||||
|
interface User {
|
||||||
|
id: number;
|
||||||
|
password: string;
|
||||||
|
realName: string;
|
||||||
|
roles: string[];
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MockDatabaseData {
|
||||||
|
users: User[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { MockDatabaseData, User };
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { MockService } from './mock.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
exports: [MockService],
|
||||||
|
providers: [MockService],
|
||||||
|
})
|
||||||
|
export class MockModule {}
|
|
@ -0,0 +1,71 @@
|
||||||
|
import type { MockDatabaseData } from './mock.interface';
|
||||||
|
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import { Injectable, type OnModuleInit } from '@nestjs/common';
|
||||||
|
import bcrypt from 'bcryptjs';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class MockService implements OnModuleInit {
|
||||||
|
private data: MockDatabaseData;
|
||||||
|
private readonly filePath: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.filePath = path.join(__dirname, '.', 'mock-db.json');
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadData() {
|
||||||
|
const fileData = fs.readFileSync(this.filePath, 'utf8');
|
||||||
|
this.data = JSON.parse(fileData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private saveData() {
|
||||||
|
fs.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(collection: string, item: any) {
|
||||||
|
this.data[collection].push(item);
|
||||||
|
this.saveData();
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCollection(collection: string) {
|
||||||
|
this.data[collection] = [];
|
||||||
|
this.saveData();
|
||||||
|
return this.data[collection];
|
||||||
|
}
|
||||||
|
|
||||||
|
findAll(collection: string) {
|
||||||
|
return this.data[collection];
|
||||||
|
}
|
||||||
|
|
||||||
|
findOneById(collection: string, id: number) {
|
||||||
|
return this.data[collection].find((item) => item.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onModuleInit() {
|
||||||
|
// 清空表,并初始化两条数据
|
||||||
|
await this.clearCollection('users');
|
||||||
|
|
||||||
|
// 密码哈希
|
||||||
|
const hashPassword = await bcrypt.hash('123456', 10);
|
||||||
|
await this.addItem('users', {
|
||||||
|
id: 0,
|
||||||
|
password: hashPassword,
|
||||||
|
realName: 'Vben',
|
||||||
|
roles: ['admin'],
|
||||||
|
username: 'vben',
|
||||||
|
});
|
||||||
|
await this.addItem('users', {
|
||||||
|
id: 1,
|
||||||
|
password: hashPassword,
|
||||||
|
realName: 'Jack',
|
||||||
|
roles: ['user'],
|
||||||
|
username: 'jack',
|
||||||
|
});
|
||||||
|
const count = await this.findAll('users').length;
|
||||||
|
console.log('Database has been initialized with seed data, count:', count);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,11 @@
|
||||||
import { UserEntity } from '@/models/entity/user.entity';
|
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
|
|
||||||
|
import { MockModule } from '../mock/mock.module';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
exports: [UsersService],
|
exports: [UsersService],
|
||||||
imports: [TypeOrmModule.forFeature([UserEntity])],
|
imports: [MockModule],
|
||||||
providers: [UsersService],
|
providers: [UsersService],
|
||||||
})
|
})
|
||||||
export class UsersModule {}
|
export class UsersModule {}
|
||||||
|
|
|
@ -1,28 +1,18 @@
|
||||||
import type { CreateUserDto } from '@/models/dto/user.dto';
|
|
||||||
import type { Repository } from 'typeorm';
|
|
||||||
|
|
||||||
import { UserEntity } from '@/models/entity/user.entity';
|
import { UserEntity } from '@/models/entity/user.entity';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
|
||||||
import bcrypt from 'bcryptjs';
|
import { MockService } from '../mock/mock.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
constructor(
|
constructor(private mockService: MockService) {}
|
||||||
@InjectRepository(UserEntity)
|
|
||||||
private usersRepository: Repository<UserEntity>,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async create(user: CreateUserDto): Promise<UserEntity> {
|
|
||||||
user.password = await bcrypt.hash(user.password, 10); // 密码哈希
|
|
||||||
return this.usersRepository.save(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find user by username
|
* Find user by username
|
||||||
* @param username
|
* @param username
|
||||||
*/
|
*/
|
||||||
async findOne(username: string): Promise<UserEntity | undefined> {
|
async findOne(username: string): Promise<UserEntity | undefined> {
|
||||||
return await this.usersRepository.findOne({ where: { username } });
|
const allUsers = await this.mockService.findAll('users');
|
||||||
|
return allUsers.find((user) => user.username === username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,50 +38,3 @@ const tokenTheme = computed(() => {
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</GlobalProvider>
|
</GlobalProvider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- <style>
|
|
||||||
:root {
|
|
||||||
--background: 0 0% 100%;
|
|
||||||
--foreground: 240 10% 3.9%;
|
|
||||||
--card: 0 0% 100%;
|
|
||||||
--card-foreground: 240 10% 3.9%;
|
|
||||||
--popover: 0 0% 100%;
|
|
||||||
--popover-foreground: 240 10% 3.9%;
|
|
||||||
--primary: 240 5.9% 10%;
|
|
||||||
--primary-foreground: 0 0% 98%;
|
|
||||||
--secondary: 240 4.8% 95.9%;
|
|
||||||
--secondary-foreground: 240 5.9% 10%;
|
|
||||||
--muted: 240 4.8% 95.9%;
|
|
||||||
--muted-foreground: 240 3.8% 46.1%;
|
|
||||||
--accent: 240 4.8% 95.9%;
|
|
||||||
--accent-foreground: 240 5.9% 10%;
|
|
||||||
--destructive: 0 84.2% 60.2%;
|
|
||||||
--destructive-foreground: 0 0% 98%;
|
|
||||||
--border: 240 5.9% 90%;
|
|
||||||
--input: 240 5.9% 90%;
|
|
||||||
--ring: 240 5.9% 10%;
|
|
||||||
--radius: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
--background: 240 10% 3.9%;
|
|
||||||
--foreground: 0 0% 98%;
|
|
||||||
--card: 240 10% 3.9%;
|
|
||||||
--card-foreground: 0 0% 98%;
|
|
||||||
--popover: 240 10% 3.9%;
|
|
||||||
--popover-foreground: 0 0% 98%;
|
|
||||||
--primary: 0 0% 98%;
|
|
||||||
--primary-foreground: 240 5.9% 10%;
|
|
||||||
--secondary: 240 3.7% 15.9%;
|
|
||||||
--secondary-foreground: 0 0% 98%;
|
|
||||||
--muted: 240 3.7% 15.9%;
|
|
||||||
--muted-foreground: 240 5% 64.9%;
|
|
||||||
--accent: 240 3.7% 15.9%;
|
|
||||||
--accent-foreground: 0 0% 98%;
|
|
||||||
--destructive: 0 62.8% 30.6%;
|
|
||||||
--destructive-foreground: 0 0% 98%;
|
|
||||||
--border: 240 3.7% 15.9%;
|
|
||||||
--input: 240 3.7% 15.9%;
|
|
||||||
--ring: 240 4.9% 83.9%;
|
|
||||||
}
|
|
||||||
</style> -->
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
"words": [
|
"words": [
|
||||||
"clsx",
|
"clsx",
|
||||||
"esno",
|
"esno",
|
||||||
"typeorm",
|
|
||||||
"unref",
|
"unref",
|
||||||
"taze",
|
"taze",
|
||||||
"acmr",
|
"acmr",
|
||||||
|
|
|
@ -12,6 +12,7 @@ const customConfig: Linter.FlatConfig[] = [
|
||||||
rules: {
|
rules: {
|
||||||
'@typescript-eslint/no-extraneous-class': 'off',
|
'@typescript-eslint/no-extraneous-class': 'off',
|
||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
|
'unicorn/prefer-module': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -115,6 +115,7 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
renderEcharts,
|
renderEcharts,
|
||||||
|
resize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
531
pnpm-lock.yaml
531
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue