需求變更
拆包出現異常,需要留下照片憑證,以防后期抵賴。這當然屬於手機端功能,於是強烈向電商老板推薦手機客戶端。
另外近期出現了一個奇怪的bug,經常掃碼時重復出現同一個編碼,明明已經掃了別的碼了,系統里接收一的還是前一個。非常難復現,初步懷疑是掃碼槍的緩存功能造成的,但沒有辦法根治,造成倉庫抱怨。於是將掃碼入庫功能也加到手機客戶端上,並控制該功能只允許在倉庫使用(GPS定位,划定區域內使用,有點電子圍欄的意思)。
開發過程中,封裝了幾個組件,版本升級已放到uni的插件市場上,我寫了一個非常詳細的使用方法,歡迎大家免費下載,順手打個星。
https://ext.dcloud.net.cn/plugin?id=3931
主要功能預覽
1. 登錄
在線升級支持多種皮膚定制,支持強制升級和非強制升級,支持下載進度並中途中斷升級,支持ios下載升級(企業證書)和appstore升級。圖片截的有點高高低低的,湊合看吧。



2. 拆包檢驗
默認出現列表供拆包,也可以快速掃條形碼進入檢驗。列表上拉翻頁下拉刷新用的是MescrollBody,比uni自帶的那個好用且體驗好很多。
多照片布局直接用的colorui。最多支持9張照片上傳。

3. 掃碼入庫
界面應該是首頁,后面應該會做成首頁。
業務邏輯跟電腦客戶端一致,先選擇快遞公司,然后掃碼入庫,不同的是,手機端不會暫存,直接調單個入庫接口上傳服務器。


4. 照片補錄
為保證補錄的是當前快遞的照片,不允許列表選擇和手動輸入單號,只能掃碼拍照,最多支持9張照片。

5. 關於
現在界面上還叫“我的”,應該叫“關於”更合適點。功能比較少。我從colorui里把wave.gif扒出來了,頂部圖片顯示波紋效果,看着就很舒服了,我特意截了一個 gif

部分代碼
1. 封裝一個httpclient用於請求網絡。
由於每次請求都有簽名驗證、時間戳等參數一同上傳,就封了一個js文件。多圖片上傳,本來也准備封到這個js里,結果服務端只能收到一張,h5端正常,已向dcloud報了bug,有了解的同學也請幫忙回復下:https://ask.dcloud.net.cn/question/115109
function request(url, data = {}, type = 'GET', header = { }){ let ts = util.gettimestamp(); let transid = util.gettransid(ts); let sign = util.getsign(transid); const baseUrl = getApp().globalData.serverInterfaceUrl data.ts = ts data.transid = transid data.sign = sign return new Promise((resolve, reject) => { uni.request({ method: type, url: baseUrl + url, data: data, header: header, dataType: 'json', }).then((response) => { console.log(response) setTimeout(function() { uni.hideLoading(); }, 200); let [error, res] = response; resolve(res.data); }).catch(error => { let [err, res] = error; console.log(err) reject(err) }) }); }
調用:
httpclient.request('user',{method:"login","uname":that.user_name,"ucode":that.password}
).then(res=>{
if(res.code == 100){
//登錄成功
if(that.remember_username){
uni.setStorageSync("remember_username",true)
}
if(that.remember_password){
uni.setStorageSync("remember_password",true)
}
//寫入其他緩存.......
//跳轉首頁
uni.switchTab({
url:'../index/index'
})
}else{
uni.showToast({
title: '登錄失敗:'+res.msg,
icon:'none'
});
}
});
2. 升級業務代碼也放下吧,不解釋了。差分升級還在實現中,暫未放在代碼里。
<template>
<view class="zy-modal" :class="dshow?'show':''">
<view class="zy-dialog" style="background-color: transparent;">
<view class="padding-top text-white" :class="'zy-upgrade-topbg-'+theme">
<view>
<text class="zy-upgrade-title">
發現新版本
</text>
</view>
<text class="flex-wrap">{{version}}</text>
</view>
<view class="padding-xl bg-white text-left">
<scroll-view style="max-height: 200rpx;" scroll-y="auto" v-if="!update_flag">
<text>{{update_tips}}</text>
</scroll-view>
<view class="zy-progress radius striped active" v-if="update_flag">
<view :class="'bg-'+theme" :style="'width: '+update_process+'%;'">
{{update_process}}
</view>
</view>
</view>
<view class="zy-bar bg-white justify-end">
<view class="action" v-if="!update_flag">
<button class="zy-btn" :class="'bg-'+theme" @click="upgrade_checked">確認升級</button>
<button class="zy-btn margin-left" :class="'line-'+theme"
v-if="!forceupgrade"
@click="upgrade_cancel">取消升級</button>
</view>
<view class="action text-center" v-if="update_flag&&!forceupgrade">
<button class="zy-btn" :class="'bg-'+theme" @click="upgrade_break">中斷升級</button>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'ZyUpgrade',
props: {
theme: { //主題,目前支持green,pink,blue,yellow,red
type: String,
default: 'green'
},
updateurl: { //升級檢測url,全路徑
type:String,
default: ''
},
h5preview:{ //H5界面下是否預覽升級
type: Boolean,
default: false
},
oldversion: { //如果是H5,為了方便測試,可以傳入一個舊版本號進來。
type: String,
default: ''
},
oldcode: { //如果是H5,為了方便測試,可以傳一個舊版本的code進來。
type: Number,
default: 0
},
appstoreflag: { //是否啟用appstore升級,如果啟用,由服務端返回appstore的地址
type: Boolean,
default: false
},
noticeflag:{ //是否通知主界面無需更新
type:Boolean,
default: false
},
autocheckupdate:{ //是否頁面截入時就判斷升級
type:Boolean,
default: false
}
},
data() {
return {
update_flag: false, //點擊升級按鈕后,顯示進度條
dshow: false,
update_process: 0,
downloadTask: [],
updated2version: '',
version_url: '',
update_tips: '',
forceupgrade: false,
currentversion: this.oldversion,
versionname: '',
vesioncode: this.oldcode
}
},
mounted() {
let app_flag = false
// #ifdef APP-PLUS
app_flag = true
// #endif
if((this.h5preview || app_flag) && this.autocheckupdate){
console.log("檢測升級")
this.check_update()
}
},
computed:{
version(){
let retversion = ''
retversion = this.currentversion + (this.currentversion!=''&&this.updated2version!=''?'->':'')+this.updated2version
return retversion
}
},
methods:{
//檢測升級
check_update(){
let that = this
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {
that.currentversion = widgetInfo.version
that.versionname = widgetInfo.name
that.versioncode = widgetInfo.versionCode
that.updatebusiness(that)
});
// #endif
// #ifdef H5
if(this.h5preview){
this.updatebusiness(that)
}
// #endif
},
updatebusiness: function(that){ //具體升級的業務邏輯
uni.showLoading({
title: '',
mask: false
});
let platform = uni.getSystemInfoSync().platform
let formdata = {
method: "upgrade",
version: that.currentversion,
name: that.versionname,
code: that.versioncode,
ts:'123',
transid:'123',
sign:'123',
platform: platform
}
uni.request({
url: that.updateurl,
data: formdata,
success: (result) => {
uni.hideLoading()
let data = result.data
if(data.code == 100){
console.log(data)
//提示升級
if(data.data.update_flag == 1){
that.dshow = true
that.update_tips = data.data.update_tips
that.forceupgrade = data.data.forceupdate==1
that.version_url = data.data.update_url
//that.currentversion = widgetInfo.version
that.updated2version = data.data.version
}else{
if(that.noticeflag){
//通知父組件,當前版為最新版本
that.$emit("showupdateTips",0)
}
}
}else{
uni.showToast({
title: '請求升級出錯:'+data.msg,
icon:'none'
});
}
}
});
},
//點擊開始升級按鈕,開始升級
upgrade_checked:function(){
this.update_flag = true
this.updateversion()
},
//點擊取消升級按鈕,取消升級
upgrade_cancel:function(){
this.dshow = false
},
//升級過程中,點擊中斷升級按鈕,中斷升級
upgrade_break: function(){
this.downloadTask.abort()
this.update_flag = false
},
//升級下載apk安裝包的具體處理業務邏輯
updateversion: function(){
let platform = uni.getSystemInfoSync().platform
console.log("操作系統:",platform)
if(platform == 'ios' && this.appstoreflag){
//如果啟用ios appstore升級,則打開appstore
that.dshow = false
console.log("跳轉至appstore")
plus.runtime.launchApplication({
action: that.version_url
}, function(e) {
uni.showToast({
title: '打開appstore失敗',
icon:'none'
});
});
}else{
let that = this
this.update_confirm = true
this.downloadTask = uni.downloadFile({
url: that.version_url,
success:function(res){
if(res.statusCode == 200){
//開始安裝
plus.runtime.install(res.tempFilePath, {
force: false
}, function() {
console.log('install success...');
plus.runtime.restart();
}, function(e) {
console.error('install fail...');
});
}else{
uni.showToast({
title: '下載失敗,網絡錯誤',
icon:'none'
});
}
},
fail:function(e) {
console.log("下載失敗",e)
uni.showToast({
title: '下載失敗:'+e.errMsg,
icon:'none'
});
this.update_flag = false
},
complete:function(){
}
})
this.downloadTask.onProgressUpdate(function(res){
that.update_process = res.progress
})
}
},
}
}
</script>
<style scoped>
@import url("static/css/main.css");
.zy-upgrade-topbg-green {
background-image: url('static/images/green.png');
background-size: 100% 100%;
background-repeat: no-repeat;
height: 290rpx;
}
.zy-upgrade-topbg-red {
background-image: url('static/images/red.png');
background-size: 100% 100%;
background-repeat: no-repeat;
height: 290rpx;
}
.zy-upgrade-topbg-pink {
background-image: url('static/images/pink.png');
background-size: 100% 100%;
background-repeat: no-repeat;
height: 290rpx;
}
.zy-upgrade-topbg-yellow {
background-image: url('static/images/yellow.png');
background-size: 100% 100%;
background-repeat: no-repeat;
height: 290rpx;
}
.zy-upgrade-topbg-blue {
background-image: url('static/images/blue.png');
background-size: 100% 100%;
background-repeat: no-repeat;
height: 290rpx;
}
.zy-upgrade-title {
font-size: 50rpx;
color: white;
}
</style>
其他代碼不放了,都是一些輪子。
