完善访客接口

main
rustdreamer 3 years ago
parent 696ec918e8
commit b312dcd929

@ -7,8 +7,8 @@
host: host:
path: /var/run/docker.sock path: /var/run/docker.sock
- name: cache - name: cache
host: host: ·
path: /tmp/cache/nanjing path: /tmp/cache/visitor-new-api
steps: steps:
- name: restore-cache - name: restore-cache
@ -64,7 +64,7 @@
- name: dockersock - name: dockersock
path: /var/run/docker.sock path: /var/run/docker.sock
settings: settings:
repo: hub.kaiguawang.cn/qunsense/api repo: hub.kaiguawang.cn/longge/visitor-node-api
registry: hub.kaiguawang.cn registry: hub.kaiguawang.cn
tags: tags:
- latest - latest

@ -1,33 +1,202 @@
import { Controller, Get } from '@nestjs/common'; import { Body, Controller, Get, Post } from '@nestjs/common';
import { AppService } from './app.service'; import { AppService } from './app.service';
import * as fs from 'fs'; import * as fs from 'fs';
import { ApiProperty } from '@nestjs/swagger';
import { IsArray, IsBoolean, IsDateString, IsNotEmpty, IsString } from 'class-validator';
import { NodeVisitorEntity } from './node-visitor.entity';
import { DataSource } from 'typeorm';
import * as bluebird from 'bluebird';
import { NodeOtherVisitorEntity } from './node-other-visitor.entity';
export class Electronics {
@ApiProperty({ description: "电子产品名称" })
@IsString()
@IsNotEmpty()
public name: string;
}
export class VisitorList {
@ApiProperty({ description: "访客姓名" })
@IsString()
@IsNotEmpty()
public name: string;
@ApiProperty({ description: "访客身份证号" })
@IsString()
@IsNotEmpty()
public identity_card_no: string;
@ApiProperty({ description: "国籍(中国/其他国籍)" })
@IsString()
@IsNotEmpty()
public nationality_type: string;
@ApiProperty({ description: "国籍名称" })
@IsString()
@IsNotEmpty()
public nationality: string;
}
export class CreateVisitor {
@ApiProperty({ description: "申请人" })
@IsString()
@IsNotEmpty()
public applicant: string;
@ApiProperty({ description: "申请人部门" })
@IsString()
@IsNotEmpty()
public applicant_department: string;
@ApiProperty({ description: "申请日期" })
@IsDateString()
@IsNotEmpty()
public apply_date: string;
@ApiProperty({ description: "申请单号" })
@IsString()
@IsNotEmpty()
public code: string;
// TODO 确定访客类型
@ApiProperty({ description: "来访类型" })
@IsString()
@IsNotEmpty()
public visitor_type: string;
@ApiProperty({ description: "来访区域" })
@IsString()
@IsNotEmpty()
public area: string;
@ApiProperty({ description: "来访单位" })
@IsString()
@IsNotEmpty()
public visitor_unit: string;
@ApiProperty({ description: "访客人数" })
@IsString()
@IsNotEmpty()
public visitor_number: string;
@ApiProperty({ description: "交通方式" })
@IsString()
@IsNotEmpty()
public transport: string;
@ApiProperty({ description: "车牌号" })
@IsString()
@IsNotEmpty()
public plate_no: string;
@ApiProperty({ description: "起始日期" })
@IsDateString()
@IsNotEmpty()
public start_date: string;
@ApiProperty({ description: "截止日期" })
@IsDateString()
@IsNotEmpty()
public end_date: string;
@ApiProperty({ description: "被访人" })
@IsString()
@IsNotEmpty()
public visited_staff: string;
@ApiProperty({ description: "被访部门" })
@IsString()
@IsNotEmpty()
public visited_deparment: string;
@ApiProperty({ description: "被访部门" })
@IsString()
@IsNotEmpty()
public purpose: string;
@ApiProperty({ description: "携带的电子产品", type: [Electronics] })
@IsArray()
@IsNotEmpty()
public electronics: Electronics[];
@ApiProperty({ description: "访客清单", type: [VisitorList] })
@IsArray()
@IsNotEmpty()
public visitor_list: VisitorList[];
@ApiProperty({ description: "访客是否有可能接触受控设备" })
@IsBoolean()
@IsNotEmpty()
public may_access_sensitive_info: boolean;
}
@Controller() @Controller()
export class AppController { export class AppController {
constructor(private readonly appService: AppService) {} constructor(
private readonly appService: AppService,
private readonly dataSource: DataSource,
) { }
@Get() @Get()
getHello(): string { getHello(): string {
return this.appService.getHello(); return this.appService.getHello();
} }
@Get("/doc/json") // @Get("/doc/json")
getDoc(): string { // getDoc(): string {
const json = fs.readFileSync("swagger-spec.json", "utf-8"); // const json = fs.readFileSync("swagger-spec.json", "utf-8");
return JSON.parse(json); // return JSON.parse(json);
} // }
// @Get("/app.config")
// appConfig() {
// return {
// app_id: process.env.QUNSENSE_SUITE_ID
// }
// }
@Get("/app.config")
appConfig() {
return {
app_id: process.env.QUNSENSE_SUITE_ID
}
}
// @Get("/WW_verify_n9zX2u8E9ShFgYmx.txt") // @Get("/WW_verify_n9zX2u8E9ShFgYmx.txt")
// config(): string { // config(): string {
// return "n9zX2u8E9ShFgYmx"; // return "n9zX2u8E9ShFgYmx";
// } // }
@Post("/visitor")
async create(@Body() data: CreateVisitor) {
return await this.dataSource.transaction(async transactionalEntityManager => {
const new_node_visitor = new NodeVisitorEntity();
new_node_visitor.applicant = data.applicant;
new_node_visitor.applicant_department = data.applicant_department;
new_node_visitor.apply_date = data.apply_date;
new_node_visitor.code = data.code;
new_node_visitor.visitor_type = data.visitor_type;
new_node_visitor.area = data.area;
new_node_visitor.visitor_unit = data.visitor_unit;
new_node_visitor.visitor_number = data.visitor_number;
new_node_visitor.transport = data.transport;
new_node_visitor.plate_no = data.plate_no;
new_node_visitor.start_date = data.start_date;
new_node_visitor.end_date = data.end_date;
new_node_visitor.visited_staff = data.visited_staff;
new_node_visitor.visited_deparment = data.visited_deparment;
new_node_visitor.purpose = data.purpose;
new_node_visitor.electronics = JSON.stringify(data.electronics);
// new_node_visitor.visitor_list = data.visitor_list;
new_node_visitor.may_access_sensitive_info = data.may_access_sensitive_info;
const result = await transactionalEntityManager.save(new_node_visitor);
await bluebird.each(data.visitor_list, async (item) => {
const new_node_other_visitor = new NodeOtherVisitorEntity();
new_node_other_visitor.name = item.name;
new_node_other_visitor.identity_card_no = item.identity_card_no;
new_node_other_visitor.nationality_type = item.nationality_type;
new_node_other_visitor.nationality = item.nationality;
})
return result;
});
}
} }

@ -3,18 +3,25 @@ import { ScheduleModule } from '@nestjs/schedule';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import {mysql_config} from './config/config.mysql'; import { mysql_config } from './config/config.mysql';
import { ConfigModule } from './config/config.module'; import { ConfigModule } from './config/config.module';
import { AuthModule } from './auth/auth.module'; import { AuthModule } from './auth/auth.module';
import { UserModule } from './user/user.module'; import { UserModule } from './user/user.module';
import { RoleModule } from './role/role.module'; import { RoleModule } from './role/role.module';
import { FileModule } from './file/file.module'; import { FileModule } from './file/file.module';
import { VisitorEntity } from './visitor.entity';
import { NodeVisitorEntity } from './node-visitor.entity';
@Module({ @Module({
imports: [ imports: [
ConfigModule, ConfigModule,
AuthModule, AuthModule,
UserModule, UserModule,
TypeOrmModule.forRoot(mysql_config), TypeOrmModule.forRoot(mysql_config),
TypeOrmModule.forFeature([
VisitorEntity,
NodeVisitorEntity,
]),
ScheduleModule.forRoot(), ScheduleModule.forRoot(),
RoleModule, RoleModule,
FileModule, FileModule,
@ -22,4 +29,4 @@ import { FileModule } from './file/file.module';
controllers: [AppController], controllers: [AppController],
providers: [AppService], providers: [AppService],
}) })
export class AppModule {} export class AppModule { }

@ -34,23 +34,23 @@ export class AuthController {
private readonly userRepository: Repository<UserEntity>, private readonly userRepository: Repository<UserEntity>,
) { } ) { }
@Get('login/status/is_login') // @Get('login/status/is_login')
@ApiOperation({ summary: '获取 token 是否失效' }) // @ApiOperation({ summary: '获取 token 是否失效' })
@UsePipes(new ValidationPipe()) // @UsePipes(new ValidationPipe())
@ApiResponse({ // @ApiResponse({
status: 200, // status: 200,
description: '返回参数说明', // description: '返回参数说明',
type: LoginStatus, // type: LoginStatus,
}) // })
async loginGetStatus(@Query() loginData: IsLogin): Promise<any> { // async loginGetStatus(@Query() loginData: IsLogin): Promise<any> {
const result = await redis.get(`qunsense_code:${loginData.qunsense_code}`) // const result = await redis.get(`qunsense_code:${loginData.qunsense_code}`)
if (result) { // if (result) {
return { // return {
status: true // status: true
} // }
} // }
return { // return {
status: false // status: false
} // }
} // }
} }

@ -15,12 +15,13 @@ let gen1 = new snowId.SnowflakeIdv1({ workerId: 1, seqBitLength: 2, workerIdBitL
// @ObjectType() // @ObjectType()
@Entity() @Entity()
export class Base extends BaseEntity { export class Base extends BaseEntity {
@BeforeInsert() // @BeforeInsert()
generateId() { // generateId() {
this.id = String(gen1.NextId()) // this.id = String(gen1.NextId())
} // }
// @Field() // @Field()
@PrimaryColumn({ length: 12 }) // @PrimaryColumn({ length: 12 })
@PrimaryGeneratedColumn('uuid')
// @Column({ type: 'varchar', length: '12', nullable: false }) // @Column({ type: 'varchar', length: '12', nullable: false })
@ApiProperty({ description: "数据唯一id" }) @ApiProperty({ description: "数据唯一id" })
id: string; id: string;

@ -2,16 +2,18 @@ import { DocumentBuilder } from '@nestjs/swagger';
export const options = new DocumentBuilder() export const options = new DocumentBuilder()
.setTitle('restfull api') .setTitle('restfull api')
.setDescription(` .setDescription("restfull风格api"
Apirestfullapi使headerstatus200get201POST/PUT/PATCH // `
204deletecodemessageheaderstatus=500 {message:"Internal server error"} // Api为restfull风格api接口请求成功与否请使用header里面的status来判断200表示get请求成功201表示POST/PUT/PATCH请求成功
messagestringorm使typeorm@0.3.15iduuidvachar(36) // 204表示delete成功非上述code返回体会有message字段表示请求失败的错误描述例如header的status=500 那么返回体中回包含{message:"Internal server error"}
idER_NO_REFERENCED_ROW2can not add or update a children row:xx // 注意返回的message字段并不一定是string类型。注意orm使用的是固定版本typeorm@0.3.15。表结构存在关联字段更高版本每次都会重建主键id字段无论关联字段类型是uuid还是vachar(36)
`) // 重建时会删除id对应的值导致外建关联报错“ER_NO_REFERENCED_ROW2can not add or update a children row:xx
// `
)
.setVersion('1.0') .setVersion('1.0')
// .setTermsOfService('test') // .setTermsOfService('test')
// .setContact('时间伙伴', 'shijianhuoban.com', 'shijianhuoban@outlook.com') // .setContact('时间伙伴', 'kaiguawang.com', 'kaiguawang@outlook.com')
.setLicense('2019 © shijianhuoban', 'https://github.com/shijianhuoban') .setLicense('2023 © kaiguawang', 'https://github.com/shijianhuoban')
.setBasePath('/api') .setBasePath('/api')
.addBearerAuth() .addBearerAuth()
// .addOAuth2() // .addOAuth2()

@ -45,67 +45,67 @@ export class FileController {
private readonly fileRepository: Repository<FileEntity>, private readonly fileRepository: Repository<FileEntity>,
) { } ) { }
@Post('upload/public') // @Post('upload/public')
@ApiOperation({ summary: '上传文件' }) // @ApiOperation({ summary: '上传文件' })
@ApiConsumes('multipart/form-data') // @ApiConsumes('multipart/form-data')
@ApiBody({ // @ApiBody({
description: 'file', // description: 'file',
type: FileUploadType, // type: FileUploadType,
}) // })
@UseGuards(AuthGuard('jwt')) // @UseGuards(AuthGuard('jwt'))
// @Roles('super_admin', '批量创建门锁') // // @Roles('super_admin', '批量创建门锁')
@UseInterceptors( // @UseInterceptors(
FileInterceptor('file', { // FileInterceptor('file', {
storage: diskStorage({ // storage: diskStorage({
destination: './upload/file', // destination: './upload/file',
filename: async (req, file, cb) => { // filename: async (req, file, cb) => {
const randomName = Array(32) // const randomName = Array(32)
.fill(null) // .fill(null)
.map(() => Math.round(Math.random() * 16).toString(16)) // .map(() => Math.round(Math.random() * 16).toString(16))
.join(''); // .join('');
return cb(null, `${randomName}${extname(file.originalname)}`); // return cb(null, `${randomName}${extname(file.originalname)}`);
}, // },
}), // }),
}), // }),
) // )
async uploadPublicFile(@UploadedFile() file, @Query() query: any, @Res() res, @User() viewer: any) { // async uploadPublicFile(@UploadedFile() file, @Query() query: any, @Res() res, @User() viewer: any) {
// const filterType: string[] = ['.pdf', '.PDF', '.png', '.doc', '.docx', '.jpeg']; // // const filterType: string[] = ['.pdf', '.PDF', '.png', '.doc', '.docx', '.jpeg'];
const { filename } = file; // const { filename } = file;
// const ext = extname(filename) // // const ext = extname(filename)
// 判断当前上传至接口的文件类型是否在白名单中,如果在则允许上传,不在则返回错误信息 // // 判断当前上传至接口的文件类型是否在白名单中,如果在则允许上传,不在则返回错误信息
// if (!filterType.includes(ext)) { // // if (!filterType.includes(ext)) {
// return res.json({ // // return res.json({
// success: false, // // success: false,
// message: "文件格式错误,支持'.pdf'、'.PDF'、 '.png'、 '.doc'、 '.docx'、 '.jpeg'", // // message: "文件格式错误,支持'.pdf'、'.PDF'、 '.png'、 '.doc'、 '.docx'、 '.jpeg'",
// }); // // });
// } // // }
// const file_name = query.code + "-" + file.filename // // const file_name = query.code + "-" + file.filename
return res.json({ // return res.json({
message: 'ok', // message: 'ok',
success: true, // success: true,
file_name: file.filename, // file_name: file.filename,
// uri: getDownloadUrl(file_name), // // uri: getDownloadUrl(file_name),
}); // });
} // }
@Post('upload/base64') // @Post('upload/base64')
@ApiOperation({ summary: '上传头像文件' }) // @ApiOperation({ summary: '上传头像文件' })
@UseGuards(AuthGuard('jwt')) // @UseGuards(AuthGuard('jwt'))
@UsePipes(new ValidationPipe()) // @UsePipes(new ValidationPipe())
async louploadBase64Filegin(@Body() input: Base64File): Promise<any> { // async louploadBase64Filegin(@Body() input: Base64File): Promise<any> {
const file_name = uuid() + '.png'; // const file_name = uuid() + '.png';
// if (!input.base64.startsWith('data:image/png;base64') && !input.base64.startsWith('data:image/jpeg;base64')) { // // if (!input.base64.startsWith('data:image/png;base64') && !input.base64.startsWith('data:image/jpeg;base64')) {
// throw new BadRequestException('文件类型不支持仅支持jpegpng') // // throw new BadRequestException('文件类型不支持仅支持jpegpng')
// } // // }
//过滤data:URL // //过滤data:URL
const base64Data = input.base64.replace(/^data:image\/\w+;base64,/, ''); // const base64Data = input.base64.replace(/^data:image\/\w+;base64,/, '');
const dataBuffer = new Buffer(base64Data, 'base64'); // const dataBuffer = new Buffer(base64Data, 'base64');
// await uploadBase64File(file_name, dataBuffer); // // await uploadBase64File(file_name, dataBuffer);
return { // return {
message: 'ok', // message: 'ok',
success: true, // success: true,
file_name, // file_name,
// uri: getDownloadUrl(file_name), // // uri: getDownloadUrl(file_name),
}; // };
} // }
} }

@ -0,0 +1,28 @@
import { BaseEntity, Column, Entity, Index, JoinColumn, OneToMany, OneToOne } from 'typeorm';
import { createHmac } from 'crypto';
import { Base } from './common';
import { ApiProperty } from '@nestjs/swagger';
// 访客
@Entity({ name: 'node-other-visitor' })
export class NodeOtherVisitorEntity extends Base {
@ApiProperty({ description: "访客姓名" })
@Column({ length: 150, nullable: true, type: 'char' })
public name: string;
@ApiProperty({ description: "访客身份证号" })
@Column({ length: 150, nullable: true, type: 'char' })
public identity_card_no: string;
@ApiProperty({ description: "国籍(中国/其他国籍)" })
@Column({ length: 150, nullable: true, type: 'char' })
public nationality_type: string;
@ApiProperty({ description: "国籍名称" })
@Column({ length: 150, nullable: true, type: 'char' })
public nationality: string;
@ApiProperty({ description: "" })
@Column({ length: 36, nullable: true, type: 'char' })
public node_visitor_id: string;
}

@ -0,0 +1,82 @@
import { BaseEntity, Column, Entity, Index, JoinColumn, OneToMany, OneToOne } from 'typeorm';
import { createHmac } from 'crypto';
import { Base } from './common';
import { ApiProperty } from '@nestjs/swagger';
// 访客
@Entity({ name: 'node-visitor' })
export class NodeVisitorEntity extends Base {
@ApiProperty({ description: "申请人" })
@Column({ length: 150, nullable: true, type: 'char' })
public applicant: string;
@ApiProperty({ description: "申请人部门" })
@Column({ length: 150, nullable: true, type: 'char' })
public applicant_department: string;
@ApiProperty({ description: "申请日期" })
@Column({ nullable: true, type: 'date' })
public apply_date: string;
@ApiProperty({ description: "申请单号" })
@Column({ length: 150, nullable: true, type: 'char' })
public code: string;
// TODO 确定访客类型
@ApiProperty({ description: "来访类型" })
@Column({ length: 150, nullable: true, type: 'char' })
public visitor_type: string;
@ApiProperty({ description: "来访区域" })
@Column({ length: 150, nullable: true, type: 'char' })
public area: string;
@ApiProperty({ description: "来访单位" })
@Column({ length: 150, nullable: true, type: 'char' })
public visitor_unit: string;
@ApiProperty({ description: "访客人数" })
@Column({ length: 150, nullable: true, type: 'char' })
public visitor_number: string;
@ApiProperty({ description: "交通方式" })
@Column({ length: 150, nullable: true, type: 'char' })
public transport: string;
@ApiProperty({ description: "车牌号" })
@Column({ length: 150, nullable: true, type: 'char' })
public plate_no: string;
@ApiProperty({ description: "起始日期" })
@Column({ nullable: true, type: 'date' })
public start_date: string;
@ApiProperty({ description: "截止日期" })
@Column({ nullable: true, type: 'date' })
public end_date: string;
@ApiProperty({ description: "被访人" })
@Column({ length: 150, nullable: true, type: 'char' })
public visited_staff: string;
@ApiProperty({ description: "被访部门" })
@Column({ length: 150, nullable: true, type: 'char' })
public visited_deparment: string;
@ApiProperty({ description: "被访部门" })
@Column({ length: 150, nullable: true, type: 'char' })
public purpose: string;
@ApiProperty({ description: "携带的电子产品" })
@Column({ length: 255, nullable: true, type: 'char' })
public electronics: string;
// @ApiProperty({ description: "访客清单", type: [VisitorList] })
// @IsArray()
// @IsNotEmpty()
// public visitor_list: VisitorList[];
@ApiProperty({ description: "访客是否有可能接触受控设备" })
@Column({ nullable: true })
public may_access_sensitive_info: boolean;
}

@ -9,28 +9,28 @@ import { ApiTags } from '@nestjs/swagger';
export class RoleController { export class RoleController {
constructor(private readonly roleService: RoleService) {} constructor(private readonly roleService: RoleService) {}
@Post() // @Post()
create(@Body() createRoleDto: CreateRoleDto) { // create(@Body() createRoleDto: CreateRoleDto) {
return this.roleService.create(createRoleDto); // return this.roleService.create(createRoleDto);
} // }
@Get() // @Get()
findAll() { // findAll() {
return this.roleService.findAll(); // return this.roleService.findAll();
} // }
@Get(':id') // @Get(':id')
findOne(@Param('id') id: string) { // findOne(@Param('id') id: string) {
return this.roleService.findOne(+id); // return this.roleService.findOne(+id);
} // }
@Patch(':id') // @Patch(':id')
update(@Param('id') id: string, @Body() updateRoleDto: UpdateRoleDto) { // update(@Param('id') id: string, @Body() updateRoleDto: UpdateRoleDto) {
return this.roleService.update(+id, updateRoleDto); // return this.roleService.update(+id, updateRoleDto);
} // }
@Delete(':id') // @Delete(':id')
remove(@Param('id') id: string) { // remove(@Param('id') id: string) {
return this.roleService.remove(+id); // return this.roleService.remove(+id);
} // }
} }

@ -32,18 +32,18 @@ export class UserController {
// private readonly authService: AuthService, // private readonly authService: AuthService,
) { } ) { }
@Get('/viewer') // @Get('/viewer')
@ApiOperation({ summary: '获取个人信息' }) // @ApiOperation({ summary: '获取个人信息' })
@UseGuards(AuthGuard('jwt'), RolesGuard) // @UseGuards(AuthGuard('jwt'), RolesGuard)
@UsePipes(new ValidationPipe()) // @UsePipes(new ValidationPipe())
@Roles('company', 'tester', 'admin') // @Roles('company', 'tester', 'admin')
@ApiBearerAuth() // @ApiBearerAuth()
@ApiResponse({ // @ApiResponse({
status: 200, // status: 200,
description: '返回参数说明', // description: '返回参数说明',
}) // })
async viewer(@User() viewer: UserEntity) { // async viewer(@User() viewer: UserEntity) {
const result = await this.userRepository.findOne({ where: { id: viewer.id } }) // const result = await this.userRepository.findOne({ where: { id: viewer.id } })
return result; // return result;
} // }
} }

@ -4,7 +4,7 @@ import { Base } from '../common';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
// 用户表 // 用户表
@Entity({ name: 'users' }) @Entity({ name: 'node-users' })
export class UserEntity extends Base { export class UserEntity extends Base {
@ApiProperty({ description: '真实姓名' }) @ApiProperty({ description: '真实姓名' })
@Column({ length: 50, nullable: true, type: 'char' }) @Column({ length: 50, nullable: true, type: 'char' })

@ -0,0 +1,75 @@
import { BaseEntity, Column, Entity, Index, JoinColumn, OneToMany, OneToOne } from 'typeorm';
import { createHmac } from 'crypto';
import { Base } from './common';
import { ApiProperty } from '@nestjs/swagger';
// 访客
@Entity({ name: 'visitor' })
export class VisitorEntity extends Base {
@ApiProperty({ description: '真实姓名' })
@Column({ length: 50, nullable: true, type: 'char' })
public true_name: string;
@ApiProperty({ description: '手机号' })
@Column({ length: 50 })
public mobile: string;
@ApiProperty({ description: '公司' })
@Column({ length: 50 })
public company: string;
@ApiProperty({ description: '邀请码' })
@Column({ length: 50 })
public code: string;
@ApiProperty({ description: '邀请码' })
@Column({ length: 50 })
public card_code: string;
@ApiProperty({ description: '二维码有效时间' })
@Column({ length: 50 })
public qrCode?: string;
@ApiProperty({ description: '事由' })
@Column({ length: 50 })
public reason?: string;
@ApiProperty({ description: '身份证号' })
@Column({ length: 50 })
public id_number?: string;
@ApiProperty({ description: '受访人' })
@Column({ length: 50 })
public interviewee?: string;
@ApiProperty({ description: '楼层' })
@Column({ length: 50 })
public floor?: string;
@ApiProperty({ description: '开始日期' })
@Column({ type: "date" })
public start_date: string;
@ApiProperty({ description: '开始时间' })
@Column({ type: "time" })
public start_time: string;
@ApiProperty({ description: '结束日期' })
@Column({ type: "date" })
public end_date: string;
@ApiProperty({ description: '结束时间' })
@Column({ type: "time" })
public end_time: string;
// #[sea_orm(column_type = "Char(Some(36))", nullable)]
// pub create_user_id: Option<String>,
// #[sea_orm(column_type = "DateTime", indexed)]
// #[component(value_type = String)]
// pub created_date: DateTime<Utc>,
// #[sea_orm(column_type = "DateTime")]
// #[component(value_type = String)]
// pub updated_date: DateTime<Utc>,
}

@ -1 +1 @@
{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}}}},"/doc/json":{"get":{"operationId":"AppController_getDoc","parameters":[],"responses":{"200":{"description":""}}}},"/app.config":{"get":{"operationId":"AppController_appConfig","parameters":[],"responses":{"200":{"description":""}}}},"/auth/login/status/is_login":{"get":{"operationId":"AuthController_loginGetStatus","summary":"获取 token 是否失效","parameters":[{"name":"qunsense_code","required":true,"in":"query","description":"小程序码","schema":{"type":"string"}}],"responses":{"200":{"description":"返回参数说明","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginStatus"}}}}},"tags":["用户登录"]}},"/users/viewer":{"get":{"operationId":"UserController_viewer","summary":"获取个人信息","parameters":[],"responses":{"200":{"description":"返回参数说明"}},"tags":["系统用户"],"security":[{"bearer":[]},{"bearer":[]}]}},"/roles":{"post":{"operationId":"RoleController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleDto"}}}},"responses":{"201":{"description":""}},"tags":["用户角色"]},"get":{"operationId":"RoleController_findAll","parameters":[],"responses":{"200":{"description":""}},"tags":["用户角色"]}},"/roles/{id}":{"get":{"operationId":"RoleController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["用户角色"]},"patch":{"operationId":"RoleController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoleDto"}}}},"responses":{"200":{"description":""}},"tags":["用户角色"]},"delete":{"operationId":"RoleController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["用户角色"]}},"/file/upload/public":{"post":{"operationId":"FileController_uploadPublicFile","summary":"上传文件","parameters":[],"requestBody":{"required":true,"description":"file","content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/FileUploadType"}}}},"responses":{"201":{"description":""}},"tags":["file"],"security":[{"bearer":[]}]}},"/file/upload/base64":{"post":{"operationId":"FileController_louploadBase64Filegin","summary":"上传头像文件","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Base64File"}}}},"responses":{"201":{"description":""}},"tags":["file"],"security":[{"bearer":[]}]}}},"info":{"title":"restfull api","description":"\n Api为restfull风格api接口请求成功与否请使用header里面的status来判断200表示get请求成功201表示POST/PUT/PATCH请求成功 \n 204表示delete成功非上述code返回体会有message字段表示请求失败的错误描述例如header的status=500 那么返回体中回包含{message:\"Internal server error\"}\n 注意返回的message字段并不一定是string类型。注意orm使用的是固定版本typeorm@0.3.15。表结构存在关联字段更高版本每次都会重建主键id字段无论关联字段类型是uuid还是vachar(36)\n 重建时会删除id对应的值导致外建关联报错“ER_NO_REFERENCED_ROW2can not add or update a children row:xx\n ","version":"1.0","contact":{},"license":{"name":"2019 © shijianhuoban","url":"https://github.com/shijianhuoban"}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"LoginStatus":{"type":"object","properties":{"status":{"type":"boolean","description":"登录状态返回"}}},"CreateRoleDto":{"type":"object","properties":{}},"UpdateRoleDto":{"type":"object","properties":{}},"FileUploadType":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]},"Base64File":{"type":"object","properties":{"base64":{"type":"string"}},"required":["base64"]}}}} {"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}}}},"/visitor":{"post":{"operationId":"AppController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVisitor"}}}},"responses":{"201":{"description":""}}}}},"info":{"title":"restfull api","description":"restfull风格api","version":"1.0","contact":{},"license":{"name":"2023 © kaiguawang","url":"https://github.com/shijianhuoban"}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"Electronics":{"type":"object","properties":{"name":{"type":"string","description":"电子产品名称"}},"required":["name"]},"VisitorList":{"type":"object","properties":{"name":{"type":"string","description":"访客姓名"},"identity_card_no":{"type":"string","description":"访客身份证号"},"nationality_type":{"type":"string","description":"国籍(中国/其他国籍)"},"nationality":{"type":"string","description":"国籍名称"}},"required":["name","identity_card_no","nationality_type","nationality"]},"CreateVisitor":{"type":"object","properties":{"applicant":{"type":"string","description":"申请人"},"applicant_department":{"type":"string","description":"申请人部门"},"apply_date":{"type":"string","description":"申请日期"},"code":{"type":"string","description":"申请单号"},"visitor_type":{"type":"string","description":"来访类型"},"area":{"type":"string","description":"来访区域"},"visitor_unit":{"type":"string","description":"来访单位"},"visitor_number":{"type":"string","description":"访客人数"},"transport":{"type":"string","description":"交通方式"},"plate_no":{"type":"string","description":"车牌号"},"start_date":{"type":"string","description":"起始日期"},"end_date":{"type":"string","description":"截止日期"},"visited_staff":{"type":"string","description":"被访人"},"visited_deparment":{"type":"string","description":"被访部门"},"purpose":{"type":"string","description":"被访部门"},"electronics":{"description":"携带的电子产品","type":"array","items":{"$ref":"#/components/schemas/Electronics"}},"visitor_list":{"description":"访客清单","type":"array","items":{"$ref":"#/components/schemas/VisitorList"}},"may_access_sensitive_info":{"type":"boolean","description":"访客是否有可能接触受控设备"}},"required":["applicant","applicant_department","apply_date","code","visitor_type","area","visitor_unit","visitor_number","transport","plate_no","start_date","end_date","visited_staff","visited_deparment","purpose","electronics","visitor_list","may_access_sensitive_info"]}}}}
Loading…
Cancel
Save