2025年04月21日18:27:41
@ -15,6 +15,7 @@ export default defineConfig(async (merge, { command, mode }) => {
|
|||||||
'@src': require('path').resolve(__dirname, '../src/src'),
|
'@src': require('path').resolve(__dirname, '../src/src'),
|
||||||
'@api': require('path').resolve(__dirname, '../src/api'),
|
'@api': require('path').resolve(__dirname, '../src/api'),
|
||||||
'@config': require('path').resolve(__dirname, '../src/config'),
|
'@config': require('path').resolve(__dirname, '../src/config'),
|
||||||
|
'@baseRouter': require('path').resolve(__dirname, '../src/baseRouter'),
|
||||||
},
|
},
|
||||||
projectName: 'myApp',
|
projectName: 'myApp',
|
||||||
date: '2023-8-18',
|
date: '2023-8-18',
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"@/images/*": ["./src/images/*"],
|
"@/images/*": ["./src/images/*"],
|
||||||
"@/api/*": ["./src/api/*"],
|
"@/api/*": ["./src/api/*"],
|
||||||
"@/store/*": ["./src/store/*"],
|
"@/store/*": ["./src/store/*"],
|
||||||
|
"@/baseRouter/*": ["./src/baseRouter/*"],
|
||||||
"@/src/*": ["./src/*"]
|
"@/src/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
export default defineAppConfig({
|
export default defineAppConfig({
|
||||||
pages: [
|
pages: [
|
||||||
|
"pages/device/index",
|
||||||
|
"pages/deviceList/index",
|
||||||
"pages/index/index",
|
"pages/index/index",
|
||||||
"pages/game/index",
|
"pages/game/index",
|
||||||
"pages/history/index",
|
"pages/history/index",
|
||||||
@ -10,4 +12,23 @@ export default defineAppConfig({
|
|||||||
navigationBarBackgroundColor: "#fff",
|
navigationBarBackgroundColor: "#fff",
|
||||||
navigationBarTextStyle: "black",
|
navigationBarTextStyle: "black",
|
||||||
},
|
},
|
||||||
|
tabBar: {
|
||||||
|
color: "#787878",
|
||||||
|
selectedColor: "#5F93FA",
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
pagePath: "pages/index/index",
|
||||||
|
text: "控制",
|
||||||
|
iconPath: "./assets/menu/m1.png",
|
||||||
|
selectedIconPath: "./assets/menu/m1_a.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: "pages/device/index",
|
||||||
|
text: "设备",
|
||||||
|
iconPath: "./assets/menu/m2.png",
|
||||||
|
selectedIconPath: "./assets/menu/m2_a.png",
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,7 @@ import BLESDK from './utils/ble'
|
|||||||
|
|
||||||
function App({ children }) {
|
function App({ children }) {
|
||||||
useLaunch(() => {
|
useLaunch(() => {
|
||||||
// BLESDK.openBluetoothAdapter()
|
BLESDK.openBluetoothAdapter()
|
||||||
})
|
})
|
||||||
|
|
||||||
// children 是将要会渲染的页面
|
// children 是将要会渲染的页面
|
||||||
|
10
src/app.less
@ -1,7 +1,3 @@
|
|||||||
.index {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
page {
|
page {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -13,5 +9,9 @@ page {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.index {
|
||||||
|
flex: 1;
|
||||||
|
background: #F7F7F7;
|
||||||
}
|
}
|
||||||
|
BIN
src/assets/addDev.png
Normal file
After Width: | Height: | Size: 139 KiB |
BIN
src/assets/connectble.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
src/assets/menu/m1.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/menu/m1_a.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/menu/m2.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/menu/m2_a.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/pause.png
Normal file
After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 17 KiB |
BIN
src/assets/roundble.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
92
src/baseRouter/index.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { getCurrentPages, debounce } from "@/utils/index";
|
||||||
|
import Taro from "@tarojs/taro";
|
||||||
|
|
||||||
|
class BaseRouter {
|
||||||
|
// 防止重复点击跳转页面
|
||||||
|
toPageFlag = false;
|
||||||
|
data = null;
|
||||||
|
|
||||||
|
verifyIsLogin(options) {
|
||||||
|
const token = Taro.getStorageSync("token");
|
||||||
|
if (options?.isLogin && !token) {
|
||||||
|
Taro.showToast({ title: "登录后可使用所有功能", icon: "error" });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} url 跳转url
|
||||||
|
* @param {*} options 要传递的参数
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
navigate(url, options) {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
if (!this.verifyIsLogin(options)) return;
|
||||||
|
this.data = options;
|
||||||
|
if (this.toPageFlag) return;
|
||||||
|
this.toPageFlag = true;
|
||||||
|
Taro.navigateTo({
|
||||||
|
url,
|
||||||
|
events: {
|
||||||
|
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
|
||||||
|
acceptDataFromOpenedPage: (data) => {
|
||||||
|
resolve(data);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.toPageFlag = false;
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} url 跳转url
|
||||||
|
* @param {*} options 要传递的参数
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
reLaunch(url, options) {
|
||||||
|
this.data = options;
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
if (!this.verifyIsLogin(options)) return;
|
||||||
|
Taro.reLaunch({
|
||||||
|
url,
|
||||||
|
events: {
|
||||||
|
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
|
||||||
|
acceptDataFromOpenedPage: (data) => {
|
||||||
|
resolve(data);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回上一页面
|
||||||
|
* @param delta
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
back = debounce((data, delta = 1) => {
|
||||||
|
this.data = null;
|
||||||
|
const eventChannel = getCurrentPages();
|
||||||
|
if (data != null) eventChannel?.emit("acceptDataFromOpenedPage", data);
|
||||||
|
Taro.navigateBack({ delta });
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns 获取上一个页面传递过来的参数
|
||||||
|
*/
|
||||||
|
getData(fn) {
|
||||||
|
this.eventChannel = getCurrentPages();
|
||||||
|
this.eventChannel.on &&
|
||||||
|
this.eventChannel.on("acceptDataFromOpenedPage", (res) => {
|
||||||
|
fn && fn(res);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default new BaseRouter();
|
@ -5,11 +5,11 @@ import { useEffect, useState } from 'react'
|
|||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import { Popup } from "@taroify/core"
|
import { Popup } from "@taroify/core"
|
||||||
|
|
||||||
export default function Index({ open, handleColorPicker }) {
|
export default function Index({ open, onChange }) {
|
||||||
let [data, setData] = useState({
|
let [data, setData] = useState({
|
||||||
boundaryData: [], // 元素边界信息
|
boundaryData: [], // 元素边界信息
|
||||||
gradient: '',
|
gradient: '',
|
||||||
hex: '#000000',
|
hex: '#ff0000',
|
||||||
rgba: {
|
rgba: {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 0,
|
g: 0,
|
||||||
@ -18,8 +18,8 @@ export default function Index({ open, handleColorPicker }) {
|
|||||||
},
|
},
|
||||||
hsb: {
|
hsb: {
|
||||||
h: 0,
|
h: 0,
|
||||||
s: 0,
|
s: 100,
|
||||||
b: 0
|
b: 100
|
||||||
},
|
},
|
||||||
bgcolor: {
|
bgcolor: {
|
||||||
r: 255,
|
r: 255,
|
||||||
@ -37,15 +37,6 @@ export default function Index({ open, handleColorPicker }) {
|
|||||||
}],
|
}],
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setData((state) => {
|
|
||||||
state.hsb = rgbToHsb(data.rgba)
|
|
||||||
state.hex = '#' + rgbToHex(data.rgba)
|
|
||||||
return { ...state }
|
|
||||||
})
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -62,18 +53,16 @@ export default function Index({ open, handleColorPicker }) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.boundaryData = res
|
data.boundaryData = res
|
||||||
console.log(res);
|
|
||||||
|
|
||||||
setData({ ...data })
|
setData({ ...data })
|
||||||
}).exec()
|
}).exec()
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
handleColorPicker({ rgba: [data.rgba.r, data.rgba.g, data.rgba.b, data.rgba.a], hex: data.hex })
|
onChange({ rgba: `${data.rgba.r}, ${data.rgba.g}, ${data.rgba.b}`, hex: data.hex })
|
||||||
}
|
}
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
handleColorPicker()
|
onChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
const touchstart = (e) => {
|
const touchstart = (e) => {
|
||||||
@ -137,7 +126,6 @@ export default function Index({ open, handleColorPicker }) {
|
|||||||
b: rgb.b,
|
b: rgb.b,
|
||||||
a: data.rgba.a
|
a: data.rgba.a
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置data
|
// 设置data
|
||||||
setData((state) => {
|
setData((state) => {
|
||||||
state.point[index] = {
|
state.point[index] = {
|
||||||
|
72
src/pages/device/index.jsx
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { View, Image, Text } from '@tarojs/components'
|
||||||
|
import './index.less'
|
||||||
|
import connectble from "@/assets/connectble.png";
|
||||||
|
import addDev from "@/assets/addDev.png";
|
||||||
|
import router from '@/baseRouter/index'
|
||||||
|
import BLESDK from '@/utils/ble'
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import Taro, { useDidShow } from '@tarojs/taro';
|
||||||
|
|
||||||
|
export default function Index() {
|
||||||
|
const [isLink, setIsLink] = useState(BLESDK.deviceInfo.state)
|
||||||
|
|
||||||
|
const addDevice = () => {
|
||||||
|
router.navigate('/pages/deviceList/index')
|
||||||
|
}
|
||||||
|
const deviceCallBack = () => {
|
||||||
|
setIsLink(BLESDK.deviceInfo.state)
|
||||||
|
}
|
||||||
|
useDidShow(() => {
|
||||||
|
BLESDK.deviceCallBack(deviceCallBack)
|
||||||
|
setIsLink(BLESDK.deviceInfo.state)
|
||||||
|
})
|
||||||
|
useEffect(() => {
|
||||||
|
if (BLESDK.deviceInfo.name) {
|
||||||
|
BLESDK.createBleConnection()
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const unbind = () => {
|
||||||
|
Taro.showModal({
|
||||||
|
title: '解绑设备',
|
||||||
|
content: '确认解绑当前设备?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
setIsLink(false)
|
||||||
|
BLESDK.unBindDevice()
|
||||||
|
Taro.removeStorageSync('deviceInfo')
|
||||||
|
Taro.showToast({ title: '设备解绑成功', icon: 'success' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log(BLESDK.deviceInfo, BLESDK.deviceInfo?.name ? 1 : 2, 'BLESDK.deviceInfo');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="index device">
|
||||||
|
{BLESDK.deviceInfo?.name ? <>
|
||||||
|
<View className="deviceinfo">
|
||||||
|
<Image src={connectble} className='deviceimg' />
|
||||||
|
<View className="item">
|
||||||
|
<View className="item-label">连接状态</View>
|
||||||
|
<View className="item-text active">{isLink ? '已连接' : '未连接'}</View>
|
||||||
|
</View>
|
||||||
|
<View className="item">
|
||||||
|
<View className="item-label">设备名称</View>
|
||||||
|
<View className="item-text">{BLESDK.deviceInfo.name}</View>
|
||||||
|
</View>
|
||||||
|
<View className="item">
|
||||||
|
<View className="item-label">MAC 地址</View>
|
||||||
|
<View className="item-text">{BLESDK.deviceInfo.mac}</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View className='btn' onClick={unbind}>解绑设备</View>
|
||||||
|
</> :
|
||||||
|
<View className='adddevice' onClick={addDevice}>
|
||||||
|
<Image src={addDev} className='addimg' />
|
||||||
|
<View className='text'>添加设备</View>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
79
src/pages/device/index.less
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
.device {
|
||||||
|
background: #F7F7F7;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.deviceinfo {
|
||||||
|
width: 686rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
padding: 48rpx 32rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
|
||||||
|
.deviceimg {
|
||||||
|
width: 300rpx;
|
||||||
|
height: 300rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 64rpx;
|
||||||
|
|
||||||
|
.item-label {
|
||||||
|
color: #212121;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-text {
|
||||||
|
color: #666666;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
color: #5F93FA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 686rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
background: #E0EBFF;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 80rpx;
|
||||||
|
color: #5F93FA;
|
||||||
|
font-size: 30rpx;
|
||||||
|
margin-top: 48rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adddevice {
|
||||||
|
width: 544rpx;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
.addimg {
|
||||||
|
width: 544rpx;
|
||||||
|
height: 334rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
color: #BABABA;
|
||||||
|
font-size: 32rpx;
|
||||||
|
margin-top: 32rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
src/pages/deviceList/index.config.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: "设备列表",
|
||||||
|
});
|
65
src/pages/deviceList/index.jsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { View } from '@tarojs/components'
|
||||||
|
import './index.less'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
import router from '@/baseRouter/index'
|
||||||
|
import BLESDK from '@/utils/ble'
|
||||||
|
|
||||||
|
export default function Index() {
|
||||||
|
let [deviceList, setDeviceList] = useState([])
|
||||||
|
const connect = (item) => {
|
||||||
|
Taro.showLoading({
|
||||||
|
title: '正在连接设备',
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
BLESDK.deviceInfo = item
|
||||||
|
BLESDK.createBleConnection()
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
BLESDK.startBluetoothDevicesDiscovery()
|
||||||
|
Taro.showLoading({ title: '设备搜索中..', mask: true })
|
||||||
|
BLESDK.deviceCallBack(deviceCallBack)
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
Taro.hideLoading()
|
||||||
|
}, 3000)
|
||||||
|
return () => {
|
||||||
|
BLESDK.stopBluetoothDevicesDiscovery()
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const deviceCallBack = (res) => {
|
||||||
|
Taro.hideLoading()
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
|
||||||
|
BLESDK.onBluetoothDeviceFound((item) => {
|
||||||
|
if (JSON.stringify(deviceList).indexOf(item.mac) != -1) return
|
||||||
|
deviceList.push(item)
|
||||||
|
setDeviceList([...deviceList])
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="index deviceList">
|
||||||
|
<View className="head">
|
||||||
|
<View className="radar">
|
||||||
|
<View className="yuan1 yuan"></View>
|
||||||
|
<View className="yuan2 yuan"></View>
|
||||||
|
<View className="yuan3 yuan"></View>
|
||||||
|
</View>
|
||||||
|
<View className="text">请确保手机蓝牙开启,同时待激活设备也处于上电开启状态,尽量靠近设备,强信号有助于提高设备激活的成功率!</View>
|
||||||
|
</View>
|
||||||
|
<View className='list'>
|
||||||
|
{deviceList.map(item => <View className='item'>
|
||||||
|
<View className='item-img'></View>
|
||||||
|
<View className='item-content'>
|
||||||
|
<View className='item-content-name'>{item.name}</View>
|
||||||
|
<View className='item-content-mac'>{item.mac}</View>
|
||||||
|
</View>
|
||||||
|
<View className='item-btn' onClick={() => connect(item)}>连接</View>
|
||||||
|
</View>)}
|
||||||
|
</View>
|
||||||
|
</View >
|
||||||
|
)
|
||||||
|
}
|
126
src/pages/deviceList/index.less
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
.deviceList {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
padding-top: 1rpx;
|
||||||
|
padding: 0 32rpx;
|
||||||
|
|
||||||
|
.radar {
|
||||||
|
width: 62rpx;
|
||||||
|
height: 62rpx;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.yuan {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1rpx solid #5F93FA;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.yuan1 {
|
||||||
|
&::after {
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
background-image: linear-gradient(44deg, rgba(0, 255, 51, 0) 10%, #5F93FA 100%);
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
animation: zhuan 2s infinite;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
transform-origin: bottom right;
|
||||||
|
border-radius: 100% 0 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.yuan2 {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yuan3 {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zhuan {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
margin-left: 20rpx;
|
||||||
|
flex: 1;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-family: AlibabaPuHuiTi_2_45_Light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
flex: 1;
|
||||||
|
margin-top: 32rpx;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 0 32rpx 50rpx;
|
||||||
|
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 26rpx 24rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
|
||||||
|
.item-img {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background: url('../../assets/roundble.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-content {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 16rpx;
|
||||||
|
|
||||||
|
.item-content-name {
|
||||||
|
color: #000000;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-content-mac {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-btn {
|
||||||
|
width: 140rpx;
|
||||||
|
height: 58rpx;
|
||||||
|
border-radius: 61rpx;
|
||||||
|
background: #5F93FA;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 58rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -3,35 +3,80 @@ import './index.less'
|
|||||||
import ColorPicker from "@/components/color-picker";
|
import ColorPicker from "@/components/color-picker";
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import history from "../../assets/history.png";
|
import history from "../../assets/history.png";
|
||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
import { hex, strInsert } from '@/utils/sendOrder';
|
||||||
|
import BLESDK from '@/utils/ble'
|
||||||
|
import router from '@/baseRouter/index'
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const list = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',]
|
const [list, setList] = useState(["255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255", "255, 255, 255"])
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
|
const [curColor, setCurColor] = useState({
|
||||||
|
hex: '#ff0000',
|
||||||
|
rgba: '255, 0, 0'
|
||||||
|
})
|
||||||
|
const toPage = () => {
|
||||||
|
router.navigate('/pages/history/index').then((data) => {
|
||||||
|
setList([...data])
|
||||||
|
})
|
||||||
|
}
|
||||||
const handleColorPicker = (e) => {
|
const handleColorPicker = (e) => {
|
||||||
|
console.log(e);
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
setCurColor(e)
|
||||||
|
}
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
}
|
}
|
||||||
useEffect(() => {
|
const addColor = (index) => {
|
||||||
|
setList((state) => {
|
||||||
|
state[index] = curColor.rgba
|
||||||
|
return [...state]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const submit = () => {
|
||||||
|
let str = '7B55EA10B2'
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
const item = list[i].split(',')
|
||||||
|
str += hex(item[0])
|
||||||
|
str += hex(item[1])
|
||||||
|
str += hex(item[2])
|
||||||
|
str += hex(1)
|
||||||
|
}
|
||||||
|
BLESDK.writeBleValue(new Uint8Array(strInsert(str)).buffer)
|
||||||
|
}
|
||||||
|
const saveTemplate = () => {
|
||||||
|
let historyList = Taro.getStorageSync('colorList') || []
|
||||||
|
if (historyList.length > 10) {
|
||||||
|
historyList[0] = list
|
||||||
|
} else {
|
||||||
|
historyList.unshift(list)
|
||||||
|
}
|
||||||
|
Taro.setStorageSync('colorList', historyList)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '保存成功',
|
||||||
|
icon: "none",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}, [])
|
|
||||||
return (
|
return (
|
||||||
<View className="index">
|
<View className="index">
|
||||||
<View className='head'>
|
<View className='head'>
|
||||||
<View className='head-left'>像素跳动</View>
|
<View className='head-left'>像素跳动</View>
|
||||||
<View className='head-right'> <Image className='icon' src={history} />历史记录</View>
|
<View className='head-right' onClick={toPage}> <Image className='icon' src={history} />历史记录</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="grid">
|
<View className="grid">
|
||||||
{list.map((item, index) => <View className={`grid-item ${index == 0 ? 'active' : ''}`} key={index}></View>)}
|
{list.map((item, index) => <View className="grid-item" style={{ backgroundColor: `rgb(${item})` }} key={index} onClick={() => addColor(index)}></View>)}
|
||||||
</View >
|
</View >
|
||||||
|
|
||||||
<View className='colorbox'>
|
<View className='colorbox'>
|
||||||
<View className='colorbox-icon' onClick={() => setOpen(true)}></View>
|
<View className='colorbox-icon' onClick={() => setOpen(true)}></View>
|
||||||
<View className='colorbox-btn' onClick={() => setOpen(true)}>#EDEDED</View>
|
<View className='colorbox-btn' style={{ backgroundColor: curColor.hex }} onClick={() => setOpen(true)}>{curColor.hex}</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='hint'>*请选取喜欢的颜色,再点击小方格填入颜色;</View>
|
<View className='hint'>*请选取喜欢的颜色,再点击小方格填入颜色;</View>
|
||||||
<View className='btn' >传输画面到音响屏幕</View>
|
<View className='btn' onClick={submit}>传输画面到音响屏幕</View>
|
||||||
<ColorPicker open={open} handleColorPicker={handleColorPicker} />
|
<View className='btn' onClick={saveTemplate}>保存模板</View>
|
||||||
|
<ColorPicker open={open} onChange={handleColorPicker} />
|
||||||
</View >
|
</View >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -60,10 +60,6 @@
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #FAFAFA;
|
background: #FAFAFA;
|
||||||
border: 1px solid #999999;
|
border: 1px solid #999999;
|
||||||
|
|
||||||
&.active {
|
|
||||||
border: 1px solid #5F93FA;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +105,7 @@
|
|||||||
line-height: 80rpx;
|
line-height: 80rpx;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
margin: 0 auto;
|
margin: 0 auto 30rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,41 +4,52 @@ import "./index.less";
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import empty from "@/assets/empty.png";
|
import empty from "@/assets/empty.png";
|
||||||
import { ActionSheet } from "@taroify/core"
|
import router from '@/baseRouter/index'
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const list = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',]
|
let [history, setHistory] = useState(Taro.getStorageSync("colorList") || [])
|
||||||
const history = [{}]
|
|
||||||
const [open, setOpen] = useState(false)
|
const delItem = (index) => {
|
||||||
const actions = [
|
Taro.showModal({
|
||||||
{ name: "使用此套颜色方案", value: "1", style: { color: "#5A8FFA" } },
|
title: '提示',
|
||||||
{ name: "删除此套颜色方案", value: "2", style: { color: "#FF575F" } },
|
content: '是否确认删除?',
|
||||||
]
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
history.splice(index, 1)
|
||||||
|
setHistory([...history])
|
||||||
|
Taro.setStorageSync("colorList", history)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const useItem = (item) => {
|
||||||
|
router.back(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="index">
|
<View className="history index">
|
||||||
{
|
{
|
||||||
history.length ?
|
history.length ?
|
||||||
<View>
|
<View>
|
||||||
{
|
{
|
||||||
history.map((item, index) => {
|
history.map((item, index) => <View className="card" key={index}>
|
||||||
return <View className="grid" key={index} onClick={() => setOpen(true)}>
|
<View className="grid">
|
||||||
{list.map((ite, ide) => <View className="grid-item" key={`${index}_${ide}`}></View>)}
|
{item.map((ite, ide) => <View className="grid-item" style={{ backgroundColor: `rgb(${ite})` }} key={`_${ide}`}></View>)}
|
||||||
</View >
|
</View >
|
||||||
})
|
<View className="btns">
|
||||||
}
|
<View className="btn del" onClick={() => delItem(index)}>删除</View>
|
||||||
|
<View className="btn use" onClick={() => useItem(item)}>使用</View>
|
||||||
</View>
|
</View>
|
||||||
: <View className="empty">
|
</View>)
|
||||||
|
}
|
||||||
|
</View> :
|
||||||
|
<View className="empty">
|
||||||
<Image src={empty} className="empty-img" />
|
<Image src={empty} className="empty-img" />
|
||||||
<View className="empty-text">暂无历史记录</View>
|
<View className="empty-text">暂无历史记录</View>
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
<ActionSheet
|
|
||||||
cancelText="取消"
|
|
||||||
actions={actions}
|
|
||||||
open={open}
|
|
||||||
onSelect={() => setOpen(false)}
|
|
||||||
onCancel={() => setOpen(false)}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,26 @@
|
|||||||
.index {
|
.history {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
padding: 32rpx;
|
padding: 32rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background: #F7F7F7;
|
||||||
|
|
||||||
.grid {
|
.card {
|
||||||
flex-shrink: 0;
|
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
background: #F9F9F9;
|
background: #F9F9F9;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid #999999;
|
padding: 32rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
flex-shrink: 0;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(9, 1fr);
|
grid-template-columns: repeat(9, 1fr);
|
||||||
gap: 8rpx;
|
gap: 8rpx;
|
||||||
padding: 32rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin-bottom: 30rpx;
|
|
||||||
|
|
||||||
.grid-item {
|
.grid-item {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
@ -26,6 +31,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btns {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 32rpx;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.del {
|
||||||
|
background: #FFDEE3;
|
||||||
|
color: #FC3258;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use {
|
||||||
|
background: #DEE9FF;
|
||||||
|
color: #5F93FA;
|
||||||
|
margin-left: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.empty {
|
.empty {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 40%;
|
top: 40%;
|
||||||
|
@ -5,9 +5,93 @@ import ble from "@/assets/ble.png";
|
|||||||
import soundCard from "@/assets/soundCard.png";
|
import soundCard from "@/assets/soundCard.png";
|
||||||
import game from "@/assets/game.png";
|
import game from "@/assets/game.png";
|
||||||
import ai from "@/assets/ai.png";
|
import ai from "@/assets/ai.png";
|
||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
import { useCallback, useState } from 'react';
|
||||||
|
import { hex, strInsert } from '@/utils/sendOrder';
|
||||||
|
import { debounce } from '@/utils/index'
|
||||||
|
import BLESDK from '@/utils/ble'
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const sourceList = ['Line', 'OPT', 'ARC', 'USB']
|
const sourceList = ['Line', 'OPT', 'ARC', 'USB']
|
||||||
|
const [ruleForm, setRuleForm] = useState({
|
||||||
|
volume: 0, //话筒音量
|
||||||
|
music: 0, //音乐音量
|
||||||
|
source: 0, //音源设置
|
||||||
|
bleSwitch: 0, //蓝牙开关
|
||||||
|
soundCadSwitch: 0, //声卡开关
|
||||||
|
playMode: 0, //播放模式
|
||||||
|
musicControl: 0, //音乐控制
|
||||||
|
girth: 0, //超低音强度
|
||||||
|
reverb: 1, //混响模式
|
||||||
|
microphoneReverberation: 0, //话筒混响
|
||||||
|
AI: 0, //AI
|
||||||
|
playPause: 0, //播放暂停
|
||||||
|
})
|
||||||
|
const toPage = () => {
|
||||||
|
Taro.navigateTo({ url: '/pages/game/index' })
|
||||||
|
}
|
||||||
|
const sendCode = useCallback(debounce((e) => {
|
||||||
|
BLESDK.writeBleValue(new Uint8Array(strInsert(e)).buffer)
|
||||||
|
}), [])
|
||||||
|
const handleChange = (e, key) => {
|
||||||
|
setRuleForm({
|
||||||
|
...ruleForm,
|
||||||
|
[key]: e
|
||||||
|
})
|
||||||
|
let str = ''
|
||||||
|
switch (key) {
|
||||||
|
case 'volume':
|
||||||
|
str = `7B05EA05B2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'music':
|
||||||
|
str = `7B05EA06B2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'source':
|
||||||
|
str = `7B05EA07B2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'bleSwitch':
|
||||||
|
str = `7B05EA08B2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'soundCadSwitch':
|
||||||
|
str = `7B05EA09B2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'playMode':
|
||||||
|
str = `7B05EA0AB2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'musicControl':
|
||||||
|
str = `7B05EA0BB2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'girth':
|
||||||
|
str = `7B05EA0CB2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'reverb':
|
||||||
|
str = `7B05EA0DB2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'microphoneReverberation':
|
||||||
|
str = `7B05EA0EB2${hex(e)}`
|
||||||
|
break;
|
||||||
|
case 'AI':
|
||||||
|
str = `7B05EA11B2${hex(e)}`
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sendCode(str)
|
||||||
|
}
|
||||||
|
// 音乐控制 0:停止 1:播放 2:暂停 3:上一曲 4:下一曲
|
||||||
|
const musicControl = (num) => {
|
||||||
|
let str = `7B05EA0BB2${hex(num)}`
|
||||||
|
sendCode(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
const control = (type) => {
|
||||||
|
let num = ruleForm.girth
|
||||||
|
if (type == "+" && ruleForm.girth < 3) {
|
||||||
|
num++
|
||||||
|
} else if (type == "-" && ruleForm.girth > 0) {
|
||||||
|
num--
|
||||||
|
}
|
||||||
|
handleChange(num, 'girth')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="index">
|
<View className="index">
|
||||||
<View className="headbox">
|
<View className="headbox">
|
||||||
@ -16,14 +100,13 @@ export default function Index() {
|
|||||||
<View className="list">
|
<View className="list">
|
||||||
{
|
{
|
||||||
sourceList.map((item, index) => {
|
sourceList.map((item, index) => {
|
||||||
return <View className={`list-item ${index == 0 ? 'active' : ''}`} key={index}>
|
return <View className={`list-item ${index == ruleForm.source ? 'active' : ''}`} key={index} onClick={() => handleChange(index, 'source')}>
|
||||||
<View className="yuan"></View>
|
<View className="yuan"></View>
|
||||||
<View className="line"></View>
|
<View className="line"></View>
|
||||||
<View className="text">{item}</View>
|
<View className="text">{item}</View>
|
||||||
</View>
|
</View>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@ -32,23 +115,26 @@ export default function Index() {
|
|||||||
<View className="switch-item">
|
<View className="switch-item">
|
||||||
<Image className='img' src={ble} />
|
<Image className='img' src={ble} />
|
||||||
<Text className='text'>蓝牙</Text>
|
<Text className='text'>蓝牙</Text>
|
||||||
<Switch size="20" />
|
<Switch size="20" onChange={(e) => handleChange(e, 'bleSwitch')} checked={ruleForm.bleSwitch} />
|
||||||
</View>
|
</View>
|
||||||
<View className="switch-item">
|
<View className="switch-item">
|
||||||
<Image className='img' src={soundCard} />
|
<Image className='img' src={soundCard} />
|
||||||
<Text className='text'>声卡</Text>
|
<Text className='text'>声卡</Text>
|
||||||
<Switch size="20" />
|
<Switch size="20" onChange={(e) => handleChange(e, 'soundCadSwitch')} checked={ruleForm.soundCadSwitch} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='play'>
|
<View className='play'>
|
||||||
<View className='play-icon pre'></View>
|
<View className='play-icon pre' onClick={() => musicControl(3)}></View>
|
||||||
<View className='play-play'></View>
|
<View className={ruleForm.playPause ? 'play-pause' : 'play-play'} onClick={() => {
|
||||||
<View className='play-icon next'></View>
|
musicControl(ruleForm.playPause ? 2 : 1)
|
||||||
|
handleChange(!ruleForm.playPause, 'playPause')
|
||||||
|
}}></View>
|
||||||
|
<View className='play-icon next' onClick={() => musicControl(4)}></View>
|
||||||
</View>
|
</View>
|
||||||
<View className='card'>
|
<View className='card'>
|
||||||
<View className='funitem'>
|
<View className='funitem'>
|
||||||
<View className='funitem-text'>音乐音量</View>
|
<View className='funitem-text'>音乐模式</View>
|
||||||
<View className='mode'>
|
<View className='mode'>
|
||||||
<View className='icon l'></View>
|
<View className='icon l'></View>
|
||||||
<View className='input'>MODE 1</View>
|
<View className='input'>MODE 1</View>
|
||||||
@ -60,9 +146,22 @@ export default function Index() {
|
|||||||
<View className='funitem'>
|
<View className='funitem'>
|
||||||
<View className='funitem-text'>超低音强度</View>
|
<View className='funitem-text'>超低音强度</View>
|
||||||
<View className='mode'>
|
<View className='mode'>
|
||||||
<View className='icon l'></View>
|
<View className='icon l' onClick={() => control("-")}></View>
|
||||||
<View className='input'>+ 1</View>
|
<View className='input'>{ruleForm.girth}</View>
|
||||||
<View className='icon r'></View>
|
<View className='icon r' onClick={() => control("+")}></View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View className='card'>
|
||||||
|
<View className='funitem'>
|
||||||
|
<View className='funitem-text'>音乐音量</View>
|
||||||
|
<View className='funitem-right'>
|
||||||
|
<View className='num'>{ruleForm.volume}%</View>
|
||||||
|
<Slider className="custom-color" min={0} max={100} size={4} onChange={(e) => handleChange(e, 'volume')} value={ruleForm.volume} >
|
||||||
|
<Slider.Thumb>
|
||||||
|
<View className="custom-thumb"></View>
|
||||||
|
</Slider.Thumb>
|
||||||
|
</Slider>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@ -70,40 +169,36 @@ export default function Index() {
|
|||||||
<View className='funitem'>
|
<View className='funitem'>
|
||||||
<View className='funitem-text'>话筒音量</View>
|
<View className='funitem-text'>话筒音量</View>
|
||||||
<View className='funitem-right'>
|
<View className='funitem-right'>
|
||||||
<View className='num'>50%</View>
|
<View className='num'>{ruleForm.music}%</View>
|
||||||
<Slider className="custom-color" size={4} defaultValue={50} />
|
<Slider className="custom-color" min={0} max={100} size={4} onChange={(e) => handleChange(e, 'music')} value={ruleForm.music} >
|
||||||
</View>
|
<Slider.Thumb>
|
||||||
</View>
|
<View className="custom-thumb"></View>
|
||||||
</View>
|
</Slider.Thumb>
|
||||||
<View className='card'>
|
</Slider>
|
||||||
<View className='funitem'>
|
|
||||||
<View className='funitem-text'>话筒音量</View>
|
|
||||||
<View className='funitem-right'>
|
|
||||||
<View className='num'>50%</View>
|
|
||||||
<Slider className="custom-color" size={4} defaultValue={50} />
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='funitem'>
|
<View className='funitem'>
|
||||||
<View className='funitem-text'>话筒混响音量</View>
|
<View className='funitem-text'>话筒混响音量</View>
|
||||||
<View className='funitem-right'>
|
<View className='funitem-right'>
|
||||||
<View className='num'>50%</View>
|
<View className='num'>{ruleForm.microphoneReverberation}%</View>
|
||||||
<Slider className="custom-color" size={4} defaultValue={50} />
|
<Slider className="custom-color" min={0} max={32} size={4} onChange={(e) => handleChange(e, 'microphoneReverberation')} value={ruleForm.microphoneReverberation} >
|
||||||
|
<Slider.Thumb>
|
||||||
|
<View className="custom-thumb"></View>
|
||||||
|
</Slider.Thumb>
|
||||||
|
</Slider>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='funitem'>
|
<View className='funitem'>
|
||||||
<View className='funitem-text'>话筒混响模式</View>
|
<View className='funitem-text'>话筒混响模式</View>
|
||||||
<View className='numlist'>
|
<View className='numlist'>
|
||||||
<View className='numlist-num active'>1</View>
|
{[1, 2, 3, 4, 5, 6].map(item => {
|
||||||
<View className='numlist-num'>2</View>
|
return <View className={`numlist-num ${ruleForm.reverb == item ? 'active' : ''} `} key={item} onClick={() => handleChange(item, 'reverb')}>{item}</View>
|
||||||
<View className='numlist-num'>3</View>
|
})}
|
||||||
<View className='numlist-num'>4</View>
|
|
||||||
<View className='numlist-num'>5</View>
|
|
||||||
<View className='numlist-num'>6</View>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className='btns'>
|
<View className='btns'>
|
||||||
<View className='btn-item'>
|
<View className='btn-item' onClick={toPage}>
|
||||||
<Image src={game} className='img' />
|
<Image src={game} className='img' />
|
||||||
GAME
|
GAME
|
||||||
</View>
|
</View>
|
||||||
|
@ -144,6 +144,17 @@
|
|||||||
background-size: 46rpx 39rpx;
|
background-size: 46rpx 39rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.play-pause {
|
||||||
|
width: 246rpx;
|
||||||
|
height: 246rpx;
|
||||||
|
background: url('../../assets/pause.png') no-repeat;
|
||||||
|
background-size: 246rpx 246rpx;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.play-play {
|
.play-play {
|
||||||
width: 246rpx;
|
width: 246rpx;
|
||||||
height: 246rpx;
|
height: 246rpx;
|
||||||
@ -310,3 +321,10 @@
|
|||||||
.custom-color {
|
.custom-color {
|
||||||
--slider-active-background-color: #5A8FFA;
|
--slider-active-background-color: #5A8FFA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-thumb {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background: url('../../assets/sliding.png') no-repeat;
|
||||||
|
background-size: 60rpx 60rpx;
|
||||||
|
}
|
||||||
|
3
src/pages/test/index.config.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: "首页",
|
||||||
|
});
|
@ -1,7 +1,5 @@
|
|||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import { handshake1, handshake2 } from "./sendOrder";
|
import { handshake1, handshake2 } from "./sendOrder";
|
||||||
import useStore from "@/store/index";
|
|
||||||
import { aes128Decrypt } from "@/utils/index";
|
|
||||||
import TASK from "./taskQueue";
|
import TASK from "./taskQueue";
|
||||||
|
|
||||||
const errMsg = {
|
const errMsg = {
|
||||||
@ -23,9 +21,13 @@ const errMsg = {
|
|||||||
|
|
||||||
class Bluetooth {
|
class Bluetooth {
|
||||||
config = {
|
config = {
|
||||||
serviceId: "4E31BF4A-8507-3A2B-7344-C7EDACD38104", //设备服务id
|
// serviceId: "4E31BF4A-8507-3A2B-7344-C7EDACD38104", //设备服务id
|
||||||
NotifyUUID: "4E31BF4B-8507-3A2B-7344-C7EDACD38104",
|
// NotifyUUID: "4E31BF4B-8507-3A2B-7344-C7EDACD38104",
|
||||||
WriteUUID: "4E31BF4C-8507-3A2B-7344-C7EDACD38104",
|
// WriteUUID: "4E31BF4C-8507-3A2B-7344-C7EDACD38104",
|
||||||
|
|
||||||
|
serviceId: 'C7E6FAE0-E966-1000-8000-BEF9C723DF6A', //设备服务id
|
||||||
|
NotifyUUID: 'C7E6FAE1-E966-1000-8000-BEF9C723DF6A',
|
||||||
|
WriteUUID: 'C7E6FAE2-E966-1000-8000-BEF9C723DF6A',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 连接状态
|
// 连接状态
|
||||||
@ -43,17 +45,11 @@ class Bluetooth {
|
|||||||
|
|
||||||
platform = Taro.getSystemInfoSync().platform;
|
platform = Taro.getSystemInfoSync().platform;
|
||||||
appAuthorize = Taro.getAppAuthorizeSetting();
|
appAuthorize = Taro.getAppAuthorizeSetting();
|
||||||
deviceInfo = {};
|
deviceInfo = Taro.getStorageSync('deviceInfo') || {}
|
||||||
callBack = () => { };
|
callBack = () => { };
|
||||||
searchBack = () => { };
|
searchBack = () => { };
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// if (this.platform == "android") {
|
|
||||||
// this.deviceInfo = { deviceId: "50:C0:F0:F2:99:5B", mac: "50:C0:F0:F2:99:5B", name: "W53A", state: false };
|
|
||||||
// } else {
|
|
||||||
// this.deviceInfo = { deviceId: "", mac: "50:C0:F0:C8:CC:88", name: "W53A", state: false };
|
|
||||||
// // this.deviceInfo = { deviceId: "A890AB3C-0BC3-1418-1132-CA27514B147B", mac: "50:C0:F0:F2:99:5B", name: "W53A", state: false };
|
|
||||||
// }
|
|
||||||
this.onBluetoothAdapterStateChange();
|
this.onBluetoothAdapterStateChange();
|
||||||
this.onBLEConnectionStateChange();
|
this.onBLEConnectionStateChange();
|
||||||
this.onBluetoothDeviceFound();
|
this.onBluetoothDeviceFound();
|
||||||
@ -140,7 +136,7 @@ class Bluetooth {
|
|||||||
|
|
||||||
// 监听搜索到新设备的事件
|
// 监听搜索到新设备的事件
|
||||||
// 定义一个方法用于处理蓝牙设备发现事件
|
// 定义一个方法用于处理蓝牙设备发现事件
|
||||||
onBluetoothDeviceFound() {
|
onBluetoothDeviceFound(fn) {
|
||||||
Taro.onBluetoothDeviceFound((res) => {
|
Taro.onBluetoothDeviceFound((res) => {
|
||||||
const devices = res.devices[0];
|
const devices = res.devices[0];
|
||||||
const advertisData = this.ab2hex(devices.advertisData);
|
const advertisData = this.ab2hex(devices.advertisData);
|
||||||
@ -148,17 +144,18 @@ class Bluetooth {
|
|||||||
// 判断是否有搜索到设备
|
// 判断是否有搜索到设备
|
||||||
this.isFindBt && this.clearTimeoutFn("isFindBt");
|
this.isFindBt && this.clearTimeoutFn("isFindBt");
|
||||||
|
|
||||||
if (devices.name && devices.name == "LE-AB2020") {
|
if (devices.name && devices.name == "W53A") {
|
||||||
|
// if (devices.name && devices.name == "LE-AB2020") {
|
||||||
const item = {
|
const item = {
|
||||||
deviceId: devices.deviceId,
|
deviceId: devices.deviceId,
|
||||||
mac: mac,
|
mac: mac,
|
||||||
name: devices.name,
|
name: devices.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(JSON.stringify(item), "搜索到设备");
|
// this.deviceInfo = { ...this.deviceInfo, ...item }
|
||||||
this.deviceInfo = { ...this.deviceInfo, ...item }
|
// this.stopBluetoothDevicesDiscovery();
|
||||||
this.stopBluetoothDevicesDiscovery();
|
// this.createBleConnection();
|
||||||
this.createBleConnection();
|
fn && fn(item)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -201,7 +198,6 @@ class Bluetooth {
|
|||||||
deviceId: this.deviceInfo.deviceId,
|
deviceId: this.deviceInfo.deviceId,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log(JSON.stringify(res), 'JSON.stringify(res)');
|
console.log(JSON.stringify(res), 'JSON.stringify(res)');
|
||||||
|
|
||||||
this.getBLEDeviceCharacteristics();
|
this.getBLEDeviceCharacteristics();
|
||||||
},
|
},
|
||||||
fail: (err) => this.fail(err),
|
fail: (err) => this.fail(err),
|
||||||
@ -228,6 +224,7 @@ class Bluetooth {
|
|||||||
state: true,
|
state: true,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log("连接成功");
|
console.log("连接成功");
|
||||||
|
Taro.setStorageSync("deviceInfo", this.deviceInfo);
|
||||||
handshake1()
|
handshake1()
|
||||||
this.callBack(this.deviceInfo);
|
this.callBack(this.deviceInfo);
|
||||||
},
|
},
|
||||||
@ -262,9 +259,6 @@ class Bluetooth {
|
|||||||
characteristicId: this.config.WriteUUID,
|
characteristicId: this.config.WriteUUID,
|
||||||
writeType: "writeNoResponse",
|
writeType: "writeNoResponse",
|
||||||
value: value,
|
value: value,
|
||||||
success(res) {
|
|
||||||
console.log('writeBLECharacteristicValue success', JSON.stringify(res));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,6 +310,11 @@ class Bluetooth {
|
|||||||
});
|
});
|
||||||
return hexArr.join("").toLocaleLowerCase();
|
return hexArr.join("").toLocaleLowerCase();
|
||||||
}
|
}
|
||||||
|
unBindDevice() {
|
||||||
|
this.deviceInfo = {}
|
||||||
|
wx.removeStorageSync('deviceInfo')
|
||||||
|
this.closeBluetoothAdapter()
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 字符串插入字符
|
* 字符串插入字符
|
||||||
* @param {*} str 字符串
|
* @param {*} str 字符串
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import { useEffect, useRef, useState, useCallback } from "react";
|
|
||||||
import CryptoJS from "crypto-js";
|
import CryptoJS from "crypto-js";
|
||||||
import useStore from "@/store/index";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -69,3 +67,15 @@ export const debounce = (fn, time = 300) => {
|
|||||||
}, time);
|
}, time);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取页面的占
|
||||||
|
* @param {*} len
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getCurrentPages(len = 1) {
|
||||||
|
const pages = Taro.getCurrentPages();
|
||||||
|
const current = pages[pages.length - len];
|
||||||
|
const eventChannel = current.getOpenerEventChannel();
|
||||||
|
return eventChannel;
|
||||||
|
}
|
||||||
|
@ -61,12 +61,6 @@ export function asyncDate() {
|
|||||||
|
|
||||||
// -----------------获取---------------------
|
// -----------------获取---------------------
|
||||||
export function getInitData() {
|
export function getInitData() {
|
||||||
// 话筒音量
|
|
||||||
TASK.addTask(strInsert(`7B05EA05B100`));
|
|
||||||
|
|
||||||
// 音乐音量
|
|
||||||
TASK.addTask(strInsert(`7B05EA06B100`));
|
|
||||||
|
|
||||||
// 音源设置
|
// 音源设置
|
||||||
TASK.addTask(strInsert(`7B05EA07B100`));
|
TASK.addTask(strInsert(`7B05EA07B100`));
|
||||||
|
|
||||||
@ -76,22 +70,24 @@ export function getInitData() {
|
|||||||
// 声卡开关
|
// 声卡开关
|
||||||
TASK.addTask(strInsert(`7B05EA09B100`));
|
TASK.addTask(strInsert(`7B05EA09B100`));
|
||||||
|
|
||||||
// 播放模式
|
// 播放模式 (音乐模式)
|
||||||
TASK.addTask(strInsert(`7B05EA0AB100`));
|
TASK.addTask(strInsert(`7B05EA0AB100`));
|
||||||
|
|
||||||
// 音乐控制
|
|
||||||
TASK.addTask(strInsert(`7B05EA0BB100`));
|
|
||||||
|
|
||||||
// 超低音强度
|
// 超低音强度
|
||||||
TASK.addTask(strInsert(`7B05EA0CB100`));
|
TASK.addTask(strInsert(`7B05EA0CB100`));
|
||||||
|
|
||||||
// 混响模式
|
// 音乐音量
|
||||||
TASK.addTask(strInsert(`7B05EA0DB100`));
|
TASK.addTask(strInsert(`7B05EA06B100`));
|
||||||
|
|
||||||
// 话筒混响
|
// 话筒音量
|
||||||
|
TASK.addTask(strInsert(`7B05EA05B100`));
|
||||||
|
|
||||||
|
// 话筒混响音量
|
||||||
TASK.addTask(strInsert(`7B05EA0EB100`));
|
TASK.addTask(strInsert(`7B05EA0EB100`));
|
||||||
|
|
||||||
// AI
|
// 话筒混响模式
|
||||||
TASK.addTask(strInsert(`7B05EA11B100`));
|
TASK.addTask(strInsert(`7B05EA0DB100`));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
38
src/utils/taskQueue copy.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import BLESDK from './ble'
|
||||||
|
|
||||||
|
class taskQueue {
|
||||||
|
list = []
|
||||||
|
isExecute = false
|
||||||
|
overtime = null
|
||||||
|
|
||||||
|
addTask(buffer) {
|
||||||
|
if (!BLESDK.deviceInfo.state) return
|
||||||
|
this.list.push(buffer)
|
||||||
|
|
||||||
|
if (this.isExecute) return
|
||||||
|
this.executeTask()
|
||||||
|
}
|
||||||
|
|
||||||
|
executeTask() {
|
||||||
|
this.isExecute = !!this.list.length
|
||||||
|
if (!this.list.length) return
|
||||||
|
if (!BLESDK.deviceInfo.state) {
|
||||||
|
this.list = []
|
||||||
|
this.isExecute = !!this.list.length
|
||||||
|
return
|
||||||
|
}
|
||||||
|
BLESDK.writeBleValue(new Uint8Array([...this.list[0]]).buffer)
|
||||||
|
this.list.shift()
|
||||||
|
|
||||||
|
this.overtime = setTimeout(() => {
|
||||||
|
this.stopOverTime()
|
||||||
|
this.executeTask()
|
||||||
|
}, 800)
|
||||||
|
}
|
||||||
|
stopOverTime() {
|
||||||
|
clearTimeout(this.overtime)
|
||||||
|
this.overtime = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new taskQueue()
|