feat: util 在node环境下代码提示的问题
This commit is contained in:
parent
328fc9801d
commit
4de96d32dc
|
@ -16,52 +16,62 @@
|
||||||
"new:mvc": "node ./script/new.mvc.js"
|
"new:mvc": "node ./script/new.mvc.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@backset/ui": "workspace:^1.0.0",
|
||||||
"@backset/util": "workspace:^1.0.0",
|
"@backset/util": "workspace:^1.0.0",
|
||||||
|
"@nestjs-modules/ioredis": "1.0.1",
|
||||||
"@nestjs/common": "^9.0.0",
|
"@nestjs/common": "^9.0.0",
|
||||||
"@nestjs/core": "^9.0.0",
|
|
||||||
"@nestjs/config": "2.3.1",
|
"@nestjs/config": "2.3.1",
|
||||||
"@nestjs/platform-express": "^9.0.0",
|
"@nestjs/core": "^9.0.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
|
||||||
"rxjs": "^7.2.0",
|
|
||||||
"@nestjs/mongoose": "7.2.4",
|
"@nestjs/mongoose": "7.2.4",
|
||||||
|
"@nestjs/platform-express": "^9.0.0",
|
||||||
|
"axios": "0.27.2",
|
||||||
|
"cookie": "0.5.0",
|
||||||
|
"ioredis": "5.3.1",
|
||||||
|
"jsonwebtoken": "9.0.0",
|
||||||
"mongoose": "5.13.15",
|
"mongoose": "5.13.15",
|
||||||
"mysql2": "3.0.1",
|
"mysql2": "3.0.1",
|
||||||
"typeorm": "0.3.11",
|
"reflect-metadata": "^0.1.13",
|
||||||
"axios": "0.27.2"
|
"rxjs": "^7.2.0",
|
||||||
|
"typeorm": "0.3.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/core": "7.20.12",
|
||||||
|
"@babel/preset-env": "7.20.2",
|
||||||
"@nestjs/cli": "^9.0.0",
|
"@nestjs/cli": "^9.0.0",
|
||||||
"@nestjs/schematics": "^9.0.0",
|
"@nestjs/schematics": "^9.0.0",
|
||||||
"@nestjs/typeorm": "9.0.1",
|
"@nestjs/typeorm": "9.0.1",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
|
"@types/mongoose": "^5.11.97",
|
||||||
"@types/node": "18.11.18",
|
"@types/node": "18.11.18",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
|
"babel-loader": "8.1.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"cash-dom": "8.1.3",
|
||||||
|
"chalk": "4.1.2",
|
||||||
|
"copy-webpack-plugin": "5.1.2",
|
||||||
|
"cross-env": "7.0.3",
|
||||||
|
"crypto-browserify": "^3.12.0",
|
||||||
|
"stream-browserify": "3.0.0",
|
||||||
|
"css-loader": "6.7.3",
|
||||||
|
"ejs": "3.1.8",
|
||||||
"eslint": "^8.0.1",
|
"eslint": "^8.0.1",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"inquirer": "8.0.0",
|
||||||
|
"less": "3.8.0",
|
||||||
|
"less-loader": "4.1.0",
|
||||||
|
"mini-css-extract-plugin": "2.7.2",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
|
"process": "^0.11.10",
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.20",
|
||||||
|
"ts-loader": "9.4.2",
|
||||||
"ts-node": "^10.0.0",
|
"ts-node": "^10.0.0",
|
||||||
"tsconfig-paths": "4.1.1",
|
"tsconfig-paths": "4.1.1",
|
||||||
"typescript": "^4.7.4",
|
"typescript": "^4.7.4",
|
||||||
|
"url-loader": "4.1.1",
|
||||||
"webpack": "^5.75.0",
|
"webpack": "^5.75.0",
|
||||||
"webpack-cli": "^5.0.1",
|
"webpack-cli": "^5.0.1",
|
||||||
"ts-loader": "9.4.2",
|
"assert": "2.0.0"
|
||||||
"css-loader": "6.7.3",
|
|
||||||
"url-loader": "4.1.1",
|
|
||||||
"@babel/core": "7.20.12",
|
|
||||||
"@babel/preset-env": "7.20.2",
|
|
||||||
"babel-loader": "8.1.0",
|
|
||||||
"less": "3.8.0",
|
|
||||||
"less-loader": "4.1.0",
|
|
||||||
"cross-env": "7.0.3",
|
|
||||||
"ejs": "3.1.8",
|
|
||||||
"mini-css-extract-plugin": "2.7.2",
|
|
||||||
"@types/mongoose": "^5.11.97",
|
|
||||||
"inquirer": "8.0.0",
|
|
||||||
"chalk": "4.1.2",
|
|
||||||
"copy-webpack-plugin": "5.1.2",
|
|
||||||
"cash-dom": "8.1.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,9 @@ import { mongo, mysql } from './config/db';
|
||||||
import { MongooseModule } from '@nestjs/mongoose';
|
import { MongooseModule } from '@nestjs/mongoose';
|
||||||
import { BaseModule } from './module/base.module';
|
import { BaseModule } from './module/base.module';
|
||||||
import { SmsModule } from './module/sms.module';
|
import { SmsModule } from './module/sms.module';
|
||||||
|
import { AuthModule } from './module/auth.module';
|
||||||
|
import { RedisCacheModule } from './module/redis.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({
|
ConfigModule.forRoot({
|
||||||
|
@ -14,9 +17,11 @@ import { SmsModule } from './module/sms.module';
|
||||||
}),
|
}),
|
||||||
TypeOrmModule.forRoot(mysql),
|
TypeOrmModule.forRoot(mysql),
|
||||||
MongooseModule.forRoot(mongo),
|
MongooseModule.forRoot(mongo),
|
||||||
|
RedisCacheModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
BaseModule,
|
BaseModule,
|
||||||
SmsModule,
|
SmsModule,
|
||||||
|
AuthModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|
18
apps/server/src/config/constant.ts
Normal file
18
apps/server/src/config/constant.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* token 在 cookie 的 key
|
||||||
|
*/
|
||||||
|
export const SECURE_SIGN = 'secure_sign';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt token配置
|
||||||
|
*/
|
||||||
|
export const TOKEN = {
|
||||||
|
/**
|
||||||
|
* Cookie被删除时的时间戳, 60 * 60 * 1000 * 24 一天过期
|
||||||
|
*/
|
||||||
|
EXPIRES: new Date(Date.now() + 60 * 1000 * 60 * 24),
|
||||||
|
/**
|
||||||
|
* token续签的时间戳阈值
|
||||||
|
*/
|
||||||
|
RESIGN_LIMIT: 60 * 60 * 1000 * 1,
|
||||||
|
};
|
|
@ -19,3 +19,9 @@ export const mysql: TypeOrmModuleOptions = {
|
||||||
* mongodb 链接 配置文件
|
* mongodb 链接 配置文件
|
||||||
*/
|
*/
|
||||||
export const mongo = 'mongodb://backset:cr654654.@mozzie.cn:37017/backset';
|
export const mongo = 'mongodb://backset:cr654654.@mozzie.cn:37017/backset';
|
||||||
|
|
||||||
|
export const redis = {
|
||||||
|
config: {
|
||||||
|
url: 'redis://mozzie.cn:16379',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
43
apps/server/src/controller/auth.controller.ts
Normal file
43
apps/server/src/controller/auth.controller.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { Body, Controller, Post, Response } from '@nestjs/common';
|
||||||
|
import { IUserLoginRequest } from 'src/dto/user.dto';
|
||||||
|
import { IUser } from 'src/entity/user.entity';
|
||||||
|
import { AuthService } from 'src/service/auth.service';
|
||||||
|
import { SECURE_SIGN, TOKEN } from 'src/config/constant';
|
||||||
|
import { RedisService } from 'src/service/redis.service';
|
||||||
|
import { EncryptUtil } from '@backset/util';
|
||||||
|
|
||||||
|
@Controller('auth')
|
||||||
|
export class AuthController {
|
||||||
|
constructor(
|
||||||
|
private readonly authService: AuthService,
|
||||||
|
private readonly redisService: RedisService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前台用户登录
|
||||||
|
*/
|
||||||
|
@Post('/user/login')
|
||||||
|
async userLogin(@Body() param: IUserLoginRequest, @Response() res) {
|
||||||
|
try {
|
||||||
|
const user: IUser = await this.authService.userLogin(param);
|
||||||
|
const { user_pass, ...rest } = user;
|
||||||
|
const token = EncryptUtil.createToken(rest);
|
||||||
|
const key = this.authService.getRedisKey(user);
|
||||||
|
this.redisService.set(key, token);
|
||||||
|
res.cookie(SECURE_SIGN, token, {
|
||||||
|
expires: TOKEN.EXPIRES,
|
||||||
|
sameSite: 'strict',
|
||||||
|
httpOnly: true,
|
||||||
|
});
|
||||||
|
if (user) return res.send(rest);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理系统登录
|
||||||
|
*/
|
||||||
|
@Post('/admin/login')
|
||||||
|
async adminLogin() {}
|
||||||
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
import { Body, Controller, Get, Post, Render } from '@nestjs/common';
|
import { Body, Controller, Get, Post, Render, Response } from '@nestjs/common';
|
||||||
import { BizStatus } from 'src/config/biz.code';
|
import { BizStatus } from 'src/config/biz.code';
|
||||||
import { IUserRequest } from 'src/dto/user.dto';
|
import { SECURE_SIGN } from 'src/config/constant';
|
||||||
|
import { IUserLoginRequest, IUserRequest } from 'src/dto/user.dto';
|
||||||
|
import { IUser } from 'src/entity/user.entity';
|
||||||
import { UserService } from 'src/service/user.service';
|
import { UserService } from 'src/service/user.service';
|
||||||
|
import jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
@Controller('/user')
|
@Controller('/user')
|
||||||
export class UserController {
|
export class UserController {
|
||||||
|
|
10
apps/server/src/entity/user.entity.ts
Normal file
10
apps/server/src/entity/user.entity.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
export interface IUser {
|
||||||
|
id?: number;
|
||||||
|
user_login?: string;
|
||||||
|
user_pass?: string;
|
||||||
|
user_phone?: string;
|
||||||
|
user_email?: string;
|
||||||
|
user_create_time?: number;
|
||||||
|
user_status?: number;
|
||||||
|
display_name?: string;
|
||||||
|
}
|
48
apps/server/src/interceptor/auth.interceptor.ts
Normal file
48
apps/server/src/interceptor/auth.interceptor.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import {
|
||||||
|
CallHandler,
|
||||||
|
ExecutionContext,
|
||||||
|
Inject,
|
||||||
|
Injectable,
|
||||||
|
NestInterceptor,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { Request, Response } from 'express';
|
||||||
|
import { Observable, tap } from 'rxjs';
|
||||||
|
import cookie = require('cookie');
|
||||||
|
import { SECURE_SIGN } from 'src/config/constant';
|
||||||
|
import { AuthService } from 'src/service/auth.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthInterceptor implements NestInterceptor {
|
||||||
|
|
||||||
|
intercept(
|
||||||
|
context: ExecutionContext,
|
||||||
|
next: CallHandler<any>,
|
||||||
|
): Observable<any> | Promise<Observable<any>> {
|
||||||
|
return next.handle().pipe(
|
||||||
|
tap(() => {
|
||||||
|
const host = context.switchToHttp();
|
||||||
|
const request = host.getRequest<Request>();
|
||||||
|
// 获取请求头
|
||||||
|
const cookies = cookie.parse(request.headers.cookie || '');
|
||||||
|
|
||||||
|
//TODO 缺少 token,如果访问的是接口需要鉴权重定向等登录
|
||||||
|
if (cookies[SECURE_SIGN]) return;
|
||||||
|
|
||||||
|
//TODO 如果有 token, decodeSign,判断 token 是否合法,
|
||||||
|
// const payload =authService
|
||||||
|
// 响应头续签
|
||||||
|
const response = host.getResponse<Response>();
|
||||||
|
console.log(request.headers.cookie);
|
||||||
|
// const token = 'token';
|
||||||
|
|
||||||
|
// response.cookie(SECURE_SIGN, token, {
|
||||||
|
// httpOnly: true,
|
||||||
|
// sameSite: 'strict',
|
||||||
|
// // secure: process.env.NODE_ENV === 'prod', // https 传输
|
||||||
|
// });
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
22
apps/server/src/interceptor/errors.interceptor.ts
Normal file
22
apps/server/src/interceptor/errors.interceptor.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import {
|
||||||
|
Injectable,
|
||||||
|
NestInterceptor,
|
||||||
|
ExecutionContext,
|
||||||
|
BadGatewayException,
|
||||||
|
CallHandler,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { Observable, throwError } from 'rxjs';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ErrorsInterceptor implements NestInterceptor {
|
||||||
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||||
|
return next
|
||||||
|
.handle()
|
||||||
|
.pipe(
|
||||||
|
catchError((err) =>
|
||||||
|
throwError(() => new BadGatewayException('错误:' + err)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
33
apps/server/src/interceptor/logging.interceptor.ts
Normal file
33
apps/server/src/interceptor/logging.interceptor.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import {
|
||||||
|
Injectable,
|
||||||
|
NestInterceptor,
|
||||||
|
ExecutionContext,
|
||||||
|
CallHandler,
|
||||||
|
Logger,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { Request } from 'express';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { tap } from 'rxjs/operators';
|
||||||
|
// import dayjs = require('dayjs');
|
||||||
|
// dayjs().format('{YYYY} MM-DDTHH:mm:ss')
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LoggingInterceptor implements NestInterceptor {
|
||||||
|
private readonly logger = new Logger('request'); // 实例化日志记录器
|
||||||
|
|
||||||
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||||
|
const start = Date.now(); // 请求开始时间
|
||||||
|
|
||||||
|
return next.handle().pipe(
|
||||||
|
tap(() => {
|
||||||
|
// 调用完handle()后得到RxJs响应对象,使用tap可以得到路由函数的返回值
|
||||||
|
const host = context.switchToHttp();
|
||||||
|
const request = host.getRequest<Request>();
|
||||||
|
// 打印请求方法,请求链接,处理时间和响应数据
|
||||||
|
this.logger.log(
|
||||||
|
`${request.method} ${request.url} ${Date.now() - start} ms`,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
24
apps/server/src/interceptor/timeout.interceptor.ts
Normal file
24
apps/server/src/interceptor/timeout.interceptor.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import {
|
||||||
|
Injectable,
|
||||||
|
NestInterceptor,
|
||||||
|
ExecutionContext,
|
||||||
|
CallHandler,
|
||||||
|
RequestTimeoutException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { Observable, throwError, TimeoutError } from 'rxjs';
|
||||||
|
import { catchError, timeout } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TimeoutInterceptor implements NestInterceptor {
|
||||||
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||||
|
return next.handle().pipe(
|
||||||
|
timeout(5000),
|
||||||
|
catchError((err) => {
|
||||||
|
if (err instanceof TimeoutError) {
|
||||||
|
return throwError(() => new RequestTimeoutException());
|
||||||
|
}
|
||||||
|
return throwError(() => err);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,12 @@ import { join } from 'path';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
import { PREFIX } from './config/router';
|
import { PREFIX } from './config/router';
|
||||||
import { injectTemplateVars } from './config/template.var';
|
import { injectTemplateVars } from './config/template.var';
|
||||||
|
import { HttpExceptionFilter } from './filter/httpException.filter';
|
||||||
|
import { AuthInterceptor } from './interceptor/auth.interceptor';
|
||||||
|
import { ErrorsInterceptor } from './interceptor/errors.interceptor';
|
||||||
|
import { LoggingInterceptor } from './interceptor/logging.interceptor';
|
||||||
|
import { TimeoutInterceptor } from './interceptor/timeout.interceptor';
|
||||||
|
|
||||||
const { PORT = 4000 } = process.env;
|
const { PORT = 4000 } = process.env;
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
|
@ -15,7 +21,14 @@ async function bootstrap() {
|
||||||
.useStaticAssets(join(process.cwd(), 'public'), { prefix: '/' })
|
.useStaticAssets(join(process.cwd(), 'public'), { prefix: '/' })
|
||||||
.setViewEngine('ejs')
|
.setViewEngine('ejs')
|
||||||
.setBaseViewsDir(join(process.cwd(), 'src/view'))
|
.setBaseViewsDir(join(process.cwd(), 'src/view'))
|
||||||
.setGlobalPrefix(PREFIX);
|
.setGlobalPrefix(PREFIX)
|
||||||
|
.useGlobalInterceptors(
|
||||||
|
new LoggingInterceptor(),
|
||||||
|
new ErrorsInterceptor(),
|
||||||
|
new TimeoutInterceptor(),
|
||||||
|
new AuthInterceptor(),
|
||||||
|
)
|
||||||
|
.useGlobalFilters(new HttpExceptionFilter());
|
||||||
|
|
||||||
injectTemplateVars(app);
|
injectTemplateVars(app);
|
||||||
|
|
||||||
|
|
10
apps/server/src/module/auth.module.ts
Normal file
10
apps/server/src/module/auth.module.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { AuthController } from 'src/controller/auth.controller';
|
||||||
|
import { AuthService } from 'src/service/auth.service';
|
||||||
|
import { RedisService } from 'src/service/redis.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [AuthController],
|
||||||
|
providers: [AuthService, RedisService],
|
||||||
|
})
|
||||||
|
export class AuthModule {}
|
10
apps/server/src/module/redis.module.ts
Normal file
10
apps/server/src/module/redis.module.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { RedisService } from 'src/service/redis.service';
|
||||||
|
import { RedisModule } from '@nestjs-modules/ioredis';
|
||||||
|
import { redis } from 'src/config/db';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [RedisModule.forRoot(redis)],
|
||||||
|
providers: [RedisService],
|
||||||
|
})
|
||||||
|
export class RedisCacheModule {}
|
42
apps/server/src/service/auth.service.ts
Normal file
42
apps/server/src/service/auth.service.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import { EncryptUtil } from '@backset/util';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { InjectDataSource } from '@nestjs/typeorm';
|
||||||
|
import { IUserLoginRequest } from 'src/dto/user.dto';
|
||||||
|
import { IUser } from 'src/entity/user.entity';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
import { AuthServiceImpl } from './impl/auth.interface';
|
||||||
|
import jwt = require('jsonwebtoken');
|
||||||
|
import { TOKEN } from 'src/config/constant';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthService implements AuthServiceImpl {
|
||||||
|
constructor(@InjectDataSource() private db: DataSource) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成用户 token 存 redis 的 key
|
||||||
|
*/
|
||||||
|
getRedisKey(user: IUser): string {
|
||||||
|
return `${user.id}-${user.user_login}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async userLogin(p: IUserLoginRequest): Promise<IUser> {
|
||||||
|
try {
|
||||||
|
const select_sql = `SELECT
|
||||||
|
id,
|
||||||
|
user_login
|
||||||
|
user_phone,
|
||||||
|
display_name,
|
||||||
|
user_email,
|
||||||
|
user_create_time,
|
||||||
|
user_status
|
||||||
|
FROM user WHERE user_login = ? and user_pass = ?`;
|
||||||
|
const user = await this.db.query(select_sql, [
|
||||||
|
p.user_login,
|
||||||
|
EncryptUtil.md5(p.user_pass),
|
||||||
|
]);
|
||||||
|
return user.length > 0 ? user[0] : null;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
apps/server/src/service/impl/auth.interface.ts
Normal file
6
apps/server/src/service/impl/auth.interface.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { IUserLoginRequest } from 'src/dto/user.dto';
|
||||||
|
import { IUser } from 'src/entity/user.entity';
|
||||||
|
|
||||||
|
export interface AuthServiceImpl {
|
||||||
|
userLogin(p: IUserLoginRequest): Promise<IUser>;
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { IUserRequest } from 'src/dto/user.dto';
|
import { IUserLoginRequest, IUserRequest } from 'src/dto/user.dto';
|
||||||
|
import { IUser } from 'src/entity/user.entity';
|
||||||
|
|
||||||
export interface UserServiceImpl {
|
export interface UserServiceImpl {
|
||||||
createUser(p: IUserRequest): Promise<boolean>;
|
createUser(p: IUserRequest): Promise<boolean>;
|
||||||
|
|
19
apps/server/src/service/redis.service.ts
Normal file
19
apps/server/src/service/redis.service.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import Redis from 'ioredis';
|
||||||
|
import { InjectRedis } from '@nestjs-modules/ioredis';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RedisService {
|
||||||
|
constructor(@InjectRedis() private readonly redis: Redis) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<'OK'>} 返回 ‘OK’ 操作成功
|
||||||
|
*/
|
||||||
|
async set(key: string, value: string | number | Buffer): Promise<void> {
|
||||||
|
await this.redis.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(key: string): Promise<string> {
|
||||||
|
return await this.redis.get(key);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
import { EncryptUtil } from '@backset/util';
|
import { EncryptUtil } from '@backset/util';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectDataSource } from '@nestjs/typeorm';
|
import { InjectDataSource } from '@nestjs/typeorm';
|
||||||
import { IUserRequest } from 'src/dto/user.dto';
|
import { IUserLoginRequest, IUserRequest } from 'src/dto/user.dto';
|
||||||
|
import { IUser } from 'src/entity/user.entity';
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
import { UserServiceImpl } from './impl/user.interface';
|
import { UserServiceImpl } from './impl/user.interface';
|
||||||
|
|
||||||
|
@ -19,8 +20,4 @@ export class UserService implements UserServiceImpl {
|
||||||
]);
|
]);
|
||||||
return affectedRows === 1;
|
return affectedRows === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUser() {
|
|
||||||
return await this.db.query(`select * from user`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { axiosCommon as Request } from '../lib/request';
|
||||||
* 用户登录
|
* 用户登录
|
||||||
*/
|
*/
|
||||||
export const userLogin = (p: IUserLoginRequest) =>
|
export const userLogin = (p: IUserLoginRequest) =>
|
||||||
Request.post('/user/login', p);
|
Request.post('/auth/user/login', p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取验证码
|
* 获取验证码
|
||||||
|
|
|
@ -10,6 +10,16 @@
|
||||||
|
|
||||||
<span>当前assets: <%= assets %></span>
|
<span>当前assets: <%= assets %></span>
|
||||||
|
|
||||||
|
<editable-list
|
||||||
|
title="TODO"
|
||||||
|
list-item-0="First item on the list"
|
||||||
|
list-item-1="Second item on the list"
|
||||||
|
list-item-2="Third item on the list"
|
||||||
|
list-item-3="Fourth item on the list"
|
||||||
|
list-item-4="Fifth item on the list"
|
||||||
|
listItem="This will not appear"
|
||||||
|
add-item-text="Add new list item:"
|
||||||
|
></editable-list>
|
||||||
|
|
||||||
<%- include('../_layout/footer') -%>
|
<%- include('../_layout/footer') -%>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { createUser } from '../../api';
|
import { createUser } from '../../api';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
import $ from 'cash-dom';
|
import $ from 'cash-dom';
|
||||||
import { RegUtil, ValidateUtil } from '@backset/util';
|
const { RegUtil, ValidateUtil } = require('@backset/util')
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
$('#signup-module').on('click', '#btn-signup', handleCreateUser);
|
$('#signup-module').on('click', '#btn-signup', handleCreateUser);
|
||||||
|
|
|
@ -5,6 +5,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
const CopyPlugin = require("copy-webpack-plugin");
|
const CopyPlugin = require("copy-webpack-plugin");
|
||||||
const isDev = process.env.RUNNING_ENV === 'dev'
|
const isDev = process.env.RUNNING_ENV === 'dev'
|
||||||
const isProd = process.env.RUNNING_ENV === 'prod'
|
const isProd = process.env.RUNNING_ENV === 'prod'
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引入 src/view/pages下的页面文件,排除 _ 开头的文件夹
|
* 引入 src/view/pages下的页面文件,排除 _ 开头的文件夹
|
||||||
|
@ -66,11 +67,22 @@ module.exports = {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: [new MiniCssExtractPlugin({
|
plugins: [
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
filename: '[name].css',
|
filename: '[name].css',
|
||||||
chunkFilename: '[id].css?[hash:8]',
|
chunkFilename: '[id].css?[hash:8]',
|
||||||
}), new CopyPlugin([{ from: join(process.cwd(), 'src/view/assets'), to: "assets" }]),].filter(Boolean),
|
}),
|
||||||
|
new CopyPlugin([{ from: join(process.cwd(), 'src/view/assets'), to: "assets" }]),
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
process: 'process/browser',
|
||||||
|
Buffer: ['buffer', 'Buffer']
|
||||||
|
})].filter(Boolean),
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.ts', '.js', '.ejs'],
|
extensions: ['.ts', '.js', '.ejs'],
|
||||||
|
fallback: {
|
||||||
|
"crypto": require.resolve("crypto-browserify"),
|
||||||
|
"stream": require.resolve("stream-browserify"),
|
||||||
|
"assert": require.resolve("assert"),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,5 +5,7 @@
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rimraf ./dist && tsc -p ./tsconfig.build.json"
|
"build": "rimraf ./dist && tsc -p ./tsconfig.build.json"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {},
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true
|
||||||
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*"
|
"src/**/*"
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
{
|
{
|
||||||
"name": "@backset/util",
|
"name": "@backset/util",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "dist/index",
|
"main": "dist/cjs/index",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/es/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rimraf ./dist && tsc -p ./tsconfig.build.json"
|
"build": "rimraf ./dist && tsc -p ./tsconfig.build-es.json && tsc -p ./tsconfig.build-cjs.json"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"dependencies": {
|
||||||
|
"jsonwebtoken": "5.7.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jsonwebtoken": "9.0.1"
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,15 @@
|
||||||
const hash = require("object-hash");
|
const hash = require("object-hash");
|
||||||
|
const jwt = require("jsonwebtoken");
|
||||||
|
|
||||||
export const md5 = (text: string) => hash(text, { algorithm: "md5" });
|
export const md5 = (text: string) => hash(text, { algorithm: "md5" });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密payload生成token
|
||||||
|
*/
|
||||||
|
export const createToken = (payload: any): string =>
|
||||||
|
jwt.sign({ ...payload }, "mozzie");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解 token payload
|
||||||
|
*/
|
||||||
|
export const decodeToken = (token: string): any => jwt.verify(token, "mozzie");
|
||||||
|
|
|
@ -2,6 +2,4 @@
|
||||||
* 检测对象是否存在空 value
|
* 检测对象是否存在空 value
|
||||||
* @param {Object} obj 检测的对象
|
* @param {Object} obj 检测的对象
|
||||||
*/
|
*/
|
||||||
export const withEmpty = (obj: Object) => {
|
export const withEmpty = (obj: Object) => Object.values(obj).some((v) => !v);
|
||||||
return Object.values(obj).some((v) => !v);
|
|
||||||
};
|
|
||||||
|
|
7
packages/util/tsconfig.build-cjs.json
Normal file
7
packages/util/tsconfig.build-cjs.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.build.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "CommonJS",
|
||||||
|
"outDir": "./dist/cjs"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"extends": "../../tsconfig.build.json",
|
"extends": "../../tsconfig.build.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./dist",
|
"outDir": "./dist/es",
|
||||||
}
|
}
|
||||||
}
|
}
|
748
pnpm-lock.yaml
748
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,11 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "ES2015",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
|
"module": "ES2020",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"skipLibCheck": true // 忽略烈性检查
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true, // 忽略烈性检查
|
||||||
|
"forceConsistentCasingInFileNames": true
|
||||||
},
|
},
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user