找回密码
 立即注册

QQ登录

只需一步,快速开始

willning
超级版主   /  发表于:2024-2-21 18:21  /   查看:886  /  回复:0
本帖最后由 willning 于 2024-2-21 18:21 编辑

之前我们出过一个教程介绍如何实现基础的离线数据填报,如果您需要在填报时同步采集现场照片以及GPS定位等,则需要配合上HAC(活字格安卓容器)的能力才能完成。在本教程将以一个简单的现场巡检场景为例,包含一下功能的实现方法:
1. HAC的离线模式(防止误触返回键、刷新菜单等)
2. 拍摄小尺寸照片
3. 为照片添加水印
4. 使用服务端命令处理图片字段
5. 读取NFC工卡




一、场景设定

这是一个野外巡检的应用,工人使用手持PDA操作,在现场完整记录检出的故障。根据巡检管理要求,照片和地理位置必须当场采集,不允许“先拍摄后选取”,也不允许手工录入GPS坐标和巡检人信息。该场景的主要挑战集中在业务环境下网络不稳定,巡检应用必须支持离线模式,即在出发前下载本次巡检相关的必要数据,在出发后即进入离线模式;巡检中进行故障记录时,需做到不依赖网络;巡检结束返回后,退出离线模式,并将巡检结果(含记录下的故障照片、问题类型和GPS位置)自动上传到服务器。

二、示例工程

巡检APP:https://gitee.com/low-code-dev-lab/offline-form-demo
配套版本:活字格 9.0.103.0,HAC 1.15.0

三、功能实现

3.1 工程结构
数据库
  • Staff表:员工主数据,用于存储巡检员和对应的NFC卡号
  • IssueType表:故障类型字典主数据
  • Task表:巡检任务单表
  • Issue表:巡检任务单中的故障数据,是Task表的从表

服务端命令
  • createTask服务端命令:创建一个巡检任务单
  • getTaskData服务端命令:获取指定巡检单的信息,含其中包含的故障数据(集成使用,示例工程中不涉及)
  • uploadIssues服务端命令:上传指定巡检单的检查结果,即故障列表

页面
  • TaskHome页面:巡检首页,用于扫描任务单二维码、进入任务执行页面、进入任务查看页面功能。为了方便测试,还可以通过点击“模拟创建任务”按钮创建一个新的巡检任务
  • TaskPage页面:执行巡检操作的页面,是本场景的关键,用户在该页面上添加检出故障、上传任务单
  • ViewTaskDetail页面:简易的任务单查看页面,可以看到指定任务单重点的故障列表,便于测试


3.2 使用PDA的激光头扫描二维码并将结果返回到输入框单元格
在TaskHome页面的页面加载命令和【重扫】按钮的命令中,调用“单次扫码到单元格”命令,监听PDA的扫码广播,收到扫码结果后,填充到任务单ID的输入框中,并触发检查:如果任务单未执行就启用【执行任务】按钮,否则启用【查看任务】按钮
image.png407474364.png

3.3 进入离线模式
离线模式意味着用户将无法通过点击设备上的返回按钮、首页菜单、刷新菜单等方式将当前页面导航到其他页面,避免用户误操作导致当前的离线操作页面不可用。
在TaskPage页面的页面加载命令中,调用“设置离线模式”命令即可。
image.png612797851.png

3.4 从本地缓存中读取数据并加载到页面上
本地离线数据缓存的本质是一个k/V名值对存储。实现方式上,在浏览器里用的是localStorage,在HAC里用的是性能更高的realm。具体到本场景,我们将离线操作的单据作为存储到本地缓存中的单元。即每张任务单存储为本地缓存的一条记录,key是包含有任务单ID的字符串(TASK_ISSUES_{ID},如TASK_ISSUES_8),value是任务单对象(序列化为一个JSON字符串)。需要注意的是,如果本地缓存中不存在这个key,value固定返回为DATA_NOT_FOUND,而不是空字符串。
页面加载时,我们调用“从客户端缓存中读取”命令,完成本地离线缓存的读取。
image.png735550842.png
读取完数据后,如果该任务单已经存在,我们需要将其中包含的故障列表导入到页面上的表格。
image.png827094421.png

3.5 获取当前地点的坐标
在检出问题时,我们需要将原来隐藏的行予以展示,同时调用“读取地理位置到单元格”获取当前的地理坐标,填充到【LonCell】和【LatCell】两个单元格中,再使用公式将其拼接,显示在【LocationCell】里。
具体操作参考:一看就会,超有用活字格技能:一百六十、如何快速获取当前GPS/地理位置(安卓版)

3.6 拍摄带有水印的小尺寸照片
点击【拍摄】按钮时,需要直接调用摄像头拍摄一张小尺寸的照片作为故障的描述信息。使用小尺寸而不是全尺寸的原因主要是该照片通常无需放大查看,仅以“证据”的形式来支撑管理者抽查。在该按钮的命令中,我们调用“拍摄照片”命令,勾选小尺寸,并设置存放照片文件路径的输入框单元格为【RawUriCell】。这里的文件路径和电脑上的路径不同,是uri的形式。
image.png580349731.png
照片拍摄完成后,我们需要调用“为图片添加水印”命令,将当前时间作为水印添加到图片上,然后将处理后的图片地址返回到【WMUriCell】输入框单元格。这步操作放在【RawUriCell】的命令中,由该输入框的值变更来触发。需要注意的是,该命令提供平铺模式和普通模式,前者会以45度角铺满整个图片。
image.png931659545.png
水印处理完毕后,我们需要调用“读取本地文件”命令,读取该文件的内容到变量,随后使用“设置单元格属性”命令将该变量设置为图片单元格的值,就可以预览该图片了。需要了解的是,图片单元格除了可以展示来自数据库图片字段的内容(特定的文件路径)外,还可以直接展示object url格式(包含mime和base64编码的二进制内容)的图片内容。这一步放在【WMUriCell】的命令中。
image.png267711791.png

3.7 将数据写入离线缓存
定位、拍照完毕后,工人会点击【保存】按钮将当前记录的故障保存到离线缓存中。因为保存操作涉及到隐藏故障录入区域、更新故障表格(用来驱动图文列表)等,为了提升可维护性,我们把将页面上的数据存入离线缓存的操作做成一个隐藏区域的按钮【SaveToLocalButton】的命令,这样当需要调用该操作时,只需要使用“操作单元格”命令,调用【SaveToLocalButton】的点击就可以了。
image.png499591979.png
在【SaveToLocalButton】的命令中,我们需要先通过“数组操作”、“JSON序列化”来构建需要保存到缓存中的数据,然后调用“存入客户端缓存”来完成最后的存储。与利用本地缓存做性能优化不同,本场景中不涉及版本问题,将该属性设置为固定值0即可。
image.png108432005.png

3.8 读取NFC卡
为了避免人工录入巡检员,我们需要通过读取NFC工卡的方式获取巡检员信息。在点击【打卡上传】时,我们通过调用“读取NFC标签到单元格”让PDA完成扫描工作,将工卡读取到【NFCCell】输入框单元格。
image.png904528808.png
工卡读取完成后,我们就拿到了上传巡检数据的全部信息。此时我们可以通过【NFCCell】的命令调用服务端命令uploadIssues,完成数据上传。需要注意的是,因为我们这一步操作是通过【NFCCell】的值变更来触发的,所以需要在操作完成后将该输入框的内容置空,当然还需要在命令中判断当前的值是否为空,来确保置空操作不会重复进行数据上传。
image.png49336546.png

3.9 退出离线模式
操作完成后,执行页面跳转前,我们需要通过调用“设置离线模式”来退出离线模式。这一步操作放在【打卡上传】的命令中即可。
image.png437022094.png

四、扩展阅读

本应用场景涉及到的技术集中在通用能力清单的L2-L3,如果您之前没有掌握这些功能,可以通过“程序员入门课”等方式自学。
此外,离线填报的设计遵循了“前后端分离模式”,具体做法可参考最佳实践



评分

参与人数 2满意度 +10 收起 理由
true + 5
fqpeople + 5

查看全部评分

活字格新手训练营由资深技术人员为您“引路”,系统化集中的学习,让您少走弯路,效率更高。点我来报名:
https://app.grapecity.com.cn/lowcodecampus/?source=GCDN

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部