一、將 proto 文件轉(zhuǎn)成 json 文件
需要先下載 protobufjs-cli 依賴
npm i -D protobufjs-cli
然后再當(dāng)前目錄下的終端,執(zhí)行以下命令
npx pbjs -t json proto/test.proto > proto/test.json
proto/test.proto > proto/test.json :意思是找到當(dāng)前目錄的 proto 文件夾下的 test.proto 文件,將該文件轉(zhuǎn)為 test.json 并將該文件放到 proto 文件夾下
二、使用 test.json 文件
npm i -S protobufjs
由于收到數(shù)據(jù)是二進(jìn)制的,雖然拿到的 proto 文件的 json 結(jié)構(gòu),但這還是不能直接使用,還需要下轉(zhuǎn) protobufjs 依賴,將收到的二進(jìn)制數(shù)據(jù)根據(jù) test.json 文件轉(zhuǎn)成對應(yīng)的 json 結(jié)構(gòu)
import protobuf from "protobufjs";
import protoJson from "./proto/test.json";
?
// 使用 protobufjs 拿到 test.json 的 json 結(jié)構(gòu)
const root = protobuf.Root.fromJSON(protoJson);
// 找到要翻譯的包和字段
const protoData = root.lookupType("interface_message.GeneralDetectionMapData");
?
// data是收到二進(jìn)制數(shù)據(jù),使用 decode 方法,將二進(jìn)制數(shù)據(jù)根據(jù)【包和字段】轉(zhuǎn)成 json 結(jié)構(gòu)的數(shù)據(jù),該過程簡稱:解密
const data = protoData.decode(data);
?
// 當(dāng)需要發(fā)送修改過后的 proto 數(shù)據(jù)發(fā)送給后端時,使用 encode 可將數(shù)據(jù)轉(zhuǎn)成 proto 結(jié)構(gòu)的數(shù)據(jù),該過程簡稱:加密
const protoData = protoData.encode(data).finish()
例如:
const serverUrl = 'http://192.168.200.200:7081';
var protobuf = require('@/weichatPb/protobuf.js');
const awesomeConfig = require('@/proto/order.js');
var AwesomeRoot = protobuf.Root.fromJSON(awesomeConfig);
// 錯誤結(jié)果
var ErrorRequest = AwesomeRoot.lookupType("ErrorMessage");
// 結(jié)果sucess
var OperationGeneralResp = AwesomeRoot.lookupType("OperationGeneralResp");
// 獲取驗(yàn)證碼
var VerificationCodeResp = AwesomeRoot.lookupType("VerifyCodeMessage"); // 獲取驗(yàn)證碼結(jié)果
// 登錄
var SignInRes = AwesomeRoot.lookupType("UserLogInRequest"); // 登錄傳值
var SignInResp = AwesomeRoot.lookupType("LoginResp"); // 登錄結(jié)果
// 獲取初始信息 --> 1:銷售 2:商務(wù)
var AuthorInitRes = AwesomeRoot.lookupType("AuthorizationFileTicketInitReq"); // 傳值
var AuthorInitResp = AwesomeRoot.lookupType("AuthorizationFileTicketInitResp"); // 結(jié)果
// 查詢授權(quán)工單
var SearchAuthorRes = AwesomeRoot.lookupType("GetAuthorizationFileTicketReq"); // 傳值
var SearchAuthorResp = AwesomeRoot.lookupType("SalesGetAuthorizationFileTicketResp"); // 結(jié)果
// 新建授權(quán)工單
var AddAuthorRes = AwesomeRoot.lookupType("AddAuthorizationFileTicketReq"); // 傳值
// 關(guān)閉工單
var DelRes = AwesomeRoot.lookupType("CloseAuthorizationFileTicketReq"); // 傳值
// 修改工單
var UpdateRes = AwesomeRoot.lookupType("EditAuthorizationFileTicketReq"); // 傳值
// 審核工單
var ProcessRes = AwesomeRoot.lookupType("AuditAuthorizationFileTicketReq"); // 傳值
// 下載附件
var AnnexRes = AwesomeRoot.lookupType("DeleteAuthFileAttachmentReq"); // 傳值
// 上傳附件
var UpAnnexRes = AwesomeRoot.lookupType("AddAuthFileAttachmentReq"); // 傳值
const timeout = 15000;
export class Api {
// 公共發(fā)送請求體
static _request(url, requestBuffer, resMode) {
var promise = new Promise((resolve, reject) => {
var that = this;
uni.request({
url: serverUrl + url,
method: "POST",
dataType: 'protobuf',
data: requestBuffer,
responseType: "arraybuffer",
timeout: timeout,
header: {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/octet-stream",
},
success(res) {
if (res.statusCode == 200) {
var deMessage = resMode.decode(res.data);
} else {
var deMessage = ErrorRequest.decode(res.data);
}
resolve(deMessage);
},
error: function (e) {
reject("網(wǎng)絡(luò)出錯");
console.log("網(wǎng)絡(luò)出錯")
}
});
});
return promise;
}
// 序列化數(shù)據(jù)
static getUnit8Data(Message, payload) {
var message = Message.create(payload);
var buffer = Message.encode(message).finish();
var requestBuffer = new Uint8Array([...buffer]).buffer;
return requestBuffer
}
// 獲取初始信息
static async getAuthInit(payload) {
var url = "/AuthorizationFileTicketInit";
var requestBuffer = Api.getUnit8Data(AuthorInitRes, payload)
const res = await Api._request(url, requestBuffer, AuthorInitResp);
console.log(res)
return res;
}
// 新建授權(quán)工單
static async setAuthData(payload) {
var url = "/AddAuthorizationFileTicket";
var requestBuffer = Api.getUnit8Data(AddAuthorRes, payload)
const res = await Api._request(url, requestBuffer, OperationGeneralResp);
console.log(res)
return res;
}
// 查詢授權(quán)工單
static async getAuthData(payload) {
var url = "/GetAuthorizationFileTicket";
var requestBuffer = Api.getUnit8Data(SearchAuthorRes, payload)
const res = await Api._request(url, requestBuffer, SearchAuthorResp);
console.log(res)
return res;
}
// 關(guān)閉工單
static async getDel(payload) {
var url = "/CloseAuthorizationFileTicket";
var requestBuffer = Api.getUnit8Data(DelRes, payload)
const res = await Api._request(url, requestBuffer, OperationGeneralResp);
console.log(res)
return res;
}
// 修改工單
static async getUpdate(payload) {
var url = "/EditAuthorizationFileTicket";
var requestBuffer = Api.getUnit8Data(UpdateRes, payload)
const res = await Api._request(url, requestBuffer, OperationGeneralResp);
console.log(res)
return res;
}
// 審核工單
static async getProcess(payload) {
var url = "/AuditAuthorizationFileTicket";
var requestBuffer = Api.getUnit8Data(ProcessRes, payload)
const res = await Api._request(url, requestBuffer, OperationGeneralResp);
console.log(res)
return res;
}
// 刪除附件
static async getAnnex(payload) {
var url = "/DeleteAuthFileAttachment";
var requestBuffer = Api.getUnit8Data(AnnexRes, payload)
const res = await Api._request(url, requestBuffer, OperationGeneralResp);
console.log(res)
return res;
}
// 上傳附件
static async getUpAnnex(payload) {
var url = "/AddAuthFileAttachment";
var requestBuffer = Api.getUnit8Data(UpAnnexRes, payload)
const res = await Api._request(url, requestBuffer, OperationGeneralResp);
console.log(res)
return res;
}
// 獲取驗(yàn)證碼
static async getVerificationCode() {
let payload = {}
var url = "/GenerateVerificationCode";
var requestBuffer = Api.getUnit8Data(AuthorInitRes, payload)
const res = await Api._request(url, requestBuffer, VerificationCodeResp);
return res;
}
// 登錄
static async getSignIn(payload) {
var url = "/UserLogin";
var requestBuffer = Api.getUnit8Data(SignInRes, payload)
const res = await Api._request(url, requestBuffer, SignInResp);
return res;
}
}
三、微信小程序插件網(wǎng)址
四、vant-weapp網(wǎng)址
五、文本讀取文件
// this.fileList3 格式如上圖所示即可
if (this.fileList3 != 0) {
for (let i = 0; i < this.fileList3.length; i++) {
const fm = wx.getFileSystemManager(); // 獲取文件管理器
var arrayBuffer = new ArrayBuffer(`${this.fileList3[i].size}`);
try {
var fd = fm.openSync({
filePath: this.fileList3[i].path,
});
fm.readSync({
fd: fd,
arrayBuffer: arrayBuffer, //數(shù)據(jù)寫入的緩沖區(qū)
length: this.fileList3[i].size, //讀取的字節(jié)數(shù),默認(rèn)0
}); // 讀取文件內(nèi)容
// var enc = new TextDecoder("utf-8");
// var fileContent = enc.decode(arrayBuffer); //將ArrayBuffer轉(zhuǎn)為字符串
filesAll.push({
name: this.fileList3[i].name,
file: new Uint8Array(arrayBuffer),
});
fm.closeSync({ fd: fd }); // 關(guān)閉文件
} catch (exception) {
console.log("onShow >> 讀文件失敗, 異常消息: ", exception);
}
}
}
六、字符串內(nèi)容轉(zhuǎn)arraybuffer
微信小程序 JS 字符串string與utf8編碼的arraybuffer的相互轉(zhuǎn)換
 最近在做一個微信小程序,和后端用websocket連接,后端要求傳輸過去的信息是UTF8編碼的二進(jìn)制信息。JS并沒有可以直接進(jìn)行轉(zhuǎn)換的庫函數(shù),因此必須自己寫一個編碼以及解析的函數(shù)。
????最開始采用了一個字符一個字符的charCodeAt,但是通過這種方式可以傳輸非中文的內(nèi)容,有中文時則無法正確的轉(zhuǎn)換。
????后來參考了網(wǎng)上的一些資料,通過先將字符串編碼并轉(zhuǎn)換為byte[],再轉(zhuǎn)換為對應(yīng)的arraybuffer(解析同理,先將arraybuffer轉(zhuǎn)換為byte[],再進(jìn)行解碼)
????編碼及解碼的過程較復(fù)雜,不過這兩個函數(shù)是可以直接使用的,同時支持中文和英文。
????字符串內(nèi)容轉(zhuǎn)arraybuffer
stringToArrayBuffer(str) {
var bytes = new Array();
var len, c;
len = str.length;
for (var i = 0; i < len; i++) {
c = str.charCodeAt(i);
if (c >= 0x010000 && c <= 0x10ffff) {
bytes.push(((c >> 18) & 0x07) | 0xf0);
bytes.push(((c >> 12) & 0x3f) | 0x80);
bytes.push(((c >> 6) & 0x3f) | 0x80);
bytes.push((c & 0x3f) | 0x80);
} else if (c >= 0x000800 && c <= 0x00ffff) {
bytes.push(((c >> 12) & 0x0f) | 0xe0);
bytes.push(((c >> 6) & 0x3f) | 0x80);
bytes.push((c & 0x3f) | 0x80);
} else if (c >= 0x000080 && c <= 0x0007ff) {
bytes.push(((c >> 6) & 0x1f) | 0xc0);
bytes.push((c & 0x3f) | 0x80);
} else {
bytes.push(c & 0xff);
}
}
var array = new Int8Array(bytes.length);
for (var i in bytes) {
array[i] = bytes[i];
}
return array.buffer;
},
arraybuffer轉(zhuǎn)字符串內(nèi)容
function arrayBufferToString(arr){
if(typeof arr === 'string') {
return arr;
}
var dataview=new DataView(arr.data);
var ints=new Uint8Array(arr.data.byteLength);
for(var i=0;i<ints.length;i++){
ints[i]=dataview.getUint8(i);
}
arr=ints;
var str = '',
_arr = arr;
for(var i = 0; i < _arr.length; i++) {
var one = _arr[i].toString(2),
v = one.match(/^1+?(?=0)/);
if(v && one.length == 8) {
var bytesLength = v[0].length;
var store = _arr[i].toString(2).slice(7 - bytesLength);
for(var st = 1; st < bytesLength; st++) {
store += _arr[st + i].toString(2).slice(2);
}
str += String.fromCharCode(parseInt(store, 2));
i += bytesLength - 1;
} else {
str += String.fromCharCode(_arr[i]);
}
}
return str;
}
七、微信小程序頁面跳轉(zhuǎn) 的幾種方式
wx.navigateTo(OBJECT)
保留當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面, 小程序中左上角有一個返回箭頭,可返回上一個頁面,也可以通過方法 wx.navigateBack 返回原頁面.
wx.redirectTo(OBJECT)
關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面, 左上角沒有返回箭頭,不能返回上一個頁面
wx.redirectTo(OBJECT)
關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面, 左上角沒有返回箭頭,不能返回上一個頁面
wx.switchTab(OBJECT)
跳轉(zhuǎn)到 tabBar 頁面,并關(guān)閉其他所有非 tabBar 頁面, wx.navigateTo 和 wx.redirectTo 不允許跳轉(zhuǎn)到 tabbar 頁面,只能用 wx.switchTab 跳轉(zhuǎn)到 tabbar 頁面
wx.reLaunch(OBJECT)
關(guān)閉所有頁面,打開到應(yīng)用內(nèi)的某個頁面, 跟wx.redirectTo 一樣左上角不會出現(xiàn)返回箭頭,但兩者卻不完全相同
這里要提到小程序中的 getCurrentPages() 方法,在wx.navigateTo中,每跳轉(zhuǎn)一個新的頁面,其原始頁面就會被加入堆棧,通過調(diào)用wx.navigateBack(OBJECT)可通過獲取堆棧中保存的頁面 返回上一級或多級頁面
wx.redirectTo,方法則不會被加入堆棧,但仍可通過wx.navigateBack(OBJECT)方法返回之前堆棧中的頁面
wx.reLaunch 方法則會清空當(dāng)前的堆棧文章來源:http://www.zghlxwxcb.cn/news/detail-425821.html
例如: A跳轉(zhuǎn)到B,B跳轉(zhuǎn)到C,C navigateBack,將返回b頁面文章來源地址http://www.zghlxwxcb.cn/news/detail-425821.html
// 此處是A頁面
wx.navigateTo({
url: 'B?id=1'
})
// 此處是B頁面
wx.navigateTo({
url: 'C?id=1'
})
// 在C頁面內(nèi) navigateBack,將返回b頁面
wx.navigateBack({
delta: 1
})
// 此處是B頁面
wx.redirectTo({
url: 'C?id=1'
})
// 在C頁面內(nèi) navigateBack,則會返回a頁面
wx.navigateBack({
delta: 1
})
// 此處是B頁面
wx.reLaunch({
url: 'C?id=1'
})
// 在C頁面內(nèi) navigateBack,則無效
到了這里,關(guān)于微信小程序 開發(fā)中的問題(simba_wx)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!