最近做了一个E9和紫光高拍仪集成的开发,经过探索,初见成效,做下记录,也希望能对大家有所帮助。
采用的方式为base64上传图片,将图片上传到服务器物理路径后,调用E9生成到知识模块中,并更新到流程表单中。
可以通过简单配置方式,适用于多流程。
1、实现效果
说明:高拍仪型号为紫光G750。其它型号产品是否支持,暂不了解,大家可以参考尝试
2、安装紫光的sdk
安装紫光的SDK后,桌面会有一个文件夹的快捷方式。
打开快捷方式,里边会有案例demo和说明文档,可以根据自己项目的实际参考demo案例开发。
3、自定义前段js代码
3.1、高拍仪操作的html页面
页面展示效果
对应的html代码
<!DOCTYPE html>
<html>
<head><meta charset=utf-8 /><title>高拍仪系统</title><!-- 这几个是为了页面布局 不影响功能--><script class="jsbin" src="js/jquery-1.7.2.min.js"></script><link rel="stylesheet" type="text/css" href="css/easyui.css"><link rel="stylesheet" type="text/css" href="css/viewer.min.css"><link rel="stylesheet" type="text/css" href="css/style.css"><script type="text/javascript" src="js/jquery.easyui.min.js"></script><!--script type="text/javascript" src="js/main.js"></script--><script type = "text/javascript" src= "js/Concurrent.Thread.js"></script><!-- 下面三个是必须的js --><script src="js/globeVar.js" type="text/javascript" charset="utf-8"></script><script src="js/mainH5.js" type="text/javascript" charset="utf-8"></script><script src="js/WebSocket.js" type="text/javascript" charset="utf-8"></script><script src="js/wn_H5scan.js" type="text/javascript" charset="utf-8"></script><script src="js/viewer.min.js" type="text/javascript" charset="utf-8"></script><style>article, aside, figure, footer, header, hgroup,menu, nav, section { display: block; }.west{width:200px;padding:10px;}.north{height:30px;}.baseimg{width:128 !important;height:96 !important;;margin-bottom: 0;}.active {background: #00bdea !important;text-align: center;width: 128px;}li{list-style:none;}</style>
</head>
<body class="easyui-layout" onload="load()" onunload="wn_unload()"><div region="north" split="true" border="false" height="300" style="overflow: hidden; height: 300px;z-index:0;#7f99be repeat-x center 50%;line-height: 20px;color: #fff; font-family: Verdana, 微软雅黑,黑体"><span style="padding-left:10px; font-size: 16px; "><img src="images/blocks.gif" width="20" height="20" align="absmiddle" /> 高拍仪系统</span><br/><div style=" position: relative;"><img id="myCanvas" width='320' height='240' align="center"style="position: absolute;left:50%;top:10%;margin-left: -160px; /* 宽度的一半 */background-color: black;display:inline margin:0 auto" src="images/load1.gif"/></div><div style="display: none;"><img id="baseimghidden" width="20" height="20" align="absmiddle" /> 高拍仪系统</div>
</div>
<div data-options="region:'west',split:true" title="图片列表" style="width:200px;"><ul id="parentUl"></ul>
</div><div region="center" title=""><div class="easyui-tabs" fit="true" border="false" id="tabs"><div title="基础功能"><div style="margin-left: 20px;"><p>
<!-- <span>存储路径:</span>--><input type="hidden" id="saveText" value="D:\tmp\" style="margin-left:5px;width: 150px;text-align: left;"/>
<!-- <button οnclick="Capture()">拍照</button>--><input type="hidden" id="autoclick"/><button id="pz" onclick="wn_CaptureBase64()" style="margin-left: 10px;">拍照</button><button onclick="wn_uploadbase64()" style="margin-left: 10px;">上传</button>
<!-- <button οnclick="CaptureBase64Ex()" style="margin-left: 10px;">图片转Base64(本地不存图)</button>-->
<!-- <button οnclick="DeleteFile()" style="margin-left: 10px;">删除文件</button>-->
<!-- <button οnclick="OpenFile()" style="margin-left: 10px;">查看文件</button>-->
<!-- <p>-->
<!-- <span style="margin-left:5px;">要删除的文件夹路径:</span>-->
<!-- <input type="text" id="Distory" value="C:\tmp" style="margin-left:5px;width: 150px;text-align: left;"/>-->
<!-- <button οnclick="RemoveDictory()">删除文件夹内文件</button>-->
<!-- <button οnclick="FindJPGFile()" style="">遍历文件夹</button>--><p><div style="display: none"><span>设置DPI</span><span style="margin-left: 20px;">X:</span><input type="text" id="dpix" value="300" style="width: 50px;"/><span style="margin-left: 20px;">Y:</span><input type="text" id="dpiy" value="300" style="width: 50px;"/><button onclick="DPISet()" style="margin-left: 0px;">设置DPI</button><p><span style="margin-left: 0px;">JPG压缩值:</span><input type="text" id="jpg" value="100" /><button onclick="JPGQSet()" style="margin-left: 10px;">设置JPG压缩率</button></div><p><div class="sideDiv"><span>手动裁切</span><span style="margin-left: 10px;">左</span><input type="text" value="0" id="left" style="margin-left:5px;width:50px;"/><span style="margin-left: 10px;">上</span><input type="text" value="0" id="top" style="margin-left:5px;width: 50px;"/><span style="margin-left: 10px;">右</span><input type="text" value="100" id="right" style="margin-left:5px;width: 50px;"/><span style="margin-left: 10px;">下</span><input type="text" value="100" id="bottom" style="margin-left:5px;width: 50px;"/><button onclick="CropZoneSet()" style="margin-left: 10px;">设置裁切区域</button></div><br /><button onclick="closeDev()">关闭摄像头</button><button onclick="openDev()">开启摄像头</button><button onclick="DevSetting()">视频效果</button></div><div style="padding-top: 20px;margin-left: 20px; "><span >设备</span><select id="device" ></select><span >分辨率</span><select id="resoultion" ></select><span >视频格式</span><select id="videoStyle" ></select></div><div style="margin-top: 20px; margin-left: 20px; "><span >旋转类型</span><select onchange="SetRotationStyle()" id="rotationStyle"><option >不旋转</option><option >90</option><option >180</option><option >270</option></select><div style="display: inline-block;margin-left: 20px;"><span >裁切类型</span><select onchange="SetCutStyle()" id="cutStyle" ><option >不裁切</option><option >单图裁切</option><option >多图裁切</option><option >单图裁切 & 补边</option><option >书本页</option></select></div><span>图像处理</span><select onchange="setImageAdjust()" id ="imageAdjust"><option >无效果</option><option >文档增强</option><option >彩色增强</option><option >灰色</option><option >黑白</option><option >油画</option><option >怀旧</option><option >素描</option><option >边缘照亮</option><option >蓝冷</option><option >马赛克</option><option >模糊</option></select></div><!-- <div style="margin-top: 20px; margin-left: 20px; ">-->
<!-- <button οnclick="continuCapture()">连拍</button>-->
<!-- <button οnclick="timeCapture()">定时连拍</button>-->
<!-- <button οnclick="StopAutoCapture()">停止连拍</button>-->
<!-- <br/>-->
<!-- <br/>-->
<!-- <progress id="autoCaptureProgress" value="0" max="100">-->
<!-- </progress>--><!-- </div>--><!-- <div style="margin-top: 20px; margin-left: 20px; ">-->
<!-- <span>麦克风</span>-->
<!-- <select id = "Microphone">-->
<!-- </select>-->
<!-- <span>录像格式</span>-->
<!-- <select id="VideoType">-->
<!-- </select>-->
<!-- <span>音量</span>-->
<!-- <input type = "text" id = "voice" value = "0" style="margin-left:5px;width:50px;">-->
<!-- <br/>-->
<!-- <br/>-->
<!-- <span>存储路径</span>-->
<!-- <input type="text" id="SaveVieoText" value = "C:\tmp\Video.AVI" style="margin-left:5px;width: 150px;text-align: left;"/>-->
<!-- <button οnclick="StartVideo()">开始录像</button>-->
<!-- <button οnclick="StopVideo()">停止录像</button>-->
<!-- </div>--><!-- <div style="margin-top: 20px; margin-left: 20px; ">-->
<!-- <HR align=left width=100% color=#987cb9 SIZE=1>-->
<!-- <span>添加水印</span>-->
<!-- <button οnclick="AddWaterMark()">添加水印</button>-->
<!-- <br/>-->
<!-- <br/>-->
<!-- 内容<input type="text" id="WaterMarkMsg" value = "高拍仪" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 位置(0~8)<input type="text" id="WaterMarktype" value = "0" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 字体尺寸<input type="text" id="WaterMarkfontSize" value = "26" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- <br/>-->
<!-- <br/>-->
<!-- 字体<input type="text" id="WaterMarkfont" value = "宋体" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 是否斜体(0/1)<input type="text" id="WaterMarkfItalic" value = "0" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 是否下划线(0/1)<input type="text" id="WaterMarkfUnderline" value = "0" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- <br/>-->
<!-- <br/>-->
<!-- 是否粗体(0/1)<input type="text" id="WaterMarkfWeight" value = "1" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 角度(0~360)<input type="text" id="WaterMarkangle" value = "92.5" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 透明度(0~100)<input type="text" id="WaterMarktransparent" value = "53.5" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- <br/>-->
<!-- <br/>-->
<!-- 红(0~255)<input type="text" id="WaterMarkcolorR" value = "255" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 绿(0~255)<input type="text" id="WaterMarkcolorG" value = "0" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 蓝(0~255)<input type="text" id="WaterMarkcolorB" value = "0" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 是否开启(0/1)<input type="text" id="WaterMarkisAvailabel" value = "1" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- <HR align=left width=100% color=#987cb9 SIZE=1>-->
<!-- </div>--><!-- <div style="margin-top: 20px; margin-left: 20px;">-->
<!-- <HR align=left width=100% color=#987cb9 SIZE=1>-->
<!-- <button οnclick="SetVideoParameter()">设置视频参数</button>-->
<!-- <br/>-->
<!-- 参数一<input type="text" id="VideoSetPara1" value = "1" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 参数二<input type="text" id="VideoSetPara2" value = "4" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 属性值<input type="text" id="VideoSetting" value = "-3" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- 自动/手动(1/2)<input type="text" id="IsVideoSetAuto" value = "2" style="margin-left:5px;width: 50px;text-align: left;"/>-->
<!-- <HR align=left width=100% color=#987cb9 SIZE=1>-->
<!-- </div>--></div><!-- <div title="人脸识别" style="margin-left:20px">-->
<!-- <h3>人脸识别模块</h3>-->
<!-- <div>-->
<!-- <button οnclick="InitFaceSDK()">初始化人脸SDK</button>-->
<!-- <button οnclick="UinitFaceSDK()">反初始化人脸SDK(需要先关闭视频流)</button>--><!-- <input type="checkbox" id="FaceCrop" οnchange="FaceCropChanged()">人脸框</input>-->
<!-- <input type="checkbox" id="LiveBody" οnchange="LiveBodyChanged()">活体</input>--><!-- <br />-->
<!-- <br />-->
<!-- <label>图片路径1</label>-->
<!-- <input type="text" id="imgOne" value="C:\\temp\\1.jpg"/>-->
<!-- <button οnclick="comparePic()">匹配</button>-->
<!-- <button οnclick="compareVideo()">比对视频(图片1路径)</button>-->
<!-- <br />-->
<!-- <br />-->
<!-- <label>图片路径2</label>-->
<!-- <input type="text" id="imgTwo" value="C:\\temp\\2.jpg"/>-->
<!-- <br />-->
<!-- <br />--><!-- </div>-->
<!-- </div>--><!-- <div title="指纹">--><!-- <div>-->
<!-- <p></p>-->
<!-- <button οnclick="InitFingerData() " style="margin-left: 10px;">初始化指纹仪</button>-->
<!-- <button οnclick="UinitFingerData()" style="margin-left: 10px;">反初始化指纹仪</button>--><!-- <p>-->
<!-- <button οnclick="GetFingerPic(1)" style="margin-left: 10px;">采集指纹1</button>-->
<!-- <button οnclick="GetFingerPic(2)" style="margin-left: 10px;">采集指纹2</button>-->
<!-- <p>-->
<!-- <button οnclick="ComperaFingerPic()" style="margin-left: 10px;">对比指纹1和指纹2</button>-->
<!-- </div>--><!-- </div>-->
<!-- <div title="读卡">-->
<!-- <div style="float: left; margin-left: 10px;">-->
<!-- <p>-->
<!-- <span>二代证头像路径:</span>-->
<!-- <input type = "text" id = "HeadPath" value = "C:\temp\Head.bmp">-->
<!-- <p>-->
<!-- <button οnclick="ReadIDCard()" >读取二代证</button>-->
<!-- <p>-->
<!-- <button οnclick="ReadBankCard()" >读取银行卡</button>--><!-- <p>-->
<!-- <button οnclick="ReadMagneticCard()" >读取磁条卡</button>--><!-- <p>-->
<!-- <button οnclick="ReadSBKCard()" >读取社保卡</button>-->
<!-- </div>-->
<!-- <img id = "head" src = "images/Head.bmp" style=" float: left; margin-left:100px"/>-->
<!-- </div>--><!-- <div title="图像合并">--><!-- <table border="0" width="100%" >-->
<!-- <tr>-->
<!-- <td width="85" height="20">生成文件路径:</td>-->
<!-- <td><input type="text" id="pdftext" value="C:\tmp\" style="margin-left:5px;width: 150px;text-align: left;"/></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td width="85" height="20">编号</td>-->
<!-- <td height="10%">图像路径</td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><div id="Div2"></div></td>-->
<!-- <td id="tdRemove"><div id="uploadContent" width="100%"></div></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><a href="javascript:addFile()">添加文件</a></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td><input type="button" value="合并PDF" id="CombinePDF" οnclick="CombineFile()"></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td>-->
<!-- <select οnchange="SetCombineType()" id="CombineType" >-->
<!-- <option >上下合并</option>-->
<!-- <option >左右合并</option>-->
<!-- </select>-->
<!-- </td>-->
<!-- <td><input type="button" value="图像合并" id="CombinePicture" οnclick="CombinePicture()"></td>-->
<!-- </tr>-->
<!-- </table>--><!-- </div>-->
<!-- <div title="Internet">-->
<!-- <p>-->
<!-- <span>存储路径:</span>-->
<!-- <input type="text" id="UploadsaveText" value="C:\tmp\" style="margin-left:5px;width: 150px;text-align: left;"/>-->
<!-- <p>-->
<!-- <span style="margin-left:5px;">HTTP文件上传url路径:</span>-->
<!-- <input type="text" id="urlText" value="http://192.168.231.136:8088/api/weavernorth/scan/uploadFile" style="margin-left:5px;width: 370px;text-align: left;"/>-->
<!-- <button οnclick="HttpUpload(1)" style="margin-left: 10px;">文件上传</button>-->
<!-- <p>-->
<!-- <a target="_blank" href="http://121.52.219.174:8088/Uploader/index.jsp" >链接服务器,查看上传结果</a>-->
<!-- PS:121.52.219.174:8088此服务器允许HTTP上传.jpg .bmp文件,其它格式可能失败。-->
<!-- <p>-->
<!-- <span style="margin-left:5px;">FTP文件上传地址:</span>-->
<!-- <input type="text" id="FtpAddressText" value="192.168.1.74" style="margin-left:5px;width: 370px;text-align: left;"/>-->
<!-- <button οnclick="HttpUpload(2)" style="margin-left: 10px;">FTP文件上传</button>-->
<!-- <P>-->
<!-- <span style="margin-left: 20px;" >用 户 名:</span>-->
<!-- <input type="text" style="width: 50px;" id="user" value="admin"/>-->
<!-- <span style="margin-left: 20px;">密 码:</span>-->
<!-- <input type = "text" style="width: 50px;" id="pwd" value="123456">-->
<!-- <span style="margin-left: 20px;">端 口:</span>-->
<!-- <input type = "text" style="width: 50px;" id="iport" value="21">-->
<!-- <span style="margin-left: 20px;">创 建 路 径:</span>-->
<!-- <input type = "text" style="width: 50px;" id="floder" value="">-->
<!-- </div>-->
<!-- <div title="识别">-->
<!-- <table border="0" width="100%" >-->
<!-- </p>-->
<!-- <tr >-->
<!-- <td><input type="button" value="初始化" id="RECInit" οnclick="InitOCR()"></td>-->
<!-- <td width="120" >识别文件路径:</td>-->
<!-- <td colspan="3"><input type="text" id="OCR_Pathtext" value="" style="margin-left:5px;width: 150px;text-align: left;"/></td>-->
<!-- </tr>-->
<!-- <tr height="20"></tr>-->
<!-- <tr >-->
<!-- <td width="120">保存目录:</td>-->
<!-- <td colspan="3"><input type="text" id="OCR_SavePathtext" value="D:\\" style="margin-left:5px;width: 150px;text-align: left;"/></td>-->
<!-- </tr>-->
<!-- <tr height="20"></tr>-->
<!-- <tr >-->
<!-- <td>文本识别:</td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td colspan="2">-->
<!-- 语 言:-->
<!-- <select style = "width:160;" name = "language" id = "language" onchange = "">-->
<!-- </select>-->
<!-- </td>-->
<!-- <td colspan="2" >-->
<!-- 导出类型:-->
<!-- <select style = "width:160;" name = "filetype" id = "filetype" onchange = "">-->
<!-- <option value=".doc">doc</option>-->
<!-- <option value=".docx">docx</option>-->
<!-- <option value=".pdf">pdf</option>-->
<!-- <option value=".txt">txt</option>-->
<!-- <option value=".xls">xls</option>-->
<!-- </select>-->
<!-- </td>-->
<!-- <td><input type="button" value="识别单张到文本" id="RecToFile" οnclick="RecToFile(1)" style = "width:120; text-align:center"></td>-->
<!-- <td><input type="button" value="识别单张成文字" id="RecToString" οnclick="RecToFile(2)" style = "width:120; text-align:center"></td>-->
<!-- </tr>-->
<!-- <tr height="20"></tr>-->
<!-- <tr >-->
<!-- <td colspan="5">Barcode识别:</td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td colspan="2"><input type="button" value="Barcode识别" id="coderRecBarcode" οnclick="coderRecBarcode()"></td>-->
<!-- </tr>--><!-- <tr>-->
<!-- <td colspan="2">-->
<!-- 条码类型:-->
<!-- <select style = "width:160;" name = "codetype" id = "codetype" onchange = "">-->
<!-- <option value="1">条码</option>-->
<!-- <option value="2">二维码</option>-->
<!-- </select>-->
<!-- </td>-->
<!-- <td><input type="button" value="条码/二维码识别ocr" id="RecBarcode" οnclick="RecBarcode()" style = "width:120; text-align:center></td>-->
<!-- </tr>-->
<!-- <tr height="20"></tr>-->
<!-- <tr>-->
<!-- <td colspan="5">-->
<!-- 识别结果:-->
<!-- </td>-->
<!-- <tr height="30%">-->
<!-- <td colspan="5">-->
<!-- <textarea id="Msg" style="width:100%;height:100%;">-->
<!-- </textarea>-->
<!-- </td>-->
<!-- </tr>-->
<!-- </tr>-->
<!-- </table>--><!-- </div>-->
<!-- <div title="手写板">-->
<!-- <input type="button" value="初始化" οnclick="InitSign()" style = "width:120; text-align:center">-->
<!-- <input type="button" value="反初始化" οnclick="UinitSign()" style = "width:120; text-align:center">-->
<!-- <input type="button" value="开始签名" id="BeginSign" οnclick="BeginSign()" style = "width:120; text-align:center">-->
<!-- <input type="button" value="获得签名" id="GetSign" οnclick="GetSign()" style = "width:120; text-align:center">-->
<!-- <input type="button" value="结束签名" id="EndSign" οnclick="EndSign()" style = "width:120; text-align:center">-->
<!-- </div>-->
<!-- <div title="IC卡" id="nav">-->
<!-- <input type = "button" value = "测试IC卡" id = "TestIC" οnclick=window.open("./SSCardDriverAB.html") style = "width:120; text-align:center">-->
<!-- </div>--></div>
</div>
<!--div region="west" class="west" title="菜单">
<ul id="tree"></ul>
</div--><div style="text-align:center;margin:50px 0; font:normal 14px/24px 'MicroSoft YaHei';"><p>适用浏览器:IE10、360、FireFox、Chrome、Safari、Opera、傲游、搜狗、世界之窗.</p>
</div>
</body>
</html>
3.2、wn_H5scan.js
封装了一些处理操作的js
//自定义的base64拍照
function wn_CaptureBase64() {CaptureBase64Ex();setTimeout(function () {console.log("延时执行获取照片")var img_base64_src = $("#baseimghidden").attr("src");//console.log("延时获取的src=", img_base64_src)if ('' != img_base64_src && img_base64_src != undefined && img_base64_src != 'data:image/png;base64,') {wn_addlist("parentUl", img_base64_src);}}, 2000);
}//左侧图片的预览
function wn_showpicture(obj) {var options = {title: false,inline: false,button: true,url: 'data-original',fullscreen: true,zIndex: 3018,zoomRatio: 0.5,toolbar: false,tooltip: true,rotatable: true,show: function () {viewer.update();}};var viewer = new Viewer(obj, options);
}//左侧图片列表的删除动作
function wn_imgdelete(obj) {$(obj).parent().remove();
}//将图片添加到左侧列表中
function wn_addlist(obj, src) {//console.log("list-src", src);var time = new Date();var checktime = time.getHours();var title = time.getYear() + time.getMonth() + time.getDate() + time.getDate() + time.getTime() + ".png";var ul = document.getElementById(obj);var li = document.createElement("li");var img = document.createElement("img");img.setAttribute("width", "128");img.setAttribute("height", "96");img.setAttribute("id", "newImg");img.setAttribute("alt", "");img.setAttribute("title", title);img.onclick = function () {wn_showpicture(this)};img.src = src;var div = document.createElement("div");div.onclick = function () {wn_imgdelete(this);}div.textContent = "删除";div.setAttribute("class", "active");li.appendChild(img);li.appendChild(div);ul.appendChild(li);clearTimeout(timer);;
}//页面关闭时执行的操作
function wn_unload() {//执行高拍仪的卸载操作unload();//流程表单页面刷新一次parent.WfForm.reloadPage();
}//获取url中的参数
function getUrlParam(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象var r = window.location.search.substr(1).match(reg); //匹配目标参数if (r != null) return unescape(r[2]);return null; //返回参数值
}//base64上传到后端
async function wn_uploadbase64() {//setTimeout(function () {parent.GlobalStart();var jsonArr = new Array();$("#parentUl li").each(function () {//获取对应img的srcvar base64img = $(this).find("img").attr("src");if (base64img != undefined) {var imgObj = {};imgObj.baseimg = base64img.split('base64,')[1];jsonArr.push(imgObj);}});var requestid = getUrlParam("requestid");var params = {"imglist": jsonArr,"requestid": requestid}//请求后端,传入信息await jQuery.ajax({type: "POST",data: JSON.stringify(params),contentType: "application/json",cache: false, //不设置缓存processData: false, // 不处理数据dataType: "text",url: "/api/weavernorth/scan/uploadFile",//后端接口async: true,success: function (data) {var result = JSON.parse(data);if (result.code == "S") {//parent.GlobalDestroy();parent.WfForm.showConfirm("处理成功,是否继续操作?", function () {//继续操作,清空之前的拍照列表$("#parentUl li").each(function () {$(this).remove();});}, function () {//取消操作//卸载高拍仪unload();parent.WfForm.reloadPage();}, {title: "信息确认", //弹确认框的title,仅PC端有效okText: "确认", //自定义确认按钮名称cancelText: "取消" //自定义取消按钮名称});} else {//parent.GlobalDestroy();parent.weaJs.alert("上传失败,原因:" + result.msg);}},error: function () {//parent.GlobalDestroy();parent.weaJs.alert("上传失败!");}})//}, 12000);parent.GlobalDestroy();
}
3.3、后端上传附件的代码
package com.engine.weavernorth.scan;import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.engine.weavernorth.scan.util.ScanUtil;
import com.engine.weavernorth.scan.util.UploadUtil;
import com.engine.weavernorth.scan.util.WorkflowUtil;
import sun.misc.BASE64Decoder;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.integration.logging.Logger;
import weaver.integration.logging.LoggerFactory;import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;/*** @Classname UploadFileAction* @Description TODO* @Version 1.0.0* @Date 2023/2/22 9:46* @Created by 刘立华*/public class UploadFileAction {private Logger log = LoggerFactory.getLogger(UploadFileAction.class);private BaseBean baseBean = new BaseBean();@POST@Path("/uploadFile")@Produces({"text/plain"})@Consumes(MediaType.APPLICATION_JSON)public String upload(String jsonparam, @Context HttpServletResponse response) {JSONObject returnObj = new JSONObject();log.info("传入的扫描数据:" + jsonparam);if (!JSONUtil.isJsonObj(jsonparam)) {returnObj.put("code", "E");returnObj.put("msg", "传入数据非json格式");return returnObj.toString();}JSONObject paramObj = JSONUtil.parseObj(jsonparam);//usr/weaver/ecology/weavernorth/scanimg/";//文件写入系统硬盘的路径String filesavepath = baseBean.getPropValue("wn_scan", "filesavepath");//图片后缀名String imgsuffix = baseBean.getPropValue("wn_scan", "imgsuffix");//文件命名 存储的文件名String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS") + imgsuffix;JSONArray imglist = paramObj.getJSONArray("imglist");for (int j = 0; j < imglist.size(); j++) {JSONObject o = (JSONObject) imglist.get(j);String baseimg = o.getStr("baseimg");log.info("接收到的base64:" + baseimg);base64ToFile(baseimg.replaceAll(" ", "+"), filesavepath, fileName);//判断文件是否存在boolean exist = FileUtil.exist(new File(filesavepath + fileName));//请求idString requestid = paramObj.getStr("requestid");//获取对应的workflowidString workflowid = WorkflowUtil.getWorkflowidByRequestid(requestid);//说明附件没有存到硬盘上if (!exist) {returnObj.put("code", "E");returnObj.put("msg", "OA上传附件到服务器失败!");return returnObj.toString();}//文件成功放在硬盘后else {//附件上传到系统数据库的操作//附件的本地网络地址路径String fileuploadpath = baseBean.getPropValue("wn_scan", "fileuploadpath");//执行将附件写入系统,并更新到流程中String fileHttpName = "http:" + fileName;String fileHttpPath = fileuploadpath + fileName;String scanDocids = UploadUtil.addAttachments(fileHttpName.split("\\|"), fileHttpPath.split("\\|"), getDocCategoryByWorkflowid(workflowid), new User(1));log.info("docids=" + scanDocids);if (!"".equals(scanDocids) && scanDocids.indexOf("-1") > -1) {returnObj.put("code", "E");returnObj.put("msg", "生成图片到系统中失败!");return returnObj.toString();}// 图片上传成功后,将附件更新到流程中else {boolean clean = FileUtil.del(filesavepath + fileName);log.info(fileName + " ,删除缓存文件是否成功=" + clean);//流程主表名称String mainTable = WorkflowUtil.getTableNameByWFid(workflowid);//所有版本的流程IDString allVersionWfIds = WorkflowUtil.getAllVersionWfIds(workflowid);ArrayList WfIds_arrayList = Util.TokenizerString(allVersionWfIds, ",");//多版本判断是否包含当前流程if (WfIds_arrayList.contains(workflowid)) {try {//获取建模配置信息Map scanSetting = ScanUtil.getScanSetting(workflowid);if (scanSetting == null || scanSetting.size() == 0) {returnObj.put("code", "E");returnObj.put("msg", "未获取到该流程的建模配置信息!");return returnObj.toString();}log.info("ScanSetting=" + JSONUtil.parse(scanSetting));//获取配置的附件上传字段String uploadFileField = (String) scanSetting.get("fjzdm");//获取到附件上传字段if (!"".equals(uploadFileField)) {RecordSet rs = new RecordSet();String fileValue = "";String searchSql = "select " + uploadFileField + " from " + mainTable + " where requestid=?";rs.executeQuery(searchSql, requestid);if (rs.next()) {fileValue = Util.null2String(rs.getString(uploadFileField));}if (!"".equals(fileValue)) {scanDocids = fileValue + "," + scanDocids;}String updatesql = "update " + mainTable + " set " + uploadFileField + "='" + scanDocids + "' where requestid =?";log.info("执行的sql=" + updatesql);rs.executeUpdate(updatesql, requestid);} else {returnObj.put("code", "E");returnObj.put("msg", "OA建模未配置附件上传字段!");return returnObj.toString();}} catch (Exception e) {e.printStackTrace();log.error(e);returnObj.put("code", "E");returnObj.put("msg", "图片上传表单失败!");return returnObj.toString();}}}}}returnObj.put("code", "S");returnObj.put("msg", "处理成功!");return returnObj.toString();}private boolean base64ToFile(String base64, String filesavepath, String fileName) {if (filesavepath == null || "".equals(filesavepath)) {return false;}if (fileName == null || "".equals(fileName)) {return false;}// 写入到硬盘FileOutputStream out = null;String str = "";// 解码try {byte[] bytes = new BASE64Decoder().decodeBuffer(base64);out = new FileOutputStream(filesavepath + fileName);for (int i = 0; i < bytes.length; ++i) {if (bytes[i] < 0) {// 调整异常数据bytes[i] += 256;}}out.write(bytes);} catch (Exception e) {log.error(e);e.printStackTrace();return false;} finally {try {out.flush();out.close();} catch (IOException e) {log.error(e);e.printStackTrace();}}return true;}private String getDocCategoryByWorkflowid(String workflowid) {String docCategory = "";if (!"".equals(workflowid) || workflowid != null) {RecordSet rs = new RecordSet();String sql = "select doccategory from workflow_base where id=?";rs.executeQuery(sql, workflowid);if (rs.next()) {docCategory = Util.null2String(rs.getString("doccategory"));}}return docCategory;}}
4、整体代码
整理代码下载
高拍仪SDK安装包
温馨提示:
高拍仪在安装后会有一个本地的websocket服务,浏览器报错无法连接WebSocketws://localhost:9000.failed:connection,需要手动启动SDK服务。
启动方式如下图