微信小程序实现WiFi打卡的思路

2022/9/4 分享

昨天在实现WiFi打卡时,因为是第一次实现这种需求,故在此记录一下。

# 起因

昨天在判断用户是否是使用指定WiFi时,发现了一个bug。

我们都知道,打开/关闭WiFi有两个途径:

  1. 系统设置里的WiFi开关
  2. 手机界面右上角的状态栏中的WiFi开关

那么此时问题就来了,如果查询微信小程序文档时,会找到通过wx.getSystemInfo()来获取WiFi开关的状态

// 回调函数返回的属性中有个wifiEnabled,它表明WiFi开关的状态
wx.getSystemInfo({
  success(res) {
    console.log(res.wifiEnabled)
    if (res.wifiEnabled) {
      // wx.startwifi() 初始化WiFi模块
      // wx.connectWifi() 连接WiFi
      // wx.onWifiConnected() 监听WiFi连接
      // 成功则发送签到打卡请求
    }
  }
})

如果是以上方案,那么就会漏掉一个重要的因素:手机界面右上角的状态栏中的WiFi开关,因为wifiEnabled仅仅表明系统设置里面的WiFi开关状态

模拟一个情况

​ 先连上指定的WiFi,调用wx.getSystemInfo(),获取到了wifiEnabled且值为true,wx.onWifiConnected()回调成功的函数并发送签到打卡请求...

​ 但此时,如果将手机界面右上角的状态栏中的WiFi开关关闭(此时手机设置里的WiFi开关依然是开启状态,但手机右上角的状态栏中的WiFi开关是关闭状态),此时依然会触发wx.onWifiConnected()并执行成功的回调,进而发送签到打卡请求

# 解决

​ 虽然关闭了右上角的状态栏中的WiFi开关仍会触发签到打卡请求,但此时手机使用的是流量,而非WiFi

​ 抓住这一点,就可以成功实现WiFi签到打卡的需求

大概流程

  1. 首先判断用户手机设置中是否开启WiFi,如果没有则不进行接下来的操作
  2. 如果手机设置中开启了WiFi,那么接下来获取手机的网络类型
    • 如果网络类型不是WiFi,则提示用户连接指定WiFi后再签到,不进行接下来的操作
    • 如果网络类型是WiFi,需要判断用户连接的WiFi是否是指定的WiFi
      • 如果是指定的WiFi,则发送签到打卡请求

流程代码

onDuty() {
	let that = this
	// 判断手机设置有没有打开WiFi开关
	wx.getSystemInfo({
		success(res) {
			that.isOpenMobileWifi = res.wifiEnabled
			if (!that.isOpenMobileWifi) {
				uni.showToast({
					icon: "error",
					title: "请打开WiFi开关",
					duration: 2000
				})
		} else {
			let SSID = "指定的WiFi的名称"
			let BSSID = "指定的WiFi的MAC地址"
      // 获取网络类型
      wx.getNetworkType({
        success(res) {
          if (res.networkType !== "wifi") {
            uni.showToast({
              icon: "error",
              title: "请连接工作室WiFi",
              duration: 2000
            })
          } else {
            // 判断是不是工作室的WiFi
            wx.getConnectedWifi({
              success(res) {
                if (res.wifi.SSID === SSID && res.wifi.BSSID === BSSID) {
                  that.isSuccess = true
                  uni.request({
                    url: '签到打卡请求',
                    method: 'GET',
                    header: {
                      "Authorization": uni.getStorageSync('tokenHead') + ' ' + uni.getStorageSync('token')
                    },
                    data: {
                      place: that.isSuccess,
                      success: that.isSuccess,
                      type: 2
                    },
                    success(res) {
                      if (res.data.code === 200) {
                        uni.showToast({
                          icon: 'success',
                          title: "签到成功",
                          duration: 2000
                        })
                      }
                      if (res.data.code === 401) {
                        uni.showToast({
                          icon: 'error',
                          title: "请先登录",
                          duration: 2000
                        })
                      }
                      if (res.data.code === 500) {
                        uni.showToast({
                          icon: 'error',
                          title: "本周不是你值班",
                          duration: 2000
                        })
                      }
                    }
                  })
                }
              }
            })
          }
        }
      })
    }
    }
  })
}

# 总结

使用网络进行打卡签到时,尤其注意手机设置手机右上角状态栏的区别,流程倒不难理解,在此mark一下。