diff --git a/yack-mini/.gitignore b/yack-mini/.gitignore
index 4883dfd2..faef680a 100644
--- a/yack-mini/.gitignore
+++ b/yack-mini/.gitignore
@@ -2,6 +2,7 @@
.DS_Store
*.mp3
*.mp4
+project.private.config.json
# 依赖目录(如果有使用 npm)
node_modules/
diff --git a/yack-mini/docs/图标资源获取指南.md b/yack-mini/docs/图标资源获取指南.md
new file mode 100644
index 00000000..e5cc6e36
--- /dev/null
+++ b/yack-mini/docs/图标资源获取指南.md
@@ -0,0 +1,214 @@
+# 图标资源获取指南
+
+## 需要的图标清单
+
+### 1. TabBar 图标(底部导航栏)
+- **device.png** - 设备图标(普通状态)
+ - 搜索关键词:设备、蓝牙、bluetooth、chip、device
+ - 颜色:#999999(灰色)
+ - 尺寸:81px × 81px
+
+- **device-active.png** - 设备图标(激活状态)
+ - 同上图标,颜色改为:#1890ff(蓝色)
+
+- **mine.png** - 我的图标(普通状态)
+ - 搜索关键词:用户、user、个人中心、person
+ - 颜色:#999999(灰色)
+ - 尺寸:81px × 81px
+
+- **mine-active.png** - 我的图标(激活状态)
+ - 同上图标,颜色改为:#1890ff(蓝色)
+
+### 2. 功能图标
+- **default-avatar.png** - 默认头像
+ - 搜索关键词:头像、avatar、用户头像、default avatar
+ - 建议尺寸:200px × 200px
+ - 颜色:浅灰色填充
+
+- **device-empty.png** - 空状态占位图
+ - 搜索关键词:空状态、empty、无数据、no data
+ - 建议尺寸:300px × 300px
+ - 建议:选择带有设备元素的空状态插画
+
+- **ble-scan.png** - 蓝牙扫描图标
+ - 搜索关键词:蓝牙扫描、bluetooth scan、搜索、search
+ - 建议尺寸:120px × 120px
+ - 颜色:#1890ff(主题蓝色)
+
+## iconfont 使用步骤
+
+### 1. 访问网站
+https://www.iconfont.cn/
+
+### 2. 搜索图标
+- 使用上面提供的关键词搜索
+- 筛选条件:
+ - 类型:图标
+ - 风格:线性/面性(根据喜好选择)
+ - 免费:是
+
+### 3. 选择并添加到项目
+- 点击喜欢的图标
+- 添加到购物车
+- 创建项目:yack-mini-icons
+
+### 4. 下载图标
+- 进入项目
+- 选择 PNG 格式
+- 设置对应尺寸和颜色
+- 批量下载
+
+### 5. 重命名文件
+下载后按照本项目的命名规范重命名:
+```
+下载的图标.png → device.png
+下载的图标.png → device-active.png(修改颜色后再次下载)
+...
+```
+
+## 通过 API 获取图标信息
+
+iconfont.cn 提供了搜索 API,可以通过编程方式获取图标信息。
+
+### API 端点
+```
+POST https://www.iconfont.cn/api/icon/search.json
+```
+
+### 请求参数
+
+| 参数 | 类型 | 说明 | 示例 |
+|------|------|------|------|
+| q | string | 搜索关键词 | 蓝牙 |
+| sortType | string | 排序方式 | updated_at |
+| page | int | 页码 | 1 |
+| pageSize | int | 每页数量 | 54 |
+| sType | string | 筛选类型 | 空(全部) |
+| fromCollection | int | 来源集合 | -1 |
+| fills | string | 填充参数 | 空 |
+| t | long | 时间戳 | 1788578495971 |
+| ctoken | string | CSRF Token | null |
+
+### 请求示例(curl)
+
+```bash
+curl 'https://www.iconfont.cn/api/icon/search.json' \
+ -H 'accept: application/json, text/javascript, */*; q=0.01' \
+ -H 'accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-US;q=0.7' \
+ -H 'content-type: application/x-www-form-urlencoded; charset=UTF-8' \
+ -H 'origin: https://www.iconfont.cn' \
+ -H 'referer: https://www.iconfont.cn/search/index' \
+ -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' \
+ --data-raw 'q=%E8%93%9D%E7%89%99&sortType=updated_at&page=1&pageSize=54&sType=&fromCollection=-1&fills=&t=1788578495971&ctoken=null'
+```
+
+### 响应格式
+
+```json
+{
+ "code": 200,
+ "data": {
+ "count": 1234,
+ "page": 1,
+ "pageSize": 54,
+ "icons": [
+ {
+ "id": "12345",
+ "name": "蓝牙",
+ "font_class": "icon-bluetooth",
+ "show_svg": "",
+ "author_name": "作者名",
+ "price": 0,
+ "tags": ["蓝牙", "bluetooth", "设备"]
+ }
+ ]
+ }
+}
+```
+
+### 使用建议
+
+1. **关键词搜索**:使用中文或英文关键词,如"蓝牙"、"bluetooth"
+2. **URL 编码**:中文关键词需要 URL 编码(如 `%E8%93%9D%E7%89%99` 表示"蓝牙")
+3. **分页**:通过 `page` 参数获取更多结果
+4. **时间戳**:`t` 参数可使用当前时间戳,防止缓存
+5. **鉴权**:部分接口需要登录态,使用 Cookie 中的 `EGG_SESS_ICONFONT` 等
+
+### 批量下载脚本示例
+
+```javascript
+// Node.js 示例:获取蓝牙相关图标
+const axios = require('axios');
+
+async function searchIcons(keyword, page = 1) {
+ const params = new URLSearchParams();
+ params.append('q', keyword);
+ params.append('sortType', 'updated_at');
+ params.append('page', page);
+ params.append('pageSize', 54);
+ params.append('fromCollection', -1);
+ params.append('t', Date.now());
+ params.append('ctoken', 'null');
+
+ const response = await axios.post(
+ 'https://www.iconfont.cn/api/icon/search.json',
+ params,
+ {
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'User-Agent': 'Mozilla/5.0'
+ }
+ }
+ );
+
+ return response.data;
+}
+
+// 使用示例
+searchIcons('蓝牙').then(data => {
+ console.log(`找到 ${data.data.count} 个图标`);
+ data.data.icons.forEach(icon => {
+ console.log(`- ${icon.name} (ID: ${icon.id})`);
+ });
+});
+```
+
+### 注意事项
+
+1. **登录态**:下载 SVG 或 PNG 可能需要登录态
+2. **版权**:部分图标需要付费或遵守商用许可
+3. **频率限制**:避免高频请求,建议间隔 1-2 秒
+4. **Cookie 失效**:长时间使用需重新获取登录态
+5. **官方推荐**:推荐使用网页界面或官方工具进行批量下载
+
+## 替代方案
+
+### 如果找不到合适的图标,可以使用:
+
+1. **微信官方图标库**
+ - WeUI 图标库:https://weui.io/
+ - 提供了标准的小程序图标
+
+2. **Ant Design 图标库**
+ - https://ant.design/components/icon-cn/
+ - 有丰富的图标资源
+
+3. **Font Awesome**
+ - https://fontawesome.com/
+ - 国际知名图标库
+
+## 颜色值参考
+
+```css
+/* 主题色 */
+--primary-color: #1890ff;
+
+/* TabBar 普通状态 */
+--tabbar-normal: #999999;
+
+/* TabBar 激活状态 */
+--tabbar-active: #1890ff;
+
+/* 辅助灰色 */
+--gray-light: #f5f5f5;
+```
\ No newline at end of file
diff --git a/yack-mini/miniprogram/app.json b/yack-mini/miniprogram/app.json
index b01dbfe6..2b9277fb 100644
--- a/yack-mini/miniprogram/app.json
+++ b/yack-mini/miniprogram/app.json
@@ -3,7 +3,8 @@
"pages/login/login",
"pages/index/index",
"pages/device/scan/scan",
- "pages/device/detail/detail"
+ "pages/device/detail/detail",
+ "pages/mine/mine"
],
"window": {
"navigationBarTitleText": "岩安测控网关",
@@ -23,6 +24,12 @@
"text": "设备",
"iconPath": "assets/images/device.png",
"selectedIconPath": "assets/images/device-active.png"
+ },
+ {
+ "pagePath": "pages/mine/mine",
+ "text": "我的",
+ "iconPath": "assets/images/mine.png",
+ "selectedIconPath": "assets/images/mine-active.png"
}
]
},
diff --git a/yack-mini/miniprogram/assets/images/ble-scan.png b/yack-mini/miniprogram/assets/images/ble-scan.png
index 08cd6f2b..75d8a75c 100644
Binary files a/yack-mini/miniprogram/assets/images/ble-scan.png and b/yack-mini/miniprogram/assets/images/ble-scan.png differ
diff --git a/yack-mini/miniprogram/assets/images/default-avatar.png b/yack-mini/miniprogram/assets/images/default-avatar.png
index 08cd6f2b..606ab90f 100644
Binary files a/yack-mini/miniprogram/assets/images/default-avatar.png and b/yack-mini/miniprogram/assets/images/default-avatar.png differ
diff --git a/yack-mini/miniprogram/assets/images/device-active.png b/yack-mini/miniprogram/assets/images/device-active.png
index 08cd6f2b..f7932d9c 100644
Binary files a/yack-mini/miniprogram/assets/images/device-active.png and b/yack-mini/miniprogram/assets/images/device-active.png differ
diff --git a/yack-mini/miniprogram/assets/images/device-empty.png b/yack-mini/miniprogram/assets/images/device-empty.png
index 08cd6f2b..190e8fb3 100644
Binary files a/yack-mini/miniprogram/assets/images/device-empty.png and b/yack-mini/miniprogram/assets/images/device-empty.png differ
diff --git a/yack-mini/miniprogram/assets/images/device.png b/yack-mini/miniprogram/assets/images/device.png
index 08cd6f2b..4207cccd 100644
Binary files a/yack-mini/miniprogram/assets/images/device.png and b/yack-mini/miniprogram/assets/images/device.png differ
diff --git a/yack-mini/miniprogram/assets/images/logo.png b/yack-mini/miniprogram/assets/images/logo.png
deleted file mode 100644
index 08cd6f2b..00000000
Binary files a/yack-mini/miniprogram/assets/images/logo.png and /dev/null differ
diff --git a/yack-mini/miniprogram/assets/images/logo_en.png b/yack-mini/miniprogram/assets/images/logo_en.png
new file mode 100644
index 00000000..6581696c
Binary files /dev/null and b/yack-mini/miniprogram/assets/images/logo_en.png differ
diff --git a/yack-mini/miniprogram/assets/images/logo_zh.png b/yack-mini/miniprogram/assets/images/logo_zh.png
new file mode 100644
index 00000000..d4302087
Binary files /dev/null and b/yack-mini/miniprogram/assets/images/logo_zh.png differ
diff --git a/yack-mini/miniprogram/assets/images/mine-active.png b/yack-mini/miniprogram/assets/images/mine-active.png
new file mode 100644
index 00000000..e7ef7a07
Binary files /dev/null and b/yack-mini/miniprogram/assets/images/mine-active.png differ
diff --git a/yack-mini/miniprogram/assets/images/mine.png b/yack-mini/miniprogram/assets/images/mine.png
new file mode 100644
index 00000000..bd8b46a8
Binary files /dev/null and b/yack-mini/miniprogram/assets/images/mine.png differ
diff --git a/yack-mini/miniprogram/pages/login/login.js b/yack-mini/miniprogram/pages/login/login.js
index 0b67b5cc..f356bd16 100644
--- a/yack-mini/miniprogram/pages/login/login.js
+++ b/yack-mini/miniprogram/pages/login/login.js
@@ -100,11 +100,14 @@ Page({
const loginRes = await request.login(username, password, captchaCode, captchaUuid);
const token = loginRes.token;
+ // 先保存 token(重要:后续请求需要认证)
+ storage.setToken(token);
+
// 获取用户信息
const infoRes = await request.getInfo();
const user = infoRes.user;
- // 保存登录信息
+ // 保存用户信息
app.setLoginInfo({
token: token,
userId: user.userId,
diff --git a/yack-mini/miniprogram/pages/login/login.wxml b/yack-mini/miniprogram/pages/login/login.wxml
index 60a12972..9a8353c9 100644
--- a/yack-mini/miniprogram/pages/login/login.wxml
+++ b/yack-mini/miniprogram/pages/login/login.wxml
@@ -2,7 +2,7 @@
diff --git a/yack-mini/miniprogram/pages/login/login.wxss b/yack-mini/miniprogram/pages/login/login.wxss
index d9a35d2e..aae82f74 100644
--- a/yack-mini/miniprogram/pages/login/login.wxss
+++ b/yack-mini/miniprogram/pages/login/login.wxss
@@ -15,7 +15,7 @@
}
.logo {
- width: 160rpx;
+ width: 400rpx;
height: 160rpx;
margin-bottom: 32rpx;
}
diff --git a/yack-mini/miniprogram/pages/mine/mine.js b/yack-mini/miniprogram/pages/mine/mine.js
new file mode 100644
index 00000000..aa414ae2
--- /dev/null
+++ b/yack-mini/miniprogram/pages/mine/mine.js
@@ -0,0 +1,130 @@
+/* pages/mine/mine.js */
+const storage = require('../../utils/storage.js');
+const { mqttClient } = require('../../services/mqtt-client.js');
+const { bleService } = require('../../services/ble.js');
+
+Page({
+ data: {
+ userInfo: null,
+ mqttStatus: '未连接',
+ mqttStatusColor: '#999',
+ bleStatus: '未初始化',
+ bleStatusColor: '#999',
+ pendingCount: 0,
+ appVersion: '1.0.0'
+ },
+
+ onLoad() {
+ this.loadUserInfo();
+ this.checkStatus();
+ },
+
+ onShow() {
+ // 每次显示页面时刷新状态
+ this.checkStatus();
+ },
+
+ // 加载用户信息
+ loadUserInfo() {
+ const userInfo = storage.getUserInfo();
+ this.setData({ userInfo });
+ },
+
+ // 检查连接状态
+ checkStatus() {
+ // MQTT 状态
+ const mqttState = mqttClient.getState();
+ let mqttStatus = '未连接';
+ let mqttStatusColor = '#999';
+ if (mqttState.connected) {
+ mqttStatus = '已连接';
+ mqttStatusColor = '#52c41a';
+ } else if (mqttState.connecting) {
+ mqttStatus = '连接中';
+ mqttStatusColor = '#1890ff';
+ }
+
+ // 蓝牙状态
+ const bleState = bleService.getState();
+ let bleStatus = '未初始化';
+ let bleStatusColor = '#999';
+ if (bleState.connected) {
+ bleStatus = '已连接设备';
+ bleStatusColor = '#52c41a';
+ } else if (bleState.adapterAvailable) {
+ bleStatus = '蓝牙已开启';
+ bleStatusColor = '#1890ff';
+ } else if (bleState.adapterAvailable === false) {
+ bleStatus = '蓝牙未开启';
+ bleStatusColor = '#ff4d4f';
+ }
+
+ // 离线缓存数量
+ const pendingData = storage.getPendingData();
+ const pendingCount = pendingData ? pendingData.length : 0;
+
+ this.setData({
+ mqttStatus,
+ mqttStatusColor,
+ bleStatus,
+ bleStatusColor,
+ pendingCount
+ });
+ },
+
+ // 清除缓存
+ clearCache() {
+ wx.showModal({
+ title: '提示',
+ content: '确定要清除缓存吗?这将清除所有离线数据。',
+ success: (res) => {
+ if (res.confirm) {
+ storage.clearPendingData();
+ wx.showToast({
+ title: '清除成功',
+ icon: 'success'
+ });
+ this.checkStatus();
+ }
+ }
+ });
+ },
+
+ // 退出登录
+ logout() {
+ wx.showModal({
+ title: '提示',
+ content: '确定要退出登录吗?',
+ success: (res) => {
+ if (res.confirm) {
+ // 断开 MQTT 连接
+ if (mqttClient.isConnected()) {
+ mqttClient.disconnect();
+ }
+
+ // 断开蓝牙连接
+ if (bleService.isConnected()) {
+ bleService.disconnect();
+ }
+
+ // 清除所有本地数据
+ storage.clearAll();
+
+ // 跳转到登录页
+ wx.reLaunch({
+ url: '/pages/login/login'
+ });
+ }
+ }
+ });
+ },
+
+ // 关于我们
+ showAbout() {
+ wx.showModal({
+ title: '岩安测控网关',
+ content: '版本:' + this.data.appVersion + '\n\n轻量化蓝牙网关,采集 BLE 设备数据透传上报至 yack 平台。',
+ showCancel: false
+ });
+ }
+});
\ No newline at end of file
diff --git a/yack-mini/miniprogram/pages/mine/mine.json b/yack-mini/miniprogram/pages/mine/mine.json
new file mode 100644
index 00000000..1da73fa2
--- /dev/null
+++ b/yack-mini/miniprogram/pages/mine/mine.json
@@ -0,0 +1,3 @@
+{
+ "navigationBarTitleText": "我的"
+}
\ No newline at end of file
diff --git a/yack-mini/miniprogram/pages/mine/mine.wxml b/yack-mini/miniprogram/pages/mine/mine.wxml
new file mode 100644
index 00000000..9fc5fb88
--- /dev/null
+++ b/yack-mini/miniprogram/pages/mine/mine.wxml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+ {{userInfo.userName || '未登录'}}
+ ID: {{userInfo.userId || '-'}}
+
+
+
+
+
+
+ 连接状态
+
+
+ MQTT 状态
+ {{mqttStatus}}
+
+
+ 蓝牙状态
+ {{bleStatus}}
+
+
+ 离线缓存
+ {{pendingCount}} 条
+
+
+
+
+
+
+ 功能
+
+
+ 清除缓存
+ >
+
+
+ 关于
+ >
+
+
+
+
+
+
+
+
+
+
+
+ 版本 {{appVersion}}
+
+
\ No newline at end of file
diff --git a/yack-mini/miniprogram/pages/mine/mine.wxss b/yack-mini/miniprogram/pages/mine/mine.wxss
new file mode 100644
index 00000000..da6aa39e
--- /dev/null
+++ b/yack-mini/miniprogram/pages/mine/mine.wxss
@@ -0,0 +1,139 @@
+/* pages/mine/mine.wxss */
+.container {
+ min-height: 100vh;
+ background-color: #f5f5f5;
+ padding-bottom: 20px;
+}
+
+/* 用户卡片 */
+.user-card {
+ background-color: #1890ff;
+ padding: 40rpx 30rpx;
+ margin-bottom: 20rpx;
+}
+
+.user-info {
+ display: flex;
+ align-items: center;
+}
+
+.avatar {
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 60rpx;
+ background-color: #fff;
+ margin-right: 30rpx;
+}
+
+.info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.username {
+ font-size: 36rpx;
+ color: #fff;
+ font-weight: bold;
+ margin-bottom: 10rpx;
+}
+
+.user-id {
+ font-size: 24rpx;
+ color: rgba(255, 255, 255, 0.8);
+}
+
+/* 通用区块样式 */
+.status-section,
+.function-section {
+ background-color: #fff;
+ margin-bottom: 20rpx;
+}
+
+.section-title {
+ padding: 20rpx 30rpx;
+ font-size: 28rpx;
+ color: #999;
+ background-color: #f5f5f5;
+}
+
+/* 状态列表 */
+.status-list {
+ padding: 0 30rpx;
+}
+
+.status-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 30rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+}
+
+.status-item:last-child {
+ border-bottom: none;
+}
+
+.status-item .label {
+ font-size: 32rpx;
+ color: #333;
+}
+
+.status-item .status {
+ font-size: 28rpx;
+}
+
+/* 功能列表 */
+.function-list {
+ padding: 0 30rpx;
+}
+
+.function-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 30rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+}
+
+.function-item:last-child {
+ border-bottom: none;
+}
+
+.function-name {
+ font-size: 32rpx;
+ color: #333;
+}
+
+.function-arrow {
+ font-size: 28rpx;
+ color: #999;
+}
+
+/* 退出登录 */
+.logout-section {
+ padding: 40rpx 30rpx;
+}
+
+.logout-btn {
+ width: 100%;
+ height: 88rpx;
+ line-height: 88rpx;
+ background-color: #fff;
+ color: #ff4d4f;
+ font-size: 32rpx;
+ border: none;
+ border-radius: 8rpx;
+}
+
+.logout-btn::after {
+ border: none;
+}
+
+/* 版本信息 */
+.version-info {
+ text-align: center;
+ padding: 40rpx 0;
+ font-size: 24rpx;
+ color: #999;
+}
\ No newline at end of file
diff --git a/yack-mini/project.config.json b/yack-mini/project.config.json
index 5e349b16..0f2e11c9 100644
--- a/yack-mini/project.config.json
+++ b/yack-mini/project.config.json
@@ -37,16 +37,24 @@
"ignore": [],
"disablePlugins": [],
"outputPath": ""
- }
+ },
+ "compileWorklet": false,
+ "localPlugins": false,
+ "disableUseStrict": false,
+ "useCompilerPlugins": false,
+ "condition": false,
+ "swc": false,
+ "disableSWC": true
},
"compileType": "miniprogram",
"libVersion": "3.3.4",
- "appid": "wx0000000000000000",
+ "appid": "wxede2cc5d39b2c6ea",
"projectname": "yack-mini",
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
},
- "miniprogramRoot": "miniprogram/"
+ "miniprogramRoot": "miniprogram/",
+ "simulatorPluginLibVersion": {}
}
\ No newline at end of file