点击这里,查看扫码入库系统演示的网址

一、界面样式

主要功能:

  • 扫码入库,无线,有线扫码枪均可。
  • 断点后自动续存编号,比如之前1号服务站入库了2单,换成8号服务站入库,当切换回1号服务站继续入库时,快递编号自动从第3单开始向后续。
  • 能够把入库数据转换成EXCEL表格,以供下载使用。
  • 手动输入,倒计时12秒后自动检测单号是否合规,并需要用户确认后存入浏览器本地存储
  • 本地存储的几个主要用途。 ①计算时间,当第一次打开网站会存入一个毫秒时间,每次刷新或者重新打开页面都会比对当前时间与存储时间的差值,大于13小时,即弹出对话框让用户选择是否清理页面缓存信息。同时存入当前毫秒时间。 ②断点续号,将服务站编号与他的入库数,作为key:value保存于本地存储中,当点击切换服务站时,保存旧服务站的信息,调出新服务站的信息,以达到序号不乱的目的。 ③显示列表信息和下载EXCEL信息都来源于本地存储

二、扫码入库和手动入库

2.1 扫码入库,扫码枪获取单号的时间一般不超过20毫秒,为了保险起见,设置了300毫秒后,开始验证数据。
  • 2.1.1 methods的首个函数,主要功能一些开关和计时
`this.flag 为 ture 时把毫秒时间存放于数组中,单号有15位就会存放15次毫秒时间`
`this.istrue 为 ture 时立即锁定并执行 this.timerSet() 函数`
`this.isFalse 用于切换提示信息与手动输入提示信息有关`
scanWrite() {if (this.flag) {let time = Date.now();this.timeArr.push(time);}if (this.istrue) {this.istrue = false;this.isFalse = false;this.timerSet();}
}
  • 2.1.2 自动分通道检测单号
`this.isShow 为 ture 时,是扫码入库,反之是手动入库`
timerSet() {if (this.isShow) {this.checkNumA();} else {this.checkNumB();}}
  • 2.1.3 检测单号的有效性
 ` this.istrue 为 false 时 300毫秒后执行数据检测 ``第一步计算了时间,展示在网页顶部右侧的提示信息框内``第二步检测单号是否已经存在,并展示提示信息,开启或关闭某些开关``第三部检测单号属于哪个快递公司``第四步统计保存数据``重复或者错误都将执行清除函数 this.remove()`checkNumA() {if (!this.istrue) {setTimeout(async () => {this.timeArr.push(Date.now());this.timess = '用时:' + (this.timeArr[this.timeArr.length - 1] - this.timeArr[0]) + '毫秒';/*检测快递单号是否重复*/let myforArr = await this.forArr(this.numA);if (!myforArr) {this.remove();this.countdown = `${this.numA}号码重复`;return;}/*检测快递单号长度*/let checkLength = await this.checkLength(this.numA);if (!checkLength) {this.remove();this.countdown = `单号长度有误,应当在11~19位之间`;return;} else {this.totalCount(this.numA);}}, 300);}}
2.2 手动入库,当点击输入框,倒计时启动,然后验证单号有效性。
  • 2.2.1 倒计时。
  `倒计时开启后运行倒计时音乐``倒计时结束后运行 this.timerSet()``this.right用于锁定,当前只能运行一个timer()函数`timer() {if(this.isRight){this.isRight =false;this.isHandleShow = true;this.timer_audio = new Audio('../../static/yx/10s.mp3');this.timer_audio.play();let num = 12;this.countdown = `将在${num}秒后自动入库`;this.myTimerNum = setInterval(() => {num -= 1;if (num <= 1) {clearInterval(this.myTimerNum);this.isShow = false;this.timerSet();} else {this.countdown = `将在${num}秒后自动入库`;}}, 1000);}else{return}}
  • 2.2.2 自动分通道检测单号,同上this.timerSet()
  • 2.2.3 手动输入单号检测验证区
  `第一步验证单号是否重复``第二步匹配对应的快递公司``第三步统计并保存数据``重复或者错误都将执行清除函数 this.remove()`async checkNumB() {/*检测快递单号是否重复*/let myforArr = await this.forArr(this.numB);if (!myforArr) {this.remove(this.numB);this.isHandleShow = false;return;}/*检测快递单号长度*/let checkLength = await this.checkLength(this.numB);if (!checkLength) {this.isRight = true;this.remove(this.numB);return;} else {if (this.timer_audio) {this.timer_audio.pause();}const that = this;uni.showModal({title: '无法匹配快递公司',content: '确定要保存当前单号吗?',success: function(res) {if (res.confirm) {that.isRight = true;that.totalCount(that.numB);that.remove(that.numB);return} else if (res.cancel) {that.countdown = '单号有误,已经删除';that.isRight = true;that.remove(that.numB);return}}});}}

三、统计并本地保存数据

  `this.countNum 是当前服务站的快递排序编号``this.totalNums 是当前总入库数 ``this.expressNum 当前单号,用于首页展示``this.totalJsonData() 整合汇总数据 并存入EXCEL表所需数组中 ``把EXCEL表所需数组存入浏览器本地存储``计算用时,运行清理函数`async totalCount(e) {this.countNum++;this.totalNums++;this.expressNum = e;this.buffNumArr.push(e);let buffResult = await this.totalJsonData();uni.setStorage({key: 'expressJsonArr',data: buffResult});this.timeArr.push(Date.now());this.timess = '用时:' + (this.timeArr[this.timeArr.length - 1] - this.timeArr[0]) + '毫秒';this.remove(e);}

四、打开网页时的初始化数据

  • 4.1 onLoad()页面生命周期
`this.getDate().slice(0, 10)获取当前时间`
`初始化EXCEL表下载时所用的文件名`
`this.timess 顶部显示的时间`
`获取本地存储的时间数据,如果大于13小时,就显示模态框,并存入新的时间`
`this.checkStorageObj() 获取本地存储 更新页面数据`onLoad() {let str = this.getDate().slice(0, 10);this.fileName = str + '快递单.xls';this.timess = this.getDate();uni.getStorage({key: 'dateNow',success: res => {this.starTimer = res.data;let H = Math.round((Date.now() - this.starTimer) / 3600000);if (H > 13) {uni.setStorage({key: 'dateNow',data: Date.now()});this.clearArr();}},fail: err => {uni.setStorage({key: 'dateNow',data: Date.now()});}});this.checkStorageObj();}
  • 4.2 this.getDate()获取当前年月日时分秒
  `时间格式为 2021/04/09/09:07:58`getDate(e) {if (typeof e === Number) {var D = new Date(e);} else {var D = new Date();}let Y = D.getFullYear();let M = D.getMonth() + 1;M = M < 10 ? '0' + M : M;let R = D.getDate();R = R < 10 ? '0' + R : R;let H = D.getHours();H = H < 10 ? '0' + H : H;let F = D.getMinutes();F = F < 10 ? '0' + F : F;let S = D.getSeconds();S = S < 10 ? '0' + S : S;return Y + '/' + M + '/' + R + '/' + H + ':' + F + ':' + S;}
  • 4.3 this.checkStorageObj()获取本地存储数据
  `this.ServStaNumObj 包含服务站编号和该服务站入库单号统计数``arr.map()用于计算已入库的快递总数`checkStorageObj() {uni.getStorage({key: 'ServStaNumObj',success: res => {this.ServStaNumObj = res.data;let arr = Object.values(res.data);let num = 0;arr.map(val=>{num+=Number(val);})this.totalNums = num;},fail: err => {console.log('当前还没有服务站的数据缓存信息');}});}

五、页面中的几个点击事件

  • 5.1 handleXL(e)选择服务站点后的事件
  `e.newVal 是新站点编号``this.defaultVal 是旧站点编号``this.myIndex 是站点编号加了 - 后的字符串``this.forStorageObj(newIndex,oldIndex,oldVal) 用于对比数据交换数据`handleXL(e) {let my_index = e.newVal + '-';if (this.myIndex != my_index) {let newIndex = e.newVal;let oldIndex = this.defaultVal;let oldVal = this.countNum;this.countNum = 0;this.forStorageObj(newIndex,oldIndex,oldVal);this.myIndex = my_index;this.defaultVal = newIndex;} else {return;}}
  • 5.2 this.forStorageObj()对比、交换、存储数据
   `当旧服务站入库数不为 0 时,把当前的入库数更新到 this.ServStaNumObj 中``获取 this.ServStaNumObj 对象中是否有新服务站的数据,把入库数赋值给 this.countNum ``最后进行本地存储,这个存储就是用于,onLoad()时调用`forStorageObj(newIndex,oldIndex,oldVal) {/*保存旧值*/if(oldVal!=0){this.ServStaNumObj[oldIndex] = `${oldVal}`;}/*更新新值*/for (let k in this.ServStaNumObj) {if(k === newIndex){this.countNum = this.ServStaNumObj[k];break;}}uni.setStorage({key: 'ServStaNumObj',data: this.ServStaNumObj});}
  • 5.3 更换入库输入方式changeDemo()
  `打开或者关闭开关``改变当前按钮的形态,颜色,提示信息等``关闭定时器,关闭音乐`changeDemo() {this.isShow = !this.isShow;this.flag = true;this.istrue = true;if (this.isShow) {this.countdown = '现在已经是扫码输入模式了';this.type = 'primary';this.btnShow = '尝试手动输入?';if (this.timer_audio) {this.timer_audio.pause();}clearInterval(this.myTimerNum);} else {this.countdown = '您选择了手动输入单号';this.isRight = true;this.type = 'warn';this.btnShow = '返回扫码输入?';}
}
  • 5.4 清除页面缓存
clearArr() {let that = this;uni.showModal({title: '确定要清除',content: '保存在浏览器内的快递单号吗?',success: function(res) {if (res.confirm) {this.ServStaNumObj = {};uni.removeStorage({key: 'expressJsonArr',success: function(res) {that.countdown = '清除成功';}});uni.removeStorage({key: 'ServStaNumObj',success: function(res) {that.countdown = '清除成功';}});window.location.reload();} else if (res.cancel) {that.countdown = '取消清除';}}});
},
  • 5.5 获取全部快递单号列表
  `that.buffTotal是 excel表的数据源`getList() {this.isListShow = !this.isListShow;if (this.isListShow) {var that = this;that.buffTotal = [];uni.getStorage({key: 'expressJsonArr',success: function(resa) {that.buffTotal.push(...resa.data);}});}
}
  • 5.6 EXCEL表下载,使用的是组件
<template><view @click.stop="downExcel"><slot></slot></view>
</template><script>
export default {name: 'min-excel',data() {return {thName: `编号,快递公司,快递单号,入库时间\n`};},props: {excelList: {type: Array},fileName: {type: String,default: '快递单.xls'}},methods: {downExcel() {if (this.excelList.length === 0) {uni.showModal({title: '抱歉不能下载',content: '当前没有可用的数据',showCancel: false});}else{let str = this.thName;let arrList = this.excelList;for (let i = 0; i < arrList.length; i++) {for (let key in arrList[i]) {str += `${arrList[i][key] + '\t'},`;}str += '\n';}const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);const link = window.document.createElement('a');link.href = uri;link.download = this.fileName;link.click();}}}
};
</script><style></style>
  • 5.7 选择服务站点的下拉列表组件
<template><view class="xl-content" @click.stop.prevent="downUp"><!--列表分为三个部分--><view class="xl-show"><!--1.默认显示栏--><input disabled="true" type="text" :value="inputStr === '' ? defaultVal : inputStr" /></view><view class="xl-sj" :class="isClick ? 'xl-sj-up' : 'xl-sj-down'"><!--2.倒三角按钮--><image src="@/static/components/sj.png"></image></view><view class="xl-lb" v-show="isClick"><!--3.数据列表--><view class="xl-lb-view" v-for="(item, index) in list" :key="item" :data-index="index" hover-class="color-blue" @click.stop="choose(item, $event)">{{ item }}</view></view></view>
</template><script>
export default {data() {return {isClick: false,inputStr: '',oldIndex: 0,eve: '',timer:null};},props: {list: {type: Array},defaultVal:{type:String}},watch: {list: function() {this.inputStr = '';},/*监听点击事件,如果打开了列表就开始监听点击事件,如果列表关闭就移除监听事件*/isClick:function(){if(this.isClick){window.addEventListener('click', (e)=>{this.endClick(e);});}else{clearTimeout(this.timer);window.removeEventListener('click',this.endClick);}}},methods: {/*endClick需要传的参数*/endClick(e){if (this.isClick && this.eve === '') {this.eve = e.path[0];} else if(this.eve === e.path[0]){return;}else{this.isClick = false;}},downUp() {this.isClick = !this.isClick;if (this.isClick) {this.timer = setTimeout(() => {this.isClick = false;}, 8000);}},choose(newVal, event) {if (this.inputStr === '') {this.inputStr = this.list[0];}let oldVal = this.inputStr;this.inputStr = newVal;let oldIndex = this.oldIndex;let newIndex = event.target.dataset.index;let timer = setTimeout(() => {this.isClick = false;clearTimeout(timer);}, 200);this.$emit('btns', { oldVal, newVal, newIndex, oldIndex, event });this.oldIndex = event.target.dataset.index;}}
};
</script><style lang="scss">---样式就不写了--
</style>

六、其他衔接函数

  • 6.1 清除输入框数据的函数 remove(e)
  • 6.2 判断单号是否重复的函数forArr(e)
  • 6.3 根据单号,匹配快递公司的函数checkLength(e)
  • 6.4 生成EXCEL表数据源的函数totalJsonData()
  • 6.5 监听数字变化就播放音乐的函数watch
 `点击输入框、错误、重复、完成后都要运行的清除输入框数据的函数`remove(e) {if (e === this.numB || e === 'numB') {this.countdown = '您正在手动输入';this.isFalse = false;this.timeArr = [];this.flag = true;this.istrue = true;this.numB = '';this.timer();} else {this.numA = '';this.timeArr = [];this.flag = true;this.istrue = true;}}
`检测单号是否重复的函数` forArr(e) {if (this.buffNumArr.length === 0) {return true;}var arr = this.buffNumArr.filter(k => {return k === e;});if (arr.length !== 0) {this.isFalse = true;this.num++;this.wrong;return false;} else {return true;}}
`检测单号长度,匹配快递公司的函数`checkLength(e) {var that = this;this.timess = '单号长度为:'+ e.length;if (e.length < 11) {this.wrong++;this.countdown = `快递单号长度有误${this.wrong}次`;this.istrue = true;return false;}let str1 = e.slice(0, 2);let str2 = e.slice(0, 1);let strLength = e.length;if (str1 == 'SN') {that.expressName = '苏宁快递';that.countdown = `快递公司&ensp;:&ensp;苏宁快递&nbsp;快递单号:${e}`;return true;} else if (str1 === 'JT') {that.expressName = '极兔快递';that.countdown = `快递公司:极兔快递&nbsp;快递单号:${e}`;return true;} else {that.expressName = '-未知-';that.countdown = `快递公司:-未知-&nbsp;快递单号:${e}`;return '-未知-';}}
`对数据进行合并分发处理,排序处理,给EXCEL表提供数据源`
totalJsonData() {let flag = true;let index = Number(this.countNum);let myIndex = this.myIndex + index;let oldMyIndex = this.myIndex + (index - 1);const time = Date.now();let buffObj = {           expressIndex: myIndex,index:index,expressName: this.expressName,expressNum: this.expressNum,inputTimer: this.getDate(time)};this.buffTotal.forEach((k,i)=>{if(k.expressIndex === oldMyIndex ){++i;this.buffTotal.splice(i,0,buffObj);flag = false;}})if(flag){this.buffTotal.push(buffObj);}return this.buffTotal;}
`监听数字变化,播放对应的音效`watch: {totalNums: function() {const audio = new Audio('../../static/yx/ok.wav');audio.play();},wrong: function() {const audio = new Audio('../../static/yx/wrong.wav');audio.play();},num: function() {const audio = new Audio('../../static/yx/wrong.mp3');audio.play();}}

七、其他系统设置

  • 7.1 manifest.json H5的自定义设置。官方文档地址
  • 7.2 网站小图标的设置,在项目根目录下创建html文件,在H5配置内,关联此html文件"template":"link_index.html"
 "h5": {//网站小图标需要使用到的link_index.html文件,在此关联"template":"link_index.html",//网站的名称"title": "快递扫码入库",//反向代理相关设置,是否允许自己的网站去访问其他的 https 网站"devServer": {"https": true},//网络地址中不显示 # 号 "router": {"mode": "history"}}
<!DOCTYPE html>
<!--在项目根目录下生成 link_index.html文件 把小图标的引用 link rel 放进去-->
<!-- <link rel="shortcut icon" href="https://static.oschina.net/new-osc/img/favicon.ico"> -->
<html lang="zh-CN"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title><%= htmlWebpackPlugin.options.title %></title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" /><link rel="shortcut icon" href="https://static.oschina.net/new-osc/img/favicon.ico"></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id="app"></div><!-- built files will be auto injected --></body>
</html>

八、遗憾

没有添加删除单号的功能,如果录入的一条或多条单号有误,比如对应的服务站点错误,或者手动输入的单号错了,需要修改或是删除。只需要调用本地存储的信息,修改后再保存即可,懒得写了。打完收工!

快递扫码入库PC系统相关推荐

  1. java毕业生设计疫苗药品批量扫码识别追溯系统计算机源码+系统+mysql+调试部署+lw

    java毕业生设计疫苗药品批量扫码识别追溯系统计算机源码+系统+mysql+调试部署+lw java毕业生设计疫苗药品批量扫码识别追溯系统计算机源码+系统+mysql+调试部署+lw 本源码技术栈: ...

  2. 一种仓库扫码出库系统的实现

    前言 最近在做公司的仓库管理系统,这个系统设计到商品出库.回仓.损耗等.系统在设计之初就一直到考虑仓库人员使用的方便性,提高他们的工作效率.但是不管我们怎样做,仓库那边的人员总说系统复杂,不会用.现在 ...

  3. 计算机毕业设计Java疫苗药品批量扫码识别追溯系统(系统+源码+mysql数据库+Lw文档)

    计算机毕业设计Java疫苗药品批量扫码识别追溯系统(系统+源码+mysql数据库+Lw文档) 计算机毕业设计Java疫苗药品批量扫码识别追溯系统(系统+源码+mysql数据库+Lw文档) 本源码技术栈 ...

  4. 计算机毕业设计PHP疫苗药品批量扫码识别追溯系统(源码+程序+VUE+lw+部署)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程.欢迎交流 项目运行 环境配置: phpStudy+ Vscode +Mysql5.7 + HBuilderX+Navicat11+Vue ...

  5. [附源码]计算机毕业设计springboot疫苗药品批量扫码识别追溯系统

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  6. java-php-python-ssm疫苗药品批量扫码识别追溯系统计算机毕业设计

    java-php-python-ssm疫苗药品批量扫码识别追溯系统计算机毕业设计 java-php-python-ssm疫苗药品批量扫码识别追溯系统计算机毕业设计 本源码技术栈: 项目架构:B/S架构 ...

  7. node.js+Express计算机毕业设计疫苗药品批量扫码识别追溯系统(程序+LW+部署)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程.欢迎交流 项目运行 环境配置: Node.js+ Vscode +Mysql5.7 + HBuilderX+Navicat11+Vue+ ...

  8. [附源码]Python计算机毕业设计Django疫苗药品批量扫码识别追溯系统

    项目运行 环境配置: Pychram社区版+ python3.7.7 + Mysql5.7 + HBuilderX+list pip+Navicat11+Django+nodejs. 项目技术: dj ...

  9. java计算机毕业设计疫苗药品批量扫码识别追溯系统源码+数据库+系统+lw文档+部署

    java计算机毕业设计疫苗药品批量扫码识别追溯系统源码+数据库+系统+lw文档+部署 java计算机毕业设计疫苗药品批量扫码识别追溯系统源码+数据库+系统+lw文档+部署 本源码技术栈: 项目架构:B ...

  10. android简单点餐系统_微信点餐和扫码点餐系统能为商家带来什么?

    近几年来,我们去餐厅吃饭的时候可能会发现,很多餐厅都安装扫码点餐系统.和微信点餐系统,相比传统餐饮软件及传统模式,这带来的不只是节省人工.一套系统稳定.功能齐全的微信点餐系统,对餐饮管理而言,能够降低 ...

最新文章

  1. wegame饥荒一直连接中_23万人捧场热血传奇怀旧版,WeGame拯救计划,前景如何?...
  2. 驰骋工作流引擎设置消息收听
  3. HttpApplication类及派生的Global类
  4. CDH-5.7.0:基于Parcels方式离线安装配置
  5. python spark 配置
  6. mybatis学习(8):The server time zone value '???ú±ê×??±??' is unrecognized or represents more
  7. 立体视觉–stereo correspondence(双目立体匹配)
  8. 012-Java有几种文件拷贝方式?哪一种最高效?
  9. c/c++标准库中的文件操作总结
  10. 关于iOS 7以后自定义UIAlertview(CustomIOS7AlertView)的用法心得
  11. c语言编程伤心代码,C语言恶作剧代码:慎用,被打了不负责
  12. java yyyymmddThhmiss_如何在Javascript中以mm-dd-hh格式获取两个日期的差
  13. centos7,php7.3使用pecl安装swoole,新手教学
  14. Cypress UI 自动化测试框架
  15. Android TV 开发简介
  16. python 不区分大小写的字典实现
  17. 物联网跟人的神经网络相似通过各种信息传感设备
  18. 【Altium秘籍】room 复制报错的解决办法
  19. tomcat配置启动端口和默认项目及默认404
  20. C#联合Halcon打开笔记本摄像头

热门文章

  1. vue3.0中使用百度离线地图
  2. unity shader 流光(1)
  3. win10亮度_安利一款PC端调节多显示器亮度的软件
  4. c++采集声卡输出_windows上面捕获声卡数据
  5. 无线PLC专用数据终端应用方案
  6. FlashFXP v3.5.4注册码+FlashFXP v3.6.0注册码+FlashFXP v3.7.2.build.1266...
  7. java题库管理考试管理源码,基于jsp的题库管理系统-JavaEE实现题库管理系统 - java项目源码...
  8. [内附完整源码和文档] 基于MySql和JSP的题库管理系统
  9. 【WINDOWS / DOS 批处理】添加注释
  10. photoshop印章效果制作