最近做了一个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的src
var 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));
//请求id
String requestid = paramObj.getStr("requestid");
//获取对应的workflowid
String 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);
//所有版本的流程ID
String 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服务。
启动方式如下图