update:添加多项目
This commit is contained in:
parent
2e9154085b
commit
4c4c83c259
1
app.json
1
app.json
@ -48,6 +48,7 @@
|
||||
"train/user-report/user-report",
|
||||
"train/check-type/check-page",
|
||||
"train/train/train",
|
||||
"train/select-sport/select-sport",
|
||||
"bluebooth/search",
|
||||
"train/bluetooth/train",
|
||||
"train/result/result",
|
||||
|
||||
@ -51,7 +51,7 @@ page {
|
||||
}
|
||||
|
||||
.chose {
|
||||
margin: 34rpx 20rpx 0;
|
||||
margin: 64rpx 30rpx 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
/* background-color: brown; */
|
||||
@ -62,7 +62,7 @@ page {
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
|
||||
@ -75,8 +75,11 @@ page {
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
font-size: 24rpx;
|
||||
font-size: 26rpx;
|
||||
padding: 20rpx 0;
|
||||
margin: 26rpx 30rpx 20rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow:0 0 12px #0000000d;
|
||||
}
|
||||
|
||||
.lab-item {
|
||||
@ -87,10 +90,10 @@ page {
|
||||
}
|
||||
|
||||
.lab-img {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
/* margin-top: 20rpx; */
|
||||
margin-bottom: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.cell {
|
||||
@ -103,6 +106,7 @@ page {
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
margin: 20rpx 30rpx 0 30rpx;
|
||||
box-shadow:0 0 12px #0000000d;
|
||||
}
|
||||
|
||||
.left {
|
||||
|
||||
@ -147,10 +147,16 @@ Page({
|
||||
},
|
||||
|
||||
goTrainer(e){ //去训练
|
||||
console.log('aaaa')
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/train/train/train?type='+ e.currentTarget.id.replace('.png',''),
|
||||
})
|
||||
const type = e.currentTarget.id.replace('.png','')
|
||||
if(type === 'fit'){
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/train/select-sport/select-sport',
|
||||
})
|
||||
} else {
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/train/train/train?type=' + type,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
|
||||
@ -47,6 +47,8 @@ page{
|
||||
background: linear-gradient(180deg, #e8f5fd 0%, #fff 100%);
|
||||
/* height: 480rpx; */
|
||||
padding: 29rpx;
|
||||
box-shadow:0 0 12px #0000000d;
|
||||
|
||||
}
|
||||
|
||||
.goal{
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "3.7.12",
|
||||
"appid": "wx9d179138d229d06b",
|
||||
"projectname": "YZ-Ai-Sport-Native-Demo",
|
||||
"projectname": "跃动",
|
||||
"condition": {},
|
||||
"editorSetting": {
|
||||
"tabIndent": "insertSpaces",
|
||||
|
||||
@ -24,12 +24,19 @@
|
||||
"condition": {
|
||||
"miniprogram": {
|
||||
"list": [
|
||||
{
|
||||
"name": "subpackage/train/result/result",
|
||||
"pathName": "subpackage/train/result/result",
|
||||
"query": "type=time&count=0&time=3&theme=myself&isAi=true&sportType=%E4%BF%AF%E5%8D%A7%E6%92%91",
|
||||
"scene": null,
|
||||
"launchMode": "default"
|
||||
},
|
||||
{
|
||||
"name": "module-sport/pages/sport-full-screen",
|
||||
"pathName": "module-sport/pages/sport-full-screen",
|
||||
"query": "sportKey=Rope-Skipping&time=120&number=20&type=num&theme=homeWork&homeWorkId=51&groupNumber=2&timeout=3&music=https%3A%2F%2Fyuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com%2FUpload%2FBackgroundMusic%2FCarly%2520Rae%2520Jepsen-Turn%2520Me%2520Up.mp3",
|
||||
"scene": null,
|
||||
"launchMode": "default"
|
||||
"launchMode": "default",
|
||||
"scene": null
|
||||
},
|
||||
{
|
||||
"name": "subpackage/train/check-type/check-page",
|
||||
|
||||
@ -8,7 +8,12 @@ Page({
|
||||
connectedDeviceId: null,
|
||||
deviceServices: [],
|
||||
deviceCharacteristics: [],
|
||||
blueIsOk: false
|
||||
blueIsOk: false,
|
||||
battery: null,
|
||||
batteryLoading: false,
|
||||
deviceName: '',
|
||||
nameInput: '',
|
||||
nameLoading: false
|
||||
},
|
||||
|
||||
// 1. 初始化蓝牙模块
|
||||
@ -133,7 +138,7 @@ Page({
|
||||
wx.onBluetoothDeviceFound((res) => {
|
||||
console.log('发现新设备', res.devices);
|
||||
res.devices.forEach(device => {
|
||||
if (device.name == 'YD-Jump' || device.name == 'YD_Jump' || device.name == 'YD-O1' || device.localName == 'YD-O1' || device.localName == 'YD-Jump' || device.localName == 'YD_Jump') {
|
||||
if (device.name == 'YD-Jump' || device.name == 'YD_Jump' || device.name == 'YD-O1' || device.localName == 'YD-O1' || device.localName == 'YD-Jump' || device.localName == 'YD_Jump') {
|
||||
const exists = this.data.devices.find(d => d.deviceId === device.deviceId);
|
||||
if (!exists) {
|
||||
if (device.deviceId == last_device_id) {
|
||||
@ -190,7 +195,7 @@ Page({
|
||||
deviceId: device.deviceId,
|
||||
success: () => {
|
||||
console.log('连接成功', device.deviceId);
|
||||
console.log('连接成功', device);
|
||||
console.log('连接成功的设备信息:', JSON.stringify(device));
|
||||
wx.showToast({
|
||||
title: '连接成功',
|
||||
icon: 'success'
|
||||
@ -204,14 +209,20 @@ Page({
|
||||
wx.setStorageSync('device_id', device.deviceId)
|
||||
wx.setStorageSync('device_name', device.name)
|
||||
if (device.name == 'YD-O1') {
|
||||
wx.setStorageSync('uuid', device.advertisServiceUUIDs[0])
|
||||
const serviceId = device.advertisServiceUUIDs[0];
|
||||
wx.setStorageSync('uuid', serviceId)
|
||||
this.setupWriteAndNotify(device.deviceId, serviceId);
|
||||
} else {
|
||||
// 获取设备的服务
|
||||
wx.getBLEDeviceServices({
|
||||
deviceId: device.deviceId,
|
||||
success: (res) => {
|
||||
console.log('设备服务', res.services);
|
||||
wx.setStorageSync('uuid', res.services[0].uuid)
|
||||
// YD_Jump(下划线)使用 services[1],YD-Jump(短横线)使用 services[0]
|
||||
const serviceIndex = device.name === 'YD_Jump' ? 1 : 0;
|
||||
const serviceId = res.services[serviceIndex].uuid;
|
||||
wx.setStorageSync('uuid', serviceId)
|
||||
this.setupWriteAndNotify(device.deviceId, serviceId);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('获取服务失败', err);
|
||||
@ -373,6 +384,69 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
// 连接成功后获取特征值、存储写特征并建立通知监听
|
||||
setupWriteAndNotify(deviceId, serviceId) {
|
||||
wx.getBLEDeviceCharacteristics({
|
||||
deviceId,
|
||||
serviceId,
|
||||
success: (res) => {
|
||||
const writeChar = res.characteristics.find(c => c.properties.write || c.properties.writeNoResponse);
|
||||
if (writeChar) {
|
||||
wx.setStorageSync('writeCharacteristic', writeChar.uuid);
|
||||
}
|
||||
const notifyChar = res.characteristics.find(c => c.properties.notify);
|
||||
if (notifyChar) {
|
||||
wx.notifyBLECharacteristicValueChange({
|
||||
deviceId,
|
||||
serviceId,
|
||||
characteristicId: notifyChar.uuid,
|
||||
state: true,
|
||||
});
|
||||
wx.onBLECharacteristicValueChange((result) => {
|
||||
const deviceName = wx.getStorageSync('device_name');
|
||||
if (deviceName === 'YD-O1') {
|
||||
// YD-O1: 二进制协议解析电量响应
|
||||
const int16Array = new Int16Array(result.value);
|
||||
if (int16Array.length > 0) {
|
||||
const battery = int16Array[0]; // 根据实际协议调整字段索引
|
||||
if (battery >= 0 && battery <= 100) {
|
||||
this.setData({ battery, batteryLoading: false });
|
||||
wx.hideLoading();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// YD_Jump / YD-Jump: 字符串协议解析 $Batt,xx!
|
||||
const bytes = new Uint8Array(result.value);
|
||||
let str = '';
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
str += String.fromCharCode(bytes[i]);
|
||||
}
|
||||
console.log('收到蓝牙数据:', str);
|
||||
// 解析电量响应 $Batt,xx!
|
||||
const battMatch = str.match(/\$Batt,(\d+)!/);
|
||||
if (battMatch) {
|
||||
this.setData({ battery: parseInt(battMatch[1], 10), batteryLoading: false });
|
||||
wx.hideLoading();
|
||||
}
|
||||
// 解析获取名称响应 $My Name:xxxxxxxx!
|
||||
const nameMatch = str.match(/\$My Name:(.+)!/);
|
||||
if (nameMatch) {
|
||||
this.setData({ deviceName: nameMatch[1].trim(), nameLoading: false });
|
||||
wx.hideLoading();
|
||||
}
|
||||
// 解析修改名称响应 $Set Name OK!
|
||||
if (str.includes('$Set Name OK!')) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '名称修改成功', icon: 'success' });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => console.error('获取特征值失败', err)
|
||||
});
|
||||
},
|
||||
|
||||
// 4. 断开连接
|
||||
disconnectDevice(id) {
|
||||
wx.closeBLEConnection({
|
||||
@ -381,9 +455,145 @@ Page({
|
||||
console.log('断开连接');
|
||||
this.setData({
|
||||
status: '未连接',
|
||||
connected: false
|
||||
connected: false,
|
||||
battery: null,
|
||||
batteryLoading: false,
|
||||
deviceName: '',
|
||||
nameInput: '',
|
||||
nameLoading: false
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 5. 获取设备电量(按设备类型发送不同协议命令)
|
||||
getBattery() {
|
||||
if (!this.data.connected || !this.data.connectedDeviceId) {
|
||||
wx.showToast({ title: '请先连接设备', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const characteristic = wx.getStorageSync('writeCharacteristic');
|
||||
if (!characteristic) {
|
||||
wx.showToast({ title: '特征值未就绪,请重新连接', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const deviceId = this.data.connectedDeviceId;
|
||||
const serviceId = wx.getStorageSync('uuid');
|
||||
const deviceName = wx.getStorageSync('device_name');
|
||||
|
||||
wx.showLoading({ title: '获取电量中...' });
|
||||
this.setData({ batteryLoading: true });
|
||||
|
||||
let commandData;
|
||||
if (deviceName === 'YD-O1') {
|
||||
// YD-O1: 二进制协议获取电量
|
||||
commandData = new ArrayBuffer(4);
|
||||
const dataView = new DataView(commandData);
|
||||
dataView.setUint8(0, 0x07); // 获取电量命令字节
|
||||
dataView.setUint8(1, 0x00);
|
||||
dataView.setUint8(2, 0x00);
|
||||
dataView.setUint8(3, 0x00);
|
||||
} else {
|
||||
// YD_Jump / YD-Jump: 字符串协议获取电量
|
||||
commandData = this.stringToArrayBuffer('$Get Batt!');
|
||||
}
|
||||
|
||||
wx.writeBLECharacteristicValue({
|
||||
deviceId,
|
||||
serviceId,
|
||||
characteristicId: characteristic,
|
||||
value: commandData,
|
||||
success: () => {
|
||||
console.log(`${deviceName} 发送获取电量命令成功`);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('发送命令失败', err);
|
||||
wx.hideLoading();
|
||||
this.setData({ batteryLoading: false });
|
||||
wx.showToast({ title: '发送命令失败', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 获取设备名称
|
||||
getDeviceName() {
|
||||
if (!this.data.connected || !this.data.connectedDeviceId) {
|
||||
wx.showToast({ title: '请先连接设备', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const characteristic = wx.getStorageSync('writeCharacteristic');
|
||||
if (!characteristic) {
|
||||
wx.showToast({ title: '特征值未就绪,请重新连接', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const deviceId = this.data.connectedDeviceId;
|
||||
const serviceId = wx.getStorageSync('uuid');
|
||||
wx.showLoading({ title: '获取名称中...' });
|
||||
this.setData({ nameLoading: true });
|
||||
wx.writeBLECharacteristicValue({
|
||||
deviceId,
|
||||
serviceId,
|
||||
characteristicId: characteristic,
|
||||
value: this.stringToArrayBuffer('$Get Name!'),
|
||||
success: () => console.log('发送获取名称命令成功'),
|
||||
fail: (err) => {
|
||||
console.error('发送命令失败', err);
|
||||
wx.hideLoading();
|
||||
this.setData({ nameLoading: false });
|
||||
wx.showToast({ title: '发送命令失败', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 修改设备名称(名称不足8位用空格填充,超过8位截断)
|
||||
setDeviceName() {
|
||||
if (!this.data.connected || !this.data.connectedDeviceId) {
|
||||
wx.showToast({ title: '请先连接设备', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const nameInput = this.data.nameInput.trim();
|
||||
if (!nameInput) {
|
||||
wx.showToast({ title: '请输入新名称', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const characteristic = wx.getStorageSync('writeCharacteristic');
|
||||
if (!characteristic) {
|
||||
wx.showToast({ title: '特征值未就绪,请重新连接', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const deviceId = this.data.connectedDeviceId;
|
||||
const serviceId = wx.getStorageSync('uuid');
|
||||
// 名称固定8字节:不足补空格,超过截断
|
||||
const paddedName = nameInput.padEnd(8, ' ').substring(0, 8);
|
||||
const cmd = `$Set Name:${paddedName}!`;
|
||||
console.log('发送修改名称命令:', cmd);
|
||||
wx.showLoading({ title: '修改名称中...' });
|
||||
wx.writeBLECharacteristicValue({
|
||||
deviceId,
|
||||
serviceId,
|
||||
characteristicId: characteristic,
|
||||
value: this.stringToArrayBuffer(cmd),
|
||||
success: () => console.log('修改名称命令已发送:', cmd),
|
||||
fail: (err) => {
|
||||
console.error('发送命令失败', err);
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '发送命令失败', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 名称输入框变化
|
||||
onNameInput(e) {
|
||||
this.setData({ nameInput: e.detail.value });
|
||||
},
|
||||
|
||||
// 字符串转 ArrayBuffer(与 bluetoothServe.js 保持一致)
|
||||
stringToArrayBuffer(str) {
|
||||
const buffer = new ArrayBuffer(str.length);
|
||||
const view = new Uint8Array(buffer);
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
view[i] = str.charCodeAt(i) & 0xFF;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
});
|
||||
@ -44,4 +44,44 @@
|
||||
|
||||
<!-- 断开连接按钮 -->
|
||||
<!-- <button bindtap="disconnectDevice" wx:if="{{connected}}">断开连接</button> -->
|
||||
|
||||
<!-- 获取电量 -->
|
||||
<view class="battery-section" wx:if="{{connected}}">
|
||||
<view class="titlee">
|
||||
<view class="titlee-before"></view>设备电量
|
||||
</view>
|
||||
<view class="battery-card">
|
||||
<view class="battery-display" wx:if="{{battery !== null}}">
|
||||
<view class="battery-icon-wrap">
|
||||
<view class="battery-icon">
|
||||
<view class="battery-level" style="width: {{battery}}%;"></view>
|
||||
</view>
|
||||
<view class="battery-cap"></view>
|
||||
</view>
|
||||
<text class="battery-percent">{{battery}}%</text>
|
||||
</view>
|
||||
<view class="battery-placeholder" wx:else>
|
||||
<text>--</text>
|
||||
</view>
|
||||
<button class="battery-btn" bindtap="getBattery" loading="{{batteryLoading}}">获取电量</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 设备名称管理 -->
|
||||
<view class="name-section" wx:if="{{connected}}">
|
||||
<view class="titlee">
|
||||
<view class="titlee-before"></view>设备名称
|
||||
</view>
|
||||
<view class="name-card">
|
||||
<view class="name-info">
|
||||
<text class="name-label">当前名称</text>
|
||||
<text class="name-value">{{deviceName || '--'}}</text>
|
||||
</view>
|
||||
<button class="name-action-btn" bindtap="getDeviceName" loading="{{nameLoading}}">获取名称</button>
|
||||
</view>
|
||||
<view class="name-edit-card">
|
||||
<input class="name-input" placeholder="输入新名称(最多8位)" maxlength="8" value="{{nameInput}}" bindinput="onNameInput" />
|
||||
<button class="name-action-btn" bindtap="setDeviceName">修改名称</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -166,3 +166,149 @@ button {
|
||||
margin-top: 20rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
/* 电量区域 */
|
||||
.battery-section {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.battery-card {
|
||||
margin: 0 30rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 10rpx 10rpx rgba(0, 0, 0, 0.06);
|
||||
padding: 40rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.battery-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.battery-placeholder {
|
||||
font-size: 60rpx;
|
||||
color: #ccc;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.battery-icon-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.battery-icon {
|
||||
width: 80rpx;
|
||||
height: 40rpx;
|
||||
border: 4rpx solid #333;
|
||||
border-radius: 6rpx;
|
||||
padding: 4rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: #f5f5f5;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.battery-level {
|
||||
height: 100%;
|
||||
border-radius: 3rpx;
|
||||
background: linear-gradient(90deg, #4cd964, #26a5f6);
|
||||
transition: width 0.4s ease;
|
||||
}
|
||||
|
||||
.battery-cap {
|
||||
width: 8rpx;
|
||||
height: 18rpx;
|
||||
background-color: #333;
|
||||
border-radius: 0 3rpx 3rpx 0;
|
||||
margin-left: 2rpx;
|
||||
}
|
||||
|
||||
.battery-percent {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.battery-btn {
|
||||
margin: 0 !important;
|
||||
padding: 0 30rpx !important;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
font-size: 26rpx;
|
||||
background-color: #007aff;
|
||||
color: white;
|
||||
border-radius: 50rpx;
|
||||
min-width: 160rpx;
|
||||
}
|
||||
|
||||
/* 名称管理区域 */
|
||||
.name-section {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.name-card {
|
||||
margin: 0 30rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 10rpx 10rpx rgba(0, 0, 0, 0.06);
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.name-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.name-label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.name-value {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.name-action-btn {
|
||||
margin: 0 !important;
|
||||
padding: 0 30rpx !important;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
font-size: 26rpx;
|
||||
background-color: #007aff;
|
||||
color: white;
|
||||
border-radius: 50rpx;
|
||||
min-width: 160rpx;
|
||||
}
|
||||
|
||||
.name-edit-card {
|
||||
margin: 0 30rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 10rpx 10rpx rgba(0, 0, 0, 0.06);
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.name-input {
|
||||
flex: 1;
|
||||
height: 70rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@ -4,10 +4,11 @@ const COMMAND = {
|
||||
PAUSE: 0x04,
|
||||
RESUME: 0x05,
|
||||
STOP: 0x06,
|
||||
GET_COUNT: 'Get CT',
|
||||
GET_COUNT: 'Get CT',
|
||||
START_COUNT: 'Start Count',
|
||||
STOP_COUNT: 'Stop Count',
|
||||
CLEAN_COUNT: 'Clean Count'
|
||||
CLEAN_COUNT: 'Clean Count',
|
||||
GET_BATTERY: 'Get Batt'
|
||||
};
|
||||
|
||||
const DEVICE_TYPE = {
|
||||
@ -73,9 +74,40 @@ function stringToArrayBuffer(str) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// 获取设备电量,根据设备型号发送不同协议的命令
|
||||
function getBattery(deviceId, serviceId, deviceName) {
|
||||
const characteristic = wx.getStorageSync('writeCharacteristic');
|
||||
if (!characteristic) {
|
||||
console.error('没有可写的特征值');
|
||||
return;
|
||||
}
|
||||
|
||||
if (deviceName === DEVICE_TYPE.YD_O1) {
|
||||
// YD-O1:二进制协议获取电量
|
||||
const commandData = new ArrayBuffer(4);
|
||||
const dataView = new DataView(commandData);
|
||||
dataView.setUint8(0, 0x07); // 获取电量命令字节
|
||||
dataView.setUint8(1, 0x00);
|
||||
dataView.setUint8(2, 0x00);
|
||||
dataView.setUint8(3, 0x00);
|
||||
wx.writeBLECharacteristicValue({
|
||||
deviceId,
|
||||
serviceId,
|
||||
characteristicId: characteristic,
|
||||
value: commandData,
|
||||
success: () => console.log('YD-O1 获取电量命令已发送'),
|
||||
fail: err => console.error('YD-O1 获取电量命令失败', err)
|
||||
});
|
||||
} else {
|
||||
// YD_Jump / YD-Jump:字符串协议获取电量
|
||||
sendCommandJump(deviceId, serviceId, COMMAND.GET_BATTERY);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
COMMAND,
|
||||
DEVICE_TYPE,
|
||||
startFreeJumpRope,
|
||||
sendCommandJump
|
||||
sendCommandJump,
|
||||
getBattery
|
||||
};
|
||||
@ -58,7 +58,7 @@ Page({
|
||||
})
|
||||
|
||||
if (who == 'user') { //用户端仅有跳绳======================================================================================
|
||||
if (theme == 'team') {
|
||||
if (theme == 'team') {
|
||||
//2.添加团队任务成绩
|
||||
const {
|
||||
data
|
||||
@ -77,14 +77,23 @@ Page({
|
||||
//1.添加个人目标成绩
|
||||
const app = getApp()
|
||||
console.log(app)
|
||||
console.log('自由训练')
|
||||
const homeWorkList = await getHomeWorkType()
|
||||
const sportObj = homeWorkList.data.filter(item => item.name == options.sportType)
|
||||
let isTime = options.type == 'time'
|
||||
let calorie = isTime ? options.count * sportObj[0].kcalIndex : amount * sportObj[0].kcalIndex * groupNumber
|
||||
let params = {
|
||||
"personalGoalName": this.data.theme == 'small' ? '小学体测' : this.data.theme == 'fit' ? '健身减肥' : '中学考试',
|
||||
"workModeType": 1,
|
||||
"workModeTypeName": this.data.theme == 'small' ? '小学体测' : this.data.theme == 'fit' ? '健身减肥' : '中学考试',
|
||||
"workType": sportObj[0].id,
|
||||
"workTypeName": sportType,
|
||||
"workModeType": isTime ? 1 : 2,
|
||||
"workModeTypeName": isTime ? '定时计数' : this.data.type == 'num' ? '定数计时' : '自由训练',
|
||||
"duration": time,
|
||||
"amount": count,
|
||||
"PersonalGoalType": this.data.theme == 'small' ? 2 : this.data.theme == 'fit' ? 1 : 2,
|
||||
"dataSourceType": isAi == 'true' ? 2 : 1
|
||||
"dataSourceType": isAi == 'true' ? 2 : 1,
|
||||
"calorie":calorie,
|
||||
"startTime":this.getCurrentDateTime(),
|
||||
"endTime":this.getCurrentDateTime(),
|
||||
"groupNumber":1
|
||||
}
|
||||
if (this.data.theme == 'small') {
|
||||
const dd = await getSmallScore({
|
||||
@ -165,7 +174,7 @@ Page({
|
||||
console.log(params)
|
||||
const res = await postParentTrain(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
39
subpackage/train/select-sport/select-sport.js
Normal file
39
subpackage/train/select-sport/select-sport.js
Normal file
@ -0,0 +1,39 @@
|
||||
const { sportKeyList } = require('../../../utils/soprt-key');
|
||||
|
||||
const sportEmojiMap = {
|
||||
'Rope-Skipping': '🪢',
|
||||
'Jumping-Jack': '🤸',
|
||||
'Sit-Up': '💪',
|
||||
'Push-Up': '🏋️',
|
||||
'Squat': '🦵',
|
||||
'Plank': '⚡',
|
||||
'High-Knee': '🏃',
|
||||
'Sit-Forward-Bend': '🧘',
|
||||
};
|
||||
|
||||
const colorClasses = ['c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7'];
|
||||
|
||||
Page({
|
||||
data: {
|
||||
sportList: []
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
const excluded = ['Squat-Horse', 'Crunch'];
|
||||
const sportList = sportKeyList
|
||||
.filter(item => !excluded.includes(item.key))
|
||||
.map((item, index) => ({
|
||||
...item,
|
||||
emoji: sportEmojiMap[item.key] || '🏃',
|
||||
colorClass: colorClasses[index % colorClasses.length],
|
||||
}));
|
||||
this.setData({ sportList });
|
||||
},
|
||||
|
||||
selectSport(e) {
|
||||
const sportKey = e.currentTarget.id;
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/train/train/train?type=fit&sportKey=' + sportKey,
|
||||
});
|
||||
}
|
||||
});
|
||||
8
subpackage/train/select-sport/select-sport.json
Normal file
8
subpackage/train/select-sport/select-sport.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"mp-bar": "weui-miniprogram/navigation-bar/navigation-bar"
|
||||
},
|
||||
"navigationStyle": "custom",
|
||||
"backgroundColor": "#f0f5ff",
|
||||
"backgroundColorContent": "#f0f5ff"
|
||||
}
|
||||
55
subpackage/train/select-sport/select-sport.wxml
Normal file
55
subpackage/train/select-sport/select-sport.wxml
Normal file
@ -0,0 +1,55 @@
|
||||
<view class="page page-content">
|
||||
<mp-bar background="linear-gradient(190deg, #49a5fc 0%, #f7f7f7 800rpx, #f7f7f7 100%)" title="选择运动" color="#fff"></mp-bar>
|
||||
<view class="play">
|
||||
<view class="play-text">
|
||||
<view class="text-style">
|
||||
一键开启
|
||||
<view class="text-line"></view>
|
||||
</view>
|
||||
<view>定制专属你的减脂蜕变</view>
|
||||
</view>
|
||||
<image src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/user-play.png" class="logo-play" />
|
||||
</view>
|
||||
|
||||
<view class="tab {{theme=='fit'?'tab-fit':''}}">
|
||||
<view class="tab-l">
|
||||
<view class="tab-l-content">{{
|
||||
theme=='small'?'小学体测':theme=='mid'?'中学考试':'健身减肥'
|
||||
}}</view>
|
||||
</view>
|
||||
<view class="tab-r" bind:tap="goSetting">
|
||||
<view class="tab-r-content">
|
||||
<mp-icon icon="setting" class="iconn" color="#fff" type="field" size="{{16}}"></mp-icon>
|
||||
运动偏好
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 2 列卡片网格 -->
|
||||
<view class="card1">
|
||||
<view class="grid">
|
||||
<view
|
||||
class="card {{item.colorClass}}"
|
||||
wx:for="{{sportList}}"
|
||||
wx:key="key"
|
||||
id="{{item.key}}"
|
||||
bind:tap="selectSport"
|
||||
>
|
||||
<view class="card-circle-1"></view>
|
||||
<view class="card-circle-2"></view>
|
||||
<!-- <view class="card-emoji-wrap">
|
||||
<image src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/teacher/icon/{{item.key}}.png" alt=""/>
|
||||
</view> -->
|
||||
<view class="card-bottom">
|
||||
<view class="card-name">{{item.name}}</view>
|
||||
<view class="card-arrow-circle">
|
||||
<text class="card-arrow-text">›</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
357
subpackage/train/select-sport/select-sport.wxss
Normal file
357
subpackage/train/select-sport/select-sport.wxss
Normal file
@ -0,0 +1,357 @@
|
||||
page{
|
||||
background-color: rgb(247, 247, 247);
|
||||
}
|
||||
|
||||
.page-content{
|
||||
background-color: rgb(247, 247, 247);
|
||||
background: linear-gradient(190deg, #49a5fc 0%, #f7f7f7 800rpx, #f7f7f7 100%);
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding-bottom: 80rpx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ===== 头部 ===== */
|
||||
.header {
|
||||
/* background: linear-gradient(160deg, #0d1f3c 0%, #0d2a55 100%); */
|
||||
padding: 0 44rpx 52rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header-glow {
|
||||
position: absolute;
|
||||
width: 500rpx;
|
||||
height: 500rpx;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(0,130,255,0.2) 0%, transparent 70%);
|
||||
top: -180rpx;
|
||||
right: -120rpx;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-top: 6rpx;
|
||||
}
|
||||
|
||||
.header-kicker {
|
||||
font-size: 22rpx;
|
||||
color: #4fc3f7;
|
||||
letter-spacing: 3rpx;
|
||||
margin-bottom: 18rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 58rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
line-height: 1.15;
|
||||
margin-bottom: 22rpx;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.header-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14rpx;
|
||||
font-size: 24rpx;
|
||||
color: rgba(255,255,255,0.45);
|
||||
}
|
||||
|
||||
.meta-dot {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 50%;
|
||||
background: #4fc3f7;
|
||||
opacity: 0.7;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ===== 2列卡片网格 ===== */
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 28rpx;
|
||||
padding: 30rpx 0 ;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 单张卡片 */
|
||||
.card {
|
||||
border-radius: 22rpx;
|
||||
padding: 28rpx 24rpx 24rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* height: 272rpx; */
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.card:active {
|
||||
opacity: 0.82;
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
/* 卡片内装饰圆 */
|
||||
.card-circle-1 {
|
||||
position: absolute;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
top: -80rpx;
|
||||
right: -60rpx;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.card-circle-2 {
|
||||
position: absolute;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
bottom: -30rpx;
|
||||
left: -20rpx;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* emoji 区域:占据卡片中局上半部分 */
|
||||
.card-emoji-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.card-emoji-wrap image {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
|
||||
.card-emoji {
|
||||
font-size: 80rpx;
|
||||
line-height: 1;
|
||||
filter: drop-shadow(0 4rpx 8rpx rgba(0, 0, 0, 0.15));
|
||||
}
|
||||
|
||||
/* 底部:名称 + 箭头同一行 */
|
||||
.card-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.card-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
text-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.card-arrow-circle {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card-arrow-text {
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
margin-top: -2rpx;
|
||||
padding-left: 2rpx;
|
||||
}
|
||||
|
||||
/* ===== 8种卡片颜色 ===== */
|
||||
.c0 { background: linear-gradient(140deg, #ff6b6b 0%, #ee2d2d98 100%); }
|
||||
.c1 { background: linear-gradient(140deg, #ffa340 0%, #f0600098 100%); }
|
||||
.c2 { background: linear-gradient(140deg, #20c997 0%, #0a8f6098 100%); }
|
||||
.c3 { background: linear-gradient(140deg, #a855f7 0%, #6d28d998 100%); }
|
||||
.c4 { background: linear-gradient(140deg, #3b82f6 0%, #1d4ed898 100%); }
|
||||
.c5 { background: linear-gradient(140deg, #06b6d4 0%, #0284c798 100%); }
|
||||
.c6 { background: linear-gradient(140deg, #f43f8e 0%, #be185d98 100%); }
|
||||
.c7 { background: linear-gradient(140deg, #34d399 0%, #05966998 100%); }
|
||||
|
||||
|
||||
|
||||
.title{
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 66rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title-before{
|
||||
height: 24rpx;
|
||||
border-radius: 6rpx;
|
||||
width: 6rpx;
|
||||
margin-right: 20rpx;
|
||||
background:linear-gradient(180.00deg, rgb(38, 165, 246),rgba(38, 165, 246, 0) 100%)
|
||||
}
|
||||
|
||||
.play{
|
||||
padding: 0 30rpx 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
/* margin-bottom: -170rpx; */
|
||||
/* min-height: 428rpx; */
|
||||
height: 350rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.logo-play{
|
||||
margin-right: -82rpx;
|
||||
width: 428rpx;
|
||||
height: 428rpx;
|
||||
/* z-index: 1; */
|
||||
/* overflow: hidden; */
|
||||
}
|
||||
|
||||
.play-text{
|
||||
font-size: 28rpx;
|
||||
padding-top: 70rpx;
|
||||
}
|
||||
|
||||
.text-style{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text-line{
|
||||
height: 16rpx;
|
||||
background-color: #FFC20E;
|
||||
border-radius: 10rpx;
|
||||
width: 110rpx;
|
||||
margin-top: -18rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.tab{
|
||||
width: 536rpx;
|
||||
display: flex;
|
||||
height: 80rpx;
|
||||
font-size: 28rpx;
|
||||
margin-top: -80rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab-l{
|
||||
flex: 1;
|
||||
background-color: rgba(38, 165, 246, 1);
|
||||
/* backdrop-filter: blur(20rpx); */
|
||||
border-radius: 20rpx 0 0 0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.tab-l-content{
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx 38rpx 0 0;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tab-r{
|
||||
flex: 1;
|
||||
background:linear-gradient(90deg,rgba(255,255,255,1) 0%, rgba(255,255,255,.6) 30%) ;
|
||||
border-radius: 0 20rpx 0 0rpx;
|
||||
|
||||
}
|
||||
|
||||
.tab-r-content{
|
||||
background: linear-gradient(90deg, rgba(38, 165, 246, 1) 0%, rgba(38, 165, 246, 0.7) 50%,
|
||||
rgba(38, 165, 246, 0.7) 100%);
|
||||
border-radius: 0 20rpx 0 38rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card1{
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
padding: 16rpx 18rpx 24rpx;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.iconn{
|
||||
margin-right: 6rpx;
|
||||
margin-top: -6rpx;
|
||||
}
|
||||
|
||||
.cell{
|
||||
padding: 44rpx 4rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.left{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.left-img{
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-right: 26rpx;
|
||||
}
|
||||
|
||||
.desc{
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
max-width: 60%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.name{
|
||||
margin-top: 4rpx;
|
||||
font-size: 24rpx;
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
.right{
|
||||
border-radius: 75px;
|
||||
background: rgb(38, 166, 246);
|
||||
padding: 12rpx 0rpx;
|
||||
width: 120rpx;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
width: 160rpx;
|
||||
min-width: 160rpx;
|
||||
}
|
||||
|
||||
.use{
|
||||
color: rgb(38, 166, 246);
|
||||
background-color: #fff;
|
||||
border: 2rpx solid rgb(38, 166, 246);
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
const tabService = require("../../../utils/tab-serve");
|
||||
const util = require("../../../utils/utils")
|
||||
const { sportKeyObj, sportDes } = require('../../../utils/soprt-key')
|
||||
import {getAreaList} from "../../../utils/serve/train"
|
||||
const app = getApp()
|
||||
Page({
|
||||
@ -14,6 +15,10 @@ Page({
|
||||
number: 100, //计数
|
||||
timeStr:'01:00',
|
||||
theme:'small',
|
||||
sportKey: '',
|
||||
sportName: '',
|
||||
sportDesc: '',
|
||||
videoUrl: '',
|
||||
gradeList:[
|
||||
'一年级',
|
||||
'二年级',
|
||||
@ -34,8 +39,16 @@ Page({
|
||||
*/
|
||||
async onLoad(options) {
|
||||
this.setData({
|
||||
theme:options.type
|
||||
theme: options.type
|
||||
})
|
||||
if (options.sportKey) {
|
||||
this.setData({
|
||||
sportKey: options.sportKey,
|
||||
sportName: sportKeyObj[options.sportKey] || '',
|
||||
sportDesc: sportDes[options.sportKey] || '',
|
||||
videoUrl: 'https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/train/video/new/' + options.sportKey + '.mp4',
|
||||
})
|
||||
}
|
||||
if(options.type == 'mid'){
|
||||
const res = await getAreaList()
|
||||
this.setData({
|
||||
@ -132,12 +145,17 @@ Page({
|
||||
if(this.data.sex == '' && this.data.theme != 'fit') return app.showToast('请选择性别')
|
||||
if(this.data.theme == 'small' && this.data.grade == '') return app.showToast('请选择年级')
|
||||
if(this.data.theme == 'mid' && this.data.areaId == '') return app.showToast('请选择省份')
|
||||
console.log(getApp())
|
||||
const data = `&type=${this.data.tabName}&time=${this.data.time}&number=${this.data.number}&theme=${this.data.theme}`
|
||||
wx.navigateTo({
|
||||
// url: '/module-sport/pages/sport-full-screen?sportKey=Rope-Skipping'+data,
|
||||
url: '/subpackage/train/check-type/check-page?sportKey=Rope-Skipping'+data,
|
||||
})
|
||||
const sportKey = this.data.sportKey || 'Rope-Skipping'
|
||||
const data = `&type=${this.data.tabName}&time=${this.data.time}&number=${this.data.number}&theme=myself`
|
||||
if(this.data.sportKey == 'Rope-Skipping' ){
|
||||
wx.navigateTo({
|
||||
url: '/subpackage/train/check-type/check-page?sportKey=' + this.data.sportKey + data,
|
||||
})
|
||||
}else{
|
||||
wx.navigateTo({
|
||||
url: '/module-sport/pages/sport-full-screen?sportKey=' + this.data.sportKey + data,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
handleCancel() {
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
<view class="page-content">
|
||||
<mp-bar background="linear-gradient(190deg, #49a5fc 0%, #f7f7f7 800rpx, #f7f7f7 100%)" title="训练"></mp-bar>
|
||||
|
||||
<view class="play">
|
||||
<!-- 非健身减肥模式:展示原来的 banner -->
|
||||
<view class="play" wx:if="{{theme != 'fit'}}">
|
||||
<view class="play-text">
|
||||
<view class="text-style">
|
||||
一键开启
|
||||
@ -12,7 +13,35 @@
|
||||
<image src="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/user-play.png" class="logo-play" />
|
||||
</view>
|
||||
|
||||
<view class="tab">
|
||||
<!-- 健身减肥模式:展示运动演示视频 -->
|
||||
<view class="play-fit" wx:if="{{theme == 'fit'}}">
|
||||
<view class="play-fit-header">
|
||||
<view class="play-fit-name">{{sportName}}</view>
|
||||
<view class="play-fit-tag">健身减肥</view>
|
||||
</view>
|
||||
<view class="video-wrap">
|
||||
<video
|
||||
class="sport-video"
|
||||
src="{{videoUrl}}"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
show-play-btn="{{true}}"
|
||||
show-fullscreen-btn="{{true}}"
|
||||
object-fit="cover"
|
||||
poster="https://yuedong-wechatapplet.oss-cn-shanghai.aliyuncs.com/static/user-play.png"
|
||||
></video>
|
||||
</view>
|
||||
<view class="sport-desc-card" wx:if="{{sportDesc}}">
|
||||
<view class="sport-desc-title">
|
||||
<!-- <view class="desc-icon"></view> -->
|
||||
动作说明
|
||||
</view>
|
||||
<view class="sport-desc-text">{{sportDesc}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view class="tab {{theme=='fit'?'tab-fit':''}}">
|
||||
<view class="tab-l">
|
||||
<view class="tab-l-content">{{
|
||||
theme=='small'?'小学体测':theme=='mid'?'中学考试':'健身减肥'
|
||||
@ -24,7 +53,7 @@
|
||||
运动偏好
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<view class="card">
|
||||
<block wx:if="{{theme == 'fit'}}">
|
||||
|
||||
@ -74,6 +74,10 @@ page{
|
||||
margin-top: -80rpx;
|
||||
}
|
||||
|
||||
.tab-fit {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.tab-l{
|
||||
flex: 1;
|
||||
background-color: rgba(38, 165, 246, 1);
|
||||
@ -114,10 +118,10 @@ page{
|
||||
min-height: 1000rpx;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-radius: 0 20rpx 20rpx 20rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 60rpx 100rpx;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 1px 1px 4px 0px rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 1px 1px 4px 2px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.iconn{
|
||||
@ -223,5 +227,76 @@ page{
|
||||
.click{
|
||||
color: #0082FF;
|
||||
background-color: #e9f6fe;
|
||||
}
|
||||
|
||||
}
|
||||
/* ===== 健身减肥模式 - 视频展示区 ===== */
|
||||
.play-fit {
|
||||
/* padding: 0 30rpx; */
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.play-fit-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24rpx 0 20rpx 0;
|
||||
}
|
||||
|
||||
.play-fit-name {
|
||||
font-size: 44rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.play-fit-tag {
|
||||
font-size: 22rpx;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
border-radius: 20rpx;
|
||||
padding: 6rpx 20rpx;
|
||||
backdrop-filter: blur(10rpx);
|
||||
}
|
||||
|
||||
.video-wrap {
|
||||
width: 100%;
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 130, 255, 0.2);
|
||||
/* background: #000; */
|
||||
}
|
||||
|
||||
.sport-video {
|
||||
width: 100%;
|
||||
height: 400rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sport-desc-card {
|
||||
margin-top: 20rpx;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 20rpx;
|
||||
padding: 28rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 130, 255, 0.1);
|
||||
}
|
||||
|
||||
.sport-desc-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.desc-icon {
|
||||
margin-right: 10rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.sport-desc-text {
|
||||
font-size: 26rpx;
|
||||
color: #555;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
@ -56,8 +56,23 @@ let sportKeyObj = {
|
||||
"Sit-Forward-Bend":"坐位体前屈",
|
||||
}
|
||||
|
||||
let sportDes = {
|
||||
"Rope-Skipping":"双手打开与肩同宽或稍宽,手指指向前方,手掌平放在地面上,确保双手稳定支撑身体。慢慢弯曲手肘,使身体逐渐下降,下降至胸部几乎贴近地面时停止,伸臂起身还原。",
|
||||
"Jumping-Jack":"双脚掌蹬地跳起,打开双脚与肩同宽,双手举过头顶击掌落地。.面正对手机,保持在图像中间。",
|
||||
"Sit-Up":"手臂抱头于头部两侧,脚底并拢,脚跟靠近臀部,腹肌发力起身,下放时背部、肩部、头部依次着地。",
|
||||
"Push-Up":"双手打开与肩同宽或稍宽,手指指向前方,手掌平放在地面上,确保双手稳定支撑身体。慢慢弯曲手肘,使身体逐渐下降,下降至胸部几乎贴近地面时停止,伸臂起身还原。",
|
||||
"Crunch":"",
|
||||
"Squat":"双脚分开与肩同宽或略宽,脚尖可以稍微外展(约30度),在保持背部挺直的前提下,慢慢屈膝下蹲至髌骨顶端所在的水平面,再缓慢起身。",
|
||||
"Plank":"俯身面对地面,屈肘,前臂平放在地面上,确保手肘与肩膀处于同一垂直线上,双腿伸直,双脚并拢或稍微分开,使身体从头到脚呈一条直线。在整个平板支撑过程中,需要保持腹部肌肉持续收紧,这有助于维持身体的稳定性和平衡性",
|
||||
"High-Knee":"双脚与肩同宽,身体保持直立,保持腹部收紧,前脚掌着地快速交替抬腿。在整个动作过程中,保持身体直立且稳定,避免晃动或摇摆。",
|
||||
"Squat-Horse":"马步蹲",
|
||||
"Sit-Forward-Bend":"坐位体前屈",
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
sportKeyList,
|
||||
sportNameObj,
|
||||
sportKeyObj
|
||||
sportKeyObj,
|
||||
sportDes
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user