由于新型冠状病毒肺炎的原因,口罩成了紧俏货,可谓是一罩难求,应某地方政府的要求,开发了在线申请口罩的WebAPP,基本需求是政府集中采购口罩,辖区居民在线申请(抢购),申请成功后,由快递公司配送给市民。申请时需要填写配送地址、居民基本信息,同时需要上传身份证正面照片。
核心技术功能如下:
1、拍照、上传身份证照片功能(需要兼容iOS系统和安卓系统)
2、大部分手机拍照的像素很高,照片的体积一般都在3~5M,需要在手机端进行图片压缩。
同时,由于形势紧迫,要求开发、调试的时间只有1天。
综上所述,决定采用“红贝应用架构”,该架构因为简易、高效、开源,可用通过JSON配置文件的方式快速完成常见功能的开发,先以该WebAPP为实例,再次向大家介绍“红贝应用架构”,同时给出手机端纯Javascript方式进行图片压缩和上传的函数代码。
一、核心功能页面
二、申领口罩页面JSON配置文件
{ "id": "forms-elements", "component": [ { "type": "navbar", "list": [ { "type": "left", "icoIos": "icon icon-back", "icoMat": "icon icon-back", "class": "back link", "click": "#" }, { "type": "title", "text": "申领口罩" } ] }, { "type": "title", "shape": "pillar", "fill": "1", "text": "配送地址" }, { "type": "input", "subtype": "form", "id": "form-elements-form", "class": "list bg-form", "lblFloating": "0", "list": [ { "input": "text", "name": "txtName", "icoIos": "person", "icoMat": "person_outline", "icoColor": "color-green", "label": "收货人", "placeholder": "请填写收货人姓名" }, { "input": "tel", "name": "txtPhone", "icoIos": "phone", "icoMat": "call", "icoColor": "color-green", "label": "收货人电话", "placeholder": "请填写收货人电话" }, { "input": "select", "name": "selArea", "icoIos": "persons", "icoMat": "view_column", "icoColor": "color-green", "label": "行政区划(金华市)", "onchange": "doAreaChange(this.value)", "item": [ { "value": "330711000000", "text": "开发区" }, { "value": "330702000000", "text": "婺城区" } ] }, { "input": "select", "name": "selPlace", "icoIos": "place", "icoMat": "place", "icoColor": "color-green", "label": "乡镇/街道", "item": [ { "value": "", "text": "请选择" } ] }, { "input": "textarea", "name": "txtAddr", "icoIos": "place", "icoMat": "chat_bubble_outline", "icoColor": "color-green", "label": "详细收货地址" } ] }, { "type": "title", "shape": "pillar", "fill": "1", "text": "申请人信息" }, { "type": "input", "subtype": "form", "id": "form-elements-floating-form1", "lblFloating": "0", "list": [ { "input": "text", "name": "name1", "icoIos": "person", "icoMat": "person_outline", "icoColor": "color-blue", "label": "姓名", "placeholder": "请填写申请人姓名" }, { "input": "text", "name": "card1", "icoIos": "email", "icoMat": "credit_card", "icoColor": "color-blue", "label": "身份证号码", "placeholder": "请填写申请人身份证号码" }, { "input": "file", "name": "file1", "icoIos": "email", "icoMat": "photo", "icoColor": "color-blue", "label": "身份证照片", "placeholder": "+上传身份证正面照片", "onchange": "doUploadImg('file1')" } ] }, { "type": "input", "subtype": "form", "id": "form-elements-form-qty", "lblFloating": "0", "list": [ { "input": "stepper", "name": "lblStepper0", "value": "5", "icoIos": "bag", "icoMat": "add_shopping_cart", "icoColor": "color-blue", "label": "口罩数量", "type": "outer", "min": "1", "max": "5", "step": "1", "color": "#2196F3", "extCls": "stepper-small stepper-fill stepper-round" } ] }, { "type": "content", "list": [ { "text": "<div style=\"width:94%;margin:0 auto;padding:12px;text-align:center;border-radius:8px;border:solid 1px #F6EB78;background:#FFFCE9;color:#FBB750;\">口罩单价:¥2.00/只,快递费:¥6.00</div>" } ] }, { "type": "button", "list": [ { "text": "提交订单", "click": "doSubmitOrder()", "clsIos": "button color-blue", "clsMat": "button button-fill color-blue" } ] }, { "type": "style", "data": ".bg-form{background:#F6FFF4 url(Assets/img/bg-form.png);background-position:left top;background-repeat:repeat-y;border-top:solid 2px #A4E3A2;border-bottom:solid 2px #A4E3A2;border-right:solid 2px #A4E3A2;}" } ] }
三、核心功能函数说明
[1] 图片压缩函数
Be.util.compressImage(objFile, quality, zoomRate, ignoreSize, callback)
上述函数中包括五个参数,第1个参数是上传的图片文件对象;第2个参数是压缩的质量,取值范围0~1;第3个参数是图片缩放的比例,如果该值为1则保持原图尺寸,如果该值为2则,原图的宽、高分别缩小至原尺寸的一般,即压缩后图片的宽度=原图宽度/n,压缩后图片的高度=原图高度/n;第4个参数用于设置进行压缩的文件体积,比如规定文件大于1M需要压缩,则该值可设置为1024*1024;第5个参数为回调函数,用于在图片压缩完毕后,返回文件对象,执行上传功能。
[2] 文件上传函数
Be.util.upload(objFile, inputId, postUrl);
上述函数中包括三个参数,第1个参数是上传的文件对象;第2个参数是file选择框的id;第3个参数是服务器端接受、保存上传文件的网址。
文件上传示例
根据上面的“配置示例”,分别给出触发onchange事件后的文件上传函数doUploadFile()和doUploadPhoto()的代码,其中doUploadPhoto()函数包括对图片的压缩。
[1] doUploadFile函数
function doUploadFile(inputId) { var uploadInput = document.getElementById(inputId); var postUrl = Be.config.url + '/' + Be.config.handlerPostName + '.ashx'; postUrl = Be.util.appendString(postUrl); for (var i = 0, fileCount = uploadInput.files.length; i < fileCount; i++) { Be.util.upload(uploadInput.files[i], inputId, postUrl); } }
[2] doUploadPhoto函数
function doUploadPhoto(inputId) { var uploadInput = document.getElementById(inputId); var postUrl = Be.config.url + '/' + Be.config.handlerPostName + '.ashx'; postUrl = Be.util.appendString(postUrl); var quality=0.8, zoomRate = 2, ignoreSize=1024*512; //设置压缩大于512KB的文件 for (var i = 0, fileCount = uploadInput.files.length; i < fileCount; i++) { //console.log(uploadInput.files[i]); Be.util.compressImage(uploadInput.files[i], quality, zoomRate, ignoreSize, function (file) { Be.util.upload(file, inputId, postUrl); uploadInput.value = ''; //解决无法上传重复图片的问题。 }); } }