
在日常开发中,我们经常需要处理图片中的文字信息提取需求,尤其是财务、电商等领域,对支付截图、账单图片的自动化解析需求日益增长。本文将带你从零实现一个智能图片识别工具,用户上传交易截图后,系统自动提取金额、时间、商户、退款状态等核心字段,并将"实付金额"高亮标红展示。
一、项目背景与功能概览
1.1 解决什么问题?
-
手动录入交易信息效率低、易出错
-
不同支付平台截图格式不统一
-
需要快速提取实付金额、退款情况等关键数据
1.2 核心功能
-
支持拖拽/点击上传图片(JPG/PNG/WebP等,≤10MB)
-
调用后端OCR+解析接口,返回结构化交易数据
-
将实付金额红色大字号突出显示,退款信息单独标注
-
响应式布局,适配PC与移动端
1.3 技术栈
-
前端:原生HTML5/CSS3/JavaScript (ES6+)
-
交互:拖拽上传、XMLHttpRequest进度监听、Fetch API
-
后端接口 :
/big/upload_image_file(上传) +/big/upload_image_and_analyze(识别) -
认证:固定AccessToken(示例中硬编码,生产环境建议加密存储)
二、界面设计与核心布局
页面采用左右分栏设计,左侧上传与预览,右侧展示识别结果。
2.1 左侧面板:上传区
<div class="upload-area" id="uploadArea">
<div class="upload-icon">📤</div>
<div>点击或拖拽图片到此区域上传</div>
<div style="font-size: 12px;">支持 JPG、PNG、GIF、WebP,最大10MB</div>
</div>
<img id="preview" class="preview-image">
-
支持
click触发文件选择 +dragover/drop拖拽上传 -
预览图片,显示文件名及大小
-
进度条展示上传进度(基于XHR的upload事件)
2.2 右侧面板:结果展示区
动态生成<table>展示识别结果,其中实付金额行独立高亮:
.amount-red {
font-size: 28px;
font-weight: 800;
color: #e74c3c;
}
.highlight-row {
background: #fff5f5;
border-left: 4px solid #e74c3c;
}
三、核心逻辑实现
3.1 文件选择与校验
function handleFileSelect(file) {
if (!file.type.startsWith('image/')) {
showMessage('请选择图片文件', 'error');
return;
}
if (file.size > 10 * 1024 * 1024) {
showMessage('图片大小不能超过10MB', 'error');
return;
}
currentFile = file;
// 预览 + 清空上次结果
const reader = new FileReader();
reader.onload = (e) => { preview.src = e.target.result; };
reader.readAsDataURL(file);
}
3.2 上传图片(带进度)
使用XMLHttpRequest实现进度监听,返回服务器存储的文件路径。
function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
const percent = (e.loaded / e.total) * 100;
updateProgress(percent);
});
xhr.onload = () => {
const resp = JSON.parse(xhr.responseText);
if (resp.code === '200' && resp.object) {
resolve(resp.object); // 返回文件路径
} else reject(new Error(resp.message));
};
xhr.open('POST', UPLOAD_URL);
xhr.send(formData);
});
}
3.3 调用识别接口
async function callAnalyzeAPI(imagePath) {
const requestBody = {
accessToken: ACCESS_TOKEN, // 固定token
imagePath: imagePath
};
const response = await fetch(ANALYZE_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestBody)
});
return await response.json();
}
3.4 结果解析与高亮渲染
后端返回的object字段包含交易详情(可能是JSON字符串或对象)。重点处理实付金额:
-
优先取
actualPaymentAmount -
若无,则根据
payment_amount - refund_amount计算 -
支付金额
payment_amount正常显示,不标红 -
若存在退款,额外提示退款信息
function displayResult(result) {
let data = typeof result.object === 'string'
? JSON.parse(result.object)
: result.object;
let actualAmount = data.actualPaymentAmount;
if (actualAmount === undefined && data.payment_amount) {
actualAmount = data.has_refund
? data.payment_amount - (data.refund_amount || 0)
: data.payment_amount;
}
let html = `<table class="result-table">
<tr style="background:#fff6f0;">
<td>💰 实付金额</td>
<td class="amount-red">${formatMoney(actualAmount)}</td>
</tr>
<tr>
<td>💵 支付金额</td>
<td class="amount-normal">${formatMoney(data.payment_amount)}</td>
</tr>
... // 其他字段
</table>`;
resultContent.innerHTML = html;
}
四、关键技术点解析
4.1 拖拽上传
监听dragover阻止默认事件,drop中获取dataTransfer.files。
4.2 进度条模拟
使用<div class="progress-bar">内嵌动态宽度<div>,通过xhr.upload.onprogress更新宽度百分比。
4.3 跨域与接口调试
-
后端地址为
http://183.61.241.8:1005,需确保前端请求不跨域或被CORS策略拦截 -
建议在本地开发时使用代理或后端配置CORS
4.4 安全性提醒
示例中AccessToken硬编码在脚本中,仅适用于演示。生产环境应将Token存储在HttpOnly Cookie或后端代理中。
五、运行效果展示
-
上传图片 :点击或拖拽支付截图
https://via.placeholder.com/400x200?text=Upload+Preview -
点击识别:显示加载动画,上传进度条从0%→100%
-
结果展示:
-
实付金额:¥89.00(红色大字号)
-
支付金额:¥100.00(黑色常规)
-
若有退款,额外展示退款金额与时间,并给出提示"实付金额低于原支付金额"
-
六、优化建议与扩展方向
6.1 可优化的点
-
添加图片压缩(前端压缩后上传,节省带宽)
-
支持批量识别(循环上传+并发控制)
-
增加识别历史记录(IndexedDB或localStorage)
6.2 扩展为通用OCR工具
将后端接口通用化,可提取身份证、发票、车牌等结构化信息,只需修改提示词或解析模板。
七、总结
本文实现了一个轻量级但功能完整的图片识别前端工具,核心难点在于:
-
拖拽上传与进度反馈
-
异步流程控制(上传→识别→渲染)
-
动态高亮渲染实付金额
完整的HTML/CSS/JS代码已在文中给出,你只需修改后端地址和Token即可接入自己的识别服务。希望这篇文章能帮助你快速搭建图片识别类应用的前端界面,提升数据录入效率。