增加接口

main
rustdreamer 2 years ago
parent be7122fbb9
commit 52fe6a618c

@ -7,9 +7,15 @@ REDIS_DB=0
DOC=true
CLIENT_URI=https://liulinlin.test.qunsense.com/
RUST_URI=http://127.0.0.1:8007
# RUST_URI=http://192.168.1.4:8007
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_USERNAME=api-visitor
MYSQL_PASSWORD=api-visitor
MYSQL_DATABASE=api-visitor
FACE_API_KEY=x
FACE_URL=x
FACE_PORT=x

@ -24,6 +24,7 @@
"migration:revert": "npx typeorm-ts-node-esm migration:revert -d src/config/config.mysql.ts"
},
"dependencies": {
"@exadel/compreface-js-sdk": "^1.0.0",
"@nestjs/bull": "^0.6.3",
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
@ -46,6 +47,7 @@
"co-wechat-api": "^3.11.0",
"cron": "^2.4.0",
"dotenv": "^16.0.3",
"fix-esm": "^1.0.1",
"global": "^4.4.0",
"ioredis": "^5.3.2",
"joi": "^17.9.2",
@ -66,7 +68,9 @@
"tree": "^0.1.3",
"typeorm": "0.3.15",
"uuid": "^9.0.0",
"wechatpay-node-v3": "^2.1.4"
"wechatpay-node-v3": "^2.1.4",
"winston": "^3.10.0",
"winston-daily-rotate-file": "^4.7.1"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",

@ -11,6 +11,8 @@ import * as moment from 'moment';
import { CommonPageArgs } from './common';
import { InjectRepository } from '@nestjs/typeorm';
import axios from 'axios';
import { v4 as uuid } from 'uuid';
import { verificationService } from './lib/face';
export class Electronics {
@ApiProperty({ description: "电子产品名称" })
@ -163,6 +165,12 @@ export class QueryVisitorDto extends CommonPageArgs {
end_date?: string
}
export class QueryVisitorByNumberDto {
@ApiPropertyOptional({ description: "身份证号", required: true })
@IsString()
identity_card_no: string
}
@Controller()
export class AppController {
constructor(
@ -198,6 +206,12 @@ export class AppController {
// config(): string {
// return "n9zX2u8E9ShFgYmx";
// }
@Get("/visitor")
@ApiBearerAuth()
async getVisiotr(@Query() { identity_card_no }: QueryVisitorByNumberDto, @Req() req: any) {
const node_visitor = await this.nodeOtherVisitorRepository.findOne({ where: { identity_card_no } })
return node_visitor
}
@Get("/visitors")
@ApiBearerAuth()
@ -321,4 +335,55 @@ export class AppController {
return { statusCode: 201, data: result };
});
}
@Post('upload/base64')
async louploadBase64Filegin(
@Body() input: any,
@Req() req: any,
): Promise<any> {
try {
const file_name = uuid() + '.jpg';
const id_file_name = uuid() + '.id.jpg';
//过滤data:URL
const base64Data = input.image1.replace(/^data:image\/\w+;base64,/, '');
const base64Data2 = input.image2.replace(/^data:image\/\w+;base64,/, '');
const dataBuffer = new Buffer(base64Data, 'base64');
const first = './upload/' + file_name;
fs.writeFileSync(first, dataBuffer);
const second = './upload/' + id_file_name;
const dataBuffer2 = new Buffer(base64Data2, 'base64');
fs.writeFileSync(second, dataBuffer2);
fs.writeFileSync(
'./upload/' + uuid() + '-log.log',
JSON.stringify(input),
);
const { result } = await verificationService.verify(first, second, null);
if (
result &&
result.length > 0 &&
result[0].face_matches &&
result[0].face_matches.length > 0
) {
console.log('result[0].face_matches[0]', result[0].face_matches[0]);
return {
code: 0,
data: { score: result[0].face_matches[0].similarity * 100 },
msg: '成功',
};
}
// console.log('dd', JSON.stringify(result));
return {
code: -1,
msg: '失败',
data: result,
};
} catch (e) {
return {
code: -2,
msg: e.message,
};
}
}
}

@ -0,0 +1,23 @@
// import { readFileSync } from 'fs';
// import module from 'module';
// import { CompreFace } from '@exadel/compreface-js-sdk';
// const { CompreFace } = import('@exadel/compreface-js-sdk');
const { CompreFace } = require('fix-esm').require('@exadel/compreface-js-sdk');
// module.Module._extensions['.js'] = function (module, filename) {
// module._compile(readFileSync(filename, 'utf8'), filename);
// };
// const { CompreFace } = module;
const api_key = process.env.FACE_API_KEY || '7807f145-65a1-4744-aa63-6f51ec37d7b7';
const url = process.env.FACE_URL || 'http://192.168.0.2';
const port = process.env.FACE_PORT ? Number(process.env.FACE_PORT) : 8000;
const compreFace = new CompreFace(url, port); // set CompreFace url and port
export const verificationService =
compreFace.initFaceVerificationService(api_key); // initialize service
// verificationService.verify(source_image_location, target_image_location, options)

@ -0,0 +1,124 @@
import winston from 'winston';
import 'winston-daily-rotate-file';
const myFormat = winston.format.printf((data) => {
const { level, message, label, timestamp } = data;
return `${timestamp} [${label}] ${level}: ${message}`;
});
export const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'debug',
format: winston.format.json(),
defaultMeta: { service: '盘古' },
transports: [
new winston.transports.DailyRotateFile({
filename: 'log/pangu-%DATE%.error.log',
level: 'error',
format: winston.format.combine(
winston.format.label({ label: '盘古' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
new winston.transports.DailyRotateFile({
filename: 'log/pangu-%DATE%.info.log',
level: 'info',
format: winston.format.combine(
winston.format.label({ label: '盘古' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
new winston.transports.Console({
format: winston.format.combine(
winston.format.label({ label: '盘古' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
],
});
export const loggerd = winston.createLogger({
level: process.env.LOG_LEVEL || 'debug',
format: winston.format.json(),
defaultMeta: { service: '达实' },
transports: [
new winston.transports.DailyRotateFile({
filename: 'log/dashi-%DATE%.error.log',
level: 'error',
format: winston.format.combine(
winston.format.label({ label: '达实' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
new winston.transports.DailyRotateFile({
filename: 'log/dashi-%DATE%.info.log',
level: 'info',
format: winston.format.combine(
winston.format.label({ label: '达实' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
new winston.transports.Console({
format: winston.format.combine(
winston.format.label({ label: '达实' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
],
});
export const loggerSystem = winston.createLogger({
level: process.env.LOG_LEVEL || 'debug',
format: winston.format.json(),
defaultMeta: { service: '系统' },
transports: [
new winston.transports.DailyRotateFile({
filename: 'log/system-%DATE%.error.log',
level: 'error',
format: winston.format.combine(
winston.format.label({ label: '系统' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
new winston.transports.DailyRotateFile({
filename: 'log/system-%DATE%.info.log',
level: 'info',
format: winston.format.combine(
winston.format.label({ label: '系统' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
new winston.transports.Console({
format: winston.format.combine(
winston.format.label({ label: '系统' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
myFormat,
),
}),
],
});

@ -0,0 +1,11 @@
import crypto from 'crypto';
export function md5(data) {
const hash = crypto.createHash('md5');
return hash.update(data).digest('hex');
}
export function MD5(data) {
const hash = crypto.createHash('md5');
return hash.update(data).digest('hex').toUpperCase();
}

@ -0,0 +1,86 @@
/**
* randomWord
* @param randomFlag min-[] max-
* @param min
* @param max
* @returns {string}
*/
export function randomWord(randomFlag, min, max?) {
let str = '',
range = min;
const arr = [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
];
// 随机产生
if (randomFlag) {
range = Math.round(Math.random() * (max - min)) + min;
}
let pos;
for (let i = 0; i < range; i++) {
pos = Math.round(Math.random() * (arr.length - 1));
str += arr[pos];
}
return str;
}

@ -1 +1 @@
{"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"]}}}}
{"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"]}}}}

11382
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save