实习日志5

活字格图片上传功能(批量)

这个报错真的恶心,又看不了他服务器源码,接口文档又是错的

活字格V9获取图片失败bug,报错404-CSDN博客

代码BUG记录:

问题:上传多个文件的base64编码被最后一个文件给覆盖导致循环多张图片的base64编码都一样

在代码中,使用了一个循环来加载图片并获取其base64编码。然而,在image.onload回调函数中,使用了i变量,而这个变量在循环结束后可能已经发生了变化。这可能导致所有的回调函数都在循环结束后执行,因此它们都使用了相同的i值。

为了解决这个问题,可以使用一个闭包来保存每次循环的i值。可以通过将i传递给一个立即执行的函数,并在该函数内部返回一个新的函数,该新函数就是image.onload的回调函数。

//imgs=ffc31308-ec72-4268-a977-16f4c366a75f_whitepig.png|3e8582d5-7e4b-4544-8e51-446ba8f70905_blackpig.png
//img[1]=ffc31308-ec72-4268-a977-16f4c366a75f_whitepig.png
//img[2]=3e8582d5-7e4b-4544-8e51-446ba8f70905_blackpig.png
//....
const imgs = Forguncy.Page.getCell("img").getValue();
const imgArray = imgs.split("|");
//遍历imgArray
for (let i = 0; i < imgArray.length; i++) {
    (function(index) {
        var img = `http://${window.location.host}/Forguncy/FileDownloadUpload/Download?file=` + imgArray[index];
        var image = new Image();
        var base64;
        image.src = img;
        console.log("第" + index + "轮次的src:" + image.src);
        image.onload = function () {
            base64 = getBase64Image(image);
            console.log(index + base64);
            Forguncy.modifyTablesData({
                image: {
                    addRows: [
                        {
                            name: getImgName(imgArray[index]),
                            code: imgArray[index],
                            base64: base64,
                            is_identify: false
                        }
                    ],
                }
            });
        }
    })(i);
}


function getBase64Image(img) {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);
    var ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
    var dataURL = canvas.toDataURL("image/" + ext);
    return dataURL;
}

function getImgName(input) {
    var match = input.match(/_([^_]*)(?:\.|$)/);
    var result = match && match[1];
    return result || null;
}

活字格发票识别功能(批量)*待完善

这个改了一下数据库,打算把刚刚上传的图片标记一个false,识别后标为true,之前的图片再加一个past_标记一下,批量识别就只用识别FALSE的文件了

因为要循环的缘故,把后续操作都改成js的形式

代码: 

// 获取当前页面上名称为account的单元格
// 获取当前页面
var page = Forguncy.Page;
var access_token = page.getCell("access_token").getValue();

var invoiceTypeChooseCell = page.getCell("invoice_type_choose");

var invoiceCodeCell = page.getCell("invoice_code");
var invoiceNumCell = page.getCell("invoice_num");
var invoiceDateCell = page.getCell("invoice_date");
var invoiceTypeCell = page.getCell("invoice_type");
var checkCodeCell = page.getCell("check_code");
var totalAmountCell = page.getCell("total_amount");

var imgIdCell = page.getCell("img_id");
var imageBase64Cell = page.getCell("image_base64");
var imgLengthCell = page.getCell("img_length");

var identifyResultCell = page.getCell("identify_result");

var isRepeatCell = page.getCell("is_repeat");

var imageBase64;

for (let i = 0; i < imgLengthCell.getValue(); i++) {
    imageBase64 = imageBase64Cell.getValue();
    InvoiceIdentificationPost();
}

function InvoiceIdentificationPost() {
    //获取单元格的值
    var data = {
        //传入请求地址
        token: access_token,
        imageUrl: imageBase64
    };
    console.log("***发送百度AI*发票识别*请求***");
    Forguncy.Helper.post("customapi/fapiaoapi/vatinvoicebyimg", data,
        function (res) {
            console.log("res:" + res);
            let jsonData = JSON.parse(res);
            if (jsonData.words_result === undefined || jsonData.words_result === null) {
                alert("发送百度AI发票识别请求失败:" + jsonData.error_msg);
                return;
            }
            jsonData = jsonData.words_result;
            console.log(jsonData);

            //获取发票类型
            let invoiceType = invoiceTypeChooseCell.getValue();
            console.log("获取发票类型:" + invoiceType);
            //获取不到,自动识别
            if (invoiceType === "" || invoiceType === null) {
                console.log(jsonData.InvoiceType);
                invoiceType = translateInvoiceType(jsonData.InvoiceType);
            }
            console.log("识别发票类型:" + invoiceType);
            //识别不到
            if (invoiceType === "" || invoiceType === null) {
                console.log("无法自动识别出发票类型!!!");
                return;
            }
            invoiceCodeCell.setValue(jsonData.InvoiceCode);
            invoiceNumCell.setValue(jsonData.InvoiceNum);
            invoiceDateCell.setValue(convertDateFormat(jsonData.InvoiceDate));
            invoiceTypeCell.setValue(invoiceType);
            let checkCode = jsonData.CheckCode;
            /**
             * 处理分类逻辑
             */
            // 发票金额
            // 增值税专票、电子专票、区块链电子发票、机动车销售发票、货运专票填写不含税金额
            // 二手车销售发票填写车价合计
            // 全电发票(专用发票)、全电发票(普通发票)填写价税合计金额
            // 其他类型发票可为空
            if (invoiceType == "elec_invoice_special" || invoiceType == "elec_invoice_normal") {
                console.log("价税合计金额");
                //价税合计金额
                totalAmountCell.setValue(jsonData.AmountInFiguers);
            } else if (invoiceType == "used_vehicle_invoice") {
                console.log("车价合计");
                //车价合计
                totalAmountCell.setValue(jsonData.AmountInFiguers);
            } else {
                console.log("不含税金额");
                // 不含税金额
                totalAmountCell.setValue(jsonData.TotalAmount);
            }
            //invoice_code:全电发票(专用发票)、全电发票(普通发票)此参数可为空
            if (invoiceType != "elec_invoice_special" && invoiceType != "elec_invoice_normal") {
                //其他的类型不能为空
                if (jsonData.InvoiceCode == "" || jsonData.InvoiceCode == null) {
                    alert("发票代码不可为空!!!");
                    return;
                }
            }
            //校验码。填写发票校验码后6位。
            //增值税电子专票、普票、电子普票、卷票、
            //区块链电子发票、通行费增值税电子普通发票此参数必填;
            if (invoiceType == "elec_special_vat_invoice" || invoiceType == "normal_invoice" || invoiceType == "elec_normal_invoice" || invoiceType == "roll_normal_invoice" || invoiceType == "blockchain_invoice" || invoiceType == "toll_elec_normal_invoice") {
                console.log("需要校验码");
                if (checkCode != "" && checkCode != null) {
                    checkCode = getLastSixDigits(checkCode);
                    console.log(checkCode);
                    checkCodeCell.setValue(checkCode);
                } else {
                    alert("校验码不可为空!!!");
                    return;
                }
            } else {
                console.log("不需要校验码");
                checkCodeCell.setValue(checkCode);
            }
            identifyResultCell.setValue(JSON.stringify(jsonData));
        });
    //后续操作
    //判断发票是否重复
    Forguncy.getTableData("invoice", {"invoice_num": page.getCell("invoice_num").getValue()},
        function (data) {
            console.log("发票重复识别");
            isRepeatCell.setValue("重复");
        }, function (errorMessage) {
            isRepeatCell.setValue("未重复");
        });
    //没用重复则添加
    if (isRepeatCell.getValue() === "未重复") {
        Forguncy.modifyTablesData({
            invoice: {
                // 添加操作
                addRows: [{
                    invoice_code: invoiceCodeCell.getValue(),
                    invoice_num: invoiceNumCell.getValue(),
                    invoice_date: invoiceDateCell.getValue(),
                    invoice_type: invoiceTypeCell.getValue(),
                    check_code: checkCodeCell.getValue(),
                    total_amount: totalAmountCell.getValue(),
                    is_repeat: isRepeatCell.getValue(),
                    img_id: imgIdCell.getValue()
                }]
            }
        });
    } else if (isRepeatCell.getValue() === "重复") {
        alert("识别到重复发票,请核对发票信息");
    }
}

//日期格式转换
function convertDateFormat(inputDateString) {
    // 使用正则表达式提取数字
    var numbersArray = inputDateString.match(/\d+/g);
    // 将数字字符串拼接在一起
    var outputDateString = numbersArray.join("");
    return outputDateString;
}


//发票类型自动识别转换
function translateInvoiceType(chineseInvoiceType) {
    var translationMap = {
        //增值税专票、电子专票、区块链电子发票、机动车销售发票、货运专票填写不含税金额
        "电子专用发票": "elec_special_vat_invoice",
        "普通发票(电子)": "elec_normal_invoice",
        "电子普通发票": "elec_normal_invoice",
        "普通发票(卷式)": "roll_normal_invoice",
        "卷式普通发票": "roll_normal_invoice",
        "通行费增值税电子普通发票": "toll_elec_normal_invoice",
        "区块链电子发票": "blockchain_invoice", // 全电发票(专用发票)、全电发票(普通发票)填写价税合计金额
        "全电发票(专用发票)": "elec_invoice_special",
        "电子发票(专用发票)": "elec_invoice_special",
        "全电发票(普通发票)": "elec_invoice_normal",
        "电子发票(普通发票)": "elec_invoice_normal",

        "货运运输业增值税专用发票": "special_freight_transport_invoice",
        "机动车销售发票": "motor_vehicle_invoice", //二手车销售发票填写车价合计
        "二手车销售发票": "used_vehicle_invoice",
        "普通发票": "normal_invoice",
        "专用发票": "special_vat_invoice",
    };

    // 检查输入的中文发票类型是否在映射中,如果是则返回对应的英文翻译,否则返回原始值
    for (var chineseType in translationMap) {
        if (chineseInvoiceType.includes(chineseType)) {
            return translationMap[chineseType];
        }
    }

    // 如果未找到匹配的中文发票类型,则返回空值
    return "";
}

//获取发票校验码后六位数
function getLastSixDigits(str) {
    // 通过正则表达式匹配字符串中的数字
    const matches = str.match(/\d+/g);

    // 如果有匹配到数字
    if (matches) {
        // 获取最后一个匹配到的数字
        const lastNumber = matches[matches.length - 1];

        // 如果数字的长度大于等于六位,则返回后六位
        if (lastNumber.length >= 6) {
            return lastNumber.slice(-6);
        } else {
            // 如果数字的长度小于六位,则直接返回该数字
            return lastNumber;
        }
    } else {
        // 如果没有匹配到数字,则返回空字符串或其他适当的值
        return "";
    }
}

这个代码暂时只能识别一张图片

 

图片预览功能

暂时没啥头绪,不能改html真的难写,建议@活字格给个插入HTML代码的插件

更改数据库(功能已加入代码,还没测试)

关联图片功能 和 查重的记录功能

关联图片功能

查重的记录功能

C#代码更改

从图片URL来请求改成从图片base64编码来请求,还增加了pdf请求的发票识别功能

现在支持图片和PDF形式的发票上传、识别

活字格C#代码调用服务器给百度ai接口发送请求设置-CSDN博客

总结一下:

呃呃,有一种牵一发而动全身的感觉,改个图片识别形式,代码全都改了

1. 修复上传多个文件的base64编码被最后一个文件覆盖的问题:

在图片上传的循环中,通过使用闭包来保存每次循环的i值,确保image.onload回调函数使用正确的i值。这解决了循环多张图片的base64编码都一样的问题。

2. 活字格发票识别功能(批量):

  • 通过循环处理多张图片的发票识别。
  • 使用闭包确保在循环中正确传递imageBase64值,以防止最后一个值覆盖其他图片的问题。
  • 对识别结果进行处理,并根据发票类型分类填充相应的单元格。

3. 改动数据库:

  • 在发票识别后,标记已识别的图片,并将未重复的发票信息添加到数据库中。
  • 实现了查重的记录功能,根据发票号码判断是否重复。

4. C#代码更改:

  • 从图片URL请求改成从图片base64编码请求,增加了对PDF形式的发票上传和识别的功能。

5. 图片预览功能:

  • 目前尚未实现图片预览功能,可能需要活字格提供插入HTML代码的插件来更方便地修改HTML。

总体而言,代码经历了多个方面的修改,包括修复bug、批量处理发票识别、数据库操作、C#代码改动等。需要注意的是,确保在循环中正确处理闭包以防止变量覆盖的问题是关键之一。此外,对于图片预览功能,可能需要进一步探讨或等待相关插件支持。

后续需要的操作:

1.完善批量识别和验真
2.图片预览
3.图片关联识别
4.我捷通的FRID打印机和那个EPC程序还没搞明白嘞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/349796.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

76 C++对象模型探索。多重继承中虚函数表分析

多重继承非重点内容&#xff0c;在实际开发中使用的不多&#xff0c; 这里只是为了知识点的完整&#xff0c;记录一下。 直接上结论。 一个类&#xff0c;如果继承于多个基类&#xff0c;且这个多个基类中有虚函数&#xff0c;那么 这个类 会有多个 虚函数表。 这个 类的对…

THM学习笔记——john

John the Ripper是目前最好的哈希破解工具之一。 John基本语法&#xff1a; john [options] [path to file] john&#xff1a;调用John the Ripper程序。 [path to file]&#xff1a;包含你要尝试破解的哈希的文件&#xff0c;如果它们在同一个目录中&#xff0c;你就不需要命名…

Docker容器基本管理

目录 一、概述 &#xff08;一&#xff09;为什么要用到容器 &#xff08;二&#xff09;docker概念 1.镜像 2.容器 3.仓库 &#xff08;三&#xff09;Docker与虚拟机的区别 &#xff08;四&#xff09;Linux namespace的六大类型 二、安装docker容器引擎 &#xff…

光耦驱动继电器电路图大全

光耦驱动继电器电路图&#xff08;一&#xff09; 注&#xff1a; 1U1-1脚可接12V&#xff0c;也可接5V&#xff0c;1U1导通&#xff0c;1Q1导通&#xff0c;1Q1-30V&#xff0c;线圈两端电压为11.7V. 1U1-1脚不接或接地&#xff0c;1U1不通&#xff0c;1Q1截止&#xff0c;1…

Federated Optimization in Heterogeneous Networks —— Fedprox算法

Federated Optimization in Heterogeneous Networks 1. 论文信息 论文题目: Federated Optimization in Heterogeneous Networks Fedprox算法&#xff0c;plato小项目跑通并理解作者&#xff1a;Tian Li, Anit Kumar Sahu, Manzil Zaheer, Maziar Sanjabi, Ameet Talwalkar, …

使用阿里云的oss对象存储服务实现图片上传(前端vue后端java详解)

一&#xff1a;前期准备&#xff1a; 1.1&#xff1a;注册阿里云账号&#xff0c;开启对象存储oss功能&#xff0c;创建一个bucket&#xff08;百度教程多的是&#xff0c;跟着创建一个就行&#xff0c;创建时注意存储类型是标准存储&#xff0c;读写权限是公共读&#xff09;…

HNU-编译原理-甘晴void学习感悟

前言 熬过煎熬的考试周、复习以及更加煎熬的等成绩&#xff0c;查到成绩的那一刻&#xff0c;心里还是挺开心的。 虽然我没有完全学懂这门课程&#xff0c;但我还是兢兢业业地通过了课程的考试&#xff0c;拿到了这门课程的认可。 记录一下自己对编译原理的学习感悟&#xf…

python使用pyinstaller 快速打包成一个exe程序方案

使用PyInstaller是一种将Python脚本打包成独立可执行文件&#xff08;.exe&#xff09;的方便方法。 以下是一个简单的步骤&#xff0c;以及相关的说明和代码示例&#xff1a; 1.安装PyInstaller: pip install pyinstaller2.在终端中导航到你的Python脚本所在的目录: cd pat…

day32_CSS

今日内容 0 复习昨日 1 css属性 2 盒子模型 【重点】 3 css扩展属性 4 Bootstrap【重点】 0 复习昨日 1 表格标签 table表格里面有tr , (行)行内有单元格,td行合并,rowspan列合并,colspan 2 写出input标签type属性的值 文本框 text 密码框 password 单选框 radio 复选框 checkb…

在线教育系统开发:构建现代化学习平台

随着科技的迅速发展&#xff0c;在线教育系统在教育领域扮演着越来越重要的角色。本文将深入探讨在线教育系统的开发过程&#xff0c;涉及关键技术和代码实现。 技术选型 在开始开发之前&#xff0c;我们首先需要选择适合在线教育系统的技术栈。以下是一些常见的技术选项&am…

使用宝塔面板部署Nuxt3项目到云服务器上

1、前期准备 1&#xff09;准备一台云服务器2&#xff09; 在云服务器上安装宝塔面板软件应用&#xff0c;安装步骤可参考博客:使用宝塔面板部署Node.jsMysql服务和Vue3-Admin项目到云服务器上 2、进行Nuxt3项目的部署 1)、本地执行打包命令&#xff0c;输出以下两个文件目录…

Android系统开发之TimeZoneDetectorService浅析--上

一&#xff1a;问题描述&#xff1a; 客户有一个关闭通话功能的需求&#xff0c;根据MTK的配置方法关闭了大概8个宏开关后&#xff0c;实现通话功能&#xff0c;但是导致插好sim卡开机后&#xff0c;时间和时区不能更新的问题。 二&#xff1a;问题分析&#xff1a; (1).MTK…

AF700 NHS 酯,AF 700 Succinimidyl Ester,一种明亮且具有光稳定性的近红外染料

AF700 NHS 酯&#xff0c;AF 700 Succinimidyl Ester&#xff0c;一种明亮且具有光稳定性的近红外染料&#xff0c;AF700-NHS-酯&#xff0c;具有水溶性和 pH 值不敏感性 您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;AF700 NHS 酯&#xff0c;AF 700 Succinimid…

深度视觉目标跟踪进展综述-论文笔记

中科大学报上的一篇综述&#xff0c;总结得很详细&#xff0c;整理了相关笔记。 1 引言 目标跟踪旨在基于初始帧中指定的感兴趣目标( 一般用矩形框表示) &#xff0c;在后续帧中对该目标进行持续的定位。 基于深度学习的跟踪算法&#xff0c;采用的框架包括相关滤波器、分类…

pcl+vtk(十四)vtkCamera相机简单介绍

一、vtkCamera相机 人眼相当于三维场景下的相机&#xff0c; VTK是用vtkCamera类来表示三维渲染场景中的相机。vtkCamera负责把三维场景投影到二维平面&#xff0c;如屏幕、图像等。 相机位置&#xff1a;即相机所在的位置&#xff0c;用方法vtkCamera::SetPosition()设置。 相…

力扣hot100 腐烂的橘子 BFS 矢量数组 满注释版

Problem: 994. 腐烂的橘子 文章目录 思路复杂度&#x1f49d; Code 思路 &#x1f468;‍&#x1f3eb; 参考 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) &#x1f49d; Code class Solution {int[] dx new int[] { 0, 1, 0, -1 };// 行 矢…

如何快速搭建实用的爬虫管理平台

目录 一、前言 二、选择合适的爬虫框架 三、搭建数据库 步骤1 步骤2 步骤3 四、搭建Web服务器 步骤1 步骤2 步骤3 步骤4 五、管理爬虫 六、总结 一、前言 爬虫是互联网数据采集的关键工具&#xff0c;但是随着数据量的增加和需求的多样化&#xff0c;手动运行和管…

SpringMVC-HttpMessageConverter 报文信息转化器

文章目录 HttpMessageConverter一、概念二、RequestBody三、RequestEntity四、 ResponseBody1.返回JSON格式的字符串 五、RestController六、ResponseEntity HttpMessageConverter 一、概念 报文信息转化器&#xff0c;将请求报文转化为Java对象&#xff0c;或将Java对象转化…

【图像分割】【深度学习】Windows10下UNet代码Pytorch实现与源码讲解

【图像分割】【深度学习】Windows10下UNet代码Pytorch实现与源码讲解 提示:最近开始在【医学图像分割】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【图像分割】【深度学习】Windows10下UNet代码Pytorch实现与源码讲解前言UNet模型运行环境搭…

解决 Required Integer parameter ‘uid‘ is not present

1.原因分析 后端没接收到uid可能是前端没传递uid也可能是前端传递了uid&#xff0c;但是传递方式与后端接收方式不匹配&#xff0c;导致没接收到更大的可能是因为后端请求方式错了。比如&#xff1a; 2.解决方案 先确定前端传参方式与后端请求方式是匹配的后端get请求的话…
最新文章