uniapp_code项目代码初始化,第一次上传至仓库

This commit is contained in:
Rdzleo 2026-03-10 17:17:17 +08:00
commit 3ffb60fc73
136 changed files with 10446 additions and 0 deletions

9
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,9 @@
{
"version" : "1.0",
"configurations" : [
{
"playground" : "standard",
"type" : "uni-app:app-android"
}
]
}

View File

@ -0,0 +1,594 @@
# BLE 蓝牙传图接口说明
> 本文档供 APP 开发工程师参考,描述手机端与 ESP32-S3 设备端的 BLE 图片传输协议。
> 设备固件ESP-IDF 5.4 + Bluedroid BLE GATT Server
> 适用平台Android + iOSFlutter 跨平台框架)
> 更新日期2026-02-27
---
## 一、设备信息
| 项目 | 值 |
|------|-----|
| 设备名称 | `Airhub_xx:xx:xx:xx:xx:xx`(动态名称,后缀为 BLE MAC 地址) |
| 广播类型 | ADV_IND可连接、可扫描 |
| 广播间隔 | 20ms |
| MTU | 512 字节设备端已设置APP 端连接后必须协商) |
| 屏幕分辨率 | 360×360 圆形 LCD |
| 图片格式 | JPEGBaseline |
| 存储空间 | SPIFFS 2MB |
| 厂商标识 | Scan Response 厂商字段 Company ID `0x4C44` + ASCII `dzbj` |
### 广播数据结构
设备广播分为两部分:
**ADV 数据(主广播包):**
```
02 01 06 — Flags: LE General Discoverable + BR/EDR Not Supported
1C 09 41 69 72 68 75 62 5F xx xx ... — 完整设备名: "Airhub_xx:xx:xx:xx:xx:xx"(长度动态)
```
**Scan Response 数据(扫描响应包):**
```
07 FF 4C 44 64 7A 62 6A — 厂商数据: Company ID 0x4C44 + "dzbj"
03 03 00 0B — 16-bit 服务 UUID: 0x0B00
```
**设备识别方法**:解析 Scan Response 厂商数据段,跳过前 2 字节 Company ID取后 4 字节判断是否为 ASCII `dzbj``0x64 0x7A 0x62 0x6A`)。也可通过设备名称前缀 `Airhub_` 辅助识别。
---
## 二、BLE 服务与特征
设备仅注册一个自定义服务:
```
图片传输服务 (Service UUID: 0x0B00)
├── 图片写入特征 (Characteristic UUID: 0x0B01)
│ ├── 属性: Write + Write Without Response
│ ├── 最大长度: 512 字节
│ └── 用途: 传输图片数据(前序帧 + 分包数据帧)
└── 图片管理特征 (Characteristic UUID: 0x0B02)
├── 属性: Write + Write Without Response
├── 最大长度: 24 字节
└── 用途: 管理命令(设置当前表盘 / 删除图片)
```
> **重要**
> - 两个特征均支持 Write 和 Write Without Response**推荐使用 Write Without ResponsewriteNoResponse** 以提升传输速度
> - APP 端发现服务和特征时,**必须通过 UUID 匹配**`0x0B00` / `0x0B01` / `0x0B02`),不要用数组索引,不同固件版本的服务/特征顺序可能不同
> - 16-bit UUID 在 BLE 协议栈中会被扩展为 128-bit 格式,例如 `0x0B00``00000b00-0000-1000-8000-00805f9b34fb`
---
## 三、连接流程
```
1. 初始化蓝牙适配器openBluetoothAdapter
2. 扫描设备(通过厂商数据 "dzbj" 或设备名前缀 "Airhub_" 识别目标设备)
3. 建立 BLE 连接createBLEConnection
4. 协商 MTU = 512setBLEMTU ← 必须!否则每包只能发 20 字节
5. 发现服务,通过 UUID 匹配 0x0B00
6. 发现特征,通过 UUID 匹配 0x0B01写入和 0x0B02管理
7. 就绪,可以传输图片或发送管理命令
```
---
## 四、图片传输协议(写入特征 0x0B01
### 4.1 关键参数
| 参数 | 值 | 说明 |
|------|-----|------|
| MTU | 512 | 设备端设置APP 端连接后协商 |
| ATT 有效载荷 | **509** | MTU - 3ATT 协议头占 3 字节) |
| 帧头大小 | 2 | 包序号(1) + 结束标志(1) |
| **CHUNK_SIZE** | **507** | 509 - 2 = 每包最大图片数据 |
| 写入方式 | writeNoResponse | Write Without Response不等 ACK |
| 包间延时 | **5ms** | 防止 Android BLE 队列溢出 |
| 前序帧延时 | **50ms** | 前序帧后等待设备端建立接收通道 |
> **严格约束:每个 BLE 数据包总长不得超过 509 字节MTU - 3**
> 超出此限制时Android 系统会**静默截断**数据包不报错导致设备端接收到的数据不完整JPEG 解码失败。
### 4.2 前序帧(固定 26 字节,每次传图发 1 次)
| 字节偏移 | 长度 | 内容 | 说明 |
|----------|------|------|------|
| 0 | 1 | `0xFD` | 固定标识:开始图片传输 |
| 1 ~ 22 | 22 | 文件名 | UTF-8/ASCII 编码,不足 22 字节补 `0x00` |
| 23 | 1 | `(len >> 16) & 0xFF` | 图片总大小 - 高字节 |
| 24 | 1 | `(len >> 8) & 0xFF` | 图片总大小 - 中字节 |
| 25 | 1 | `len & 0xFF` | 图片总大小 - 低字节 |
> - 图片大小为 3 字节大端序,最大支持 16,777,215 字节(~16MB
> - 文件名**必须以 `.jpg` 结尾**,示例:`face_1708012345.jpg`
> - 文件名不能超过 22 字节(含扩展名),建议用 `face_时间戳.jpg` 格式
### 4.3 数据帧(循环发送直到传完)
| 字节偏移 | 长度 | 内容 | 说明 |
|----------|------|------|------|
| 0 | 1 | 包序号 | 从 0 递增溢出后回绕0~255 循环) |
| 1 | 1 | 结束标志 | `0x00` = 后续还有数据;`非0` = 最后一包 |
| 2 ~ N | 最大 **507** | 图片数据 | 实际负载 = 本包总长 - 2 |
> 每个数据帧总长 = 2帧头 + 图片数据 ≤ **509 字节**
### 4.4 传输示例
以一张 1521 字节的图片 `face_170801.jpg` 为例CHUNK_SIZE = 507
```
第 1 包前序帧26 字节):
FD 66 61 63 65 5F 31 37 30 38 30 31 2E 6A 70 67 00 ... 00 05 F1
│ └─────── "face_170801.jpg" + 补零 ──────────────┘ └── 1521 大端序
└─ 标识符 0xFD
[等待 50ms]
第 2 包数据帧509 字节 = 2 + 507:
00 00 [507 字节图片数据]
│ └─ 未结束
└─ 包序号 0
[等待 5ms]
第 3 包数据帧509 字节 = 2 + 507:
01 00 [507 字节图片数据]
│ └─ 未结束
└─ 包序号 1
[等待 5ms]
第 4 包数据帧最后一包509 字节 = 2 + 507:
02 01 [507 字节图片数据]
│ └─ 结束标志 = 1
└─ 包序号 2
```
设备端收到结束帧后,自动:写入 SPIFFS → 更新 NVS → 跳转到图片浏览界面显示新图片。
---
## 五、图片管理命令(管理特征 0x0B02
### 5.1 设置为当前表盘
| 字节偏移 | 长度 | 内容 | 说明 |
|----------|------|------|------|
| 0 ~ 22 | 23 | 文件名 | 与传输时使用的文件名一致,不足补 `0x00` |
| 23 | 1 | `0xFF` | 命令标识:设置为当前表盘 |
设备端收到后:更新 NVS 记录 → 跳转到图片浏览界面显示指定图片。
### 5.2 删除图片
| 字节偏移 | 长度 | 内容 | 说明 |
|----------|------|------|------|
| 0 ~ 22 | 23 | 文件名 | 要删除的文件名 |
| 23 | 1 | `0xF1` | 命令标识:删除该图片 |
设备端收到后从 SPIFFS 中物理删除该文件。
---
## 六、APP 端图片处理流程
APP 端在传输前**必须对图片进行预处理**,确保设备端能正确解码显示:
```
用户选图/拍照
裁剪为 360×360必须设备屏幕分辨率
保存为 .jpg 文件(文件名后缀必须是 .jpg
JPEG 压缩quality: 80~100
读取为 ArrayBuffer
BLE 分包传输
```
### 6.1 关键约束
| 约束项 | 要求 | 原因 |
|--------|------|------|
| 分辨率 | **裁剪**为 360×360 | 设备屏幕为 360×360 圆形 LCD |
| 格式 | JPEGBaseline | 设备端 `esp_jpeg` 仅支持 Baseline JPEG 解码 |
| 文件后缀 | `.jpg` | 文件后缀决定设备端解码方式 |
| 压缩质量 | 80~100 | quality < 70 360×360 屏幕上画质明显模糊 |
| 单张大小 | 建议 < 100KB | SPIFFS 总容量 2MB兼顾传输速度和存储 |
> **踩坑提醒**
> - 裁剪 ≠ 缩放。使用 `crop` 参数进行裁剪,不要使用 `compressedWidth/compressedHeight`(那是缩放,会变形)
> - 文件保存时后缀必须是 `.jpg`,如果用 `.png` 后缀,压缩工具会输出 PNG 格式而非 JPEG设备端无法解码
> - 不支持 Progressive JPEG仅支持 Baseline JPEG
---
## 七、APP 端实现参考代码
### 7.1 通过 UUID 匹配服务和特征
```javascript
// 16-bit UUID 在 BLE 协议栈中会被扩展为 128-bit 格式
// 例如 0x0B00 → "00000b00-0000-1000-8000-00805f9b34fb"
// Android 和 iOS 均返回 128-bit 格式,统一用小写匹配
function findByUuid16(list, uuid16) {
const target = `0000${uuid16.toString(16).padStart(4, '0')}-0000-1000-8000-00805f9b34fb`;
return list.find(item => item.uuid.toLowerCase() === target.toLowerCase());
}
// 使用示例
uni.getBLEDeviceServices({
deviceId: deviceId,
success(res) {
const imageService = findByUuid16(res.services, 0x0B00);
if (!imageService) { console.error('未找到图片服务'); return; }
uni.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: imageService.uuid,
success(charRes) {
const writeChar = findByUuid16(charRes.characteristics, 0x0B01);
const editChar = findByUuid16(charRes.characteristics, 0x0B02);
// writeChar.uuid → 用于图片传输
// editChar.uuid → 用于管理命令
}
});
}
});
```
### 7.2 BLE 写入封装
```javascript
// 必须使用 writeNoResponse传输速度更快
function bleWrite(deviceId, serviceId, characteristicId, buffer) {
return new Promise((resolve, reject) => {
uni.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId,
value: buffer,
writeType: 'writeNoResponse', // 关键Write Without Response
success: resolve,
fail: reject
});
});
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
```
### 7.3 图片选择与预处理
```javascript
// 1. 选择图片并裁剪为 360×360
function chooseAndCropImage() {
return new Promise((resolve, reject) => {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
crop: {
quality: 100, // 裁剪时不压缩
width: 360, // 裁剪宽度
height: 360, // 裁剪高度
resize: true
},
success: (res) => resolve(res.tempFilePaths[0]),
fail: reject
});
});
}
// 2. 保存为 .jpg 后缀文件(关键!决定 compressImage 输出格式)
function saveAsJpg(tempPath, targetDir) {
const fileName = `face_${Date.now()}.jpg`; // 必须 .jpg 后缀
// APP-PLUS 使用 plus.io 复制文件
// 小程序端使用 getFileSystemManager
// ... 平台相关实现
return { fileName, filePath };
}
// 3. JPEG 压缩(输入文件后缀必须是 .jpg
function compressToJpeg(srcPath) {
return new Promise((resolve, reject) => {
uni.compressImage({
src: srcPath, // 输入路径后缀必须是 .jpg
quality: 80, // 80~100 推荐,兼顾画质和体积
success: (res) => resolve(res.tempFilePath),
fail: reject
});
});
}
// 4. 读取文件为 ArrayBufferAPP-PLUS 平台)
function readImageAsArrayBuffer(filePath) {
return new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(filePath, (fileEntry) => {
fileEntry.file((file) => {
const reader = new FileReader();
reader.onloadend = (e) => {
if (e.target.result) {
resolve(e.target.result);
} else {
reject(new Error('读取文件失败'));
}
};
reader.readAsArrayBuffer(file);
});
}, reject);
});
}
```
### 7.4 图片分包传输
```javascript
/**
* 发送图片到设备
* @param {string} deviceId - BLE 设备 ID
* @param {string} serviceUuid - 图片服务 UUID (0x0B00 的 128-bit 形式)
* @param {string} writeUuid - 写入特征 UUID (0x0B01 的 128-bit 形式)
* @param {string} filename - 文件名(须 .jpg 后缀,最长 22 字节)
* @param {ArrayBuffer} imageData - JPEG 图片二进制数据
* @param {function} onProgress - 进度回调 (0~100)
*/
async function sendImage(deviceId, serviceUuid, writeUuid, filename, imageData, onProgress) {
const data = new Uint8Array(imageData);
const len = data.length;
// 1. 发送前序帧26 字节)
const header = new Uint8Array(26);
header[0] = 0xFD;
for (let i = 0; i < Math.min(filename.length, 22); i++) {
header[i + 1] = filename.charCodeAt(i);
}
header[23] = (len >> 16) & 0xFF;
header[24] = (len >> 8) & 0xFF;
header[25] = len & 0xFF;
await bleWrite(deviceId, serviceUuid, writeUuid, header.buffer);
await delay(50); // 等待设备端建立接收通道
// 2. 分包发送图片数据
const CHUNK_SIZE = 507; // (MTU-3) - 2字节帧头 = 509 - 2
let offset = 0;
let packetNo = 0;
while (offset < len) {
const remaining = len - offset;
const chunkLen = Math.min(CHUNK_SIZE, remaining);
const isEnd = (offset + chunkLen >= len) ? 0x01 : 0x00;
const packet = new Uint8Array(2 + chunkLen);
packet[0] = packetNo & 0xFF;
packet[1] = isEnd;
packet.set(data.slice(offset, offset + chunkLen), 2);
await bleWrite(deviceId, serviceUuid, writeUuid, packet.buffer);
await delay(5); // 每包间隔 5ms防止 Android BLE 队列溢出
offset += chunkLen;
packetNo++;
if (onProgress) {
onProgress(Math.floor(offset / len * 100));
}
}
}
```
### 7.5 发送管理命令
```javascript
// 设置为当前表盘
async function setCurrentFace(deviceId, serviceUuid, editUuid, filename) {
const cmd = new Uint8Array(24);
for (let i = 0; i < Math.min(filename.length, 23); i++) {
cmd[i] = filename.charCodeAt(i);
}
cmd[23] = 0xFF;
await bleWrite(deviceId, serviceUuid, editUuid, cmd.buffer);
}
// 删除图片
async function deleteImage(deviceId, serviceUuid, editUuid, filename) {
const cmd = new Uint8Array(24);
for (let i = 0; i < Math.min(filename.length, 23); i++) {
cmd[i] = filename.charCodeAt(i);
}
cmd[23] = 0xF1;
await bleWrite(deviceId, serviceUuid, editUuid, cmd.buffer);
}
```
### 7.6 完整传输流程示例
```javascript
async function uploadWatchFace(deviceId, serviceUuid, writeUuid) {
// 1. 选图并裁剪为 360×360
const tempPath = await chooseAndCropImage();
// 2. 保存为 .jpg 后缀(关键!)
const { fileName, filePath } = saveAsJpg(tempPath, imageDir);
// 3. JPEG 压缩
const jpegPath = await compressToJpeg(filePath);
// 4. 读取为 ArrayBuffer
const buffer = await readImageAsArrayBuffer(jpegPath);
console.log('JPEG 大小:', buffer.byteLength, '字节');
// 5. BLE 分包传输
await sendImage(deviceId, serviceUuid, writeUuid, fileName, buffer, (progress) => {
console.log('传输进度:', progress + '%');
});
console.log('传输完成,设备将自动显示新图片');
}
```
---
## 八、Android / iOS 兼容注意事项
### 8.1 BLE 差异汇总
| 差异项 | Android | iOS |
|--------|---------|-----|
| MTU 协商 | `setBLEMTU(512)` 通常成功 | 系统自动协商,可能返回不同值,需检查实际 MTU |
| 广播数据 | 厂商数据在 `advertisData` 中 | 厂商数据可能在 `advertisData` 或其他字段中 |
| 设备 ID 格式 | MAC 地址格式(如 `D0:CF:13:03:BB:F2` | UUID 格式(每次配对可能不同) |
| BLE 队列 | **队列有限,发送过快触发 10007 错误** | 队列较深,但仍建议加延时 |
| writeNoResponse | 必须加 5ms+ 包间延时 | 可适当减少延时 |
| 蓝牙缓存 | 无明显缓存问题 | **系统缓存服务/特征列表,设备固件更新后可能读到旧数据** |
### 8.2 Android 特别注意
1. **BLE 队列溢出(错误码 10007**Android 的 BLE 写入队列有限,使用 `writeNoResponse` 时如果发送速度过快,队列满后会返回错误码 10007。**必须在每包之间加 5ms 延时**。
2. **MTU 协商**:部分 Android 设备可能协商到低于 512 的 MTU。建议协商后读取实际 MTU 值,动态调整 CHUNK_SIZE = `实际MTU - 3 - 2`
3. **数据包截断**:如果单包超过 `MTU - 3` 字节Android **不会报错**,而是**静默截断**数据。这会导致设备端数据不完整JPEG 解码报错(错误码 6 = JDR_FMT1
### 8.3 iOS 特别注意
1. **蓝牙缓存**iOS 会缓存 BLE 设备的服务和特征信息。如果设备固件更新了 UUID 或服务结构iOS 可能仍使用旧缓存。解决方法:关闭 iOS 蓝牙 → 重新打开 → 重连设备。
2. **设备 ID 不固定**iOS 返回的 `deviceId` 是系统分配的 UUID**不是 MAC 地址**,且取消配对后可能变化。不要用 `deviceId` 做设备持久化标识。
3. **MTU 自动协商**iOS 不支持手动设置 MTU`setBLEMTU` 可能不生效),系统自动协商。通常 iOS 12+ 协商到 185~512 之间。
### 8.4 统一兼容建议
```javascript
// 连接后获取实际 MTU兼容 Android/iOS
let actualMtu = 512;
// Android: 手动协商
// #ifdef APP-PLUS
if (uni.getSystemInfoSync().platform === 'android') {
await new Promise((resolve) => {
uni.setBLEMTU({
deviceId,
mtu: 512,
success: (res) => { actualMtu = 512; resolve(); },
fail: () => { actualMtu = 23; resolve(); } // 协商失败用默认 MTU
});
});
}
// #endif
// 动态计算 CHUNK_SIZE
const CHUNK_SIZE = actualMtu - 3 - 2; // MTU - ATT头(3) - 帧头(2)
```
---
## 九、错误排查指南
| 现象 | 可能原因 | 解决方案 |
|------|----------|----------|
| 设备端 JPEG 解码失败(错误码 6 | 数据包超过 MTU-3 被截断 | 确认 CHUNK_SIZE = MTU-3-2 = 507 |
| Android 报错 10007 | BLE 写入队列溢出 | 每包间隔加 `await delay(5)` |
| 设备收到的不是 JPEG | 文件后缀为 `.png` | 保存文件时后缀改为 `.jpg` |
| 图片模糊 | JPEG quality 过低 | 提高 quality 至 80~100 |
| 图片变形拉伸 | 使用了缩放而非裁剪 | 使用 `crop` 参数裁剪 360×360 |
| 传输完成但设备无反应 | 前序帧 `type` 不是 `0xFD` | 检查前序帧第 0 字节 |
| 找不到服务/特征 | UUID 匹配逻辑错误 | 16-bit UUID 需扩展为 128-bit 后比较 |
| iOS 发现旧的服务结构 | iOS 蓝牙缓存 | 关闭/重开 iOS 蓝牙后重连 |
| 传输中断无法恢复 | 无断点续传机制 | 需从头重新传输整张图片 |
---
## 十、完整时序图
```
APP 端 设备端 (ESP32-S3)
| |
|--- BLE 扫描(过滤厂商数据 "dzbj" | 广播中
| 或设备名前缀 "Airhub_"------------------->|
| |
|--- createBLEConnection --------------------->|
|<-- 连接成功 ----------------------------------|
| |
|--- setBLEMTU(512) [Android] ---------------->|
|<-- MTU 协商完成 -------------------------------|
| |
|--- getBLEDeviceServices -------------------->|
|<-- 服务列表匹配 UUID 0x0B00----------------|
| |
|--- getBLEDeviceCharacteristics -------------->|
|<-- 特征列表0x0B01 写入 + 0x0B02 管理--------|
| |
|=========== 图片预处理 ==========================|
| |
| 裁剪 360×360 → 保存 .jpg → JPEG 压缩 |
| → 读取为 ArrayBuffer |
| |
|=========== 传输图片 ============================|
| |
|--- writeNoResponse 0x0B01: |
| [0xFD + 文件名 + 大小] (26 字节) | 解析前序帧
| | → malloc 接收缓冲区
| [等待 50ms] | → fopen 创建文件
| |
|--- writeNoResponse 0x0B01: |
| [0 + 0x00 + 507字节数据] (≤509字节) | 数据帧 1
| [等待 5ms] |
|--- writeNoResponse 0x0B01: |
| [1 + 0x00 + 507字节数据] (≤509字节) | 数据帧 2
| [等待 5ms] |
|--- ... |
|--- writeNoResponse 0x0B01: |
| [N + 0x01 + 剩余数据] (≤509字节) | 末尾帧
| | → fwrite 写入 SPIFFS
| | → 更新 NVS 当前表盘
| | → 自动跳转图片浏览界面
| |
|=========== 管理命令 ============================|
| |
|--- writeNoResponse 0x0B02: |
| [文件名 + 0xFF] (24字节) | 设置为当前表盘
| | → 跳转图片浏览界面
| |
|--- writeNoResponse 0x0B02: |
| [文件名 + 0xF1] (24字节) | 删除指定图片
| |
|--- closeBLEConnection ---------------------->| → 自动恢复广播
| |
```
---
## 附录:协议参数速查
```
设备名称: Airhub_xx:xx:xx:xx:xx:xx动态后缀为BLE MAC
服务 UUID: 0x0B00 (00000b00-0000-1000-8000-00805f9b34fb)
写入特征 UUID: 0x0B01 (00000b01-0000-1000-8000-00805f9b34fb)
管理特征 UUID: 0x0B02 (00000b02-0000-1000-8000-00805f9b34fb)
MTU: 512
单包最大值: 509 字节 (MTU - 3)
CHUNK_SIZE: 507 字节 (509 - 2字节帧头)
前序帧标识: 0xFD
设置表盘命令: 0xFF
删除图片命令: 0xF1
图片格式: JPEG (Baseline)
图片分辨率: 360 × 360
写入方式: writeNoResponse
包间延时: 5ms (数据帧) / 50ms (前序帧后)
```

0
APP运行日志.md Normal file
View File

48
App.vue Normal file
View File

@ -0,0 +1,48 @@
<script lang="uts">
// #ifdef APP-ANDROID || APP-HARMONY
let firstBackTime = 0
// #endif
export default {
onLaunch: function () {
console.log('App Launch')
},
onShow: function () {
console.log('App Show')
},
onHide: function () {
console.log('App Hide')
},
// #ifdef APP-ANDROID || APP-HARMONY
onLastPageBackPress: function () {
console.log('App LastPageBackPress')
if (firstBackTime == 0) {
uni.showToast({
title: '再按一次退出应用',
position: 'bottom',
})
firstBackTime = Date.now()
setTimeout(() => {
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni.exit()
}
},
// #endif
onExit: function () {
console.log('App Exit')
},
}
</script>
<style>
/*每个页面公共css */
.uni-row {
flex-direction: row;
}
.uni-column {
flex-direction: column;
}
</style>

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main"></script>
</body>
</html>

22
main.js Normal file
View File

@ -0,0 +1,22 @@
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif

77
manifest.json Normal file
View File

@ -0,0 +1,77 @@
{
"name" : "电子吧唧",
"appid" : "__UNI__F18BB63",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {
"Bluetooth" : {},
"Camera" : {}
},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {
"dSYMs" : false
},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
}

24
pages.json Normal file
View File

@ -0,0 +1,24 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "连接设备",
"navigationStyle": "custom"
}
},
{
"path": "pages/connect/connect",
"style": {
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"navigationStyle": "custom"
},
"uniIdRouter": {}
}

1174
pages/connect/connect.vue Normal file

File diff suppressed because it is too large Load Diff

367
pages/index/index.vue Normal file
View File

@ -0,0 +1,367 @@
<template>
<view class="container">
<view class="title-bar">
<text class="title">连接设备</text>
<button
class="scan-btn"
:disabled="isScanning"
@click="toggleScan"
>
{{ isScanning ? '停止扫描' : '开始扫描' }}
</button>
</view>
<view class="status-tip" v-if="isScanning">
<text>正在扫描设备...</text>
<view class="loading"></view>
</view>
<view class="status-tip" v-else-if="foundDevices.length === 0">
<text>未发现设备请点击"开始扫描"</text>
</view>
<view class="device-list">
<view
class="device-item"
v-for="(device, index) in foundDevices"
:key="device.deviceId"
@click="connectDevice(device)"
>
<!-- 设备名称 -->
<view class="device-name">
<text>{{ device.name || '未知设备' }}</text>
<view class="is_bj" v-if="device.is_bj" >吧唧</view>
<text class="device-id">{{ device.deviceId }}</text>
</view>
<!-- 信号强度 -->
<view class="device-rssi">
<text>信号: {{ device.rssi }} dBm</text>
<view class="rssi-bar" :style="{ width: getRssiWidth(device.rssi) }"></view>
</view>
<!-- 连接状态 -->
<view class="device-status" v-if="device.connected">
<text class="connected">已连接</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
foundDevices: [],
isScanning: false,
bluetoothEnabled: false,
connectedDeviceId: ''
};
},
onLoad() {
//
this.initBluetooth();
},
onUnload() {
//
this.stopScan();
uni.closeBluetoothAdapter();
//
uni.offBluetoothDeviceFound(this.onDeviceFound);
},
methods: {
//
initBluetooth() {
uni.openBluetoothAdapter({
success: () => {
this.bluetoothEnabled = true;
// uni.showToast({ title: '', icon: 'none' });
},
fail: (err) => {
this.bluetoothEnabled = false;
uni.showModal({
title: '蓝牙开启失败',
content: '请检查设备蓝牙是否开启',
showCancel: false
});
console.error('蓝牙初始化失败:', err);
}
});
},
// /
toggleScan() {
if (!this.bluetoothEnabled) {
this.initBluetooth();
return;
}
if (this.isScanning) {
this.stopScan();
} else {
this.startScan();
}
},
//
startScan() {
this.isScanning = true;
this.foundDevices = []; //
// services
uni.startBluetoothDevicesDiscovery({
services: [],
allowDuplicatesKey: false, //
success: () => {
uni.showToast({ title: '开始扫描', icon: 'none' });
//
uni.onBluetoothDeviceFound(this.onDeviceFound);
},
fail: (err) => {
this.isScanning = false;
uni.showToast({ title: '扫描失败', icon: 'none' });
console.error('扫描失败:', err);
}
});
// 10
setTimeout(() => {
if (this.isScanning) this.stopScan();
}, 5000);
},
//
stopScan() {
if (!this.isScanning) return;
uni.stopBluetoothDevicesDiscovery({
success: () => {
this.isScanning = false;
if(this.foundDevices.length == 0){
uni.showToast({
title: `暂未扫描到任何设备`,
icon: 'none'
});
return;
}
uni.showToast({
title: `扫描完成,发现${this.foundDevices.length}台设备`,
icon: 'none'
});
},
fail: (err) => {
console.error('停止扫描失败:', err);
}
});
},
//
onDeviceFound(res) {
const devices = res.devices || [];
devices.forEach(device => {
var that = this
if (!device.deviceId) return;
const isExist = this.foundDevices.some(
d => d.deviceId === device.deviceId
);
if (isExist) return;
var is_bj = false;
const advData = new Uint8Array(device.advertisData);
// const companyidData = (advData[0]<<8)| advData[1];
const devicenameData = advData.slice(2, 6);
const devicename = String.fromCharCode(...devicenameData)
if(devicename == 'dzbj') is_bj = true;
this.foundDevices.push({
is_bj: is_bj,
name: device.name || '未知设备',
deviceId: device.deviceId,
rssi: device.RSSI,
connected: device.deviceId === this.connectedDeviceId
});
});
},
// -100dBm0%-30dBm100%
getRssiWidth(rssi) {
const minRssi = -100;
const maxRssi = -30;
let ratio = (rssi - minRssi) / (maxRssi - minRssi);
ratio = Math.max(0, Math.min(1, ratio)); // 0-1
return `${ratio * 100}%`;
},
connectDevice(device) {
var that = this
this.stopScan();
uni.showLoading({ title: '连接中...' });
uni.createBLEConnection({
deviceId:device.deviceId,
success(res) {
that.foundDevices = that.foundDevices.map(d => ({
...d,
connected: d.deviceId === device.deviceId
}));
uni.hideLoading();
uni.showToast({ title: `已连接${device.name}`, icon: 'none' });
uni.navigateTo({
url:'../connect/connect?deviceId='+device.deviceId,
fail: (err) => {
uni.showToast({ title: `连接失败,请稍后重试`, icon: 'error' });
uni.closeBLEConnection({
deviceId:device.deviceId,
success() {
console('断开连接成功')
}
})
}
})
},
fail() {
uni.hideLoading();
uni.showToast({ title: `连接失败`, icon: 'error' });
}
})
}
}
};
</script>
<style scoped>
.container {
padding: 16rpx;
background-color: #f5f5f5;
/* min-height: 100vh; */
}
/* 标题栏 */
.title-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
border-bottom: 1px solid #eee;
margin-bottom: 20rpx;
margin-top: 80rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.scan-btn {
background-color: #00c900;
color: white;
padding: 0rpx 24rpx;
border-radius: 8rpx;
font-size: 28rpx;
margin-right: 5%;
}
.scan-btn:disabled {
background-color: #ccc;
}
/* 状态提示 */
.status-tip {
text-align: center;
padding: 40rpx 0;
color: #666;
font-size: 28rpx;
}
.loading {
width: 30rpx;
height: 30rpx;
border: 3rpx solid #007aff;
border-top-color: transparent;
border-radius: 50%;
margin: 20rpx auto;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* 设备列表 */
.device-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.device-item {
background-color: white;
border-radius: 12rpx;
padding: 24rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
cursor: pointer;
}
.device-name {
display: flex;
justify-content: space-between;
margin-bottom: 16rpx;
}
.device-name text:first-child {
font-size: 32rpx;
color: #333;
}
.is_bj{
padding: 3px 8px;
border-radius: 5px;
color: white;
background-color: rgba(30, 228, 156, 0.4);
position: relative;
right: 30px;
}
.device-id {
font-size: 24rpx;
color: #999;
}
.device-rssi {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.device-rssi text {
font-size: 26rpx;
color: #666;
}
.rssi-bar {
height: 8rpx;
background-color: #eee;
border-radius: 4rpx;
overflow: hidden;
}
.rssi-bar::after {
content: '';
display: block;
height: 100%;
background: linear-gradient(to right, #ff4d4f, #faad14, #52c41a);
}
.device-status {
margin-top: 16rpx;
text-align: right;
}
.connected {
font-size: 26rpx;
color: #07c160;
background-color: #f0fff4;
padding: 4rpx 16rpx;
border-radius: 12rpx;
}
</style>

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

76
uni.scss Normal file
View File

@ -0,0 +1,76 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16px;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;

View File

@ -0,0 +1,20 @@
{
"version": "1",
"env": {
"compiler_version": "4.75"
},
"files": {
"index.kt": {
"md5": "b0472b5db44be590378fc50326855998d60e269f",
"class": ""
},
"pages/index/index.kt": {
"md5": "1a4e97ed30f53bc3dfac7578dc936112fdea97ac",
"class": "GenPagesIndexIndex"
},
"pages/connect/connect.kt": {
"class": "GenPagesConnectConnect",
"md5": "26eaeeb2bc930c21bc0dfa3ec88ca0c191fa336f"
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,259 @@
@file:Suppress("UNCHECKED_CAST", "USELESS_CAST", "INAPPLICABLE_JVM_NAME", "UNUSED_ANONYMOUS_PARAMETER", "NAME_SHADOWING", "UNNECESSARY_NOT_NULL_ASSERTION")
package uni.UNIuniappx
import io.dcloud.uniapp.*
import io.dcloud.uniapp.extapi.*
import io.dcloud.uniapp.framework.*
import io.dcloud.uniapp.runtime.*
import io.dcloud.uniapp.vue.*
import io.dcloud.uniapp.vue.shared.*
import io.dcloud.unicloud.*
import io.dcloud.uts.*
import io.dcloud.uts.Map
import io.dcloud.uts.Set
import io.dcloud.uts.UTSAndroid
import io.dcloud.uniapp.extapi.closeBLEConnection as uni_closeBLEConnection
import io.dcloud.uniapp.extapi.closeBluetoothAdapter as uni_closeBluetoothAdapter
import io.dcloud.uniapp.extapi.createBLEConnection as uni_createBLEConnection
import io.dcloud.uniapp.extapi.hideLoading as uni_hideLoading
import io.dcloud.uniapp.extapi.navigateTo as uni_navigateTo
import io.dcloud.uniapp.extapi.offBluetoothDeviceFound as uni_offBluetoothDeviceFound
import io.dcloud.uniapp.extapi.onBluetoothDeviceFound as uni_onBluetoothDeviceFound
import io.dcloud.uniapp.extapi.openBluetoothAdapter as uni_openBluetoothAdapter
import io.dcloud.uniapp.extapi.showLoading as uni_showLoading
import io.dcloud.uniapp.extapi.showModal as uni_showModal
import io.dcloud.uniapp.extapi.showToast as uni_showToast
import io.dcloud.uniapp.extapi.startBluetoothDevicesDiscovery as uni_startBluetoothDevicesDiscovery
import io.dcloud.uniapp.extapi.stopBluetoothDevicesDiscovery as uni_stopBluetoothDevicesDiscovery
open class GenPagesIndexIndex : BasePage {
constructor(__ins: ComponentInternalInstance, __renderer: String?) : super(__ins, __renderer) {
onLoad(fun(_: OnLoadOptions) {
this.initBluetooth()
}
, __ins)
onUnload(fun() {
this.stopScan()
uni_closeBluetoothAdapter()
uni_offBluetoothDeviceFound(this.onDeviceFound)
}
, __ins)
}
@Suppress("UNUSED_PARAMETER", "UNUSED_VARIABLE")
override fun `$render`(): Any? {
val _ctx = this
val _cache = this.`$`.renderCache
return _cE("view", _uM("class" to "container"), _uA(
_cE("view", _uM("class" to "title-bar"), _uA(
_cE("text", _uM("class" to "title"), "连接设备"),
_cE("button", _uM("class" to "scan-btn", "disabled" to _ctx.isScanning, "onClick" to _ctx.toggleScan), _tD(if (_ctx.isScanning) {
"停止扫描"
} else {
"开始扫描"
}
), 9, _uA(
"disabled",
"onClick"
))
)),
if (isTrue(_ctx.isScanning)) {
_cE("view", _uM("key" to 0, "class" to "status-tip"), _uA(
_cE("text", null, "正在扫描设备..."),
_cE("view", _uM("class" to "loading"))
))
} else {
if (_ctx.foundDevices.length === 0) {
_cE("view", _uM("key" to 1, "class" to "status-tip"), _uA(
_cE("text", null, "未发现设备,请点击\"开始扫描\"")
))
} else {
_cC("v-if", true)
}
}
,
_cE("view", _uM("class" to "device-list"), _uA(
_cE(Fragment, null, RenderHelpers.renderList(_ctx.foundDevices, fun(device, index, __index, _cached): Any {
return _cE("view", _uM("class" to "device-item", "key" to device.deviceId, "onClick" to fun(){
_ctx.connectDevice(device)
}
), _uA(
_cE("view", _uM("class" to "device-name"), _uA(
_cE("text", null, _tD(device.name || "未知设备"), 1),
if (isTrue(device.is_bj)) {
_cE("view", _uM("key" to 0, "class" to "is_bj"), "吧唧")
} else {
_cC("v-if", true)
}
,
_cE("text", _uM("class" to "device-id"), _tD(device.deviceId), 1)
)),
_cE("view", _uM("class" to "device-rssi"), _uA(
_cE("text", null, "信号: " + _tD(device.rssi) + " dBm", 1),
_cE("view", _uM("class" to "rssi-bar", "style" to _nS(_uM("width" to _ctx.getRssiWidth(device.rssi)))), null, 4)
)),
if (isTrue(device.connected)) {
_cE("view", _uM("key" to 0, "class" to "device-status"), _uA(
_cE("text", _uM("class" to "connected"), "已连接")
))
} else {
_cC("v-if", true)
}
), 8, _uA(
"onClick"
))
}
), 128)
))
))
}
open var foundDevices: UTSArray<Any?> by `$data`
open var isScanning: Boolean by `$data`
open var bluetoothEnabled: Boolean by `$data`
open var connectedDeviceId: String by `$data`
@Suppress("USELESS_CAST")
override fun data(): Map<String, Any?> {
return _uM("foundDevices" to _uA(), "isScanning" to false, "bluetoothEnabled" to false, "connectedDeviceId" to "")
}
open var initBluetooth = ::gen_initBluetooth_fn
open fun gen_initBluetooth_fn() {
uni_openBluetoothAdapter(OpenBluetoothAdapterOptions(success = fun(_){
this.bluetoothEnabled = true
}
, fail = fun(err){
this.bluetoothEnabled = false
uni_showModal(ShowModalOptions(title = "蓝牙开启失败", content = "请检查设备蓝牙是否开启", showCancel = false))
console.error("蓝牙初始化失败:", err, " at pages/index/index.uvue:88")
}
))
}
open var toggleScan = ::gen_toggleScan_fn
open fun gen_toggleScan_fn() {
if (!this.bluetoothEnabled) {
this.initBluetooth()
return
}
if (this.isScanning) {
this.stopScan()
} else {
this.startScan()
}
}
open var startScan = ::gen_startScan_fn
open fun gen_startScan_fn() {
this.isScanning = true
this.foundDevices = _uA()
uni_startBluetoothDevicesDiscovery(StartBluetoothDevicesDiscoveryOptions(services = _uA(), allowDuplicatesKey = false, success = fun(_){
uni_showToast(ShowToastOptions(title = "开始扫描", icon = "none"))
uni_onBluetoothDeviceFound(this.onDeviceFound)
}
, fail = fun(err){
this.isScanning = false
uni_showToast(ShowToastOptions(title = "扫描失败", icon = "none"))
console.error("扫描失败:", err, " at pages/index/index.uvue:124")
}
))
setTimeout(fun(){
if (this.isScanning) {
this.stopScan()
}
}
, 5000)
}
open var stopScan = ::gen_stopScan_fn
open fun gen_stopScan_fn() {
if (!this.isScanning) {
return
}
uni_stopBluetoothDevicesDiscovery(StopBluetoothDevicesDiscoveryOptions(success = fun(_){
this.isScanning = false
if (this.foundDevices.length == 0) {
uni_showToast(ShowToastOptions(title = "\u6682\u672A\u626B\u63CF\u5230\u4EFB\u4F55\u8BBE\u5907", icon = "none"))
return
}
uni_showToast(ShowToastOptions(title = "\u626B\u63CF\u5B8C\u6210\uFF0C\u53D1\u73B0" + this.foundDevices.length + "\u53F0\u8BBE\u5907", icon = "none"))
}
, fail = fun(err){
console.error("停止扫描失败:", err, " at pages/index/index.uvue:154")
}
))
}
open var onDeviceFound = ::gen_onDeviceFound_fn
open fun gen_onDeviceFound_fn(res) {
val devices = res.devices || _uA()
devices.forEach(fun(device){
if (!device.deviceId) {
return
}
val isExist = this.foundDevices.some(fun(d): Boolean {
return d.deviceId === device.deviceId
}
)
if (isExist) {
return
}
var is_bj = false
val advData = Uint8Array(device.advertisData)
val devicenameData = advData.slice(2, 6)
val devicename = String.fromCharCode(*devicenameData.toTypedArray())
if (devicename == "dzbj") {
is_bj = true
}
this.foundDevices.push(_uO("is_bj" to is_bj, "name" to (device.name || "未知设备"), "deviceId" to device.deviceId, "rssi" to device.RSSI, "connected" to (device.deviceId === this.connectedDeviceId)))
}
)
}
open var getRssiWidth = ::gen_getRssiWidth_fn
open fun gen_getRssiWidth_fn(rssi): String {
val minRssi: Number = -100
val maxRssi: Number = -30
var ratio = (rssi - minRssi) / (maxRssi - minRssi)
ratio = Math.max(0, Math.min(1, ratio))
return "" + ratio * 100 + "%"
}
open var connectDevice = ::gen_connectDevice_fn
open fun gen_connectDevice_fn(device) {
var that = this
this.stopScan()
uni_showLoading(ShowLoadingOptions(title = "连接中..."))
uni_createBLEConnection(CreateBLEConnectionOptions(deviceId = device.deviceId, success = fun(res) {
that.foundDevices = that.foundDevices.map(fun(d){
return UTSJSONObject.assign(UTSJSONObject(), d, object : UTSJSONObject() {
var connected = d.deviceId === device.deviceId
})
}
)
uni_hideLoading()
uni_showToast(ShowToastOptions(title = "\u5DF2\u8FDE\u63A5" + device.name, icon = "none"))
uni_navigateTo(NavigateToOptions(url = "../connect/connect?deviceId=" + device.deviceId, fail = fun(err){
uni_showToast(ShowToastOptions(title = "\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5", icon = "error"))
uni_closeBLEConnection(CloseBLEConnectionOptions(deviceId = device.deviceId, success = fun(_) {
console("断开连接成功")
}
))
}
))
}
, fail = fun(_) {
uni_hideLoading()
uni_showToast(ShowToastOptions(title = "\u8FDE\u63A5\u5931\u8D25", icon = "error"))
}
))
}
companion object {
val styles: Map<String, Map<String, Map<String, Any>>> by lazy {
_nCS(_uA(
styles0
), _uA(
GenApp.styles
))
}
val styles0: Map<String, Map<String, Map<String, Any>>>
get() {
return _uM("container" to _pS(_uM("paddingTop" to "16rpx", "paddingRight" to "16rpx", "paddingBottom" to "16rpx", "paddingLeft" to "16rpx", "backgroundColor" to "#f5f5f5")), "title-bar" to _pS(_uM("display" to "flex", "justifyContent" to "space-between", "alignItems" to "center", "paddingTop" to "20rpx", "paddingRight" to 0, "paddingBottom" to "20rpx", "paddingLeft" to 0, "borderBottomWidth" to 1, "borderBottomStyle" to "solid", "borderBottomColor" to "#eeeeee", "marginBottom" to "20rpx", "marginTop" to "80rpx")), "title" to _pS(_uM("fontSize" to "36rpx", "fontWeight" to "bold", "color" to "#333333")), "scan-btn" to _pS(_uM("backgroundColor" to "#00c900", "color" to "#FFFFFF", "paddingTop" to "0rpx", "paddingRight" to "24rpx", "paddingBottom" to "0rpx", "paddingLeft" to "24rpx", "borderTopLeftRadius" to "8rpx", "borderTopRightRadius" to "8rpx", "borderBottomRightRadius" to "8rpx", "borderBottomLeftRadius" to "8rpx", "fontSize" to "28rpx", "marginRight" to "5%", "backgroundColor:disabled" to "#cccccc")), "status-tip" to _pS(_uM("textAlign" to "center", "paddingTop" to "40rpx", "paddingRight" to 0, "paddingBottom" to "40rpx", "paddingLeft" to 0, "color" to "#666666", "fontSize" to "28rpx")), "loading" to _pS(_uM("width" to "30rpx", "height" to "30rpx", "borderTopWidth" to "3rpx", "borderRightWidth" to "3rpx", "borderBottomWidth" to "3rpx", "borderLeftWidth" to "3rpx", "borderTopStyle" to "solid", "borderRightStyle" to "solid", "borderBottomStyle" to "solid", "borderLeftStyle" to "solid", "borderTopColor" to "rgba(0,0,0,0)", "borderRightColor" to "#007aff", "borderBottomColor" to "#007aff", "borderLeftColor" to "#007aff", "marginTop" to "20rpx", "marginRight" to "auto", "marginBottom" to "20rpx", "marginLeft" to "auto", "animation" to "spin 1s linear infinite")), "device-list" to _pS(_uM("display" to "flex", "flexDirection" to "column", "gap" to "16rpx")), "device-item" to _pS(_uM("backgroundColor" to "#FFFFFF", "borderTopLeftRadius" to "12rpx", "borderTopRightRadius" to "12rpx", "borderBottomRightRadius" to "12rpx", "borderBottomLeftRadius" to "12rpx", "paddingTop" to "24rpx", "paddingRight" to "24rpx", "paddingBottom" to "24rpx", "paddingLeft" to "24rpx", "boxShadow" to "0 2rpx 8rpx rgba(0,0,0,0.1)", "cursor" to "pointer")), "device-name" to _pS(_uM("display" to "flex", "justifyContent" to "space-between", "marginBottom" to "16rpx")), "is_bj" to _pS(_uM("paddingTop" to 3, "paddingRight" to 8, "paddingBottom" to 3, "paddingLeft" to 8, "borderTopLeftRadius" to 5, "borderTopRightRadius" to 5, "borderBottomRightRadius" to 5, "borderBottomLeftRadius" to 5, "color" to "#FFFFFF", "backgroundColor" to "rgba(30,228,156,0.4)", "position" to "relative", "right" to 30)), "device-id" to _pS(_uM("fontSize" to "24rpx", "color" to "#999999")), "device-rssi" to _pS(_uM("display" to "flex", "flexDirection" to "column", "gap" to "8rpx")), "rssi-bar" to _pS(_uM("height" to "8rpx", "backgroundColor" to "#eeeeee", "borderTopLeftRadius" to "4rpx", "borderTopRightRadius" to "4rpx", "borderBottomRightRadius" to "4rpx", "borderBottomLeftRadius" to "4rpx", "overflow" to "hidden", "content::after" to "''", "height::after" to "100%", "backgroundImage::after" to "linear-gradient(to right, #ff4d4f, #faad14, #52c41a)", "backgroundColor::after" to "rgba(0,0,0,0)")), "device-status" to _pS(_uM("marginTop" to "16rpx", "textAlign" to "right")), "connected" to _pS(_uM("fontSize" to "26rpx", "color" to "#07c160", "backgroundColor" to "#f0fff4", "paddingTop" to "4rpx", "paddingRight" to "16rpx", "paddingBottom" to "4rpx", "paddingLeft" to "16rpx", "borderTopLeftRadius" to "12rpx", "borderTopRightRadius" to "12rpx", "borderBottomRightRadius" to "12rpx", "borderBottomLeftRadius" to "12rpx")), "@FONT-FACE" to _uM("0" to _uM()))
}
var inheritAttrs = true
var inject: Map<String, Map<String, Any?>> = _uM()
var emits: Map<String, Any?> = _uM()
var props = _nP(_uM())
var propsNeedCastKeys: UTSArray<String> = _uA()
var components: Map<String, CreateVueComponent> = _uM()
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

1
unpackage/cache/apk/apkurl vendored Normal file
View File

@ -0,0 +1 @@
https://app.liuyingyong.cn/build/download/94072910-00bc-11f1-8671-85bf92ef3a20

View File

@ -0,0 +1 @@
b1kWame9yBmby5SJKXZdMiBIfIZ7jYUx3ZnXt20I8klef9B7ZTIAFKtSJZT7FZLkzKWKT9W6pVd8W3D0oyyg68ZjK8usUw2Toml0WV8t5QFWqr7P89AaSN8HUAszjVXW1MTW5vkTdkhlvsbW3fbL5AbghM72zG0rued7+eRmRt+1Jn/eYqbLM+g65OPdI5QhFMPb49NcXcw+Vu8FXdaBtcN+w/JXJ4BQztTi1BY8F54ipgU0ugffXgTOzZCMQBLqCasZHJYLlyuMhUn0QEqYIVBVp0GZiQr2UmabZgoHhXDRFTL4fSPtnXCDHpBlPkqMzoteSc683WNGpWb4pyf60MN85hK92DlgJcUvua4jsfJoh8+dxCAlz3Un/Lrjy/0FCTSacipV53EHKrrVFMo0dy449zameraaGqYWsFaRflEX/X9vaI1141lyDRAHcyyVBYeJanS0MTGzuaSftW4jVrMapUsCrJTsFvtfRsSjxR5WBi44KvjHw0EEnGABqwUWZK+UwlllNY+FhMMqzLbd49bWhPEo4UBuR8nNPr9N4XJZ/K6KJVst0pgwq4v0SRNp+gcnAmsyiL1rpKHtU2EaQe+G6cnC5JsLrulJ+tpopxLwadoCFxgnC7koRwCtqp5P3lYUf9dFZ1b8Z5nrrgpzoKtvONRaIWKStFomxMlgfQvXrsf72zRuriUD2ex4aWBgF8aCZpM19tf971pvigSKP+0x425P016Ziel4QrwKK13l96x1ITKN/itq+RIW89WyoBTAzPub1qReIDbzBU5kuokhG2069F9wdbIQPhnb+ef3MnOb/U43ixonzfcQ4tw/6Ws6uUrbzIl7YqRG0HOiW2h5/28QbigB6RdRa1e3Q3byxLO/ZVP04c9NYdFOu4JjP3pvlKO93OpmfwKVxUzIDiA3Qfr5AV8pFNLekSPpKN+TeCsk+o4rpNPecU75cwtyucFsjtwE7PVHVtd6bB5KP/jJgp655nnaiKPV21nJIcXFx5dJUqYL+3qf/EDIQD7xtMu+FH2DaKvOCxrnoiBvvj9hi+m3okYGXx+GuKe1DcMAkTqBSCzEf0GglPBERTfXH5N/lYNfUgG3XhxeEcpPcXWXDTgrTJGM0yhHPuRT7qgsx3w56GnITYO5uExxQCWHZhPZwP8mxBci1crPQfw864OtaYgt5DDfQwuu3rAl6MwF7e3oMtel7Qt0OVVhUczxu+D/YptjpnQ25Ylf4d8O4i0bqqdLpBzsSE9loQ+h4xUE9LPmhoxLjghF1ViY/rd67bQhEwRGpZlHvNyMZzrgBfUy2L2Z4ofX7+3T3aGIKgkHpEehrvAILNNj9l6F3fqOAd3pU3nEwg79GeMqBXUAqOWYQxTEI2hJg918gCWY2B5oKy5l3jG9vL7PiEgw6/vVv1evN3z0wPFvPZ4iSSiauV/fs1HyZUEou2nqq34/EVOhVvMQ1oyRLJj8GaoQShYw2MsWEhjdpPN5LVf6TTjN9YNgJcItgX5JaitQ3RuO7+QifHuTjlAKbcMkKfnBLdZXUVEqma+YJ1ecviFQmplGjP+a1RfDHYMuk+AS+oSpCKkQVqLAu9jgctvdXfWXcesj+F3ELZ+2PemsTLed0VlhB2uHe57T0h3sbtmfXeXrdCLifYGbFzypI1IXU8QBY3ZNUjtGv0+d5S1+Qiyt4fR6QFzeLrwMGFDUgWWh2BMhp5VGpsvie+QSP+odus/TXsuDqOpSgPuSEZh3BnUiKTbroUEKc7NQ6xgNSYOVIon57ZzrVNiREIyvgCrr3PIheIwywo/9824G/Jmt61aw1Ms9DoibvSrvIG/98R5T4Bphb51awa4PIzhaKoTHXnPpEziG5x1Wilme65GfiSQ7wRtzuoZU67wICTiR65ZZKGSykuTA2mZ74odYR543h2EJ4p+ZSHIXpsCmLr04Pn1+yMLRggHmWWbZwGNWBzfh+JUg1F02waxaw9oOTM/+2BKMLoBscCd3Pi4kg2awynB7ef/AHPC3qkxkSofRodWQWcJeut8/iZdhEZZ2xbcBo+uoI/2l4DmkSBVhNlpsGNpXzCpJLndoDSgqvOzojF4x7oT2al9Vaf2kq4BRyyMw2IBExksnjXbMf/K0lPBzYIxX+TvTKUgXuWpOnr7nQGJr12hNT6tfdO5lCZI7T7BQPxj4klew5P9isiYnOQH4ECudYsoaLg+14tfHG1LHcCWcxO1qtNv9C6uB1jLj+zaHHvHCrFqUi1zd3w+s3mKvp7HqfcmlEoCsdSkqD3NVBYeSDWXIjfZfk7Y1vidOIHBqEt8clr4kdGPPMuNT4vJsVl0ZOaduVoAUCeCK1E8K8x1hxmpF/481vp0+HzW1eerUsb5z76dGsJ0lOcUSfv8bilGSVOM0snxuwrtVkiKN4zD8TP1MkSQBXsedjM/xHnxk989Qdo7zPX/e8GLXNpnjhkl0NFNm560bd7tsuc7z9HKuTPG99F++ETEyVZ6jPNzlRMe3sUPBQpOuWlCvZGUUsNeyUHxjQ77TAbTkDMO6xOFrY0vruAO+5VPMqEk6UJqS3nuDKcdQFypQo3dGQClZ3VC4NUt/SEDQd9PdYlhvR6ZQG9o4HGyjFOcr+pbGXpRgdCjXs/Z6VSIEo+WneTCQbLMYR6bJ0i7fJ849yLlCrWbkEfC9BoJc1DhetkK4ElgLy6Hx3J8e/nFxz+a6AKRPYB84ZUk/2Ixrlf5awtW8LXjZuUkGYznSvSpvpW69b9ziU/FtZ3ucMOX6oY+HB2nlrrV48ppp1/+f2C3nG0swNgy1LIAEicyYNq+ufoaCRHwPG3Oa7csIzxCrsJtEV/u1GXa2bY3bcmf9SBuDSCx6zvj+zEm9hUgGCPrW2OVCAWE4oQsm7NNGko5NxjjTgVUbTY6Q2XnFfbrx6RMAwa+qMTkT1Ypk7eA+oJYe5+vp0nrK94SYX3ag1hxi+SL8CCjnr02Hnsd2mAU+OxaH6zeLSiVkTaKTPvyX/oEJLYEynpIV0zFLZ9mMn8epgq2gkJy3DaMNpzOFDccUwszWTxuSBtVhHbGUweZ74p+N9sg148XmFnx7WRuyYfEBF6hTza6MgRBpihD64iNU1j9PkGZAS4TlegofkmpyiZoknyx6r0VWZfbV2S6JV4XEhdiuwRcPTFfgitr0O6J/1J6kzhhyQpK5q3O2b30y2+D7YtzPFfssTvidpvSuCZkHy06MjdZBeTt03mY2C/koDP7PSFQAUO2yAhDh1ahLbl8EPd965f5vFTIdOYAJ5txk2iErTlBH3PWfu44nraG+EX7R37HGSon3ATBqAtqm/1TJEu6Luow4YcqvI3vP1svlfBCeJUuF7+CbCULvuJCySxtqzYMnuwlTxaVG7HEzTS8qIMb4zU/L+PfgI/MsWKQNp11AmUTOxIMJdmb4eXRkgmiVNqpR8SD+bAdn2nI1ar6jth6blGoPufSRL/0l

4
unpackage/cache/certdata vendored Normal file
View File

@ -0,0 +1,4 @@
andrCertfile=D:/HBuilderX/plugins/app-safe-pack/Test.keystore
andrCertAlias=android
andrCertPass=ep/Tdjka4Y7WYqDB6/S7dw==
storePassword=ep/Tdjka4Y7WYqDB6/S7dw==

View File

@ -0,0 +1,4 @@
[General]
andrCertfile=package.keystore
andrCertAlias=__UNI__F18BB63
andrCertPass="53DWTUGpKLtjkDlwhCDiOA=="

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>View</title>
<link rel="icon" href="data:,">
<link rel="stylesheet" href="app.css" />
<script>var __uniConfig = {"globalStyle":{},"darkmode":false}</script>
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
</head>
<body>
<div id="app"></div>
<script src="uni-app-view.umd.js"></script>
</body>
</html>

View File

@ -0,0 +1,11 @@
;(function(){
let u=void 0,isReady=false,onReadyCallbacks=[],isServiceReady=false,onServiceReadyCallbacks=[];
const __uniConfig = {"pages":[],"globalStyle":{"backgroundColor":"#F8F8F8","navigationBar":{"backgroundColor":"#F8F8F8","titleText":"","style":"custom","type":"default","titleColor":"#000000"},"isNVue":false},"nvue":{"compiler":"uni-app","styleCompiler":"uni-app","flex-direction":"column"},"renderer":"auto","appname":"dzbj","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":true},"compilerVersion":"4.75","entryPagePath":"pages/index/index","entryPageQuery":"","realEntryPagePath":"","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000},"locales":{},"darkmode":false,"themeConfig":{}};
const __uniRoutes = [{"path":"pages/index/index","meta":{"isQuit":true,"isEntry":true,"navigationBar":{"titleText":"连接设备","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/connect/connect","meta":{"navigationBar":{"type":"default"},"isNVue":false}}].map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute));
__uniConfig.styles=[];//styles
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:16})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:u,window:u,document:u,frames:u,self:u,location:u,navigator:u,localStorage:u,history:u,Caches:u,screen:u,alert:u,confirm:u,prompt:u,fetch:u,XMLHttpRequest:u,WebSocket:u,webkit:u,print:u}}}});
})();

View File

@ -0,0 +1 @@
(function(){})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"file":"app.css.js","sources":["uni-app:///D:/HBuilderX/plugins/uniapp-cli-vite/app.css.js"],"sourcesContent":null,"names":[],"mappings":";;;;;;;AAGA,YAAQ,SAAS,CAAC,QAAQ;AAAA;AAAA;"}

View File

@ -0,0 +1 @@
{"version":3,"file":"app.js","sources":[],"sourcesContent":null,"names":[],"mappings":";;"}

View File

@ -0,0 +1 @@
{"@platforms":["android","iPhone","iPad"],"id":"__UNI__F18BB63","name":"dzbj","version":{"name":"1.0.0","code":"100"},"description":"","developer":{"name":"","email":"","url":""},"permissions":{"Bluetooth":{},"Camera":{},"UniNView":{"description":"UniNView原生渲染"}},"plus":{"useragent":{"value":"uni-app","concatenate":true},"splashscreen":{"autoclose":true,"delay":0,"target":"id:1","waiting":true},"popGesture":"close","launchwebview":{"render":"always","id":"1","kernel":"WKWebview"},"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"distribute":{"google":{"permissions":["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>","<uses-permission android:name=\"android.permission.VIBRATE\"/>","<uses-permission android:name=\"android.permission.READ_LOGS\"/>","<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>","<uses-feature android:name=\"android.hardware.camera.autofocus\"/>","<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.CAMERA\"/>","<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>","<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>","<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>","<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>","<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>","<uses-feature android:name=\"android.hardware.camera\"/>","<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"],"packagename":"uni.app.UNI08167A6","custompermissions":true},"apple":{"dSYMs":false,"devices":"universal"},"plugins":{"audio":{"mp3":{"description":"Android平台录音支持MP3格式文件"}}},"orientation":"portrait-primary"},"statusbar":{"immersed":"supportedDevice","style":"dark","background":"#F8F8F8"},"uniStatistics":{"enable":false},"allowsInlineMediaPlayback":true,"uni-app":{"control":"uni-v3","vueVersion":"3","compilerVersion":"4.75","nvueCompiler":"uni-app","renderer":"auto","nvue":{"flex-direction":"column"},"nvueLaunchMode":"normal","webView":{"minUserAgentVersion":"49.0"}},"adid":"128665270412"},"app-harmony":{"useragent":{"value":"uni-app","concatenate":true},"uniStatistics":{"enable":false}},"launch_path":"__uniappview.html"}

View File

@ -0,0 +1 @@
.status-pot[data-v-6b60e2e0]{width:16px;height:16px;border-radius:50%}.container[data-v-6b60e2e0]{background-color:#f5f5f7;min-height:100vh}.nav-bar[data-v-6b60e2e0]{display:flex;justify-content:space-between;align-items:center;padding:.625rem .9375rem;background-color:#fff}.nav-title[data-v-6b60e2e0]{color:#fff;font-size:1.125rem;font-weight:500}.upload-btn[data-v-6b60e2e0]{align-items:center;gap:.25rem;background-color:#28d50e;color:#fff;width:35%;margin-top:10px;padding:.4375rem 0;border-radius:.25rem;font-size:.8125rem}.content[data-v-6b60e2e0]{padding:.9375rem}.section-title[data-v-6b60e2e0]{display:block;font-size:1rem;color:#333;margin:.9375rem 0 .625rem;font-weight:500}.preview-container[data-v-6b60e2e0]{display:flex;flex-direction:column;align-items:center;margin-bottom:.625rem}.preview-frame[data-v-6b60e2e0]{width:15rem;height:15rem;border-radius:50%;background-color:#fff;box-shadow:0 .125rem .375rem rgba(0,0,0,.1);display:flex;justify-content:center;align-items:center;overflow:hidden;position:relative}.preview-image[data-v-6b60e2e0]{width:100%;height:100%}.empty-preview[data-v-6b60e2e0]{display:flex;flex-direction:column;align-items:center;color:#ccc}.empty-preview uni-text[data-v-6b60e2e0]{margin-top:.625rem;font-size:.875rem}.set-btn[data-v-6b60e2e0]{margin-top:.625rem;background-color:#3cbb19;color:#fff;width:35%;padding:.46875rem 0;border-radius:.25rem;font-size:.875rem}.carousel-section[data-v-6b60e2e0]{margin-bottom:.9375rem}.carousel-container[data-v-6b60e2e0]{background-color:#fff;border-radius:.5rem;padding:.625rem 0;box-shadow:0 .0625rem .25rem rgba(0,0,0,.05);overflow:hidden}.card-swiper[data-v-6b60e2e0]{width:100%;height:7.5rem}.card-swiper .swiper-item[data-v-6b60e2e0]{display:flex;justify-content:center;align-items:center;transition:all .3s ease}.card-item[data-v-6b60e2e0]{width:7.5rem;height:7.5rem}.card-frame[data-v-6b60e2e0]{width:7.5rem;height:100%;border-radius:50%;overflow:hidden;box-shadow:0 .1875rem .5rem rgba(0,0,0,.15);position:relative}.card-image[data-v-6b60e2e0]{width:7.5rem;height:100%}.card-overlay[data-v-6b60e2e0]{position:absolute;top:0;left:0;width:7.5rem;height:100%;background-color:rgba(0,0,0,.3);display:flex;justify-content:center;align-items:center}.card-swiper .swiper-item[data-v-6b60e2e0]:not(.swiper-item-active){transform:scale(.8);opacity:.6;z-index:1}.card-swiper .swiper-item-active[data-v-6b60e2e0]{transform:scale(1);z-index:2}.carousel-hint[data-v-6b60e2e0]{height:6.25rem;display:flex;justify-content:center;align-items:center;color:#999;font-size:.8125rem;text-align:center}.data-section[data-v-6b60e2e0]{background-color:#fff;border-radius:.5rem;padding:.625rem .9375rem;box-shadow:0 .0625rem .25rem rgba(0,0,0,.05)}.data-grid[data-v-6b60e2e0]{display:grid;grid-template-columns:1fr 1fr;gap:.625rem;margin-bottom:.9375rem}.data-card[data-v-6b60e2e0]{background-color:#f9f9f9;border-radius:.375rem;padding:.625rem;display:flex;align-items:center;gap:.625rem}.data-icon[data-v-6b60e2e0]{width:1.875rem;height:1.875rem;border-radius:.375rem;display:flex;justify-content:center;align-items:center}.battery-icon[data-v-6b60e2e0]{background-color:#f6ffed}.temp-icon[data-v-6b60e2e0]{background-color:#fff7e6}.humidity-icon[data-v-6b60e2e0]{background-color:#e6f7ff}.status-icon[data-v-6b60e2e0]{background-color:#f0f9ff}.data-info[data-v-6b60e2e0]{flex:1}.data-value[data-v-6b60e2e0]{font-size:1rem;font-weight:700;color:#333}.data-label[data-v-6b60e2e0]{font-size:.75rem;color:#666}.connection-status[data-v-6b60e2e0]{display:flex;justify-content:space-between;align-items:center;padding:.46875rem 0;border-top:.03125rem solid #f0f0f0}.status-text[data-v-6b60e2e0]{flex:1;margin:0 .46875rem;font-size:.875rem;color:#333}.connect-btn[data-v-6b60e2e0]{padding:.375rem .75rem;border-radius:.25rem;font-size:.8125rem;background-color:#007aff;color:#fff}.connect-btn[data-v-6b60e2e0]:disabled{background-color:#ccc}

View File

@ -0,0 +1 @@
.container[data-v-a57057ce]{padding:.5rem;background-color:#f5f5f5}.title-bar[data-v-a57057ce]{display:flex;justify-content:space-between;align-items:center;padding:.625rem 0;border-bottom:1px solid #eee;margin-bottom:.625rem;margin-top:2.5rem}.title[data-v-a57057ce]{font-size:1.125rem;font-weight:700;color:#333}.scan-btn[data-v-a57057ce]{background-color:#00c900;color:#fff;padding:0 .75rem;border-radius:.25rem;font-size:.875rem;margin-right:5%}.scan-btn[data-v-a57057ce]:disabled{background-color:#ccc}.status-tip[data-v-a57057ce]{text-align:center;padding:1.25rem 0;color:#666;font-size:.875rem}.loading[data-v-a57057ce]{width:.9375rem;height:.9375rem;border:.09375rem solid #007aff;border-top-color:transparent;border-radius:50%;margin:.625rem auto;animation:spin-a57057ce 1s linear infinite}@keyframes spin-a57057ce{to{transform:rotate(360deg)}}.device-list[data-v-a57057ce]{display:flex;flex-direction:column;gap:.5rem}.device-item[data-v-a57057ce]{background-color:#fff;border-radius:.375rem;padding:.75rem;box-shadow:0 .0625rem .25rem rgba(0,0,0,.1);cursor:pointer}.device-name[data-v-a57057ce]{display:flex;justify-content:space-between;margin-bottom:.5rem}.device-name uni-text[data-v-a57057ce]:first-child{font-size:1rem;color:#333}.is_bj[data-v-a57057ce]{padding:3px 8px;border-radius:5px;color:#fff;background-color:rgba(30,228,156,.4);position:relative;right:30px}.device-id[data-v-a57057ce]{font-size:.75rem;color:#999}.device-rssi[data-v-a57057ce]{display:flex;flex-direction:column;gap:.25rem}.device-rssi uni-text[data-v-a57057ce]{font-size:.8125rem;color:#666}.rssi-bar[data-v-a57057ce]{height:.25rem;background-color:#eee;border-radius:.125rem;overflow:hidden}.rssi-bar[data-v-a57057ce]:after{content:"";display:block;height:100%;background:linear-gradient(to right,#ff4d4f,#faad14,#52c41a)}.device-status[data-v-a57057ce]{margin-top:.5rem;text-align:right}.connected[data-v-a57057ce]{font-size:.8125rem;color:#07c160;background-color:#f0fff4;padding:.125rem .5rem;border-radius:.375rem}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
const __uniConfig = {"pages":[],"globalStyle":{"navigationBarTextStyle":"black","navigationBarTitleText":"","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom"},"appname":"电子吧唧_old","compilerVersion":"4.75","entryPagePath":"pages/index/index","entryPageQuery":"","realEntryPagePath":"","themeConfig":{}};
__uniConfig.getTabBarConfig = () => {return undefined};
__uniConfig.tabBar = __uniConfig.getTabBarConfig();
const __uniRoutes = [{"path":"pages/index/index","meta":{"isQuit":true,"isEntry":true,"navigationBarTitleText":"连接设备","navigationStyle":"custom"}},{"path":"pages/connect/connect","meta":{}}].map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute)).concat(typeof __uniSystemRoutes !== 'undefined' ? __uniSystemRoutes : []);
globalThis.__uniConfig = __uniConfig;
globalThis.__uniRoutes = __uniRoutes;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
import '../app-config'

View File

@ -0,0 +1 @@
import '../app-service'

View File

@ -0,0 +1,13 @@
{
"id": "__UNI__08167A6",
"name": "电子吧唧_old",
"description": "",
"version": {
"name": "1.0.0",
"code": "100"
},
"uni-app-x": {
"compilerVersion": "4.75"
},
"app-harmony": {}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,3 @@
{
"modules": []
}

View File

@ -0,0 +1,12 @@
// This file is automatically generated by uni-app.
// Do not modify this file -- YOUR CHANGES WILL BE ERASED!
import { uni } from '@dcloudio/uni-app-x-runtime'
export function initUniModules() {
initUniExtApi()
}
function initUniExtApi() {
}

View File

@ -0,0 +1,3 @@
{
"dependencies": {}
}

11
unpackage/dist/build/.nvue/app.css.js vendored Normal file
View File

@ -0,0 +1,11 @@
var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var require_app_css = __commonJS({
"app.css.js"(exports) {
const _style_0 = {};
exports.styles = [_style_0];
}
});
export default require_app_css();

View File

@ -0,0 +1 @@
{"version":3,"file":"app.css.js","sources":["uni-app:///D:/HBuilderX/plugins/uniapp-cli-vite/app.css.js"],"sourcesContent":null,"names":[],"mappings":";;;;;;;AAGA,YAAQ,SAAS,CAAC,QAAQ;AAAA;AAAA;"}

2
unpackage/dist/build/.nvue/app.js vendored Normal file
View File

@ -0,0 +1,2 @@
Promise.resolve("./app.css.js").then(() => {
});

1
unpackage/dist/build/.nvue/app.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"app.js","sources":[],"sourcesContent":null,"names":[],"mappings":";;"}

View File

@ -0,0 +1 @@
{"version":3,"sources":["App.uvue","main.uts"],"sourcesContent":["<script lang=\"uts\">\r\n\r\n\tlet firstBackTime = 0\r\n\r\n\texport default {\r\n\t\tonLaunch: function () {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function () {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function () {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t},\r\n\r\n\t\tonLastPageBackPress: function () {\r\n\t\t\tconsole.log('App LastPageBackPress')\r\n\t\t\tif (firstBackTime == 0) {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: '再按一次退出应用',\r\n\t\t\t\t\tposition: 'bottom',\r\n\t\t\t\t})\r\n\t\t\t\tfirstBackTime = Date.now()\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\tfirstBackTime = 0\r\n\t\t\t\t}, 2000)\r\n\t\t\t} else if (Date.now() - firstBackTime < 2000) {\r\n\t\t\t\tfirstBackTime = Date.now()\r\n\t\t\t\tuni.exit()\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tonExit: function () {\r\n\t\t\tconsole.log('App Exit')\r\n\t\t},\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n\t.uni-row {\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.uni-column {\r\n\t\tflex-direction: column;\r\n\t}\r\n</style>","import App from './App.uvue'\r\n\r\nimport { createSSRApp } from 'vue'\r\nexport function createApp() {\r\n\tconst app = createSSRApp(App)\r\n\treturn {\r\n\t\tapp\r\n\t}\r\n}\nexport function main(app: IApp) {\n definePageRoutes();\n defineAppConfig();\n (createApp()['app'] as VueApp).mount(app, GenUniApp());\n}\n\nexport class UniAppConfig extends io.dcloud.uniapp.appframe.AppConfig {\n override name: string = \"电子吧唧_old\"\n override appid: string = \"__UNI__08167A6\"\n override versionName: string = \"1.0.0\"\n override versionCode: string = \"100\"\n override uniCompilerVersion: string = \"4.75\"\n \n constructor() { super() }\n}\n\nimport GenPagesIndexIndexClass from './pages/index/index.uvue'\nimport GenPagesConnectConnectClass from './pages/connect/connect.uvue'\nfunction definePageRoutes() {\n__uniRoutes.push({ path: \"pages/index/index\", component: GenPagesIndexIndexClass, meta: { isQuit: true } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"连接设备\"],[\"navigationStyle\",\"custom\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/connect/connect\", component: GenPagesConnectConnectClass, meta: { isQuit: false } as UniPageMeta, style: _uM() } as UniPageRoute)\n}\nconst __uniTabBar: Map<string, any | null> | null = null\nconst __uniLaunchPage: Map<string, any | null> = _uM([[\"url\",\"pages/index/index\"],[\"style\",_uM([[\"navigationBarTitleText\",\"连接设备\"],[\"navigationStyle\",\"custom\"]])]])\nfunction defineAppConfig(){\n __uniConfig.entryPagePath = '/pages/index/index'\n __uniConfig.globalStyle = _uM([[\"navigationBarTextStyle\",\"black\"],[\"navigationBarTitleText\",\"\"],[\"navigationBarBackgroundColor\",\"#F8F8F8\"],[\"backgroundColor\",\"#F8F8F8\"],[\"navigationStyle\",\"custom\"]])\n __uniConfig.getTabBarConfig = ():Map<string, any> | null => null\n __uniConfig.tabBar = __uniConfig.getTabBarConfig()\n __uniConfig.conditionUrl = ''\n __uniConfig.uniIdRouter = _uM()\n \n __uniConfig.ready = true\n}\n"],"names":[],"mappings":";;;;;;;;;;;;+BA4BQ;+BAVA;;;;;;AAhBP,IAAI,wBAAgB,CAAA;AAEf;;iBACM,wBAAA;YACT,QAAQ,GAAG,CAAC;QACb;;kBACQ,sBAAA;YACP,QAAQ,GAAG,CAAC;QACb;;kBACQ,MAAA;YACP,QAAQ,GAAG,CAAC;QACb;;4BAEqB,MAAA;YACpB,QAAQ,GAAG,CAAC;YACZ,IAAI,iBAAiB,CAAC,EAAE;gBACvB,+BACC,QAAO,YACP,WAAU;gBAEX,gBAAgB,KAAK,GAAG;gBACxB,WAAW,KAAI;oBACd,gBAAgB,CAAA;gBACjB,GAAG,IAAI;mBACD,IAAI,KAAK,GAAG,KAAK,gBAAgB,IAAI,EAAE;gBAC7C,gBAAgB,KAAK,GAAG;gBACxB;;QAEF;;eAEQ,MAAA;YACP,QAAQ,GAAG,CAAC;QACb;;;;;;;;;;;;;;AACD;;;;;;;;;;;;;;;;;;;;;;AChCK,IAAU,aAAS,cAAA;IACxB,IAAM,MAAM;IACZ,OAAO,IACN,SAAA;AAEF;AACM,IAAU,KAAK,KAAK,IAAI,EAAA;IAC1B;IACA;IACA,CAAC,WAAW,CAAC,MAAM,CAAA,EAAA,CAAI,MAAM,EAAE,KAAK,CAAC,KAAK;AAC9C;AAEM,WAAO,eAAqB,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS;IACjE,aAAS,MAAM,MAAM,GAAG,UAAU;IAClC,aAAS,OAAO,MAAM,GAAG,gBAAgB;IACzC,aAAS,aAAa,MAAM,GAAG,OAAO;IACtC,aAAS,aAAa,MAAM,GAAG,KAAK;IACpC,aAAS,oBAAoB,MAAM,GAAG,MAAM;IAE5C,gBAAgB,KAAK,GAArB,CAAwB;;AAK5B,IAAS,mBAAgB;IACzB,YAAY,IAAI,cAAG,OAAM,qBAAqB,qCAAoC,mBAAQ,SAAQ,IAAI,GAAmB,QAAO,IAAM,4BAAyB,QAAS,qBAAkB;IAC1L,YAAY,IAAI,cAAG,OAAM,yBAAyB,yCAAwC,mBAAQ,SAAQ,KAAK,GAAmB,QAAO;AACzI;AAEA,IAAM,iBAAiB,IAAI,MAAM,EAAE,GAAG,KAAW,IAAM,SAAM,qBAAsB,WAAQ,IAAM,4BAAyB,QAAS,qBAAkB;AACrJ,IAAS,kBAAe;IACtB,YAAY,aAAa,GAAG;IAC5B,YAAY,WAAW,GAAG,IAAM,4BAAyB,SAAU,4BAAyB,IAAK,kCAA+B,WAAY,qBAAkB,WAAY,qBAAkB;IAC5L,YAAY,eAAe,GAAG,OAAG,IAAI,MAAM,EAAE,GAAG;eAAa,IAAI;;IACjE,YAAY,MAAM,GAAG,YAAY,eAAe;IAChD,YAAY,YAAY,GAAG;IAC3B,YAAY,WAAW,GAAG;IAE1B,YAAY,KAAK,GAAG,IAAI;AAC1B;;;;8BA1CA,EAAA;;;;8BAAA,EAAA;;;;uBAAA,EAAA"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,132 @@
@file:Suppress("UNCHECKED_CAST", "USELESS_CAST", "INAPPLICABLE_JVM_NAME", "UNUSED_ANONYMOUS_PARAMETER", "NAME_SHADOWING", "UNNECESSARY_NOT_NULL_ASSERTION")
package uni.UNI08167A6
import io.dcloud.uniapp.*
import io.dcloud.uniapp.extapi.*
import io.dcloud.uniapp.framework.*
import io.dcloud.uniapp.runtime.*
import io.dcloud.uniapp.vue.*
import io.dcloud.uniapp.vue.shared.*
import io.dcloud.uts.*
import io.dcloud.uts.Map
import io.dcloud.uts.Set
import io.dcloud.uts.UTSAndroid
import io.dcloud.uniapp.extapi.exit as uni_exit
import io.dcloud.uniapp.extapi.showToast as uni_showToast
val runBlock1 = run {
__uniConfig.getAppStyles = fun(): Map<String, Map<String, Map<String, Any>>> {
return GenApp.styles
}
}
var firstBackTime: Number = 0
open class GenApp : BaseApp {
constructor(__ins: ComponentInternalInstance) : super(__ins) {
onLaunch(fun(_: OnLaunchOptions) {
console.log("App Launch")
}
, __ins)
onAppShow(fun(_: OnShowOptions) {
console.log("App Show")
}
, __ins)
onAppHide(fun() {
console.log("App Hide")
}
, __ins)
onLastPageBackPress(fun() {
console.log("App LastPageBackPress")
if (firstBackTime == 0) {
uni_showToast(ShowToastOptions(title = "再按一次退出应用", position = "bottom"))
firstBackTime = Date.now()
setTimeout(fun(){
firstBackTime = 0
}, 2000)
} else if (Date.now() - firstBackTime < 2000) {
firstBackTime = Date.now()
uni_exit(null)
}
}
, __ins)
onExit(fun() {
console.log("App Exit")
}
, __ins)
}
companion object {
val styles: Map<String, Map<String, Map<String, Any>>> by lazy {
_nCS(_uA(
styles0
))
}
val styles0: Map<String, Map<String, Map<String, Any>>>
get() {
return _uM("uni-row" to _pS(_uM("flexDirection" to "row")), "uni-column" to _pS(_uM("flexDirection" to "column")))
}
}
}
val GenAppClass = CreateVueAppComponent(GenApp::class.java, fun(): VueComponentOptions {
return VueComponentOptions(type = "app", name = "", inheritAttrs = true, inject = Map(), props = Map(), propsNeedCastKeys = _uA(), emits = Map(), components = Map(), styles = GenApp.styles)
}
, fun(instance): GenApp {
return GenApp(instance)
}
)
val GenPagesIndexIndexClass = CreateVueComponent(GenPagesIndexIndex::class.java, fun(): VueComponentOptions {
return VueComponentOptions(type = "page", name = "", inheritAttrs = GenPagesIndexIndex.inheritAttrs, inject = GenPagesIndexIndex.inject, props = GenPagesIndexIndex.props, propsNeedCastKeys = GenPagesIndexIndex.propsNeedCastKeys, emits = GenPagesIndexIndex.emits, components = GenPagesIndexIndex.components, styles = GenPagesIndexIndex.styles)
}
, fun(instance, renderer): GenPagesIndexIndex {
return GenPagesIndexIndex(instance, renderer)
}
)
val GenPagesConnectConnectClass = CreateVueComponent(GenPagesConnectConnect::class.java, fun(): VueComponentOptions {
return VueComponentOptions(type = "page", name = "", inheritAttrs = GenPagesConnectConnect.inheritAttrs, inject = GenPagesConnectConnect.inject, props = GenPagesConnectConnect.props, propsNeedCastKeys = GenPagesConnectConnect.propsNeedCastKeys, emits = GenPagesConnectConnect.emits, components = GenPagesConnectConnect.components, styles = GenPagesConnectConnect.styles)
}
, fun(instance, renderer): GenPagesConnectConnect {
return GenPagesConnectConnect(instance, renderer)
}
)
fun createApp(): UTSJSONObject {
val app = createSSRApp(GenAppClass)
return _uO("app" to app)
}
fun main(app: IApp) {
definePageRoutes()
defineAppConfig()
(createApp()["app"] as VueApp).mount(app, GenUniApp())
}
open class UniAppConfig : io.dcloud.uniapp.appframe.AppConfig {
override var name: String = "电子吧唧_old"
override var appid: String = "__UNI__08167A6"
override var versionName: String = "1.0.0"
override var versionCode: String = "100"
override var uniCompilerVersion: String = "4.75"
constructor() : super() {}
}
fun definePageRoutes() {
__uniRoutes.push(UniPageRoute(path = "pages/index/index", component = GenPagesIndexIndexClass, meta = UniPageMeta(isQuit = true), style = _uM("navigationBarTitleText" to "连接设备", "navigationStyle" to "custom")))
__uniRoutes.push(UniPageRoute(path = "pages/connect/connect", component = GenPagesConnectConnectClass, meta = UniPageMeta(isQuit = false), style = _uM()))
}
val __uniLaunchPage: Map<String, Any?> = _uM("url" to "pages/index/index", "style" to _uM("navigationBarTitleText" to "连接设备", "navigationStyle" to "custom"))
fun defineAppConfig() {
__uniConfig.entryPagePath = "/pages/index/index"
__uniConfig.globalStyle = _uM("navigationBarTextStyle" to "black", "navigationBarTitleText" to "", "navigationBarBackgroundColor" to "#F8F8F8", "backgroundColor" to "#F8F8F8", "navigationStyle" to "custom")
__uniConfig.getTabBarConfig = fun(): Map<String, Any>? {
return null
}
__uniConfig.tabBar = __uniConfig.getTabBarConfig()
__uniConfig.conditionUrl = ""
__uniConfig.uniIdRouter = _uM()
__uniConfig.ready = true
}
open class GenUniApp : UniAppImpl() {
open val vm: GenApp?
get() {
return getAppVm() as GenApp?
}
open val `$vm`: GenApp?
get() {
return getAppVm() as GenApp?
}
}
fun getApp(): GenUniApp {
return getUniApp() as GenUniApp
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,258 @@
@file:Suppress("UNCHECKED_CAST", "USELESS_CAST", "INAPPLICABLE_JVM_NAME", "UNUSED_ANONYMOUS_PARAMETER", "NAME_SHADOWING", "UNNECESSARY_NOT_NULL_ASSERTION")
package uni.UNI08167A6
import io.dcloud.uniapp.*
import io.dcloud.uniapp.extapi.*
import io.dcloud.uniapp.framework.*
import io.dcloud.uniapp.runtime.*
import io.dcloud.uniapp.vue.*
import io.dcloud.uniapp.vue.shared.*
import io.dcloud.uts.*
import io.dcloud.uts.Map
import io.dcloud.uts.Set
import io.dcloud.uts.UTSAndroid
import io.dcloud.uniapp.extapi.closeBLEConnection as uni_closeBLEConnection
import io.dcloud.uniapp.extapi.closeBluetoothAdapter as uni_closeBluetoothAdapter
import io.dcloud.uniapp.extapi.createBLEConnection as uni_createBLEConnection
import io.dcloud.uniapp.extapi.hideLoading as uni_hideLoading
import io.dcloud.uniapp.extapi.navigateTo as uni_navigateTo
import io.dcloud.uniapp.extapi.offBluetoothDeviceFound as uni_offBluetoothDeviceFound
import io.dcloud.uniapp.extapi.onBluetoothDeviceFound as uni_onBluetoothDeviceFound
import io.dcloud.uniapp.extapi.openBluetoothAdapter as uni_openBluetoothAdapter
import io.dcloud.uniapp.extapi.showLoading as uni_showLoading
import io.dcloud.uniapp.extapi.showModal as uni_showModal
import io.dcloud.uniapp.extapi.showToast as uni_showToast
import io.dcloud.uniapp.extapi.startBluetoothDevicesDiscovery as uni_startBluetoothDevicesDiscovery
import io.dcloud.uniapp.extapi.stopBluetoothDevicesDiscovery as uni_stopBluetoothDevicesDiscovery
open class GenPagesIndexIndex : BasePage {
constructor(__ins: ComponentInternalInstance, __renderer: String?) : super(__ins, __renderer) {
onLoad(fun(_: OnLoadOptions) {
this.initBluetooth()
}
, __ins)
onUnload(fun() {
this.stopScan()
uni_closeBluetoothAdapter()
uni_offBluetoothDeviceFound(this.onDeviceFound)
}
, __ins)
}
@Suppress("UNUSED_PARAMETER", "UNUSED_VARIABLE")
override fun `$render`(): Any? {
val _ctx = this
val _cache = this.`$`.renderCache
return _cE("view", _uM("class" to "container"), _uA(
_cE("view", _uM("class" to "title-bar"), _uA(
_cE("text", _uM("class" to "title"), "连接设备"),
_cE("button", _uM("class" to "scan-btn", "disabled" to _ctx.isScanning, "onClick" to _ctx.toggleScan), _tD(if (_ctx.isScanning) {
"停止扫描"
} else {
"开始扫描"
}
), 9, _uA(
"disabled",
"onClick"
))
)),
if (isTrue(_ctx.isScanning)) {
_cE("view", _uM("key" to 0, "class" to "status-tip"), _uA(
_cE("text", null, "正在扫描设备..."),
_cE("view", _uM("class" to "loading"))
))
} else {
if (_ctx.foundDevices.length === 0) {
_cE("view", _uM("key" to 1, "class" to "status-tip"), _uA(
_cE("text", null, "未发现设备,请点击\"开始扫描\"")
))
} else {
_cC("v-if", true)
}
}
,
_cE("view", _uM("class" to "device-list"), _uA(
_cE(Fragment, null, RenderHelpers.renderList(_ctx.foundDevices, fun(device, index, __index, _cached): Any {
return _cE("view", _uM("class" to "device-item", "key" to device.deviceId, "onClick" to fun(){
_ctx.connectDevice(device)
}
), _uA(
_cE("view", _uM("class" to "device-name"), _uA(
_cE("text", null, _tD(device.name || "未知设备"), 1),
if (isTrue(device.is_bj)) {
_cE("view", _uM("key" to 0, "class" to "is_bj"), "吧唧")
} else {
_cC("v-if", true)
}
,
_cE("text", _uM("class" to "device-id"), _tD(device.deviceId), 1)
)),
_cE("view", _uM("class" to "device-rssi"), _uA(
_cE("text", null, "信号: " + _tD(device.rssi) + " dBm", 1),
_cE("view", _uM("class" to "rssi-bar", "style" to _nS(_uM("width" to _ctx.getRssiWidth(device.rssi)))), null, 4)
)),
if (isTrue(device.connected)) {
_cE("view", _uM("key" to 0, "class" to "device-status"), _uA(
_cE("text", _uM("class" to "connected"), "已连接")
))
} else {
_cC("v-if", true)
}
), 8, _uA(
"onClick"
))
}
), 128)
))
))
}
open var foundDevices: UTSArray<Any?> by `$data`
open var isScanning: Boolean by `$data`
open var bluetoothEnabled: Boolean by `$data`
open var connectedDeviceId: String by `$data`
@Suppress("USELESS_CAST")
override fun data(): Map<String, Any?> {
return _uM("foundDevices" to _uA(), "isScanning" to false, "bluetoothEnabled" to false, "connectedDeviceId" to "")
}
open var initBluetooth = ::gen_initBluetooth_fn
open fun gen_initBluetooth_fn() {
uni_openBluetoothAdapter(OpenBluetoothAdapterOptions(success = fun(_){
this.bluetoothEnabled = true
}
, fail = fun(err){
this.bluetoothEnabled = false
uni_showModal(ShowModalOptions(title = "蓝牙开启失败", content = "请检查设备蓝牙是否开启", showCancel = false))
console.error("蓝牙初始化失败:", err)
}
))
}
open var toggleScan = ::gen_toggleScan_fn
open fun gen_toggleScan_fn() {
if (!this.bluetoothEnabled) {
this.initBluetooth()
return
}
if (this.isScanning) {
this.stopScan()
} else {
this.startScan()
}
}
open var startScan = ::gen_startScan_fn
open fun gen_startScan_fn() {
this.isScanning = true
this.foundDevices = _uA()
uni_startBluetoothDevicesDiscovery(StartBluetoothDevicesDiscoveryOptions(services = _uA(), allowDuplicatesKey = false, success = fun(_){
uni_showToast(ShowToastOptions(title = "开始扫描", icon = "none"))
uni_onBluetoothDeviceFound(this.onDeviceFound)
}
, fail = fun(err){
this.isScanning = false
uni_showToast(ShowToastOptions(title = "扫描失败", icon = "none"))
console.error("扫描失败:", err)
}
))
setTimeout(fun(){
if (this.isScanning) {
this.stopScan()
}
}
, 5000)
}
open var stopScan = ::gen_stopScan_fn
open fun gen_stopScan_fn() {
if (!this.isScanning) {
return
}
uni_stopBluetoothDevicesDiscovery(StopBluetoothDevicesDiscoveryOptions(success = fun(_){
this.isScanning = false
if (this.foundDevices.length == 0) {
uni_showToast(ShowToastOptions(title = "\u6682\u672A\u626B\u63CF\u5230\u4EFB\u4F55\u8BBE\u5907", icon = "none"))
return
}
uni_showToast(ShowToastOptions(title = "\u626B\u63CF\u5B8C\u6210\uFF0C\u53D1\u73B0" + this.foundDevices.length + "\u53F0\u8BBE\u5907", icon = "none"))
}
, fail = fun(err){
console.error("停止扫描失败:", err)
}
))
}
open var onDeviceFound = ::gen_onDeviceFound_fn
open fun gen_onDeviceFound_fn(res) {
val devices = res.devices || _uA()
devices.forEach(fun(device){
if (!device.deviceId) {
return
}
val isExist = this.foundDevices.some(fun(d): Boolean {
return d.deviceId === device.deviceId
}
)
if (isExist) {
return
}
var is_bj = false
val advData = Uint8Array(device.advertisData)
val devicenameData = advData.slice(2, 6)
val devicename = String.fromCharCode(*devicenameData.toTypedArray())
if (devicename == "dzbj") {
is_bj = true
}
this.foundDevices.push(_uO("is_bj" to is_bj, "name" to (device.name || "未知设备"), "deviceId" to device.deviceId, "rssi" to device.RSSI, "connected" to (device.deviceId === this.connectedDeviceId)))
}
)
}
open var getRssiWidth = ::gen_getRssiWidth_fn
open fun gen_getRssiWidth_fn(rssi): String {
val minRssi: Number = -100
val maxRssi: Number = -30
var ratio = (rssi - minRssi) / (maxRssi - minRssi)
ratio = Math.max(0, Math.min(1, ratio))
return "" + ratio * 100 + "%"
}
open var connectDevice = ::gen_connectDevice_fn
open fun gen_connectDevice_fn(device) {
var that = this
this.stopScan()
uni_showLoading(ShowLoadingOptions(title = "连接中..."))
uni_createBLEConnection(CreateBLEConnectionOptions(deviceId = device.deviceId, success = fun(res) {
that.foundDevices = that.foundDevices.map(fun(d){
return UTSJSONObject.assign(UTSJSONObject(), d, object : UTSJSONObject() {
var connected = d.deviceId === device.deviceId
})
}
)
uni_hideLoading()
uni_showToast(ShowToastOptions(title = "\u5DF2\u8FDE\u63A5" + device.name, icon = "none"))
uni_navigateTo(NavigateToOptions(url = "../connect/connect?deviceId=" + device.deviceId, fail = fun(err){
uni_showToast(ShowToastOptions(title = "\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5", icon = "error"))
uni_closeBLEConnection(CloseBLEConnectionOptions(deviceId = device.deviceId, success = fun(_) {
console("断开连接成功")
}
))
}
))
}
, fail = fun(_) {
uni_hideLoading()
uni_showToast(ShowToastOptions(title = "\u8FDE\u63A5\u5931\u8D25", icon = "error"))
}
))
}
companion object {
val styles: Map<String, Map<String, Map<String, Any>>> by lazy {
_nCS(_uA(
styles0
), _uA(
GenApp.styles
))
}
val styles0: Map<String, Map<String, Map<String, Any>>>
get() {
return _uM("container" to _pS(_uM("paddingTop" to "16rpx", "paddingRight" to "16rpx", "paddingBottom" to "16rpx", "paddingLeft" to "16rpx", "backgroundColor" to "#f5f5f5")), "title-bar" to _pS(_uM("display" to "flex", "justifyContent" to "space-between", "alignItems" to "center", "paddingTop" to "20rpx", "paddingRight" to 0, "paddingBottom" to "20rpx", "paddingLeft" to 0, "borderBottomWidth" to 1, "borderBottomStyle" to "solid", "borderBottomColor" to "#eeeeee", "marginBottom" to "20rpx", "marginTop" to "80rpx")), "title" to _pS(_uM("fontSize" to "36rpx", "fontWeight" to "bold", "color" to "#333333")), "scan-btn" to _pS(_uM("backgroundColor" to "#00c900", "color" to "#FFFFFF", "paddingTop" to "0rpx", "paddingRight" to "24rpx", "paddingBottom" to "0rpx", "paddingLeft" to "24rpx", "borderTopLeftRadius" to "8rpx", "borderTopRightRadius" to "8rpx", "borderBottomRightRadius" to "8rpx", "borderBottomLeftRadius" to "8rpx", "fontSize" to "28rpx", "marginRight" to "5%", "backgroundColor:disabled" to "#cccccc")), "status-tip" to _pS(_uM("textAlign" to "center", "paddingTop" to "40rpx", "paddingRight" to 0, "paddingBottom" to "40rpx", "paddingLeft" to 0, "color" to "#666666", "fontSize" to "28rpx")), "loading" to _pS(_uM("width" to "30rpx", "height" to "30rpx", "borderTopWidth" to "3rpx", "borderRightWidth" to "3rpx", "borderBottomWidth" to "3rpx", "borderLeftWidth" to "3rpx", "borderTopStyle" to "solid", "borderRightStyle" to "solid", "borderBottomStyle" to "solid", "borderLeftStyle" to "solid", "borderTopColor" to "rgba(0,0,0,0)", "borderRightColor" to "#007aff", "borderBottomColor" to "#007aff", "borderLeftColor" to "#007aff", "marginTop" to "20rpx", "marginRight" to "auto", "marginBottom" to "20rpx", "marginLeft" to "auto", "animation" to "spin 1s linear infinite")), "device-list" to _pS(_uM("display" to "flex", "flexDirection" to "column", "gap" to "16rpx")), "device-item" to _pS(_uM("backgroundColor" to "#FFFFFF", "borderTopLeftRadius" to "12rpx", "borderTopRightRadius" to "12rpx", "borderBottomRightRadius" to "12rpx", "borderBottomLeftRadius" to "12rpx", "paddingTop" to "24rpx", "paddingRight" to "24rpx", "paddingBottom" to "24rpx", "paddingLeft" to "24rpx", "boxShadow" to "0 2rpx 8rpx rgba(0,0,0,0.1)", "cursor" to "pointer")), "device-name" to _pS(_uM("display" to "flex", "justifyContent" to "space-between", "marginBottom" to "16rpx")), "is_bj" to _pS(_uM("paddingTop" to 3, "paddingRight" to 8, "paddingBottom" to 3, "paddingLeft" to 8, "borderTopLeftRadius" to 5, "borderTopRightRadius" to 5, "borderBottomRightRadius" to 5, "borderBottomLeftRadius" to 5, "color" to "#FFFFFF", "backgroundColor" to "rgba(30,228,156,0.4)", "position" to "relative", "right" to 30)), "device-id" to _pS(_uM("fontSize" to "24rpx", "color" to "#999999")), "device-rssi" to _pS(_uM("display" to "flex", "flexDirection" to "column", "gap" to "8rpx")), "rssi-bar" to _pS(_uM("height" to "8rpx", "backgroundColor" to "#eeeeee", "borderTopLeftRadius" to "4rpx", "borderTopRightRadius" to "4rpx", "borderBottomRightRadius" to "4rpx", "borderBottomLeftRadius" to "4rpx", "overflow" to "hidden", "content::after" to "''", "height::after" to "100%", "backgroundImage::after" to "linear-gradient(to right, #ff4d4f, #faad14, #52c41a)", "backgroundColor::after" to "rgba(0,0,0,0)")), "device-status" to _pS(_uM("marginTop" to "16rpx", "textAlign" to "right")), "connected" to _pS(_uM("fontSize" to "26rpx", "color" to "#07c160", "backgroundColor" to "#f0fff4", "paddingTop" to "4rpx", "paddingRight" to "16rpx", "paddingBottom" to "4rpx", "paddingLeft" to "16rpx", "borderTopLeftRadius" to "12rpx", "borderTopRightRadius" to "12rpx", "borderBottomRightRadius" to "12rpx", "borderBottomLeftRadius" to "12rpx")), "@FONT-FACE" to _uM("0" to _uM()))
}
var inheritAttrs = true
var inject: Map<String, Map<String, Any?>> = _uM()
var emits: Map<String, Any?> = _uM()
var props = _nP(_uM())
var propsNeedCastKeys: UTSArray<String> = _uA()
var components: Map<String, CreateVueComponent> = _uM()
}
}

View File

@ -0,0 +1,32 @@
{
"id": "__UNI__08167A6",
"name": "电子吧唧_old",
"description": "",
"version": {
"name": "1.0.0",
"code": "100"
},
"uni-app-x": {
"compilerVersion": "4.75"
},
"app-android": {
"distribute": {
"modules": {
"uni-exit": {},
"uni-prompt": {},
"uni-media": {},
"uni-storage": {},
"uni-fileSystemManager": {}
},
"icons": {
"hdpi": "",
"xhdpi": "",
"xxhdpi": "",
"xxxhdpi": ""
},
"splashScreens": {
"default": {}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,5 @@
const __uniConfig = {"pages":[],"globalStyle":{"navigationBarTextStyle":"black","navigationBarTitleText":"","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom"},"appname":"电子吧唧_old","compilerVersion":"4.75","entryPagePath":"pages/index/index","entryPageQuery":"","realEntryPagePath":"","themeConfig":{}};
__uniConfig.getTabBarConfig = () => {return undefined};
__uniConfig.tabBar = __uniConfig.getTabBarConfig();
const __uniRoutes = [{"path":"pages/index/index","meta":{"isQuit":true,"isEntry":true,"navigationBarTitleText":"连接设备","navigationStyle":"custom"}},{"path":"pages/connect/connect","meta":{}}].map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute)).concat(typeof __uniSystemRoutes !== 'undefined' ? __uniSystemRoutes : []);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,24 @@
{
"id": "__UNI__08167A6",
"name": "电子吧唧_old",
"description": "",
"version": {
"name": "1.0.0",
"code": "100"
},
"uni-app-x": {
"compilerVersion": "4.75"
},
"app-ios": {
"distribute": {
"modules": {
"uni-prompt": {},
"uni-storage": {},
"uni-media": {},
"uni-fileSystemManager": {}
},
"icons": {},
"splashScreens": {}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>View</title>
<link rel="icon" href="data:,">
<link rel="stylesheet" href="app.css" />
<script>var __uniConfig = {"globalStyle":{},"darkmode":false}</script>
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
</head>
<body>
<div id="app"></div>
<script src="uni-app-view.umd.js"></script>
</body>
</html>

View File

@ -0,0 +1,11 @@
;(function(){
let u=void 0,isReady=false,onReadyCallbacks=[],isServiceReady=false,onServiceReadyCallbacks=[];
const __uniConfig = {"pages":[],"globalStyle":{"backgroundColor":"#F8F8F8","navigationBar":{"backgroundColor":"#F8F8F8","titleText":"","style":"custom","type":"default","titleColor":"#000000"},"isNVue":false},"nvue":{"compiler":"uni-app","styleCompiler":"uni-app","flex-direction":"column"},"renderer":"auto","appname":"dzbj","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":true},"compilerVersion":"4.75","entryPagePath":"pages/index/index","entryPageQuery":"","realEntryPagePath":"","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000},"locales":{},"darkmode":false,"themeConfig":{}};
const __uniRoutes = [{"path":"pages/index/index","meta":{"isQuit":true,"isEntry":true,"navigationBar":{"titleText":"连接设备","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/connect/connect","meta":{"navigationBar":{"type":"default"},"isNVue":false}}].map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute));
__uniConfig.styles=[];//styles
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:16})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:u,window:u,document:u,frames:u,self:u,location:u,navigator:u,localStorage:u,history:u,Caches:u,screen:u,alert:u,confirm:u,prompt:u,fetch:u,XMLHttpRequest:u,WebSocket:u,webkit:u,print:u}}}});
})();

View File

@ -0,0 +1 @@
(function(){})();

File diff suppressed because one or more lines are too long

3
unpackage/dist/build/app-plus/app.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"file":"app.css.js","sources":["uni-app:///D:/HBuilderX/plugins/uniapp-cli-vite/app.css.js"],"sourcesContent":null,"names":[],"mappings":";;;;;;;AAGA,YAAQ,SAAS,CAAC,QAAQ;AAAA;AAAA;"}

View File

@ -0,0 +1 @@
{"version":3,"file":"app.js","sources":[],"sourcesContent":null,"names":[],"mappings":";;"}

View File

@ -0,0 +1,111 @@
{
"@platforms": [
"android",
"iPhone",
"iPad"
],
"id": "__UNI__F18BB63",
"name": "dzbj",
"version": {
"name": "1.0.0",
"code": "100"
},
"description": "",
"developer": {
"name": "",
"email": "",
"url": ""
},
"permissions": {
"Bluetooth": {},
"Camera": {},
"UniNView": {
"description": "UniNView原生渲染"
}
},
"plus": {
"useragent": {
"value": "uni-app",
"concatenate": true
},
"splashscreen": {
"target": "id:1",
"autoclose": true,
"waiting": true,
"delay": 0
},
"popGesture": "close",
"launchwebview": {
"render": "always",
"id": "1",
"kernel": "WKWebview"
},
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"distribute": {
"google": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"apple": {
"dSYMs": false
},
"plugins": {
"audio": {
"mp3": {
"description": "Android平台录音支持MP3格式文件"
}
}
}
},
"statusbar": {
"immersed": "supportedDevice",
"style": "dark",
"background": "#F8F8F8"
},
"uniStatistics": {
"enable": false
},
"allowsInlineMediaPlayback": true,
"uni-app": {
"control": "uni-v3",
"vueVersion": "3",
"compilerVersion": "4.75",
"nvueCompiler": "uni-app",
"renderer": "auto",
"nvue": {
"flex-direction": "column"
},
"nvueLaunchMode": "normal",
"webView": {
"minUserAgentVersion": "49.0"
}
}
},
"app-harmony": {
"useragent": {
"value": "uni-app",
"concatenate": true
},
"uniStatistics": {
"enable": false
}
},
"launch_path": "__uniappview.html"
}

View File

@ -0,0 +1 @@
.status-pot[data-v-6b60e2e0]{width:16px;height:16px;border-radius:50%}.container[data-v-6b60e2e0]{background-color:#f5f5f7;min-height:100vh}.nav-bar[data-v-6b60e2e0]{display:flex;justify-content:space-between;align-items:center;padding:.625rem .9375rem;background-color:#fff}.nav-title[data-v-6b60e2e0]{color:#fff;font-size:1.125rem;font-weight:500}.upload-btn[data-v-6b60e2e0]{align-items:center;gap:.25rem;background-color:#28d50e;color:#fff;width:35%;margin-top:10px;padding:.4375rem 0;border-radius:.25rem;font-size:.8125rem}.content[data-v-6b60e2e0]{padding:.9375rem}.section-title[data-v-6b60e2e0]{display:block;font-size:1rem;color:#333;margin:.9375rem 0 .625rem;font-weight:500}.preview-container[data-v-6b60e2e0]{display:flex;flex-direction:column;align-items:center;margin-bottom:.625rem}.preview-frame[data-v-6b60e2e0]{width:15rem;height:15rem;border-radius:50%;background-color:#fff;box-shadow:0 .125rem .375rem rgba(0,0,0,.1);display:flex;justify-content:center;align-items:center;overflow:hidden;position:relative}.preview-image[data-v-6b60e2e0]{width:100%;height:100%}.empty-preview[data-v-6b60e2e0]{display:flex;flex-direction:column;align-items:center;color:#ccc}.empty-preview uni-text[data-v-6b60e2e0]{margin-top:.625rem;font-size:.875rem}.set-btn[data-v-6b60e2e0]{margin-top:.625rem;background-color:#3cbb19;color:#fff;width:35%;padding:.46875rem 0;border-radius:.25rem;font-size:.875rem}.carousel-section[data-v-6b60e2e0]{margin-bottom:.9375rem}.carousel-container[data-v-6b60e2e0]{background-color:#fff;border-radius:.5rem;padding:.625rem 0;box-shadow:0 .0625rem .25rem rgba(0,0,0,.05);overflow:hidden}.card-swiper[data-v-6b60e2e0]{width:100%;height:7.5rem}.card-swiper .swiper-item[data-v-6b60e2e0]{display:flex;justify-content:center;align-items:center;transition:all .3s ease}.card-item[data-v-6b60e2e0]{width:7.5rem;height:7.5rem}.card-frame[data-v-6b60e2e0]{width:7.5rem;height:100%;border-radius:50%;overflow:hidden;box-shadow:0 .1875rem .5rem rgba(0,0,0,.15);position:relative}.card-image[data-v-6b60e2e0]{width:7.5rem;height:100%}.card-overlay[data-v-6b60e2e0]{position:absolute;top:0;left:0;width:7.5rem;height:100%;background-color:rgba(0,0,0,.3);display:flex;justify-content:center;align-items:center}.card-swiper .swiper-item[data-v-6b60e2e0]:not(.swiper-item-active){transform:scale(.8);opacity:.6;z-index:1}.card-swiper .swiper-item-active[data-v-6b60e2e0]{transform:scale(1);z-index:2}.carousel-hint[data-v-6b60e2e0]{height:6.25rem;display:flex;justify-content:center;align-items:center;color:#999;font-size:.8125rem;text-align:center}.data-section[data-v-6b60e2e0]{background-color:#fff;border-radius:.5rem;padding:.625rem .9375rem;box-shadow:0 .0625rem .25rem rgba(0,0,0,.05)}.data-grid[data-v-6b60e2e0]{display:grid;grid-template-columns:1fr 1fr;gap:.625rem;margin-bottom:.9375rem}.data-card[data-v-6b60e2e0]{background-color:#f9f9f9;border-radius:.375rem;padding:.625rem;display:flex;align-items:center;gap:.625rem}.data-icon[data-v-6b60e2e0]{width:1.875rem;height:1.875rem;border-radius:.375rem;display:flex;justify-content:center;align-items:center}.battery-icon[data-v-6b60e2e0]{background-color:#f6ffed}.temp-icon[data-v-6b60e2e0]{background-color:#fff7e6}.humidity-icon[data-v-6b60e2e0]{background-color:#e6f7ff}.status-icon[data-v-6b60e2e0]{background-color:#f0f9ff}.data-info[data-v-6b60e2e0]{flex:1}.data-value[data-v-6b60e2e0]{font-size:1rem;font-weight:700;color:#333}.data-label[data-v-6b60e2e0]{font-size:.75rem;color:#666}.connection-status[data-v-6b60e2e0]{display:flex;justify-content:space-between;align-items:center;padding:.46875rem 0;border-top:.03125rem solid #f0f0f0}.status-text[data-v-6b60e2e0]{flex:1;margin:0 .46875rem;font-size:.875rem;color:#333}.connect-btn[data-v-6b60e2e0]{padding:.375rem .75rem;border-radius:.25rem;font-size:.8125rem;background-color:#007aff;color:#fff}.connect-btn[data-v-6b60e2e0]:disabled{background-color:#ccc}

View File

@ -0,0 +1 @@
.container[data-v-a57057ce]{padding:.5rem;background-color:#f5f5f5}.title-bar[data-v-a57057ce]{display:flex;justify-content:space-between;align-items:center;padding:.625rem 0;border-bottom:1px solid #eee;margin-bottom:.625rem;margin-top:2.5rem}.title[data-v-a57057ce]{font-size:1.125rem;font-weight:700;color:#333}.scan-btn[data-v-a57057ce]{background-color:#00c900;color:#fff;padding:0 .75rem;border-radius:.25rem;font-size:.875rem;margin-right:5%}.scan-btn[data-v-a57057ce]:disabled{background-color:#ccc}.status-tip[data-v-a57057ce]{text-align:center;padding:1.25rem 0;color:#666;font-size:.875rem}.loading[data-v-a57057ce]{width:.9375rem;height:.9375rem;border:.09375rem solid #007aff;border-top-color:transparent;border-radius:50%;margin:.625rem auto;animation:spin-a57057ce 1s linear infinite}@keyframes spin-a57057ce{to{transform:rotate(360deg)}}.device-list[data-v-a57057ce]{display:flex;flex-direction:column;gap:.5rem}.device-item[data-v-a57057ce]{background-color:#fff;border-radius:.375rem;padding:.75rem;box-shadow:0 .0625rem .25rem rgba(0,0,0,.1);cursor:pointer}.device-name[data-v-a57057ce]{display:flex;justify-content:space-between;margin-bottom:.5rem}.device-name uni-text[data-v-a57057ce]:first-child{font-size:1rem;color:#333}.is_bj[data-v-a57057ce]{padding:3px 8px;border-radius:5px;color:#fff;background-color:rgba(30,228,156,.4);position:relative;right:30px}.device-id[data-v-a57057ce]{font-size:.75rem;color:#999}.device-rssi[data-v-a57057ce]{display:flex;flex-direction:column;gap:.25rem}.device-rssi uni-text[data-v-a57057ce]{font-size:.8125rem;color:#666}.rssi-bar[data-v-a57057ce]{height:.25rem;background-color:#eee;border-radius:.125rem;overflow:hidden}.rssi-bar[data-v-a57057ce]:after{content:"";display:block;height:100%;background:linear-gradient(to right,#ff4d4f,#faad14,#52c41a)}.device-status[data-v-a57057ce]{margin-top:.5rem;text-align:right}.connected[data-v-a57057ce]{font-size:.8125rem;color:#07c160;background-color:#f0fff4;padding:.125rem .5rem;border-radius:.375rem}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
{
"hash": "82ed7da1",
"configHash": "0414020c",
"lockfileHash": "c52ceb15",
"browserHash": "5470c59f",
"optimized": {},
"chunks": {}
}

View File

@ -0,0 +1,3 @@
{
"type": "module"
}

11
unpackage/dist/dev/.nvue/app.css.js vendored Normal file
View File

@ -0,0 +1,11 @@
var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var require_app_css = __commonJS({
"app.css.js"(exports) {
const _style_0 = {};
exports.styles = [_style_0];
}
});
export default require_app_css();

2
unpackage/dist/dev/.nvue/app.js vendored Normal file
View File

@ -0,0 +1,2 @@
Promise.resolve("./app.css.js").then(() => {
});

View File

@ -0,0 +1,26 @@
{
"id": "",
"name": "电子吧唧_old",
"description": "",
"version": {
"name": "1.0.0",
"code": "100"
},
"uni-app-x": {
"compilerVersion": "4.75"
},
"app-android": {
"distribute": {
"modules": {},
"icons": {
"hdpi": "",
"xhdpi": "",
"xxhdpi": "",
"xxxhdpi": ""
},
"splashScreens": {
"default": {}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Some files were not shown because too many files have changed in this diff Show More