| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- <!DOCTYPE html>
- <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="icon" href="{{asset('icon/faviconc.ico')}}" type="image/x-icon"/>
- <!-- CSRF Token -->
- <meta name="csrf-token" content="{{ csrf_token() }}">
- <title>快递记录</title>
- <link href="{{ mix('css/app.css') }}" rel="stylesheet">
- <style>
- html{
- width: 100%;
- height: 100%;
- }
- body{
- width: 100%;
- height: 100%;
- }
- .bg-suc{
- background: RGB(240,249,235);
- }
- .bg-fail{
- background: RGB(255,240,240);
- }
- </style>
- </head>
- <body allowfullscreen="true">
- <div class="container-fluid w-100 h-100" id="container">
- <div id="toast-container" style="position: absolute;top: 0;width: 100%;z-index: 999"></div>
- <div class="row w-100 h-100">
- <div class="col-4">
- <div class="dropdown">
- <button type="button" class="btn col-5 p-0" id="dropdownMenu"
- data-toggle="dropdown">
- <h4 class="text-muted mt-1">@{{ name }} <i class="fa fa-exchange text-info"></i></h4>
- </button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu">
- <li role="presentation" v-for="warehouse in warehouses" v-if="warehouse.id!==selected">
- <a role="menuitem" tabindex="-1" style="cursor: pointer" class="ml-3"
- @click="selectedWarehouse(warehouse)">@{{ warehouse.name }}</a>
- </li>
- </ul>
- </div>
- <p class="text-center h1 pt-3 font-weight-bold">@{{sum}}</p>
- <p class="text-center text-secondary">本次单量</p>
- <div class="form-group mt-4">
- <label for="logisticNumber">快递单号</label>
- <input class="form-control" disabled id="logisticNumber" placeholder="快递单号"
- v-model="logisticNumber">
- </div>
- <div class="form-group">
- <label for="recordAt">记录时间</label>
- <input class="form-control" disabled id="recordAt" placeholder="记录时间"
- v-model="recordAt">
- </div>
- <button class="btn btn-info col-12 text-white" @click="fullScreen()" style="position:absolute;bottom: 20px;cursor: pointer">
- <span v-if="!full">全屏</span>
- <span v-else>退出全屏</span>
- </button>
- </div>
- <div class="col-8 p-0">
- <p class="bg-white h2 text-center p-2 text-secondary" style="height: 5vh">记录信息</p>
- <div class="w-100" style="height: 93vh;overflow: auto">
- <table class="table w-100 text-center">
- <thead>
- <tr>
- <th>快递单号</th>
- <th>快递公司</th>
- <th>记录时间</th>
- <th>上传状态<button class="ml-1 btn btn-sm btn-outline-primary" @click="failRetry()">失败重传</button></th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="item in data" :class="item.status ? 'bg-suc text-success' : 'bg-fail text-danger'">
- <td>@{{ item.logisticNumber }}</td>
- <td>@{{ item.logistic }}</td>
- <td>@{{ item.recordAt }}</td>
- <td>
- <span v-if="item.status">OK</span>
- <span v-else>FAIL</span>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div>
- </body>
- <script src="{{ mix('js/app.js') }}"></script>
- <script type="text/javascript">
- var vue = new Vue({
- el:"#container",
- data:{
- sum:0,
- data:[
- ],
- warehouses:[@foreach($warehouses as $warehouse)@json($warehouse),@endforeach],
- logisticNumber:"",
- recordAt:"",
- maxLen:20,
- full:false,
- selected:"",
- name:"",
- errorSum:0,
- jwtToken:"{{$jwtToken}}",
- voiceLoadSign:false,
- },
- mounted() {
- this.registerEvent();
- let record = localStorage.getItem("record:warehouse");
- if (record){
- let recordObj = JSON.parse(record);
- this.selected = recordObj.id;
- this.name = recordObj.name;
- }else{
- if (this.warehouses.length>0)this.selectedWarehouse(this.warehouses[0]);
- }
- window.onbeforeunload = e=>{
- if (this.errorSum===0)return;
- e = e || window.event;
- // 兼容IE8和Firefox 4之前的版本
- if (e) {
- e.returnValue = '当前存在失败数据未处理';
- }
- return '当前存在失败数据未处理';
- };
- setTimeout(()=>{
- this.refreshToken();
- },600800000);
- },
- methods:{
- playAudio(src){
- let audio = document.createElement('audio');
- audio.src = src;
- document.body.append(audio);
- setTimeout(()=>{
- audio.play();
- },10);
- setTimeout(()=>{
- audio.remove();
- },5000);
- },
- refreshToken(){
- window.axios.post('{{url('record/refreshToken')}}',{},{
- headers: {
- "jwtToken" : this.jwtToken
- }
- }).then(body=>{
- let res = body.data;
- if (!res.success){
- this.playAudio('storage/logonFailure.mp3');
- this.buildToast(false,"tokenFailure");
- return;
- }
- this.jwtToken = res.data;
- setTimeout(()=>{
- this.refreshToken();
- },600800000);
- }).catch(err=>{
- this.playAudio('storage/networkError.mp3');
- this.buildToast(false,"tokenFailure");
- });
- },
- selectedWarehouse(warehouse){
- this.selected = warehouse.id;
- this.name = warehouse.name;
- localStorage.setItem("record:warehouse", JSON.stringify(warehouse));
- },
- //全屏
- fullScreen() {
- if (this.full){
- this.exitFullscreen();
- return;
- }
- let element = document.documentElement;
- if (element.requestFullscreen) {
- element.requestFullscreen();
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen();
- } else if (element.mozRequestFullScreen) {
- element.mozRequestFullScreen();
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen();
- }
- this.full = true;
- },
- //退出全屏
- exitFullscreen() {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- }
- this.full = false;
- },
- registerEvent(){
- $(document).on('keypress', e=>{
- if (!this.voiceLoadSign){
- this.voiceLoadSign = true;
- let audio = document.createElement('audio');
- let audio1 = document.createElement('audio');
- audio.src = 'storage/logonFailure.mp3';
- audio1.src = 'storage/networkError.mp3';
- document.body.append(audio);
- document.body.append(audio1);
- setTimeout(()=>{
- audio.remove();
- audio1.remove();
- },10);
- }
- if (e.keyCode===13){
- if(this.logisticNumber==="")return;
- this.submitRecord(this.logisticNumber,this.recordAt);
- this.logisticNumber = "";
- this.recordAt = "";
- return;
- }
- if (this.logisticNumber.length===this.maxLen)return;
- if ((e.keyCode>=97 && e.keyCode<=122) || (e.keyCode>=65 && e.keyCode<=90)
- || (e.keyCode>=48 && e.keyCode<=57)){
- if (this.logisticNumber===""){
- let now = new Date();
- let yy = now.getFullYear();
- let mm = now.getMonth() + 1;
- let dd = now.getDate();
- let hh = now.getHours();
- let m = now.getMinutes();
- let ss = now.getSeconds();
- this.recordAt = yy+'-'+(mm<10 ? '0'+mm : mm)+'-'+(dd<10 ? '0'+dd : dd)+" "+(hh<10 ? '0'+hh : hh)+":"+(m<10 ? '0'+m : m)+":"+(ss<10 ? '0'+ss : ss);
- }
- this.logisticNumber += e.key;
- }
- });
- },
- failRetry(){
- this.data.forEach(item=>{
- if (!item.status){
- window.axios.post('{{url('record')}}',{logisticNumber:item.logisticNumber,warehouse:this.selected},{
- headers: {
- "jwtToken" : this.jwtToken
- }
- }).then(body=>{
- let res = body.data;
- let status = true;
- if (!res.success && res.data!=="unique")status = false;
- this.buildToast(status,item.logisticNumber);
- if (status){
- if (res.data!=="unique"){
- item.recordAt = res.data.recordAt;
- item.logistic = res.data.logistic;
- }
- item.status = true;
- this.errorSum--;
- }
- }).catch(err=>{
- this.playAudio('storage/networkError.mp3');
- this.buildToast(false,item.logisticNumber);
- });
- }
- });
- },
- submitRecord(logisticNumber,recordAt){
- window.axios.post('{{url('record')}}',{logisticNumber:logisticNumber,warehouse:this.selected},{
- headers: {
- "jwtToken" : this.jwtToken,
- }
- }).then(body=>{
- let res = body.data;
- let status = true;
- if (!res.success){
- status = false;
- if (res.data==="unique"){
- this.buildToast(false,logisticNumber);
- return;
- }
- }
- this.buildToast(status,logisticNumber);
- this.data.unshift({
- logisticNumber:logisticNumber,logistic:status ? res.data.logistic : "未知",recordAt:status ? res.data.recordAt : recordAt,status:status
- });
- if (!status)this.errorSum++;
- this.sum++;
- }).catch(err=>{
- this.playAudio('storage/networkError.mp3');
- this.buildToast(false,logisticNumber);
- this.data.unshift({
- logisticNumber:logisticNumber,logistic:"未知",recordAt:recordAt,status:false
- });
- this.errorSum++;
- this.sum++;
- });
- },
- buildToast(status,sign){
- let div = document.createElement("div");
- div.className = "d-flex justify-content-center align-items-center p-2";
- let toast = document.createElement("div");
- toast.className = "toast hide";
- toast.setAttribute("role","alert");
- toast.setAttribute("aria-live","assertive");
- toast.setAttribute("aria-atomic","true");
- toast.setAttribute("data-delay","2000");
- toast.id = sign;
- let info = document.createElement("div");
- info.style.width = "400px";
- let txt = document.createElement("div");
- txt.className = "ml-3";
- let i = document.createElement("i");
- if (status){
- info.style.background = "RGB(240,249,235)";
- info.className = "toast-body text-success";
- i.className = "fa fa-chevron-circle-down text-success";
- }else {
- info.style.background = "RGB(255,240,240)";
- info.className = "toast-body text-danger";
- i.className = "fa fa-times-circle text-danger";
- }
- txt.append(i);
- txt.append(document.createTextNode(" 退件记录"+(status ? '成功' : "失败")+"!"));
- info.append(txt);
- toast.append(info);
- div.append(toast);
- $("#toast-container").append(div);
- let jqEl = $("#"+sign);
- jqEl.toast("show");
- jqEl.on("hidden.bs.toast",function (){
- div.remove();
- });
- }
- },
- });
- </script>
- </html>
|