mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 01:04:25 +08:00
create transactions from AI receipt image recognition results
This commit is contained in:
@@ -35,6 +35,10 @@ export function isMCPServerEnabled(): boolean {
|
||||
return getServerSetting('mcp') === 1;
|
||||
}
|
||||
|
||||
export function isTransactionFromAIImageRecognitionEnabled(): boolean {
|
||||
return getServerSetting('llmt') === 1;
|
||||
}
|
||||
|
||||
export function getLoginPageTips(): Record<string, string>{
|
||||
return getServerSetting('lpt') as Record<string, string>;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
DEFAULT_UPLOAD_API_TIMEOUT,
|
||||
DEFAULT_EXPORT_API_TIMEOUT,
|
||||
DEFAULT_IMPORT_API_TIMEOUT,
|
||||
DEFAULT_LLM_API_TIMEOUT,
|
||||
GOOGLE_MAP_JAVASCRIPT_URL,
|
||||
BAIDU_MAP_JAVASCRIPT_URL,
|
||||
AMAP_JAVASCRIPT_URL
|
||||
@@ -134,6 +135,9 @@ import type {
|
||||
import type {
|
||||
UserApplicationCloudSettingsUpdateRequest
|
||||
} from '@/models/user_app_cloud_setting.ts';
|
||||
import type {
|
||||
RecognizedReceiptImageResponse
|
||||
} from '@/models/large_language_model.ts';
|
||||
|
||||
import {
|
||||
getCurrentToken,
|
||||
@@ -635,6 +639,13 @@ export default {
|
||||
deleteTransactionTemplate: (req: TransactionTemplateDeleteRequest): ApiResponsePromise<boolean> => {
|
||||
return axios.post<ApiResponse<boolean>>('v1/transaction/templates/delete.json', req);
|
||||
},
|
||||
recognizeReceiptImage: ({ imageFile }: { imageFile: File }): ApiResponsePromise<RecognizedReceiptImageResponse> => {
|
||||
return axios.postForm<ApiResponse<RecognizedReceiptImageResponse>>('v1/llm/transactions/recognize_receipt_image.json', {
|
||||
image: imageFile
|
||||
}, {
|
||||
timeout: DEFAULT_LLM_API_TIMEOUT
|
||||
});
|
||||
},
|
||||
getLatestExchangeRates: (param: { ignoreError?: boolean }): ApiResponsePromise<LatestExchangeRateResponse> => {
|
||||
return axios.get<ApiResponse<LatestExchangeRateResponse>>('v1/exchange_rates/latest.json', {
|
||||
ignoreError: !!param.ignoreError,
|
||||
|
||||
@@ -3,6 +3,7 @@ import Clipboard from 'clipboard';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
|
||||
import { type AmountColor, PresetAmountColor } from '@/core/color.ts';
|
||||
import { KnownFileType } from '@/core/file.ts';
|
||||
|
||||
import logger from '../logger.ts';
|
||||
|
||||
@@ -134,6 +135,64 @@ export function startDownloadFile(fileName: string, fileData: Blob): void {
|
||||
dataLink.click();
|
||||
}
|
||||
|
||||
export function compressJpgImage(file: File, maxWidth: number, maxHeight: number, quality: number): Promise<Blob> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = (event) => {
|
||||
const img = new Image();
|
||||
|
||||
img.onload = () => {
|
||||
let width = img.width;
|
||||
let height = img.height;
|
||||
|
||||
if (width > maxWidth || height > maxHeight) {
|
||||
const scale = Math.min(maxWidth / width, maxHeight / height);
|
||||
width = Math.floor(width * scale);
|
||||
height = Math.floor(height * scale);
|
||||
}
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
if (!ctx) {
|
||||
reject(new Error('failed to get canvas context'));
|
||||
return;
|
||||
}
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
|
||||
canvas.toBlob((blob) => {
|
||||
if (blob) {
|
||||
resolve(blob);
|
||||
} else {
|
||||
reject(new Error('failed to compress image'));
|
||||
}
|
||||
}, KnownFileType.JPG.contentType, quality);
|
||||
};
|
||||
|
||||
img.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
|
||||
if (event.target && event.target.result) {
|
||||
img.src = event.target.result as string;
|
||||
} else {
|
||||
reject(new Error('failed to read file'));
|
||||
}
|
||||
};
|
||||
|
||||
reader.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
|
||||
export function clearBrowserCaches(): Promise<void> {
|
||||
if (!window.caches) {
|
||||
logger.error('caches API is not supported in this browser');
|
||||
|
||||
Reference in New Issue
Block a user