Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion src/module/DocumentAI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ import { makeFormData } from 'koajax';
import { BaseModel, RESTClient, toggle } from 'mobx-restful';

import { LarkData } from '../../type';
import { TaxiInvoice, TrainInvoice, VatInvoice, VehicleInvoice } from './type';
import {
BankCard,
ContractField,
Resume,
TaxiInvoice,
TrainInvoice,
VatInvoice,
VehicleInvoice
} from './type';

export * from './type';

Expand Down Expand Up @@ -58,4 +66,60 @@ export abstract class DocumentAIModel extends BaseModel {

return body!.data!.vehicle_invoice;
}

/**
* @see {@link https://open.feishu.cn/document/server-docs/ai/optical_char_recognition-v1/basic_recognize}
*/
@toggle('uploading')
async recognizeImageText(image: string) {
const { body } = await this.client.post<LarkData<{ text_list: string[] }>>(
'optical_char_recognition/v1/image/basic_recognize',
{ image }
);

return body!.data!.text_list;
}

/**
* @see {@link https://open.feishu.cn/document/ai/document_ai-v1/bank_card/recognize}
*/
@toggle('uploading')
async recognizeBankCard(file: File) {
const { body } = await this.client.post<LarkData<{ bank_card: BankCard }>>(
`${this.baseURI}/bank_card/recognize`,
makeFormData({ file })
);

return body!.data!.bank_card;
}

/**
* @see {@link https://open.feishu.cn/document/ai/document_ai-v1/resume/parse}
*/
@toggle('uploading')
async parseResume(file: File) {
const { body } = await this.client.post<LarkData<{ resumes: Resume[] }>>(
`${this.baseURI}/resume/parse`,
makeFormData({ file })
);

return body!.data!.resumes;
}

/**
* @see {@link https://open.feishu.cn/document/server-docs/ai/document_ai-v1/contract/field_extraction}
*/
@toggle('uploading')
async extractContractFields(
file: File,
pdf_page_limit = 15,
ocr_mode: 'force' | 'auto' | 'unused' = 'auto'
) {
const { body } = await this.client.post<LarkData<ContractField>>(
`${this.baseURI}/contract/field_extraction`,
makeFormData({ file, pdf_page_limit, ocr_mode })
);

return body!.data!;
}
}
186 changes: 185 additions & 1 deletion src/module/DocumentAI/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface VatInvoice {
| 'is_sealed'
| 'machine_num';
value: string;
items: Record<'type' | 'value', string>[][];
items: Record<'type' | 'value', string>[][][];
}

export interface TaxiInvoice {
Expand Down Expand Up @@ -67,3 +67,187 @@ export interface VehicleInvoice {
| `total_price${'' | '_little'}`;
value: string;
}

// Bank Card Recognition

export interface BankCardEntity {
type: 'card_number' | 'date_of_expiry';
value: string;
}

export interface BankCard {
entities: BankCardEntity[];
}

// Resume Parsing

export type Qualification =
| 1 // primary school
| 2 // junior high school
| 3 // secondary vocational
| 4 // high school
| 5 // specialist
| 6 // undergraduate
| 7 // master
| 8 // doctoral
| 9; // other

export interface ResumeEducation {
school: string;
start_date: string;
start_time: string;
end_date: string;
end_time: string;
major: string;
degree: string;
qualification: Qualification;
}

export interface ResumeCareer {
company: string;
start_date: string;
start_time: string;
end_date: string;
end_time: string;
title: string;
type: 1 | 2;
type_str: 'internship' | 'full-time';
job_description: string;
}

export interface ResumeProject {
name: string;
title: string;
start_date: string;
start_time: string;
end_date: string;
end_time: string;
description: string;
}

export interface ResumeLanguage {
level: number;
description: string;
}

export interface ResumeAward {
award: string;
date: string;
description: string;
}

export interface ResumeCertificate {
name: string;
desc: string;
}

export interface ResumeCompetition {
name: string;
desc: string;
}

export interface Resume {
file_md5: string;
content: string;
new_content: string;
name: string;
email: string;
mobile: string;
mobile_is_virtual: boolean;
country_code: string;
educations: ResumeEducation[];
careers: ResumeCareer[];
projects: ResumeProject[];
work_year: number | null;
date_of_birth: string;
gender: 0 | 1 | 2;
willing_positions: string[];
current_location: string;
willing_locations: string[];
home_location: string;
languages: ResumeLanguage[];
awards: ResumeAward[];
certificates: ResumeCertificate[];
competitions: ResumeCompetition[];
self_evaluation: string;
urls: string[];
social_links: string[];
}

// Contract Field Extraction

export interface ExtractPrice {
contract_price: number;
contract_price_original: string;
text: string;
}

export interface ExtractTime {
time_start: string;
time_end: string;
original_time_start: string;
original_time_end: string;
text_start: string;
text_end: string;
}

export interface ExtractTerm {
initial_time: string;
initial_unit: string;
text_initial_term: string;
}

export interface ExtractCopy {
copy_num: number;
original_copy: string;
key: string;
text: string;
}

export interface ExtractCurrency {
currency_name: string;
currency_text: string;
}

export interface BodyEntity {
address: string;
contacts: string;
email: string;
phone: string;
id_number: string;
legal_representative: string;
party: string;
}

export interface BodyInfo {
body_type: 'buy' | 'sell' | 'third';
value: BodyEntity;
}

export interface BankEntity {
account_name: string;
bank_name: string;
account_number: string;
phone: string;
contacts: string;
tax_number: string;
address: string;
id_number: string;
email: string;
}

export interface BankInfo {
bank_type: 'buy_bank' | 'sell_bank' | 'third_bank' | 'unceratin_bank';
value: BankEntity;
}

export interface ContractField {
file_id: string;
price: ExtractPrice;
time: ExtractTime & { initial_term: ExtractTerm };
copy: ExtractCopy;
currency: ExtractCurrency;
header: string;
body_info: BodyInfo[];
bank_info: BankInfo[];
}