nest.js + vue實現(xiàn)用戶組織權(quán)限系統(tǒng)

用戶組織權(quán)限管理系統(tǒng)

技術(shù)棧:

  • 前端:Vue + ElementUi + TypeScript
  • 后端:nest.js + mysql + redis

演示地址

用戶組織管理系統(tǒng)(演示地址)
github

功能設(shè)計

BSp-blog.png

數(shù)據(jù)庫設(shè)計

用戶實體

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column({nullable: true, type: 'text'})
  desc: string;

  @Column({
    nullable: true,
    length: 100,
    select: false,
  })
  password: string;

  @Column( {select: false} )
  email: string;

  @Column({nullable: true})
  age: string;

  @Column({nullable: true})
  address: string;

  @Column({nullable: true})
  nick: string;

  @Column({default: 0})
  status: number;

  @ManyToOne(type => Role, role => role.users)
  role: Role;

  @ManyToMany( type => Organization, orientation => orientation.users)
  organizations: Organization[];

  @Column({default: 0})
  isDelete: number;

  @Column({default: '', nullable: true })
  crateTime: string;

  @Column({default: '', nullable: true })
  updateTime: string;

  @Column({default: '', nullable: true })
  deleteTime: string;
}

角色實體

@Entity()
export class Role {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text', {nullable: true})
  desc: string;

  @Column()
  code: string;

  @ManyToMany(type => Authority, authority => authority.roles)
  @JoinTable()
  authority: Authority[];

  @OneToMany(type => User, user => user.role)
  users: User[];

  @Column({default: 0})
  isDelete: number;

  @Column({default: '', nullable: true })
  crateTime: string;

  @Column({default: '', nullable: true })
  updateTime: string;

  @Column({default: '', nullable: true })
  deleteTime: string;
}

資源實體

@Entity()
export class Authority {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text', {nullable: true})
  desc: string;

  @Column()
  path: string;

  @Column()
  value: string;

  @Column()
  parentId: number;

  @Column({default: '', nullable: true })
  parentName: string;

  @Column({nullable: true})
  icon: string;

  @Column({nullable: false})
  system: string;

  @Column()
  code: string;

  @ManyToMany(type => Role, role => role.authority)
  roles: Role[];

  @Column({default: 0})
  isDelete: number;

  @Column({default: '', nullable: true })
  crateTime: string;

  @Column({default: '', nullable: true })
  updateTime: string;

  @Column({default: '', nullable: true })
  deleteTime: string;
}

API實現(xiàn)

數(shù)據(jù)庫配置(main.module.ts)

TypeOrmModule.forRoot(
        {
          type: 'mysql',
          host: mysqlConfig.host,
          port: 3306,
          username: mysqlConfig.userName,
          password: mysqlConfig.password,
          database: 'b_simple_user_center',
          entities: [join(__dirname, '**/**.entity{.ts,.js}')],
          synchronize: true,
        },
    ),

全局緩存

CacheModule.register({
          store: redisStore,
          host: redisCacheConfig.host,
          port: redisCacheConfig.port,
          ttl: redisCacheConfig.ttl, // seconds
          max: redisCacheConfig.max, // seconds
      }),

業(yè)務(wù)層實現(xiàn)

該系統(tǒng)中使用typeorm操作數(shù)據(jù)庫,常見的typeorm操作方式包Entity Manager 和Query Builder,結(jié)合系統(tǒng)多條件查詢場景,因此采用Query Builder方式,控制層和服務(wù)層為一一對應(yīng)關(guān)系,代碼內(nèi)參見src/controller、src/service

采坑點

nest多條件查詢

...
const queryConditionList = ['c.isDelete = :isDelete'];
            if (query.name) {
                queryConditionList.push('c.name LIKE :name');
            }
            const queryCondition = queryConditionList.join(' AND ');
            const res = await this.productBrandRepository
                .createQueryBuilder('c')
                .where(queryCondition, {
                    name: `%${query.name}%`,
                    isDelete: 0,
                })
                .orderBy('c.name', 'ASC')
                .skip((query.page - 1) * query.pageSize)
                .take(query.pageSize)
                .getManyAndCount();
...

typeorm實體間任意聯(lián)查

typeorm中聯(lián)查任意實體(在實體關(guān)系間沒有表關(guān)聯(lián))時,getManyAndCount無法查詢關(guān)聯(lián)字段,必須采用getRawAndEntities,typeorm文檔書寫有誤。

...
            const res = await this.productAttributeRepository
                .createQueryBuilder('c')
                .leftJoinAndSelect(ProductAttributeCategoryEntity, 'a', 'a.id = c.product_attribute_category_id')
                .where(queryCondition, {
                    name: `%${query.name}%`,
                    isDelete: 0,
                    productAttributeCategoryId: Number(query.cateAttrId),
                    type: Number(query.type),
                })
                .orderBy('c.name', 'ASC')
                .skip((query.page - 1) * query.pageSize)
                .take(query.pageSize)
                .getRawAndEntities();


...

JWT用戶認證拆分單獨服務(wù)

用戶系統(tǒng)中與身份認證拆分成單獨的服務(wù)(網(wǎng)關(guān)服務(wù))

原文地址:http://www.yongfeifeilove.xyz:3002/blog/nest/%E7%94%A8%E6%88%B7%E7%BB%84%E7%BB%87%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容