diff --git a/App.vue b/App.vue
index c67ca08..15ddf32 100644
--- a/App.vue
+++ b/App.vue
@@ -1,16 +1,41 @@
-
-
diff --git a/pages/home/home.vue b/pages/home/home.vue
new file mode 100644
index 0000000..d96a461
--- /dev/null
+++ b/pages/home/home.vue
@@ -0,0 +1,317 @@
+
+
+
+
+
+
+
+
+
+
+
+ 填加锁时,手机必须在锁旁边
+
+
+
+
+ {{group.groupName}}
+
+
+
+
+
+
+
+
+ {{lock.electricQuantity}}%
+
+ {{getRole(lock.userType)}}
+
+
+ {{lock.lockName}}
+
+ {{ getTimeLimit(lock.keyType) }}
+
+ {{ timeFormat(lock.startDate, 'yyyy-mm-dd h:M') }}
+ {{ timeFormat(lock.endDate, 'yyyy-mm-dd h:M ') + getTimeLimit(lock.keyType) }}
+
+
+
+
+
+
+
+
+
+
+ 登录
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
index 320385f..c4ed272 100644
--- a/pages/index/index.vue
+++ b/pages/index/index.vue
@@ -1,68 +1,205 @@
-
-
- {{title}}{{userInfo.name}}
-
-
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
+
+
+
+ 名称:{{currentLockInfo.name}}
+ 设备Id:{{currentLockInfo.deviceId}}
+
-
diff --git a/pages/lockDetail/lockDetail.vue b/pages/lockDetail/lockDetail.vue
new file mode 100644
index 0000000..608c2be
--- /dev/null
+++ b/pages/lockDetail/lockDetail.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/pages/mine/mine.vue b/pages/mine/mine.vue
new file mode 100644
index 0000000..05c5914
--- /dev/null
+++ b/pages/mine/mine.vue
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+ 个人信息
+
+
+
+
+
+
+ 公司介绍
+
+
+
+
+ 用户协议
+
+
+
+
+ 隐私政策
+
+
+
+ 退出
+
+
+ 登录
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/safeQuestion/safeQuestion.vue b/pages/safeQuestion/safeQuestion.vue
new file mode 100644
index 0000000..7b59ca3
--- /dev/null
+++ b/pages/safeQuestion/safeQuestion.vue
@@ -0,0 +1,137 @@
+
+
+ 如果手机丢了,可以通过回答设置的安全问题来登录新设备
+
+
+ {{item.question}}
+
+
+
+
+
+ 修改
+
+
+
+
+
+
+
+
diff --git a/pages/searchDevice/searchDevice.vue b/pages/searchDevice/searchDevice.vue
new file mode 100644
index 0000000..608c2be
--- /dev/null
+++ b/pages/searchDevice/searchDevice.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/pages/updateEmail/updateEmail.vue b/pages/updateEmail/updateEmail.vue
new file mode 100644
index 0000000..cc45226
--- /dev/null
+++ b/pages/updateEmail/updateEmail.vue
@@ -0,0 +1,209 @@
+
+
+
+
+
+ {{text}}
+
+ 确定
+
+
+
+
+
+
+
+
diff --git a/pages/updateName/updateName.vue b/pages/updateName/updateName.vue
new file mode 100644
index 0000000..97f7538
--- /dev/null
+++ b/pages/updateName/updateName.vue
@@ -0,0 +1,110 @@
+
+
+
+ 保存
+
+
+
+
+
+
+
+
diff --git a/pages/updatePassword/updatePassword.vue b/pages/updatePassword/updatePassword.vue
new file mode 100644
index 0000000..11462b3
--- /dev/null
+++ b/pages/updatePassword/updatePassword.vue
@@ -0,0 +1,143 @@
+
+
+
+
+
+ 密码必须是8-20位,至少包括数字/字母/符号中的2种
+ 保存
+
+
+
+
+
+
+
+
diff --git a/pages/updateSafeQuestion/updateSafeQuestion.vue b/pages/updateSafeQuestion/updateSafeQuestion.vue
new file mode 100644
index 0000000..53d323f
--- /dev/null
+++ b/pages/updateSafeQuestion/updateSafeQuestion.vue
@@ -0,0 +1,252 @@
+
+
+ 如果手机丢了,可以通过回答设置的安全问题来登录新设备
+
+
+ {{answer[0].question}}
+
+
+
+
+
+
+
+ {{answer[1].question}}
+
+
+
+
+
+
+
+ {{answer[2].question}}
+
+
+
+
+
+ 保存
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/userInfo/userInfo.vue b/pages/userInfo/userInfo.vue
new file mode 100644
index 0000000..6ada060
--- /dev/null
+++ b/pages/userInfo/userInfo.vue
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+ 昵称
+
+ {{userInfo.nickname}}
+
+
+
+
+
+ 手机号
+
+ {{userInfo.mobile}}
+
+
+
+
+
+
+ 邮箱
+
+ {{userInfo.email}}
+
+
+
+
+
+
+ 重置密码
+
+
+
+
+ 安全问题
+
+
+
+
+
+
+
+ 国家/地区
+
+ {{userInfo.countryName}}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/verifyEmail/verifyEmail.vue b/pages/verifyEmail/verifyEmail.vue
new file mode 100644
index 0000000..d041c40
--- /dev/null
+++ b/pages/verifyEmail/verifyEmail.vue
@@ -0,0 +1,182 @@
+
+
+
+
+ {{text}}
+
+ 下一步
+
+
+
+
+
+
+
+
diff --git a/pages/webview/webview.vue b/pages/webview/webview.vue
new file mode 100644
index 0000000..29ca69c
--- /dev/null
+++ b/pages/webview/webview.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
diff --git a/static/images/background_mine.png b/static/images/background_mine.png
new file mode 100644
index 0000000..41ee0d6
Binary files /dev/null and b/static/images/background_mine.png differ
diff --git a/static/images/icon_add.png b/static/images/icon_add.png
new file mode 100644
index 0000000..d0f9a4d
Binary files /dev/null and b/static/images/icon_add.png differ
diff --git a/static/images/icon_arrow.png b/static/images/icon_arrow.png
new file mode 100644
index 0000000..a0a91ec
Binary files /dev/null and b/static/images/icon_arrow.png differ
diff --git a/static/images/icon_lock.png b/static/images/icon_lock.png
new file mode 100644
index 0000000..7997525
Binary files /dev/null and b/static/images/icon_lock.png differ
diff --git a/static/images/icon_power.png b/static/images/icon_power.png
new file mode 100755
index 0000000..ceeeb8d
Binary files /dev/null and b/static/images/icon_power.png differ
diff --git a/static/images/tabbar_key_no_select.png b/static/images/tabbar_key_no_select.png
new file mode 100644
index 0000000..ea6aa06
Binary files /dev/null and b/static/images/tabbar_key_no_select.png differ
diff --git a/static/images/tabbar_key_select.png b/static/images/tabbar_key_select.png
new file mode 100644
index 0000000..2adb1a3
Binary files /dev/null and b/static/images/tabbar_key_select.png differ
diff --git a/static/images/tabbar_mine_no_select.png b/static/images/tabbar_mine_no_select.png
new file mode 100644
index 0000000..5cd3e24
Binary files /dev/null and b/static/images/tabbar_mine_no_select.png differ
diff --git a/static/images/tabbar_mine_select.png b/static/images/tabbar_mine_select.png
new file mode 100644
index 0000000..4864337
Binary files /dev/null and b/static/images/tabbar_mine_select.png differ
diff --git a/static/logo.png b/static/logo.png
deleted file mode 100644
index b5771e2..0000000
Binary files a/static/logo.png and /dev/null differ
diff --git a/stores/basic.js b/stores/basic.js
new file mode 100644
index 0000000..43e57e0
--- /dev/null
+++ b/stores/basic.js
@@ -0,0 +1,124 @@
+import { defineStore } from 'pinia'
+
+// 页面配置
+const pages = [
+ {
+ name: 'home',
+ path: '/pages/home/home',
+ tabBar: true
+ },
+ {
+ name: 'mine',
+ path: '/pages/mine/mine',
+ tabBar: true
+ },
+ {
+ name: 'userInfo',
+ path: '/pages/userInfo/userInfo',
+ tabBar: false
+ },
+ {
+ name: 'updateName',
+ path: '/pages/updateName/updateName',
+ tabBar: false
+ },
+ {
+ name: 'updatePassword',
+ path: '/pages/updatePassword/updatePassword',
+ tabBar: false
+ },
+ {
+ name: 'updateEmail',
+ path: '/pages/updateEmail/updateEmail',
+ tabBar: false
+ },
+ {
+ name: 'verifyEmail',
+ path: '/pages/verifyEmail/verifyEmail',
+ tabBar: false
+ },
+ {
+ name: 'safeQuestion',
+ path: '/pages/safeQuestion/safeQuestion',
+ tabBar: false
+ },
+ {
+ name: 'updateSafeQuestion',
+ path: '/pages/updateSafeQuestion/updateSafeQuestion',
+ tabBar: false
+ },
+ {
+ name: 'webview',
+ path: '/pages/webview/webview',
+ tabBar: false
+ },
+ {
+ name: 'lockDetail',
+ path: '/pages/lockDetail/lockDetail',
+ tabBar: false
+ },
+ {
+ name: 'searchDevice',
+ path: '/pages/searchDevice/searchDevice',
+ tabBar: false
+ }
+]
+
+
+export const useBasicStore = defineStore('basic', {
+ state() {
+ return {
+ // 设备信息
+ deviceInfo: null,
+ // 胶囊按钮的位置信息
+ buttonInfo: null
+ }
+ },
+ actions: {
+ // 路由跳转
+ /* data 入参 name string页面名称 type string跳转方式 params object传递参数 delta number返回页面数
+ * 具体入参查看文档 https://www.uviewui.com/js/route.html */
+ routeJump(data) {
+ const page = pages.find((page) => {
+ return page.name === data.name
+ })
+ if (page) {
+ uni.$u.route({
+ url: page.path,
+ ...data
+ })
+ }
+ },
+ // 获取设备信息
+ getDeviceInfo() {
+ const that = this
+ return new Promise((resolve) => {
+ if (that.deviceInfo?.model) {
+ resolve(that.deviceInfo)
+ return
+ }
+ uni.getSystemInfo({
+ success: function (res) {
+ that.deviceInfo = res
+ resolve(that.deviceInfo)
+ },
+ fail: function () {
+ resolve({})
+ }
+ })
+ })
+ },
+ // 获取胶囊信息
+ getButtonInfo() {
+ return new Promise((resolve, reject) => {
+ if (this.buttonInfo?.top) {
+ resolve(this.buttonInfo)
+ return
+ }
+ this.buttonInfo = uni.getMenuButtonBoundingClientRect()
+ resolve(this.buttonInfo)
+ return
+ })
+ },
+ }
+})
diff --git a/stores/bluetooth.js b/stores/bluetooth.js
new file mode 100644
index 0000000..541e2a7
--- /dev/null
+++ b/stores/bluetooth.js
@@ -0,0 +1,1024 @@
+/**
+ * @description 蓝牙数据持久化
+ */
+import { defineStore } from 'pinia'
+import crc from 'crc'
+import { sm4 } from 'sm-crypto'
+import { md5 } from 'js-md5'
+
+// 定时器
+let timer
+// 特性值回调
+let characteristicValueCallback = null
+
+// 命令ID
+const cmdIds = {
+ // 获取公钥
+ getPublicKey: 0x3090,
+ // 获取私钥
+ getCommKey: 0x3091,
+ // 获取锁状态
+ getLockStatus: 0x3040,
+ // 新增用户
+ addUser: 0x3001,
+ // 开门
+ openDoor: 0x3005,
+ // 重置设备
+ resetDevice: 0x3004,
+ // 清理用户
+ cleanUser: 0x300C,
+ // 扩展命令
+ expandCmd: 0x3030
+}
+
+// 子命令ID
+const subCmdIds = {
+ // 设置开锁密码
+ setLockPassword: 3,
+ // 重置开锁密码
+ resetLockPassword: 19
+}
+
+export const useBluetoothStore = defineStore('ble', {
+ state() {
+ return {
+ /*
+ * 蓝牙状态
+ * -1 未知(初始状态)
+ * 0 正常
+ * 1 系统蓝牙未打开
+ * 2 小程序蓝牙功能被禁用
+ * 3 系统蓝牙未打开且小程序蓝牙功能被禁用
+ */
+ bluetoothStatus: -1,
+ // 设备列表
+ deviceList: [],
+ // 当前锁信息
+ currentLockInfo: {},
+ // 消息序号
+ messageCount: 1,
+ // 是否初始化蓝牙
+ isInitBluetooth: false
+ }
+ },
+ actions: {
+ // 初始化并监听
+ async initAndListenBluetooth() {
+ // 初始化蓝牙
+ const initResult = await this.initBluetooth()
+ if (initResult) {
+ // 更新蓝牙初始化状态
+ this.updateInitBluetooth(true)
+ // 监听蓝牙开关状态
+ this.onBluetoothState()
+ // 监听蓝牙连接状态
+ this.onBluetoothConnectStatus()
+ // 监听设备特征值变化
+ this.onBluetoothCharacteristicValueChange()
+
+ return true
+ } else {
+ return false
+ }
+ },
+ // 更新是否初始化蓝牙字段
+ updateInitBluetooth(value) {
+ this.isInitBluetooth = value
+ },
+ // 初始化蓝牙模块
+ initBluetooth() {
+ const that = this
+ // 初始化蓝牙模块
+ return new Promise(resolve => {
+ uni.openBluetoothAdapter({
+ success() {
+ that.bluetoothStatus = 0
+ console.log('蓝牙初始化成功')
+ resolve(true)
+ },
+ fail(err) {
+ console.log('蓝牙初始化失败', err)
+ // 系统蓝牙未打开
+ if(err.errCode === 10001) {
+ if(that.bluetoothStatus === 2) {
+ that.bluetoothStatus = 3
+ } else {
+ that.bluetoothStatus = 1
+ }
+ }
+ // 小程序蓝牙功能被禁用
+ if(err.errno === 103) {
+ if(that.bluetoothStatus === 1) {
+ that.bluetoothStatus = 3
+ } else {
+ that.bluetoothStatus = 2
+ }
+ }
+ // 蓝牙已经初始化
+ if(err.errMsg === 'openBluetoothAdapter:fail already opened') {
+ resolve(true)
+ return
+ }
+ resolve(false)
+ }
+ })
+ })
+ },
+ // 监听蓝牙状态变化
+ onBluetoothState() {
+ const that = this
+ uni.onBluetoothAdapterStateChange((res) => {
+ console.log('蓝牙状态改变', res)
+ if(that.bluetoothStatus === 3 && res.available) {
+ that.bluetoothStatus = 2
+ } else if (that.bluetoothStatus === 2 && !res.available) {
+ that.bluetoothStatus = 3
+ } else if (that.bluetoothStatus === 1 && res.available) {
+ that.bluetoothStatus = 0
+ } else if (that.bluetoothStatus === 0 && !res.available){
+ that.bluetoothStatus = 1
+ } else if (that.bluetoothStatus === -1) {
+ if(res.available) {
+ that.bluetoothStatus = 0
+ } else {
+ that.bluetoothStatus = 1
+ }
+ }
+ })
+ },
+ // 监听蓝牙设备连接状态
+ onBluetoothConnectStatus() {
+ const that = this
+ uni.onBLEConnectionStateChange(function (res) {
+ if(res.deviceId === that.currentLockInfo.deviceId) {
+ console.log('设备连接状态改变', res)
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ connected: res.connected
+ })
+ }
+ })
+ },
+ // 解析特征值
+ parsingCharacteristicValue(binaryData) {
+ const that = this
+ // 0x20 明文 0x22 SM4(事先约定密钥) 0x23 SM4(设备指定密钥)
+ if(binaryData[7] === 0x20) {
+ if(binaryData[12] * 256 + binaryData[13] === cmdIds.getPublicKey) {
+ if(binaryData[14] === 0) {
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ publicKey: binaryData.slice(15, 31)
+ })
+ }
+ characteristicValueCallback({
+ code: binaryData[14]
+ })
+ }
+ } else if(binaryData[7] === 0x22) {
+ // 截取入参
+ const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
+ // 解密
+ const key = new Uint8Array(16)
+ for (let i = 0; i < that.currentLockInfo.name.length; i++) {
+ key[i] = that.currentLockInfo.name.charCodeAt(i)
+ }
+ const decrypted = sm4.decrypt(cebBinaryData, key, { mode: 'ecb', output: 'array' })
+ console.log('ecb解密后的数据', decrypted)
+
+ if(decrypted[0] * 256 + decrypted[1] === cmdIds.getCommKey) {
+ if(decrypted[2] === 0) {
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ commKey: decrypted.slice(3, 19),
+ signKey: decrypted.slice(19, 35)
+ })
+ console.log('commKey', Array.from(that.currentLockInfo.commKey))
+ console.log('signKey', Array.from(that.currentLockInfo.signKey))
+ }
+ characteristicValueCallback({
+ code: decrypted[2]
+ })
+ }
+ } else {
+ const cebBinaryData = binaryData.slice(12, binaryData.length - 2)
+ const decrypted = sm4.decrypt(cebBinaryData, that.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
+ console.log('ecb解密后的数据', decrypted)
+
+ const cmdId = decrypted[0] * 256 + decrypted[1]
+
+ switch (cmdId) {
+ case cmdIds.getLockStatus:
+ if (decrypted[2] === 0) {
+ const lockConfig = {
+ vendor: decrypted.slice(3, 23),
+ product: decrypted[23],
+ model: decrypted.slice(24, 44),
+ fwVersion: decrypted.slice(44, 64),
+ hwVersion: decrypted.slice(64, 84),
+ serialNum0: decrypted.slice(84, 100),
+ serialNum1: decrypted.slice(100, 116),
+ btDeviceName: decrypted.slice(116, 132),
+ battRemCap: decrypted[132],
+ battRemCapStandby: decrypted[133],
+ restoreCounter: decrypted.slice(134, 136),
+ restoreDate: decrypted.slice(136, 140),
+ icPartNo: decrypted.slice(140, 150),
+ inDate: decrypted.slice(150, 154),
+ mac: decrypted.slice(154, 174),
+ featurevalueLength: decrypted[174],
+ featureValue: decrypted.slice(175, 175 + decrypted[174]),
+ featureEnValLength: decrypted[175 + decrypted[174]],
+ featureEnVal: decrypted.slice(176 + decrypted[174], 176 + decrypted[174] + decrypted[175 + decrypted[174]]),
+ }
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ lockConfig
+ })
+ console.log('获取锁状态成功', that.currentLockInfo.lockConfig)
+ }
+ characteristicValueCallback({
+ code: decrypted[2]
+ })
+ break
+ case cmdIds.addUser:
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ token: decrypted.slice(42,46)
+ })
+ characteristicValueCallback({
+ code: decrypted[46]
+ })
+ break
+ case cmdIds.expandCmd:
+ const subCmdId = decrypted[3]
+ switch (subCmdId) {
+ case subCmdIds.resetLockPassword:
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ token: decrypted.slice(5,9)
+ })
+ characteristicValueCallback({
+ code: decrypted[2]
+ })
+ if(decrypted[2] === 0) {
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ encrpyKey: decrypted.slice(9, 17)
+ })
+ }
+ break
+ case subCmdIds.setLockPassword:
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ token: decrypted.slice(5,9)
+ })
+ characteristicValueCallback({
+ code: decrypted[2],
+ data: {
+ status: decrypted[11]
+ }
+ })
+ break
+ }
+ break
+ default:
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ token: decrypted.slice(2,6)
+ })
+ characteristicValueCallback({
+ code: decrypted[6]
+ })
+ break
+ }
+ }
+ },
+ // 监听蓝牙设备特征值改变
+ onBluetoothCharacteristicValueChange() {
+ const that = this
+ // 完整数据
+ let completeArray
+ // 完整内容数据长度
+ let length
+ console.log('开始监听特征值改变')
+ uni.onBLECharacteristicValueChange(function (res) {
+ if(res.deviceId === that.currentLockInfo.deviceId) {
+ let binaryData = new Uint8Array(res.value)
+ if(binaryData[0] === 0xEF && binaryData[1] === 0x01 && binaryData[2] === 0xEE && binaryData[3] === 0x02) {
+ length = binaryData[8] * 256 + binaryData[9]
+ if(length + 14 > binaryData.length) {
+ completeArray = binaryData
+ } else {
+ that.parsingCharacteristicValue(binaryData)
+ }
+ } else {
+ if(completeArray) {
+ const combinedArray = new Uint8Array(completeArray.length + binaryData.length)
+ combinedArray.set(completeArray, 0);
+ combinedArray.set(binaryData, completeArray.length)
+ completeArray = combinedArray
+ if(length + 14 === completeArray.length) {
+ that.parsingCharacteristicValue(completeArray)
+ completeArray = null
+ }
+ }
+ }
+ }
+ })
+ },
+ // 开始搜索蓝牙设备
+ getBluetoothDevices() {
+ const that = this
+ if(this.bluetoothStatus !== 0) {
+ console.log('搜索未执行', this.bluetoothStatus)
+ this.getBluetoothStatus()
+ return
+ }
+ uni.startBluetoothDevicesDiscovery({
+ success: function (res) {
+ setTimeout(() => {
+ that.searchBluetoothDevices()
+ }, 300)
+ },
+ fail: async function (res) {
+ console.log('开始搜索失败', res)
+ if(res.errCode === 10000) {
+ // 重新初始化蓝牙适配器
+ await that.initBluetooth()
+ that.getBluetoothDevices()
+ }
+ }
+ })
+ },
+ // 定时查询蓝牙设备
+ searchBluetoothDevices() {
+ const that = this
+ if(this.bluetoothStatus !== 0) {
+ console.log('搜索未执行', this.bluetoothStatus)
+ this.getBluetoothStatus()
+ return
+ }
+ timer = setInterval(() => {
+ uni.getBluetoothDevices({
+ success(res) {
+ const deviceList = res.devices
+ that.deviceList = []
+ for(let i = 0; i < deviceList.length; i++) {
+ if(deviceList[i]?.advertisServiceUUIDs) {
+ const uuid = deviceList[i]?.advertisServiceUUIDs[0]
+ if(uuid && uuid.slice(2,8)==='758824' && uuid.slice(30,32)==='00') {
+ that.deviceList.push(deviceList[i])
+ }
+ }
+ }
+ console.log('设备列表', that.deviceList)
+ },
+ fail: async function (res) {
+ console.log('获取设备列表失败', res)
+ if(res.errCode === 10000) {
+ // 重新初始化蓝牙适配器
+ await that.initBluetooth()
+ }
+ }
+ })
+ }, 1000)
+ },
+ // 停止搜索蓝牙设备
+ stopGetBluetoothDevices() {
+ clearInterval(timer)
+ uni.stopBluetoothDevicesDiscovery()
+ },
+ // 蓝牙状态提示
+ getBluetoothStatus() {
+ if(this.bluetoothStatus === 1) {
+ uni.showModal({
+ title: '提示',
+ content: '蓝牙尚未打开,请先打开蓝牙',
+ showCancel: false,
+ confirmText: '确定',
+ })
+ } else if(this.bluetoothStatus === 2 || this.bluetoothStatus === 3) {
+ uni.showModal({
+ title: '提示',
+ content: '小程序蓝牙功能被禁用,请打开小程序蓝牙权限',
+ showCancel: false,
+ confirmText: '去设置',
+ success(res) {
+ if(res.confirm) {
+ uni.openSetting()
+ }
+ }
+ })
+ }
+ },
+ // 检查小程序设置
+ checkSetting() {
+ const that = this
+ return new Promise((resolve) => {
+ uni.getSetting({
+ async success(res) {
+ const bluetooth = res.authSetting['scope.bluetooth']
+ if(that.bluetoothStatus === -1) {
+ if(bluetooth !== false) {
+ that.bluetoothStatus = 0
+ } else {
+ that.bluetoothStatus = 2
+ }
+ } else if(that.bluetoothStatus === 0 && bluetooth === false) {
+ that.bluetoothStatus = 2
+ } else if(that.bluetoothStatus === 1 && bluetooth === false) {
+ that.bluetoothStatus = 3
+ } else if(that.bluetoothStatus === 2 && bluetooth !== false) {
+ that.bluetoothStatus = 0
+ await that.initBluetooth()
+ } else if(that.bluetoothStatus === 3 && bluetooth !== false) {
+ that.bluetoothStatus = 1
+ await that.initBluetooth()
+ that.onBluetoothState()
+ }
+ console.log('蓝牙权限', bluetooth, that.bluetoothStatus)
+ resolve(bluetooth)
+ },
+ fail() {
+ resolve(false)
+ }
+ })
+ })
+ },
+ // 连接蓝牙设备+获取设备服务+获取设备特征值
+ connectBluetoothDevice() {
+ const that = this
+ return new Promise((resolve) => {
+ if(that.bluetoothStatus !== 0) {
+ console.log('连接未执行', that.bluetoothStatus)
+ that.getBluetoothStatus()
+ resolve(false)
+ return
+ }
+ uni.createBLEConnection({
+ deviceId: that.currentLockInfo.deviceId,
+ success(res) {
+ console.log('连接成功', res)
+ // 获取设备服务
+ uni.getBLEDeviceServices({
+ deviceId: that.currentLockInfo.deviceId,
+ success (res) {
+ let serviceId
+ for(let i = 0; i < res.services.length; i++) {
+ if(res.services[i].isPrimary) {
+ serviceId = res.services[i].uuid
+ }
+ }
+ // 获取设备对应服务的特征值
+ uni.getBLEDeviceCharacteristics({
+ deviceId: that.currentLockInfo.deviceId,
+ serviceId: serviceId,
+ success (res) {
+ let notifyCharacteristicId
+ let writeCharacteristicId
+ for(let i = 0; i < res.characteristics.length; i++) {
+ const characteristic = res.characteristics[i]
+ if(characteristic.properties.notify) {
+ notifyCharacteristicId = characteristic.uuid
+ }
+ if(characteristic.properties.write) {
+ writeCharacteristicId = characteristic.uuid
+ }
+ }
+ that.updateCurrentLockInfo({
+ ...that.currentLockInfo,
+ serviceId,
+ notifyCharacteristicId,
+ writeCharacteristicId
+ })
+ that.notifyBluetoothCharacteristicValueChange()
+ resolve(true)
+ },
+ fail(res) {
+ if(res.errCode === 10006) {
+ uni.showToast({
+ title: '连接失败,请靠近设备并保持设备处于唤醒状态',
+ icon: 'none'
+ })
+ }
+ console.log('获取设备特征值失败', res)
+ resolve(false)
+ }
+ })
+ },
+ fail(res) {
+ if(res.errCode === 10006) {
+ uni.showToast({
+ title: '连接失败,请靠近设备并保持设备处于唤醒状态',
+ icon: 'none'
+ })
+ }
+ console.log('获取设备服务失败', res)
+ resolve(false)
+ }
+ })
+ },
+ fail(res) {
+ uni.showToast({
+ title: '连接失败,请靠近设备并保持设备处于唤醒状态',
+ icon: 'none'
+ })
+ console.log('连接失败', res)
+ resolve(false)
+ }
+ })
+ })
+ },
+ // 更新当前锁信息
+ updateCurrentLockInfo(lockInfo) {
+ console.log('更新当前锁信息', lockInfo)
+ this.currentLockInfo = lockInfo
+ },
+ // 订阅设备特征值改变
+ notifyBluetoothCharacteristicValueChange() {
+ const that = this
+ uni.notifyBLECharacteristicValueChange({
+ state: true,
+ deviceId: that.currentLockInfo.deviceId,
+ serviceId: that.currentLockInfo.serviceId,
+ characteristicId: that.currentLockInfo.notifyCharacteristicId,
+ success(res) {
+ console.log('订阅成功', res)
+ },
+ fail(res) {
+ console.log('订阅失败', res)
+ }
+ })
+ },
+ // 断开蓝牙连接
+ closeBluetoothConnection() {
+ const that = this
+ uni.closeBLEConnection({
+ deviceId: that.currentLockInfo.deviceId,
+ success(res) {
+ console.log('断开连接成功', res)
+ },
+ fail(res) {
+ console.log('断开连接失败', res)
+ }
+ })
+ },
+ // 写入特征值
+ async writeBLECharacteristicValue(binaryData) {
+ const that = this
+
+ // 确认蓝牙状态正常
+ if(this.bluetoothStatus !== 0) {
+ console.log('写入未执行', this.bluetoothStatus)
+ this.getBluetoothStatus()
+ return
+ }
+
+ // 确认设备连接正常
+ if(!that.currentLockInfo.connected) {
+ const result = await that.connectBluetoothDevice()
+ if(!result) return
+ }
+
+ console.log('设备ID:', that.currentLockInfo.deviceId)
+ console.log('设备名称:', that.currentLockInfo.name)
+ console.log('设备主服务:', that.currentLockInfo.serviceId)
+ console.log('设备写入特征值:', that.currentLockInfo.writeCharacteristicId)
+ console.log('设备写入数据:', Array.from(binaryData))
+
+ // 次数
+ const count = Math.ceil(binaryData.length / 20)
+ for(let i = 0; i < count; i++) {
+ const writeData = binaryData.slice(i * 20, i === (count - 1) ? binaryData.length : (i + 1) * 20)
+
+ uni.writeBLECharacteristicValue({
+ deviceId: that.currentLockInfo.deviceId,
+ serviceId: that.currentLockInfo.serviceId,
+ characteristicId: that.currentLockInfo.writeCharacteristicId,
+ value: writeData.buffer,
+ fail(res) {
+ console.log('写入失败', res)
+ }
+ })
+ }
+ },
+ /*
+ * 生成包头
+ * encryptionType 加密类型 0:明文,1:AES128,2:SM4(事先约定密钥),3:SM4(设备指定密钥)
+ * originalLength 原始数据长度
+ * */
+ createPackageHeader(encryptionType, originalLength) {
+ // 头部数据
+ let headArray = new Uint8Array(12)
+
+ // 固定包头
+ headArray[0] = 0xEF
+ headArray[1] = 0x01
+ headArray[2] = 0xEE
+ headArray[3] = 0x02
+
+ // 包类型 发送
+ headArray[4] = 0x01
+
+ // 包序号
+ headArray[5] = this.messageCount / 256
+ headArray[6] = this.messageCount % 256
+ this.messageCount++
+
+ // 包标识
+ if(encryptionType === 0) {
+ headArray[7] = 0x20
+ } else if(encryptionType === 2) {
+ headArray[7] = 0x22
+ } else {
+ headArray[7] = 0x23
+ }
+
+ // 数据长度
+ if(encryptionType === 0) {
+ headArray[8] = originalLength / 256
+ headArray[9] = originalLength % 256
+ } else {
+ const length = Math.ceil(originalLength / 16) * 16
+ headArray[8] = length / 256
+ headArray[9] = length % 256
+ }
+ headArray[10] = originalLength / 256
+ headArray[11] = originalLength % 256
+
+ return headArray
+ },
+ // 生成包尾 头部数据+内容数据
+ createPackageEnd(headArray,conentArray) {
+ // 拼接头部和内容
+ let mergerArray = new Uint8Array(headArray.length + conentArray.length)
+ mergerArray.set(headArray)
+ mergerArray.set(conentArray, headArray.length)
+
+ // crc加密
+ const crcResult = crc.crc16kermit(mergerArray)
+
+ // 拼接crc
+ let newArray = new Uint8Array(mergerArray.length + 2)
+ newArray.set(mergerArray)
+ newArray.set([crcResult / 256, crcResult % 256], mergerArray.length)
+
+ return newArray
+ },
+ // 获取公钥
+ async getPublicKey(name) {
+ const headArray = this.createPackageHeader(0, 42)
+ const conentArray = new Uint8Array(42)
+
+ conentArray[0] = cmdIds.getPublicKey / 256
+ conentArray[1] = cmdIds.getPublicKey % 256
+
+ for(let i = 0; i < name.length; i++) {
+ conentArray[i + 2] = name.charCodeAt(i)
+ }
+
+ const packageArray = this.createPackageEnd(headArray, conentArray)
+
+ await this.writeBLECharacteristicValue(packageArray)
+ return this.getWriteResult()
+ },
+ // 获取私钥
+ async getCommKey(name, keyId, authUid, nowTime) {
+ const length = 2 + 40 + 40 + 20 + 4 + 1 + 16
+ const headArray = this.createPackageHeader(2, length)
+ const conentArray = new Uint8Array(length)
+
+ conentArray[0] = cmdIds.getCommKey / 256
+ conentArray[1] = cmdIds.getCommKey % 256
+
+ for (let i = 0; i < name.length; i++) {
+ conentArray[i + 2] = name.charCodeAt(i)
+ }
+
+ for(let i = 0; i < keyId.length; i++) {
+ conentArray[i + 42] = keyId.charCodeAt(i)
+ }
+
+ for(let i = 0; i < authUid.length; i++) {
+ conentArray[i + 82] = authUid.charCodeAt(i)
+ }
+
+ conentArray.set(this.timestampToArray(nowTime), 102)
+
+ conentArray[106] = 16
+
+ const md5Array = this.md5Encrypte(authUid + keyId, conentArray.slice(102, 106), this.currentLockInfo.publicKey)
+
+ conentArray.set(md5Array, 107)
+
+ const cebArray = sm4.encrypt(conentArray, conentArray.slice(2, 18), { mode: 'ecb', output: 'array' })
+
+ const packageArray = this.createPackageEnd(headArray, cebArray)
+
+ await this.writeBLECharacteristicValue(packageArray)
+ return this.getWriteResult()
+ },
+ // md5加密
+ md5Encrypte(text, token, key) {
+ const length = text.length + 4 + 16
+ const md5Array = new Uint8Array(length)
+
+ for (let i = 0; i < text.length; i++) {
+ md5Array[i] = text.charCodeAt(i)
+ }
+
+ md5Array.set(token , text.length)
+ md5Array.set(key, text.length + 4)
+
+ const md5Text= md5(md5Array)
+ return new Uint8Array(md5Text.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
+ },
+ // 获取锁状态
+ async getLockStatus(data) {
+ const { name, uid, nowTime, localTime } = data
+ const length = 2 + 40 + 20 + 4 + 4
+ const headArray = this.createPackageHeader(3, length)
+
+ const conentArray = new Uint8Array(length)
+ conentArray[0] = cmdIds.getLockStatus / 256
+ conentArray[1] = cmdIds.getLockStatus % 256
+ for (let i = 0; i < name.length; i++) {
+ conentArray[i + 2] = name.charCodeAt(i)
+ }
+ for (let i = 0; i < uid.length; i++) {
+ conentArray[i + 42] = uid.charCodeAt(i)
+ }
+ conentArray.set(this.timestampToArray(nowTime), 62)
+ conentArray.set(this.timestampToArray(localTime), 66)
+
+ const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
+
+ const packageArray = this.createPackageEnd(headArray, cebArray)
+
+ await this.writeBLECharacteristicValue(packageArray)
+
+ return this.getWriteResult(this.getLockStatus, data)
+ },
+ // 时间戳转二进制
+ timestampToArray(timestamp) {
+ const array = new Uint8Array(4)
+ array[0] = (timestamp & 0xff000000) >> 24
+ array[1] = (timestamp & 0xff0000) >> 16
+ array[2] = (timestamp & 0xff00) >> 8
+ array[3] = (timestamp & 0xff)
+ return array
+ },
+ // 添加用户
+ async addLockUser(data) {
+ const { name, authUid, uid, keyId, openMode, keyType, startDate, expireDate, useCountLimit, isRound, weekRound,
+ startHour, startMin, endHour, endMin, role, password, publicKey, commKey } = data
+ const length = 2 + 40 + 20 + 40 + 20 + 1 + 1 + 4 + 4 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 20 + 4 + 1 + 16
+ const headArray = this.createPackageHeader(3, length)
+ const conentArray = new Uint8Array(length)
+
+ conentArray[0] = cmdIds.addUser / 256
+ conentArray[1] = cmdIds.addUser % 256
+
+ for(let i = 0; i < name.length; i++) {
+ conentArray[i + 2] = name.charCodeAt(i)
+ }
+
+ for(let i = 0; i < authUid.length; i++) {
+ conentArray[i + 42] = authUid.charCodeAt(i)
+ }
+
+ for(let i = 0; i < keyId.length; i++) {
+ conentArray[i + 62] = keyId.charCodeAt(i)
+ }
+
+ for(let i = 0; i < uid.length; i++) {
+ conentArray[i + 102] = uid.charCodeAt(i)
+ }
+
+ conentArray[122] = openMode
+ conentArray[123] = keyType
+
+ conentArray.set(this.timestampToArray(startDate), 124)
+ conentArray.set(this.timestampToArray(expireDate), 128)
+
+ conentArray[132] = useCountLimit / 256
+ conentArray[133] = useCountLimit % 256
+
+ conentArray[134] = isRound
+ conentArray[135] = weekRound
+ conentArray[136] = startHour
+ conentArray[137] = startMin
+ conentArray[138] = endHour
+ conentArray[139] = endMin
+ conentArray[140] = role
+
+ for(let i = 0; i < password.length; i++) {
+ conentArray[i + 141] = password.charCodeAt(i)
+ }
+
+ conentArray.set(this.currentLockInfo.token || this.timestampToArray(startDate), 161)
+
+ conentArray[165] = 16
+
+ const md5Array = this.md5Encrypte(authUid + keyId, this.currentLockInfo.token || this.timestampToArray(startDate), this.currentLockInfo.publicKey)
+
+ conentArray.set(md5Array, 166)
+
+ const cebArray = sm4.encrypt(conentArray, commKey, { mode: 'ecb', output: 'array' })
+
+ const packageArray = this.createPackageEnd(headArray, cebArray)
+ await this.writeBLECharacteristicValue(packageArray)
+ return this.getWriteResult(this.addLockUser, data)
+ },
+ // 获取写入结果
+ getWriteResult(request, params) {
+ return new Promise(resolve => {
+ const timer = setTimeout(() => {
+ resolve({ code: -1 })
+ }, 10000)
+ characteristicValueCallback = async (data) => {
+ // code 6 token过期,重新获取
+ if(data.code === 6) {
+ resolve(await request(params))
+ } else {
+ clearTimeout(timer)
+ resolve(data)
+ }
+ }
+ })
+ },
+ // 开门
+ async openDoor(data) {
+ const { name, uid, openMode, openTime, onlineToken } = data
+ const length = 2 + 40 + 20 + 1 + 4 + 4 + 1 + 16 + 16
+ const headArray = this.createPackageHeader(3, length)
+
+ const conentArray = new Uint8Array(length)
+ conentArray[0] = cmdIds.openDoor / 256
+ conentArray[1] = cmdIds.openDoor % 256
+
+ for(let i = 0; i < name.length; i++) {
+ conentArray[i + 2] = name.charCodeAt(i)
+ }
+
+ for (let i = 0; i < uid.length; i++) {
+ conentArray[i + 42] = uid.charCodeAt(i)
+ }
+
+ conentArray[62] = openMode
+
+ conentArray.set(this.timestampToArray(openTime), 63)
+
+ conentArray.set(this.currentLockInfo.token, 67)
+
+ conentArray[71] = 16
+
+ const md5Array = this.md5Encrypte(name + uid, this.currentLockInfo.token, this.currentLockInfo.signKey)
+
+ conentArray.set(md5Array, 72)
+
+ for (let i = 0; i < onlineToken.length; i++) {
+ conentArray[i + 88] = onlineToken.charCodeAt(i)
+ }
+
+ const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
+
+ const packageArray = this.createPackageEnd(headArray, cebArray)
+
+ await this.writeBLECharacteristicValue(packageArray)
+
+ return this.getWriteResult(this.openDoor, data)
+ },
+ // 恢复出厂设置
+ async resetDevice(data) {
+ const { name, authUid, keyId } = data
+ const length = 2 + 40 + 20 + 4 + 1 + 16
+ const headArray = this.createPackageHeader(3, length)
+ const conentArray = new Uint8Array(length)
+
+ conentArray[0] = cmdIds.resetDevice / 256
+ conentArray[1] = cmdIds.resetDevice % 256
+
+ for(let i = 0; i < name.length; i++) {
+ conentArray[i + 2] = name.charCodeAt(i)
+ }
+
+ for(let i = 0; i < authUid.length; i++) {
+ conentArray[i + 42] = authUid.charCodeAt(i)
+ }
+ conentArray.set(this.currentLockInfo.token, 62)
+ conentArray[66] = 16
+
+ const md5Array = this.md5Encrypte(name, this.currentLockInfo.token, this.currentLockInfo.publicKey)
+ conentArray.set(md5Array, 67)
+
+ const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
+
+ const packageArray = this.createPackageEnd(headArray, cebArray)
+
+ await this.writeBLECharacteristicValue(packageArray)
+
+ return this.getWriteResult(this.resetDevice, data)
+ },
+ // 重置开锁密码
+ async resetLockPassword(data) {
+ const { keyId, uid } = data
+ const length = 2 + 1 + 1 + 40 + 20 + 4 + 1 + 16
+ const headArray = this.createPackageHeader(3, length)
+ const conentArray = new Uint8Array(length)
+
+ conentArray[0] = cmdIds.expandCmd / 256
+ conentArray[1] = cmdIds.expandCmd % 256
+
+ // 子命令
+ conentArray[2] = subCmdIds.resetLockPassword
+
+ conentArray[3] = length - 4
+
+ for (let i = 0; i < keyId.length; i++) {
+ conentArray[i + 4] = keyId.charCodeAt(i)
+ }
+
+ for (let i = 0; i < uid.length; i++) {
+ conentArray[i + 44] = uid.charCodeAt(i)
+ }
+
+ conentArray.set(this.currentLockInfo.token, 64)
+
+ conentArray[68] = 16
+
+ const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token, this.currentLockInfo.signKey)
+
+ conentArray.set(md5Array, 69)
+
+ const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
+
+ const packageArray = this.createPackageEnd(headArray, cebArray)
+
+ await this.writeBLECharacteristicValue(packageArray)
+
+ return this.getWriteResult(this.resetLockPassword, data)
+ },
+ // 清理用户
+ async cleanUser(data) {
+ const { name, authUid, keyId, uid, userNoLength, userNoList } = data
+ // const length = 2 + 40 + 20 + 40 + 20 + 2 + userNoLength * 4 + 1 + 16
+ },
+ // 设置密码
+ async setLockPassword(data) {
+ const { keyId, uid, pwdNo, operate, isAdmin, pwd, userCountLimit, startTime, endTime} = data
+ const length = 2 + 1 + 1 + 40 + 20 + 2 + 1 + 1 + 20 + 2 + 4 + 4 + 4 + 1 + 16
+ const headArray = this.createPackageHeader(3, length)
+ const conentArray = new Uint8Array(length)
+
+ conentArray[0] = cmdIds.expandCmd / 256
+ conentArray[1] = cmdIds.expandCmd % 256
+
+ // 子命令
+ conentArray[2] = subCmdIds.setLockPassword
+
+ conentArray[3] = length - 3
+
+ for (let i = 0; i < keyId.length; i++) {
+ conentArray[i + 4] = keyId.charCodeAt(i)
+ }
+
+ for (let i = 0; i < uid.length; i++) {
+ conentArray[i + 44] = uid.charCodeAt(i)
+ }
+
+ conentArray[64] = pwdNo / 256
+ conentArray[65] = pwdNo % 256
+
+ conentArray[66] = operate
+ conentArray[67] = isAdmin
+
+ for (let i = 0; i < pwd.length; i++) {
+ conentArray[i + 68] = pwd.charCodeAt(i)
+ }
+
+ conentArray[88] = userCountLimit / 256
+ conentArray[89] = userCountLimit % 256
+
+ conentArray.set(this.currentLockInfo.token, 90)
+
+ conentArray.set(this.timestampToArray(startTime), 94)
+ conentArray.set(this.timestampToArray(endTime), 98)
+
+ conentArray[102] = 16
+
+ const md5Array = this.md5Encrypte(keyId + uid, this.currentLockInfo.token, this.currentLockInfo.signKey)
+
+ conentArray.set(md5Array, 103)
+
+ const cebArray = sm4.encrypt(conentArray, this.currentLockInfo.commKey, { mode: 'ecb', output: 'array' })
+
+ const packageArray = this.createPackageEnd(headArray, cebArray)
+
+ await this.writeBLECharacteristicValue(packageArray)
+
+ return this.getWriteResult(this.setLockPassword, data)
+ }
+ }
+})
diff --git a/stores/lock.js b/stores/lock.js
new file mode 100644
index 0000000..3a67f19
--- /dev/null
+++ b/stores/lock.js
@@ -0,0 +1,54 @@
+/**
+ * @description 锁信息数据持久化
+ */
+import { defineStore } from 'pinia'
+import { getLockListRequest } from '@/api/lock'
+
+export const useLockStore = defineStore('lock', {
+ state() {
+ return {
+ // 锁列表
+ lockList: [],
+ // 锁总数
+ lockTotal: 0
+ }
+ },
+ actions: {
+ getRole(userType) {
+ if(userType === 110301) {
+ return '超级管理员'
+ } else {
+ return '普通用户'
+ }
+ },
+ getTimeLimit(keyType) {
+ if(keyType === 1) {
+ return '永久'
+ } else if(keyType === 2) {
+ return '限时'
+ } else if(keyType === 3) {
+ return '单次'
+ } else {
+ return '循环'
+ }
+ },
+ async getLockList(params) {
+ const { code, data, message } = await getLockListRequest(params)
+ if(code === 0) {
+ this.lockTotal = data.total
+ if(params.pageNo === 1) {
+ this.lockList = data.groupList
+ } else {
+ this.lockList = this.lockList.concat(data.groupList)
+ }
+ return { code }
+ } else {
+ uni.showToast({
+ title: message,
+ icon: 'none'
+ })
+ return { code, message }
+ }
+ }
+ }
+})
diff --git a/stores/user.js b/stores/user.js
index a431d0f..5aa4988 100644
--- a/stores/user.js
+++ b/stores/user.js
@@ -2,16 +2,37 @@
* @description 用户信息数据持久化
*/
import { defineStore } from 'pinia'
+import { getUserInfoRequest } from '@/api/user'
+import { useLockStore } from '@/stores/lock'
export const useUserStore = defineStore('user', {
state() {
return {
- userInfo: {}
+ // 用户信息
+ userInfo: {},
+ // 登录状态
+ isLogin: false
}
},
actions: {
updateUserInfo(data) {
this.userInfo = data
+ },
+ updateLoginStatus(status) {
+ this.isLogin = status
+ },
+ async login() {
+ uni.setStorageSync('token', '3021|MZv7iEf0NwjCPSGx4QWs37zOjeVN3GrSJ2v7D56L7db1fcc5')
+ const { code, data } = await getUserInfoRequest()
+ await useLockStore().getLockList({
+ pageNo: 1,
+ pageSize: 50
+ })
+ if(code === 0) {
+ this.updateUserInfo(data)
+ }
+ this.isLogin = true
+ return this.isLogin
}
}
})
diff --git a/uni.scss b/uni.scss
index c712a1a..642511a 100644
--- a/uni.scss
+++ b/uni.scss
@@ -32,7 +32,7 @@ $uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
-$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-grey:#f3f3f3;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
diff --git a/utils/request.js b/utils/request.js
index 6248774..f7567ae 100644
--- a/utils/request.js
+++ b/utils/request.js
@@ -12,9 +12,10 @@ import baseConfig from '@/config/env'
const request = (config) => {
return new Promise((resolve) => {
+ const token = config?.token ? config.token : uni.getStorageSync('token')
const headerDefault = {
version: baseConfig.version,
- token: config?.token ? config.token : uni.getStorageSync('token')
+ authorization: `Bearer ${token}`
}
const URL = config.baseUrl ? config.baseUrl + config.url : baseConfig.baseUrl + config.url
const method = config.method || 'POST'
@@ -30,8 +31,29 @@ const request = (config) => {
async success(res) {
const { statusCode, data } = res
if (statusCode === 200) {
- // 根据情况添加处理代码
- resolve(data)
+ const code = data.errorCode
+ const message = data.errorMsg
+ if(code === 403) {
+ uni.removeStorageSync('token')
+ getApp().globalData.updateIsLogin(false)
+ resolve({ code: 403, data, message: '登录已过期' })
+ uni.showModal({
+ title: '提示',
+ content: '登录已过期,请重新登录',
+ showCancel: false,
+ success() {
+ uni.reLaunch({
+ url: '/pages/home/home'
+ })
+ }
+ })
+ } else {
+ resolve({
+ code,
+ data: data.data,
+ message
+ })
+ }
} else {
resolve({ code: -1, data, message: '网络不太好哦,请稍后再试' })
}
@@ -49,10 +71,9 @@ const request = (config) => {
console.log(URL.substring(baseConfig.baseUrl.length + 1), {
url: URL.substring(baseConfig.baseUrl.length + 1),
req: config?.data || {},
- code: res?.data?.code,
+ code: res?.data?.errorCode,
res: res?.data?.data,
- requestId: res?.header ? res?.header['X-Ca-Request-Id'] : '',
- token: header?.token || '',
+ token: header?.authorization || '',
duration: new Date().getTime() - timestamp
})
}