From 9f750832015b2b0b6f83131769d82fea3abf2a8b Mon Sep 17 00:00:00 2001 From: rustdreamer Date: Sun, 7 Apr 2024 13:36:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8E=82=E5=8C=BA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 4 + src/app.controller.ts | 172 +++++++++++++++++++++++++++++++++++++++++- src/area.entity.ts | 16 ++++ swagger-spec.json | 2 +- 4 files changed, 189 insertions(+), 5 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/area.entity.ts diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a283b1f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "DevChat.PythonForChat": "/usr/bin/python3", + "DevChat.PythonForCommands": "/Users/tianshuai/.chat/mamba/envs/devchat-commands/bin/python" +} \ No newline at end of file diff --git a/src/app.controller.ts b/src/app.controller.ts index c8d4f50..0312e6b 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -1,4 +1,4 @@ -import { BadRequestException, Body, Controller, Get, Post, Put, Query, Req, Res } from '@nestjs/common'; +import { BadRequestException, Body, Controller, Delete, Get, NotFoundException, Param, Post, Put, Query, Req, Res } from '@nestjs/common'; import { AppService } from './app.service'; import * as fs from 'fs'; import { ApiBearerAuth, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; @@ -14,6 +14,7 @@ import axios from 'axios'; import { v4 as uuid } from 'uuid'; import { verificationService } from './lib/face'; import { join } from 'path'; +import { AreaEntity } from './area.entity'; export class Electronics { @ApiProperty({ description: "电子产品名称" }) @@ -205,6 +206,45 @@ export class QueryVisitorDto extends CommonPageArgs { end_date?: string } +export class AreaDto extends CommonPageArgs { + @ApiPropertyOptional({ description: "根据名称模糊搜索", required: false }) + @IsString() + @IsOptional() + search?: string +} + +export class CreateArea { + @ApiProperty({ description: "" }) + @IsString() + @IsNotEmpty() + public name: string; + + @ApiProperty({ description: "" }) + @IsString() + @IsNotEmpty() + public code: string; +} + +export class UpdateArea { + @ApiProperty({ description: "" }) + @IsString() + @IsNotEmpty() + public name: string; + + @ApiProperty({ description: "" }) + @IsString() + @IsNotEmpty() + public code: string; +} + +export class DeleteArea { + @ApiProperty({ description: "" }) + @IsString() + @IsNotEmpty() + public id: string; +} + + export class QueryVisitorByNumberDto { @ApiPropertyOptional({ description: "身份证号", required: true }) @IsString() @@ -219,6 +259,8 @@ export class AppController { private readonly dataSource: DataSource, @InjectRepository(NodeVisitorEntity) private readonly nodeVisitorRepository: Repository, + @InjectRepository(AreaEntity) + private readonly areaRepository: Repository, @InjectRepository(NodeOtherVisitorEntity) private readonly nodeOtherVisitorRepository: Repository, ) { } @@ -501,6 +543,128 @@ export class AppController { }); } + + @Post("/area") + 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(); + area.name = data.name; + area.code = data.code; + + const result = await transactionalEntityManager.save(area); + + return { statusCode: 201, data: result }; + }); + } + + @Put("/area/:id") + 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"); + } + area.name = data.name; + area.code = data.code; + const result = await this.areaRepository.save(area); + return result; + } + + @Delete("/area/:id") + 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"); + } + await this.areaRepository.delete(id); + return result; + } + + @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); + if (query_data.search) { + const string = `%${query_data.search}%`; + const fields = ['applicant', 'applicant_department', 'code', 'visitor_unit', 'plate_no', 'visited_staff', 'visited_department']; + const searchString = fields.join(' like :search OR area.'); + query.where(`area.${searchString} like :search`, { + search: string, + }); + } + const order_key = 'area.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 } + } + @Put("/visitor/number") async updateVisitor(@Body() data: UpdateVisitorNumber) { const node_other_visitor = await this.nodeOtherVisitorRepository.findOne({ where: { id: data.id } }) @@ -598,13 +762,13 @@ export class AppController { @Req() req: any, ): Promise { return { - "versionName":"1.2.0", - "apkUrl":`http://${process.env.LOCAL_IP}/app.apk`, + "versionName": "1.2.0", + "apkUrl": `http://${process.env.LOCAL_IP}/app.apk`, "forceUpdate": false, "whatsNew": "新版本更新" }; } - + @Get('app.apk') async file( @Res() res: any, diff --git a/src/area.entity.ts b/src/area.entity.ts new file mode 100644 index 0000000..687edc7 --- /dev/null +++ b/src/area.entity.ts @@ -0,0 +1,16 @@ +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: 'area' }) +export class AreaEntity extends Base { + @ApiProperty({ description: "name" }) + @Column({ length: 150, nullable: false, type: 'char' }) + public name: string; + + @ApiProperty({ description: "code" }) + @Column({ length: 150, nullable: false, type: 'char' }) + public code: string; +} diff --git a/swagger-spec.json b/swagger-spec.json index 484d8ce..5e8e2bc 100644 --- a/swagger-spec.json +++ b/swagger-spec.json @@ -1 +1 @@ -{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}}}},"/visitor":{"get":{"operationId":"AppController_getVisiotr","parameters":[{"name":"identity_card_no","required":false,"in":"query","description":"身份证号","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}]},"post":{"operationId":"AppController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVisitor"}}}},"responses":{"201":{"description":""}}}},"/visitors":{"get":{"operationId":"AppController_get","parameters":[{"name":"skip","required":false,"in":"query","description":"页码","schema":{"type":"number"}},{"name":"take","required":false,"in":"query","description":"条数","schema":{"type":"number"}},{"name":"search","required":false,"in":"query","description":"根据名称模糊搜索","schema":{"type":"string"}},{"name":"start_date","required":false,"in":"query","description":"","schema":{"type":"string"}},{"name":"end_date","required":false,"in":"query","description":"","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}]}},"/upload/base64":{"post":{"operationId":"AppController_louploadBase64Filegin","parameters":[],"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":{"VisitorList":{"type":"object","properties":{"name":{"type":"string","description":"访客姓名"},"identity_card_no":{"type":"string","description":"访客身份证号"},"id_type":{"type":"string","description":"证件类型"},"nationality_type":{"type":"string","description":"国籍(中国/其他国籍)"},"nationality":{"type":"string","description":"国籍名称"}},"required":["name","identity_card_no","id_type","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_department":{"type":"string","description":"被访部门"},"purpose":{"type":"string","description":"被访部门"},"electronics":{"type":"string","description":"携带的电子产品"},"visitor_list":{"description":"访客清单","type":"array","items":{"$ref":"#/components/schemas/VisitorList"}},"may_access_sensitive_info":{"type":"string","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_department","purpose","electronics","visitor_list","may_access_sensitive_info"]}}}} \ No newline at end of file +{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}}}},"/visitor":{"get":{"operationId":"AppController_getVisiotr","parameters":[{"name":"identity_card_no","required":false,"in":"query","description":"身份证号","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}]},"post":{"operationId":"AppController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVisitor"}}}},"responses":{"201":{"description":""}}}},"/visitors":{"get":{"operationId":"AppController_get","parameters":[{"name":"skip","required":false,"in":"query","description":"页码","schema":{"type":"number"}},{"name":"take","required":false,"in":"query","description":"条数","schema":{"type":"number"}},{"name":"search","required":false,"in":"query","description":"根据名称模糊搜索","schema":{"type":"string"}},{"name":"applicant","required":false,"in":"query","description":"申请人","schema":{"type":"string"}},{"name":"visited_staff","required":false,"in":"query","description":"被访人","schema":{"type":"string"}},{"name":"start_date","required":false,"in":"query","description":"","schema":{"type":"string"}},{"name":"end_date","required":false,"in":"query","description":"","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}]}},"/visitor-records":{"get":{"operationId":"AppController_getRecord","parameters":[{"name":"skip","required":false,"in":"query","description":"页码","schema":{"type":"number"}},{"name":"take","required":false,"in":"query","description":"条数","schema":{"type":"number"}},{"name":"search","required":false,"in":"query","description":"根据名称模糊搜索","schema":{"type":"string"}},{"name":"applicant","required":false,"in":"query","description":"申请人","schema":{"type":"string"}},{"name":"visited_staff","required":false,"in":"query","description":"被访人","schema":{"type":"string"}},{"name":"start_date","required":false,"in":"query","description":"","schema":{"type":"string"}},{"name":"end_date","required":false,"in":"query","description":"","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}]}},"/visitor/number":{"put":{"operationId":"AppController_updateVisitor","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVisitorNumber"}}}},"responses":{"200":{"description":""}}}},"/visitor/end":{"put":{"operationId":"AppController_updateVisitorEnd","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVisitorEnd"}}}},"responses":{"200":{"description":""}}}},"/visitor/start":{"put":{"operationId":"AppController_updateVisitorStart","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVisitorEnd"}}}},"responses":{"200":{"description":""}}}},"/upload/base64":{"post":{"operationId":"AppController_louploadBase64Filegin","parameters":[],"responses":{"201":{"description":""}}}},"/version.json":{"get":{"operationId":"AppController_version","parameters":[],"responses":{"200":{"description":""}}}},"/app.apk":{"get":{"operationId":"AppController_file","parameters":[],"responses":{"200":{"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":{"VisitorList":{"type":"object","properties":{"name":{"type":"string","description":"访客姓名"},"identity_card_no":{"type":"string","description":"访客身份证号"},"id_type":{"type":"string","description":"证件类型"},"nationality_type":{"type":"string","description":"国籍(中国/其他国籍)"},"nationality":{"type":"string","description":"国籍名称"}},"required":["name","identity_card_no","id_type","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_department":{"type":"string","description":"被访部门"},"purpose":{"type":"string","description":"被访部门"},"electronics":{"type":"string","description":"携带的电子产品"},"personnel_carrying_electronics":{"type":"string","description":"携带电子产品人员"},"sfslqt":{"type":"string","description":"是否上E1楼洽谈"},"visitor_list":{"description":"访客清单","type":"array","items":{"$ref":"#/components/schemas/VisitorList"}},"may_access_sensitive_info":{"type":"string","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_department","purpose","electronics","personnel_carrying_electronics","sfslqt","visitor_list","may_access_sensitive_info"]},"UpdateVisitorNumber":{"type":"object","properties":{"id":{"type":"string","description":"id"},"card_number":{"type":"string","description":"card_number"}},"required":["id","card_number"]},"UpdateVisitorEnd":{"type":"object","properties":{"id":{"type":"string","description":"id"}},"required":["id"]}}}} \ No newline at end of file