github库房地址
运用技能
midwayjs + typeorm + redis
现有功用
- 登录注册、验证码
- 用户办理
- 角色办理
- 权限办理
项目建立
这部分内容参考 midwayjs官网 即可
引进 typeorm
这部分引荐参考官网
装置依赖
npm i @midwayjs/typeorm@3 typeorm mysql2 --save
装备连接信息和实体模型
// src/config/config.default.ts
export default {
// ...
typeorm: {
dataSource: {
default: {
type: 'mysql',
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
database: 'db1',
synchronize: true, // 如果第一次运用,不存在表,有同步的需求能够写 true,注意会丢数据
logging: false,
// 装备实体模型-扫描实体
entities: ['**/entity/*.ts'],
dateStrings: true
}
}
}
}
entity 实体层/模型层
BaseEntity 提取公共表字段 如(id、createTime、updateTime)等
// src/entity/base.ts
import { Entity, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm'
@Entity('role')
export class BaseEntity {
@PrimaryGeneratedColumn()
id: number
@CreateDateColumn({ comment: '创立时刻', type: 'timestamp' })
createTime: Date
@UpdateDateColumn({ comment: '更新时刻', type: 'timestamp' })
updateTime: Date
}
创立User实体
// src/entity/user.ts
import { Entity, Column } from 'typeorm'
import { BaseEntity } from './base'
@Entity('user')
export class User extends BaseEntity {
@Column({ comment: '用户名' })
username: string
@Column({ comment: '密码(md5加密)' })
password: string
@Column({ comment: '真实名字', nullable: true })
realname: string
@Column({ comment: '昵称', nullable: true })
nickname: string
@Column({ comment: '角色Id(1,2,3)', nullable: true })
roleId: string
}
service 事务层
BaseService 提取公共办法
// src/service/base.ts
import { Provide } from '@midwayjs/core'
import { Repository } from 'typeorm'
import { BaseEntity } from '../entity/base'
@Provide()
export abstract class BaseService<T extends BaseEntity> {
public abstract entity: Repository<T>
add(query) {
return this.entity.save(query)
}
update(query) {
return this.entity.update(query.id, query)
}
delete(ids: number | string | string[]) {
return this.entity.delete(ids)
}
info(data) {
return this.entity.findOne({ where: data })
}
async page(data) {
const { page = 1, size = 10 } = data
const [list, total] = await this.entity.findAndCount({
where: {},
take: size,
skip: (page - 1) * size
})
return { list, pagination: { total, size, page } }
}
list(data?) {
return this.entity.find({ where: data } as any)
}
}
UserService
- 集成BaseService需求供给具体的entity,这样BaseService里边的公共办法才有用
- 如果用不着 BaseService 里的办法也能够不用继承
- 关于复杂的办法能够进行重写
// src/service/user.ts
import { Provide, Inject } from '@midwayjs/core'
import { InjectEntityModel, } from '@midwayjs/typeorm'
import { Repository } from 'typeorm'
import { BaseService } from './base'
import { User } from '../entity/user'
import * as md5 from 'md5'
import { CustomHttpError } from '../common/CustomHttpError'
@Provide()
export class UserService extends BaseService<User> {
@InjectEntityModel(User)
entity: Repository<User>
async add(data: User) {
const user = await this.entity.findOne({ where: { username: data.username } })
if (user) {
throw new CustomHttpError('用户已存在')
}
if (data.password) {
data.password = md5(data.password)
}
return await super.add(data)
}
async update(data: User) {
if (data.password) {
data.password = md5(data.password)
}
return await super.update(data)
}
}
Controller 操控层
BaseController 提取公共属性和办法
- 这儿只供给了回来成功和失利办法
// src/controller/base.ts
import { Inject } from '@midwayjs/core'
import { Context } from '@midwayjs/web'
import { Result, IResult } from '../utils'
export abstract class BaseController {
@Inject()
ctx: Context
success<T>(data?: T, option: IResult<T> = {}): IResult<T> {
return Result.success<T>({ data, ...option })
}
error(message?, option: IResult = {}) {
return Result.error({ message, ...option })
}
}
- 上面用到了 Result对象的办法(因为其它地方如反常处理和中间件中也或许会运用到回来成功或失利的功用,所有对其进行了抽离)
// src/utils/result.ts
export const DEFAULT_SUCCESS_CODE = 200
export const DEFAULT_ERROR_CODE = 900
export interface IResult<T = any> {
data?: T
code?: number
message?: string
}
export const Result = {
success<T>(option: IResult<T> = {}): IResult<T> {
const { data = null, code = DEFAULT_SUCCESS_CODE, message = 'success' } = option
return {
code,
data,
message
}
},
error(option: IResult = {}): IResult {
const { data = null, code = DEFAULT_ERROR_CODE, message = 'error' } = option
return {
code,
data,
message
}
}
}
UserController
// src/controller/user.ts
import { Body, Controller, Inject, Post } from '@midwayjs/core'
import { User } from '../entity/user'
import { UserService } from '../service/user'
import { BaseController } from './base'
@Controller('/user')
export class UserController extends BaseController {
@Inject()
service: UserService
@Post('/add')
async add(@Body() data: User) {
const res = await this.service.add(data)
return this.success(res)
}
@Post('/update')
async update(@Body() data: User) {
await this.service.update(data)
return this.success()
}
}
反常处理
在 UserService中运用到了自界说反常,在midwayjs中咱们能够轻松完成这一功用
// src/common/CustomHttpError.ts
import { MidwayHttpError, HttpStatus } from '@midwayjs/core'
export class CustomHttpError extends MidwayHttpError {
constructor(message) {
super(message || '服务器出错啦!!!', HttpStatus.BAD_REQUEST)
}
}
- 这样咱们就能够抛出自己界说的反常了,但问题是我想让接口调用者看到过错信息该怎么做呢?这便是咱们接下来要讲的反常捕获(midwayjs也供给了十分快捷的方法完成反常捕获,运用装饰器 Catch)
// src/filter/exception.ts
import { Catch } from '@midwayjs/core'
import { Context } from 'egg'
import { Result } from '../utils'
@Catch()
export class ExceptionFilter {
async catch(err, ctx: Context) {
ctx.logger.error(err)
return Result.error({
code: err.status ?? 500,
message: err.message
})
}
}
上面只是界说了咱们要捕获的反常,咱们还需求将它应用到咱们某个框架的 app 中,比方 http 协议的 app。
咱们能够在 src/configuration.ts 中将过错处理过滤器应用上,因为参数能够是数组,咱们能够应用多个过错处理器。
import { App, Configuration, ILifeCycle } from '@midwayjs/core'
import { Application } from 'egg'
import { join } from 'path'
import * as orm from '@midwayjs/typeorm'
import * as egg from '@midwayjs/web'
import { ExceptionFilter } from './filter/exception'
@Configuration({
imports: [egg, orm],
importConfigs: [join(__dirname, './config')],
})
export class ContainerLifeCycle implements ILifeCycle {
@App()
app: Application
async onReady() {
this.app.useFilter(ExceptionFilter) // +
}
}
在midwayjs官网有十分详细反常处理的运用
最后
因为项目还在开发中,目前就完成了这些功用,后面会不断完善,也会出一些相关文章。
done…
点个赞在走呗!!!(●’◡’●)