增加用户管理
continuous-integration/drone/push Build is passing Details

main
rustdreamer 2 years ago
parent 2ff8396a3b
commit ccceb68367

@ -1,14 +1,14 @@
import { BadRequestException, Body, Controller, Delete, Get, NotFoundException, Param, Post, Put, Query, Req, Res } from '@nestjs/common';
import { BadRequestException, Body, Controller, Delete, Get, NotFoundException, Param, Post, Put, Query, Req, Res, UseGuards, UsePipes } from '@nestjs/common';
import { AppService } from './app.service';
import * as fs from 'fs';
import { ApiBearerAuth, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { ApiBearerAuth, ApiOperation, ApiProperty, ApiPropertyOptional, ApiResponse } from '@nestjs/swagger';
import { IsArray, IsBoolean, IsDateString, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { NodeVisitorEntity } from './node-visitor.entity';
import { Between, DataSource, IsNull, LessThan, Not, Repository } from 'typeorm';
import * as bluebird from 'bluebird';
import { NodeOtherVisitorEntity } from './node-other-visitor.entity';
import * as moment from 'moment';
import { CommonPageArgs } from './common';
import { CommonPageArgs, Roles, RolesGuard, ValidationPipe } from './common';
import { InjectRepository } from '@nestjs/typeorm';
import axios from 'axios';
import { v4 as uuid } from 'uuid';
@ -16,6 +16,7 @@ import { verificationService } from './lib/face';
import { join } from 'path';
import { AreaEntity } from './area.entity';
import { DeviceEntity } from './device.entity';
import { AuthGuard } from '@nestjs/passport';
export class Electronics {
@ApiProperty({ description: "电子产品名称" })
@ -433,24 +434,17 @@ export class AppController {
}
@Get("/visitors")
@ApiOperation({ summary: '查看预约记录' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '查看预约记录')
@ApiBearerAuth()
// @ApiResponse({
// status: 200,
// description: '返回参数说明',
// type: UserEntity,
// })
async get(@Query() query_data: QueryVisitorDto, @Req() req: any) {
// console.log("req", req.headers)
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
const where: any = {};
if (query_data.applicant) {
where.applicant = query_data.applicant
@ -513,24 +507,12 @@ export class AppController {
}
@Get("/visitor-records")
@ApiOperation({ summary: '查看到访记录' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '查看到访记录')
@ApiBearerAuth()
async getRecord(@Query() query_data: QueryVisitorDto, @Req() req: any) {
// console.log("req", req.headers)
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
const where: any = {
start_time: Not(IsNull())
};
@ -653,22 +635,12 @@ export class AppController {
@Post("/area")
@ApiOperation({ summary: '创建厂区' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '创建厂区')
@ApiBearerAuth()
async createArea(@Body() data: CreateArea, @Req() req: any) {
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
return await this.dataSource.transaction(async transactionalEntityManager => {
const area = new AreaEntity();
@ -682,22 +654,12 @@ export class AppController {
}
@Put("/area/:id")
@ApiOperation({ summary: '更新厂区' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '更新厂区')
@ApiBearerAuth()
async updateArea(@Param() { id }: any, @Body() data: UpdateArea, @Req() req: any) {
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
const area = await this.areaRepository.findOne({ where: { id } });
if (!area) {
throw new NotFoundException("area not found");
@ -709,22 +671,12 @@ export class AppController {
}
@Delete("/area/:id")
@ApiOperation({ summary: '删除厂区' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '删除厂区')
@ApiBearerAuth()
async deleteArea(@Param() { id }: any, @Req() req: any) {
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
const result = await this.areaRepository.findOne({ where: { id } });
if (!result) {
throw new NotFoundException("area not found");
@ -736,22 +688,6 @@ export class AppController {
@Get("/areas")
@ApiBearerAuth()
async areas(@Query() query_data: AreaDto, @Req() req: any) {
// console.log("req", req.headers)
// if (!req.headers.authorization) {
// throw new BadRequestException("无权限")
// }
// try {
// // console.log(`${process.env.RUST_URI}/api/viewer`)
// const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
// headers: {
// authorization: req.headers.authorization
// }
// })
// // console.log("result", result)
// } catch (e) {
// // console.log(e)
// throw new BadRequestException("无权限, 请联系管理员")
// }
const where: any = {};
const query = this.areaRepository.createQueryBuilder('area');
query.where(where);
@ -774,22 +710,12 @@ export class AppController {
}
@Post("/device")
@ApiOperation({ summary: '创建设备' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '创建设备')
@ApiBearerAuth()
async createDevice(@Body() data: CreateDevice, @Req() req: any) {
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
return await this.dataSource.transaction(async transactionalEntityManager => {
const device = new DeviceEntity();
@ -805,22 +731,12 @@ export class AppController {
}
@Put("/device/:id")
@ApiOperation({ summary: '更新设备' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '更新设备')
@ApiBearerAuth()
async updateDevice(@Param() { id }: any, @Body() data: UpdateDevice, @Req() req: any) {
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
const device = await this.deviceRepository.findOne({ where: { id } });
if (!device) {
throw new NotFoundException("device not found");
@ -835,22 +751,12 @@ export class AppController {
}
@Delete("/device/:id")
@ApiOperation({ summary: '删除设备' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '删除设备')
@ApiBearerAuth()
async deleteDevice(@Param() { id }: any, @Req() req: any) {
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
const result = await this.deviceRepository.findOne({ where: { id } });
if (!result) {
throw new NotFoundException("device not found");
@ -860,24 +766,12 @@ export class AppController {
}
@Get("/devices")
@ApiOperation({ summary: '查看设备' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '查看设备')
@ApiBearerAuth()
async devices(@Query() query_data: AreaDto, @Req() req: any) {
// console.log("req", req.headers)
if (!req.headers.authorization) {
throw new BadRequestException("无权限")
}
try {
// console.log(`${process.env.RUST_URI}/api/viewer`)
const result = await axios.get(`${process.env.RUST_URI}/api/viewer`, {
headers: {
authorization: req.headers.authorization
}
})
// console.log("result", result)
} catch (e) {
// console.log(e)
throw new BadRequestException("无权限, 请联系管理员")
}
const where: any = {};
const query = this.deviceRepository.createQueryBuilder('device');
query.where(where);

@ -53,4 +53,16 @@ export class AuthController {
// status: false
// }
// }
@Post('login/admin')
@ApiOperation({ summary: '后台管理员登录' })
@UsePipes(new ValidationPipe())
@ApiResponse({
status: 200,
description: '返回参数说明',
type: ResponseType,
})
async loginByAdmin(@Body() loginData: Login): Promise<any> {
return this.authService.loginByAdmin(loginData.mobile, loginData.password);
}
}

@ -6,15 +6,15 @@ import { AuthService, expires_in } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserEntity } from '../user/user.entity';
import { RoleEntity } from 'src/role/entities/role.entity';
// import AuthResolver from './auth.resolver';
// import { RoleEntity } from '../role/role.entity';
// import { RoleItemEntity } from '../role-item/role-item.entity';
@Module({
imports: [
TypeOrmModule.forFeature([
UserEntity,
// RoleEntity,
RoleEntity,
// RoleItemEntity,
]),
PassportModule.register({ defaultStrategy: 'jwt' }),

@ -11,15 +11,15 @@ import {
} from 'class-validator';
export class Login {
@ApiProperty({ description: '从小程序端获取的code' })
@ApiProperty({ description: '' })
@IsString()
@IsNotEmpty()
public code: string;
public mobile: string;
@ApiProperty({ description: '小程序码' })
@ApiProperty({ description: '' })
@IsString()
@IsOptional()
public qunsense_code: string;
@IsNotEmpty()
public password: string;
}
export class SureLogin {

@ -13,8 +13,10 @@ import { JwtPayload, UserJwtPayload } from './interfaces/jwt-payload.interface';
import { UserEntity } from '../user/user.entity';
import { Login, PollingDto, LoginMobile, UpdateUserDto, IsLogin } from './auth.params';
import redis from 'src/redis';
import { RoleEntity } from 'src/role/entities/role.entity';
// import { RoleItemEntity } from '../role-item/role-item.entity';
// import { RoleEntity } from '../role/role.entity';
export const cache_in = 60 * 3;
export const expires_in = 3600 * 24 * 30;
@Injectable()
@ -25,8 +27,8 @@ export class AuthService {
private readonly userRepository: Repository<UserEntity>,
// @InjectRepository(RoleItemEntity)
// private readonly roleItemRepository: Repository<RoleItemEntity>,
// @InjectRepository(RoleEntity)
// private readonly roleRepository: Repository<RoleEntity>,
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
) { }
async verify(token: string) {
@ -76,6 +78,40 @@ export class AuthService {
throw new BadRequestException()
}
}
async loginByAdmin(mobile: string, password: string) {
const user = await this.userRepository.findOne({
where: { mobile },
select: ['id', 'password', 'role'],
});
if (!user) {
throw new BadRequestException('用户不存在');
}
const result = await bcrypt.compare(password, user.password);
if (!result) {
throw new BadRequestException('用户名或密码错误');
}
const access_token = await this.createUserToken(user);
Logger.log(`${user.id}: 管理员登录`);
// const user_role_permission = await this.getRoleAndPermission(user.id);
const user_permissions_key = `user_permissions:${user.id}`;
let user_permissions = [user.role]
const role = await this.roleRepository.findOne({ where: { name: user.role } })
if (role) {
user_permissions = [...user_permissions, ...role.permissions.split('、')]
}
redis.set(
user_permissions_key,
JSON.stringify(user_permissions),
// 'EX',
// cache_in,
);
return {
// ...user_role_permission,
...access_token,
user_id: user.id,
};
}
}

@ -0,0 +1,89 @@
import * as bcrypt from 'bcryptjs';
import * as bluebird from 'bluebird';
import { DataSource, getRepository } from 'typeorm';
import { Logger } from '@nestjs/common';
import { UserEntity } from '../user/user.entity';
import { BCRYPT_HASH_ROUNDS } from '../common';
import { RoleEntity } from 'src/role/entities/role.entity';
import { RolePermissionEntity } from 'src/role/entities/role-permission.entity';
import { mysql_migration_config } from 'src/config/config.mysql';
const admins = [
{
mobile: 'admin',
password: 'admin2022uu',
true_name: '超级管理员',
headimgurl: '',
},
];
// (async () => {
// const new_password = await bcrypt.hash('13813977385', BCRYPT_HASH_ROUNDS);
// console.log('---- new_password', new_password);
// })();
// export const a = () => {
// setTimeout(async () => {
// const new_password = await bcrypt.hash('13914730324', BCRYPT_HASH_ROUNDS);
// console.log('---- new_password', new_password);
// }, 1000)
// }
export async function createAdmin() {
const myDataSource = new DataSource(mysql_migration_config);
await myDataSource.initialize();
const roleRepository = myDataSource.getRepository(RoleEntity);
const userRepository = myDataSource.getRepository(UserEntity);
const rolePermissionRepository = myDataSource.getRepository(RolePermissionEntity);
await bluebird.each(
admins,
async ({ mobile, password, true_name, headimgurl }) => {
let role = await roleRepository.findOne({
where: { name: 'super_admin' },
});
if (!role) {
const new_role = new RoleEntity();
new_role.name = 'super_admin';
role = await roleRepository.save(new_role);
const permission = new RolePermissionEntity();
permission.role_id = role.id;
permission.name = 'super_admin';
await rolePermissionRepository.save(permission);
}
let user = await userRepository.findOne({ where: { mobile } });
if (!user) {
const new_password = await bcrypt.hash(password, BCRYPT_HASH_ROUNDS);
const new_user = Object.assign(new UserEntity(), {
mobile,
password: new_password,
true_name,
headimgurl,
role: 'super_admin',
role_id: role.id,
});
user = await userRepository.save(new_user);
}
},
);
}
export async function createRole() {
const myDataSource = new DataSource(mysql_migration_config);
await myDataSource.initialize();
const roleRepository = myDataSource.getRepository(RoleEntity);
const rolePermissionRepository = myDataSource.getRepository(RolePermissionEntity);
let role = await roleRepository.findOne({
where: { name: '厂区管理员' },
});
if (!role) {
const new_role = new RoleEntity();
new_role.name = '厂区管理员';
new_role.permissions =
"查看预约记录、查看到访记录";
role = await roleRepository.save(new_role);
}
}

@ -1,5 +1,6 @@
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import redis from 'src/redis';
@Injectable()
export class RolesGuard implements CanActivate {
@ -18,6 +19,20 @@ export class RolesGuard implements CanActivate {
// fix graphql 需要特殊处理
user = context.getArgs()[2].req.user;
}
const user_permissions_key = `user_permissions:${user.id}`;
const result = await redis.get(
user_permissions_key,
);
console.log("result", result)
if (!result) {
return false;
}
user.roles = JSON.parse(result);
const hasRole = () =>
user.roles.some(role => !!roles.find(item => item === role));
console.log(roles, user.roles)

@ -7,6 +7,7 @@ import { SwaggerModule } from '@nestjs/swagger';
import { LoggingInterceptor } from './common/interceptor/logging.interceptor';
import * as fs from 'fs';
import { urlencoded, json } from 'express';
import { createAdmin, createRole } from './boot';
/**
*
@ -57,7 +58,8 @@ async function bootstrap() {
// RequestId: 'ce06f1e7-163a-40ab-90c5-fc227b3ecbd2',
// Url: 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxa50a8ac379585f53&redirect_uri=https%3A%2F%2Feid.faceid.qq.com%2Fapi%2Fv1%2FGetOpenId%3Ftoken%3D095FA750-2234-4B1C-B395-22D2197657AB%26v%3Dv2&response_type=code&scope=snsapi_base&state=&component_appid=wx9802ee81e68d6dee#wechat_redirect'
// }
createAdmin();
createRole();
const port: number = 9998
await app.listen(port);
Logger.log(`the server listing on ${port}`)

@ -1 +1,14 @@
export class CreateRoleDto {}
import { ApiProperty } from "@nestjs/swagger";
import { IsNotEmpty, IsString } from "class-validator";
export class CreateRoleDto {
@ApiProperty({ description: '' })
@IsString()
@IsNotEmpty()
public name: string;
@ApiProperty({ description: '' })
@IsString()
@IsNotEmpty()
public permissions: string;
}

@ -0,0 +1,17 @@
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"
import { IsEnum, IsOptional, IsString } from "class-validator"
import { CommonPageArgs } from "src/common"
export class QueryRoleDto extends CommonPageArgs {
@ApiPropertyOptional({ description: '' })
@IsString()
@IsOptional()
name: string
@ApiPropertyOptional({ description: "根据名称模糊搜索", required: false })
@IsString()
@IsOptional()
search?: string
}

@ -0,0 +1,16 @@
import { Column, Entity, OneToOne, JoinColumn, ManyToOne } from 'typeorm';
import { RoleEntity } from './role.entity';
import { Base } from 'src/common';
@Entity({ name: 'role-permission' })
export class RolePermissionEntity extends Base {
@Column({ nullable: false })
public name: string;
@Column({ type: "bigint", width: 18, nullable: true })
public role_id: string;
// @ManyToOne(type => RoleEntity)
// @JoinColumn({ name: 'role_id' })
// role: RoleEntity;
}

@ -1 +1,11 @@
export class Role {}
import { Base } from 'src/common';
import { Column, Entity } from 'typeorm';
@Entity({ name: 'node-roles' })
export class RoleEntity extends Base {
@Column({ length: 50, nullable: false })
public name: string;
@Column({ type: 'text', nullable: true })
public permissions: string;
}

@ -1,13 +1,26 @@
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { Controller, Get, Post, Body, Patch, Param, Delete, Put, UseGuards, UsePipes, NotFoundException, Query } from '@nestjs/common';
import { RoleService } from './role.service';
import { CreateRoleDto } from './dto/create-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';
import { ApiTags } from '@nestjs/swagger';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { Roles, RolesGuard, ValidationPipe } from 'src/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { RoleEntity } from './entities/role.entity';
import { QueryRoleDto } from './dto/query-role.dto';
import { all_role } from './role.db';
@ApiTags('用户角色')
@Controller('roles')
export class RoleController {
constructor(private readonly roleService: RoleService) {}
constructor(
private readonly roleService: RoleService,
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
private readonly dataSource: DataSource,
) { }
// @Post()
// create(@Body() createRoleDto: CreateRoleDto) {
@ -33,4 +46,91 @@ export class RoleController {
// remove(@Param('id') id: string) {
// return this.roleService.remove(+id);
// }
@Get('/all')
all() {
return all_role;
}
@Get("/list")
@ApiOperation({ summary: '查看角色' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '查看角色', '创建管理员', '更新管理员')
@ApiBearerAuth()
async areas(@Query() query_data: QueryRoleDto) {
const where: any = {};
if (query_data.name) {
where['name'] = query_data.name;
}
const query = this.roleRepository.createQueryBuilder('role');
query.where(where);
if (query_data.search) {
const string = `%${query_data.search}%`;
const fields = ['name'];
const searchString = fields.join(' like :search OR role.');
query.where(`role.${searchString} like :search`, {
search: string,
});
}
const order_key = 'role.created_date';
let order_value: any = 'DESC';
const [list, count] = await query
.skip(query_data.skip)
.take(query_data.take)
.orderBy(order_key, order_value)
.getManyAndCount();
return { list, count }
}
@Post("/")
@ApiOperation({ summary: '创建角色' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '创建角色')
@ApiBearerAuth()
async createRole(@Body() data: CreateRoleDto) {
return await this.dataSource.transaction(async transactionalEntityManager => {
const role = new RoleEntity();
role.name = data.name;
role.permissions = data.permissions;
const result = await transactionalEntityManager.save(role);
return { statusCode: 201, data: result };
});
}
@Put("/:id")
@ApiOperation({ summary: '更新角色' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '更新角色')
@ApiBearerAuth()
async updateRole(@Param() { id }: any, @Body() data: UpdateRoleDto) {
const role = await this.roleRepository.findOne({ where: { id } });
if (!role) {
throw new NotFoundException("role not found");
}
role.name = data.name;
role.permissions = data.permissions;
const result = await this.roleRepository.save(role);
return result;
}
@Delete("/:id")
@ApiOperation({ summary: '删除角色' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '删除角色')
@ApiBearerAuth()
async deleteRole(@Param() { id }: any) {
const result = await this.roleRepository.findOne({ where: { id } });
if (!result) {
throw new NotFoundException("role not found");
}
await this.roleRepository.delete(id);
return result;
}
}

@ -0,0 +1,38 @@
export const all_role = {
"管理员管理": [
"查看管理员",
"创建管理员",
"修改管理员",
"删除管理员"
],
"角色管理": [
"查看角色",
"创建角色",
"修改角色",
"删除角色"
],
"设备管理": [
"查看设备",
"创建设备",
"修改设备",
"删除设备"
],
// "权限管理": [
// "查看权限",
// "创建权限",
// "修改权限",
// "删除权限"
// ],
"厂区管理": [
"查看厂区",
"创建厂区",
"修改厂区",
"删除厂区"
],
"访客管理": [
"查看预约记录",
"查看到访记录",
"导出访客预约",
"导出到访记录"
],
}

@ -1,8 +1,15 @@
import { Module } from '@nestjs/common';
import { RoleService } from './role.service';
import { RoleController } from './role.controller';
import { RoleEntity } from './entities/role.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forFeature([
RoleEntity,
]),
],
controllers: [RoleController],
providers: [RoleService]
})

@ -1,4 +1,89 @@
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"
import { IsEnum, IsOptional, IsString } from "class-validator"
import { IsEnum, IsNotEmpty, IsOptional, IsString } from "class-validator"
export class CreateUser {
@ApiProperty({ description: '真实姓名' })
@IsString()
@IsNotEmpty()
public true_name: string;
@ApiProperty({ description: '角色' })
@IsString()
@IsNotEmpty()
public role: string;
@ApiProperty({ description: '角色 id' })
@IsString()
@IsNotEmpty()
public role_id: string;
@ApiProperty({ description: '手机号' })
@IsString()
@IsOptional()
public mobile?: string;
@ApiProperty({ description: '用户头像' })
@IsString()
@IsOptional()
public avatar?: string;
@ApiProperty({ description: 'area' })
@IsString()
@IsNotEmpty()
public area: string;
@ApiProperty({ description: 'area id' })
@IsString()
@IsNotEmpty()
public area_id: string;
@ApiProperty({ description: '密码' })
@IsString()
@IsOptional()
public password?: string;
}
export class UpdateUser {
@ApiProperty({ description: '真实姓名' })
@IsString()
@IsNotEmpty()
public true_name: string;
@ApiProperty({ description: '角色' })
@IsString()
@IsNotEmpty()
public role: string;
@ApiProperty({ description: '角色 id' })
@IsString()
@IsNotEmpty()
public role_id: string;
@ApiProperty({ description: 'area' })
@IsString()
@IsNotEmpty()
public area: string;
@ApiProperty({ description: 'area id' })
@IsString()
@IsNotEmpty()
public area_id: string;
@ApiProperty({ description: '手机号' })
@IsString()
@IsOptional()
public mobile?: string;
@ApiProperty({ description: '用户头像' })
@IsString()
@IsOptional()
public avatar?: string;
}
export class UpdatePassword {
@ApiProperty({ description: '' })
@IsString()
@IsNotEmpty()
public password: string;
}

@ -3,22 +3,35 @@ import {
Get,
UsePipes,
UseGuards,
Query,
Post,
Body,
Delete,
Param,
Put,
NotFoundException,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { InjectRepository } from '@nestjs/typeorm';
import {
DataSource,
Repository,
} from 'typeorm';
import { AuthGuard } from '@nestjs/passport';
import * as bcrypt from 'bcryptjs';
import {
ValidationPipe,
User,
Roles,
RolesGuard,
BCRYPT_HASH_ROUNDS,
} from '../common';
import { UserEntity } from './user.entity';
import { UserService } from './user.service';
import { QueryUserDto } from './query-user.dto';
import { CreateUser, UpdatePassword, UpdateUser } from './update-user.dto';
import { RoleEntity } from 'src/role/entities/role.entity';
@ApiTags('系统用户')
@ApiBearerAuth()
@ -27,23 +40,141 @@ export class UserController {
constructor(
@InjectRepository(UserEntity)
private readonly userRepository: Repository<UserEntity>,
private readonly userService: UserService
@InjectRepository(RoleEntity)
private readonly roleRepository: Repository<RoleEntity>,
private readonly userService: UserService,
private readonly dataSource: DataSource,
// @Inject(forwardRef(() => AuthService))
// private readonly authService: AuthService,
) { }
// @Get('/viewer')
// @ApiOperation({ summary: '获取个人信息' })
// @UseGuards(AuthGuard('jwt'), RolesGuard)
// @UsePipes(new ValidationPipe())
@Get('/viewer')
@ApiOperation({ summary: '获取个人信息' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
// @Roles('company', 'tester', 'admin')
// @ApiBearerAuth()
// @ApiResponse({
// status: 200,
// description: '返回参数说明',
// })
// async viewer(@User() viewer: UserEntity) {
// const result = await this.userRepository.findOne({ where: { id: viewer.id } })
// return result;
// }
@ApiBearerAuth()
@ApiResponse({
status: 200,
description: '返回参数说明',
})
async viewer(@User() viewer: UserEntity) {
const result = await this.userRepository.findOne({ where: { id: viewer.id } })
const role = await this.roleRepository.findOne({ where: { id: result.role_id } })
if (role) {
(result as any).permissions = role.permissions.split('、');
}
return result;
}
@Get("/list")
@ApiOperation({ summary: '查看管理员' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '查看管理员')
@ApiBearerAuth()
async areas(@Query() query_data: QueryUserDto) {
const where: any = {};
if (query_data.true_name) {
where['true_name'] = query_data.true_name;
}
const query = this.userRepository.createQueryBuilder('user');
query.where(where);
if (query_data.search) {
const string = `%${query_data.search}%`;
const fields = ['true_name'];
const searchString = fields.join(' like :search OR user.');
query.where(`user.${searchString} like :search`, {
search: string,
});
}
const order_key = 'user.created_date';
let order_value: any = 'DESC';
const [list, count] = await query
.skip(query_data.skip)
.take(query_data.take)
.orderBy(order_key, order_value)
.getManyAndCount();
return { list, count }
}
@Post("/")
@ApiOperation({ summary: '创建管理员' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '创建管理员')
@ApiBearerAuth()
async createUser(@Body() data: CreateUser) {
const new_password = await bcrypt.hash(data.password, BCRYPT_HASH_ROUNDS);
return await this.dataSource.transaction(async transactionalEntityManager => {
const user = new UserEntity();
user.true_name = data.true_name;
user.role = data.role;
user.role_id = data.role_id;
user.mobile = data.mobile;
user.avatar = data.avatar;
user.area_id = data.area_id;
user.area = data.area;
user.password = new_password;
const result = await transactionalEntityManager.save(user);
return { statusCode: 201, data: result };
});
}
@Put("/:id")
@ApiOperation({ summary: '更新管理员' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '更新管理员')
@ApiBearerAuth()
async updateUser(@Param() { id }: any, @Body() data: UpdateUser) {
const user = await this.userRepository.findOne({ where: { id } });
if (!user) {
throw new NotFoundException("user not found");
}
user.true_name = data.true_name;
user.role = data.role;
user.role_id = data.role_id;
user.mobile = data.mobile;
user.avatar = data.avatar;
user.area_id = data.area_id;
user.area = data.area;
const result = await this.userRepository.save(user);
return result;
}
@Put("/:id/password")
@ApiOperation({ summary: '更新管理员' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '更新管理员')
@ApiBearerAuth()
async passwordUser(@Param() { id }: any, @Body() data: UpdatePassword) {
const user = await this.userRepository.findOne({ where: { id } });
if (!user) {
throw new NotFoundException("user not found");
}
const new_password = await bcrypt.hash(data.password, BCRYPT_HASH_ROUNDS);
user.password = new_password;
const result = await this.userRepository.save(user);
return result;
}
@Delete("/:id")
@ApiOperation({ summary: '删除管理员' })
@UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe())
@Roles('super_admin', '删除管理员')
@ApiBearerAuth()
async deleteUser(@Param() { id }: any) {
const result = await this.userRepository.findOne({ where: { id } });
if (!result) {
throw new NotFoundException("user not found");
}
await this.userRepository.delete(id);
return result;
}
}

@ -14,11 +14,30 @@ export class UserEntity extends Base {
@Column({ nullable: true, type: 'int' })
public age: string;
@ApiProperty({ description: '角色' })
@Column({ nullable: true })
public role: string;
@ApiProperty({ description: '角色 id' })
@Column({ length: 36, nullable: true })
public role_id: string;
@ApiProperty({ description: 'area' })
@Column({ nullable: true })
public area: string;
@ApiProperty({ description: 'area id' })
@Column({ length: 36, nullable: true })
public area_id: string;
@ApiProperty({ description: '手机号' })
@Column({ length: 50, nullable: true, type: 'char', select: false })
@Column({ length: 50, nullable: true, type: 'char' })
public mobile?: string;
@ApiProperty({ description: '用户头像' })
@Column({ nullable: true, length: 255, type: 'char' })
public avatar?: string;
@Column({ select: false, nullable: true })
public password: string;
}

@ -4,12 +4,14 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { UserService } from './user.service';
import { UserEntity } from './user.entity';
import { UserController } from './user.controller';
import { RoleEntity } from 'src/role/entities/role.entity';
// import { AuthService } from '../auth/auth.service';
@Module({
imports: [
TypeOrmModule.forFeature([
UserEntity,
RoleEntity
],
),
// TesterModule

Loading…
Cancel
Save