【Angular2】基于localStorage实现本地备份操作记录
2017-12-21 20:03
351 查看
引言
项目中需要对用户的操作记录备份起来,如果后端出现任何问题,可以从前端把用户操作记录提取出来,然后后期把数据导入到数据库功能
网络监测1.监测每条记录的提交情况,分辨出是客户端和服务器问题;
2.呼吸灯动态显示当前整体提交状况;
3.监控中心可以查看每条记录的提交情况;
4.监控中心可以控制对每条记录的监控状态;
5.监控中心可以切换网络监测的开闭模式;
智能提交
1.监控中心每隔10秒监测一次提交情况,如果发现有没有提交成功的内容,会在监听到有提交成功的时刻,自动提交所有没有提交成功的记录;
2.监控中心可以切换智能提交的开闭模式;
自动备份
1.监控中心会在最后的时刻将所有用户的操作记录下载到本地;
2.监控中心可以切换自动备份的开闭模式;
设计思路
1.首先各个题型组件在调取服务之后,通过服务返回的值来判断提交情况,并记录操作,如果有问题则为服务端故障,同时更新网络状态;
2.如果调取服务出现任何异常导致无法获取返回值,则为客户端问题,记录操作并标记,同时更新网络状态;
3.呼吸灯实时监测网络状态,累计3次故障后客户端报警;
4..进入监控中心,读取所有操作记录及其标记,显示提交情况,同时根据具体情况选择性的关闭对应的记录的监测(否则会一直报警);
5.在操作的过程中,如果发现有没有提交成功的操作,同时监测到最近有提交成功,那么就把之前没有提交成功的操作重新自动提交;
6..监控中心如果出现很多问题或者关键性问题,可以开启备份操作下载功能,用户操作完成之后会把操作自动下载到本地;
代码说明
各题目组件 ts
/* 向后台提交学生答案 */ public updateStudentAnswerToBackend(answer: Answer) { let url: string = "examinationEvaluation-web/onlineExam/updatePaperRecordByRecord" + this.authGuardService.getTicket(); let body: string = JSON.stringify(answer); this.exampapaerservice.post(url, body).subscribe( res => { if (res.json().code == "1111" || res.json().data != true) { this.backupAnswer(answer, 1); //备份答案 } else { this.backupAnswer(answer, 0); //备份答案 } } ); console.log("学生提交答案-radio"); } /* 备份用户答案 */ private backupAnswer(answer: Answer, status: number) { //备份答案记录 console.log("answer-backup-log---"+ExamPaperService.userOperationAmount); ExamPaperService.userOperationAmount++; //操作序号递增 localStorage.setItem("userOperationAmount", ExamPaperService.userOperationAmount.toString()); //记录操作序号 localStorage.setItem(answer.studentId + ExamPaperService.userOperationAmount, JSON.stringify(answer) + status); //记录操作内容 //记录提交情况 let flag: boolean = true; let ns: string[] = JSON.parse(localStorage.getItem("NetWorkState")); for (var i = 0; i < ns.length; i++) { if (answer.questionMainId == ns[i]) { flag = false; } } if (status != 0 && flag) { ns[0] = (parseInt(ns[0]) + 1).toString(); localStorage.setItem("NetWorkState",JSON.stringify(ns)); } }
公共服务 ts
/* 处理失败提交 */ public handleUpdateAnswerError(error: Response) { //保存用户答案到localStorage let answer: Answer = <Answer>(JSON.parse(ExamPaperService.studentAnswer)); this.backupAnswer(answer, 2); return Observable.throw(error.json().error || '网络问题:server error'); } /* 备份用户答案 */ private backupAnswer(answer: Answer, status: number) { //备份答案记录 console.log("answer-backup-log---" + ExamPaperService.userOperationAmount); ExamPaperService.userOperationAmount++; //操作序号递增 localStorage.setItem("userOperationAmount", ExamPaperService.userOperationAmount.toString()); //记录操作序号 localStorage.setItem(answer.studentId + ExamPaperService.userOperationAmount, JSON.stringify(answer) + status); //记录操作内容 //记录提交情况 let flag: boolean = true; let ns: string[] = JSON.parse(localStorage.getItem("NetWorkState")); for (var i = 0; i < ns.length; i++) { if (answer.questionMainId == ns[i]) { flag = false; } } if (status != 0 && flag) { ns[0] = (parseInt(ns[0]) + 1).toString(); localStorage.setItem("NetWorkState", JSON.stringify(ns)); } }
监控中心 ts
ngOnInit() { //获得当前操作数量 this.getUserOperationAmount(); //初始化网络状态 let networkList: string[] = []; networkList.push("0"); localStorage.setItem("NetWorkState", JSON.stringify(networkList)); //初始化备份模式 localStorage.setItem("NetWorkBackupPattern", "0"); //开始监测 this.startMonitorNetworkStatus(); } /* 开始监测网络状态 */ startMonitorNetworkStatus() { this.timer = setInterval(() => { this.networkState = parseInt(JSON.parse(localStorage.getItem("NetWorkState"))[0]); let el: Element = document.getElementById("networkstate"); if (this.networkState == 1) { el.setAttribute("class", "breathe-yellow-btn"); } else if (this.networkState == 3) { el.setAttribute("class", "breathe-red-btn"); } else if (this.networkState > 3) { this.display_error = true; let ns: string[] = JSON.parse(localStorage.getItem("NetWorkState")); ns[0] = "3"; localStorage.setItem("NetWorkState", JSON.stringify(ns)); } }, 1000); } /* 刷新状态 */ refreshStatus() { this.getAnswerStatus(); this.getMonitorStatus(); } /* 清除缓存 */ clearLocalStorage() { localStorage.clear(); } /* 获得题目提交状态 */ getAnswerStatus() { console.log("Start-getAnswerStatus-------"); for (var i = 0; i < parseInt(localStorage.getItem("userOperationAmount")); i++) { let answerLog: string = localStorage.getItem(localStorage.getItem("userId") + i); let answerStatus = answerLog.substring(answerLog.length - 1); let answer: Answer = JSON.parse(answerLog.substring(0, answerLog.length - 1)); if (answerStatus == "0") { let el = document.getElementById("network" + answer.questionMainId); if (el != null) { el.setAttribute("class", "badge badge-success badge_postion"); el.innerHTML = "成功提交"; } } if (answerStatus == "1") { let el = document.getElementById("network" + answer.questionMainId); if (el != null) { el.setAttribute("class", "badge badge-warning badge_postion"); el.innerHTML = "客户端故障"; } } if (answerStatus == "2") { let el = document.getElementById("network" + answer.questionMainId); if (el != null) { el.setAttribute("class", "badge badge-important badge_postion"); el.innerHTML = "服务器故障"; } } } } /* 获得检测状态 */ getMonitorStatus() { console.log("Start-getMonitorStatus-------"); let idList: string[] = JSON.parse(localStorage.getItem("NetWorkState")); for (var i = 1; i < idList.length; i++) { let el = document.getElementById("monitor" + idList[i]); if (el != null) { el.setAttribute("class", "btn btn-danger btn-xs pull-right"); el.innerHTML = "监测已停止"; } } } /* 获得操作记录数量 */ getUserOperationAmount() { let amount: number = 1; while (localStorage.getItem("userId" + amount)!=null) { amount++; } localStorage.setItem("userOperationAmount",(amount-1).toString()); } /* 切换监测状态 */ changeMonitorStatus(monitorId: string) { console.log("Start-changeMonitorStatus-------"); let exitFlag: boolean = true; let questionId = monitorId.substring(7, monitorId.length); let idList: string[] = JSON.parse(localStorage.getItem("NetWorkState")); for (var i = 0; i < idList.length; i++) { if (questionId == idList[i]) { //切换为开始 let el = document.getElementById("monitor" + idList[i]); if (el != null) { el.setAttribute("class", "btn btn-primary btn-xs pull-right"); el.innerHTML = "正在监测中"; } idList.splice(i, 1); localStorage.setItem("NetWorkState", JSON.stringify(idList)); exitFlag = false; } } //切换为停止 if (exitFlag) { let el = document.getElementById(monitorId); if (el != null) { el.setAttribute("class", "btn btn-danger btn-xs pull-right"); el.innerHTML = "监测已停止"; } idList.push(questionId); localStorage.setItem("NetWorkState", JSON.stringify(idList)); } } private backupPatternStatus: boolean = false; //备份模式状态 /* 切换备份模式 */ changeBackupPattern() { if (this.backupPatternStatus) { //切换为不备份 let el = document.getElementById("networkbackuppattern"); if (el != null) { el.setAttribute("class", "btn btn-info pull-left"); el.innerHTML = "非备份模式"; localStorage.setItem("NetWorkBackupPattern", "0"); this.backupPatternStatus = false; } } else { //切换为开始备份 let el = document.getElementById("networkbackuppattern"); if (el != null) { el.setAttribute("class", "btn btn-warning pull-left"); el.innerHTML = "备份模式中"; localStorage.setItem("NetWorkBackupPattern", "1"); this.backupPatternStatus = true; } } } /* --------------------------------------------------------- */ private openNum: number = 0;//点击三次可以打开 /* 打开模态框 */ openModal(modal: HTMLElement) { this.openNum++; if (this.openNum > 2) { this.refreshStatus(); modal.style.visibility = 'visible'; this.openNum = 0; } } /* 关闭模态框 */ close(modal: HTMLElement) { modal.style.visibility = 'hidden'; } /* 拖动模态框 */ draggable() { $('.modal-dialog').draggable(); }
本地备份下载 ts
/* 创建备份文本并下载 */ createBackupText() { let userLog: string = ""; for (var i = 0; i < parseInt(localStorage.getItem("userOperationAmount")); i++){ userLog = userLog +localStorage.getItem(localStorage.getItem("userId")+i); } let data = new Blob([userLog], { type: 'application/json' }) var link = document.createElement("a"); link.setAttribute("href", window.URL.createObjectURL(data)); link.setAttribute("download", localStorage.getItem("userId") + '.json'); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); console.log("------ Start Create File And Download --------"); }
小结
要针对不同的业务场景采取不同的解决方案,尽可能考虑全面相关文章推荐
- HDFS-API调用-基于MVC框架实现WEB操作记录
- 基于HTML5 的localStorage 实现数据本地缓存
- 基于Hibernate Envers实现数据审计Audit操作记录
- Python之Fabric模块 Fabric是基于Python实现的SSH命令行工具,简化了SSH的应用程序部署及系统管理任务,它提供了系统基础的操作组件,可以实现本地或远程shell命令,包括:
- 基于数据库(access)层次编码记录对TreeView的操作(实现自动编码,灵活控制编码规则和编码层次)
- 基于数据库(access)层次编码记录对TreeView的操作(实现自动编码,灵活控制编码规则和编码层次)
- JS实现本地存储信息的方法(基于localStorage与userData)
- 用Angular实时获取本地Localstorage数据,实现一个模拟后台数据登入的效果
- 脚本实现svn备份与恢复,基于rsync实现远程备份,并记录日志
- MyBatis第二讲学习笔记 ,使用MyBatis对表执行增删改查操作——基于注解的实现
- javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)
- SAE 平台代码实现数据库定时备份以及同步到本地 2014/09/11 09:39:01 分类: 技术随笔 1人评论 次浏览 SAE 只允许用户通过phpMyAdmin管理远程数据库,
- SQL本地分布式操作远程数据库,可用于实现导入,导出等数据操作功能
- Oracle如何实现创建数据库、备份数据库及数据导出导入的一条龙操作-------sql方式
- 触发器实现记录操作表的日志
- 数据结构之二叉排序树(基于指针实现基本操作)
- Oracle如何实现创建数据库、备份数据库及数据导出导入的一条龙操作
- SQL语句实现跨Sql server数据库操作实例 - 查询远程SQL,本地SQL数据库与远程SQL的数据传递
- Oracle批量操作(基于Mybatis的实现)
- 用钩子实现对当前操作的记录,回放,并记录文件