commit 04d373b84e69e0bda0fe271e59f4e45a6706553c
Author: 17792275749 <812100002@qq.com>
Date: Tue Mar 25 20:52:15 2025 +0800
第一版
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..115cc02
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,31 @@
+/*
+ * Eslint config file
+ * Documentation: https://eslint.org/docs/user-guide/configuring/
+ * Install the Eslint extension before using this feature.
+ */
+module.exports = {
+ env: {
+ es6: true,
+ browser: true,
+ node: true,
+ },
+ ecmaFeatures: {
+ modules: true,
+ },
+ parserOptions: {
+ ecmaVersion: 2018,
+ sourceType: 'module',
+ },
+ globals: {
+ wx: true,
+ App: true,
+ Page: true,
+ getCurrentPages: true,
+ getApp: true,
+ Component: true,
+ requirePlugin: true,
+ requireMiniProgram: true,
+ },
+ // extends: 'eslint:recommended',
+ rules: {},
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..960990f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1138 @@
+# 乐福蓝牙秤
+## 设备接入指南
+### 介绍
+本文档提供了小程序设备接入的指导,以确保秤设备能够成功连接到程序并正常工作。
+### 流程图
+#### 通过设备列表获取设备信息
+
+
+#### 操作测量流程
+
+
+#### 数据解析
+
+
+### 准备工作
+在开始设备接入之前,请确保您已经完成以下准备工作
+确认设备已经按照制造商的说明正确组装和连接。
+确保设备所需的供电已经连接,并处于正常工作状态。
+准备好所需的网络连接信息,如Wi-Fi名称和密码。
+申请蓝牙插件和使用身体数据解析接口申请与使用步骤如下:
+#### 申请与使用步骤
+1. 申请蓝牙插件:请访问蓝牙秤插件申请地址 [https://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wx0ffb48417ce6345c](https://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wx0ffb48417ce6345c),在该页面进行申请。
+
+2. 申请身体数据解析AppId 和 AppSecret:请访问身体数据解析申请地址 [https://uniquehealth.lefuenergy.com/unique-open-web/index.html](https://uniquehealth.lefuenergy.com/unique-open-web/index.html),在该页面进行申请。
+
+3. 申请蓝牙插件和开放官网注册账号:请访问开放官网注册页面,填写相关信息进行账号注册。
+
+4. 生成 AppId 和 AppSecret:在注册成功后,登录开放官网,点击Appkey管理,生成你的 AppId 和 AppSecret。
+
+5. 下载示例代码:请访问示例代码地址 [https://gitee.com/shenzhen-lfscale/bluetoothkit-webwidgetdemo.git](https://gitee.com/shenzhen-lfscale/bluetoothkit-webwidgetdemo.git),下载示例代码到本地。
+
+6. 开发插件功能:根据你的需求,使用示例代码进行开发,将你的 AppId 和 AppSecret 配置到代码中。
+
+以上是申请和使用蓝牙插件以及申请身体数据解析的流程。
+#### 导入插件
+将所申请的插件导入到你的应用程序中,确保插件可以正常使用。
+
+### 获取设备列表
+#### 注册设备蓝牙列表获取回调
+在你的应用程序中注册回调函数,用于获取设备的蓝牙列表。当回调触发时,你可以获取到可用设备的列表。
+#### 调用开启start方法
+调用相应的方法来开启设备的蓝牙功能,以便进行蓝牙设备的连接和通信。
+#### 设备蓝牙列表获取
+通过设备蓝牙列表回调,获取到可用设备的蓝牙列表。这些设备通常是附近的蓝牙设备。
+#### 选择蓝牙列表中需要连接的设备
+根据你的需求,在蓝牙列表中选择需要连接的设备,记录选择的蓝牙对象。
+
+### 选择连接蓝牙设备测量流程
+#### 进入设备详情页
+打开设备的详情页,显示设备的详细信息和配置选项。
+#### 注册监听相关回调
+- 注册蓝牙连接设备回调
+在你的应用程序中注册回调函数,用于处理设备的蓝牙连接事件。当设备成功连接时,回调函数将被触发。
+- 注册蓝牙监听秤端数据回调
+注册回调函数,用于监听来自秤端的数据。当踩秤有新的数据传输时,回调函数将被触发。
+- 注册蓝牙设备自动断连回调
+注册回调函数,用于处理设备自动断开连接的事件。当设备断开连接时,回调函数将被触。
+- 注册蓝牙锁定数据回调
+注册回调函数,用于处理来自秤端的锁定数据。当秤端锁定数据可用时,回调函数将被触发。
+- 注册蓝牙连接状态回调
+注册回调函数,用于处理蓝牙连接状态的变化。当蓝牙连接状态发生改变时,回调函数将被触发。
+- 注册蓝牙修改设备回调
+注册回调函数,用于处理对设备进行修改的事件。当设备配置发生改变时,回调函数将被触发。
+- 注册域名修改回调
+在域名修改的接口中,添加回调函数的参数。当域名修改成功后,调用回调函数,并传递修改成功的状态。
+- 注册WiFi配网SN回调
+在WiFi配网SN的接口中,添加回调函数的参数。当WiFi配网SN修改成功后,调用回调函数,并传递修改成功的SN数据。
+#### 踩秤
+用户踩上秤盘,使秤处于活跃状态。
+#### 调用开启方法
+调用相应的方法,开启设备的测量功能。
+#### 停止扫描
+停止扫描附近的蓝牙设备,以节省电力和资源。
+#### 连接蓝牙设备
+根据用户选择的设备,进行蓝牙设备的连接。连接设备回调开始处理开启过程数据监听。
+#### 蓝牙连接设备秤端相关配置操作
+- 设备单位修改方法
+秤端单位修改成功触发设备配置回调方法返回修改成功或失败状态
+- 设备域名修改方法
+秤端域名修改成功触发回调方法成功状态
+- 设备wifi配网ssid与passwd方法
+秤端wifi配网成功触发回调方法返回修改成功snData值
+#### 上秤测量
+在设备连接成功后,进行秤端的测量操作。
+#### 秤端数据回调方法返回秤端数据显示
+当秤端传输数据时,回调函数将被触发,将秤端数据显示给用户。
+#### 秤端锁定数据回调方法返回秤端锁定数据显示
+当秤端锁定数据可用时,回调函数将被触发,将锁定的数据显示给用户。
+#### 完成测量
+用户完成测量操作,准备进行数据解析和显示。
+
+### 解析数据
+#### 根据申请的AppID与Key获取请求token
+#### 拿锁定数据测量值请求数据解析接口
+将锁定的数据发送给数据解析接口,请求解析数据的结果。
+#### 得到身体数据解析值
+接收数据解析接口返回的解析结果,得到身体数据的解析值。
+#### 显示测量
+将解析得到的身体数据显示给用户,完成整个测量过程。
+
+
+## 方法说明
+### plugin.Blue
+
+plugin.Blue 是一系列控制蓝牙设备的命令和函数的封装,可以用于在项目中连接和通信蓝牙秤设备。以下是该插件所支持的命令和函数:
+
+**重要!插件1.0.5以上版本如无法扫描出设备 需要调用setDeviceSetting设置相应的蓝牙秤配置**
+**setDeviceSetting**设置蓝牙设备搜索的设备数组列表 新名字的秤需向开发者注册设备项:
+```setDeviceSetting(devicesList: array): void```
+
+**start**开始蓝牙扫描,参数devicesName为设备名称的数组,autoFlag是否自动连接秤端 默认为是:
+```start(devicesName: array, autoFlag: Boolean): void```
+
+**stop**停止蓝牙扫描,关闭所有事件监听与关闭蓝牙秤连接,通常用于业务结束后需要调用:
+```stop(): void```
+
+**disconnect**关闭蓝牙秤连接:
+```disconnect(fn: function): object```
+
+
+**createBLEConnection**接受一个蓝牙秤设备对象 连接后触发`deviceConnect`回调
+```createBLEConnection(device: object): object```
+
+
+**stopBluetoothDevicesDiscovery**停止扫描设备回调
+```stopBluetoothDevicesDiscovery(fn: function): object```
+
+**visibleLog** 是否打印插件内部日志
+```visibleLog(flag: boolean):void```
+
+### plugin.ScaleAction
+
+plugin.ScaleAction APP操作是蓝牙秤端的通用方法,切换蓝牙秤的单位和开启监听蓝牙秤数据
+
+
+**configWifi** 蓝牙配网 - 该功能用于蓝牙WiFi秤,在给秤配置网络时使用
+```
+// 首先确保已经绑定了蓝牙WiFi秤 2、用户输入Wifi账号和密码 3、发起连接设备 4、plugin.bus.subscribe("snData")方法返回sn码,此时秤上的WiFi图标会先闪烁(连接路由器中),再常量(连接路由器成功并获取到sn)将sn传给Server验证秤是否已经完成注册 7、Server返回成功,则配网成功,否则配网失败
+configWifi(ssid: string, password:string): void
+```
+
+**configDomain** 修改秤端服务器域名 修改后调用configWifi开始蓝牙配网
+```
+// 首先确保已经绑定了蓝牙WiFi秤
+发起蓝牙配网是先更新秤端服务器域名 防止域名调试篡改
+configDomain(domain: string): void
+```
+
+
+**startDataProgress**蓝牙秤端发送数据 需要在设备连接成功后即`deviceConnect`回调中使用
+```
+startDataProgress(): void
+// 示例
+plugin.bus.subscribe("deviceConnect", (res) => {
+ // 必须调用 不然无法获得秤端数据
+ plugin.ScaleAction.startDataProgress()
+});
+
+```
+
+**fetchDeviceHistoryData**
+```
+fetchDeviceHistoryData(): void
+// 示例
+plugin.bus.subscribe("syncDeviceHistorySuccess", (res) => {
+ //同步历史数据成功回调
+});
+
+```
+
+**deleteDeviceHistoryData**
+```
+deleteDeviceHistoryData(): void
+// 示例
+plugin.bus.subscribe("deleteDeviceHistoryDataSuccess", (res) => {
+ //删除历史数据成功回调
+});
+```
+
+**syncDeviceSetting**
+体重秤syncDeviceSetting 传入对象键值对
+
+| Property | Value | Value |
+| ---------------- | ------- | ------- |
+| gender | 0 | 性别对应 Plugin.PPBluetoothDefine.PPDeviceGenderType|
+| unit | 0 | 单位对应 Plugin.PPBluetoothDefine.PPDeviceUnit |
+| isAthleteMode | false | 孕妇 |
+| isPregnantMode | false | 运动员模式 |
+| age | 23 | 年龄 |
+| height | 123 | 身高 |
+
+**食物秤**syncDeviceSetting 传入对象键值对
+
+| Property | Value | Value |
+| ---------------- | ------- | ------- |
+| unit | 0 | 单位对应 Plugin.PPBluetoothDefine.PPDeviceUnit |
+| isBuzzerGateMode | false | 开启蜂鸣 |
+| isToZeroMode | false | 食物称置零 |
+
+```
+syncDeviceSetting(): object
+// 体重秤示例
+plugin.ScaleAction.syncDeviceSetting({
+ gender:0,
+ unit:0,
+ isAthleteMode:false,
+ isPregnantMode:false,
+ age:23,
+ height:123,
+})
+
+// 食物秤示例 食物称只能修改单一项
+plugin.ScaleAction.syncDeviceSetting({
+ isBuzzerGateMode: true,
+})
+plugin.ScaleAction.syncDeviceSetting({
+ unit: 0,
+})
+plugin.ScaleAction.syncDeviceSetting({
+ isToZeroMode: true,
+})
+
+```
+
+
+**historyData** 获取历史带历史过程数据
+其中res为对象键值为
+
+| Property | Value | 描述 |
+| -------------- | ------- | ------- |
+| isPlus | true | 是否是正数 |
+| isOverload | false | 是否超载 |
+| weight | 0 | 重量放大了100倍 |
+| resistance | 0 | 阻抗 |
+| isEnd | false | 本次测量是否结束 |
+| isHeartRating | false | 心律是否测量中 |
+| heartRate | 0 | 心律 |
+| unit | 0 | 设备单位 对应Plugin.PPBluetoothDefine.PPDeviceUnit |
+```
+ plugin.bus.subscribe("historyData", (res) => {
+ console.log("historyData", res);
+ });
+```
+
+
+**devicesModel** 获取设备模型设备模型可以根据Plugin.PPBluetoothDefine了解秤相关信息
+
+```
+ plugin.bus.subscribe("devicesModel", (res) => {
+ console.log("devicesModel", res);
+ });
+```
+
+
+**devicesInfo** 获取设备内置信息
+
+```
+ plugin.bus.subscribe("devicesInfo", (res) => {
+ console.log("devicesInfo", res);
+ });
+```
+
+
+**syncDeviceTimeSuccess** 时间同步 时间同步成功回调
+
+```
+ plugin.bus.subscribe("syncDeviceTimeSuccess", (res) => {
+ console.log("syncDeviceTimeSuccess", res);
+ });
+```
+
+
+**syncDeviceHistorySuccess** 同步历史数据回调
+
+```
+ plugin.bus.subscribe("syncDeviceHistorySuccess", (res) => {
+ console.log("syncDeviceHistorySuccess", res);
+ });
+```
+
+
+**deleteDeviceHistoryDataSuccess** 历史数据删除成功回调
+
+```
+ plugin.bus.subscribe("deleteDeviceHistoryDataSuccess", (res) => {
+ console.log("deleteDeviceHistoryDataSuccess", res);
+ });
+```
+
+
+**deviceWillDisconnect** 设备将要断连回调
+
+```
+ plugin.bus.subscribe("deviceWillDisconnect", (res) => {
+ console.log("deviceWillDisconnect", res);
+ });
+```
+### plugin.bus
+ plugin.bus通信蓝牙设备,用于监听蓝牙以及秤端的数据与状态,以下是该插件所支持的命令:
+
+**connectState** 蓝牙与蓝牙秤状态监听
+
+```
+ plugin.bus.subscribe("connectState", (res) => {
+ console.log("connectState", res);
+ });
+```
+
+**unitChange** 蓝牙秤单位切换状态监听
+
+```
+ plugin.bus.subscribe("unitChange", (res) => {
+ console.log("unitChange", res);
+ });
+```
+
+**devicesList** 获取过滤后的附近设备列表
+
+```
+ plugin.bus.subscribe("devicesList", (res) => {
+ console.log("devicesList", res);
+ });
+```
+
+**getDeviceInfo** 获取附件所有附近设备信息 自动连接autoFlag不为false时有数据
+
+```
+ plugin.bus.subscribe("getDeviceInfo", (res) => {
+ console.log("getDeviceInfo", res);
+ });
+```
+
+**deviceConnect** 蓝牙秤设备成功连接后连接中状态监听
+
+```
+ plugin.bus.subscribe("deviceConnect", (res) => {
+ plugin.ScaleAction.startDataProgress()
+ });
+```
+
+**progressData** 蓝牙秤端过程数据,监听不稳定体重的实时状态
+其中res为对象键值为
+
+| Property | Value | 描述 |
+| -------------- | ------- | ------- |
+| isPlus | true | 是否是正数 |
+| isOverload | false | 是否超载 |
+| weight | 0 | 重量放大了100倍 |
+| resistance | 0 | 阻抗 |
+| isEnd | false | 本次测量是否结束 |
+| isHeartRating | false | 心律是否测量中 |
+| heartRate | 0 | 心律 |
+| unit | 0 | 设备单位 对应Plugin.PPBluetoothDefine.PPDeviceUnit |
+
+**食物秤**中res为对象键值为
+
+| Property | Value | 描述 |
+| -------------- | ------- | ------- |
+| isPlus | true | 是否是正数 |
+| isOverload | false | 是否超载 |
+| weight | 0 | 重量放大了100倍 |
+| isEnd | false | 本次测量是否结束 |
+| unit | 0 | 设备单位 对应Plugin.PPBluetoothDefine.PPDeviceUnit |
+
+```
+ plugin.bus.subscribe("progressData", (res) => {
+ console.log("progressData", res);
+ });
+
+```
+
+
+**lockData** 蓝牙秤端完成测量锁定数据,锁定的体重和阻抗
+
+```
+ plugin.bus.subscribe("lockData", (res) => {
+ console.log("lockData", res);
+ });
+```
+
+
+**heartRate** 蓝牙秤端锁定心率值,必须根据已有秤功能调用
+
+```
+ plugin.bus.subscribe("heartRate", (res) => {
+ console.log("heartRate", res);
+ });
+```
+
+**snData** 配网成功后返回sn码 sn码用于请求验证秤是否已经完成注册
+
+```
+ plugin.bus.subscribe("snData", (res) => {
+ console.log("snData", res);
+ });
+```
+
+**domainChange** 修改域名成功后返回提示
+
+```
+ plugin.bus.subscribe("domainChange", (res) => {
+ console.log("domainChange", res);
+ });
+```
+
+
+### plugin.getDeviceSettingList
+
+**插件1.0.5以上版本新增api**
+
+***plugin.getDeviceSettingList*** 获取设置设备列表
+```
+//获取设备设置列表用于用户添加扫描设备
+plugin.getDeviceSettingList({
+ url: baseUrl,
+ data: {
+ appKey: appInfo.appKey
+ },
+ header: {
+ "token": bodyToken,
+ "Accept-Language": wx.getStorageSync("lang") || 'zh'
+ }
+}).then((res)=>{
+ if (res.data.code == 200) {
+ plugin.Blue.setDeviceSetting(res.data.data)
+ console.log("plugin==", plugin.PPBluetoothDefine)
+ }
+})
+```
+
+***plugin.getAcLfBodyData*** 交流秤数据解析
+```
+// 设备device 根据plugin.Blue.getDeviceModel 获取设备类型deviceConnectType 根据相应的类型请求解析
+var param = {
+ weightKg: 60,
+ impedance: 5076001,
+ sex: 1, 0(女) 1(男)
+ age: 22,
+ height: 170,
+ heartRate: 80,
+ token: '必传',
+ }
+ plugin.getAcLfBodyData({url:url,data:param,header:{ "token":res.data.data.token,"Accept-Language":"zh"}}).then(res => {
+ console.log('解析结果',res)
+})
+```
+
+
+### plugin.getDcLfBodyData
+***plugin.getDcLfBodyData*** 直流秤数据解析
+```
+// 设备device 根据plugin.Blue.getDeviceModel 获取设备类型deviceConnectType 根据相应的类型请求解析
+var param = {
+ "age":23,
+ "heartRate":0,
+ "height":123,
+ "impedance":0,
+ "peopleType":0,
+ "sex":0,
+ "weightKg":66.6,
+ }
+ plugin.getDcLfBodyData({url:url,data:param,header:{ "token":res.data.data.token,"Accept-Language":"zh"}}).then(res => {
+ console.log('解析结果',res)
+})
+```
+
+
+### plugin.refreshToken
+***plugin.refreshToken*** 刷新token
+```
+
+// 使用refreshToken与解析数据方法结合示例
+function refreshFn() {
+ this.refreshToken(() => {
+ callDcLfBodyData(param);
+ }, true);
+}
+
+async function refreshToken(fn, flag) {
+ let bodyToken = localStorage.getItem('bodyToken');
+ let bodyTokenTime = localStorage.getItem('bodyTokenTime');
+ if (!bodyToken || bodyTokenTime * 1000 < +new Date() || flag) {
+ let res = await plugin.refreshToken({
+ url: 'https://uniquehealth.lefuenergy.com',
+ data: {
+ "appSecret": "插件开发者申请",
+ "appKey": "插件开发者申请"
+ }
+ });
+ console.log("res", res);
+ if (res.data.code == 200) {
+ localStorage.setItem('bodyToken', res.data.data.token);
+ localStorage.setItem('bodyTokenTime', res.data.data.expireTime);
+ fn();
+ }
+ } else {
+ fn();
+ }
+}
+
+function handleResponse(res) {
+ console.log("res-=-=-|||", res.data.data);
+ if (res.data.code == 200) {
+
+ // 获取解析数据操作
+
+ } else if (res.data.code == 401) {
+ this.refreshToken(() => {
+ callDcLfBodyData(param);
+ }, true);
+ }
+}
+
+function handleResponseList(res) {
+ console.log("res-=-=-|||", res.data.data);
+ if (res.data.code == 200) {
+ // 获取解析数据操作
+ } else if (res.data.code == 401) {
+ this.refreshToken(() => {
+ getDeviceSettingList(param);
+ }, true);
+ }
+}
+
+function getDeviceSettingList(param){
+ let bodyToken = localStorage.getItem('bodyToken');
+ plugin.getDeviceSettingList({
+ url: 'https://uniquehealth.lefuenergy.com',
+ data: param,
+ header: {
+ "token": bodyToken,
+ "Accept-Language": localStorage.getItem("lang") || 'zh'
+ }
+ }).then(handleResponseList);
+}
+
+
+function callDcLfBodyData(param) {
+ let bodyToken = localStorage.getItem('bodyToken');
+ plugin.getDcLfBodyData({
+ url: 'https://uniquehealth.lefuenergy.com',
+ data: param,
+ header: {
+ "token": bodyToken,
+ "Accept-Language": localStorage.getItem("lang") || 'zh'
+ }
+ }).then(handleResponse);
+}
+
+
+
+```
+
+## Torre协议测量
+
+### Torre测量流程
+
+连接设备后 必须先调用更新MTU接口 再调用开始测量接口后数据返回
+```
+
+let getActiveProtocol = null
+plugin.bus.subscribe("deviceConnect", (res) => {
+ console.log('成功连接设备')
+ // 获取协议调用方法
+ getActiveProtocol = plugin.ScaleAction.getActiveProtocol()
+ // 更新MTU
+ getActiveProtocol.codeUpdateMTU((res) => {
+ console.log("codeUpdateMTU", res)
+ })
+});
+//开始测量
+activeProtocol.codeStartMeasure((res) => {
+ console.log("res", res)
+})
+//监听到数据变化
+plugin.bus.subscribe("progressData", (res) => {console.log(res)})
+//获得测量结果
+plugin.bus.subscribe("lockData", (res) => {console.log(res)})
+
+```
+
+### 配网流程
+
+配网需要先调用获取wifi列表接口 返回数据后再进行配网
+
+```
+let getActiveProtocol = plugin.ScaleAction.getActiveProtocol()
+activeProtocol.dataFindSurroundDevice((res) => {
+ console.log("wifiList", res)
+ activeProtocol.dataConfigNetWork({
+ domain: "http://domain",
+ ssid: 'IT32',
+ password: 'whs123456'
+ }, (res) => {
+ console.log("dataConfigNetWork", res)
+ })
+})
+
+```
+
+
+开始测量
+下发此指令后设备才会上报称重情况
+参数:无
+handler: 0设置成功 1设置失败
+```
+codeStartMeasure((status) => {})
+```
+
+保活指令
+推荐首次连接成功后每10秒调用一次,可以保证设备不会主动断开连接
+```
+sendKeepAliveCode()
+```
+
+停止测量
+停止设备的测量操作
+参数:无
+handler: 0设置成功 1设置失败
+```
+codeStopMeasure((status) => {})
+```
+
+获取设备单位
+获取设备当前的单位信息
+参数:无
+```
+codeFetchUnit((status) => {})
+```
+
+修改设备单位
+修改设备的单位信息
+参数:无
+unit: 单位
+0x00:单位kg
+0x01:单位lb
+0x02:单位斤
+0x03:单位st
+0x04:单位st:lb
+handler:
+0x00:设置成功
+0x01:设置失败
+```
+codeChangeUnit(unit,(status) => {})
+```
+
+同步设备时间
+同步设备的时间
+参数:无
+```
+codeSyncTime((status) => {})
+```
+
+获取设备屏幕亮度
+获取设备当前的屏幕亮度
+```
+codeFetchScreenLuminance((status)=>{})
+```
+
+设置设备屏幕亮度
+设置设备的屏幕亮度
+```
+codeSetScreenLuminance(50,(status)=>{})
+```
+
+清除设备数据
+清除设备中的不同类型的数据
+参数-
+cmd:
+0x00:清除所有设备数据(用户信息、历史数据、配网数据、设置信息)
+0x01:清除用户信息
+0x02:清除历史数据
+0x03:清除配网状态
+0x04:清除设置信息
+handler:
+0x00:成功
+0x01:失败
+```
+codeClearDeviceData("00",(status)=>{})
+```
+
+获取心率开关状态
+获取设备当前的心率测量开关状态
+参数:无
+```
+codeFetchHeartRateSwitch((status)=>{})
+```
+
+打开心率测量
+打开设备的心率测量功能
+参数:无
+```
+codeOpenHeartRateSwitch((status)=>{})
+```
+
+关闭心率测量
+关闭设备的心率测量功能
+参数:无
+```
+codeCloseHeartRateSwitch((status)=>{})
+```
+
+获取阻抗开关状态
+获取设备当前的阻抗测量开关状态
+参数:无
+```
+codeFetchImpedanceSwitch((status)=>{})
+```
+
+打开阻抗测量
+打开设备的阻抗测量功能
+参数:无
+```
+codeOpenImpedanceSwitch((status)=>{})
+```
+
+关闭阻抗测量
+关闭设备的阻抗测量功能
+参数:无
+```
+codeCloseImpedanceSwitch((status)=>{})
+```
+
+获取设备配网状态
+获取设备当前的配网状态
+参数:无
+```
+codeFetchWifiConfig((status)=>{})
+```
+
+退出配网模式
+退出设备的配网模式
+参数:无
+```
+dataExitWifiConfig((status)=>{})
+```
+
+获取设备当前配置热点的ssid
+获取设备当前配置的热点SSID名称
+参数:无
+handler: ssid名称
+```
+dataFetchConfigNetworkSSID((status)=>{})
+```
+
+设置设备绑定状态
+设置设备的绑定状态
+参数:无
+handler:
+0:设置成功
+1:设置失败
+```
+codeSetBindingState((status)=>{})
+```
+
+设置设备未绑定状态
+设置设备的未绑定状态
+参数:无
+handler:
+0:设置成功
+1:设置失败
+```
+codeSetUnbindingState((status)=>{})
+```
+
+获取设备绑定状态
+获取设备当前的绑定状态
+参数:无
+```
+codeFetchBindingState((status)=>{})
+```
+
+开启抱婴模式
+开启设备的抱婴模式
+参数:
+step: 第几次上称(0/1)
+weight: 上次上称时的重量(step为0时传0)
+handler:
+0:设置成功
+1:设置失败
+
+```
+codeEnableBabyModel(0,0,fn)
+```
+退出抱婴模式
+退出设备的抱婴模式
+参数:无
+handler:
+0:设置成功
+1:设置失败
+
+```
+codeExitBabyModel((status)=>{})
+```
+
+
+更新MTU
+更新设备的MTU(最大传输单元)
+参数:无
+handler:
+0:设置成功
+1:设置失败
+
+```
+codeUpdateMTU((status)=>{})
+
+```
+
+发现周围的可连接热点
+搜索周围的可连接WiFi热点
+参数:无
+handler: 返回结果,包含热点名称和强度的数组对象
+
+```
+dataFindSurroundDevice((list)=>{})
+
+```
+
+获取WIFI MAC地址
+获取设备的WiFi MAC地址
+参数:无
+handler: WiFi MAC地址,示例:MAC 地址:01:02:03:04:05:06(当MAC地址为00:00:00:00:00:00时表示获取不到)
+
+```
+codeFetchWifiMac((mac)=>{})
+
+```
+
+通过WIFI进行OTA升级
+使用WiFi进行设备的OTA(空中固件升级)
+参数:无
+handler: 进度和失败状态
+
+```
+codeOtaUpdate((status)=>{})
+
+```
+
+获取设备端用户列表
+获取设备端的用户ID列表
+参数:无
+handler: 返回设备端所有用户的userId
+
+```
+dataFetchUserID((list)=>{})
+
+```
+
+删除用户
+删除设备端的用户信息
+参数:无
+userModel: 单个用户信息,包含userId和memberId
+handler:
+0:设置成功
+1:设置失败
+
+```
+dataDeleteUser({userID: "15820440620", memberID: "1885639"},(status)=>{})
+```
+
+
+获取某个用户下所有成员的历史记录
+获取某个用户下所有成员的历史记录
+参数:无
+userModel: 用户对象,userId为必传项
+handler: 历史数据结果
+
+```
+dataFetchHistoryData({userID: "15820440620"},(status)=>{})
+dataHistoricalDataStatusReport((res) => {console.log("历史数据", res)})
+```
+
+
+选中测量用户
+用于测量过程中指定测量用户,指定后不需要在设备端进行选择
+参数-userModel: 单个用户信息,包含userId和memberId
+handler:
+0:设置成功
+1:设置失败
+
+```
+dataSelectUser({userID: "15820440620", memberID: "1885639", }, (status) => {})
+```
+同步单个用户给设备
+将单个用户信息同步给设备,如果设备中已存在该用户,则会更新用户信息;如果不存在,则会插入。
+参数-infos: 单个用户信息,包含各个属性的值(参考代码注释)
+handler:
+0:设置成功
+1:设置失败
+```
+dataSyncUserInfo({
+ userID: "15820440621",
+ memberID: "1885629",
+ age: "25",
+ gender: 0,
+ height: "158",
+ isAthleteMode: 0,
+ currentWeight: "55",
+ deviceHeaderIndex: 0,
+ targetWeight: "54",
+ idealWeight: "52.8",
+ recentData: [{
+ weightKg: 59.00,
+ timeStamp: 1677046795028
+ },
+ {
+ weightKg: 58.79,
+ timeStamp: 1692264965631
+ },
+ {
+ weightKg: 52.20,
+ timeStamp: 1693894960948
+ },
+ {
+ weightKg: 46.50,
+ timeStamp: 1694051103700
+ },
+ {
+ weightKg: 61.95,
+ timeStamp: 1694159727308
+ },
+ {
+ weightKg: 61.59,
+ timeStamp: 1694232070904
+ },
+ {
+ weightKg: 62.35,
+ timeStamp: 1694425016834
+ },
+ ],
+ userName: "名字",
+ },(status)=>{})
+```
+配置热点
+配置设备连接的WiFi热点信息
+参数-model: 包含用于连接热点的信息(domain, ssid, password)
+handler: 配网过程中的状态和错误码
+
+```
+dataConfigNetWork({domain:"domain", ssid:"ssid", password:"password"},(status)=>{})
+```
+
+## 常量与枚举值
+### plugin.PPBluetoothDefine
+以下是对给定的枚举类型介绍:
+
+### PPDeviceConnectType (设备连接类型)
+
+- `PPDeviceConnectTypeUnknow` (未知)
+- `PPDeviceConnectTypeBleAdv` (蓝牙广播秤)
+- `PPDeviceConnectTypeBleConnect` (蓝牙连接秤)
+
+### PPDeviceType (设备类型)
+
+- `PPDeviceTypeUnknow` (未知)
+- `PPDeviceTypeCF` (体脂秤)
+- `PPDeviceTypeCE` (体重秤)
+- `PPDeviceTypeCB` (婴儿秤)
+- `PPDeviceTypeCA` (厨房秤)
+
+### PPDeviceProtocolType (设备蓝牙协议版本)
+
+- `PPDeviceProtocolTypeUnknow` (未知)
+- `PPDeviceProtocolTypeV2` (2.x版本)
+- `PPDeviceProtocolTypeV3` (3.x版本)
+- `PPDeviceProtocolTypeTorre` (torre版本)
+
+### PPDeviceCalcuteType (测脂计算方式)
+
+- `PPDeviceCalcuteTypeUnknow` (未知)
+- `PPDeviceCalcuteTypeInScale` (秤端计算)
+- `PPDeviceCalcuteTypeDirect` (直流算法)
+- `PPDeviceCalcuteTypeAlternate` (交流算法)
+- `PPDeviceCalcuteTypeAlternate8` (8电极交流算法)
+- `PPDeviceCalcuteTypeAlternateNormal` (默认计算库直接用合泰返回的体脂率)
+- `PPDeviceCalcuteTypeNeedNot` (无需计算)
+
+### PPDevicePowerType (设备供电方式)
+
+- `PPDevicePowerTypeUnknow` (未知)
+- `PPDevicePowerTypeBattery` (电池)
+- `PPDevicePowerTypeSolar` (太阳能)
+- `PPDevicePowerTypeCharge` (充电)
+
+### PPDeviceFuncType (设备功能类型)
+
+- `PPDeviceFuncTypeWeight` (称重)
+- `PPDeviceFuncTypeFat` (测脂)
+- `PPDeviceFuncTypeHeartRate` (心律)
+- `PPDeviceFuncTypeHistory` (历史)
+- `PPDeviceFuncTypeSafe` (孕妇)
+- `PPDeviceFuncTypeBMDJ` (闭目单脚)
+- `PPDeviceFuncTypeBaby` (抱婴模式)
+- `PPDeviceFuncTypeWifi` (wifi配网)
+
+### PPDeviceAccuracyType (设备精度)
+
+- `PPDeviceAccuracyTypeUnknow` (未知)
+- `PPDeviceAccuracyTypePoint01` (0.1KG精度)
+- `PPDeviceAccuracyTypePoint005` (0.05KG精度)
+- `PPDeviceAccuracyTypePoint001` (0.01KG精度)
+- `PPDeviceAccuracyTypePointG` (1G精度)
+- `PPDeviceAccuracyTypePoint01G` (0.1G精度)
+
+### PPDeviceUnitType (设备具有的单位)
+
+- `PPDeviceUnitTypeKG(KG)`
+- `PPDeviceUnitTypeLB(LB)`
+- `PPDeviceUnitTypeSTLB(STLB)`
+- `PPDeviceUnitTypeJin(Jin)`
+- `PPDeviceUnitTypeG(G)`
+- `PPDeviceUnitTypeLBOZ(LBOZ)`
+- `PPDeviceUnitTypeOZ(FLOZ)`
+- `PPDeviceUnitTypeMLWater(MLWater)`
+- `PPDeviceUnitTypeMLMilk(MLMilk)`
+- `PPDeviceUnitTypeFLOZWater(FLOZWater)`
+- `PPDeviceUnitTypeFLOZMilk(FLOZMilk)`
+- `PPDeviceUnitTypeST(ST)`
+
+### PPDeviceUnit (用户使用的单位)
+
+- `PPUnitKG(KG)`
+- `PPUnitLB(LB)`
+- `PPUnitST(ST)`
+- `PPUnitJin(Jin)`
+- `PPUnitSTLB(STLB)`
+- `PPUnitG(G)`
+- `PPUnitLBOZ(LBOZ)`
+- `PPUnitOZ(OZ)`
+- `PPUnitMLWater(MLWater)`
+- `PPUnitMLMilk(MLMilk)`
+- `PPUnitFLOZWater(FLOZWater)`
+- `PPUnitFLOZMilk(FLOZMilk)`
+
+### PPDeviceGenderType (性别)
+
+- `PPDeviceGenderTypeFemale` (女性)
+- `PPDeviceGenderTypeMale` (男性)
+
+### PPWIFIConfigState (配网错误状态)
+
+- `PPWIFIConfigStateUnknow`
+- `PPWIFIConfigStateStart`
+- `PPWIFIConfigStateStartSuccess`
+- `PPWIFIConfigStateStartFailed`
+- `PPWIFIConfigStateDomainSendStart`
+- `PPWIFIConfigStateDomainSendSuccess`
+- `PPWIFIConfigStateDomainSendFailed`
+- `PPWIFIConfigStateDomainSendCode`
+- `PPWIFIConfigStateDomainSendCodeSuccess`
+- `PPWIFIConfigStateDomainSendCodeFailed`
+- `PPWIFIConfigStateSSIDSendStart`
+- `PPWIFIConfigStateSSIDSendSuccess`
+- `PPWIFIConfigStateSSIDSendFailed`
+- `PPWIFIConfigStateSSIDSendCode`
+- `PPWIFIConfigStateSSIDSendCodeSuccess`
+- `PPWIFIConfigStateSSIDSendCodeFailed`
+- `PPWIFIConfigStatePasswordSendStart`
+- `PPWIFIConfigStatePasswordSendSuccess`
+- `PPWIFIConfigStatePasswordSendFailed`
+- `PPWIFIConfigStatePasswordSendCode`
+- `PPWIFIConfigStatePasswordSendCodeSuccess`
+- `PPWIFIConfigStatePasswordSendCodeFailed`
+- `PPWIFIConfigStateRegist`
+- `PPWIFIConfigStateRegistSuccess`
+- `PPWIFIConfigStateRegistFailedTimeOut`
+- `PPWIFIConfigStateRegistFailedConnect`
+- `PPWIFIConfigStateRegistFailedHTTP`
+- `PPWIFIConfigStateRegistFailedHTTPS`
+- `PPWIFIConfigStateRegistFailedRegist`
+- `PPWIFIConfigStateRegistFailedCommand`
+
+### plugin.BLUE_STATE
+connectState 状态
+BLUE_STATE对应值为
+
+| 常量名 | 描述 |
+| --- | --- |
+| UNAVAILABLE | 蓝牙不可用 |
+| READY | 蓝牙准备就绪 |
+| SCANING | 正在搜索... |
+| CONNECTSUCCESS | 连接成功 |
+| CONNECTFAILED | 连接失败, 请重试! |
+| WIFISUCCESS | 配网成功 |
+
+## 使用插件示例
+
+https://gitee.com/shenzhen-lfscale/bluetoothkit-webwidgetdemo.git
+
+app.json 的 plugins 字段加入组件插件路径:
+```
+ "plugins": {
+ "ppScale-plugin": {
+ "version": "版本号",
+ "provider": "插件appid"
+ }
+ },
+```
+
+index.json 的 usingComponents 字段加入组件插件路径:
+```
+ "ppScale": "plugin://ppScale-plugin/ppScale"
+```
+
+index.wxml 页面中使用:
+```
+
+```
+
+## 常见问题
+### 开启扫描但不到设备
+需要确认系统蓝牙与应用权限蓝牙是否开启
+如果开启依旧无法扫描到蓝牙 需要开启位置信息 部分移动设备需要开启移动信息才能扫描到设备
+是否为真机调试 开发者工具部分版本真机调试蓝牙无法使用 需要换成预览模式调试开发
+### wifi配网后如何判断成功
+wifi配网需要确认路由器wi-Fi频段是否为2.4GHz
+调用wifi配网api 如果wifi配网成功则snData会返回回调方法 如果30秒内snData监听没有回调则为配网失败
+### ios有数据返回 安卓无数据返回
+确认页面是否在上一层页调用了插件stop方法 安卓端stop方法执行满导致新注册测量页面回调被清空 需要延迟几百毫秒再注册回调方法
+### 如何获取ios真实mac地址
+注册秤模型回调 连接成功秤后 返回秤模型回调拥有设备真实mac地址
+### 传入设备对象获取到秤端模型
+秤端模型需要设备对象的advertisData 对象复制后advertisData里的二进制数据丢失导致无法计算出设备模型
+复制设备对象时需要记录advertisData的二进制值 advertisData有真实值才能获得真实的秤模型
+### ios无法配网成功
+**ios配网成功必须满足的选项 如iPhone11如下**
+- 蓝牙秤确保配网时已经连接且里热点手机不远
+- iPhone11开启的热点可被其他手机扫描到
+- iPhone11为关闭wifi状态
+- 域名与wifi名密码正确
+
+
+
+
+
+
+
+
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..a1deaf8
--- /dev/null
+++ b/app.js
@@ -0,0 +1,46 @@
+App({
+ onLaunch() {
+ this.initPpScale();
+ },
+
+ globalData: {
+ // wx.request 请求的服务地址
+ wxRequestUrl: "http://device.shuziweidao.com:8889/",
+
+ // 秤的所有信息
+ ppScale: {
+ plugin: null,
+ activeProtocol: null,
+ domain: "http://device.shuziweidao.com:8889", // http://192.168.10.173:8889
+ wifi: {
+ ssid: "",
+ password: ""
+ },
+ options: {
+ key: "lefudc91611833e18d94",
+ secret: "eQ50JYimMp0X7uhNLj6D3lTEk4TUUvEG7dvaqKM9t1U="
+ },
+ device: {
+ setting: [], // 即将要搜索周边秤的配置
+ list: [], // 根据配置搜索到秤的列表
+ mac: null, // 选中的设备mac地址/SN码
+ name: "", // 设备名称
+ connection: null, // 默认选中连接的设备
+ }
+ }
+ },
+
+ initPpScale() {
+ this.globalData.ppScale.plugin = requirePlugin('ppScale-plugin');
+ const plugin = this.globalData.ppScale.plugin;
+
+ plugin.bus.subscribe("connectState", (res) => {
+ console.log("app.js ===> connectState", res);
+ });
+
+ plugin.bus.subscribe("devicesModel", (res) => {
+ console.log('app.js devicesModel', res);
+ this.globalData.ppScale.device.mac = res.deviceMac;
+ });
+ },
+})
\ No newline at end of file
diff --git a/app.json b/app.json
new file mode 100644
index 0000000..4e066b2
--- /dev/null
+++ b/app.json
@@ -0,0 +1,52 @@
+{
+ "pages": [
+ "pages/home/home",
+ "pages/searchDevice/searchDevice",
+ "pages/connectedDevice/connectedDevice",
+ "pages/connectionSuccessful/connectionSuccessful",
+ "pages/getWifiList/getWifiList",
+ "pages/setWifiPassword/setWifiPassword",
+ "pages/setNetwork/setNetwork",
+ "pages/setNetworkSuccessful/setNetworkSuccessful",
+ "pages/my/my",
+ "pages/userInfo/userInfo",
+ "pages/deviceInfo/deviceInfo",
+ "pages/familyMembers/familyMembers",
+ "pages/index/index"
+ ],
+ "window": {
+ "navigationBarTitleText": "",
+ "navigationBarTextStyle": "black",
+ "navigationBarBackgroundColor": "#ffffff"
+ },
+ "tabBar": {
+ "color": "#808080",
+ "selectedColor": "#1385FA",
+ "borderStyle": "white",
+ "list": [{
+ "pagePath": "pages/home/home",
+ "iconPath": "/images/tabBar/home.png",
+ "selectedIconPath": "/images/tabBar/home_.png",
+ "text": "首页"
+ }, {
+ "pagePath": "pages/my/my",
+ "iconPath": "/images/tabBar/my.png",
+ "selectedIconPath": "/images/tabBar/my_.png",
+ "text": "我的"
+ }]
+ },
+ "style": "v2",
+ "plugins": {
+ "ppScale-plugin": {
+ "version": "1.2.14",
+ "provider": "wx0ffb48417ce6345c"
+ }
+ },
+ "permission": {
+ "scope.userLocation": {
+ "desc": "获取 WiFi 列表需要使用您的位置信息"
+ }
+ },
+ "sitemapLocation": "sitemap.json",
+ "lazyCodeLoading": "requiredComponents"
+}
\ No newline at end of file
diff --git a/app.wxss b/app.wxss
new file mode 100644
index 0000000..5d4946a
--- /dev/null
+++ b/app.wxss
@@ -0,0 +1,43 @@
+page {
+ width: 100%;
+ height: 100%;
+ box-sizing: border-box;
+ background-color: #F5F7FB;
+}
+
+image {
+ width: 100%;
+ height: 100%;
+}
+
+button {
+ all: unset;
+ display: inline-block;
+}
+
+button::after {
+ display: none;
+}
+
+.scrollView {
+ width: 100%;
+ height: 100%;
+}
+
+.arrowAfter {
+ position: relative;
+}
+
+.arrowAfter::after {
+ position: absolute;
+ right: 6rpx;
+ top: 0;
+ bottom: 0;
+ margin: auto;
+ content: "";
+ width: 12rpx;
+ height: 12rpx;
+ border-left: 5rpx solid #b6b6b6;
+ border-top: 5rpx solid #b6b6b6;
+ transform: rotate(135deg);
+}
\ No newline at end of file
diff --git a/components/navigation-bar/navigation-bar.js b/components/navigation-bar/navigation-bar.js
new file mode 100644
index 0000000..66daae3
--- /dev/null
+++ b/components/navigation-bar/navigation-bar.js
@@ -0,0 +1,107 @@
+Component({
+ options: {
+ multipleSlots: true // 在组件定义时的选项中启用多slot支持
+ },
+ /**
+ * 组件的属性列表
+ */
+ properties: {
+ extClass: {
+ type: String,
+ value: ''
+ },
+ title: {
+ type: String,
+ value: ''
+ },
+ background: {
+ type: String,
+ value: ''
+ },
+ color: {
+ type: String,
+ value: ''
+ },
+ back: {
+ type: Boolean,
+ value: true
+ },
+ loading: {
+ type: Boolean,
+ value: false
+ },
+ homeButton: {
+ type: Boolean,
+ value: false,
+ },
+ animated: {
+ // 显示隐藏的时候opacity动画效果
+ type: Boolean,
+ value: true
+ },
+ show: {
+ // 显示隐藏导航,隐藏的时候navigation-bar的高度占位还在
+ type: Boolean,
+ value: true,
+ observer: '_showChange'
+ },
+ // back为true的时候,返回的页面深度
+ delta: {
+ type: Number,
+ value: 1
+ },
+ },
+ /**
+ * 组件的初始数据
+ */
+ data: {
+ displayStyle: ''
+ },
+ lifetimes: {
+ attached() {
+ const rect = wx.getMenuButtonBoundingClientRect()
+ wx.getSystemInfo({
+ success: (res) => {
+ const isAndroid = res.platform === 'android'
+ const isDevtools = res.platform === 'devtools'
+ this.setData({
+ ios: !isAndroid,
+ innerPaddingRight: `padding-right: ${res.windowWidth - rect.left}px`,
+ leftWidth: `width: ${res.windowWidth - rect.left }px`,
+ safeAreaTop: isDevtools || isAndroid ? `height: calc(var(--height) + ${res.safeArea.top}px); padding-top: ${res.safeArea.top}px` : ``
+ })
+ }
+ })
+ },
+ },
+ /**
+ * 组件的方法列表
+ */
+ methods: {
+ _showChange(show) {
+ const animated = this.data.animated
+ let displayStyle = ''
+ if (animated) {
+ displayStyle = `opacity: ${
+ show ? '1' : '0'
+ };transition:opacity 0.5s;`
+ } else {
+ displayStyle = `display: ${show ? '' : 'none'}`
+ }
+ this.setData({
+ displayStyle
+ })
+ },
+ back() {
+ const data = this.data
+ if (data.delta) {
+ wx.navigateBack({
+ delta: data.delta
+ })
+ }
+ this.triggerEvent('back', {
+ delta: data.delta
+ }, {})
+ }
+ },
+})
\ No newline at end of file
diff --git a/components/navigation-bar/navigation-bar.json b/components/navigation-bar/navigation-bar.json
new file mode 100644
index 0000000..2f56a9b
--- /dev/null
+++ b/components/navigation-bar/navigation-bar.json
@@ -0,0 +1,5 @@
+{
+ "component": true,
+ "styleIsolation": "apply-shared",
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/components/navigation-bar/navigation-bar.wxml b/components/navigation-bar/navigation-bar.wxml
new file mode 100644
index 0000000..57a74ce
--- /dev/null
+++ b/components/navigation-bar/navigation-bar.wxml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{title}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/navigation-bar/navigation-bar.wxss b/components/navigation-bar/navigation-bar.wxss
new file mode 100644
index 0000000..56e9c43
--- /dev/null
+++ b/components/navigation-bar/navigation-bar.wxss
@@ -0,0 +1,98 @@
+.weui-navigation-bar {
+ --weui-FG-0: rgba(0, 0, 0, .9);
+ --height: 44px;
+ --left: 16px;
+}
+
+.weui-navigation-bar .android {
+ --height: 48px;
+}
+
+.weui-navigation-bar {
+ overflow: hidden;
+ color: var(--weui-FG-0);
+ flex: none;
+}
+
+.weui-navigation-bar__inner {
+ position: relative;
+ top: 0;
+ left: 0;
+ height: calc(var(--height) + env(safe-area-inset-top));
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ padding-top: env(safe-area-inset-top);
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.weui-navigation-bar__left {
+ position: relative;
+ padding-left: var(--left);
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ height: 100%;
+ box-sizing: border-box;
+}
+
+.weui-navigation-bar__btn_goback_wrapper {
+ padding: 11px 18px 11px 16px;
+ margin: -11px -18px -11px -16px;
+}
+
+.weui-navigation-bar__btn_goback_wrapper.weui-active {
+ opacity: 0.5;
+}
+
+.weui-navigation-bar__btn_goback {
+ font-size: 12px;
+ width: 12px;
+ height: 24px;
+ -webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
+ mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
+ -webkit-mask-size: cover;
+ mask-size: cover;
+ background-color: var(--weui-FG-0);
+}
+
+.weui-navigation-bar__center {
+ font-size: 17px;
+ text-align: center;
+ position: relative;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ font-weight: bold;
+ flex: 1;
+ height: 100%;
+}
+
+.weui-navigation-bar__loading {
+ margin-right: 4px;
+ align-items: center;
+}
+
+.weui-loading {
+ font-size: 16px;
+ width: 16px;
+ height: 16px;
+ display: block;
+ background: transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23606060' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23606060' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23606060' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
+ background-size: 100%;
+ margin-left: 0;
+ animation: loading linear infinite 1s;
+}
+
+@keyframes loading {
+ from {
+ transform: rotate(0);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+}
\ No newline at end of file
diff --git a/images/connectedDevice/device.png b/images/connectedDevice/device.png
new file mode 100644
index 0000000..843faf3
Binary files /dev/null and b/images/connectedDevice/device.png differ
diff --git a/images/connectionSuccessful/icon.png b/images/connectionSuccessful/icon.png
new file mode 100644
index 0000000..6c7a21e
Binary files /dev/null and b/images/connectionSuccessful/icon.png differ
diff --git a/images/deviceInfo/device.png b/images/deviceInfo/device.png
new file mode 100644
index 0000000..6e62bc0
Binary files /dev/null and b/images/deviceInfo/device.png differ
diff --git a/images/familyMembers/add.png b/images/familyMembers/add.png
new file mode 100644
index 0000000..a6cf6b5
Binary files /dev/null and b/images/familyMembers/add.png differ
diff --git a/images/getWifiList/icon.png b/images/getWifiList/icon.png
new file mode 100644
index 0000000..a0882a8
Binary files /dev/null and b/images/getWifiList/icon.png differ
diff --git a/images/home/bg.jpg b/images/home/bg.jpg
new file mode 100644
index 0000000..f23f89d
Binary files /dev/null and b/images/home/bg.jpg differ
diff --git a/images/home/user.png b/images/home/user.png
new file mode 100644
index 0000000..8d7c532
Binary files /dev/null and b/images/home/user.png differ
diff --git a/images/my/1.png b/images/my/1.png
new file mode 100644
index 0000000..74e4e7b
Binary files /dev/null and b/images/my/1.png differ
diff --git a/images/my/2.png b/images/my/2.png
new file mode 100644
index 0000000..04262ff
Binary files /dev/null and b/images/my/2.png differ
diff --git a/images/my/3.png b/images/my/3.png
new file mode 100644
index 0000000..ed9edac
Binary files /dev/null and b/images/my/3.png differ
diff --git a/images/my/user.png b/images/my/user.png
new file mode 100644
index 0000000..8d7c532
Binary files /dev/null and b/images/my/user.png differ
diff --git a/images/searchDevice/icon.png b/images/searchDevice/icon.png
new file mode 100644
index 0000000..8304216
Binary files /dev/null and b/images/searchDevice/icon.png differ
diff --git a/images/setNetwork/icon.png b/images/setNetwork/icon.png
new file mode 100644
index 0000000..9974df8
Binary files /dev/null and b/images/setNetwork/icon.png differ
diff --git a/images/setNetworkSuccessful/icon.png b/images/setNetworkSuccessful/icon.png
new file mode 100644
index 0000000..6c7a21e
Binary files /dev/null and b/images/setNetworkSuccessful/icon.png differ
diff --git a/images/setNetworkSuccessful/success.png b/images/setNetworkSuccessful/success.png
new file mode 100644
index 0000000..8d979ed
Binary files /dev/null and b/images/setNetworkSuccessful/success.png differ
diff --git a/images/setNetworkSuccessful/wifi.png b/images/setNetworkSuccessful/wifi.png
new file mode 100644
index 0000000..a0882a8
Binary files /dev/null and b/images/setNetworkSuccessful/wifi.png differ
diff --git a/images/setWifiPassword/close.png b/images/setWifiPassword/close.png
new file mode 100644
index 0000000..6e32387
Binary files /dev/null and b/images/setWifiPassword/close.png differ
diff --git a/images/setWifiPassword/icon.png b/images/setWifiPassword/icon.png
new file mode 100644
index 0000000..2999896
Binary files /dev/null and b/images/setWifiPassword/icon.png differ
diff --git a/images/setWifiPassword/open.png b/images/setWifiPassword/open.png
new file mode 100644
index 0000000..2b2c650
Binary files /dev/null and b/images/setWifiPassword/open.png differ
diff --git a/images/tabBar/home.png b/images/tabBar/home.png
new file mode 100644
index 0000000..186b569
Binary files /dev/null and b/images/tabBar/home.png differ
diff --git a/images/tabBar/home_.png b/images/tabBar/home_.png
new file mode 100644
index 0000000..3fe72ed
Binary files /dev/null and b/images/tabBar/home_.png differ
diff --git a/images/tabBar/my.png b/images/tabBar/my.png
new file mode 100644
index 0000000..52b5312
Binary files /dev/null and b/images/tabBar/my.png differ
diff --git a/images/tabBar/my_.png b/images/tabBar/my_.png
new file mode 100644
index 0000000..4383c26
Binary files /dev/null and b/images/tabBar/my_.png differ
diff --git a/pages/connectedDevice/connectedDevice.js b/pages/connectedDevice/connectedDevice.js
new file mode 100644
index 0000000..8587778
--- /dev/null
+++ b/pages/connectedDevice/connectedDevice.js
@@ -0,0 +1,107 @@
+const app = getApp();
+import $ from "../../utils/request";
+
+Page({
+ data: {
+ name: "",
+ deviceSelect: null
+ },
+
+ onLoad(options) {
+ let name = app.globalData.ppScale.device.name;
+ let deviceSelect = app.globalData.ppScale.device.connection;
+ this.setData({
+ name: name ? name : deviceSelect.name,
+ deviceSelect: deviceSelect
+ })
+
+ app.globalData.ppScale.plugin.bus.subscribe("deviceConnect", (res) => {
+ console.log('connectedDevice ===》deviceConnect', res);
+
+ app.globalData.ppScale.plugin.ScaleAction.startDataProgress();
+ app.globalData.ppScale.activeProtocol = app.globalData.ppScale.plugin.ScaleAction.getActiveProtocol();
+
+ app.globalData.ppScale.activeProtocol.codeUpdateMTU((res) => {
+ console.log("connectedDevice ===》codeUpdateMTU", res);
+
+ app.globalData.ppScale.activeProtocol.codeFetchBindingState((res) => {
+ console.log("connectedDevice ===》codeFetchBindingState", res);
+
+ wx.hideLoading();
+ if (res === 1) {
+ wx.showModal({
+ title: '提示',
+ content: '当前设备已被绑定,你确定要覆盖绑定吗?',
+ success: (res) => {
+ if (res.confirm) {
+ app.globalData.ppScale.activeProtocol.codeClearDeviceData("00", (res) => {
+ console.log("deviceInfo === codeClearDeviceData", res);
+
+ let scaleDeviceId = app.globalData.ppScale.device.mac.replace(/:/g, '');
+ let params = {
+ equipmentCode: scaleDeviceId,
+ };
+ $.ajax("weighingScale/del/device", params, "POST", true, "正在初始化设备...").then(res => {
+ wx.showToast({
+ icon: "none",
+ title: res.message,
+ })
+ let pages = getCurrentPages();
+ let prevPage = pages[pages.length - 2];
+ prevPage.setData({
+ getDeviceSetting: true
+ })
+ setTimeout(() => {
+ wx.navigateBack({
+ delta: 1
+ })
+ }, 1500);
+ });
+ })
+ } else if (res.cancel) {
+ app.globalData.ppScale.plugin.Blue.disconnect();
+ }
+ }
+ })
+ } else {
+ app.globalData.ppScale.device.name = this.data.name;
+ wx.navigateTo({
+ url: "/pages/connectionSuccessful/connectionSuccessful"
+ })
+ }
+ })
+ });
+ });
+ },
+
+ nameInput(e) {
+ this.setData({
+ name: e.detail.value
+ })
+ },
+
+ // 配对
+ openConnectionSuccessful() {
+ let deviceSelect = this.data.deviceSelect;
+ if (deviceSelect) {
+ let name = this.data.name;
+ if (name) {
+ wx.showLoading({
+ title: "蓝牙配对中...",
+ mask: true
+ });
+ app.globalData.ppScale.plugin.Blue.createBLEConnection(deviceSelect);
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "设备名称不能为空"
+ })
+ }
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "配对设备不能为空"
+ })
+ }
+ },
+})
\ No newline at end of file
diff --git a/pages/connectedDevice/connectedDevice.json b/pages/connectedDevice/connectedDevice.json
new file mode 100644
index 0000000..7c0a326
--- /dev/null
+++ b/pages/connectedDevice/connectedDevice.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "设备命名",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/connectedDevice/connectedDevice.wxml b/pages/connectedDevice/connectedDevice.wxml
new file mode 100644
index 0000000..580c8b3
--- /dev/null
+++ b/pages/connectedDevice/connectedDevice.wxml
@@ -0,0 +1,14 @@
+型号:{{deviceSelect.name}}
+
+
+
+
+
+
+ 设备名称
+
+
+
+
+
+配对
\ No newline at end of file
diff --git a/pages/connectedDevice/connectedDevice.wxss b/pages/connectedDevice/connectedDevice.wxss
new file mode 100644
index 0000000..5a64677
--- /dev/null
+++ b/pages/connectedDevice/connectedDevice.wxss
@@ -0,0 +1,68 @@
+page {
+ padding: 50rpx 60rpx 0;
+ background-color: #ffffff;
+}
+
+.equipmentModel {
+ color: #252535;
+ width: 100%;
+ height: 48rpx;
+ font-size: 48rpx;
+ font-weight: bold;
+ line-height: 48rpx;
+ margin-bottom: 60rpx;
+}
+
+.equipmentIcon {
+ width: 320rpx;
+ height: 320rpx;
+ margin: 0 auto 40rpx;
+}
+
+.equipmentName {
+ width: 100%;
+ height: 126rpx;
+ display: flex;
+ flex-wrap: nowrap;
+ padding-right: 35rpx;
+ box-sizing: border-box;
+ margin-bottom: 550rpx;
+ justify-content: space-between;
+ border-bottom: 1rpx solid #EAECF1;
+}
+
+.equipmentName>view:first-of-type {
+ color: #252535;
+ height: 126rpx;
+ line-height: 126rpx;
+ font-size: 36rpx;
+ font-weight: bold;
+}
+
+.equipmentName>view:last-of-type {
+ flex: 1;
+ width: 0;
+ height: 126rpx;
+}
+
+.equipmentName>view:last-of-type input {
+ color: #808080;
+ width: 100%;
+ height: 126rpx;
+ text-align: right;
+ font-size: 36rpx;
+ line-height: 126rpx;
+}
+
+.btn {
+ color: #FFFFFF;
+ width: 580rpx;
+ height: 88rpx;
+ line-height: 88rpx;
+ margin: 0 auto;
+ font-size: 32rpx;
+ font-weight: bold;
+ border-radius: 44rpx;
+ text-align: center;
+ background-color: #1385FA;
+}
\ No newline at end of file
diff --git a/pages/connectionSuccessful/connectionSuccessful.js b/pages/connectionSuccessful/connectionSuccessful.js
new file mode 100644
index 0000000..bd48f97
--- /dev/null
+++ b/pages/connectionSuccessful/connectionSuccessful.js
@@ -0,0 +1,10 @@
+const app = getApp();
+
+Page({
+ // 获取wifi列表
+ openGetWifiList() {
+ wx.navigateTo({
+ url: "/pages/getWifiList/getWifiList"
+ })
+ }
+})
\ No newline at end of file
diff --git a/pages/connectionSuccessful/connectionSuccessful.json b/pages/connectionSuccessful/connectionSuccessful.json
new file mode 100644
index 0000000..84c4caf
--- /dev/null
+++ b/pages/connectionSuccessful/connectionSuccessful.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "绑定成功",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/connectionSuccessful/connectionSuccessful.wxml b/pages/connectionSuccessful/connectionSuccessful.wxml
new file mode 100644
index 0000000..b3cbcf3
--- /dev/null
+++ b/pages/connectionSuccessful/connectionSuccessful.wxml
@@ -0,0 +1,10 @@
+
+
+
+
+ 绑定成功
+
+
+随时随地同步测量数据
+
+配置网络
\ No newline at end of file
diff --git a/pages/connectionSuccessful/connectionSuccessful.wxss b/pages/connectionSuccessful/connectionSuccessful.wxss
new file mode 100644
index 0000000..a4e895d
--- /dev/null
+++ b/pages/connectionSuccessful/connectionSuccessful.wxss
@@ -0,0 +1,49 @@
+page {
+ width: 100%;
+ padding: 200rpx 85rpx 0;
+ box-sizing: border-box;
+ background-color: #ffffff;
+}
+
+.icon {
+ width: 100%;
+ margin-bottom: 540rpx;
+}
+
+.icon>view:first-of-type {
+ width: 360rpx;
+ height: 295rpx;
+ margin: 0 auto 50rpx;
+}
+
+.icon>view:last-of-type {
+ color: #252535;
+ width: 100%;
+ height: 40rpx;
+ font-size: 40rpx;
+ font-weight: bold;
+ line-height: 40rpx;
+ text-align: center;
+}
+
+.describe {
+ color: #B6B6B6;
+ width: 100%;
+ height: 26rpx;
+ font-size: 28rpx;
+ line-height: 28rpx;
+ text-align: center;
+ margin-bottom: 46rpx;
+}
+
+.btn {
+ color: #FFFFFF;
+ width: 100%;
+ height: 88rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 88rpx;
+ text-align: center;
+ border-radius: 44rpx;
+ background-color: #1385FA;
+}
\ No newline at end of file
diff --git a/pages/deviceInfo/deviceInfo.js b/pages/deviceInfo/deviceInfo.js
new file mode 100644
index 0000000..9cfda1f
--- /dev/null
+++ b/pages/deviceInfo/deviceInfo.js
@@ -0,0 +1,151 @@
+const app = getApp();
+import $ from "../../utils/request";
+
+Page({
+ data: {
+ deviceConnect: false,
+
+ deviceInfo: null
+ },
+
+ onLoad(options) {
+ this.getDevice();
+ this.initBluetooth();
+
+ app.globalData.ppScale.plugin.bus.subscribe("deviceConnect", (res) => {
+ console.log('deviceInfo ===》deviceConnect', res);
+
+ app.globalData.ppScale.plugin.ScaleAction.startDataProgress();
+ app.globalData.ppScale.activeProtocol = app.globalData.ppScale.plugin.ScaleAction.getActiveProtocol();
+
+ app.globalData.ppScale.activeProtocol.codeUpdateMTU((res) => {
+ console.log("deviceInfo ===》codeUpdateMTU", res);
+
+ $.ajax("weighingScale/list/device", {}, "GET", false).then((res) => {
+ if(res.result && res.result.length) {
+ let deviceConnect = res.result.some(item => item.macAddress === app.globalData.ppScale.device.mac);
+ if(deviceConnect) {
+ this.setData({
+ deviceConnect: true
+ })
+ } else {
+ app.globalData.ppScale.plugin.Blue.disconnect();
+ }
+ }
+ })
+ });
+ });
+ },
+
+ // 初始化蓝牙
+ initBluetooth() {
+ wx.openBluetoothAdapter({
+ success: () => {
+ this.getDeviceSettingList();
+ },
+ fail: (err) => {
+ if (err.errCode === 10001) {
+ wx.showModal({
+ title: "提示",
+ content: "请打开手机蓝牙",
+ });
+ }
+ },
+ });
+ },
+
+ async refreshToken(fn, flag) {
+ let bodyToken = wx.getStorageSync('bodyToken');
+ let bodyTokenTime = wx.getStorageSync('bodyTokenTime');
+ if (!bodyToken || bodyTokenTime * 1000 < +new Date() || flag) {
+ let res = await app.globalData.ppScale.plugin.refreshToken({
+ url: "https://uniquehealth.lefuenergy.com",
+ data: {
+ "appKey": app.globalData.ppScale.options.key,
+ "appSecret": app.globalData.ppScale.options.secret
+ }
+ });
+ if (res.data.code == 200) {
+ wx.setStorageSync('bodyToken', res.data.data.token);
+ wx.setStorageSync('bodyTokenTime', res.data.data.expireTime);
+ fn();
+ }
+ } else {
+ fn();
+ }
+ },
+ getDeviceSettingList() {
+ let bodyToken = wx.getStorageSync("bodyToken");
+ app.globalData.ppScale.plugin.getDeviceSettingList({
+ url: "https://uniquehealth.lefuenergy.com",
+ data: {
+ appKey: app.globalData.ppScale.options.key
+ },
+ header: {
+ "token": bodyToken,
+ "Accept-Language": wx.getStorageSync("lang") || 'zh'
+ }
+ }).then((res) => {
+ if (res.data.code == 200) {
+ app.globalData.ppScale.plugin.Blue.setDeviceSetting(res.data.data);
+ app.globalData.ppScale.device.setting = res.data.data;
+ let deviceNames = res.data.data.map(item => item.deviceName);
+ app.globalData.ppScale.plugin.Blue.start(deviceNames, false);
+ app.globalData.ppScale.plugin.bus.subscribe("devicesList", (res_) => {
+ app.globalData.ppScale.plugin.Blue.stopBluetoothDevicesDiscovery();
+ app.globalData.ppScale.plugin.Blue.createBLEConnection(res_[0]);
+ });
+ } else if (res.data.code == 401 || res.data.code == 4008) {
+ // 401 token过期 / 4008 token为空
+ // 重新请求token解析数据
+ this.refreshToken(() => {
+ this.getDeviceSettingList();
+ }, true);
+ }
+ });
+ },
+
+ // 获取已经绑定的设备列表
+ getDevice() {
+ let params = {};
+ $.ajax("weighingScale/list/device", params, "GET", false).then((res) => {
+ this.setData({
+ deviceInfo: res.result[0]
+ })
+ })
+ },
+
+ delDevice() {
+ if(this.data.deviceConnect) {
+ app.globalData.ppScale.activeProtocol.codeClearDeviceData("00", (res) => {
+ console.log("deviceInfo === codeClearDeviceData", res);
+
+ let scaleDeviceId = app.globalData.ppScale.device.mac.replace(/:/g, '');
+ let params = {
+ equipmentCode: scaleDeviceId,
+ };
+ $.ajax("weighingScale/del/device", params, "POST", true, "正在解绑设备...").then(res_ => {
+ wx.showToast({
+ icon: "none",
+ title: res_.message,
+ })
+ setTimeout(() => {
+ wx.navigateBack({
+ delta: 1
+ })
+ }, 1500);
+ });
+ })
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "删除失败,请靠近设备并点亮后再试"
+ })
+ this.initBluetooth();
+ }
+ },
+
+ onUnload() {
+ app.globalData.ppScale.plugin.Blue.stop();
+ }
+})
\ No newline at end of file
diff --git a/pages/deviceInfo/deviceInfo.json b/pages/deviceInfo/deviceInfo.json
new file mode 100644
index 0000000..a1e80a4
--- /dev/null
+++ b/pages/deviceInfo/deviceInfo.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "设备详情",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/deviceInfo/deviceInfo.wxml b/pages/deviceInfo/deviceInfo.wxml
new file mode 100644
index 0000000..97c33a5
--- /dev/null
+++ b/pages/deviceInfo/deviceInfo.wxml
@@ -0,0 +1,34 @@
+
+
+
+
+
+ {{deviceInfo.equipmentName}}
+ 型号:{{deviceInfo.type}}
+
+
+
+
+
+ 设备名称
+ {{deviceInfo.equipmentName}}
+
+
+ 设备SN
+ {{deviceInfo.equipmentCode}}
+
+
+ 配置Wi-Fi
+ {{deviceInfo.wifiName}}
+
+
+ 成员
+ {{deviceInfo.subUserNum}}人
+
+
+ MAC地址
+ {{deviceInfo.macAddress}}
+
+
+
+删除设备
\ No newline at end of file
diff --git a/pages/deviceInfo/deviceInfo.wxss b/pages/deviceInfo/deviceInfo.wxss
new file mode 100644
index 0000000..88487ae
--- /dev/null
+++ b/pages/deviceInfo/deviceInfo.wxss
@@ -0,0 +1,94 @@
+page {
+ padding: 30rpx 30rpx 0;
+}
+
+.device {
+ width: 100%;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ padding: 30rpx;
+ box-sizing: border-box;
+ border-radius: 24rpx;
+ margin-bottom: 24rpx;
+ background-color: #FFFFFF;
+}
+
+.device>view:first-of-type {
+ width: 180rpx;
+ height: 180rpx;
+ margin-right: 20rpx;
+}
+
+.device>view:last-of-type {
+ flex: 1;
+ width: 0;
+}
+
+.device>view:last-of-type>view:first-of-type {
+ color: #252535;
+ width: 100%;
+ height: 40rpx;
+ font-weight: bold;
+ font-size: 40rpx;
+ line-height: 40rpx;
+ margin-bottom: 22rpx;
+}
+
+.device>view:last-of-type>view:last-of-type {
+ color: #808080;
+ width: 100%;
+ height: 26rpx;
+ font-size: 26rpx;
+ line-height: 26rpx;
+}
+
+.info {
+ width: 100%;
+ border-radius: 24rpx;
+ margin-bottom: 88rpx;
+ background-color: #FFFFFF;
+}
+
+.info>view {
+ width: 100%;
+ height: 120rpx;
+ padding: 0 30rpx;
+ box-sizing: border-box;
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ border-bottom: 1rpx solid #EAECF1;
+}
+
+.info>view:last-of-type {
+ border-bottom: 0;
+}
+
+.info>view>view {
+ height: 120rpx;
+ font-size: 30rpx;
+ line-height: 120rpx;
+}
+
+.info>view>view:first-of-type {
+ color: #252535;
+ font-weight: bold;
+}
+
+.info>view>view:last-of-type {
+ color: #808080;
+}
+
+.btn {
+ color: #FFFFFF;
+ width: 580rpx;
+ height: 88rpx;
+ margin: 0 auto;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 88rpx;
+ text-align: center;
+ border-radius: 44rpx;
+ background-color: #1385FA;
+}
\ No newline at end of file
diff --git a/pages/familyMembers/familyMembers.js b/pages/familyMembers/familyMembers.js
new file mode 100644
index 0000000..8630a22
--- /dev/null
+++ b/pages/familyMembers/familyMembers.js
@@ -0,0 +1,45 @@
+import $ from "../../utils/request";
+
+Page({
+ data: {
+ userInfo: null,
+
+ subUserList: [],
+ },
+
+ onShow() {
+ this.setData({
+ userInfo: wx.getStorageSync("userInfo") || null
+ })
+ this.getSubUser();
+ },
+
+ // 获取家庭成员列表
+ getSubUser() {
+ let params = {};
+ $.ajax("weighingScale/list/subUser", params, "GET", true, "正在获取...").then(res => {
+ this.setData({
+ subUserList: res.result
+ })
+ })
+ },
+
+ openUserInfo() {
+ wx.navigateTo({
+ url: "/pages/userInfo/userInfo?initBluetooth=1&customerType=0"
+ })
+ },
+
+ editMyInfo() {
+ wx.navigateTo({
+ url: "/pages/userInfo/userInfo?initBluetooth=1&customerType=1"
+ })
+ },
+
+ editUserInfo(e) {
+ let id = e.currentTarget.dataset.id;
+ wx.navigateTo({
+ url: "/pages/userInfo/userInfo?id="+ id +"&initBluetooth=1&customerType=0"
+ })
+ }
+})
\ No newline at end of file
diff --git a/pages/familyMembers/familyMembers.json b/pages/familyMembers/familyMembers.json
new file mode 100644
index 0000000..2a8298a
--- /dev/null
+++ b/pages/familyMembers/familyMembers.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "家庭成员",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/familyMembers/familyMembers.wxml b/pages/familyMembers/familyMembers.wxml
new file mode 100644
index 0000000..944b486
--- /dev/null
+++ b/pages/familyMembers/familyMembers.wxml
@@ -0,0 +1,31 @@
+
+
+
+
+ {{userInfo ? userInfo.realname : '-'}}
+ 修改我的档案
+
+
+
+ 家庭成员
+
+
+
+
+
+
+
+ {{item.realname}}
+ 修改档案
+
+
+
+
+
+
+
+
+
+
+ 添加新成员
+
\ No newline at end of file
diff --git a/pages/familyMembers/familyMembers.wxss b/pages/familyMembers/familyMembers.wxss
new file mode 100644
index 0000000..41d2062
--- /dev/null
+++ b/pages/familyMembers/familyMembers.wxss
@@ -0,0 +1,128 @@
+page {
+ padding: 30rpx 30rpx 0;
+}
+
+.myInfo {
+ width: 100%;
+ height: 150rpx;
+ padding: 0 30rpx 0 38rpx;
+ box-sizing: border-box;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ border-radius: 16rpx;
+ margin-bottom: 40rpx;
+ background-color: #FFFFFF;
+}
+
+.myInfo>view:nth-of-type(1) {
+ width: 84rpx;
+ height: 84rpx;
+ border-radius: 50%;
+ margin-right: 24rpx;
+}
+
+.myInfo>view:nth-of-type(2) {
+ color: #252535;
+ flex: 1;
+ height: 32rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 32rpx;
+}
+
+.myInfo>view:nth-of-type(3) {
+ color: #B6B6B6;
+ height: 28rpx;
+ font-size: 28rpx;
+ line-height: 28rpx;
+ padding-right: 30rpx;
+}
+
+.familyMembers {
+ width: 100%;
+ margin-bottom: 24rpx;
+}
+
+.familyMembers>view:first-of-type {
+ color: #252535;
+ width: 100%;
+ height: 32rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 32rpx;
+ margin-bottom: 30rpx;
+}
+
+.familyMembers>view:last-of-type {
+ width: 100%;
+ border-radius: 16rpx;
+}
+
+.familyMembers>view:last-of-type>view {
+ width: 100%;
+ height: 150rpx;
+ padding: 0 30rpx 0 38rpx;
+ box-sizing: border-box;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ background-color: #FFFFFF;
+ border-bottom: 1rpx solid #EAECF1;
+}
+
+.familyMembers>view:last-of-type>view:last-of-type {
+ border-bottom: 0;
+}
+
+.familyMembers>view:last-of-type>view>view:nth-of-type(1) {
+ width: 84rpx;
+ height: 84rpx;
+ border-radius: 50%;
+ margin-right: 24rpx;
+}
+
+.familyMembers>view:last-of-type>view>view:nth-of-type(2) {
+ color: #252535;
+ flex: 1;
+ height: 32rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 32rpx;
+}
+
+.familyMembers>view:last-of-type>view>view:nth-of-type(3) {
+ color: #B6B6B6;
+ height: 28rpx;
+ font-size: 28rpx;
+ line-height: 28rpx;
+ padding-right: 30rpx;
+}
+
+.btn {
+ width: 100%;
+ height: 150rpx;
+ padding: 0 38rpx;
+ box-sizing: border-box;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ border-radius: 16rpx;
+ background-color: #FFFFFF;
+}
+
+.btn>view:first-of-type {
+ width: 84rpx;
+ height: 84rpx;
+ border-radius: 50%;
+ margin-right: 24rpx;
+}
+
+.btn>view:last-of-type {
+ color: #252535;
+ flex: 1;
+ height: 32rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 32rpx;
+}
\ No newline at end of file
diff --git a/pages/getWifiList/getWifiList.js b/pages/getWifiList/getWifiList.js
new file mode 100644
index 0000000..9ddd513
--- /dev/null
+++ b/pages/getWifiList/getWifiList.js
@@ -0,0 +1,32 @@
+const app = getApp();
+
+Page({
+ data: {
+ wifiList: []
+ },
+
+ onLoad() {
+ this.initWifi();
+ },
+
+ initWifi() {
+ wx.showLoading({
+ title: "正在获取Wi-Fi列表...",
+ mask: true
+ });
+ app.globalData.ppScale.activeProtocol.dataFindSurroundDevice((res) => {
+ wx.hideLoading();
+ console.log("wifiList", res);
+ this.setData({
+ wifiList: res
+ })
+ })
+ },
+
+ openSetWifiPassword(e) {
+ let item = JSON.stringify(e.currentTarget.dataset.item);
+ wx.navigateTo({
+ url: "/pages/setWifiPassword/setWifiPassword?item=" + item
+ })
+ }
+})
\ No newline at end of file
diff --git a/pages/getWifiList/getWifiList.json b/pages/getWifiList/getWifiList.json
new file mode 100644
index 0000000..47fb2f9
--- /dev/null
+++ b/pages/getWifiList/getWifiList.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {},
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/getWifiList/getWifiList.wxml b/pages/getWifiList/getWifiList.wxml
new file mode 100644
index 0000000..98814b6
--- /dev/null
+++ b/pages/getWifiList/getWifiList.wxml
@@ -0,0 +1,19 @@
+
+ 可用Wi-Fi
+ 网络列表(设备暂不支持5GWi-Fi网络)
+
+
+
+
+
+
+
+
+
+
+ {{item.ssid}}
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/getWifiList/getWifiList.wxss b/pages/getWifiList/getWifiList.wxss
new file mode 100644
index 0000000..66493d5
--- /dev/null
+++ b/pages/getWifiList/getWifiList.wxss
@@ -0,0 +1,64 @@
+page {
+ display: flex;
+ flex-direction: column;
+ background-color: #ffffff;
+}
+
+.title {
+ width: 100%;
+ padding: 50rpx 55rpx 24rpx;
+ box-sizing: border-box;
+}
+
+.title>view:first-of-type {
+ color: #252535;
+ width: 100%;
+ height: 48rpx;
+ font-size: 48rpx;
+ font-weight: bold;
+ line-height: 48rpx;
+ margin-bottom: 60rpx;
+}
+
+.title>view:last-of-type {
+ color: #B6B6B6;
+ width: 100%;
+ height: 30rpx;
+ font-size: 30rpx;
+ line-height: 30rpx;
+}
+
+.wifi {
+ flex: 1;
+ overflow: hidden;
+}
+
+.content {
+ width: 100%;
+ padding: 0 55rpx;
+ box-sizing: border-box;
+}
+
+.content>view {
+ width: 100%;
+ height: 80rpx;
+ margin: 30rpx 0;
+ display: flex;
+ flex-wrap: nowrap;
+}
+
+.content>view>view:nth-of-type(1) {
+ width: 80rpx;
+ height: 80rpx;
+ margin-right: 24rpx;
+}
+
+.content>view>view:nth-of-type(2) {
+ color: #252535;
+ flex: 1;
+ width: 0;
+ height: 80rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 80rpx;
+}
\ No newline at end of file
diff --git a/pages/home/home.js b/pages/home/home.js
new file mode 100644
index 0000000..522b94f
--- /dev/null
+++ b/pages/home/home.js
@@ -0,0 +1,92 @@
+import $ from "../../utils/request";
+
+Page({
+ data: {
+ token: null,
+ userInfo: null,
+
+ deviceList: []
+ },
+
+ onShow() {
+ let token = wx.getStorageSync("token") || null;
+ let userInfo = wx.getStorageSync("userInfo") || null;
+ this.setData({
+ token: token,
+ userInfo: userInfo
+ })
+ if(token && userInfo) {
+ this.getDevice();
+ }
+ },
+
+ // 点击登录或注册
+ openLoginOrReg() {
+ wx.login({
+ success: (res) => {
+ if (res.code) {
+ this.checkOpenIdLogin(res.code);
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "登录失败,请稍后再试!",
+ })
+ }
+ }
+ })
+ },
+
+ // 微信一键登录
+ checkOpenIdLogin(code) {
+ let params = {
+ code: code
+ };
+ $.ajax("weighingScale/checkOpenIdLogin", params, "POST", true, "登录中...").then((res) => {
+ wx.setStorageSync("userInfo", res.result.user);
+ wx.setStorageSync("token", res.result.token);
+ if(res.result.token && res.result.user) {
+ this.setData({
+ token: res.result.token,
+ userInfo: res.result.user
+ })
+ this.getDevice();
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "请先补全个人信息"
+ })
+ setTimeout(() => {
+ wx.navigateTo({
+ url: "/pages/userInfo/userInfo?initBluetooth=0&customerType=1"
+ })
+ }, 1500)
+ }
+ })
+ },
+
+ // 获取已经绑定的设备列表
+ getDevice() {
+ let params = {};
+ $.ajax("weighingScale/list/device", params, "GET", true, "获取设备列表").then((res) => {
+ this.setData({
+ deviceList: res.result
+ })
+ })
+ },
+
+ // 添加设备
+ openSearchDevice() {
+ let token = this.data.token;
+ let userInfo = this.data.userInfo;
+ if (token && userInfo) {
+ wx.navigateTo({
+ url: "/pages/searchDevice/searchDevice"
+ })
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "请先登录"
+ })
+ }
+ }
+})
\ No newline at end of file
diff --git a/pages/home/home.json b/pages/home/home.json
new file mode 100644
index 0000000..7930213
--- /dev/null
+++ b/pages/home/home.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationStyle": "custom",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/home/home.wxml b/pages/home/home.wxml
new file mode 100644
index 0000000..0acabd7
--- /dev/null
+++ b/pages/home/home.wxml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{userInfo.realname}}
+
+
+ 登录/注册
+
+
+ 智能体脂秤
+ 注重更好的健康生活品质
+
+
+
+ 请添加设备
+ 添加设备后,解锁更多体验
+
+ 添加设备
+
+
+ 登录/注册
+
+
+
\ No newline at end of file
diff --git a/pages/home/home.wxss b/pages/home/home.wxss
new file mode 100644
index 0000000..209f8f8
--- /dev/null
+++ b/pages/home/home.wxss
@@ -0,0 +1,118 @@
+.bg {
+ position: absolute;
+ z-index: 1;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.home {
+ position: relative;
+ z-index: 2;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 215rpx 60rpx 120rpx;
+ box-sizing: border-box;
+}
+
+.title {
+ width: 100%;
+}
+
+.title>view:nth-of-type(1) {
+ width: 100%;
+ height: 80rpx;
+ display: flex;
+ flex-wrap: nowrap;
+ margin-bottom: 56rpx;
+}
+
+.title>view:nth-of-type(1)>view:first-of-type {
+ width: 80rpx;
+ height: 80rpx;
+ overflow: hidden;
+ border-radius: 50%;
+ margin-right: 20rpx;
+}
+
+.title>view:nth-of-type(1)>view:last-of-type {
+ color: #FFFFFF;
+ height: 80rpx;
+ line-height: 80rpx;
+ font-size: 28rpx;
+ font-weight: bold;
+ padding-right: 26rpx;
+}
+
+.title>view:nth-of-type(1)>view:last-of-type::after {
+ border-left: 5rpx solid #ffffff;
+ border-top: 5rpx solid #ffffff;
+}
+
+.title>view:nth-of-type(2) {
+ color: #FFFFFF;
+ height: 58rpx;
+ font-size: 58rpx;
+ font-weight: bold;
+ line-height: 58rpx;
+ margin-bottom: 34rpx;
+}
+
+.title>view:nth-of-type(3) {
+ color: #FFFFFF;
+ height: 32rpx;
+ font-size: 32rpx;
+ line-height: 32rpx;
+ margin-bottom: 48rpx;
+}
+
+.title>view:nth-of-type(4) {
+ width: 120rpx;
+ height: 6rpx;
+ border-radius: 3rpx;
+ background-color: #FFFFFF;
+}
+
+.device {
+ width: 580rpx;
+ margin: 0 auto;
+}
+
+.device>view:nth-of-type(1) {
+ color: #FFFFFF;
+ width: 100%;
+ height: 36rpx;
+ font-size: 36rpx;
+ font-weight: bold;
+ text-align: center;
+ line-height: 36rpx;
+ margin-bottom: 30rpx;
+}
+
+.device>view:nth-of-type(2) {
+ color: #FFFFFF;
+ width: 100%;
+ height: 30rpx;
+ font-size: 30rpx;
+ text-align: center;
+ line-height: 30rpx;
+ margin-bottom: 80rpx;
+}
+
+.device>view:nth-of-type(3) {
+ color: #FFFFFF;
+ width: 100%;
+ height: 106rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ text-align: center;
+ line-height: 106rpx;
+ border-radius: 16rpx;
+ border: 1rpx solid #FFFFFF;
+}
diff --git a/pages/index/index.js b/pages/index/index.js
new file mode 100644
index 0000000..2066c4f
--- /dev/null
+++ b/pages/index/index.js
@@ -0,0 +1,2 @@
+// index.js
+Page({})
diff --git a/pages/index/index.json b/pages/index/index.json
new file mode 100644
index 0000000..aa3f1b0
--- /dev/null
+++ b/pages/index/index.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {
+ "navigation-bar": "/components/navigation-bar/navigation-bar"
+ }
+}
\ No newline at end of file
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
new file mode 100644
index 0000000..57cc6da
--- /dev/null
+++ b/pages/index/index.wxml
@@ -0,0 +1,7 @@
+
+
+
+
+ Weixin
+
+
diff --git a/pages/index/index.wxss b/pages/index/index.wxss
new file mode 100644
index 0000000..8c2b75a
--- /dev/null
+++ b/pages/index/index.wxss
@@ -0,0 +1,10 @@
+/**index.wxss**/
+page {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+.scrollarea {
+ flex: 1;
+ overflow-y: hidden;
+}
diff --git a/pages/my/my.js b/pages/my/my.js
new file mode 100644
index 0000000..4b3cb79
--- /dev/null
+++ b/pages/my/my.js
@@ -0,0 +1,112 @@
+import $ from "../../utils/request";
+
+Page({
+ data: {
+ userInfo: null,
+
+ deviceInfo: null
+ },
+
+ onShow() {
+ let token = wx.getStorageSync("token") || null;
+ let userInfo = wx.getStorageSync("userInfo") || null;
+ this.setData({
+ userInfo: userInfo
+ })
+ if(token && userInfo) {
+ this.getDevice();
+ }
+ },
+
+ // 打开用户信息
+ openUserInfo() {
+ if(this.data.userInfo) {
+ wx.navigateTo({
+ url: "/pages/userInfo/userInfo?initBluetooth=1&customerType=1"
+ })
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "请先登录"
+ })
+ }
+ },
+
+ // 打开设备详情
+ openDeviceInfo() {
+ if(this.data.userInfo) {
+ let deviceInfo = this.data.deviceInfo;
+ if(deviceInfo) {
+ wx.navigateTo({
+ url: "/pages/deviceInfo/deviceInfo"
+ })
+ } else {
+ wx.showModal({
+ title: "提示",
+ content: "当前暂未绑定设备,需要绑定吗?",
+ confirmText: "去绑定",
+ success: (res) => {
+ if (res.confirm) {
+ wx.navigateTo({
+ url: "/pages/searchDevice/searchDevice"
+ })
+ }
+ }
+ })
+ }
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "请先登录"
+ })
+ }
+ },
+
+ // 打开成员管理
+ openFamilyMembers() {
+ if(this.data.userInfo) {
+ wx.navigateTo({
+ url: "/pages/familyMembers/familyMembers"
+ })
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "请先登录"
+ })
+ }
+ },
+
+ // 获取已经绑定的设备列表
+ getDevice() {
+ let params = {};
+ $.ajax("weighingScale/list/device", params, "GET", false).then((res) => {
+ this.setData({
+ deviceInfo: res.result && res.result.length ? res.result[0] : null
+ })
+ })
+ },
+
+ // 退出登录
+ exitLogin() {
+ wx.showModal({
+ title: "提示",
+ content: "你确定要退出登录吗?",
+ success: (res) => {
+ if (res.confirm) {
+ $.ajax("weighingScale/logout", {}, "POST", true, "正在退出登录...").then(res => {
+ wx.showToast({
+ icon: "none",
+ title: res.message
+ })
+ setTimeout(() => {
+ wx.clearStorageSync();
+ wx.switchTab({
+ url: "/pages/home/home"
+ })
+ }, 1500)
+ })
+ }
+ }
+ })
+ }
+})
\ No newline at end of file
diff --git a/pages/my/my.json b/pages/my/my.json
new file mode 100644
index 0000000..7930213
--- /dev/null
+++ b/pages/my/my.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationStyle": "custom",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/my/my.wxml b/pages/my/my.wxml
new file mode 100644
index 0000000..608e284
--- /dev/null
+++ b/pages/my/my.wxml
@@ -0,0 +1,59 @@
+
+
+
+
+
+ {{userInfo && userInfo.realname ? userInfo.realname : '未登录'}}
+
+
+
+ 身高(cm)
+ {{userInfo && userInfo.height ? userInfo.height : '--'}}
+
+
+
+ 体重(kg)
+ {{userInfo && userInfo.weight ? userInfo.weight : '--'}}
+
+
+
+ BMI
+ {{userInfo && userInfo.bmi ? userInfo.bmi : '--'}}
+
+
+
+
+
+
+ 我的服务
+
+
+
+
+ 设备绑定
+ {{deviceInfo ? '已绑定('+ deviceInfo.equipmentName +')' : '未绑定'}}
+
+
+
+
+
+ 成员管理
+
+
+
+
+
+
+
+
+ 隐私协议
+
+
+
+
+
+
+
+ 退出登录
+
+
diff --git a/pages/my/my.wxss b/pages/my/my.wxss
new file mode 100644
index 0000000..d2133f7
--- /dev/null
+++ b/pages/my/my.wxss
@@ -0,0 +1,165 @@
+.userInfo {
+ width: 100%;
+ height: 488rpx;
+ margin-bottom: 24rpx;
+ box-sizing: border-box;
+ padding: 185rpx 40rpx 0;
+ background: linear-gradient(#F3F9FD 0%, #FFFFFF 100%);
+}
+
+.user {
+ width: 100%;
+ height: 136rpx;
+ display: flex;
+ flex-wrap: nowrap;
+ margin-bottom: 46rpx;
+}
+
+.user>view:first-of-type {
+ width: 126rpx;
+ height: 126rpx;
+ margin-right: 24rpx;
+ border-radius: 50%;
+ border: 5rpx solid #FFFFFF;
+}
+
+.user>view:last-of-type {
+ color: #252536;
+ flex: 1;
+ height: 136rpx;
+ font-size: 40rpx;
+ font-weight: bold;
+ line-height: 136rpx;
+}
+
+.info {
+ width: 100%;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+}
+
+.info>view:nth-of-type(1),
+.info>view:nth-of-type(3),
+.info>view:nth-of-type(5) {
+ flex: 1;
+}
+
+.info>view:nth-of-type(2n) {
+ width: 2rpx;
+ height: 52rpx;
+ background-color: #EAECF1;
+}
+
+.info>view>view:first-of-type {
+ color: #394356;
+ width: 100%;
+ height: 28rpx;
+ font-size: 28rpx;
+ line-height: 28rpx;
+ text-align: center;
+ margin-bottom: 18rpx;
+}
+
+.info>view>view:last-of-type {
+ color: #394356;
+ width: 100%;
+ height: 36rpx;
+ font-size: 36rpx;
+ font-weight: bold;
+ line-height: 36rpx;
+ text-align: center;
+}
+
+.content {
+ width: 100%;
+ padding: 0 30rpx;
+ box-sizing: border-box;
+ margin-bottom: 360rpx;
+}
+
+.content .arrowAfter::after {
+ right: 36rpx;
+}
+
+.service {
+ width: 100%;
+ margin-bottom: 24rpx;
+ border-radius: 16rpx;
+ background-color: #FFFFFF;
+}
+
+.title {
+ color: #394356;
+ width: 100%;
+ height: 96rpx;
+ line-height: 96rpx;
+ padding: 0 30rpx;
+ font-size: 30rpx;
+ font-weight: bold;
+ box-sizing: border-box;
+ border-bottom: 1rpx solid #EAECF1;
+}
+
+.list {
+ width: 100%;
+ height: 96rpx;
+ padding: 0 30rpx;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ box-sizing: border-box;
+ border-bottom: 1rpx solid #EAECF1;
+}
+
+.list:last-of-type {
+ border-bottom: none;
+}
+
+.list>view:nth-of-type(1) {
+ width: 56rpx;
+ height: 56rpx;
+ margin-right: 30rpx;
+}
+
+.list>view:nth-of-type(2) {
+ flex: 1;
+ color: #394356;
+ height: 96rpx;
+ line-height: 96rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+}
+
+.list>view:nth-of-type(3) {
+ color: #77849E;
+ height: 96rpx;
+ font-size: 28rpx;
+ line-height: 96rpx;
+ padding-right: 34rpx;
+}
+
+.agreement {
+ width: 100%;
+ border-radius: 16rpx;
+ background-color: #FFFFFF;
+}
+
+.btn {
+ width: 100%;
+ padding: 0 85rpx;
+ box-sizing: border-box;
+}
+
+.btn>view {
+ color: #1385FA;
+ width: 580rpx;
+ height: 88rpx;
+ line-height: 88rpx;
+ font-size: 32rpx;
+ border-radius: 44rpx;
+ text-align: center;
+ background-color: #F5F7FB;
+ border: 1rpx solid #1385FA;
+
+}
\ No newline at end of file
diff --git a/pages/searchDevice/searchDevice.js b/pages/searchDevice/searchDevice.js
new file mode 100644
index 0000000..297099c
--- /dev/null
+++ b/pages/searchDevice/searchDevice.js
@@ -0,0 +1,112 @@
+const app = getApp();
+
+Page({
+ data: {
+ getDeviceSetting: false,
+
+ initText: "",
+ devicesList: []
+ },
+
+ onLoad(options) {
+ this.initBluetooth();
+ },
+
+ onShow() {
+ if (this.data.getDeviceSetting) {
+ this.getDeviceSettingList();
+ }
+ },
+
+ // 初始化蓝牙
+ initBluetooth() {
+ this.setData({
+ initText: "正在初始化蓝牙..."
+ })
+ wx.openBluetoothAdapter({
+ success: () => {
+ this.setData({
+ initText: "蓝牙初始化成功"
+ })
+ this.getDeviceSettingList();
+ },
+ fail: (err) => {
+ this.setData({
+ initText: "蓝牙初始化失败"
+ })
+ if (err.errCode === 10001) {
+ wx.showModal({
+ title: "提示",
+ content: "请打开手机蓝牙",
+ });
+ }
+ },
+ });
+ },
+
+ async refreshToken(fn, flag) {
+ let bodyToken = wx.getStorageSync('bodyToken');
+ let bodyTokenTime = wx.getStorageSync('bodyTokenTime');
+ if (!bodyToken || bodyTokenTime * 1000 < +new Date() || flag) {
+ let res = await app.globalData.ppScale.plugin.refreshToken({
+ url: "https://uniquehealth.lefuenergy.com",
+ data: {
+ "appKey": app.globalData.ppScale.options.key,
+ "appSecret": app.globalData.ppScale.options.secret
+ }
+ });
+ if (res.data.code == 200) {
+ wx.setStorageSync('bodyToken', res.data.data.token);
+ wx.setStorageSync('bodyTokenTime', res.data.data.expireTime);
+ fn();
+ }
+ } else {
+ fn();
+ }
+ },
+ getDeviceSettingList() {
+ this.setData({
+ initText: "获取设备配置中..."
+ })
+ let bodyToken = wx.getStorageSync("bodyToken");
+ app.globalData.ppScale.plugin.getDeviceSettingList({
+ url: "https://uniquehealth.lefuenergy.com",
+ data: {
+ appKey: app.globalData.ppScale.options.key
+ },
+ header: {
+ "token": bodyToken,
+ "Accept-Language": wx.getStorageSync("lang") || 'zh'
+ }
+ }).then((res) => {
+ if (res.data.code == 200) {
+ this.setData({
+ initText: "设备搜索中..."
+ });
+ app.globalData.ppScale.plugin.Blue.setDeviceSetting(res.data.data);
+ app.globalData.ppScale.device.setting = res.data.data;
+ let deviceNames = res.data.data.map(item => item.deviceName);
+ app.globalData.ppScale.plugin.Blue.start(deviceNames, false);
+ app.globalData.ppScale.plugin.bus.subscribe("devicesList", (res_) => {
+ console.log("searchDevice ===> devicesList", res_);
+ this.setData({
+ getDeviceSetting: false,
+ initText: "设备搜索完成"
+ });
+ app.globalData.ppScale.plugin.Blue.stopBluetoothDevicesDiscovery();
+ app.globalData.ppScale.device.list = res_;
+ app.globalData.ppScale.device.connection = res_[0];
+ wx.navigateTo({
+ url: "/pages/connectedDevice/connectedDevice"
+ })
+ });
+ } else if (res.data.code == 401 || res.data.code == 4008) {
+ // 401 token过期 / 4008 token为空
+ // 重新请求token解析数据
+ this.refreshToken(() => {
+ this.getDeviceSettingList();
+ }, true);
+ }
+ });
+ }
+})
\ No newline at end of file
diff --git a/pages/searchDevice/searchDevice.json b/pages/searchDevice/searchDevice.json
new file mode 100644
index 0000000..58616d8
--- /dev/null
+++ b/pages/searchDevice/searchDevice.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "搜索设备",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/searchDevice/searchDevice.wxml b/pages/searchDevice/searchDevice.wxml
new file mode 100644
index 0000000..0a6d437
--- /dev/null
+++ b/pages/searchDevice/searchDevice.wxml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+ {{initText}}
+ 请轻轻踩秤,保证屏幕亮起
+
\ No newline at end of file
diff --git a/pages/searchDevice/searchDevice.wxss b/pages/searchDevice/searchDevice.wxss
new file mode 100644
index 0000000..f2149ff
--- /dev/null
+++ b/pages/searchDevice/searchDevice.wxss
@@ -0,0 +1,78 @@
+page {
+ width: 100%;
+ height: 100%;
+ padding-top: 120rpx;
+ box-sizing: border-box;
+ background-color: #FFFFFF;
+}
+
+.icon {
+ width: 556rpx;
+ height: 556rpx;
+ position: relative;
+ margin: 0 auto 120rpx;
+}
+
+.icon>view:nth-of-type(1) {
+ position: absolute;
+ z-index: 3;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: auto;
+ width: 200rpx;
+ height: 200rpx;
+ border-radius: 50%;
+}
+
+.icon>view:nth-of-type(2),
+.icon>view:nth-of-type(3) {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: auto;
+ width: 200rpx;
+ height: 200rpx;
+ border-radius: 50%;
+ animation: expand 2s infinite;
+}
+
+@keyframes expand {
+ 0% {
+ width: 200rpx;
+ height: 200rpx;
+ background-color: #3194FB;
+ }
+ 100% {
+ width: 556rpx;
+ height: 556rpx;
+ background-color: rgba(0, 0, 0, 0);
+ }
+}
+
+.description {
+ width: 100%;
+}
+
+.description>view:nth-of-type(1) {
+ color: #252535;
+ width: 100%;
+ height: 36rpx;
+ font-size: 36rpx;
+ font-weight: bold;
+ line-height: 36rpx;
+ text-align: center;
+ margin-bottom: 30rpx;
+}
+
+.description>view:nth-of-type(2) {
+ color: #808080;
+ width: 100%;
+ height: 30rpx;
+ font-size: 30rpx;
+ line-height: 30rpx;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/pages/setNetwork/setNetwork.js b/pages/setNetwork/setNetwork.js
new file mode 100644
index 0000000..8c79b80
--- /dev/null
+++ b/pages/setNetwork/setNetwork.js
@@ -0,0 +1,42 @@
+const app = getApp();
+import $ from "../../utils/request";
+
+Page({
+ onLoad(options) {
+ let ssid = options.ssid;
+ let password = options.password;
+ app.globalData.ppScale.activeProtocol.dataConfigNetWork({
+ domain: app.globalData.ppScale.domain,
+ ssid: options.ssid,
+ password: options.password
+ }, (res) => {
+ app.globalData.ppScale.wifi.ssid = ssid;
+ app.globalData.ppScale.wifi.password = password;
+
+ let scaleDeviceId = app.globalData.ppScale.device.mac.replace(/:/g, '');
+ let params = {
+ equipmentName: app.globalData.ppScale.device.name,
+ scaleDeviceId: scaleDeviceId,
+ };
+ $.ajax("weighingScale/binding/device", params, "POST").then(res => {
+ app.globalData.ppScale.activeProtocol.codeSetBindingState((res) => {
+ console.log("setNetwork.js codeSetBindingState", res);
+
+ wx.navigateTo({
+ url: "/pages/setNetworkSuccessful/setNetworkSuccessful"
+ })
+ })
+ }).catch(err => {
+ wx.showToast({
+ icon: "none",
+ title: err.message
+ })
+ setTimeout(() => {
+ wx.switchTab({
+ url: "/pages/home/home"
+ })
+ }, 1500)
+ })
+ })
+ }
+})
\ No newline at end of file
diff --git a/pages/setNetwork/setNetwork.json b/pages/setNetwork/setNetwork.json
new file mode 100644
index 0000000..754b6a9
--- /dev/null
+++ b/pages/setNetwork/setNetwork.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "正在配网",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/setNetwork/setNetwork.wxml b/pages/setNetwork/setNetwork.wxml
new file mode 100644
index 0000000..d5908ce
--- /dev/null
+++ b/pages/setNetwork/setNetwork.wxml
@@ -0,0 +1,13 @@
+
+
+
+
+ 已链接,配网中...
+ 请持续站在秤上,耐心等待
+
+
+
+ 手机尽量靠近设备(2米以内)
+ Wi-Fi指示灯闪烁,处于配网状态
+ Wi-Fi指示灯长亮为已连接状态
+
\ No newline at end of file
diff --git a/pages/setNetwork/setNetwork.wxss b/pages/setNetwork/setNetwork.wxss
new file mode 100644
index 0000000..d15b18d
--- /dev/null
+++ b/pages/setNetwork/setNetwork.wxss
@@ -0,0 +1,54 @@
+page {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 90rpx 60rpx 120rpx;
+ background-color: #ffffff;
+}
+
+.icon {
+ width: 100%;
+}
+
+.icon>view:nth-of-type(1) {
+ width: 565rpx;
+ height: 500rpx;
+ margin: 0 auto;
+}
+
+.icon>view:nth-of-type(2) {
+ color: #1385FA;
+ width: 100%;
+ height: 36rpx;
+ font-size: 36rpx;
+ font-weight: bold;
+ line-height: 36rpx;
+ text-align: center;
+ margin-bottom: 28rpx;
+}
+
+.icon>view:nth-of-type(3) {
+ color: #808080;
+ width: 100%;
+ height: 30rpx;
+ font-size: 30rpx;
+ text-align: center;
+ line-height: 30rpx;
+}
+
+.describe {
+ width: 100%;
+}
+
+.describe>view {
+ color: #808080;
+ width: 100%;
+ font-size: 26rpx;
+ font-weight: bold;
+ line-height: 26rpx;
+ margin-bottom: 26rpx;
+}
+
+.describe>view:last-of-type {
+ margin-bottom: 0;
+}
\ No newline at end of file
diff --git a/pages/setNetworkSuccessful/setNetworkSuccessful.js b/pages/setNetworkSuccessful/setNetworkSuccessful.js
new file mode 100644
index 0000000..bf4d50b
--- /dev/null
+++ b/pages/setNetworkSuccessful/setNetworkSuccessful.js
@@ -0,0 +1,115 @@
+const app = getApp();
+
+Page({
+ data: {
+ userInfo: null,
+ subUser: {
+ i: 0,
+ data: []
+ },
+
+ ssid: ""
+ },
+
+ onLoad(options) {
+ this.setData({
+ userInfo: wx.getStorageSync("userInfo"),
+ ssid: app.globalData.ppScale.wifi.ssid
+ });
+ },
+
+ completeClick() {
+ let userInfo = this.data.userInfo;
+ // 设置主用户时userID为小程序的用户ID,memberID为空
+ app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
+ userID: userInfo.id,
+ userName: userInfo.realname,
+ memberID: "",
+ age: this.getAge(userInfo.birthday), //
+ gender: userInfo.sex, //
+ height: userInfo.height, //
+ isAthleteMode: 0,
+ currentWeight: userInfo.weight, //
+ deviceHeaderIndex: 0,
+ targetWeight: "",
+ idealWeight: "",
+ recentData: [],
+ }, (res) => {
+ console.log("dataSyncUserInfo", res);
+
+ if(this.data.subUser.data && this.data.subUser.data.length) {
+ wx.showLoading({
+ title: "正在同步用户信息,请稍等...",
+ mask: true
+ });
+ setSubUser();
+ } else {
+ app.globalData.ppScale.plugin.Blue.stop();
+ wx.switchTab({
+ url: "/pages/home/home"
+ })
+ }
+ })
+ },
+
+ setSubUser() {
+ let userInfo = this.data.userInfo;
+ let i = this.data.subUser.i;
+ let subUser = this.data.subUser.data;
+ app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
+ userID: userInfo.id,
+ userName: subUser[i].realname,
+ memberID: subUser[i].id,
+ age: this.getAge(subUser[i].birthday), //
+ gender: subUser[i].sex, //
+ height: subUser[i].height, //
+ isAthleteMode: 0,
+ currentWeight: subUser[i].weight, //
+ deviceHeaderIndex: 0,
+ targetWeight: "",
+ idealWeight: "",
+ recentData: [],
+ }, (res) => {
+ console.log("dataSyncSubUserInfo", res);
+ if(i < subUser.length) {
+ this.setData({
+ ['subUser.i']: i + 1
+ })
+ setSubUser();
+ } else {
+ app.globalData.ppScale.plugin.Blue.stop();
+ wx.hideLoading();
+ wx.switchTab({
+ url: "/pages/home/home"
+ })
+ }
+ })
+ },
+
+ // 获取家庭成员列表
+ getSubUser() {
+ let params = {};
+ $.ajax("weighingScale/list/subUser", params, "GET", true, "正在获取成员列表...").then(res => {
+ this.setData({
+ ['subUser.data']: res.result
+ })
+ })
+ },
+
+ // 根据生日获取年龄
+ getAge(birthDateString) {
+ const birthDate = new Date(birthDateString);
+ const today = new Date();
+
+ let age = today.getFullYear() - birthDate.getFullYear();
+ const monthDiff = today.getMonth() - birthDate.getMonth();
+ const dayDiff = today.getDate() - birthDate.getDate();
+
+ // 如果当前月份小于出生月份,或者同月但当前日期小于出生日期,年龄需要减 1
+ if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+ age--;
+ }
+
+ return age;
+ }
+})
\ No newline at end of file
diff --git a/pages/setNetworkSuccessful/setNetworkSuccessful.json b/pages/setNetworkSuccessful/setNetworkSuccessful.json
new file mode 100644
index 0000000..84c4caf
--- /dev/null
+++ b/pages/setNetworkSuccessful/setNetworkSuccessful.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "绑定成功",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/setNetworkSuccessful/setNetworkSuccessful.wxml b/pages/setNetworkSuccessful/setNetworkSuccessful.wxml
new file mode 100644
index 0000000..25db03c
--- /dev/null
+++ b/pages/setNetworkSuccessful/setNetworkSuccessful.wxml
@@ -0,0 +1,21 @@
+
+
+
+
+ 配网成功
+
+
+
+ 当前设备配置Wi-Fi
+
+
+
+
+ {{ssid}}
+
+
+
+
+
+
+完成
\ No newline at end of file
diff --git a/pages/setNetworkSuccessful/setNetworkSuccessful.wxss b/pages/setNetworkSuccessful/setNetworkSuccessful.wxss
new file mode 100644
index 0000000..ec46075
--- /dev/null
+++ b/pages/setNetworkSuccessful/setNetworkSuccessful.wxss
@@ -0,0 +1,93 @@
+page {
+ width: 100%;
+ padding: 200rpx 85rpx 0;
+ box-sizing: border-box;
+ background-color: #ffffff;
+}
+
+.icon {
+ width: 100%;
+ margin-bottom: 120rpx;
+}
+
+.icon>view:first-of-type {
+ width: 360rpx;
+ height: 295rpx;
+ margin: 0 auto 50rpx;
+}
+
+.icon>view:last-of-type {
+ color: #252535;
+ width: 100%;
+ height: 40rpx;
+ font-size: 40rpx;
+ font-weight: bold;
+ line-height: 40rpx;
+ text-align: center;
+}
+
+.info {
+ width: 100%;
+ margin-bottom: 380rpx;
+}
+
+.info>view:first-of-type {
+ color: #B6B6B6;
+ width: 100%;
+ height: 30rpx;
+ font-size: 30rpx;
+ line-height: 30rpx;
+ margin-bottom: 40rpx;
+}
+
+.info>view:last-of-type {
+ width: 100%;
+ height: 80rpx;
+ margin: 30rpx 0;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+}
+
+.info>view:last-of-type>view:nth-of-type(1) {
+ width: 80rpx;
+ height: 80rpx;
+ margin-right: 24rpx;
+}
+
+.info>view:last-of-type>view:nth-of-type(2) {
+ color: #252535;
+ flex: 1;
+ width: 0;
+ height: 80rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 80rpx;
+}
+
+.info>view:last-of-type>view:nth-of-type(3) {
+ width: 32rpx;
+ height: 32rpx;
+}
+
+.describe {
+ color: #B6B6B6;
+ width: 100%;
+ height: 26rpx;
+ font-size: 28rpx;
+ line-height: 28rpx;
+ text-align: center;
+ margin-bottom: 46rpx;
+}
+
+.btn {
+ color: #FFFFFF;
+ width: 100%;
+ height: 88rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 88rpx;
+ text-align: center;
+ border-radius: 44rpx;
+ background-color: #1385FA;
+}
\ No newline at end of file
diff --git a/pages/setWifiPassword/setWifiPassword.js b/pages/setWifiPassword/setWifiPassword.js
new file mode 100644
index 0000000..895e02d
--- /dev/null
+++ b/pages/setWifiPassword/setWifiPassword.js
@@ -0,0 +1,27 @@
+const app = getApp();
+
+Page({
+ data: {
+ wifiInfo: null,
+ password: "mimahaojige8"
+ },
+
+ onLoad(options) {
+ this.setData({
+ wifiInfo: JSON.parse(options.item)
+ })
+ },
+
+ passwordInput(e) {
+ this.setData({
+ password: e.detail.value
+ })
+ },
+
+ // 打开配网
+ openSetNetwork() {
+ wx.navigateTo({
+ url: "/pages/setNetwork/setNetwork?ssid=" + this.data.wifiInfo.ssid + "&password=" + this.data.password
+ })
+ }
+})
\ No newline at end of file
diff --git a/pages/setWifiPassword/setWifiPassword.json b/pages/setWifiPassword/setWifiPassword.json
new file mode 100644
index 0000000..4200326
--- /dev/null
+++ b/pages/setWifiPassword/setWifiPassword.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "输入Wi-Fi密码",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/setWifiPassword/setWifiPassword.wxml b/pages/setWifiPassword/setWifiPassword.wxml
new file mode 100644
index 0000000..4ca529d
--- /dev/null
+++ b/pages/setWifiPassword/setWifiPassword.wxml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ {{wifiInfo.ssid}}
+
+
+ 密码
+
+
+
+
+
+
+
+
+
+连接
\ No newline at end of file
diff --git a/pages/setWifiPassword/setWifiPassword.wxss b/pages/setWifiPassword/setWifiPassword.wxss
new file mode 100644
index 0000000..ebd4598
--- /dev/null
+++ b/pages/setWifiPassword/setWifiPassword.wxss
@@ -0,0 +1,81 @@
+page {
+ padding: 55rpx 55rpx 0;
+ background-color: #ffffff;
+}
+
+.form {
+ width: 100%;
+ margin-bottom: 64rpx;
+}
+
+.form>view {
+ width: 100%;
+ height: 96rpx;
+ display: flex;
+ flex-wrap: nowrap;
+ align-items: center;
+ padding: 0 24rpx;
+ box-sizing: border-box;
+ border-radius: 16rpx;
+ background-color: #F6F6F6;
+}
+
+.form>view:first-of-type {
+ margin-bottom: 32rpx;
+}
+
+.form>view>view:nth-of-type(1) {
+ color: #252535;
+ width: 100rpx;
+ height: 96rpx;
+ line-height: 96rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+}
+
+.form>view:first-of-type>view:nth-of-type(1) {
+ padding: 24rpx 45rpx 24rpx 7rpx;
+ box-sizing: border-box;
+ display: flex;
+ align-items: center;
+}
+
+.form>view>view:nth-of-type(2) {
+ color: #252535;
+ flex: 1;
+ width: 0;
+ height: 96rpx;
+ font-size: 32rpx;
+ line-height: 96rpx;
+}
+
+.form>view>view:nth-of-type(2) input {
+ color: #252535;
+ width: 100%;
+ height: 96rpx;
+ font-size: 32rpx;
+ line-height: 96rpx;
+}
+
+.placeholderClass {
+ color: #B6B6B6;
+ font-size: 32rpx;
+}
+
+.form>view>view:nth-of-type(3) {
+ width: 56rpx;
+ height: 56rpx;
+}
+
+.btn {
+ color: #FFFFFF;
+ width: 580rpx;
+ height: 88rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 88rpx;
+ margin: 0 auto;
+ text-align: center;
+ border-radius: 44rpx;
+ background-color: #1385FA;
+}
\ No newline at end of file
diff --git a/pages/userInfo/userInfo.js b/pages/userInfo/userInfo.js
new file mode 100644
index 0000000..4bd57e1
--- /dev/null
+++ b/pages/userInfo/userInfo.js
@@ -0,0 +1,475 @@
+const app = getApp();
+import $ from "../../utils/request";
+
+Page({
+ data: {
+ deviceConnect: false,
+
+ initBluetooth: "0",
+ customerType: "1",
+
+ id: "",
+ realname: "",
+ sex: {
+ index: null,
+ data: [{
+ id: 1,
+ name: '男'
+ }, {
+ id: 2,
+ name: '女'
+ }]
+ },
+ birthday: {
+ label: "1980年01月01日",
+ value: "1980-01-01"
+ },
+ phone: "",
+ height: {
+ index: 50,
+ data: Array.from({ length: 200 - 120 + 1 }, (_, i) => i + 120)
+ },
+ weight: {
+ index: 20,
+ data: Array.from({ length: 100 - 50 + 1 }, (_, i) => i + 50)
+ },
+ },
+
+ onLoad(options) {
+ // initBluetooth 是否初始化蓝牙和设备 1 是 / 0 否
+ // customerType 用户类型 1 自己 / 0 他人
+ // id 用户ID 当customerType为0时,家庭成员的用户ID / 为1时始终为空字符串
+ this.setData({
+ id: options.id ? options.id : null,
+ initBluetooth: options.initBluetooth,
+ customerType: options.customerType,
+ })
+ if(options.customerType === "0") {
+ wx.setNavigationBarTitle({
+ title: options.id ? '编辑成员档案' : '新增成员档案'
+ })
+ if(options.id) {
+ this.subUserInfo()
+ }
+ } else {
+ let userInfo = wx.getStorageSync("userInfo") || null;
+ if (userInfo && options.initBluetooth === "1") {
+ let [year, month, day] = userInfo.birthday.split("-");
+ this.setData({
+ realname: userInfo.realname,
+ ["sex.index"]: this.data.sex.data.findIndex(item => {return item.name === userInfo.sex_dictText}),
+ birthday: {
+ label: year + "年" + month + "月" + day + "日",
+ value: userInfo.birthday
+ },
+ phone: userInfo.phone,
+ ["height.index"]: this.data.height.data.findIndex(item => {return item === userInfo.height}),
+ ["weight.index"]: this.data.weight.data.findIndex(item => {return item === userInfo.weight}),
+ })
+ }
+ }
+ if(options.initBluetooth === "1") {
+ this.initBluetooth();
+
+ app.globalData.ppScale.plugin.bus.subscribe("deviceConnect", (res) => {
+ console.log('deviceInfo ===》deviceConnect', res);
+
+
+ app.globalData.ppScale.plugin.ScaleAction.startDataProgress();
+ app.globalData.ppScale.activeProtocol = app.globalData.ppScale.plugin.ScaleAction.getActiveProtocol();
+
+ app.globalData.ppScale.activeProtocol.codeUpdateMTU((res) => {
+ console.log("deviceInfo ===》codeUpdateMTU", res);
+
+ $.ajax("weighingScale/list/device", {}, "GET", false).then((res) => {
+ if(res.result && res.result.length) {
+ let deviceConnect = res.result.some(item => item.macAddress === app.globalData.ppScale.device.mac);
+ if(deviceConnect) {
+ this.setData({
+ deviceConnect: true
+ })
+ } else {
+ app.globalData.ppScale.plugin.Blue.disconnect();
+ }
+ }
+ })
+ });
+ });
+ }
+ },
+
+ // 初始化蓝牙
+ initBluetooth() {
+ wx.openBluetoothAdapter({
+ success: () => {
+ this.getDeviceSettingList();
+ },
+ fail: (err) => {
+ if (err.errCode === 10001) {
+ wx.showModal({
+ title: "提示",
+ content: "请打开手机蓝牙",
+ });
+ }
+ },
+ });
+ },
+
+ async refreshToken(fn, flag) {
+ let bodyToken = wx.getStorageSync('bodyToken');
+ let bodyTokenTime = wx.getStorageSync('bodyTokenTime');
+ if (!bodyToken || bodyTokenTime * 1000 < +new Date() || flag) {
+ let res = await app.globalData.ppScale.plugin.refreshToken({
+ url: "https://uniquehealth.lefuenergy.com",
+ data: {
+ "appKey": app.globalData.ppScale.options.key,
+ "appSecret": app.globalData.ppScale.options.secret
+ }
+ });
+ if (res.data.code == 200) {
+ wx.setStorageSync('bodyToken', res.data.data.token);
+ wx.setStorageSync('bodyTokenTime', res.data.data.expireTime);
+ fn();
+ }
+ } else {
+ fn();
+ }
+ },
+ getDeviceSettingList() {
+ let bodyToken = wx.getStorageSync("bodyToken");
+ app.globalData.ppScale.plugin.getDeviceSettingList({
+ url: "https://uniquehealth.lefuenergy.com",
+ data: {
+ appKey: app.globalData.ppScale.options.key
+ },
+ header: {
+ "token": bodyToken,
+ "Accept-Language": wx.getStorageSync("lang") || 'zh'
+ }
+ }).then((res) => {
+ if (res.data.code == 200) {
+ app.globalData.ppScale.plugin.Blue.setDeviceSetting(res.data.data);
+ app.globalData.ppScale.device.setting = res.data.data;
+ let deviceNames = res.data.data.map(item => item.deviceName);
+ app.globalData.ppScale.plugin.Blue.start(deviceNames, false);
+ app.globalData.ppScale.plugin.bus.subscribe("devicesList", (res_) => {
+ app.globalData.ppScale.plugin.Blue.stopBluetoothDevicesDiscovery();
+ app.globalData.ppScale.plugin.Blue.createBLEConnection(res_[0]);
+ });
+ } else if (res.data.code == 401 || res.data.code == 4008) {
+ // 401 token过期 / 4008 token为空
+ // 重新请求token解析数据
+ this.refreshToken(() => {
+ this.getDeviceSettingList();
+ }, true);
+ }
+ });
+ },
+
+ // 姓名输入
+ realnameInput(e) {
+ let realname = e.detail.value.replace(/\s+/g, '');
+ this.setData({
+ realname: realname
+ })
+ },
+
+ // 性别选择
+ sexChange(e) {
+ let sex = e.detail.value;
+ console.log(sex);
+ this.setData({
+ ['sex.index']: e.detail.value
+ })
+ if(this.data.height.index === null) {
+ this.setData({
+ ['height.index']: sex == 0 ? 50 : 40
+ })
+ }
+ if(this.data.weight.index === null) {
+ this.setData({
+ ['weight.index']: sex == 0 ? 20 : 10
+ })
+ }
+ },
+
+ // 生日选择
+ birthdayChange(e) {
+ let v = e.detail.value;
+ let [year, month, day] = v.split("-");
+ this.setData({
+ birthday: {
+ label: year + "年" + month + "月" + day + "日",
+ value: v
+ }
+ })
+ },
+
+ // 获取手机号
+ getPhoneNumber(e) {
+ let params = {
+ code: e.detail.code,
+ thirdId: wx.getStorageSync("userInfo").thirdId
+ };
+ $.ajax("weighingScale/getPhone", params, "POST").then(res => {
+ wx.setStorageSync("userInfo", res.result.user);
+ wx.setStorageSync("token", res.result.token);
+ this.setData({
+ phone: res.result.user.phone
+ })
+ })
+ },
+
+ // 身高选择
+ heightChange(e) {
+ this.setData({
+ ['height.index']: e.detail.value
+ })
+ },
+
+ // 体重选择
+ weightChange(e) {
+ this.setData({
+ ['weight.index']: e.detail.value
+ })
+ },
+
+ // 提交判断
+ submit() {
+ let realname = this.data.realname;
+ let sex = this.data.sex;
+ let birthday = this.data.birthday;
+ let phone = this.data.phone;
+ let height = this.data.height;
+ let weight = this.data.weight;
+ if(this.data.initBluetooth === "1" && !this.data.deviceConnect) {
+ wx.showToast({
+ icon: "none",
+ title: "请靠近设备并点亮后再试"
+ })
+ this.initBluetooth();
+ return false;
+ }
+ if(!realname) {
+ wx.showToast({
+ icon: "none",
+ title: "姓名不能为空"
+ })
+ return false;
+ }
+ if(sex.index === null) {
+ wx.showToast({
+ icon: "none",
+ title: "性别不能为空"
+ })
+ return false;
+ }
+ if(!birthday.value) {
+ wx.showToast({
+ icon: "none",
+ title: "生日不能为空"
+ })
+ return false;
+ }
+ if(this.data.customerType === "1" && !phone) {
+ wx.showToast({
+ icon: "none",
+ title: "手机号不能为空"
+ })
+ return false;
+ }
+ if(height.index === null) {
+ wx.showToast({
+ icon: "none",
+ title: "身高不能为空"
+ })
+ return false;
+ }
+ if(weight.index === null) {
+ wx.showToast({
+ icon: "none",
+ title: "体重不能为空"
+ })
+ return false;
+ }
+ if(this.data.customerType === "1") {
+ this.submitMe({
+ realname: realname,
+ sex: sex.data[sex.index].id,
+ birthday: birthday.value,
+ phone: phone,
+ height: height.data[height.index],
+ weight: weight.data[weight.index]
+ });
+ } else {
+ this.submitUser({
+ id: this.data.id,
+ realname: realname,
+ sex: sex.data[sex.index].id,
+ birthday: birthday.value,
+ height: height.data[height.index],
+ weight: weight.data[weight.index]
+ });
+ }
+ },
+
+ // 提交自己的信息
+ submitMe(params) {
+ $.ajax("weighingScale/edit/user", params, "POST", true, "保存中...").then(res => {
+ $.ajax("weighingScale/select/user", {}, "GET", true, "更新用户信息中...").then(res_ => {
+ wx.setStorageSync("userInfo", res_.result);
+ wx.showToast({
+ icon: "none",
+ title: res.message
+ })
+ if(this.data.initBluetooth === "1") {
+ app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
+ userID: res_.result.id,
+ userName: res_.result.realname,
+ memberID: "",
+ age: this.getAge(res_.result.birthday), //
+ gender: res_.result.sex, //
+ height: res_.result.height, //
+ isAthleteMode: 0,
+ currentWeight: res_.result.weight, //
+ deviceHeaderIndex: 0,
+ targetWeight: "",
+ idealWeight: "",
+ recentData: [],
+ }, (res) => {
+ console.log("dataSyncUserInfo", res)
+ app.globalData.ppScale.plugin.Blue.stop();
+ setTimeout(() => {
+ wx.navigateBack({
+ delta: 1
+ })
+ }, 1500)
+ })
+ } else {
+ setTimeout(() => {
+ wx.navigateBack({
+ delta: 1
+ })
+ }, 1500)
+ }
+ })
+ })
+ },
+
+ // 提交家庭成员的信息
+ submitUser(params) {
+ $.ajax("weighingScale/edit/subUser", params, "POST", true, "保存中...").then(res => {
+ wx.showToast({
+ icon: "none",
+ title: res.message
+ })
+ app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
+ userID: wx.getStorageSync("userInfo").id,
+ userName: params.realname,
+ memberID: res.result,
+ age: this.getAge(params.birthday), //
+ gender: params.sex, //
+ height: params.height, //
+ isAthleteMode: 0,
+ currentWeight: params.weight, //
+ deviceHeaderIndex: 0,
+ targetWeight: "",
+ idealWeight: "",
+ recentData: [],
+ }, (res) => {
+ console.log("dataSyncUserInfo", res)
+ app.globalData.ppScale.plugin.Blue.stop();
+ setTimeout(() => {
+ wx.navigateBack({
+ delta: 1
+ })
+ }, 1500)
+ })
+ })
+ },
+
+ // 删除家庭成员
+ delUser() {
+ if(this.data.deviceConnect) {
+ wx.showModal({
+ title: "提示",
+ content: "你要定要删除此成员吗?",
+ success: (res) => {
+ if (res.confirm) {
+ let params = {
+ id: this.data.id
+ };
+ console.log(params);
+ $.ajax("weighingScale/del/subUser", params, "POST", true, "删除中...").then(res => {
+ wx.showToast({
+ icon: "none",
+ title: res.message
+ })
+ app.globalData.ppScale.activeProtocol.dataDeleteUser({
+ userID: wx.getStorageSync("userInfo").id,
+ memberID: this.data.id,
+ }, (res) => {
+ console.log("dataDeleteUser", res);
+ app.globalData.ppScale.plugin.Blue.stop();
+ setTimeout(() => {
+ wx.navigateBack({
+ delta: 1
+ })
+ }, 1500);
+ })
+ })
+ }
+ }
+ })
+ } else {
+ wx.showToast({
+ icon: "none",
+ title: "删除失败,请靠近设备并点亮后再试"
+ })
+ this.initBluetooth();
+ }
+ },
+
+ // 获取家庭成员信息详情
+ subUserInfo() {
+ let params = {
+ userId: this.data.id
+ };
+ $.ajax("weighingScale/select/subUser", params, "GET", false).then(res => {
+ let [year, month, day] = res.result.birthday.split("-");
+ this.setData({
+ realname: res.result.realname,
+ ["sex.index"]: this.data.sex.data.findIndex(item => {return item.name === res.result.sex_dictText}),
+ birthday: {
+ label: year + "年" + month + "月" + day + "日",
+ value: res.result.birthday
+ },
+ ["height.index"]: this.data.height.data.findIndex(item => {return item === res.result.height}),
+ ["weight.index"]: this.data.weight.data.findIndex(item => {return item === res.result.weight}),
+ })
+ })
+ },
+
+ // 根据生日获取年龄
+ getAge(birthDateString) {
+ const birthDate = new Date(birthDateString);
+ const today = new Date();
+
+ let age = today.getFullYear() - birthDate.getFullYear();
+ const monthDiff = today.getMonth() - birthDate.getMonth();
+ const dayDiff = today.getDate() - birthDate.getDate();
+
+ // 如果当前月份小于出生月份,或者同月但当前日期小于出生日期,年龄需要减 1
+ if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+ age--;
+ }
+
+ return age;
+ },
+
+ onUnload() {
+ if(this.data.initBluetooth === "1") {
+ app.globalData.ppScale.plugin.Blue.stop();
+ }
+ }
+})
\ No newline at end of file
diff --git a/pages/userInfo/userInfo.json b/pages/userInfo/userInfo.json
new file mode 100644
index 0000000..6becaf9
--- /dev/null
+++ b/pages/userInfo/userInfo.json
@@ -0,0 +1,6 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "用户档案",
+ "navigationBarBackgroundColor": "#F5F7FB",
+ "disableScroll": true
+}
\ No newline at end of file
diff --git a/pages/userInfo/userInfo.wxml b/pages/userInfo/userInfo.wxml
new file mode 100644
index 0000000..bf1eb72
--- /dev/null
+++ b/pages/userInfo/userInfo.wxml
@@ -0,0 +1,66 @@
+请填写和完善您家人的健康信息,将用于计算身体数据及运动卡路里消耗等,以便准确的分析数据。我们会严格保护您的家庭信息安全。
+
+
+
+ 姓名
+
+
+
+
+
+ 性别
+
+
+ {{sex.index === null ? '请选择性别' : sex.data[sex.index].name}}
+
+
+
+
+ 生日
+
+
+ {{birthday.value ? birthday.label : '请选择生日'}}
+
+
+
+
+
+ 手机号
+
+
+ {{phone}}
+
+
+
+
+
+
+
+
+ 身高
+
+
+ {{height.index === null ? '请选择身高' : height.data[height.index] + ' cm'}}
+
+
+
+
+ 体重
+
+
+ {{weight.index === null ? '请选择体重' : weight.data[weight.index] + ' kg'}}
+
+
+
+
+
+确定
+
+
+ 删除该档案
+
\ No newline at end of file
diff --git a/pages/userInfo/userInfo.wxss b/pages/userInfo/userInfo.wxss
new file mode 100644
index 0000000..c8823f2
--- /dev/null
+++ b/pages/userInfo/userInfo.wxss
@@ -0,0 +1,96 @@
+page {
+ padding: 30rpx 30rpx 0;
+}
+
+.tips {
+ color: #77849E;
+ width: 100%;
+ font-size: 26rpx;
+ line-height: 40rpx;
+ margin-bottom: 40rpx;
+ padding: 0 30rpx;
+ box-sizing: border-box;
+}
+
+.form {
+ width: 100%;
+ padding: 0 30rpx;
+ border-radius: 16rpx;
+ box-sizing: border-box;
+ background-color: #FFFFFF;
+ margin-bottom: 80rpx;
+}
+
+.form>view {
+ width: 100%;
+ height: 120rpx;
+ padding: 0 10rpx;
+ display: flex;
+ flex-wrap: nowrap;
+ box-sizing: border-box;
+ border-bottom: 1rpx solid #EAECF1;
+}
+
+.form>view>view:first-of-type {
+ color: #252535;
+ height: 120rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 120rpx;
+}
+
+.form>view>view:last-of-type {
+ flex: 1;
+ width: 0;
+ color: #B6B6B6;
+ font-size: 28rpx;
+ height: 120rpx;
+ line-height: 120rpx;
+ text-align: right;
+}
+
+.form>view>view:last-of-type.arrowAfter {
+ padding-right: 30rpx;
+}
+
+.form>view>view:last-of-type input {
+ color: #252535;
+ width: 100%;
+ height: 120rpx;
+ line-height: 120rpx;
+ text-align: right;
+}
+
+.placeholderClass {
+ color: #B6B6B6;
+ font-size: 28rpx;
+}
+
+.form>view {
+ border-bottom: 0;
+}
+
+.btn {
+ color: #FFFFFF;
+ width: 580rpx;
+ height: 88rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 88rpx;
+ text-align: center;
+ border-radius: 44rpx;
+ margin: 0 auto 50rpx;
+ background-color: #1385FA;
+}
+
+.delBtn {
+ color: #1385FA;
+ width: 580rpx;
+ height: 88rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ line-height: 88rpx;
+ text-align: center;
+ border-radius: 44rpx;
+ margin: 0 auto;
+}
\ No newline at end of file
diff --git a/project.config.json b/project.config.json
new file mode 100644
index 0000000..0868a6f
--- /dev/null
+++ b/project.config.json
@@ -0,0 +1,29 @@
+{
+ "appid": "wx6c71f3ebcdcddffd",
+ "compileType": "miniprogram",
+ "libVersion": "3.7.11",
+ "packOptions": {
+ "ignore": [],
+ "include": []
+ },
+ "setting": {
+ "coverView": true,
+ "es6": true,
+ "postcss": true,
+ "minified": true,
+ "enhance": true,
+ "showShadowRootInWxmlPanel": true,
+ "packNpmRelationList": [],
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ }
+ },
+ "condition": {},
+ "editorSetting": {
+ "tabIndent": "tab",
+ "tabSize": 4
+ },
+ "simulatorPluginLibVersion": {}
+}
\ No newline at end of file
diff --git a/project.private.config.json b/project.private.config.json
new file mode 100644
index 0000000..cc1267e
--- /dev/null
+++ b/project.private.config.json
@@ -0,0 +1,10 @@
+{
+ "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+ "projectname": "weightScaleMini",
+ "setting": {
+ "compileHotReLoad": true,
+ "urlCheck": false,
+ "bigPackageSizeSupport": true
+ },
+ "libVersion": "3.7.10"
+}
\ No newline at end of file
diff --git a/sitemap.json b/sitemap.json
new file mode 100644
index 0000000..cd24f35
--- /dev/null
+++ b/sitemap.json
@@ -0,0 +1,7 @@
+{
+ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+ "rules": [{
+ "action": "allow",
+ "page": "*"
+ }]
+}
\ No newline at end of file
diff --git a/utils/request.js b/utils/request.js
new file mode 100644
index 0000000..cfbc780
--- /dev/null
+++ b/utils/request.js
@@ -0,0 +1,94 @@
+const app = getApp();
+let loadingCount = 0;
+
+const showLoading = (title) => {
+ if (loadingCount === 0) {
+ wx.showLoading({
+ title: title,
+ mask: true
+ });
+ }
+ loadingCount++;
+};
+
+const hideLoading = () => {
+ if (loadingCount > 0) {
+ loadingCount--;
+ }
+ if (loadingCount === 0) {
+ wx.hideLoading();
+ }
+}
+
+const ajax = (url, params, methos, loading = true, title = "加载中...") => {
+ let requestUrl = app.globalData.wxRequestUrl + url;
+ if (loading) {
+ showLoading(title);
+ }
+
+ return new Promise((resolve, reject) => {
+ let header = {
+ "content-type": "application/json"
+ };
+
+ let token = wx.getStorageSync("token");
+ if (Boolean(token)) {
+ header['X-Access-Token'] = token;
+ }
+ wx.request({
+ url: requestUrl,
+ data: params,
+ method: methos,
+ header: header,
+ success: (res) => {
+ if (loading) {
+ hideLoading();
+ }
+ console.log("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 开始 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
+ switch (res.data.code) {
+ case 200:
+ resolve(res.data);
+ console.log("接口【 " + url + " 】请求成功!状态码为:200(正常)");
+ break;
+ case 400:
+ reject(res.data);
+ console.error("接口【 " + url + " 】请求错误!状态码为:400(报错)");
+ break;
+ case 401:
+ wx.clearStorageSync();
+ reject(res.data);
+ console.error("接口【 " + url + " 】请求错误!状态码为:401(未登录)");
+ break;
+ case 500:
+ reject(res.data);
+ console.error("接口【 " + url + " 】请求错误!状态码为:500(服务器错误)");
+ break;
+ default:
+ reject(res.data);
+ console.error("接口【 " + url + " 】请求错误!状态码为:未知");
+ }
+ console.log("Header参数为 ↓↓↓");
+ console.log(header);
+ console.log("请求参数为 ↓↓↓");
+ console.log(params);
+ console.log("返回参数为 ↓↓↓")
+ console.log(res.data);
+ console.log("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 结束 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
+ },
+ fail: (error) => {
+ if (loading) {
+ hideLoading();
+ }
+ wx.showToast({
+ title: "请求失败,请重试!",
+ icon: "none"
+ })
+ reject(error);
+ }
+ })
+ })
+}
+
+export default {
+ ajax
+}
\ No newline at end of file