快递扫码入库PC系统

news/2024/11/18 0:42:00/

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

一、界面样式

主要功能:

  • 扫码入库,无线,有线扫码枪均可。
  • 断点后自动续存编号,比如之前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>

八、遗憾

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

http://www.ppmy.cn/news/163081.html

相关文章

快递查询API(最新)

快递查询api 1、获取快递单号对应的物流公司&#xff1a; 接口&#xff1a;https://m.kuaidi100.com/autonumber/auto 访问参数&#xff1a; num&#xff1a;物流单号 如&#xff1a;获取 物流单号对应物流公司信息 https://m.kuaidi100.com/autonumber/auto?num7512148872…

快递100开放快递查询接口

http://www.kuaidi100.com/query?type快递运营商名&postid快递单号 type支持的快递公司及参数说明&#xff1a;https://cdn.kuaidi100.com/download/chaxun(20140729).doc PHP请求查询快递方式&#xff1a; 请求地址&#xff1a; 正式环境请求地址&#xff1a;https:/…

快递100物流查询插件免费开放啦

快递100是中国领先的快递物流信息服务商&#xff0c;国家高新技术企业、产业互联网代表企业&#xff0c;是国内查询量最大的快递物流信息查询平台。为帮助所有的开发者能够解决物流查询问题&#xff0c;快递100一直为开发者免费开放了物流接入能力&#xff0c;让开发者能为自己…

韵达快递 | 快递单号查询API

如何利用快递鸟提供的接口来查询韵达快递的物流轨迹。 讲解之前我们来看一下&#xff0c;接口完成以后的实际显示效果 以下是产品应用截图&#xff0c;调用快递鸟接口获得的轨迹信息&#xff1a; 实际上快递鸟返回的报文信息会更详细&#xff0c;在给客户展示的信息可根据产品…

快递100 实时查询

$post_data array(); $post_data["customer"] 公司编号; $key ; $post_data["param"] {"com":"快递类型","num":"快递单号"}; $urlhttp://poll.kuaidi100.com/poll/query.do; $post_data["sign"] …

利用快递100api查询快递信息

同时也分享一个火车票查询的&#xff1a; 接口估计不能用了&#xff0c;新的接口php写的&#xff0c;可以研究下。 http://www.widuu.com/archives/01/919.html &#xff0c;欢迎吐槽。 火车余票查询源码地址&#xff08;接口已经不可用&#xff09;&#xff1a;http://do…

一个快速批量查询快递物流数据的小工具,可同时多种快递物流信息跟踪查件

前几天写了一个用于快递批量查询并分类的小工具&#xff0c;适合快递网点或者商家用于物流或者问题件的状态跟踪。 支持批量查询&#xff0c;支持不同快递单号混合一起查询。方便物流跟踪查件&#xff0c;本程序仅一个程序文件绿色免安装下载解压即可运行。 下载地址1&#x…

极兔快递 | 快递单号查询API

本期讲解&#xff1a;极兔快递查询快递单号的方法。 纯干货&#xff0c;强烈建议收藏/转发给技术人员和管理人员学习。 提供源码&#xff0c;复制到你的项目上,就能快速完成快递鸟的极兔快递查询API接口。 下面具体讲解实现过程&#xff1a; 1.完成前期准备工作 1.1,注册快…