ESP8266開發之旅 小程序之阿里雲篇② “IOT菜鳥”小程序,源碼分析,創作自己的小程序

授人以魚不如授人以漁,目的不是爲了教會你具體項目開發,而是學會學習的能力。希望大家分享給你周邊需要的朋友或者同學,說不定大神成長之路有博哥的奠基石。。。

共同學習成長QQ羣 622368884,不喜勿加,裏面有一大羣志同道合的探路人

快速導航
單片機菜鳥的博客快速索引(快速找到你要的)

重點說一下,麻煩三連點贊,你的點贊是博主創作的前進動力

在這裏插入圖片描述

1. 前言

在上一篇 ESP8266開發之旅 小程序之阿里雲篇① “IOT菜鳥”小程序,小白簡單配置就可以玩起來中,博主教會大家如何使用該小程序,那麼接下來我們就來分析一下源碼,力求讓大家能瞭解其中核心代碼。

2. 讀者知識要求

  • 至少了解過 HTMLCSSJS
  • 至少了解過 微信小程序官方開發文檔
  • 至少要去了解阿里雲物聯網開發文檔
    在這裏插入圖片描述
    這是我們小程序業務請求的重點,也是本篇重中之重

3. 源碼分析

以下就是IOT菜鳥小程序的源碼,麻雀雖小五臟俱全,請讀者認真學習,博主會跳過某些內容(比如教你如何創建小程序、如何創建一個page頁面),重點講解我們需要關注的知識點。
在這裏插入圖片描述

  • components 組件
    公共顯示組件

  • images
    顯示圖標

  • model
    具體業務數據模塊(重點講解內容,也是讀者後面自定義比較多的地方)

  • pages
    具體顯示頁面(會挑控制頁面講解)

  • utils
    工具類方法(重點講解內容)

  • app.xxx
    小程序入口

3.1 app.xxx —— 小程序入口

app.xxx 是整個小程序的入口,我們可以在這裏設置一些整個小程序會使用的數據或者初始化內容。

在這裏插入圖片描述

包含文件:

  • app.js —— 公共JS邏輯,比如一些全局變量
    在這裏插入圖片描述
    這裏定義了我們小程序整個環境需要用到的阿里雲物聯網配置參數,並且配置參數從存儲中讀取,如果沒有我們就填一些默認值開發者也可以填寫自己的默認值,這樣第一次進入小程序的時候就不需要配置了

  • app.json—— 整個小程序的配置
    在這裏插入圖片描述
    開發者可以修改成自己想要的名字

  • app.wxss—— 整個小程序的一些css樣式
    開發者可以把一些公用的css抽取到這裏,就不用每個頁面都寫一遍。

3.2 utils —— 工具類

在這裏插入圖片描述
重點關注:

  • cryptojs 加密簽名相關
  • http.js通用網絡請求相關
  • aliyunHttp.js阿里雲物聯網網絡請求相關,依賴http.js
  • storage.js 存儲配置內容
  • timeFormat.js 時間格式化,阿里雲物聯網對時間格式有要求

這裏通過講解http.js 和 aliyunHttp.js來順帶講解其他工具類。

3.2.1 Http.js —— 通用網絡請求

源碼分析:

/**
 *  HTTP請求工具類
 *  @Date 2020-04-26
 **/

/**
 * 獲取HTTP請求頭
 * @param {Object} currentHeader - 需要配置的請求頭
 * @return {Object} header
 **/
function getHeader(currentHeader) {
    const header = currentHeader || {};
    header['content-type'] = header['content-type'] || 'application/json';
    return header;
}

/**
 * 檢查網絡狀態
 **/
function checkNetwork() {
    return new Promise((resolve, reject) => {
        wx.getNetworkType({
            success: function(res) {
                // 返回網絡類型, 有效值:
                // wifi/2g/3g/4g/unknown(Android下不常見的網絡類型)/none(無網絡)
                const networkType = res.networkType;

                if (networkType === 'none') {
                    wx.showModal({
                        title: '當前網絡不可用,請檢查網絡設置',
                        confirmText: '重試',
                        success: function(res) {
                            if (res.confirm) {
                                checkNetwork();
                            } else {
                                reject(new Error('NetWorkError'));
                            }
                        }
                    });
                } else {
                    resolve();
                }
            }
        });
    });
}

export default {

    request(url, data, method, headers, complete) {
        return new Promise((resolve, reject) => {
            checkNetwork().then(() => {
                wx.request({
                    url: url,
                    data: data,
                    method: method || 'GET', //  OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
                    header: getHeader(headers), // 設置請求的 header
                    success: (res) => {
                        // HTTP響應code
                        if (res.statusCode === 200) {
                            // 需要處理一些公關邏輯,比如公共錯誤業務code等等
                            resolve(res.data);
                        } else {
                            reject(res);
                        }
                    },
                    fail: (err) => {
                        reject(err);
                    },
                    complete
                });
            }).catch(err => {
                console.log(err);
            });
        });
    },

    get(opts = {}) {
        return this.request(opts.url, opts.data, 'GET', opts.headers);
    },

    post(opts = {}) {
        return this.request(opts.url, opts.data, 'POST', opts.headers);
    },
};

  • 我們定義了兩個請求 GETPOST(底層都是調用request)以及一個自定義的 request 方法,讀者可以自定義其他的Method(HEAD、PUT、DELETE等)

  • request是一個Promise,先去判斷網絡情況(沒有連接網絡,沒有就彈出一個model提示用戶),之後就是發起網絡請求 wx.request

  • wx.request中我們會設置一下Header (getHeaders)以及處理 HTTP響應Code,等於200纔會返回,其他Code拋出異常。

非常簡單,都是通用的HTTP協議

3.2.2 aliyunHttp.js —— 針對阿里雲物聯網的網絡請求

  • 讀者必須先去了解 阿里雲物聯網雲端開發指南
  • 重點關注公共邏輯部分
    在這裏插入圖片描述
3.2.2.1 請求結構

在這裏插入圖片描述
下面以調用Pub接口向指定Topic發佈消息爲例:

https://iot.cn-shanghai.aliyuncs.com/?Action=Pub
&Format=XML
&Version=2017-04-20
&Signature=Pc5WB8gokVn0xfeu%2FZV%2BiNM1dgI%3D
&SignatureMethod=HMAC-SHA1
&SignatureNonce=15215528852396
&SignatureVersion=1.0
&AccessKeyId=...
&Timestamp=2017-07-19T12:00:00Z
&RegionId=cn-shanghai
...
  • 一個網絡請求肯定有URL,阿里雲物聯網這個URL需要根據自己的賬號去填寫,IOT菜鳥提供了配置頁面選擇RegionID
  • 這是一個GET請求,涉及了一堆參數,包括公共參數以及業務參數
3.2.2.2 公共參數

在這裏插入圖片描述
示例:

https://iot.cn-shanghai.aliyuncs.com/
?Format=XML
&Version=2018-01-20
&Signature=Pc5WB8gokVn0xfeu%2FZV%2BiNM1dgI%3D
&SignatureMethod=HMAC-SHA1
&SignatureNonce=15215528852396
&SignatureVersion=1.0
&AccessKeyId=...
&Timestamp=2018-05-20T12:00:00Z
&RegionId=cn-shanghai
3.2.2.3 公共返回參數

API返回結果採用統一格式,返回2xx HTTP狀態碼代表調用成功;返回4xx或5xx HTTP狀態碼代表調用失敗。調用成功返回的數據格式有XML和JSON兩種。可以在發送請求時,指定返回的數據格式。默認爲XML格式。

每次接口調用,無論成功與否,系統都會返回一個唯一識別碼RequestId

我們這裏採用JSON。

成功示例:

{
    "RequestId": "4C467B38-3910-447D-87BC-AC049166F216"
    /* 返回結果數據 */
}

失敗示例:

{
    "RequestId": "8906582E-6722-409A-A6C4-0E7863B733A5",
    "Code": "UnsupportedOperation",
    "Message": "The specified action is not supported."
}

在失敗的時候,最好彈一個toast提示用戶。我們可以獲取Message內容。
在aliYunHttp裏面可以看到這個代碼:

/**
 * 處理接口響應內容
 *
 * @param {String} res
 * @param {function} resolve
 * @param {function} reject
 **/
function handleResponse(res, resolve, reject) {
    let { Success } = res;
    if (Success) {
        // api調用成功 返回整個數據
        resolve && resolve(res);
    } else {
        // api調用失敗
        let { RequestId, Code, ErrorMessage} = res;
        wx.showToast({ title: `${Code}:${ErrorMessage}`, icon: 'none' });
        reject && reject({
            RequestId,
            Code,
            ErrorMessage
        });
    }
}
3.2.2.4 簽名機制

物聯網平臺會對每個接口訪問請求的發送者進行身份驗證,所以無論使用HTTP還是HTTPS協議提交請求,都需要在請求中包含簽名(Signature)信息。

內容太多,博主以圖示來說明簽名的重要內容:

  • 構造規範化的請求字符串(Canonicalized Query String
    在這裏插入圖片描述

  • 構造簽名字符串
    在這裏插入圖片描述

  • 計算HMAC
    在這裏插入圖片描述

  • 計算簽名值
    在這裏插入圖片描述

  • 添加簽名
    在這裏插入圖片描述

3.2.2.5 aliyunHttp源碼分析
/**
 *  針對AliYun API的HTTP請求工具類
 *  @Date 2020-04-26
 **/

// 通用網絡請求
import http from './http.js';
import timeFormat from './timeFormat.js';
// 加密模塊
let crypto = require("./cryptojs/cryptojs.js").Crypto;

const app = getApp();

// 配置公共參數
const _defaultParams = () => {
    // 阿里雲要求的公共請求參數  https://help.aliyun.com/document_detail/30561.html?spm=a2c4g.11186623.6.739.6bc03d291aEGp1
    let commonParams = {
        Format: 'JSON', // 返回值的類型,支持JSON和XML類型
        Version: '2018-01-20', // API版本號
        AccessKeyId: app.aliConfig.AccessKeyId, // 阿里雲頒發給用戶的訪問服務所用的密鑰ID
        // Signature: '', // 簽名結果串 需要另外計算  爲了方便 不放在公共參數
        SignatureMethod: 'HMAC-SHA1', // 簽名方式,目前支持HMAC-SHA1
        Timestamp: timeFormat.getCurrentUTCTime('{YYYY}-{MM}-{DD}T{HH}:{mm}:{ss}Z'), // 請求的時間戳,日期格式按照ISO8601標準表示,並需要使用UTC時間。格式爲YYYY-MM-DDThh:mm:ssZ。2016-01-04T12:00:00Z
        SignatureVersion: '1.0', // 簽名算法版本
        SignatureNonce: new Date().getTime() + '', // 唯一隨機數,用於防止網絡重放攻擊。用戶在不同請求中要使用不同的隨機數值
        RegionId: app.aliConfig.RegionId, // 設備所在地域(與控制檯上的地域對應),如cn-shanghai。
    };
    return commonParams;
};

// 將數組參數格式化成url傳參方式
const _flatArrayList = (target, key, Array) => {
    for (let i = 0; i < Array.length; i++) {
        let item = Array[i];

        if (item && typeof item === 'object') {
            const keys = Object.keys(item);
            for (let j = 0; j < keys.length; j++) {
                target[`${key}.${i + 1}.${keys[j]}`] = item[keys[j]];
            }
        } else {
            target[`${key}.${i + 1}`] = item;
        }
    }
};

//將所有請求參數展開平面化,考慮到有些接口給到的參數是數組
const _flatParams = (params) => {
    let target = {};
    let keys = Object.keys(params);
    for (let i = 0; i < keys.length; i++) {
        let key = keys[i];
        let value = params[key];
        if (Array.isArray(value)) {
            _flatArrayList(target, key, value);
        } else {
            target[key] = value;
        }
    }
    return target;
};

// url編碼
const _percentEncode= (str) => {
    let result = encodeURIComponent(str);

    return result.replace(/\!/g, '%21')
        .replace(/\'/g, '%27')
        .replace(/\(/g, '%28')
        .replace(/\)/g, '%29')
        .replace(/\*/g, '%2A');
};

/**
 * 構造規範化的請求字符串
 * @param {Object} params 請求參數,不包括Signature
 * @return {String} result 格式:key1=value1&key2=value2....
 **/
const _getCanonicalizedQueryString = (params) => {
    let list = [];
    let flatParams = _flatParams(params);
    Object.keys(flatParams).sort().forEach((key) => {
        let value = flatParams[key];
        list.push([_percentEncode(key), _percentEncode(value)]);
    });

    let queryList = [];
    for (let i = 0; i < list.length; i++) {
        let [key, value] = list[i];
        queryList.push(key + '=' + value);
    }
    return queryList.join('&');
};

/**
 * 獲取加密字符串
 * @param {String} stringToSign 請求方法
 * @param {Object} key 簽名key
 **/
const _signature = (stringToSign, key) => {
    let signature = crypto.HMAC(crypto.SHA1, stringToSign, key, {
        asBase64: true
    });

    return signature;
};

/**
 * 處理接口響應內容
 *
 * @param {String} res
 * @param {function} resolve
 * @param {function} reject
 **/
function handleResponse(res, resolve, reject) {
    let { Success } = res;
    if (Success) {
        // api調用成功 返回整個數據
        resolve && resolve(res);
    } else {
        // api調用失敗
        let { RequestId, Code, ErrorMessage} = res;
        wx.showToast({ title: `${Code}:${ErrorMessage}`, icon: 'none' });
        reject && reject({
            RequestId,
            Code,
            ErrorMessage
        });
    }
}

let aliyunApi = {

    /**
     * AliyunApi GET請求
     * @param {Object} opts 包含請求參數、請求URL、請求頭
     **/
    get(opts = {}) {
        opts.url = opts.url || app.aliConfig.EndPoint;
        // 獲取公共參數
        let defaultParams = _defaultParams();
        // 合併參數
        opts.data = Object.assign(defaultParams,opts.data);
        let canonicalizedQueryString = _getCanonicalizedQueryString(opts.data);
        let stringToSign = `GET&${_percentEncode('/')}&${_percentEncode(canonicalizedQueryString)}`;
        //console.log(stringToSign);
        let signature = _signature(stringToSign, app.aliConfig.AccessKeySecret + '&');
        // 補上 Signature參數
        opts.data = {
            ...opts.data,
            Signature: signature
        };

        return new Promise((resolve, reject) => {
            http.get(opts).then((res) => {
                handleResponse(res, resolve, reject);
            }).catch(err => {
                console.log(err);
            })
        });
    },

    /**
     * AliyunApi POST請求
     * @param {Object} opts 包含請求參數、請求URL、請求頭
     **/
    post(opts = {}) {
        opts.url = opts.url || app.aliConfig.EndPoint;
        // 獲取公共參數
        let defaultParams = _defaultParams();
        // 合併參數
        opts.data = Object.assign(defaultParams,opts.data);
        let canonicalizedQueryString = _getCanonicalizedQueryString(opts.data);
        let stringToSign = `POST&${_percentEncode('/')}&${_percentEncode(canonicalizedQueryString)}`;
        let signature = _signature(stringToSign, app.aliConfig.AccessKeySecret + '&');
        // 補上 Signature參數
        opts.data = {
            ...opts.data,
            Signature: signature
        };

        opts.headers = opts.headers || {};
        opts.headers['content-type'] = 'application/x-www-form-urlencoded';

        return new Promise((resolve, reject) => {
            http.post(opts).then((res) => {
                handleResponse(res, resolve, reject);
            }).catch(err => {
                console.log(err);
            })
        });
    }
};

export { aliyunApi };

注意: 讀者需要從 get/post 方法開始閱讀,博主在裏面註釋都非常清晰
在這裏插入圖片描述

  • 公共參數
    在這裏插入圖片描述
  • 構造規範化的請求字符串 —— _getCanonicalizedQueryString
    在這裏插入圖片描述
  • 構造簽名字符串 —— stringToSign
let stringToSign = `POST&${_percentEncode('/')}&${_percentEncode(canonicalizedQueryString)}`;
  • 生成簽名值
    在這裏插入圖片描述
    到這裏,阿里雲API底層源碼講解完畢,接下來會講解具體業務。

3.3 model —— 具體業務請求

具體業務相關內容,博主放在了model目錄,當前小程序用到了設備管理。
在這裏插入圖片描述
關於設備管理,請讀者自行查閱
在這裏插入圖片描述
對應代碼如下:

/**
 *  針對AliYun 設備管理API請求
 *  https://help.aliyun.com/document_detail/69893.html?spm=a2c4g.11186623.6.736.5fcd342dh5UEoS
 *
 *  @Date 2020-04-27
 **/

import { aliyunApi } from '../../utils/aliyunHttp.js';

const app = getApp();

let deviceApi = {

    /**
     * 在指定產品下注冊設備
     *
     * @param {Object} param 請求參數
     * {
     *      DeviceName: xxxx,
     *      Nickname: xxxx
     * }
     **/
    registerDevice(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'RegisterDevice',
                ProductKey: app.aliConfig.ProductKey,
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 查詢指定設備的詳細信息
     *
     * @param {Object} param 請求參數
     * {
     *      IotId: xxxxx,
     * }
     **/
    queryDeviceDetail(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'QueryDeviceDetail',
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 批量查詢設備詳情。
     *
     * @param {Object} param 請求參數
     * {
     *      DeviceName: [
     *      ],
     * }
     **/
    batchQueryDeviceDetail(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'BatchQueryDeviceDetail',
                ProductKey: app.aliConfig.ProductKey,
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 查詢指定產品下的所有設備列表,分頁接口
     *
     * @param {Object} param 請求參數
     * {
     *      PageSize: xxxx,
     *      CurrentPage: xxxx
     * }
     **/
    queryDevice(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'QueryDevice',
                ProductKey: app.aliConfig.ProductKey,
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 刪除指定設備
     *
     * @param {Object} param 請求參數
     * {
     *      IotId: xxxxx,
     * }
     **/
    deleteDevice(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'DeleteDevice',
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 查看指定設備的運行狀態
     *
     * @param {Object} param 請求參數
     * {
     *      IotId: xxxxx,
     * }
     **/
    getDeviceStatus(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'GetDeviceStatus',
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 批量查看同一產品下指定設備的運行狀態。
     *
     * @param {Object} param 請求參數
     * {
     *      IotId: [
     *      ],
     * }
     **/
    batchGetDeviceState(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'BatchGetDeviceState',
                ProductKey: app.aliConfig.ProductKey,
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 禁用指定設備
     *
     * @param {Object} param 請求參數
     * {
     *      IotId: xxxxxx,
     * }
     **/
    disableThing(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'DisableThing',
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 解除指定設備的禁用狀態,即啓用被禁用的設備
     *
     * @param {Object} param 請求參數
     * {
     *      IotId: xxxxxx,
     * }
     **/
    enableThing(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'EnableThing',
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 查詢指定設備的屬性記錄
     *
     * @param {Object} param 請求參數
     * {
     *      Identifier: xxxxxx,
     *      PageSize: xxxxx,
     *      IotId: xxxxx
     * }
     **/
    queryDevicePropertyData(param = {}) {
        let opts = {
            data: {
                ...param,
                Asc: 0,
                EndTime: new Date().getTime() + '',
                StartTime: '',// 要轉成上線那天的時間
                Action: 'QueryDevicePropertyData',
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 調用該接口批量修改設備備註名稱
     *
     * @param {Object} param 請求參數
     * {
     *      DeviceNicknameInfo.N.IotId: xxxxx,
     *      DeviceNicknameInfo.N.Nickname: xxxxx
     * }
     **/
    updateDeviceNickname(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'BatchUpdateDeviceNickname',
            }
        };
        return aliyunApi.get(opts);
    },

    /**
     * 調用該接口爲指定設備設置屬性值
     *
     * @param {Object} param 請求參數
     * {
     *      IotId: xxxxx,
     *      Items: xxxxx
     * }
     **/
    setDeviceProperty(param = {}) {
        let opts = {
            data: {
                ...param,
                Action: 'SetDeviceProperty',
            }
        };
        return aliyunApi.get(opts);
    },


};

export { deviceApi };

每個接口都有對應的方法,並且攜帶上自己的自定義參數,非常簡單。

3.4 pages —— 展示頁面

展示頁面均放在pages下面。目前用到了index和config
在這裏插入圖片描述
我們這裏以分析index頁面爲例。請讀者自行看代碼註釋

//index.js
//獲取應用實例
import {deviceApi} from "../../model/aliyun/device";
import {storage} from "../../utils/storage";
const app = getApp();

Page({
  _data: {
      PageSize: 50,
      CurrentPage: 1,
  },

  data: {
      deviceOnLine: [],//在線設備
      deviceOffLine: [],//離線設備
      deviceUnative: [],//未激活設備
      deviceDisable: [],//已禁用設備
      showConfig: false,
  },
  onLoad: function () {
  },

  onShow() {
      if (!app.aliConfig.RegionId || !app.aliConfig.AccessKeyId
          || !app.aliConfig.ProductKey
          || !app.aliConfig.EndPoint){
          this.setData({
              showConfig: true
          });
      } else {
          this.setData({
              showConfig: false
          });
          wx.showLoading({
              title: '努力加載中...',
              mask: true
          });
          this.loadDeviceList();
      }
  },

  onPullDownRefresh() {
      this.loadDeviceList();
  },

  loadDeviceList() {
      // 先清空數據
      this.setData({
          deviceOnLine: [],
          deviceOffLine: [],
          deviceUnative: [],
          deviceDisable: [],
      }, () => {
          this._data.CurrentPage = 1; //從第一頁開始
          this.queryDevice(this._data.PageSize, this._data.CurrentPage);
      });
  },

  // 查詢設備
  queryDevice(pageSize = 50, currentPage = 1) {
      // 調用model device的api
      deviceApi.queryDevice({
          PageSize: pageSize,
          CurrentPage: currentPage,
      }).then((res) => {
          if (res.Data && res.Data.DeviceInfo) {
              this.handleDeviceList(res.Data.DeviceInfo);
              // 判斷是否需要繼續請求
              if (res.PageCount > this._data.CurrentPage) {
                  this._data.CurrentPage ++;
                  this.queryDevice(this._data.PageSize, this._data.CurrentPage);
              } else {
                  this.finishQueryDevice();
              }
          } else {
              this.finishQueryDevice();
          }
      }).catch(err => {
          console.log(err);
          this.finishQueryDevice();
      });
  },

  finishQueryDevice(){
      wx.stopPullDownRefresh();
      wx.hideLoading && wx.hideLoading();
  },

  // 處理列表返回內容
  handleDeviceList(deviceList) {
      let deviceOnLine = [];
      let deviceOffLine = [];
      let deviceUnative = [];
      let deviceDisable = [];

      // 如果你是試用過了小程序 是不是覺得led1 led2非常熟悉呢?這裏就是原因了
      if(deviceList && Array.isArray(deviceList)) {
           deviceList.forEach((device) => {
              let type;
              if (device.Nickname.indexOf('_led2') > -1) {
                  type = '_led2';
              } else if (device.Nickname.indexOf('_led3') > -1) {
                  type = '_led3';
              } else if (device.Nickname.indexOf('_lamp1') > -1) {
                  type = '_lamp1';
              } else if (device.Nickname.indexOf('_lamp2') > -1) {
                  type = '_lamp2';
              } else {
                  type = '_led1';
              }
              this.setDevice(device,type);

              if (device.DeviceStatus === 'ONLINE') {
                  deviceOnLine.push(device);
              } else if (device.DeviceStatus === 'OFFLINE') {
                  deviceOffLine.push(device);
              } else if (device.DeviceStatus === 'UNACTIVE') {
                  deviceUnative.push(device);
              } else if (device.DeviceStatus === 'DISABLE') {
                  deviceDisable.push(device);
              }
           });
      }
      this.setData({
          deviceOnLine: this.data.deviceOnLine.concat(deviceOnLine),
          deviceOffLine: this.data.deviceOffLine.concat(deviceOffLine),
          deviceUnative: this.data.deviceUnative.concat(deviceUnative),
          deviceDisable: this.data.deviceDisable.concat(deviceDisable),
      });
  },

  setDevice(device, type) {
      device.Nickname = device.Nickname.replace(type, '');
      if (device.DeviceStatus === 'ONLINE' || device.DeviceStatus === 'OFFLINE') {
          device.Image = `/images/icon${type}_on.png`;
      } else  {
          device.Image = `/images/icon${type}_off.png`;
      }
  },
  // 跳轉配置頁面
  goToConfig() {
      console.log('goToConfig');
      wx.navigateTo({
          url: '/pages/config/config',

      });
  }
});

4. 總結

本篇主要是簡單講解IOT菜鳥小程序的源碼,包括:

  • http
  • aliyunhttp
  • page/index

整體難度不高,也實現了博主的初衷,爲IOT事業做貢獻。

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
喜歡的同學,請不要跑了,給博主點個贊,你的點贊是博主前進的動力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章