3024 lines
103 KiB
HTML
Executable File
3024 lines
103 KiB
HTML
Executable File
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||
/>
|
||
|
||
<title>Control Panel</title>
|
||
{% if mode == 'handheld' %}
|
||
<style>
|
||
/* 初始隐藏状态 */
|
||
.status-container .status-card:nth-child(1),
|
||
.status-container .status-card:nth-child(2),
|
||
#strength-card {
|
||
display: none;
|
||
}
|
||
</style>
|
||
{% endif %}
|
||
<script src="{{ url_for('static', filename='js/socketio/socket.io.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/license_module.js') }}"></script>
|
||
<link rel="stylesheet" href="/static/css/swiper-bundle.min.css" />
|
||
<script src="{{ url_for('static', filename='js/i18n/jquery-3.7.1.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/i18n/jquery.i18n.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/i18n/setting-lang.js') }}"></script>
|
||
<style>
|
||
/* 禁用用户选择 */
|
||
* {
|
||
-webkit-user-select: none;
|
||
/* Chrome, Opera, Safari */
|
||
-moz-user-select: none;
|
||
/* Firefox */
|
||
-ms-user-select: none;
|
||
/* Internet Explorer/Edge */
|
||
user-select: none;
|
||
/* Non-prefixed version, currently supported by Chrome, Opera and Firefox */
|
||
-webkit-tap-highlight-color: transparent;
|
||
/* 禁用触控点击的蓝色叠加层 */
|
||
}
|
||
body,
|
||
html {
|
||
height: 100%;
|
||
margin: 0;
|
||
font-family: Arial, sans-serif;
|
||
background-color: #ffffff00;
|
||
}
|
||
|
||
.controls-container {
|
||
height: 100%;
|
||
width: 100%;
|
||
/* add-code */
|
||
padding: 20px;
|
||
box-sizing: border-box;
|
||
position: relative;
|
||
}
|
||
|
||
.scroll-view {
|
||
position: fixed;
|
||
top: 50px;
|
||
width: calc(100% - 40px);
|
||
height: calc(100% - 70px);
|
||
overflow: auto;
|
||
}
|
||
|
||
/* 隐藏滚动条 */
|
||
.scroll-view::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
.scroll-view {
|
||
-ms-overflow-style: none;
|
||
/* IE and Edge */
|
||
scrollbar-width: none;
|
||
/* Firefox */
|
||
}
|
||
|
||
.status-header-title {
|
||
height: 27px;
|
||
/* font-style: italic; */
|
||
font-size: 16px;
|
||
/* margin: 5px 0; */
|
||
margin: 25px 0 20px;
|
||
font-weight: 600;
|
||
color: #666;
|
||
}
|
||
|
||
.status-container {
|
||
box-sizing: border-box;
|
||
/* grid-auto-rows: auto; 原注释代码 */
|
||
/* justify-content: space-between; */
|
||
/* display: flex;
|
||
flex-wrap: wrap;
|
||
align-content: start; */
|
||
/* gap: 12px; */
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
grid-gap: 10px 14px;
|
||
}
|
||
|
||
.status-card {
|
||
background-color: rgba(255, 255, 255, 0.507);
|
||
border-radius: 15px;
|
||
font-size: 16px;
|
||
text-align: center;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||
overflow: hidden;
|
||
position: relative;
|
||
transition: all 0.15s ease-in-out;
|
||
/* add-code */
|
||
/* width: calc(25% - 12px); */
|
||
width: 100%;
|
||
/* height: 170px; */
|
||
height: 150px;
|
||
max-height: 230px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
/*
|
||
.status-card:not(:nth-child(4n)) {
|
||
margin-right: 10px;
|
||
} */
|
||
|
||
.massage-head-card img {
|
||
/* max-width: 100%; */
|
||
position: absolute;
|
||
height: 60%;
|
||
width: 60%;
|
||
object-fit: cover; /* 使图片适应框架大小 */
|
||
z-index: 2;
|
||
transform: rotateZ(-35deg);
|
||
/* add-code */
|
||
margin: 16px 20% 0;
|
||
aspect-ratio: 1/1;
|
||
opacity: 0.7;
|
||
bottom: 20px;
|
||
}
|
||
|
||
.status-title {
|
||
padding: 6px 10px;
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
letter-spacing: 1px;
|
||
color: rgb(247, 0, 255); /* 默认颜色 */
|
||
color: rgba(252, 74, 252, 0.7); /* 使用 RGBA 透明色 */
|
||
text-shadow: 1px 3px 6px #fff, /* 模拟内阴影的颜色 */ 0 0 0 #000,
|
||
/* 透明阴影,用来确保支持老浏览器 */ 2px 3px 6px #fff; /* 模拟内阴影的颜色 */
|
||
z-index: 1;
|
||
opacity: 0.45;
|
||
text-align: left;
|
||
text-wrap: nowrap;
|
||
overflow: hidden;
|
||
/* overflow-x: auto; */
|
||
min-height: 25px;
|
||
line-height: 25px;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.status-title::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
.status-title-span {
|
||
max-width: 84px;
|
||
overflow-x: auto;
|
||
}
|
||
.common-range {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.status-content {
|
||
width: 100%;
|
||
/* font-size: 16px; */
|
||
font-weight: 900;
|
||
letter-spacing: 5px;
|
||
color: rgb(247, 0, 255); /* 默认颜色 */
|
||
color: rgba(252, 74, 252, 0.7);
|
||
/* 使用 RGBA 透明色 */
|
||
text-shadow: 1px 3px 6px #fff, /* 模拟内阴影的颜色 */ 0 0 0 #000,
|
||
/* 透明阴影,用来确保支持老浏览器 */ 2px 3px 6px #fff; /* 模拟内阴影的颜色 */
|
||
z-index: 1;
|
||
opacity: 0.4;
|
||
text-align: center;
|
||
white-space: pre-wrap; /* 保持空白符和换行符 */
|
||
border-radius: 15px;
|
||
justify-content: center;
|
||
align-items: center;
|
||
display: flex;
|
||
/* add-code */
|
||
flex: 1;
|
||
height: calc(100% - 25px);
|
||
}
|
||
|
||
/* 隐藏滚动条 */
|
||
#status-program::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
#status-program {
|
||
-ms-overflow-style: none;
|
||
/* IE and Edge */
|
||
scrollbar-width: none;
|
||
/* Firefox */
|
||
}
|
||
|
||
/* #massage-card:active {
|
||
background-color: rgba(255, 177, 238, 0.507);
|
||
} */
|
||
|
||
#massage-head {
|
||
box-sizing: border-box;
|
||
width: 80%;
|
||
height: calc(100% - 40px);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: absolute;
|
||
bottom: 42%;
|
||
left: 50%;
|
||
transform: translate(-50%, 50%);
|
||
letter-spacing: 0px;
|
||
font-size: 5.5vw;
|
||
line-height: 6vw;
|
||
opacity: 0.6;
|
||
overflow-y: auto;
|
||
align-self: center;
|
||
}
|
||
|
||
.massage-popup {
|
||
position: fixed;
|
||
background-color: rgba(255, 255, 255, 0.65);
|
||
backdrop-filter: blur(5px);
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
||
border-radius: 10px;
|
||
display: none;
|
||
flex-direction: column;
|
||
padding: 15px;
|
||
box-sizing: border-box;
|
||
gap: 10px; /* 按钮之间的间距 */
|
||
z-index: 9999; /* 确保在最前面 */
|
||
overflow-y: auto;
|
||
transition: all 0.15s ease-in-out;
|
||
}
|
||
|
||
/* 隐藏滚动条 */
|
||
.massage-popup::-webkit-scrollbar {
|
||
width: 0px;
|
||
height: 0px;
|
||
}
|
||
|
||
/* 隐藏IE和Edge的滚动条 */
|
||
.massage-popup {
|
||
-ms-overflow-style: none; /* IE和Edge */
|
||
scrollbar-width: none; /* Firefox */
|
||
}
|
||
|
||
.massage-head-button {
|
||
background-color: #bb29ff13;
|
||
border-radius: 10px; /* 圆角 */
|
||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* 阴影 */
|
||
|
||
padding: 15px;
|
||
text-align: center;
|
||
font-size: 16px;
|
||
color: #333; /* 字体颜色 */
|
||
cursor: pointer;
|
||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||
}
|
||
|
||
.massage-head-button:hover {
|
||
background-color: rgba(255, 177, 238, 0.507);
|
||
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15); /* 悬停时的阴影 */
|
||
}
|
||
|
||
#progress {
|
||
font-size: 55px;
|
||
margin: 2.5px;
|
||
margin-top: -10px;
|
||
background-color: rgb(247, 0, 255);
|
||
background-image: linear-gradient(
|
||
to top,
|
||
rgba(4, 0, 255, 0.7) 60%,
|
||
/* 深紫色填充到60% */ rgba(247, 0, 255, 0) 60% /* 剩余40%的颜色 */
|
||
);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
text-shadow: none;
|
||
opacity: 0.4;
|
||
/* opacity: 0.25; */
|
||
}
|
||
|
||
#progress::before {
|
||
content: attr(data-text);
|
||
position: absolute;
|
||
z-index: -1;
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
text-shadow: 1px 3px 6px rgba(255, 255, 255, 0.7),
|
||
/* 模拟内阴影的颜色 */ 0 0 0 #000,
|
||
/* 透明阴影,用来确保支持老浏览器 */ 2px 3px 6px
|
||
rgba(255, 255, 255, 0.7); /* 模拟内阴影的颜色 */
|
||
opacity: 0.35;
|
||
}
|
||
|
||
#force {
|
||
bottom: 0;
|
||
letter-spacing: normal;
|
||
display: flex;
|
||
align-items: baseline; /* 让数字和字母的底部对齐 */
|
||
margin-top: -18px;
|
||
}
|
||
|
||
.function-container {
|
||
/* add-code */
|
||
/* height: 170px; */
|
||
width: calc(100% - 40px);
|
||
/* width: 30px; */
|
||
position: fixed;
|
||
bottom: 20px;
|
||
/* bottom: 10px; */
|
||
transition: all 0.1s;
|
||
display: flex;
|
||
left: 20px;
|
||
border-radius: 15px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.common-button {
|
||
bottom: 0;
|
||
/* width: 90%; */
|
||
/* add-code */
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: absolute;
|
||
z-index: 9999;
|
||
box-sizing: border-box;
|
||
padding: 10px;
|
||
}
|
||
.common-button button {
|
||
flex: 1;
|
||
height: 46px;
|
||
background-color: #bb29ff13;
|
||
color: rgba(255, 255, 255, 0.65);
|
||
border: none;
|
||
border-radius: 10px; /* 圆角矩形 */
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 32px;
|
||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
||
}
|
||
.common-button button:first-child {
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.common-button button:active {
|
||
background-color: rgba(255, 177, 238, 0.507);
|
||
}
|
||
|
||
.common-add,
|
||
.common-down {
|
||
width: 25px;
|
||
height: 25px;
|
||
background: linear-gradient(
|
||
to right bottom,
|
||
rgb(212, 96, 241),
|
||
rgba(145, 66, 197, 0.5)
|
||
);
|
||
mask-size: cover;
|
||
background-size: cover;
|
||
-webkit-mask-size: cover;
|
||
}
|
||
|
||
.common-add {
|
||
mask-image: url("static/images/massage_control/加号.svg");
|
||
-webkit-mask-image: url("static/images/massage_control/加号.svg");
|
||
}
|
||
|
||
.common-down {
|
||
mask-image: url("static/images/massage_control/减号.svg");
|
||
-webkit-mask-image: url("static/images/massage_control/减号.svg");
|
||
}
|
||
|
||
#temperature {
|
||
bottom: 0;
|
||
display: flex;
|
||
align-items: baseline; /* Align the bottom of numbers and unit */
|
||
margin-top: -20px;
|
||
}
|
||
|
||
.temperature-value {
|
||
letter-spacing: normal;
|
||
}
|
||
|
||
.temperature-unit {
|
||
letter-spacing: -4px;
|
||
}
|
||
|
||
.common-value,
|
||
.common-unit {
|
||
letter-spacing: normal;
|
||
text-align: center;
|
||
}
|
||
.common-value {
|
||
font-size: 6.5vw;
|
||
}
|
||
.common-unit {
|
||
font-size: 5vw;
|
||
}
|
||
|
||
.common-no-unit {
|
||
bottom: 0;
|
||
letter-spacing: normal;
|
||
display: flex;
|
||
align-items: baseline;
|
||
margin-top: -18px;
|
||
}
|
||
|
||
.common-no-unit-value {
|
||
font-size: 6.5vw; /* Adjust the size here */
|
||
letter-spacing: normal;
|
||
}
|
||
|
||
#direction {
|
||
opacity: 0.9;
|
||
margin-top: -16px;
|
||
}
|
||
.direction-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 14px;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.direction-value {
|
||
opacity: 0.4;
|
||
letter-spacing: normal;
|
||
font-size: 12px;
|
||
}
|
||
.common-switch {
|
||
position: relative;
|
||
height: 40px;
|
||
width: 80px;
|
||
background-color: #f5f5f5;
|
||
border-radius: 20px;
|
||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
|
||
z-index: 3;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.common-slide-toggle {
|
||
position: absolute;
|
||
height: 41px;
|
||
width: 41px;
|
||
background: linear-gradient(
|
||
to right bottom,
|
||
rgb(212, 96, 241, 1),
|
||
rgba(145, 66, 197, 1)
|
||
);
|
||
border-radius: 50%;
|
||
transition: left 0.2s ease-in-out;
|
||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
|
||
box-shadow: -4px 2px 8px rgba(0, 0, 0, 0.25);
|
||
-webkit-transition: left 0.2s ease-in-out;
|
||
-moz-transition: left 0.2s ease-in-out;
|
||
-ms-transition: left 0.2s ease-in-out;
|
||
-o-transition: left 0.2s ease-in-out;
|
||
}
|
||
|
||
.joystick {
|
||
width: 150px;
|
||
height: 150px;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.joystick-text {
|
||
font-weight: bold;
|
||
opacity: 0.35;
|
||
font-size: 15px;
|
||
}
|
||
|
||
#joystick-frame {
|
||
width: 165px;
|
||
height: 175px; /* 调整iframe高度为页面底部的50% */
|
||
background-color: transparent; /* 设置背景透明 */
|
||
border: none; /* 去除边框 */
|
||
overflow: hidden;
|
||
/* background-color: #4CAF50; */
|
||
}
|
||
|
||
.flag-button {
|
||
width: 40px;
|
||
min-width: 40px;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
background-color: #bb29ff13;
|
||
z-index: 99;
|
||
}
|
||
|
||
.flag-button #flag-img {
|
||
width: 20px;
|
||
height: 20px;
|
||
}
|
||
|
||
.button-container {
|
||
display: flex;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
overflow: hidden;
|
||
border-radius: 15px;
|
||
}
|
||
|
||
.control-button {
|
||
/* flex: 8; */
|
||
display: flex;
|
||
/* flex-direction: column; */
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-sizing: border-box;
|
||
flex: 1;
|
||
width: 100%;
|
||
/* width: calc(100% - 40px); */
|
||
overflow: hidden !important;
|
||
border-radius: 15px;
|
||
gap: 20px;
|
||
}
|
||
|
||
.control-button .pause-btn-box {
|
||
position: relative;
|
||
overflow: hidden !important;
|
||
flex: 3.5;
|
||
border-radius: 10px;
|
||
-webkit-border-radius: 10px;
|
||
-moz-border-radius: 10px;
|
||
-ms-border-radius: 10px;
|
||
-o-border-radius: 10px;
|
||
}
|
||
|
||
.pause {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
}
|
||
|
||
.pause-icon {
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
|
||
.re-start-icon {
|
||
width: 30px;
|
||
height: 30px;
|
||
display: none;
|
||
}
|
||
|
||
.control-button button {
|
||
height: 60px;
|
||
/* height: 55px; */
|
||
background-color: rgba(255, 255, 255, 0.507);
|
||
color: rgba(255, 255, 255, 0.65);
|
||
border: none;
|
||
border-radius: 10px; /* 圆角矩形 */
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
||
position: relative;
|
||
overflow: hidden !important;
|
||
}
|
||
/* .control-button button:not(:first-child) {
|
||
margin-left: 10px;
|
||
} */
|
||
|
||
/* .control-button button:last-child::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: linear-gradient(
|
||
to right,
|
||
rgb(9, 198, 245),
|
||
rgb(44, 243, 120)
|
||
);
|
||
} */
|
||
|
||
.progress-bar {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
height: 100%;
|
||
width: 0;
|
||
/* background: linear-gradient(
|
||
to right,
|
||
rgb(9, 198, 245),
|
||
rgb(44, 243, 120)
|
||
); */
|
||
animation: rise 12s linear forwards;
|
||
background: linear-gradient(
|
||
90deg,
|
||
rgba(214, 111, 240, 0.8),
|
||
rgba(145, 66, 197, 0.8)
|
||
);
|
||
overflow: hidden;
|
||
/* animation: rise 12s linear forwards; */
|
||
}
|
||
|
||
/* @keyframes rise {
|
||
0% {
|
||
width: 50px;
|
||
}
|
||
|
||
100% {
|
||
height: 100%;
|
||
filter: hue-rotate(360deg);
|
||
}
|
||
} */
|
||
|
||
.progress-bar::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 50%;
|
||
margin-top: -40px;
|
||
right: -74px;
|
||
width: 80px;
|
||
height: 80px;
|
||
border-radius: 45%;
|
||
background-color: rgba(255, 255, 255, 0.507);
|
||
animation: move 8s linear infinite;
|
||
}
|
||
@keyframes move {
|
||
100% {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
.progress-bar::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: 50%;
|
||
margin-top: -35px;
|
||
right: -62px;
|
||
width: 70px;
|
||
height: 70px;
|
||
border-radius: 38%;
|
||
background-color: rgba(255, 255, 255, 0.507);
|
||
animation: move2 5s linear infinite;
|
||
}
|
||
@keyframes move2 {
|
||
100% {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
.control-button button:active {
|
||
background-color: rgba(255, 177, 238, 0.507);
|
||
}
|
||
|
||
.start div {
|
||
background: linear-gradient(45deg, #ff7e5f, #ffa764);
|
||
/* background: linear-gradient(45deg, #ff7e5f, #ffa764); */
|
||
}
|
||
|
||
.stop {
|
||
flex: 1;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.stop div {
|
||
background: linear-gradient(45deg, #ff9fc4, #f83b64);
|
||
position: relative;
|
||
z-index: 1;
|
||
text-align: right;
|
||
}
|
||
|
||
.progress-num {
|
||
background: linear-gradient(45deg, #ff9fc4, #f83b64);
|
||
margin-left: 10px;
|
||
font-size: 15px !important;
|
||
text-align: left;
|
||
font-weight: bolder;
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
/* position: relative;
|
||
z-index: 1; */
|
||
color: transparent; /* 设置文字颜色为透明,让背景色能透过文字 */
|
||
}
|
||
|
||
.start div,
|
||
.stop div {
|
||
font-size: 18px;
|
||
/* max-height: 55px; */
|
||
max-height: 60px;
|
||
font-weight: bolder;
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
/* word-break: break-word; */
|
||
text-wrap: nowrap;
|
||
text-align: center;
|
||
overflow: hidden;
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.popup {
|
||
display: block;
|
||
position: fixed;
|
||
top: -50px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
background-color: #ffcccc;
|
||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
||
padding: 10px 14px;
|
||
color: #ff0000ab;
|
||
border-radius: 17.5px;
|
||
z-index: 1000;
|
||
font-size: 14px;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
opacity: 0;
|
||
transition: all 0.15s ease-in-out; /* 添加滑动动画 */
|
||
}
|
||
|
||
.popup.show {
|
||
display: flex;
|
||
opacity: 0.8;
|
||
top: calc(2.5% + 40px); /* 显示时滑动到顶部的正常位置 */
|
||
}
|
||
|
||
.popup.hide {
|
||
opacity: 0;
|
||
top: -50px; /* 隐藏时滑回到视图上方 */
|
||
}
|
||
|
||
.program-swiper,
|
||
.body-part-swiper {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: calc(100% - 25px);
|
||
margin-top: -10px;
|
||
width: 100%;
|
||
position: absolute;
|
||
}
|
||
.swiper-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
.swiper-slide {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-sizing: border-box;
|
||
position: relative;
|
||
/* transform: 0.5s; */
|
||
}
|
||
.swiper-slide div {
|
||
border-radius: 10px;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
letter-spacing: 0px;
|
||
box-shadow: 2px 4px 6px rgba(0, 0, 0, 0.4);
|
||
font-size: 12px;
|
||
}
|
||
|
||
.swiper-slide-active {
|
||
z-index: 6;
|
||
}
|
||
|
||
.swiper-slide-active div {
|
||
position: absolute;
|
||
width: 76%;
|
||
transform: width 0.5s;
|
||
font-size: 16px;
|
||
padding: 14px 8px;
|
||
opacity: 0.9;
|
||
background: linear-gradient(
|
||
to right bottom,
|
||
rgb(212, 96, 241, 0.8),
|
||
rgba(145, 66, 197, 0.8)
|
||
);
|
||
text-shadow: none;
|
||
color: white;
|
||
min-height: 60px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.body-swiper {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.body-swiper-icon {
|
||
margin-bottom: 6px;
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
|
||
.swiper-slide-next div,
|
||
.swiper-slide-prev div {
|
||
min-width: 40px;
|
||
position: absolute;
|
||
transform: width 0.5s;
|
||
font-size: 10px;
|
||
opacity: 0.9;
|
||
background-color: rgba(255, 255, 255, 0.3);
|
||
background-color: rgb(220, 246, 251, 0.5);
|
||
padding: 8px 6px;
|
||
color: #333;
|
||
background-color: rgba(249, 244, 252, 0.5);
|
||
}
|
||
|
||
.swiper-slide-next div {
|
||
left: -20%;
|
||
}
|
||
|
||
.swiper-slide-prev div {
|
||
right: -20%;
|
||
}
|
||
.swiper-slide-active {
|
||
z-index: 6;
|
||
}
|
||
|
||
.swiper-slide-next,
|
||
.swiper-slide-prev {
|
||
z-index: 5;
|
||
}
|
||
|
||
.swiper-button-next,
|
||
.swiper-button-prev {
|
||
display: none;
|
||
}
|
||
|
||
.swiper-button-next svg,
|
||
.swiper-button-prev svg {
|
||
display: none;
|
||
}
|
||
|
||
.swiper-button-next:after,
|
||
.swiper-button-prev:after {
|
||
display: none;
|
||
}
|
||
|
||
/* 弹窗的背景遮罩 */
|
||
.popup-modal {
|
||
display: none; /* 默认隐藏 */
|
||
position: fixed;
|
||
z-index: 1000; /* 确保弹窗在最顶层 */
|
||
left: 0;
|
||
top: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: rgba(0, 0, 0, 0.5); /* 背景透明 */
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
/* 弹窗的内容 */
|
||
.popup-content {
|
||
background-color: rgba(255, 255, 255, 0.7); /* 背景透明度 */
|
||
backdrop-filter: blur(5px); /* 背景模糊效果 */
|
||
padding: 20px;
|
||
border-radius: 15px;
|
||
text-align: center;
|
||
width: 300px;
|
||
box-shadow: 0px 0px 24px rgba(255, 255, 255, 0.65); /* 与其他元素一致的阴影效果 */
|
||
}
|
||
|
||
/* 按钮样式 */
|
||
#popup-buttons button {
|
||
margin: 5px;
|
||
padding: 10px 25px;
|
||
border: none;
|
||
border-radius: 10px;
|
||
background: linear-gradient(
|
||
to right bottom,
|
||
rgb(212, 96, 241),
|
||
rgba(145, 66, 197, 0.5)
|
||
); /* 紫色渐变 */
|
||
color: white;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
transition: background 0.3s ease;
|
||
}
|
||
|
||
#popup-buttons button:active {
|
||
background: linear-gradient(
|
||
to right bottom,
|
||
rgba(145, 66, 197, 1),
|
||
rgb(212, 96, 241)
|
||
); /* 悬停时加深渐变 */
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="controls-container">
|
||
<div class="scroll-view">
|
||
<div
|
||
class="status-header-title"
|
||
i18n="control.massage.header_title"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="40"
|
||
checkHeight="true"
|
||
></div>
|
||
<div class="status-container">
|
||
<div class="status-card" {% if mode == 'handheld' %}style="display: none"{% endif %}>
|
||
<div class="status-title" i18n="control.massage.title"></div>
|
||
|
||
<div id="status-program">
|
||
<div id="program" class="program-swiper">
|
||
<div class="swiper-wrapper">
|
||
<div class="selectable swiper-slide">
|
||
<div i18n="control.massage.program"></div>
|
||
<!--基础放松-->
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div i18n="control.massage.program2"></div>
|
||
<!--深入舒缓-->
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div i18n="control.massage.program3"></div>
|
||
<!--深层修复-->
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div i18n="control.massage.program4"></div>
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div i18n="control.massage.program5"></div>
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div i18n="control.massage.program6"></div>
|
||
</div>
|
||
</div>
|
||
<div class="program-prev"></div>
|
||
<div class="program-next"></div>
|
||
</div>
|
||
</div>
|
||
<!-- <img src="{{ url_for('static', filename='images/0.png') }}" alt=""> -->
|
||
</div>
|
||
<div class="status-card" {% if mode == 'handheld' %}style="display: none"{% endif %}>
|
||
<div
|
||
class="status-title"
|
||
i18n="control.massage.title2"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="40"
|
||
checkHeight="true"
|
||
></div>
|
||
<div id="status-body-part">
|
||
<div id="body-part" class="body-part-swiper">
|
||
<div class="swiper-wrapper" id="body-part-wrapper"></div>
|
||
<div class="body-part-prev"></div>
|
||
<div class="body-part-next"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="status-card massage-head-card" id="massage-card">
|
||
<div
|
||
class="status-title"
|
||
i18n="control.massage.title3"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="40"
|
||
checkHeight="true"
|
||
></div>
|
||
<div
|
||
class="status-content"
|
||
id="massage-head"
|
||
changeLineHeight="true"
|
||
smallSize="40"
|
||
checkHeight="true"
|
||
></div>
|
||
<img
|
||
src="{{ url_for('static', filename='images/massage_control/loading.gif') }}"
|
||
alt=""
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="status-header-title"
|
||
i18n="control.massage.header_title"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="40"
|
||
checkHeight="true"
|
||
></div>
|
||
<!-- 力度 -->
|
||
<div class="status-container">
|
||
<div class="status-card" id="strength-card" {% if mode == 'handheld' %}style="display: none"{% endif %}>
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title4"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span class="common-range" id="force-range"></span>
|
||
</div>
|
||
<div class="status-content" id="force">
|
||
<span class="force-value common-value">20</span>
|
||
<span class="force-unit common-unit">N</span>
|
||
</div>
|
||
<div class="force-button common-button">
|
||
<button class="force-down-btn">
|
||
<div class="force-down common-down"></div>
|
||
</button>
|
||
<button class="force-add-btn">
|
||
<div class="force-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 温度 -->
|
||
<div class="status-card" id="temperature-card">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title5"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span class="common-range" id="temperature-range">[0~5]</span>
|
||
</div>
|
||
<div class="status-content" id="temperature">
|
||
<span class="temperature-value common-value">1</span>
|
||
<!-- <span class="temperature-unit common-unit">°C</span> -->
|
||
</div>
|
||
<div class="temperature-button common-button">
|
||
<button class="temperature-down-btn">
|
||
<div class="temperature-down common-down"></div>
|
||
</button>
|
||
<button class="temperature-add-btn">
|
||
<div class="temperature-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 电流档位 -->
|
||
<div class="status-card" id="current-card">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title6"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span class="common-range" id="gear-range">[0~5]</span>
|
||
</div>
|
||
<div class="status-content common-no-unit" id="gear">
|
||
<span class="gear-value common-no-unit-value">1</span>
|
||
</div>
|
||
<div class="gear-button common-button">
|
||
<button class="gear-down-btn">
|
||
<div class="gear-down common-down"></div>
|
||
</button>
|
||
<button class="gear-add-btn">
|
||
<div class="gear-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 频率 -->
|
||
<div class="status-card" id="shake-card">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title7"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span class="common-range" id="shake-range">[0~5]</span>
|
||
</div>
|
||
<div class="status-content common-no-unit" id="shake">
|
||
<span class="shake-value common-no-unit-value">1</span>
|
||
</div>
|
||
<div class="shake-button common-button">
|
||
<button class="shake-down-btn">
|
||
<div class="shake-down common-down"></div>
|
||
</button>
|
||
<button class="shake-add-btn">
|
||
<div class="shake-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 频率 -->
|
||
<div class="status-card" id="frequency-card" style="display: none">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title7"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span class="common-range" id="frequency-range">[1~16]</span>
|
||
</div>
|
||
<div class="status-content common-no-unit" id="frequency">
|
||
<span class="frequency-value common-no-unit-value">1</span>
|
||
</div>
|
||
<div class="frequency-button common-button">
|
||
<button class="frequency-down-btn">
|
||
<div class="frequency-down common-down"></div>
|
||
</button>
|
||
<button class="frequency-add-btn">
|
||
<div class="frequency-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 冲击力 -->
|
||
<div class="status-card" id="press-card" style="display: none">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title8"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span id="press-range" class="common-range">[1~27]</span>
|
||
</div>
|
||
<div class="status-content common-no-unit" id="press">
|
||
<span class="press-value common-no-unit-value">1</span>
|
||
</div>
|
||
<div class="press-button common-button">
|
||
<button class="press-down-btn">
|
||
<div class="press-down common-down"></div>
|
||
</button>
|
||
<button class="press-add-btn">
|
||
<div class="press-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 速度 -->
|
||
<div class="status-card" id="speed-card" style="display: none">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title9"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span class="common-range" id="speed-range">[0~3]</span>
|
||
</div>
|
||
<div class="status-content common-no-unit" id="speed">
|
||
<span class="speed-value common-no-unit-value">1</span>
|
||
</div>
|
||
<div class="speed-button common-button">
|
||
<button class="speed-down-btn">
|
||
<div class="speed-down common-down"></div>
|
||
</button>
|
||
<button class="speed-add-btn">
|
||
<div class="speed-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- 方向 -->
|
||
<div class="status-card" id="direction-card" style="display: none">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title10"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
</div>
|
||
<div class="status-content" id="direction">
|
||
<div class="direction-container">
|
||
<div class="common-switch">
|
||
<div class="common-slide-toggle" style="left: 40px"></div>
|
||
<!-- <div class="common-option"></div>
|
||
<div class="common-option active"></div> -->
|
||
</div>
|
||
<span
|
||
class="direction-value"
|
||
i18n="control.massage.title10_txt"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="40"
|
||
checkHeight="true"
|
||
></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 高度 -->
|
||
<div class="status-card" id="high-card" style="display: none;">
|
||
<div class="status-title">
|
||
<span
|
||
i18n="control.massage.title11"
|
||
resize-font="true"
|
||
changeLineHeight="true"
|
||
smallSize="30"
|
||
checkHeight="true"
|
||
class="status-title-span"
|
||
></span>
|
||
<span class="common-range" id="high-range">[4~15]CM</span>
|
||
</div>
|
||
<div class="status-content common-no-unit" id="high">
|
||
<span class="high-value common-no-unit-value">6</span>
|
||
</div>
|
||
<div class="high-button common-button">
|
||
<button class="high-down-btn">
|
||
<div class="high-down common-down"></div>
|
||
</button>
|
||
<button class="high-add-btn">
|
||
<div class="high-add common-add"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="function-container" id="func-box">
|
||
<!-- <div class="flag-button" id="flag-btn">
|
||
<img id="flag-img" src="../static/images/narrow.png" alt="">
|
||
</div> -->
|
||
<div class="button-container">
|
||
<div class="control-button">
|
||
<button class="start" style="display: block">
|
||
<div i18n="control.massage.start_btn"></div>
|
||
</button>
|
||
<!-- <button class="stop" style="display: none">
|
||
<div i18n="control.massage.stop_btn">停止按摩</div>
|
||
<div class="progress-num"></div>
|
||
</button>
|
||
<div class="progress-bar"></div> -->
|
||
|
||
<div id="pause-btn-box" class="pause-btn-box" style="display: none">
|
||
<button class="pause" id="pause">
|
||
<img
|
||
class="pause-icon"
|
||
id="pause-icon"
|
||
src="/static/images/select_program/pause.png"
|
||
alt=""
|
||
/>
|
||
<div class="progress-num"></div>
|
||
</button>
|
||
<div class="progress-bar"></div>
|
||
</div>
|
||
<button class="stop" style="display: none">
|
||
<div i18n="control.massage.stop_btn"></div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="popup" class="popup"></div>
|
||
|
||
<!-- Popup Modal -->
|
||
<div id="popup-modal" class="popup-modal">
|
||
<div class="popup-content">
|
||
<p id="popup-message">这里是消息内容</p>
|
||
<div id="popup-buttons">
|
||
<button
|
||
id="confirm-btn"
|
||
onclick="confirmAction()"
|
||
i18n="popup.confirm_btn"
|
||
>
|
||
确认
|
||
</button>
|
||
<button
|
||
id="cancel-btn"
|
||
onclick="cancelAction()"
|
||
i18n="popup.cancel_btn"
|
||
>
|
||
取消
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="../static/js/swiper/swiper-bundle.min.js"></script>
|
||
<script src="../static/js/base.js"></script>
|
||
|
||
<script>
|
||
function showPopup2(message, buttons = { confirm: true, cancel: true }) {
|
||
// 设置弹窗的消息内容,使用 innerHTML 以支持换行
|
||
document.getElementById("popup-message").innerHTML = message;
|
||
|
||
// 控制按钮显示
|
||
document.getElementById("confirm-btn").style.display = buttons.confirm
|
||
? "inline-block"
|
||
: "none";
|
||
document.getElementById("cancel-btn").style.display = buttons.cancel
|
||
? "inline-block"
|
||
: "none";
|
||
|
||
// 显示弹窗
|
||
document.getElementById("popup-modal").style.display = "flex";
|
||
|
||
// 返回Promise,等待用户选择
|
||
return new Promise((resolve) => {
|
||
popupResolve = resolve; // 保存 resolve 函数
|
||
});
|
||
}
|
||
|
||
function confirmAction() {
|
||
// 用户点击确认按钮,关闭弹窗并返回true
|
||
document.getElementById("popup-modal").style.display = "none";
|
||
popupResolve(true);
|
||
}
|
||
|
||
function cancelAction() {
|
||
// 用户点击取消按钮,关闭弹窗并返回false
|
||
document.getElementById("popup-modal").style.display = "none";
|
||
popupResolve(false);
|
||
}
|
||
|
||
const socket = io();
|
||
socket.on("update_massage_status", function (data) {
|
||
updateStatusDisplay(data);
|
||
});
|
||
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
const contentElement = document.getElementById("massage-head");
|
||
const text = contentElement.textContent;
|
||
const formattedText = text.replace(/(.{2})/g, "$1\n");
|
||
contentElement.textContent = formattedText;
|
||
|
||
const scrollView = document.querySelector(".scroll-view");
|
||
|
||
// 定义每个档位的高度,假设每个档位占窗口的高度
|
||
const slotHeight = window.innerHeight / 3; // 每次滚动到三分之一的窗口高度
|
||
|
||
scrollView.addEventListener("scroll", () => {
|
||
// 使用 setTimeout 来处理节流,避免频繁触发滚动事件
|
||
clearTimeout(scrollView.scrollTimeout);
|
||
|
||
scrollView.scrollTimeout = setTimeout(() => {
|
||
const scrollTop = scrollView.scrollTop;
|
||
const nearestSlot = Math.round(scrollTop / slotHeight) * slotHeight;
|
||
|
||
scrollView.scrollTo({
|
||
top: nearestSlot,
|
||
behavior: "smooth",
|
||
});
|
||
}, 100); // 延迟 100ms 检测滚动完成后吸附
|
||
});
|
||
});
|
||
|
||
let massageCard = document.getElementById("massage-card");
|
||
let massageContent = document.getElementById("massage-head");
|
||
let massageImage = massageCard.querySelector("img");
|
||
|
||
const strengthCard = document.querySelector("#strength-card");
|
||
const temperatureCard = document.querySelector("#temperature-card");
|
||
const shakeCard = document.querySelector("#shake-card");
|
||
const currentCard = document.querySelector("#current-card");
|
||
const frequencyCard = document.querySelector("#frequency-card");
|
||
const pressCard = document.querySelector("#press-card");
|
||
const speedCard = document.querySelector("#speed-card");
|
||
const directionCard = document.querySelector("#direction-card");
|
||
const highCard = document.querySelector("#high-card");
|
||
|
||
const commonSwitch = document.querySelector(".common-switch");
|
||
const commonSlideToggle = commonSwitch.querySelector(
|
||
".common-slide-toggle"
|
||
);
|
||
|
||
function getHeadSelectIndex() {
|
||
// let headerLength = parseInt(localStorage.getItem("headerLength"));
|
||
let headSelectIndex =
|
||
parseInt(localStorage.getItem("headSelectIndex")) || 0;
|
||
// if (headSelectIndex >= headerLength) {
|
||
// headSelectIndex = 0;
|
||
// localStorage.setItem("headSelectIndex", headSelectIndex);
|
||
// }
|
||
return headSelectIndex;
|
||
}
|
||
|
||
// 疗程滑块
|
||
var programSwiper = new Swiper(".program-swiper", {
|
||
// direction: "vertical", // 垂直切换选项
|
||
loop: false, // 循环模式选项
|
||
centeredSlides: true, // 居中切换选项
|
||
observer: true, // 监听选项
|
||
observeParents: true, // 监听父元素选项
|
||
centerInsufficientSlides: true, // 居中不足的slides选项
|
||
navigation: {
|
||
nextEl: ".program-next",
|
||
prevEl: ".program-prev",
|
||
},
|
||
});
|
||
|
||
// 右侧点击按摩头更换逻辑部分代码
|
||
let massageHeaderData = [
|
||
{
|
||
newText: "深部热疗",
|
||
i18n: "control.massage.data_text",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/深部热疗.png') }}",
|
||
},
|
||
{
|
||
newText: "点阵按摩",
|
||
i18n: "control.massage.data_text2",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/点阵按摩.png') }}",
|
||
},
|
||
{
|
||
newText: "全能滚珠",
|
||
i18n: "control.massage.data_text3",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/全能滚珠.png') }}",
|
||
},
|
||
{
|
||
newText: "指疗通络",
|
||
i18n: "control.massage.data_text4",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/指疗通络.png') }}",
|
||
},
|
||
{
|
||
newText: "滚滚刺疗",
|
||
i18n: "control.massage.data_text5",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/滚滚刺疗.png') }}",
|
||
},
|
||
{
|
||
newText: "温砭舒揉",
|
||
i18n: "control.massage.data_text6",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/温砭舒揉.png') }}",
|
||
},
|
||
{
|
||
newText: "离子光灸",
|
||
i18n: "control.massage.data_text7",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/离子光灸.png') }}",
|
||
},
|
||
{
|
||
newText: "能量热疗",
|
||
i18n: "control.massage.data_text8",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/能量热疗.png') }}",
|
||
},
|
||
{
|
||
newText: "天球滚捏",
|
||
i18n: "control.massage.data_text9",
|
||
newImageSrc:
|
||
"{{ url_for('static', filename='images/massage_control/head/天球滚捏.png') }}",
|
||
}
|
||
];
|
||
|
||
var bodyPartSwiper = new Swiper(".body-part-swiper", {
|
||
loop: false, // 循环模式选项
|
||
centeredSlides: true, // 居中切换选项
|
||
observer: true, // 监听选项
|
||
observeParents: true, // 监听父元素选项
|
||
centerInsufficientSlides: true, // 居中不足的slides选项
|
||
navigation: {
|
||
nextEl: ".body-part-next",
|
||
prevEl: ".body-part-prev",
|
||
},
|
||
});
|
||
|
||
const bodyPartWrapper = document.getElementById("body-part-wrapper");
|
||
|
||
function setBodySwiper(val) {
|
||
// 替换status-content中的文本
|
||
// massageContent.textContent = massageHeaderData[val].newText;
|
||
massageContent.style.fontSize = "5.5vw";
|
||
massageContent.style.lineHeight = "6vw";
|
||
massageContent.style.opacity = "0";
|
||
|
||
massageContent.setAttribute("i18n", massageHeaderData[val].i18n);
|
||
massageContent.setAttribute("resize-font", true);
|
||
massageContent.setAttribute("changeLineHeight", true);
|
||
massageContent.setAttribute("smallSize", "60");
|
||
massageContent.setAttribute("checkHeight", true);
|
||
|
||
// 替换img的图片路径
|
||
massageImage.src = massageHeaderData[val].newImageSrc;
|
||
|
||
if (val == 0 || val == 6 || val == 7 ) {
|
||
bodyPartWrapper.innerHTML = `
|
||
<div class="selectable swiper-slide swiper-slide-active">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/back-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_back"></span>
|
||
<!--背部-->
|
||
</div>
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/belly-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_belly"></span>
|
||
<!--腹部-->
|
||
</div>
|
||
</div>`;
|
||
} else if (val == 5 ) {
|
||
bodyPartWrapper.innerHTML = `
|
||
<div class="selectable swiper-slide swiper-slide-active">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/back-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_back"></span>
|
||
<!--背部-->
|
||
</div>
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/belly-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_belly"></span>
|
||
<!--腹部-->
|
||
</div>
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/leg-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_leg"></span>
|
||
<!--腿部-->
|
||
</div>
|
||
</div>`;
|
||
} else if (val == 1 || val == 8) {
|
||
bodyPartWrapper.innerHTML = `
|
||
<div class="swiper-slide swiper-slide-active" body-part="back">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/back-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_back"></span>
|
||
<!--背部-->
|
||
</div>
|
||
</div>
|
||
<div class="swiper-slide" body-part="shoulder">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/shoulder-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_shoulder"></span>
|
||
<!--肩颈-->
|
||
</div>
|
||
</div>
|
||
<div class="swiper-slide" body-part="back_shoulder">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/back_shoulder-btn.png') }}"/>
|
||
<span i18n="control.massage.body_part_back_shoulder"></span>
|
||
<!--背部+肩颈-->
|
||
</div>
|
||
</div>`;
|
||
} else if (val == 2 || val == 3 || val == 4) {
|
||
bodyPartWrapper.innerHTML = `
|
||
<div class="swiper-slide swiper-slide-active" body-part="back">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/back-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_back"></span>
|
||
<!--背部-->
|
||
</div>
|
||
</div>
|
||
<div class="swiper-slide" body-part="shoulder">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/shoulder-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_shoulder"></span>
|
||
<!--肩颈-->
|
||
</div>
|
||
</div>
|
||
<div class="swiper-slide" body-part="back_shoulder">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/back_shoulder-btn.png') }}"/>
|
||
<span i18n="control.massage.body_part_back_shoulder"></span>
|
||
<!--背部+肩颈-->
|
||
</div>
|
||
</div>
|
||
<div class="selectable swiper-slide">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/leg-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_leg"></span>
|
||
<!--腿部-->
|
||
</div>
|
||
</div>`;
|
||
} else {
|
||
bodyPartWrapper.innerHTML = `
|
||
<div class="swiper-slide swiper-slide-active" body-part="back">
|
||
<div class="body-swiper">
|
||
<img class="body-swiper-icon" src="{{ url_for('static', filename='images/massage_control/bodypart/back-btn.png') }}" />
|
||
<span i18n="control.massage.body_part_back"></span>
|
||
<!--背部-->
|
||
</div>
|
||
</div>`;
|
||
}
|
||
bodyPartSwiper.slideTo(0);
|
||
bodyPartSwiper.update();
|
||
setTimeout(() => {
|
||
loadLanguageFun(lang);
|
||
massageContent.style.opacity = "0.6";
|
||
}, 500);
|
||
}
|
||
|
||
let headSelectIndex = getHeadSelectIndex();
|
||
setBodySwiper(headSelectIndex);
|
||
toggleSettingCard(headSelectIndex);
|
||
|
||
// 监听 slideChange 事件
|
||
bodyPartSwiper.on("slideChange", function () {
|
||
// 获取当前滑动的索引
|
||
let headSelectIndex = getHeadSelectIndex();
|
||
let bodyPartSelectIndex = bodyPartSwiper.activeIndex + 1;
|
||
if (headSelectIndex == 1 || headSelectIndex == 3) {
|
||
bodyPart =
|
||
bodyPartSelectIndex == 1
|
||
? "back"
|
||
: bodyPartSelectIndex == 2
|
||
? "shoulder"
|
||
: "back_shoulder";
|
||
localStorage.setItem("bodyPart", bodyPart);
|
||
} else if (
|
||
headSelectIndex == 2 ||
|
||
headSelectIndex == 0 ||
|
||
headSelectIndex == 5
|
||
) {
|
||
bodyPart = bodyPartSelectIndex == 1 ? "back" : "belly";
|
||
localStorage.setItem("bodyPart", bodyPart);
|
||
} else {
|
||
bodyPart = "back";
|
||
localStorage.setItem("bodyPart", bodyPart);
|
||
}
|
||
changeSetting();
|
||
});
|
||
|
||
// 监听 slideChange 事件
|
||
bodyPartSwiper.on("touchMove", async function () {
|
||
if (
|
||
bodyPartSwiper.slides.length > 1 &&
|
||
bodyPartSwiper.allowSlideNext === false
|
||
) {
|
||
let commandStartedText = await getPopupText("commandStartedText");
|
||
showPopup(commandStartedText);
|
||
}
|
||
});
|
||
|
||
// 添加滑动提示
|
||
programSwiper.on("touchMove", async function () {
|
||
if (programSwiper.allowSlideNext === false) {
|
||
let commandStartedText = await getPopupText("commandStartedText");
|
||
showPopup(commandStartedText);
|
||
}
|
||
});
|
||
|
||
function toggleAllowSlide(flag) {
|
||
programSwiper.allowSlideNext = flag;
|
||
programSwiper.allowSlidePrev = flag;
|
||
|
||
bodyPartSwiper.allowSlideNext = flag;
|
||
bodyPartSwiper.allowSlidePrev = flag;
|
||
}
|
||
|
||
const popupElement = document.getElementById("popup");
|
||
|
||
function toggleSettingCard(type) {
|
||
/**
|
||
* 0:深部热疗
|
||
* 1:点阵按摩
|
||
* 2:全能滚珠
|
||
* 3:指疗通络
|
||
* 4:滚滚刺疗
|
||
* 5:温砭舒揉 stone
|
||
* 6:离子光灸
|
||
* 7:能量热疗
|
||
`````` * 8: 天球滚捏
|
||
*/
|
||
const allCards = [
|
||
strengthCard, temperatureCard, currentCard, shakeCard,
|
||
frequencyCard, pressCard, speedCard, directionCard, highCard
|
||
];
|
||
allCards.forEach(card => card.style.display = "none");
|
||
|
||
switch (parseInt(type)) {
|
||
case 0:
|
||
strengthCard.style.display = "block";
|
||
temperatureCard.style.display = "block";
|
||
shakeCard.style.display = "block";
|
||
currentCard.style.display = "block";
|
||
break;
|
||
|
||
case 1:
|
||
strengthCard.style.display = "block";
|
||
frequencyCard.style.display = "block";
|
||
pressCard.style.display = "block";
|
||
break;
|
||
|
||
case 2:
|
||
case 3:
|
||
case 4:
|
||
case 8:
|
||
strengthCard.style.display = "block";
|
||
break;
|
||
|
||
case 5:
|
||
strengthCard.style.display = "block";
|
||
temperatureCard.style.display = "block";
|
||
speedCard.style.display = "block";
|
||
directionCard.style.display = "block";
|
||
break;
|
||
|
||
case 6:
|
||
temperatureCard.style.display = "block";
|
||
highCard.style.display = "block";
|
||
break;
|
||
|
||
case 7:
|
||
strengthCard.style.display = "block";
|
||
temperatureCard.style.display = "block";
|
||
break;
|
||
}
|
||
}
|
||
|
||
function handleClickOutside(event) {
|
||
const massagePopup = document.getElementById("massage-popup");
|
||
if (
|
||
massagePopup.style.display === "flex" &&
|
||
!massagePopup.contains(event.target) &&
|
||
!document.getElementById("massage-card").contains(event.target)
|
||
) {
|
||
massagePopup.style.display = "none";
|
||
document.removeEventListener("click", handleClickOutside); // 移除文档的点击事件监听
|
||
}
|
||
}
|
||
|
||
// 获取按钮元素
|
||
const startButton = document.querySelector(".start");
|
||
const pauseButton = document.querySelector(".pause-btn-box");
|
||
const pauseIcon = document.querySelector("#pause-icon");
|
||
const stopButton = document.querySelector(".stop");
|
||
const massageHeadElement = document.getElementById("massage-head");
|
||
|
||
const calculateModeReal = () => {
|
||
let modeReal = parseInt(localStorage.getItem("modeReal")) === 0 ? 0 : 1;
|
||
|
||
const powerControl = localStorage.getItem("powerControl");
|
||
let loadMode = parseInt(localStorage.getItem("loadMode")) === 1 ? 1 : 0;
|
||
|
||
// if (loadMode === 1) {
|
||
// return 3;
|
||
// }
|
||
|
||
// // 如果 loadMode 为 0,根据 modeReal 判断返回值
|
||
// if (loadMode === 0) {
|
||
// if (modeReal === 0) {
|
||
// // 如果 modeReal 为 0,根据 powerControl 判断返回值
|
||
// if (powerControl === "导纳" || !powerControl) {
|
||
// return 0; // 如果 powerControl 为 "导纳" 或为空,则返回 0
|
||
// } else {
|
||
// return 2; // 否则返回 2
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// // 默认返回 1
|
||
// return 1;
|
||
|
||
if (modeReal === 0) {
|
||
if (powerControl === "导纳" || !powerControl) {
|
||
modeReal = 0;
|
||
} else {
|
||
modeReal = 2;
|
||
}
|
||
} else {
|
||
if (loadMode === 1) {
|
||
modeReal = 3;
|
||
} else if (loadMode === 0) {
|
||
modeReal = 1;
|
||
}
|
||
}
|
||
return modeReal;
|
||
};
|
||
|
||
const headSelectionMap = [
|
||
{
|
||
head: "thermotherapy",
|
||
headTxt: "深部热疗",
|
||
message: "请确认按摩机器人已经安装“深部热疗”按摩头",
|
||
},
|
||
{
|
||
head: "shockwave",
|
||
headTxt: "点阵按摩",
|
||
message: "请确认按摩机器人已经安装“点阵按摩”按摩头",
|
||
},
|
||
{
|
||
head: "ball",
|
||
headTxt: "全能滚珠",
|
||
message: "请确认按摩机器人已经安装“全能滚珠”按摩头",
|
||
},
|
||
{
|
||
head: "finger",
|
||
headTxt: "指疗通络",
|
||
message: "请确认按摩机器人已经安装“指疗通络”按摩头",
|
||
},
|
||
{
|
||
head: "roller",
|
||
headTxt: "滚滚刺疗",
|
||
message: "请确认按摩机器人已经安装“滚滚刺疗”按摩头",
|
||
},
|
||
{
|
||
head: "stone",
|
||
headTxt: "温砭舒揉",
|
||
message: "请确认按摩机器人已经安装“温砭舒揉”按摩头",
|
||
},
|
||
{
|
||
head: "ion",
|
||
headTxt: "离子光灸",
|
||
message: "请确认按摩机器人已经安装“离子光灸”按摩头",
|
||
},
|
||
{
|
||
head: "heat",
|
||
headTxt: "能量热疗",
|
||
message: "请确认按摩机器人已经安装“能量热疗”按摩头",
|
||
},
|
||
{
|
||
head: "spheres",
|
||
headTxt: "天球滚捏",
|
||
message: "请确认按摩机器人已经安装“天球滚捏”按摩头",
|
||
},
|
||
];
|
||
|
||
// 开始按摩点击事件
|
||
startButton.addEventListener(
|
||
"click",
|
||
debounce(async () => {
|
||
checkLicense()
|
||
.then(async (data) => {
|
||
console.log("License Data:", data);
|
||
const topDocument = window.top;
|
||
|
||
if (data.can_use) {
|
||
try {
|
||
// 获取状态
|
||
const status = await getStatus();
|
||
if (!status) {
|
||
let infoFailedText = await getPopupText("infoFailedText");
|
||
showPopup(infoFailedText);
|
||
return;
|
||
}
|
||
|
||
if (!status.massage_service_started) {
|
||
let connectArmText = await getPopupText("connectArmText");
|
||
showPopup(connectArmText);
|
||
return;
|
||
}
|
||
|
||
if (status.is_massaging) {
|
||
let massageStartText = await getPopupText(
|
||
"massageStartText"
|
||
);
|
||
showPopup(massageStartText);
|
||
return;
|
||
}
|
||
|
||
let head, headTxt;
|
||
const headSelectIndex =
|
||
parseInt(localStorage.getItem("headSelectIndex")) || 0;
|
||
|
||
const selection = headSelectionMap[headSelectIndex];
|
||
if (selection) {
|
||
head = selection.head;
|
||
headTxt = selection.headTxt;
|
||
// topDocument.showPopup(selection.message).then((confirm) => {
|
||
// if (confirm) {
|
||
// doMassage();
|
||
// }
|
||
// });
|
||
|
||
function setHintMsg(selectedHeadText) {
|
||
let msg = {
|
||
zh: `
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>本设备必须由</span>
|
||
<span class="hint-bold-text">经过培训的专业人员</span>
|
||
<span>操作使用,非专业人员请勿擅自操作。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">孕妇、心血管疾病患者、局部皮肤破损者</span>
|
||
<span>等禁止使用。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">体内有金属者、佩戴金属饰品、严重骨质疏松患者</span>
|
||
<span>及其他身体不适者在理疗前告知理疗师。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">生理期与哺乳期</span>
|
||
<span>不建议进行理疗,建议根据身体状况选择理疗时间。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">空腹、醉酒</span>
|
||
<span>等状态下不宜进行理疗。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>冬季理疗时请避免</span>
|
||
<span class="hint-bold-text">穿过厚、过宽松的衣物</span>
|
||
<span>,以确保最佳效果。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item" style="margin-top: 20px; font-weight: 600;">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>请确认安装的按摩头为</span>
|
||
<span class="hint-bold-text" style="color: #FF5722;">${selectedHeadText}</span>
|
||
<span>按摩头</span>
|
||
</div>
|
||
</div>
|
||
`,
|
||
en: `
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>This device must be operated by </span>
|
||
<span class="hint-bold-text">certified professionals only</span>
|
||
<span>. Unauthorized use is prohibited.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">Pregnant women, cardiovascular patients, individuals with skin lesions</span>
|
||
<span> are strictly prohibited from use.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">Metal implants, jewelry wearers, osteoporosis patients</span>
|
||
<span> must inform therapist prior to treatment.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">Menstruation and lactation periods</span>
|
||
<span> require medical consultation before therapy.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">Fasting or intoxication</span>
|
||
<span> are contraindicated for therapy.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>In winter, avoid </span>
|
||
<span class="hint-bold-text">bulky clothing</span>
|
||
<span> to ensure therapeutic efficacy.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item" style="margin-top: 20px; font-weight: 600;">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>Confirm installed head: </span>
|
||
<span class="hint-bold-text" style="color: #FF5722;">${selectedHeadText}</span>
|
||
</div>
|
||
</div>`,
|
||
jp: `
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>本機器は</span>
|
||
<span class="hint-bold-text">訓練を受けた専門家のみ</span>
|
||
<span>が操作可能です。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">妊婦・心臓病患者・皮膚損傷者</span>
|
||
<span>は使用禁止です。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">体内金属・装身具・骨粗鬆症患者</span>
|
||
<span>は施術前に申告してください。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">生理中・授乳中</span>
|
||
<span>の方は医師にご相談ください。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">空腹時・飲酒時</span>
|
||
<span>の施術は避けてください。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>冬季は</span>
|
||
<span class="hint-bold-text">厚着を避け</span>
|
||
<span>効果を確保してください。</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item" style="margin-top: 20px; font-weight: 600;">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>装着ヘッド確認: </span>
|
||
<span class="hint-bold-text" style="color: #FF5722;">${selectedHeadText}</span>
|
||
</div>
|
||
</div>`,
|
||
ko: `
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>본 장비는 </span>
|
||
<span class="hint-bold-text">훈련된 전문가만</span>
|
||
<span> 조작 가능합니다.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">임산부, 심혈관 질환자, 피부 손상자</span>
|
||
<span> 사용 금지.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">체내 금속, 장신구, 골다공증 환자</span>
|
||
<span>는 시술 전 알려주세요.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">생리 중, 수유 중</span>
|
||
<span>에는 의사 상담이 필요합니다.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span class="hint-bold-text">공복, 음주 상태</span>
|
||
<span>에서는 사용을 자제하세요.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>겨울철 </span>
|
||
<span class="hint-bold-text">두꺼운 옷 착용을 피하고</span>
|
||
<span> 효과를 극대화하세요.</span>
|
||
</div>
|
||
</div>
|
||
<div class="hint-item" style="margin-top: 20px; font-weight: 600;">
|
||
<img class="hint-icon" src="static/images/hint/hint.png" alt="">
|
||
<div>
|
||
<span>장착 헤드 확인: </span>
|
||
<span class="hint-bold-text" style="color: #FF5722;">${selectedHeadText}</span>
|
||
</div>
|
||
</div>`,
|
||
};
|
||
|
||
return msg[lang];
|
||
}
|
||
|
||
let msg = setHintMsg(headTxt);
|
||
|
||
topDocument.showHintModal(msg).then((confirm) => {
|
||
if (confirm) {
|
||
doMassage();
|
||
}
|
||
});
|
||
} else {
|
||
console.error("Invalid headSelectIndex:", headSelectIndex);
|
||
}
|
||
|
||
const doMassage = async () => {
|
||
const bodyPart = localStorage.getItem("bodyPart") || "back";
|
||
const modeReal = calculateModeReal();
|
||
const selectedItem = getSelectedItem();
|
||
|
||
if (!head) {
|
||
console.error("Unknown massage head type");
|
||
return;
|
||
}
|
||
|
||
const postData = new URLSearchParams({
|
||
progress: "0",
|
||
current_head: head,
|
||
current_task: "-1",
|
||
task_time: selectedItem,
|
||
body_part: bodyPart,
|
||
});
|
||
|
||
try {
|
||
const response = await fetch("/update_massage_status", {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
body: postData.toString(),
|
||
});
|
||
|
||
const result = await response.json();
|
||
console.log("Massage status updated:", result);
|
||
|
||
socket.emit(
|
||
"send_command",
|
||
`begin:${head}:${selectedItem}:${bodyPart}:${modeReal}`
|
||
);
|
||
console.log(
|
||
"send_command",
|
||
`begin:${head}:${selectedItem}:${bodyPart}:${modeReal}`
|
||
);
|
||
|
||
localStorage.setItem("headChangeFlag", false);
|
||
startButton.style.display = "none";
|
||
pauseButton.style.display = "block";
|
||
stopButton.style.display = "flex";
|
||
} catch (error) {
|
||
console.error("Failed to update massage status:", error);
|
||
}
|
||
};
|
||
} catch (error) {
|
||
console.error("Error during massage initialization:", error);
|
||
}
|
||
} else {
|
||
let activatePleaseText = await getPopupText(
|
||
"activatePleaseText"
|
||
);
|
||
topDocument.showPopup(activatePleaseText, {
|
||
confirm: true,
|
||
cancel: false,
|
||
});
|
||
}
|
||
})
|
||
.catch((error) => {
|
||
console.error("Error checking license:", error);
|
||
});
|
||
}, 800)
|
||
);
|
||
pauseButton.addEventListener(
|
||
"click",
|
||
debounce(async () => {
|
||
let isPausedText = await getPopupText("isPausedText");
|
||
let topDocument = window.top;
|
||
topDocument.showPopup(isPausedText).then(async (confirm) => {
|
||
if (confirm) {
|
||
try {
|
||
// 获取状态
|
||
const status = await getStatus();
|
||
|
||
if (!status) {
|
||
let infoFailedText = await getPopupText("infoFailedText");
|
||
showPopup(infoFailedText);
|
||
return;
|
||
}
|
||
|
||
if (status.is_massaging === true) {
|
||
socket.emit("send_command", "pause");
|
||
// pauseIcon.src = "/static/images/select_program/re-start.png";
|
||
} else {
|
||
if (status.is_pause === true) {
|
||
const head = status.current_head.replace(/_head$/, "");
|
||
const selectedItem = status.task_time;
|
||
const bodyPart = status.body_part;
|
||
const modeReal = calculateModeReal();
|
||
socket.emit(
|
||
"send_command",
|
||
`begin:${head}:${selectedItem}:${bodyPart}:${modeReal}`
|
||
);
|
||
console.log(
|
||
"send_command",
|
||
`begin:${head}:${selectedItem}:${bodyPart}:${modeReal}`
|
||
);
|
||
// pauseIcon.src = "/static/images/select_program/pause.png";
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error("Error during massage initialization:", error);
|
||
}
|
||
}
|
||
});
|
||
}, 500)
|
||
);
|
||
// 监听"停止按摩"按钮点击事件
|
||
stopButton.addEventListener(
|
||
"click",
|
||
debounce(() => {
|
||
let topDocument = window.top;
|
||
topDocument.showPopup("确认结束按摩").then(async (confirm) => {
|
||
if (confirm) {
|
||
const status = await getStatus();
|
||
if (status && status.is_massaging === false) {
|
||
// 使用返回的状态字典
|
||
let massageStoppedText = await getPopupText(
|
||
"massageStoppedText"
|
||
);
|
||
showPopup(massageStoppedText);
|
||
} else {
|
||
socket.emit("send_command", "stop");
|
||
}
|
||
}
|
||
});
|
||
}, 800)
|
||
);
|
||
|
||
// 显示弹出框,message是要显示的内容
|
||
function showPopup(message) {
|
||
popupElement.textContent = message;
|
||
popupElement.classList.add("show");
|
||
popupElement.classList.remove("hide");
|
||
|
||
setTimeout(() => {
|
||
popupElement.classList.add("hide");
|
||
setTimeout(() => {
|
||
popupElement.classList.remove("show");
|
||
}, 300); // 与CSS中的动画时间匹配
|
||
}, 2000); // 2秒后开始隐藏弹出框
|
||
}
|
||
|
||
// 公用设置项
|
||
let settings = [
|
||
{
|
||
name: "force",
|
||
min: 5,
|
||
// max: 50,
|
||
max: getDefaultData("max-force"),
|
||
initialValue: getDefaultData("force"),
|
||
elementSelectors: {
|
||
value: ".force-value",
|
||
addButton: ".force-add-btn",
|
||
downButton: ".force-down-btn",
|
||
},
|
||
socketCommand: {
|
||
increase: "adjust:force:increase:low",
|
||
decrease: "adjust:force:decrease:low",
|
||
},
|
||
maxPopupText: "maxForceText",
|
||
minPopupText: "minForceText",
|
||
},
|
||
{
|
||
name: "temperature",
|
||
min: 0,
|
||
max: getDefaultData("max-temperature"),
|
||
initialValue: getDefaultData("temperature"),
|
||
elementSelectors: {
|
||
value: ".temperature-value",
|
||
addButton: ".temperature-add-btn",
|
||
downButton: ".temperature-down-btn",
|
||
},
|
||
socketCommand: {
|
||
increase: "adjust:temperature:increase:low",
|
||
decrease: "adjust:temperature:decrease:low",
|
||
},
|
||
maxPopupText: "maxTempText",
|
||
minPopupText: "minTempText",
|
||
},
|
||
{
|
||
name: "shake",
|
||
min: 0,
|
||
max: 5,
|
||
initialValue: 0,
|
||
elementSelectors: {
|
||
value: ".shake-value",
|
||
addButton: ".shake-add-btn",
|
||
downButton: ".shake-down-btn",
|
||
},
|
||
socketCommand: {
|
||
increase: "adjust:shake:increase:low",
|
||
decrease: "adjust:shake:decrease:low",
|
||
},
|
||
maxPopupText: "maxLevelText",
|
||
minPopupText: "minLevelText",
|
||
},
|
||
{
|
||
name: "gear",
|
||
min: 0,
|
||
max: 5,
|
||
initialValue: 0,
|
||
elementSelectors: {
|
||
value: ".gear-value",
|
||
addButton: ".gear-add-btn",
|
||
downButton: ".gear-down-btn",
|
||
},
|
||
socketCommand: {
|
||
increase: "adjust:gear:increase:low",
|
||
decrease: "adjust:gear:decrease:low",
|
||
},
|
||
maxPopupText: "maxLevelText",
|
||
minPopupText: "minLevelText",
|
||
},
|
||
{
|
||
name: "frequency",
|
||
min: 1,
|
||
max: 16,
|
||
initialValue: 6,
|
||
elementSelectors: {
|
||
value: ".frequency-value",
|
||
addButton: ".frequency-add-btn",
|
||
downButton: ".frequency-down-btn",
|
||
},
|
||
socketCommand: {
|
||
increase: "adjust:frequency:increase:low",
|
||
decrease: "adjust:frequency:decrease:low",
|
||
},
|
||
maxPopupText: "maxFrequencyText",
|
||
minPopupText: "minFrequencyText",
|
||
},
|
||
{
|
||
name: "press",
|
||
min: 1,
|
||
max: 27,
|
||
initialValue: 12,
|
||
elementSelectors: {
|
||
value: ".press-value",
|
||
addButton: ".press-add-btn",
|
||
downButton: ".press-down-btn",
|
||
},
|
||
socketCommand: {
|
||
increase: "adjust:press:increase:low",
|
||
decrease: "adjust:press:decrease:low",
|
||
},
|
||
maxPopupText: "maxPressText",
|
||
minPopupText: "minPressText",
|
||
},
|
||
{
|
||
name: "speed",
|
||
min: 0,
|
||
max: 3,
|
||
initialValue: 2,
|
||
elementSelectors: {
|
||
value: ".speed-value",
|
||
addButton: ".speed-add-btn",
|
||
downButton: ".speed-down-btn",
|
||
},
|
||
socketCommand: {
|
||
increase: "adjust:speed:increase:low",
|
||
decrease: "adjust:speed:decrease:low",
|
||
},
|
||
maxPopupText: "maxLevelText",
|
||
minPopupText: "minLevelText",
|
||
},
|
||
{
|
||
name: "direction",
|
||
min: 0,
|
||
max: 1,
|
||
initialValue: 1,
|
||
},
|
||
];
|
||
|
||
// 创建通用函数来处理增减逻辑
|
||
async function handleAdjustButtonClick(setting, isIncrease) {
|
||
const btnClick = function () {
|
||
return new Promise(async (resolve, reject) => {
|
||
if (isIncrease) {
|
||
// 判断增值操作
|
||
if (setting.initialValue == setting.max) {
|
||
let maxPopupText = await getPopupText(setting.maxPopupText);
|
||
showPopup(maxPopupText, { confirm: true, cancel: false }); // 超过最大值时弹出提示
|
||
reject(); // 直接返回,不执行后续逻辑
|
||
} else {
|
||
socket.emit(
|
||
"send_command",
|
||
setting.socketCommand.increase,
|
||
() => {
|
||
resolve(); // 确保命令执行后再继续
|
||
}
|
||
);
|
||
}
|
||
} else {
|
||
// 判断减值操作
|
||
if (setting.initialValue == setting.min) {
|
||
let minPopupText = await getPopupText(setting.minPopupText);
|
||
showPopup(minPopupText, { confirm: true, cancel: false }); // 超过最小值时弹出提示
|
||
reject(); // 直接返回,不执行后续逻辑
|
||
} else {
|
||
socket.emit(
|
||
"send_command",
|
||
setting.socketCommand.decrease,
|
||
() => {
|
||
resolve(); // 确保命令执行后再继续
|
||
}
|
||
);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
const status = await getStatus(); // 获取当前状态
|
||
if (status.is_massaging === true) {
|
||
if (
|
||
status.massage_state === "CV_TASK" ||
|
||
status.massage_state === "IDLE"
|
||
) {
|
||
let notAdjustText = await getPopupText("notAdjustText");
|
||
showPopup(notAdjustText);
|
||
return;
|
||
}
|
||
try {
|
||
btnClick().then((res) => {
|
||
getStatus();
|
||
});
|
||
} catch (error) {
|
||
console.error("操作未执行", error);
|
||
}
|
||
} else {
|
||
// 如果是 shockwave 模式,需要特殊处理
|
||
let notAdjustText = await getPopupText("notAdjustText");
|
||
showPopup(notAdjustText);
|
||
}
|
||
}
|
||
|
||
// 方向按钮的点击事件:
|
||
commonSwitch.addEventListener(
|
||
"click",
|
||
throttle(async () => {
|
||
const status = await getStatus(); // 等待获取状态
|
||
|
||
if (
|
||
status &&
|
||
status.massage_state === "CV_TASK" &&
|
||
status.is_massaging === true
|
||
) {
|
||
let photoingText = await getPopupText("photoingText");
|
||
showPopup(photoingText);
|
||
} else if (status && status.is_massaging === true) {
|
||
if (settings[7].initialValue == 0) {
|
||
settings[7].initialValue = 1;
|
||
commonSlideToggle.style.left = "40px";
|
||
} else {
|
||
settings[7].initialValue = 0;
|
||
commonSlideToggle.style.left = 0;
|
||
}
|
||
socket.emit("send_command", "adjust:direction:null:null");
|
||
} else {
|
||
// 如果是 shockwave 模式,需要特殊处理
|
||
let notAdjustText = await getPopupText("notAdjustText");
|
||
showPopup(notAdjustText);
|
||
return;
|
||
}
|
||
}, 2000)
|
||
);
|
||
|
||
// 更新显示的通用函数
|
||
function updateDisplay(setting) {
|
||
const valueElement = document.querySelector(
|
||
setting.elementSelectors.value
|
||
);
|
||
valueElement.textContent = String(setting.initialValue).padStart(
|
||
2,
|
||
"0"
|
||
);
|
||
}
|
||
|
||
// 创建并绑定事件监听器
|
||
function initializeSettings() {
|
||
settings.forEach((setting, index) => {
|
||
if (index != 7) {
|
||
// 更新显示初始值
|
||
updateDisplay(setting);
|
||
// 获取按钮元素
|
||
const addButton = document.querySelector(
|
||
setting.elementSelectors.addButton
|
||
);
|
||
const downButton = document.querySelector(
|
||
setting.elementSelectors.downButton
|
||
);
|
||
|
||
// 增加按钮,减少按钮
|
||
// 绑定点击事件
|
||
addButton.addEventListener(
|
||
"click",
|
||
throttle(() => handleAdjustButtonClick(setting, true), 500)
|
||
); // 增加
|
||
downButton.addEventListener(
|
||
"click",
|
||
throttle(() => handleAdjustButtonClick(setting, false), 500)
|
||
); // 减少
|
||
}
|
||
});
|
||
}
|
||
|
||
function getDefaultData(type) {
|
||
let bodyPart = localStorage.getItem("bodyPart") || "back";
|
||
// let val;
|
||
let headSelectIndex =
|
||
parseInt(localStorage.getItem("headSelectIndex")) || 0;
|
||
|
||
let val;
|
||
switch (type) {
|
||
case "force":
|
||
val =
|
||
headSelectIndex == 1
|
||
? 5
|
||
: headSelectIndex == 2
|
||
? 15
|
||
: bodyPart == "belly"
|
||
? 10
|
||
: 20;
|
||
break;
|
||
case "max-force":
|
||
// val = headSelectIndex === 1 ? 12 : 50;
|
||
val = 70;
|
||
break;
|
||
case "temperature":
|
||
val = headSelectIndex == 0 ? 3 : 1;
|
||
break;
|
||
case "max-temperature":
|
||
// val = 5;
|
||
val = headSelectIndex == 7 ? 3 : 5;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return val;
|
||
}
|
||
|
||
async function changeSetting() {
|
||
// 初始化设置的默认值
|
||
settings[0].initialValue = getDefaultData("force");
|
||
settings[0].max = getDefaultData("max-force"); // force
|
||
settings[1].initialValue = getDefaultData("temperature"); // temperature
|
||
settings[1].max = getDefaultData("max-temperature"); // temperature
|
||
settings[2].initialValue = 0; // shake
|
||
settings[3].initialValue = 0; // gear
|
||
settings[4].initialValue = 6; // frequency
|
||
settings[5].initialValue = 12; // press
|
||
settings[6].initialValue = 2; // speed
|
||
settings[7].initialValue = 1; // direction
|
||
|
||
commonSlideToggle.style.left = "40px";
|
||
|
||
const forceRange = document.querySelector("#force-range");
|
||
forceRange.innerText = `[${settings[0].min}~${settings[0].max}]`;
|
||
const temperatureRange = document.querySelector("#temperature-range");
|
||
temperatureRange.innerText = `[${settings[1].min}~${settings[1].max}]`;
|
||
// 更新显示
|
||
settings.forEach((setting, index) => {
|
||
if (index != 7) {
|
||
updateDisplay(setting);
|
||
}
|
||
});
|
||
}
|
||
|
||
async function initDisplay() {
|
||
const status = await getStatus();
|
||
updateStatusDisplay(status);
|
||
}
|
||
|
||
function changeData(name, val) {
|
||
let setting = settings.find((setting) => setting.name === name);
|
||
setting.initialValue = parseInt(val);
|
||
if (name !== "direction") {
|
||
updateDisplay(setting);
|
||
} else {
|
||
// commonSlideToggle.style.left = "40px";
|
||
if (val == 1) {
|
||
commonSlideToggle.style.left = "40px";
|
||
} else {
|
||
commonSlideToggle.style.left = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
let progressBar = document.querySelector(".progress-bar");
|
||
let progressData = document.querySelector(".progress-num");
|
||
|
||
async function updateStatusDisplay(data) {
|
||
console.log("adfdsf", JSON.stringify(data));
|
||
|
||
let topDocument = window.top;
|
||
let img2dImage = topDocument.document.getElementById("img2d-image");
|
||
|
||
if (data.hasOwnProperty("progress")) {
|
||
var newValueStr = data.progress; // 接收到的字符串类型的progress
|
||
var newValue = Math.round(parseFloat(newValueStr));
|
||
|
||
if (!isNaN(newValue)) {
|
||
// 确保转换成功
|
||
// 格式化 progress 值
|
||
var formattedValue;
|
||
if (
|
||
newValue === 0 ||
|
||
(newValue !== 0 && newValue < progressData.innerText)
|
||
) {
|
||
if (data.is_massaging) {
|
||
formattedValue = parseFloat(progressData.innerText) || 0;
|
||
} else {
|
||
formattedValue = newValue;
|
||
startButton.style.display = "block";
|
||
pauseButton.style.display = "none";
|
||
stopButton.style.display = "none";
|
||
// progressBar.style.transition = "none"; // 移除过渡效果
|
||
progressBar.style.width = "0%";
|
||
progressData.innerText = `0%`;
|
||
// setTimeout(() => {
|
||
// progressBar.style.transition = "width 0.5s ease-out";
|
||
// }, 50);
|
||
}
|
||
// formattedValue = '100'
|
||
} else if (newValue >= 100) {
|
||
if (data.is_massaging) {
|
||
formattedValue = 100;
|
||
} else {
|
||
formattedValue = 0;
|
||
}
|
||
} else if (newValue < 10) {
|
||
formattedValue = Math.round(newValue * 10) / 10; // 保留一位小数
|
||
} else {
|
||
formattedValue = Math.round(newValue * 10) / 10; // 保留一位小数
|
||
}
|
||
|
||
progressBar.style.width = `${formattedValue}%`;
|
||
progressData.innerText = `${formattedValue}%`;
|
||
} else {
|
||
console.error("Received an invalid progress value:", newValueStr);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("is_massaging")) {
|
||
if (data.is_massaging) {
|
||
// 按摩开始禁止切换
|
||
toggleAllowSlide(false);
|
||
localStorage.setItem("headChangeFlag", false);
|
||
startButton.style.display = "none";
|
||
// 显示暂停按钮和停止按钮
|
||
pauseButton.style.display = "block";
|
||
pauseIcon.src = "/static/images/select_program/pause.png";
|
||
stopButton.style.display = "flex";
|
||
|
||
// 替换穴位图片
|
||
if (data.hasOwnProperty("is_acupoint")) {
|
||
if (data.is_acupoint) {
|
||
img2dImage.src = "/static/images/back108points.png";
|
||
}
|
||
} else {
|
||
setImg2dImage(data.body_part, img2dImage);
|
||
}
|
||
} else {
|
||
setImg2dImage(data.body_part, img2dImage);
|
||
|
||
if (data.is_pause === true) {
|
||
// 按摩开始禁止切换
|
||
toggleAllowSlide(false);
|
||
localStorage.setItem("headChangeFlag", false);
|
||
|
||
startButton.style.display = "none";
|
||
// 显示暂停按钮和停止按钮
|
||
pauseButton.style.display = "block";
|
||
pauseIcon.src = "/static/images/select_program/re-start.png";
|
||
stopButton.style.display = "flex";
|
||
} else {
|
||
startButton.style.display = "block";
|
||
pauseButton.style.display = "none";
|
||
stopButton.style.display = "none";
|
||
|
||
// 按摩停止允许切换
|
||
toggleAllowSlide(true);
|
||
localStorage.setItem("headChangeFlag", true);
|
||
startButton.style.display = "block";
|
||
stopButton.style.display = "none";
|
||
// progressBar.style.transition = "none"; // 移除过渡效果
|
||
progressBar.style.width = "0%";
|
||
progressData.innerText = `0%`;
|
||
|
||
changeSetting();
|
||
}
|
||
}
|
||
}
|
||
|
||
if (data.is_massaging) {
|
||
if (
|
||
data.massage_state !== "CV_TASK" ||
|
||
data.massage_state !== "IDLE"
|
||
) {
|
||
if (data.hasOwnProperty("force")) {
|
||
if (data.force) {
|
||
changeData("force", data.force);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("temperature")) {
|
||
if (data.temperature) {
|
||
changeData("temperature", data.temperature);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("shake")) {
|
||
if (data.shake) {
|
||
changeData("shake", data.shake);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("gear")) {
|
||
if (data.gear) {
|
||
changeData("gear", data.gear);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("speed")) {
|
||
if (data.speed) {
|
||
changeData("speed", data.speed);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("direction")) {
|
||
if (data.direction) {
|
||
changeData("direction", data.direction);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("high")) {
|
||
if (data.high) {
|
||
changeData("high", data.high);
|
||
}
|
||
}
|
||
if (data.hasOwnProperty("current_head")) {
|
||
if (data.current_head) {
|
||
head = data.current_head;
|
||
let newText;
|
||
let headIndex;
|
||
let i18n;
|
||
if (data.is_massaging) {
|
||
if (head.includes("thermotherapy")) {
|
||
newText = "深部热疗";
|
||
headIndex = 0;
|
||
i18n = massageHeaderData[0].i18n;
|
||
} else if (head.includes("shockwave")) {
|
||
newText = "点阵按摩";
|
||
headIndex = 1;
|
||
i18n = massageHeaderData[1].i18n;
|
||
} else if (head.includes("ball")) {
|
||
newText = "全能滚珠";
|
||
headIndex = 2;
|
||
i18n = massageHeaderData[2].i18n;
|
||
} else if (head.includes("finger")) {
|
||
newText = "指疗通络";
|
||
headIndex = 3;
|
||
i18n = massageHeaderData[3].i18n;
|
||
} else if (head.includes("roller")) {
|
||
newText = "滚滚刺疗";
|
||
headIndex = 4;
|
||
i18n = massageHeaderData[4].i18n;
|
||
} else if (head.includes("stone")) {
|
||
newText = "温砭舒揉";
|
||
headIndex = 5;
|
||
i18n = massageHeaderData[5].i18n;
|
||
} else if (head.includes("ion")) {
|
||
newText = "离子光灸";
|
||
headIndex = 6;
|
||
i18n = massageHeaderData[6].i18n;
|
||
} else if (head.includes("heat")) {
|
||
newText = "能量热疗";
|
||
headIndex = 7;
|
||
i18n = massageHeaderData[7].i18n;
|
||
} else if (head.includes("spheres")) {
|
||
newText = "天球滚捏";
|
||
headIndex = 8;
|
||
i18n = massageHeaderData[8].i18n;
|
||
}
|
||
} else {
|
||
let headSelectIndex = getHeadSelectIndex();
|
||
headIndex = headSelectIndex;
|
||
if (headSelectIndex == 0) {
|
||
newText = "深部热疗";
|
||
} else if (headSelectIndex == 1) {
|
||
newText = "点阵按摩";
|
||
} else if (headSelectIndex == 2) {
|
||
newText = "全能滚珠";
|
||
} else if (headSelectIndex == 3) {
|
||
newText = "指疗通络";
|
||
} else if (headSelectIndex == 4) {
|
||
newText = "滚滚刺疗";
|
||
} else if (headSelectIndex == 5) {
|
||
newText = "温砭舒揉";
|
||
} else if (headSelectIndex == 6) {
|
||
newText = "离子光灸";
|
||
} else if (headSelectIndex == 7) {
|
||
newText = "能量热疗";
|
||
} else if (headSelectIndex == 8) {
|
||
newText = "天球滚捏";
|
||
}
|
||
i18n = massageHeaderData[headSelectIndex].i18n;
|
||
}
|
||
|
||
// 替换status-content中的文本
|
||
massageContent.setAttribute("i18n", i18n);
|
||
// 替换img的图片路径
|
||
massageImage.src = "static/images/" + newText + ".png";
|
||
localStorage.setItem("headSelectIndex", headIndex);
|
||
toggleSettingCard(headIndex);
|
||
await setBodySwiper(headIndex);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("task_time") && data.task_time) {
|
||
if (data.is_massaging) {
|
||
let taskTime = data.task_time;
|
||
let taskTimeIndex;
|
||
switch (taskTime) {
|
||
case 900:
|
||
taskTimeIndex = 0;
|
||
break;
|
||
case 1800:
|
||
taskTimeIndex = 1;
|
||
break;
|
||
case 2700:
|
||
taskTimeIndex = 2;
|
||
break;
|
||
case 3600:
|
||
taskTimeIndex = 3;
|
||
break;
|
||
case 5400:
|
||
taskTimeIndex = 4;
|
||
break;
|
||
case 7200:
|
||
taskTimeIndex = 5;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
programSwiper.slideTo(taskTimeIndex);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("body_part")) {
|
||
if (data.is_massaging) {
|
||
let bodyPart = data.body_part;
|
||
let bodyPartSelectIndex;
|
||
let headSelectIndex = getHeadSelectIndex();
|
||
switch (bodyPart) {
|
||
case "back":
|
||
bodyPartSelectIndex = 0;
|
||
break;
|
||
case "shoulder":
|
||
bodyPartSelectIndex = 1;
|
||
break;
|
||
case "back_shoulder":
|
||
bodyPartSelectIndex = 2;
|
||
break;
|
||
case "belly":
|
||
bodyPartSelectIndex = 1;
|
||
break;
|
||
default:
|
||
bodyPartSelectIndex = 0;
|
||
break;
|
||
}
|
||
bodyPartSwiper.slideTo(bodyPartSelectIndex);
|
||
toggleAllowSlide(false);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("press")) {
|
||
if (data.press) {
|
||
changeData("press", data.press);
|
||
}
|
||
}
|
||
|
||
if (data.hasOwnProperty("frequency")) {
|
||
if (data.frequency) {
|
||
changeData("frequency", data.frequency);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function setImg2dImage(body_part, img2dImage) {
|
||
switch (body_part) {
|
||
case "belly":
|
||
img2dImage.src = "/static/images/smart_mode/穴位2.png";
|
||
break;
|
||
default:
|
||
img2dImage.src = "/static/images/smart_mode/穴位.png";
|
||
break;
|
||
}
|
||
}
|
||
|
||
async function getStatus() {
|
||
try {
|
||
const response = await fetch("/get_status");
|
||
if (!response.ok) {
|
||
throw new Error("Network response was not ok");
|
||
}
|
||
const data = await response.json();
|
||
console.log("Status data:", data);
|
||
return data; // 直接返回字典数据
|
||
} catch (error) {
|
||
console.error("There was a problem with the fetch operation:", error);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function getSelectedItem() {
|
||
let activeSlide = programSwiper.activeIndex;
|
||
let timeVal;
|
||
switch (activeSlide) {
|
||
case 0:
|
||
timeVal = 900;
|
||
break;
|
||
case 1:
|
||
timeVal = 1800;
|
||
break;
|
||
case 2:
|
||
timeVal = 2700;
|
||
break;
|
||
case 3:
|
||
timeVal = 3600;
|
||
break;
|
||
case 4:
|
||
timeVal = 5400;
|
||
break;
|
||
case 5:
|
||
timeVal = 7200;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return timeVal;
|
||
}
|
||
|
||
function setStorageBodyPart() {
|
||
let headSelectIndex = getHeadSelectIndex();
|
||
let bodyPart = localStorage.getItem("bodyPart") || "back";
|
||
let slideIndex;
|
||
if (
|
||
headSelectIndex == 2 ||
|
||
headSelectIndex == 0 ||
|
||
headSelectIndex == 5
|
||
) {
|
||
slideIndex = bodyPart === "back" ? 0 : 1;
|
||
} else {
|
||
slideIndex =
|
||
bodyPart === "back" ? 0 : bodyPart === "shoulder" ? 1 : 2;
|
||
}
|
||
bodyPartSwiper.slideTo(slideIndex);
|
||
}
|
||
|
||
window.onload = function () {
|
||
const startElement = document.querySelector(".start");
|
||
const stopElement = document.querySelector(".stop");
|
||
|
||
initDisplay();
|
||
initializeSettings();
|
||
setStorageBodyPart();
|
||
changeSetting();
|
||
};
|
||
|
||
window.onresize = function () {
|
||
const startElement = document.querySelector(".start");
|
||
const stopElement = document.querySelector(".stop");
|
||
};
|
||
</script>
|
||
|
||
<script>
|
||
// 监听 storage 事件
|
||
window.addEventListener("storage", function (event) {
|
||
if (event.key === "headSelectIndex") {
|
||
if (event.oldValue === event.newValue) {
|
||
return;
|
||
} else {
|
||
// if
|
||
toggleSettingCard(event.newValue);
|
||
setBodySwiper(event.newValue);
|
||
changeSetting();
|
||
}
|
||
}
|
||
});
|
||
|
||
document.addEventListener("visibilitychange", async function () {
|
||
if (document.visibilityState === "visible") {
|
||
let welcomeBackText = await getPopupText("welcomeBackText");
|
||
showPopup(welcomeBackText);
|
||
if (!socket.connected) {
|
||
socket.on("connect", () => {
|
||
console.log("Reconnected to the server");
|
||
// 确保连接后你可以继续监听事件
|
||
socket.on("update_massage_status", function (data) {
|
||
updateStatusDisplay(data);
|
||
});
|
||
});
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|