You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2768 lines
84 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import Taro from "@tarojs/taro";
import dayjs from "dayjs";
import classnames from "classnames";
import { debounce } from "lodash";
import React, {
Component,
PropsWithChildren,
useEffect,
useState,
} from "react";
/*** redux ***/
import { connect } from "react-redux";
/*** redux end ***/
import {
Block,
View,
Text,
Image,
Video,
Input,
Button,
} from "@tarojs/components";
import {
notifyBLECharacteristicValueChange,
sendCommand,
} from "@/utils/bluetoothWXAPI";
import {
deviceCommandSamples,
bleCommandSamples,
} from "@/components/bluetoot/connection/wl200";
import { minSecToS, s_to_ms, s_to_hms, sleep, s_to_s } from "@/utils/util";
// import { DeviceToolKit as DeviceToolKitWE100 } from "@flossom-npm/iot-translater-we100";
import {
DeviceToolKit as DeviceToolKitWM,
TResponseFromDevice as TResponseFromDeviceWM,
} from "@flossom-npm/iot-translater";
import commandMap from "@/utils/commandMap";
import { Popup } from "@antmjs/vantui";
import { fr200BleCommand } from "@/components/bluetoot/connection/fr200";
import { go, getStorageSync, setStorageSync, msg } from "@/utils/traoAPI";
import { InstrumentInfo } from "@/utils/Interface";
/* 公共组件 */
import Navbar from "@/components/navbar/navbar";
import PopupCountdown from "@/components/popup/popup-countdown";
import PopupStepTips from "@/components/popup/popup-step-tips";
import PopupConfirm from "@/components/popup/popup-confirm";
import PopupAlert from "@/components/popup/popup-alert";
import PopupStatus from "@/components/popup/popup-status";
import PopupInstrumentUploadTips from "@/components/popup/popup-instrument-upload-tips";
import ConnectionBluetoot from "@/components/bluetoot/connection";
/* 公共组件 END */
/* 本页组件 */
import ElectricityView from "./components/ElectricityView/Electricity";
import ModeListView from "./components/ModeList/FR200";
import Footer from "./components/Footer/FR200";
import WaterTest from "./components/WaterTest/index";
/* 本页组件 END */
import Echarts from "./components/Echart";
import Gears from "./components/Gears";
import "./FR200.less";
const deviceToolKitInstanceFR200 = new DeviceToolKitWM("FR200");
let deviceToolKitInstance = deviceToolKitInstanceFR200;
let currentTimeTimer: any = null; // 当前项目时间定时器
let CountdownTimer: any = null;
let timer: any = null;
let showTipsTimer: any = null;
let loadingTipsTimer: any = null; // 蓝牙连接提示
// 设备运行时间校准频率,每多少秒校准一次
const TIME_CALIBRATION_FREQUENCY = 5;
const MODE_WORKING_ENUM = {
STANDBY: "standby", // 待命
WORKING: "working", // 工作
PAUSE: "pause",
END: "end",
};
// 不同模式启动前的倒计时时间
let CountDownTime = {};
let DeviceSyncData = {
totalWorkingMinutes: 0,
totalWorkingSeconds: 0,
};
class IotCarePlanFR200 extends Component<any, any> {
constructor(props) {
super(props);
this.state = {
name: "FR200",
title: "FR200", // 页面标题
// 当前设备
currentDevice: {
name: "",
model: "",
},
/** 连接设备 */
hasVersion: false, // 是否已查询到版本号
basicModeList: [], //模式列表
modelActiveIndex: 0, //模式下标
sliderProgress: 22,
DeviceConnectStatus: 1, // 设备连接状态 0未连接 1已连接
Electricity: 4, // WL200电量
matrixElectricity: 4, // WE200发箍电量
workMode: "", //当前模式
// 挡位调节组件参数
GearData: [
{ name: "额头", forehead: 5, Total: 10 },
{ name: "左脸颊", forehead: 6, Total: 10 },
{ name: "右脸颊", forehead: 2, Total: 10 },
],
waterStepList: [
{
value: "Step1",
name: "额头",
finish: false,
schedule: 0,
color: "#c2e5f3",
forehead: 0,
},
{
value: "Step2",
name: "左脸颊",
finish: false,
schedule: 0,
color: "#c2e5f3",
forehead: 0,
},
{
value: "Step3",
name: "右脸颊",
finish: false,
schedule: 0,
color: "#c2e5f3",
forehead: 0,
},
],
waterStepIndex: 0,
// 进度条定时器
timerIdSchedule: null,
timerIdSuccess: null,
currentShowDialog: "",
showVideoPlayBtn: true, // 视频播放按钮
duration: 0, // 视频总时长
hadShowBreakTips: false, // 是否展示过支架断开提示
isConnectShow: false, // 是否弹出连蓝牙弹窗:在蓝牙断开时弹出
/** 连接设备 End */
/** 护理过程 */
currentGear: 5, // 默认档位
isRuningTest: 1, // 是否正在测试
isShowStepTips: false, // 是否显示介绍步骤弹窗
isConnectionBlutoot: true, // 是否已连接蓝牙
isShowNurse: true, // 是否开始并显示护理 FR200默认已经开始准备护理
isStopNurse: false, // 是否暂停护理
isEndNurse: false, // 是否结束护理
errorTips: "", // 错误提示
/** 护理过程 END*/
// 模式列表
currentWorkModeType: 1, // 现在的模式类型
currentVideoSrc: "", // 现在模式的视频地址
isModeLock: false, // 模式是否锁定
isSwitchActiveMode: false, // 是否显示弹窗切换模式
ModeList: [],
ModeType: "all", // all 1基础护理 2专区护理 3专研促渗 4敏期护理 5智能测肤
ActiveModeItem: {
openSourceData: [],
}, // 当前选中模式
SwitchActiveModeItem: {}, // 切换选中模式
ModeID: "mode_", // 模式KEY
activeModeID: "", // 当前选中模式ID:用于高亮
ModeStepIndex: 0, // 当前护理功效步骤:每个步骤时间不定,所以时间另外计算,根据步骤显示
ModeStepTimeArray: [], // 护理功效时间步骤用于切换显示GIF
// TestModeStepIndex: 0, // 水分测试步骤
EssenceStepIndex: 0, // 精华促渗步骤
MaskModeStepIndex: 0, // 面膜促渗步骤
EssenceBuzzingIndex: 0, // 精华蜂鸣
EssenceVibrateIndex: 0, // 精华震动
MaskModeBuzzingIndex: 0, // 面膜蜂鸣
MaskModeVibrateIndex: 0, // 面膜震动
currentServiceData: {
// 当前展示的开启暂停GIF: 因为时间判断不方便,所以单独领出来
startSource: "",
stopSource: "",
},
// 倒计时
isShowCountdown: false, // 倒计时弹窗
countdown: 3,
// 是否结束护理
isEndCarePlan: false,
currentTime: "10:00", // 倒计时时间WR200以视频为准
currentVideoTime: "10:00", // 当前视频时间
// 护理时间不够
isNotEnoughTime: false,
// 通用错误提示
isShowErrorTipsText: false, // 护理模式切换错误弹窗
errorTipsText: "", // 护理模式切换错误提示
isShowNursingSuccess: false, // 护理成功弹窗
isShowTipsSave: false, // 切换模式时,提示是否保存部分护理记录
// 初次护理弹窗
isFirstTipShow: false,
nurseInfo: [],
// 上一次护理记录未生成,是否继续连接设备
isShowReReadRecordConnect: false,
// isFirstEntryMode: false, // 模式首次打开
isShowHistoryMsg: false, // 是否显示正在同步历史
showEcharts: false,
echartsData: "", //传给echarts图表的数据
};
}
// 不涉及渲染的页面变量
isRuning: any = true; // 设备默认运行中fr200贴脸就会自动开始工作
jsonStatus: any = {}; // 同步设备返回数据,用于结束
workJsonStatus: any = {}; // 同步工作中的仪器
tempModeCurrent: any = {}; // 临时保存的当前模式
elapsedTime: any = 0; // 设备已运行时间
workStatus: any = ""; // 工作状态
FR200NursingHistory: any = null; // 护理缓存历史
hadCheckReport = false; // 是否已检查仪器护理记录
hadGotInstrumentHistoryData = false; // 是否已缓存仪器历史数据
hadLoadedPage = false; // 判断是否首次进入页面
// FR200同步状态
FR200Status: any = {
gear: 1, // 1-5 挡位
isCharging: false, // 是否充电
joulePerSecond: 0, // 每秒焦耳 0-10
nasolabialOrMandibularOutput: false, // 鼻唇或下颌输出
partition: 0, // 分割?
pointOutChangeSide: false, // 交叉输出点
impedance: 107, // 阻抗/能量等级1档<200 200<2档<280 280<3档<360 后面以此类推每加一档+80抗阻
};
// 1档 等于0<200,2档等于200<280,3档等于280<360
/** FR200模式类型名称 */
ModeTypeArray: string[] = [
"all",
"base",
"eyes",
"zone",
"permeation",
"sensitive",
"intelligence",
];
/** 基础版:脸部/眼部/PRO 设备使用时,会自动开启暂停 */
BaseModeType: string[] = [
"face",
"eyes",
"nasolabialFold",
"mandibularLine",
"headLiftingPro",
];
async onLoad(option) {
console.log(option, "跳转过来的数据");
if (option.modeId) {
this.setState({ activeModeID: option.modeId });
}
// 保持屏幕常亮
Taro.setKeepScreenOn({
keepScreenOn: true,
});
this.initData();
this.getInstrumentClockSummary();
this.getInstrumentClockDetail();
}
componentDidMount() {}
componentWillUnmount() {}
componentDidShow() {
console.log("页面显示了");
if (!this.hadLoadedPage) {
this.hadLoadedPage = true; // 二次进入页面(非首次进入)
return;
}
this.getFR200NursingHistory();
// 重置初始值,每次进入页面重新检查面罩护理记录
this.hadCheckReport = false;
this.hadGotInstrumentHistoryData = false;
}
componentDidHide() {
console.log("Hide");
// 页面隐藏后,下次显示需要重新检查记录
this.hadCheckReport = false;
}
async initData() {
let obj = getStorageSync("instrument_detail");
if (obj) {
this.setState({
currentDevice: obj,
title: obj.name,
});
await this.GetModeList(obj.id);
// 如果不存在设备模式值,则判断为首次进入,弹窗提示
let isFirstTipShow = getStorageSync("first_instrument_" + obj.id);
if (!isFirstTipShow) {
this.firstNurseInfo();
}
}
// 开发者工具
const platform = Taro.getSystemInfoSync().platform;
if (platform !== "devtools") {
// 仅手机端初始化蓝牙
this.init();
}
}
getOption() {
const option = {
grid: { top: 8, right: 8, bottom: 24, left: 36 },
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
},
yAxis: {
type: "value",
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: "line",
smooth: true,
},
],
tooltip: {
trigger: "axis",
},
// title: {
// text: 'ECharts 示例'
// },
// tooltip: {},
// xAxis: {
// data: ['A', 'B', 'C', 'D', 'E']
// },
// yAxis: {},
// series: [{
// name: '数量',
// type: 'bar',
// data: [5, 20, 36, 10, 10]
// }]
};
return option;
}
async init() {
// 查询离线记录汇总
const queryInstructionParams = {
commandType: "InfoQuery",
infoQueryType: "offlineClockInInfo",
dataType: "summary",
};
let commandBuffer = deviceToolKitInstance.toBleCommand(
queryInstructionParams as any
);
sendCommand({ value: commandBuffer }).then((res) => {
console.log("查询查询离线记录汇总 参数为=>", queryInstructionParams);
});
// 监听蓝牙连接状态改变
Taro.onBLEConnectionStateChange(this.listener);
await this.notifyBLECharacteristicValueChange();
// this.handleWorkStatus(false, MODE_WORKING_ENUM.STANDBY);
}
listener = (res) => {
console.log("listener res", res);
if (res?.connected) return;
// 蓝牙未连接才执行下面逻辑
Taro.offBLECharacteristicValueChange((res) => {
console.log("offBLECharacteristicValueChange", res);
});
clearTimeout(loadingTipsTimer);
console.log(commandMap.WL200Command, "监听到蓝牙断开, 打开断开提示");
this.workStatus = "";
// 显示蓝牙断开弹窗
this.setState({
isConnectShow: true, // 打开蓝牙链接弹窗
isConnectionBlutoot: false, // 断开蓝牙
// isShowCountdown: false, // 关闭倒计时,防止倒计时还在运行
});
};
// 获取模式列表
GetModeList = async (id) => {
let params = {
instrumentId: id,
};
let res = await InstrumentInfo.modeInfoList(params);
if (res.data.code === 200) {
if (res.data.data.length > 0) {
this.setState({
ModeList: res.data.data, // 模式列表
ActiveModeItem: res.data.data[0], // 让模式列表正常显示
ModeType: this.ModeTypeArray[res.data.data[0].modeClass],
});
if (this.state.activeModeID != "") {
let res1 = res.data.data.find((e) => e.id == this.state.activeModeID);
setTimeout(() => {
this.modeCurrentFun(res1);
}, 100);
} else {
setTimeout(() => {
this.modeCurrentFun(res.data.data[0]);
}, 100);
}
let res1 = res.data.data.find((e) => e.id == this.state.activeModeID);
setTimeout(() => {
this.modeCurrentFun(res1);
}, 100);
} else {
this.setState({ ModeList: [] });
}
}
};
/**
* 倒计时弹窗
* param 重置倒计时
* callback 回调函数
*/
showCountdownFun(count = 3, callback: any = null) {
this.setState({
countdown: count,
});
setTimeout(() => {
clearInterval(CountdownTimer);
this.setState({
isShowCountdown: true,
});
CountdownTimer = setInterval(() => {
if (this.state.countdown === 0) {
clearInterval(CountdownTimer);
this.setState({
isShowCountdown: false,
});
if (callback) callback();
} else {
this.setState({
countdown: this.state.countdown - 1,
});
}
}, 1000);
}, 0);
}
/**
* @name 选中/切换护理模式
* */
modeCurrentFun = async (data, isNotCheck = false) => {
let { isShowNurse, activeModeID } = this.state;
// 护理检查改变模式,是否提示切换护理模式
// isNotCheck为真时不进行校验直接切换
this.tempModeCurrent = data;
// 仅在未开始护理前,切换模式的时候提示模式弹窗
// FR200默认开始护理
if (!isShowNurse) {
this.openStepTips();
}
// 如果按钮不可点击则报错,内部自带检查底部按钮函数
// this.onEmitErrorTips();
if (!isNotCheck) {
let isReturn = this.modeRuningChange();
if (isReturn) return;
}
// 根据模式,动态设置底部按钮样式
let currentWorkModeType = 1;
if (data.modeType === "moistureTest") {
currentWorkModeType = 3;
} else if (
data.modeType === "maskPenetration" ||
data.modeType === "essence"
) {
currentWorkModeType = 2;
}
this.setState({
ActiveModeItem: data,
activeModeID: data.id,
ModeID: "mode_" + data.id,
ModeStepIndex: 0,
waterStepIndex: 0, // 水分测试步骤
EssenceStepIndex: 0, // 精华促渗步骤
MaskModeStepIndex: 0, // 面膜促渗步骤
ModeType: this.ModeTypeArray[data.modeClass],
currentWorkModeType,
});
// 切换模式时:重新设置视频地址
this.VideoSrcLoad(data.modeVideo);
// 开发中,暂时允许直接切换
// 每次切换模式时清空一下历史数据
this.changeItemUpdateFR200NursingHistory();
this.stepNext(); // 仅切换模式,不执行开始逻辑
// FR200水分测试不可自动运行需手动点击开始测试手动启动检测
// 其他模式可以自动运行
if (data.modeType !== "moistureTest") {
setTimeout(() => {
this.onNursingTap("switch");
}, 800);
}
};
/** 设备运行中切换模式 */
modeRuningChange() {
// 运行中切换模式逻辑
// 当且仅当,护理模式时长大于设备最低时常时,提示是否保存护理记录。
// 若不满足,直接切换
if (
this.workStatus === MODE_WORKING_ENUM.PAUSE ||
this.workStatus === MODE_WORKING_ENUM.WORKING
) {
const { totalWorkingMinutes, totalWorkingSeconds } = DeviceSyncData;
const totalTime = totalWorkingMinutes * 60 + totalWorkingSeconds; // 设备时间
let { ActiveModeItem } = this.state;
if (!ActiveModeItem || totalTime === 0) {
return false;
}
if (this.isRuning && this.state.DeviceConnectStatus == 1) {
// 提示切换护理模式
if (this.isCheckNurseTime()) {
// 满足时间条件,提示是否保存部分护理记录
this.judgementWorkStatus(
MODE_WORKING_ENUM.PAUSE,
this.state.ActiveModeItem?.modeType
);
this.setState({
isShowTipsSave: true,
});
return true;
}
}
}
return false;
}
// 加减组件- 减号操作
handleMinus = async (data, inde) => {
let GearData = this.state.GearData;
if (GearData[inde].forehead !== 1) {
GearData[inde].forehead = GearData[inde].forehead - 1;
this.setState({ GearData });
}
};
// 加减组件- 加号操作
handleAdd = async (data, inde) => {
let GearData = this.state.GearData;
if (GearData[inde].forehead !== GearData[inde].Total) {
GearData[inde].forehead = GearData[inde].forehead + 1;
this.setState({ GearData });
}
};
/** 切换护理模式 */
switchModeCurrentFun = async (data) => {
this.setState({
SwitchActiveModeItem: data,
activeModeID: data.id,
ModeID: "mode_" + data.id,
});
};
// 打开模式切换弹窗
openModeSwitch = () => {
console.log("openModeSwitch");
this.setState({
isSwitchActiveMode: true,
});
};
// 取消并关闭切换护理模式弹窗
cancelModeSwitchBtn = () => {
this.setState({
isSwitchActiveMode: false,
});
};
// 弹窗确定切换护理模式
confirmModeSwitchBtn = () => {
let { SwitchActiveModeItem } = this.state;
this.cancelModeSwitchBtn();
this.modeCurrentFun(SwitchActiveModeItem);
this.setState({
ModeType: this.ModeTypeArray[SwitchActiveModeItem.modeClass],
});
};
stepNext = () => {
let modeClass = this.state.ActiveModeItem.modeClass;
this.workStatus = "pause";
this.isRuning = true; // 暂停也是运行中
this.setState({
ModeType: this.ModeTypeArray[modeClass],
isShowNurse: true,
isStopNurse: true,
});
setTimeout(() => {
this.handleWorkStatus(false, MODE_WORKING_ENUM.STANDBY);
});
};
/** 开始护理按钮:点击开始,页面进行到下一步 */
onStartNurse = async () => {
this.stepNext();
setTimeout(() => {
this.onNursingTap();
// // 倒计时弹窗: 倒计时完成后,自动开始,并判断弹窗
// let downNum = CountDownTime[this.state.ActiveModeItem.modeType] || 3;
// this.showCountdownFun(downNum, () => {});
}, 500);
// 如果检查失败,则报错
this.onEmitErrorTips();
};
/** 完成护理,跳转到水分 */
onsuccess = async () => {
let waterStepList = this.state.waterStepList;
this.setState({
isShowNursingSuccess: true,
});
// return;
let { currentDevice, ActiveModeItem } = this.state;
let params: any = {};
params = {
instrumentId: currentDevice.id,
instrumentName: currentDevice.name,
modeId: ActiveModeItem.id,
modeName: ActiveModeItem.modeName,
nursingTime: s_to_hms(this.elapsedTime),
nursingData: JSON.stringify({
GearData: [...waterStepList],
}),
};
// params = { ...params, ...nursingData };
let res: any = await InstrumentInfo.apiNursingLog.addLog(
JSON.stringify(params)
);
setTimeout(async () => {
this.setState({
isShowNursingSuccess: false,
});
let date = new Date();
let year = date.getFullYear();
let month = (date.getMonth() + 1).toString().padStart(2, "0");
let day = date.getDate().toString().padStart(2, "0");
let formattedDate = `${year}.${month}.${day}`;
this.moistureTest(
params.nursingData,
formattedDate,
ActiveModeItem.id,
currentDevice.id
);
}, 2000);
};
async moistureTest(
nursingData,
formattedDate,
ActiveModeItemId,
currentDeviceId
) {
let data = {
queryDate: formattedDate,
instrumentId: currentDeviceId,
};
let res = await InstrumentInfo.fr200.moistureTest(data);
let echartsData = res.data.rows;
for (let i = 0; i < echartsData.length; i++) {
for (let j = i + 1; j < echartsData.length; j++) {
if (
echartsData[i].createTime.split(" ")[0] ==
echartsData[j].createTime.split(" ")[0]
) {
let result =
Date.parse(echartsData[i].createTime) -
Date.parse(echartsData[j].createTime);
if (result < 0) {
echartsData.splice(i, 1);
} else {
echartsData.splice(j, 1);
}
}
}
}
let gears: any = [];
let eDate: any = [];
echartsData?.map((item) => {
console.log(item, "查看数据");
const result = item.createTime.split(" ")[0].substring(5);
eDate.push(result);
item.nursingData = JSON.parse(item.nursingData);
let level: any = 0;
item.nursingData?.GearData?.map((gear) => {
level = level + gear.forehead;
});
level = Math.floor(level / 3);
gears.push(level);
});
echartsData = {
gears,
eDate,
};
setStorageSync("moistureEachtsData", JSON.stringify(echartsData));
let report =true
// go(`/recoding/pages/moisture_test_report/moisture_test_report?data=${allData.nursingData}&date=${allData.createTime}&modeId=${allData.modeId}&id=${allData.instrumentId}&echartsData=${JSON.stringify(echartsData)}`);
go(
`/recoding/pages/moisture_test_report/moisture_test_report?data=${nursingData}&date=${formattedDate}&modeId=${ActiveModeItemId}&id=${currentDeviceId}&echartsData=${JSON.stringify(
echartsData
)}&report=${report }`
);
}
/**
* @name 不可切换光照提示
* @description 检测紧贴肌肤
*/
onEmitErrorTips = async () => {
setTimeout(() => {
let { ActiveModeItem } = this.state;
// 按钮不可点击时,提示报错
this.showTips("检测到您的设备没有紧贴肌肤,请紧贴肌肤后重新尝试");
});
};
look() {
let that = this;
// this.setState({ showEcharts: !this.state.showEcharts });
let stop = 0;
let time = setInterval(function () {
stop++;
let random = Math.random();
that.setState({ echartsData: random });
if (stop >= 20) {
clearInterval(time);
}
}, 1000);
}
updata() {}
// 绘制能量图
drawProwerPicture() {}
/** 切换光照 */
onSwitchChange = async () => {
// todo
let { isStopNurse } = this.state;
if (isStopNurse) {
// 开始光照逻辑
this.onNursingTap();
this.switchVideoPlay(); // 开始
} else {
// 暂停光照逻辑
this.handleWorkStatus(false, MODE_WORKING_ENUM.PAUSE);
this.switchVideoPause(); // 暂停
}
this.setState({
isStopNurse: !isStopNurse,
});
};
/**
* @name 每次进入设备运行页,打开首个模式的介绍弹窗
*/
openStepTips = () => {
let isFirstEntryModeNot = getStorageSync(
"isFirstEntryMode_" + this.state.currentDevice.id
);
// 1.如果没有持久化不再提示,每次进入都会弹窗提示
if (!isFirstEntryModeNot) {
// 2.必须要有数据才弹窗
if (this.state.ActiveModeItem.openSourceData.length > 0) {
this.setState({ isShowStepTips: true });
}
}
};
closeStepTips = (data) => {
if (data.isLocal) {
setStorageSync("isFirstEntryMode_" + this.state.currentDevice.id, true); // 关闭首次进入弹窗
}
this.setState({ isShowStepTips: false });
};
/** 蓝牙连接相关 */
switchBLEMatch = (jsonStatus: any) => {
console.log("蓝牙连接相关", jsonStatus);
switch (jsonStatus.bleCommandType) {
// 如果设备配对链接发送配对码的时候,设备应答小程序配对码是否正确。
case "SendMatchCode":
if (jsonStatus.matchedSuccess) {
console.log("设备配对成功");
this.setState({
DeviceConnectStatus: 1,
});
}
break;
}
};
// 蓝牙特征更改
notifyBLECharacteristicValueChange = () => {
console.log("notifyBLECharacteristicValueChange deviceInfo 参数为=>");
const bluetoothInfo = this.props.bluetoothInfo;
notifyBLECharacteristicValueChange({
deviceId: bluetoothInfo.deviceId,
servicesuuid: bluetoothInfo.servicesuuid,
characteristicsuuid1: bluetoothInfo.characteristicsuuid1,
characteristicsuuid0: bluetoothInfo.characteristicsuuid0,
}).then((res) => {
Taro.onBLECharacteristicValueChange((value) => {
const jsonStatus: any = deviceToolKitInstance.toJsonStatus(value.value);
console.log(
"onBLECharacteristicValueChange jsonStatus => ",
jsonStatus
);
if (!jsonStatus || jsonStatus == null) {
return;
}
this.workStatus = jsonStatus.workStatus; // 记录工作状态
// end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而言处理流程都一样
if (jsonStatus.workStatus && jsonStatus.workStatus == "endWork") {
jsonStatus.workStatus = "end";
console.log(jsonStatus.workStatus, "护理结束");
}
switch (jsonStatus?.commandType) {
//设备配对和连接的返回
case "BleMatch":
// 蓝牙相关指令
this.switchBLEMatch(jsonStatus);
break;
//设备状态同步
case "DeviceStatusSync":
if (jsonStatus.battery) {
// 防止抖动
this.setState({
Electricity: jsonStatus.battery,
});
}
switch (jsonStatus.workStatus) {
case "standby":
//设备的待机状态 可能workMode字段为空
console.log("设备状态同步 待机状态", jsonStatus);
if (this.BaseModeType.includes(jsonStatus.workMode)) {
this.openTips("检测到您的设备没有紧贴肌肤,请紧贴肌肤");
}
break;
case "pause":
//设备的暂停状态
console.log("设备状态同步 暂停状态", jsonStatus);
if (this.BaseModeType.includes(jsonStatus.workMode)) {
this.openTips(
"检测到您的设备没有紧贴肌肤,请紧贴肌肤后重新尝试"
);
}
break;
case "working":
//设备的运行中状态
console.log("设备状态同步 工作中状态", jsonStatus.workMode);
// 脸部模式
if (this.BaseModeType.includes(jsonStatus.workMode)) {
this.closeTips();
}
break;
default:
break;
}
if (jsonStatus.workMode === "moistureTest") {
if ("success" === jsonStatus.testStatus) {
let waterStepList = this.state.waterStepList;
// 到达第几个step
let waterStepIndex = this.state.waterStepIndex;
// 代表5秒以后最后拿到的结果
if (waterStepList[waterStepIndex].finish) {
// 获取等级
waterStepList[waterStepIndex].forehead =
jsonStatus.waterLevel;
// 检测完成
if (waterStepIndex === 2) {
this.setState({
isRuningTest: 4,
});
} else {
// 启动检测
this.setState({
isRuningTest: 1,
});
}
// 一共有3条数据
let num = waterStepIndex;
if (waterStepIndex < 2) {
num = waterStepIndex + 1;
this.waterTestNext(num);
}
this.setState({
waterStepIndex: num,
waterStepList,
});
}
} else {
let waterStepList = this.state.waterStepList;
let waterStepIndex = this.state.waterStepIndex;
// 5秒后获取的结果
if (waterStepList[waterStepIndex].finish) {
// 获取失败后把进度条清理0
waterStepList[waterStepIndex].schedule = 0;
waterStepList[waterStepIndex].finish = false;
this.setState({
waterStepList,
isRuningTest: 3,
});
}
}
// 水分测试
// testStatus:success
}
console.log("设备运行中?", this.isRuning);
if (jsonStatus?.workMode === this.state.ActiveModeItem.modeType) {
if (this.state.workMode !== jsonStatus?.workMode) {
this.setState({
workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时,才允许改变小程序变量缓存
});
}
// 判断设备是否在运行中(护理中)
// 仅当设备模式与小程序是否一致,才允许更改设备运行时间
if (this.isRuning) {
if (
this.state.DeviceConnectStatus === 1 &&
jsonStatus.workStatus !== MODE_WORKING_ENUM.END
) {
// 水分测试手动检测时间,不自动计算倒计时
if (jsonStatus?.workMode !== "moistureTest")
this.updateDeviceSyncData(
{
totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
},
jsonStatus
);
}
}
}
break;
//设备对控制指令的响应
case "DeviceControl":
console.log("设备控制响应", jsonStatus);
if (jsonStatus.responseStatus == "OK") {
console.log("发送控制指令成功");
this.workJsonStatus = jsonStatus;
this.workStatus = jsonStatus.workStatus;
setTimeout(() => console.log("this.workStatus", this.workStatus));
if (jsonStatus.battery) {
this.setState({
Electricity: jsonStatus.battery,
});
}
// 判断设备主动上报的关机事件
if (jsonStatus.workStatus === MODE_WORKING_ENUM.END) {
// 判断id是否一致, 一致的话则生成护理报表, 并提示
if (jsonStatus.id == this.FR200NursingHistory.id) {
debounce(
this.checkInstrumentRecord.bind(this, jsonStatus),
500
);
}
return;
}
if (jsonStatus?.workMode === this.state.ActiveModeItem.modeType) {
this.setState({
workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时,才允许改变小程序变量缓存
});
// 判断是否在isRuning(护理中)
// 仅当设备模式与小程序是否一致,才允许更改设备运行时间
if (
this.state.DeviceConnectStatus === 1 &&
this.isRuning &&
jsonStatus.workStatus !== MODE_WORKING_ENUM.END
) {
this.updateDeviceSyncData(
{
totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
},
jsonStatus
);
}
}
if (
jsonStatus.workMode === MODE_WORKING_ENUM.WORKING &&
this.isRuning
) {
const { ActiveModeItem } = this.state;
const item = ActiveModeItem;
if (jsonStatus.workMode !== item.modeType) {
clearTimeout(loadingTipsTimer);
this.setState({
isShowCountdown: false,
});
}
}
}
break;
// 设备对信息查询指令的响应
case "InfoQuery":
console.log("设备对信息查询指令的响应 InfoQuery", jsonStatus);
switch (jsonStatus.infoQueryType) {
// 离线记录
case "offlineClockInInfo":
console.log("离线记录", jsonStatus);
break;
// 版本信息
case "versionInfo":
console.log("版本信息", jsonStatus);
break;
// 时间同步
case "timeSync":
console.log("时间同步", jsonStatus);
break;
default:
break;
}
break;
default:
break;
}
});
/**
* 延迟600毫秒获取附属设备状态
*/
const querySubDeviceArrayBuffer = deviceToolKitInstance.toBleCommand({
...bleCommandSamples.querySubDevice,
queryType: "WL200",
} as any);
setTimeout(() => {
console.log("发送查询附属设备指令 querySubDeviceArrayBuffer");
sendCommand({
value: querySubDeviceArrayBuffer,
});
}, 600);
/**
* 延迟500毫秒获取设备电量
*/
const queryDeviceArrayBuffer = deviceToolKitInstance.toBleCommand(
bleCommandSamples.queryDeviceStatus as any
);
setTimeout(() => {
console.log("发送查询设备电量指令");
sendCommand({
value: queryDeviceArrayBuffer,
});
}, 500);
});
};
/**监听关机事件*/
onEndDevice = () => {
this.rmFR200NursingHistory(this.FR200NursingHistory, true);
// 判断护理时间,如果不足,则提示不足
if (!this.isCheckNurseTime()) {
this.setState({ isNotEnoughTime: true });
} else {
this.endNurseFun();
}
};
/** 同步设备运行信息:运行时间 */
updateDeviceSyncData = (newData, jsonStatus) => {
DeviceSyncData = {
...DeviceSyncData,
...newData,
};
if (newData.hasOwnProperty("totalWorkingSeconds")) {
this.renderDeviceStatus.renderWorkTime(jsonStatus);
}
};
// 页面同步护理剩余时间
renderDeviceStatus = {
renderWorkTime: (jsonStatus) => {
const { totalWorkingMinutes, totalWorkingSeconds } = DeviceSyncData;
let { ActiveModeItem, currentTime } = this.state;
const totalTime = totalWorkingMinutes * 60 + totalWorkingSeconds;
console.log("仪器上报的已经运行的总秒数", totalTime);
console.log("时间校准频率默认5秒一次", TIME_CALIBRATION_FREQUENCY);
//对比仪器上报运行的总秒数 和小程序页面运行的已经运行的总秒数,如果不一致就进行校准
let sceneTime = ActiveModeItem?.breakTimeStr
? minSecToS(ActiveModeItem.breakTimeStr)
: minSecToS(this.state.currentVideoTime); // 场景时间
console.log("场景时间 sceneTime", sceneTime);
console.log("当前显示时间 currentTime", currentTime);
console.log("设备运行时间 totalTime", totalTime);
// 更新界面倒计时
this.resetTimer();
if (
sceneTime > totalTime &&
this.isRuning &&
this.state.DeviceConnectStatus == 1
) {
// 界面倒计时同步设备时间
const t = sceneTime - totalTime; // 场景时间 - 已运行时间 = 剩余时间
this.setState({
currentTime: s_to_ms(t),
});
} else {
this.setState({
currentTime: "00:00",
});
this.judgementWorkStatus(MODE_WORKING_ENUM.END, jsonStatus.workMode);
}
// 每次同步后,更新历史缓存
setTimeout(() => {
this.updateFR200NursingHistory(null, jsonStatus);
}, 100);
},
};
// 仪器开始倒计时
setLoadingTips(time) {
this.setState({
countdown: time,
});
if (time >= 0) {
loadingTipsTimer = setTimeout(() => {
this.setLoadingTips(--time);
}, 1000);
} else {
// 停止倒计时
// that.data.startSettingCountDown = false;
this.setState({
isShowCountdown: false,
});
}
}
/**
* 设备上报不同状态
* params 工作状态 工作模式 响应状态
*/
judgementWorkStatus(nWorkStatus, nWorkMode) {
const { ActiveModeItem, ModeList, currentVideoTime } = this.state;
const opts: any = {};
// ActiveModeItem
let nowModeItem;
if (nWorkMode) {
nowModeItem = ModeList.find((item) => {
return item.modeType === nWorkMode;
});
}
opts.workStatus = nWorkStatus;
let nowCurrentTime = currentVideoTime;
// 完成重连同步则删除重连时间字段
if (ActiveModeItem?.breakTimeStr) {
nowCurrentTime = ActiveModeItem?.breakTimeStr;
}
const statusF = {
sleep: () => {
this.setState({
isShowCountdown: false,
});
},
standby: () => {
this.setState({
isShowCountdown: false,
});
},
setting: () => {
this.isRuning = true;
this.setState({
title: "正在护理",
isStopNurse: false,
});
if (nowModeItem) {
opts.currentTime = nowCurrentTime;
}
// 倒计时loading
// if (!this.state.isShowCountdown) {
// this.setState({
// isShowCountdown: true,
// });
// this.setLoadingTips(CountDownTime[workMode] || 6);
// }
},
working: () => {
this.setState({
title: "正在护理",
isStopNurse: false,
isShowCountdown: false,
});
this.closeTips();
},
pause: () => {
clearInterval(currentTimeTimer);
this.setState({
isShowCountdown: false,
});
this.setState({
title: "暂停护理",
isStopNurse: true,
});
},
end: () => {
// 已进入了报告阶段, 防止重复进入, 主要防止在手动点击结束护理接收到仪器消息
console.log("END 护理结束");
clearInterval(currentTimeTimer);
this.endnursing(true);
},
};
statusF[nWorkStatus] && statusF[nWorkStatus]();
if (Object.keys(opts).length) {
this.setState(opts);
}
}
/**
* 保存护理报告
* 1.是否跳转 2.数据
* */
saveNurseReport = async (isJump = true, from) => {
this.endNurseFun();
};
/**
* 结束护理
* param isAuto 是否仪器自动结束
*/
endnursing = (isAuto) => {
if (isAuto == true) {
// 仪器自动上报完成, 直接上报并跳转报告页
clearInterval(currentTimeTimer);
const isEnough = this.isCheckNurseTime();
if (isEnough) {
this.saveNurseReport(true, "endnursing");
}
} else {
// 手动点击结束, 弹出弹窗, 看看是否需要结束
this.onEndPlan();
}
};
// 重置并同步计时器
resetTimer = () => {
// 切换模式后, 需要重新设置计时器, 以防进行中的计时器
currentTimeTimer && clearInterval(currentTimeTimer);
currentTimeTimer = setInterval(() => {
let {
DeviceConnectStatus,
currentTime,
ActiveModeItem,
currentVideoTime,
} = this.state;
if (
this.workStatus == MODE_WORKING_ENUM.WORKING &&
this.isRuning &&
DeviceConnectStatus == 1
) {
let totalSeconds = ActiveModeItem?.breakTimeStr
? minSecToS(ActiveModeItem.breakTimeStr)
: minSecToS(currentVideoTime);
// 现在的倒计时剩余时间:同步时检查是否断开重连,如果是,则使用断开的剩余时长,进行倒计时计算
let currentSeconds = minSecToS(currentTime);
let checkTime = totalSeconds - currentSeconds;
// 缓存经过的时间:用于接口提交
this.elapsedTime = checkTime;
// fr200不需要加上中断的时间
// 如果存在中断时间,则要加上间隔的时间
// if (ActiveModeItem?.breakTimeStr) {
// let intervalTime =
// minSecToS(ActiveModeItem.modeTimeStr) -
// minSecToS(ActiveModeItem.breakTimeStr);
// this.elapsedTime += intervalTime;
// }
console.log("this.elapsedTime", this.elapsedTime);
// 判断剩余时间是否大于1
if (currentSeconds >= 1) {
// 小程序显示倒计时
this.setState({
currentTime: s_to_ms(--currentSeconds),
});
// 根据不同的模式,切换步骤到下一步
if (ActiveModeItem.modeType === "essence") {
this.essencePenetrationNext();
} else if (ActiveModeItem.modeType === "maskPenetration") {
this.maskPenetrationNext();
}
} else {
clearInterval(currentTimeTimer);
this.setState({
currentTime: "00:00",
waterStepIndex: 0, // 水分测试步骤
EssenceStepIndex: 0, // 精华促渗步骤
MaskModeStepIndex: 0, // 面膜促渗步骤
});
this.saveNurseReport(true, "setTimer"); // 保存护理计划,并且结束
}
}
}, 1000);
};
/**
* @name 水分测试下一步,手动调用
* @description 步骤+1并设置视频
*/
waterTestNext(index) {
let ActiveModeItem = this.state.ActiveModeItem;
if (index === 0 && ActiveModeItem.stepOneVideo) {
this.VideoSrcLoad(ActiveModeItem.stepOneVideo);
} else if (index === 1 && ActiveModeItem.stepTwoVideo) {
this.VideoSrcLoad(ActiveModeItem.stepTwoVideo);
} else if (index === 2 && ActiveModeItem.stepThreeVideo) {
this.VideoSrcLoad(ActiveModeItem.stepThreeVideo);
}
}
/**
* @name 面膜促渗下一步,根据时间自动调用
* @description 1.切换步骤 2.检测记录蜂鸣/震动的时间节点与步骤
* */
maskPenetrationNext() {
let {
MaskModeStepIndex,
MaskModeBuzzingIndex,
MaskModeVibrateIndex,
ActiveModeItem,
} = this.state;
// 模式多个步骤节点切换
// 已运行时间达到下一节点时,切换
let GearLength = ActiveModeItem.modeGear.length;
if (GearLength && MaskModeStepIndex < GearLength) {
let GearTime = minSecToS(ActiveModeItem.modeGear[MaskModeStepIndex].time);
if (this.elapsedTime > GearTime) {
// 已运行时间达到下一节点,且存在下一节点,步骤切换时更新
if (MaskModeStepIndex < GearLength) {
let index = MaskModeStepIndex + 1; // 提前步骤+1
this.setState({
MaskModeStepIndex: index,
});
this.FR200AutoChangeGear(index);
}
}
}
let BuzzingLength = ActiveModeItem.modeBuzzing.length;
if (BuzzingLength && MaskModeStepIndex < GearLength) {
let BuzzingTime = minSecToS(
ActiveModeItem.modeBuzzing[MaskModeStepIndex].time
);
if (this.elapsedTime > BuzzingTime) {
if (MaskModeBuzzingIndex < BuzzingLength) {
let index = MaskModeBuzzingIndex + 1; // 提前步骤+1
this.setState({
MaskModeBuzzingIndex: index,
});
this.FR200Buzzing();
}
}
}
let VibrateLength = ActiveModeItem.modeVibrate.length;
if (VibrateLength && MaskModeStepIndex < VibrateLength) {
let VibrateTime = minSecToS(
ActiveModeItem.modeVibrate[MaskModeStepIndex].time
);
if (this.elapsedTime > VibrateTime) {
if (MaskModeVibrateIndex < VibrateLength) {
let index = MaskModeVibrateIndex + 1; // 提前步骤+1
this.setState({
MaskModeVibrateIndex: index,
});
this.FR200Vibrate();
}
}
}
}
/** @name 精华促渗下一步,根据时间自动调用 */
essencePenetrationNext() {
let {
EssenceStepIndex,
EssenceBuzzingIndex,
EssenceVibrateIndex,
ActiveModeItem,
} = this.state;
// 模式多个步骤节点切换
// 已运行时间达到下一节点时,切换
let GearLength = ActiveModeItem.modeGear.length;
if (GearLength && EssenceBuzzingIndex < GearLength) {
let GearTime = minSecToS(
ActiveModeItem.modeGear[EssenceBuzzingIndex].time
);
if (this.elapsedTime > GearTime) {
// 已运行时间达到下一节点,且存在下一节点,步骤切换时更新
if (EssenceStepIndex < GearLength) {
let index = EssenceStepIndex + 1; // 提前步骤+1
this.setState({
EssenceStepIndex: index,
});
this.FR200AutoChangeGear(index);
}
}
}
let BuzzingLength = ActiveModeItem.modeBuzzing.length;
if (BuzzingLength && EssenceBuzzingIndex < BuzzingLength) {
let BuzzingTime = minSecToS(
ActiveModeItem.modeBuzzing[EssenceBuzzingIndex].time
);
if (this.elapsedTime > BuzzingTime) {
if (EssenceBuzzingIndex < BuzzingLength) {
let index = EssenceBuzzingIndex + 1; // 提前步骤+1
this.setState({
EssenceBuzzingIndex: index,
});
this.FR200Buzzing();
}
}
}
let VibrateLength = ActiveModeItem.modeVibrate.length;
if (VibrateLength && EssenceBuzzingIndex < VibrateLength) {
let VibrateTime = minSecToS(
ActiveModeItem.modeBuzzing[EssenceBuzzingIndex].time
);
if (this.elapsedTime > VibrateTime) {
if (EssenceVibrateIndex < VibrateLength) {
let index = EssenceVibrateIndex + 1; // 提前步骤+1
this.setState({
EssenceVibrateIndex: index,
});
this.FR200Vibrate();
}
}
}
}
/**切换挡位发起蜂鸣:可以切换到现在的挡位?*/
FR200Buzzing = () => {
console.log("FR200Buzzing 蜂鸣", this.elapsedTime);
const { ActiveModeItem, currentGear } = this.state;
let sendParams: any = {
...deviceCommandSamples.pause,
workMode: ActiveModeItem.modeType, // 使用模式
workStatus: "working",
gear: currentGear,
};
if (currentGear > 1) {
sendParams.gear = currentGear - 1;
let pauseArrayBuffer = deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
});
} else {
sendParams.gear = currentGear + 1;
let pauseArrayBuffer = deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
});
}
setTimeout(() => {
sendParams.gear = currentGear;
let pauseArrayBuffer = deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
});
}, 300);
};
/**
* @name FR200自动切换挡位
* @description 需要传参索引
*/
FR200AutoChangeGear = (index: number = 0) => {
console.log("FR200AutoChangeGear 切换挡位", this.elapsedTime);
const { ActiveModeItem, GearData } = this.state;
let gear = GearData[index].forehead;
// 同步挡位
this.setState({
currentGear: gear,
});
let sendParams: any = {
...deviceCommandSamples.pause,
workMode: ActiveModeItem.modeType, // 使用模式
workStatus: "working",
gear: gear,
};
const pauseArrayBuffer = deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
}).then(() => {
this.workStatus = "working";
this.resetTimer();
});
};
/**
* @name FR200震动
* @description 同步设备工作却不改变档位,仅震动
*/
FR200Vibrate = () => {
console.log("FR200Vibrate FR200震动", this.elapsedTime);
const { ActiveModeItem, currentGear } = this.state;
let sendParams: any = {
...deviceCommandSamples.pause,
workMode: ActiveModeItem.modeType, // 使用模式
workStatus: "working",
gear: currentGear,
};
const pauseArrayBuffer = deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
});
};
executePromises = async () => {
let waterStepList = this.state.waterStepList;
let waterStepIndex = this.state.waterStepIndex;
let that =this
await new Promise<void>((resolve) => {
setTimeout(() => {
waterStepList[waterStepIndex].schedule = 100;
that.setState({
waterStepList,
});
resolve();
}, 3000);
}).then(() => {
return new Promise<void>((resolve) => {
setTimeout(() => {
waterStepList[waterStepIndex].finish = true;
that.setState({
waterStepList,
});
resolve();
}, 2000);
});
});
};
// 检测并控制工作状态
handleWorkStatus = async (isBtnClick: boolean, workStatus) => {
const { DeviceConnectStatus, ActiveModeItem } = this.state;
let newWorkStatus =
workStatus ||
(this.workStatus == MODE_WORKING_ENUM.WORKING ? "pause" : "working");
// if (isBtnClick && newWorkStatus == "working") {
// // todo FR200 不判断舱体,判断肌肤
// if (!ActiveModeItem.isCabinMode && DeviceConnectStatus != 1) {
// console.log("DeviceConnectStatus", DeviceConnectStatus);
// this.showTips("检测到您的设备没有紧贴肌肤,请紧贴肌肤后点击重新检测");
// return;
// }
// }
let sendParams: any = {
...deviceCommandSamples.pause,
workMode: ActiveModeItem.modeType, // 使用模式
workStatus: newWorkStatus,
};
console.log(ActiveModeItem, "查看工作状态");
// 水分测试需要特殊处理
// 水分测试准备 水分测试工作 水分测试启动
if (ActiveModeItem.modeType === "moistureTest") {
let that = this;
sendParams.testStatus = "standby"; // 切换为准备
// 3秒定时器逻辑3秒把进度条弄成100再加2秒获取最后结果
if (isBtnClick) {
that.setState({
isRuningTest: 2,
});
this.executePromises()
sendParams.testStatus = "start"; // 点击开始再开始
console.log("点击开始", isBtnClick);
}
}
if (ActiveModeItem.modeType === "maskPenetration") {
sendParams.gear = this.state.currentGear; // 点击开始再开始
}
console.log("准备发送自定义或工作指令", ActiveModeItem, sendParams);
const pauseArrayBuffer = deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
}).then(() => {
this.workStatus = newWorkStatus;
this.resetTimer();
console.info(
`handleWorkStatus 发送${newWorkStatus}指令成功 参数为 =>`,
sendParams
);
});
};
/**
* @name 点击开始护理
* @params type 传值 switch 则用于区分是否切换模式的启动如果是WL200的切换模式则倒计时
*/
onNursingTap(type = "") {
// 如果已禁止运行,则停止执行后续逻辑
if (this.state.isRuningTest === 2) return;
// 防止多次点击
if (this.state.hadClickStart) return;
this.setState({
hadClickStart: true,
});
setTimeout(() => {
this.setState({
hadClickStart: false,
});
}, 500);
const { ActiveModeItem, DeviceConnectStatus } = this.state;
if (DeviceConnectStatus != 1) {
console.log("DeviceConnectStatus 开始处", DeviceConnectStatus);
this.showTips("检测到FR200未连接成功请确认FR200开机并佩戴");
return;
}
// 仅在切换模式的时候,弹窗倒计时.
// if (type === "switch") {
// let downNum = CountDownTime[ActiveModeItem.modeType] || 3;
// this.showCountdownFun(downNum, () => {}); // 倒计时弹窗
// }
// 开始执行护理
this.workStatus = MODE_WORKING_ENUM.WORKING; // 不管当前什么状态,直接设为工作状态
this.handleWorkStatus(true, MODE_WORKING_ENUM.WORKING);
this.setState({
isStopNurse: false,
});
}
// 结束护理
endNurseFun() {
this.handleWorkStatus(false, "end");
if (this.isCheckNurseTime()) {
this.PostNursingLogClock();
} else {
// 时间不满足,回到主页
this.handleWorkStatus(false, "end");
this.setState({
isEndCarePlan: false,
isNotEnoughTime: true,
});
}
}
/** 检查时间是否达标仪器最低护理时间 */
isCheckNurseTime() {
const { currentDevice, currentVideoTime } = this.state;
let sceneTime = minSecToS(currentVideoTime);
const timeRemaining = sceneTime - minSecToS(this.state.currentTime); // 当前模式已运行时间
let nursingTimeStr = currentDevice?.nursingTimeStr;
let nursingTime = nursingTimeStr ? minSecToS(nursingTimeStr) : 60; // 设备生成护理记录至少需要运行时间
console.log("检查已运行时间", timeRemaining, nursingTime);
if (timeRemaining >= nursingTime) {
return true;
} else {
return false;
}
}
/*** 护理记录 START ***/
/** 小程序查询护理记录概要 */
getInstrumentClockSummary() {
this.hadGotInstrumentHistoryData = true;
console.log("发送指令clockSummary 获取设备护理概要");
setTimeout(() => {
const queryClockSummary = deviceToolKitInstance.toBleCommand({
...(fr200BleCommand.InfoQuery.clockSummary as any),
});
sendCommand({
value: queryClockSummary,
});
}, 1000);
}
/** 小程序查询最近一条护理详情 */
getInstrumentClockDetail() {
this.hadGotInstrumentHistoryData = true;
console.log("发送指令clockDetail 查询最近一条护理详情");
setTimeout(() => {
const queryClockSummary = deviceToolKitInstance.toBleCommand({
...(fr200BleCommand.InfoQuery.clockDetail as any),
});
sendCommand({
value: queryClockSummary,
});
}, 2000);
}
/**
* @title 检查护理记录
* @description
* 1.判断是否存在工作状态:如果不存在,则等待两秒用于连接设备与赋值,再执行后面的代码
*
* 2.判断是否已存在缓存的护理记录:如果没有历史,则缓存
*
* 3.判断是否当天(如果不是当天,则删除记录)
*
* 4.判断设备状态-未运行/已完成/待机
* 4-1.已有缓存护理记录判断ID一致同步时间。若主动结束需判断时间是否满足仪器最低护理时间满足直接跳转护理报告页不满足需提示不满足回到首页
* 4-2.已有缓存护理记录判断ID不一致同步异常。直接提交固定设置为一分钟。
*
* 5.判断设备状态-运行中
* 正常执行逻辑
*
* */
checkInstrumentRecord = async (jsonStatus: any) => {
console.log("检查护理记录");
let { currentDevice, ActiveModeItem, ModeList, currentVideoTime } =
this.state;
await sleep(2);
let isSyncHistory = Taro.getStorageSync("isSyncHistory");
if (isSyncHistory) {
this.setState({ isShowHistoryMsg: false });
Taro.removeStorageSync("isSyncHistory");
}
console.log(
"this.workJsonStatus",
this.workJsonStatus,
this.workJsonStatus.workMode
);
if (this.workJsonStatus.workMode) {
// FR200可能要判断是否水分测试 Test
// console.log("现在运行的模式:", this.workJsonStatus.workMode);
}
// 2.判断是否已存在缓存的护理记录:如果没有历史,则缓存
let workStatus = this.workJsonStatus.workStatus;
let FR200NursingHistory = this.FR200NursingHistory;
if (!this.FR200NursingHistory) {
console.log("小程序缓存没有数据, 忽略");
if (
workStatus == MODE_WORKING_ENUM.WORKING ||
workStatus == MODE_WORKING_ENUM.PAUSE
) {
// 缓存没有数据, 要存缓存
this.setFR200NursingHistory(jsonStatus);
}
return;
}
// 3.判断是否当天(如果不是当天,则删除记录)
if (!dayjs().isSame(FR200NursingHistory?.createDate, "day")) {
console.log("小程序缓存有数据,但是不是当天数据,忽略");
this.rmFR200NursingHistory(FR200NursingHistory);
return;
}
// 仪器缓存模式,判断是否存在于现有模式中
let recordModeItem = ModeList.find((item) => {
return item.id == FR200NursingHistory.modeId;
});
if (!FR200NursingHistory || !recordModeItem) {
console.log("仪器有数据, 但是缓存没有数据, 忽略");
return;
}
console.log("workStatus", workStatus);
console.log("jsonStatus", jsonStatus, this.workJsonStatus);
console.log("currentTime", FR200NursingHistory.currentTime);
let historyElapsedTime =
minSecToS(currentVideoTime) - minSecToS(FR200NursingHistory.currentTime);
this.elapsedTime =
this.elapsedTime > historyElapsedTime
? this.elapsedTime
: historyElapsedTime;
// 4.判断设备状态-未运行/已完成/待机
if (
workStatus == MODE_WORKING_ENUM.STANDBY ||
workStatus == MODE_WORKING_ENUM.END ||
!workStatus
) {
// 判断id是否一致, 一致的话则生成护理报表
if (jsonStatus.id == FR200NursingHistory.id) {
console.log("id一致, 设备没有运行/已完成/待机");
let totalSeconds = jsonStatus.totalSeconds; // 从仪器上获取的使用时间
let nursingTimeStr = currentDevice?.nursingTimeStr;
let nursingTime = nursingTimeStr ? minSecToS(nursingTimeStr) : 60; // 设备生成护理记录至少需要运行时间
if (totalSeconds < nursingTime) {
// 护理时间不足
this.setState({ isNotEnoughTime: true });
this.rmFR200NursingHistory(FR200NursingHistory);
return;
}
// 小程序时间和设备时间,谁大用谁
let timeValue =
totalSeconds > this.elapsedTime
? s_to_hms(totalSeconds)
: s_to_hms(this.elapsedTime);
let params = {
instrumentId: currentDevice.id,
instrumentName: currentDevice.name,
modeId: ActiveModeItem.id,
modeName: ActiveModeItem.modeName,
nursingTime: timeValue,
};
this.handleWorkStatus(false, "end");
let res: any = await this.PostNursingLogClock(params);
console.log("res", res);
this.rmFR200NursingHistory(FR200NursingHistory);
} else {
// ID不一致同步异常统一提交一分钟
let params = {
instrumentId: currentDevice.id,
instrumentName: currentDevice.name,
modeId: ActiveModeItem.id,
modeName: ActiveModeItem.modeName,
nursingTime: "00:01:00",
};
this.handleWorkStatus(false, "end");
let res: any = await this.PostNursingLogClock(params);
console.log("res", res);
this.rmFR200NursingHistory(FR200NursingHistory);
}
} else {
console.log("id一致, 设备运行中或暂停");
// 5.判断设备状态-运行中
// 同步时间
if (jsonStatus.id == FR200NursingHistory.id) {
if (FR200NursingHistory.currentTime) {
this.isRuning = true;
this.resetTimer();
}
}
}
};
/** 获取小程序本地缓存的历史记录 */
getFR200NursingHistory() {
this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
console.log(
this.FR200NursingHistory,
"获取本地数据++++++++++++++++++++++++++++++++++++++++++"
);
// 是否同步历史记录
let isSyncHistory = Taro.getStorageSync("isSyncHistory");
if (isSyncHistory) {
let ActiveModeItem = this.FR200NursingHistory.ActiveModeItem;
// 直接进入开始护理状态
this.setState({
isShowNurse: true,
isShowHistoryMsg: true,
videoTime: this.FR200NursingHistory.videoTime,
tempModeCurrent: ActiveModeItem,
ActiveModeItem: ActiveModeItem,
activeModeID: ActiveModeItem.id,
ModeID: "mode_" + ActiveModeItem.id,
currentTime: this.FR200NursingHistory.currentTime,
});
}
}
/** 设置WL200护理历史 */
setFR200NursingHistory = (jsonStatus: any) => {
let { currentDevice, ActiveModeItem } = this.state;
const params = {
createDate: dayjs().format("YYYY-MM-DD"),
workMode: jsonStatus.workMode,
instrumentId: currentDevice.id,
instrumentName: currentDevice.name,
modeId: ActiveModeItem.id,
modeName: ActiveModeItem.modeName,
id: dayjs().format("YYYY-MM-DD HH:mm:ss"),
neededTotalSeconds: jsonStatus.neededTotalSeconds,
jsonStatus,
ActiveModeItem: this.state.ActiveModeItem,
};
this.FR200NursingHistory = JSON.parse(JSON.stringify(params));
Taro.setStorageSync("FR200NursingHistory", params);
console.log("保存setFR200NursingHistory");
};
/** 更新WL200护理历史运行时间 */
updateFR200NursingHistory = (data: any = null, jsonStatus: any = null) => {
this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
if (this.FR200NursingHistory) {
let params: any = this.FR200NursingHistory;
// 设置当前时间
params.currentTime = this.state.currentTime;
// params.videoTime;
// 设置正确封面
if (!data) {
if (jsonStatus) {
// 缓存每秒数据
if (!params.dataArray) params.dataArray = [];
params.dataArray.push(jsonStatus);
params.jsonStatus = jsonStatus;
params.workMode = jsonStatus?.workMode;
params.modeId = this.state.ActiveModeItem.id;
params.modeName = this.state.ActiveModeItem.modeName;
}
} else {
params.jsonStatus = jsonStatus;
params.workMode = jsonStatus?.workMode;
params.modeId = data.id;
params.modeName = data.modeName;
}
Taro.setStorageSync("FR200NursingHistory", params);
console.log("更新updateFR200NursingHistory");
// 基础模式可在这里调用函数更新图标Echarts
// 最新一条数据jsonStatus
// 注意事项只拿working状态
// todo
} else {
this.setFR200NursingHistory(jsonStatus);
}
};
// 改变模式时清空dataArray防止数据无限叠加
changeItemUpdateFR200NursingHistory() {
this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
if (this.FR200NursingHistory) {
this.FR200NursingHistory.dataArray = [];
Taro.setStorageSync("FR200NursingHistory", this.FR200NursingHistory);
}
}
/**
* @name 删除WL200护理历史
* @description 参数1 护理历史 参数2 强制删除
* 如果传入护理历史ID与现有ID相等则删除。
* 如果参数二为真,则强制删除
*/
rmFR200NursingHistory = (FR200NursingHistory, hard = false) => {
const nowFR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
if (nowFR200NursingHistory) {
Taro.setStorageSync("FR200Echart", nowFR200NursingHistory); // 临时保存用于观看和调试
}
Taro.removeStorageSync("FR200NursingHistory");
};
// 脸部one
todoPromise = async () => {
const nowFR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
console.log(nowFR200NursingHistory, "nowFR200NursingHistory");
// 护理脸部
if (
[
"face",
"eyes",
"nasolabialFold",
"mandibularLine",
"headLiftingPro",
].includes(nowFR200NursingHistory.jsonStatus.workMode)
) {
// 把working=工作中的状态数据筛选出来
let filtered = nowFR200NursingHistory.dataArray.filter(
(item) => item.workStatus === "working"
);
// 能量发数
filtered = filtered.slice(0, 360);
// 脸部能量
let faceEnergy = 0;
filtered.forEach((item) => {
faceEnergy += item.joulePerSecond;
});
// 计算平均数
// let sum = filtered.reduce((accumulator, currentValue) => accumulator + currentValue.impedance, 0);
// let average = sum / filtered.length;
// 最大
let max: any = Math.max(...filtered.map((item) => item.impedance));
max = this.determineTier(max);
// 最小
let min: any = Math.min(...filtered.map((item) => item.impedance));
min = this.determineTier(min);
// 平均数最大等级处于2
let average: any = max / 2;
average = this.determineTier(average);
// 能量图里面的图谱每10秒为一个数组
// 创建一个空数组用于存储分组后的结果
// 创建一个空数组用于存储分组后的结果
let groupedAa: any[] = [];
// 使用循环遍历数组 aa
for (let i = 0; i < filtered.length; i += 10) {
// 提取每组的三个对象
let group = filtered.slice(i, i + 10);
// 找到组中最大的 name 值
let maxName = Math.max(...group.map((obj) => obj.impedance));
// 计算并存储每组的平均数
let average: any = this.determineTier(maxName / 2);
// let average = maxName / 2;
if (average >= 1) {
average = average - 1;
average = average * 10;
}
// 将包含该组对象和平均数的对象添加到 groupedAa 数组中
groupedAa.push(average);
}
let nursingData = {
// nursingTime:result,
nursingData: JSON.stringify({
faceEnergy,
max,
min,
average,
groupedAa,
filtered: filtered.length,
workMode: nowFR200NursingHistory.workMode,
}),
};
return nursingData;
}
return { nursingData: JSON.stringify({ workMode: nowFR200NursingHistory.workMode, }), showFace: true }
};
// 计算挡位
determineTier = (sun) => {
// 定义每档的范围
const tiers = [0, 200, 280, 360, 440, 520, 600, 680, 760, 840];
// 遍历每一档的范围,找到 sun 所属的档
for (let i = 0; i < tiers.length; i++) {
if (sun < tiers[i + 1]) {
return i + 1;
}
}
// 如果 sun 不在任何一档范围内,返回默认档或处理错误
return "10";
};
/** 提交护理记录:完成护理后自动调用,会跳转页面 */
PostNursingLogClock = async (data: any = null, isJump = true) => {
// todo 建议写一个Promise异步函数用 await 执行,在提交前处理好数据
// return;
let { currentDevice, ActiveModeItem } = this.state;
let params = {};
if (data) {
params = data;
} else {
params = {
instrumentId: currentDevice.id,
instrumentName: currentDevice.name,
modeId: ActiveModeItem.id,
modeName: ActiveModeItem.modeName,
nursingTime: s_to_hms(this.elapsedTime),
};
}
let res1: any = await this.todoPromise();
if (!res1?.showFace) {
params = { ...params, ...res1 };
}
console.log(res1, "查看返回数据");
let res2: any = await InstrumentInfo.apiNursingLog.addLog(params);
console.log("PostNursingLogClock", res2);
if (res2.data.code === 200) {
let params = {
instrumentId: currentDevice.id,
};
// 上传护理完成的仪器ID
let res = await InstrumentInfo.apiClock.addClockInstrument(params);
console.log(res, "护理完成");
this.rmFR200NursingHistory(this.FR200NursingHistory); // 护理完成,删除记录
if (isJump) {
this.setState({
isShowNursingSuccess: true,
});
setTimeout(() => {
this.setState({
isShowNursingSuccess: false,
});
this.goFaceReport(
res1,
ActiveModeItem.id,
res2.data.data,
currentDevice.id
); // 跳转
}, 2000);
}
}
};
/*** 护理记录 END ***/
//蓝牙断开连接处理
bluetoothDisconnectProcessing() {
clearInterval(timer);
Taro.offBLEConnectionStateChange(this.listener); // 需传入与监听时同一个的函数对象
Taro.offBLECharacteristicValueChange((res) => {
console.log("offBLECharacteristicValueChange", res);
});
if (!this.state.isToOTA) {
Taro.closeBluetoothAdapter();
}
}
/** 会自动关闭的护理错误提示 */
showTips(ctx) {
if (!ctx) return;
if (showTipsTimer) clearTimeout(showTipsTimer);
this.setState({
errorTips: ctx,
});
showTipsTimer = setTimeout(() => {
this.setState({
errorTips: "",
});
}, 2000);
}
/** 不自动关闭的护理错误提示 */
openTips(ctx) {
if (!ctx) return;
this.setState({
errorTips: ctx,
});
}
/** 关闭护理错误提示 */
closeTips() {
this.setState({
errorTips: "",
});
}
/** 结束护理弹窗 */
onEndPlan = async () => {
this.setState({
isEndCarePlan: true,
});
};
confirmEndBtn = () => {
console.log("confirmEndBtn", this.isCheckNurseTime());
if (this.isCheckNurseTime()) {
this.endNurseFun();
this.cancelEndBtn();
} else {
this.handleWorkStatus(false, "end");
this.setState({
isEndCarePlan: false,
isNotEnoughTime: true,
});
}
};
cancelEndBtn = () => {
this.setState({
isEndCarePlan: false,
});
};
/** 弹窗 END*/
// 打开通用错误弹窗
openErrorTipsText = (str) => {
this.setState({
isShowErrorTipsText: true,
errorTipsText: str,
});
};
// 关闭通用错误弹窗
closeErrorTipsText = () => {
this.setState({
isShowErrorTipsText: false,
});
};
closeNotEnoughTime = () => {
this.setState({
isNotEnoughTime: false,
});
Taro.reLaunch({
url: "/pages/index/index",
});
};
/** 完成护理提交:跳转护理报告页 */
goFaceReport = async (data, id, deviceid, currentDevice) => {
let nursingData = JSON.parse(data.nursingData);
// 跳转前置空定时器,防止重复提交
if (currentTimeTimer) clearInterval(currentTimeTimer);
if (
[
"face",
"eyes",
"nasolabialFold",
"mandibularLine",
"headLiftingPro",
].includes(nursingData.workMode)
) {
let ids = Number(deviceid);
// 获取echarts数据 这个是获取接口更新echarts页面
let res2 = await InstrumentInfo.apiNursingLog.getStatiCDE(ids);
let nursingDatas = JSON.parse(res2.data.data.nursingData);
let obj = {
modeName: res2.data.data.modeName,
data: nursingDatas,
};
let report = true;
go(
"/recoding/pages/face_report_one/face_report_one?id=" +
ids +
"&report=" +
report +
"&obj=" +
JSON.stringify(obj)
);
} else if ("moistureTest" === nursingData.workMode) {
console.log("水分测试");
} else {
console.log("跳转11111111");
let report = true;
go(
"/recoding/pages/face_report/face_report?id=" +
deviceid +
"&recordId=" +
currentDevice +
"&report=" +
report
);
}
};
// 完成配对
pairingChange = () => {
this.setState({
isConnectShow: false,
isShowNurse: true,
});
setTimeout(() => {
this.onNursingTap("switch");
});
};
connectionClose = () => {
this.setState({
isConnectShow: false,
});
Taro.switchTab({ url: "/pages/index/index" });
};
// 手动护理模式切换:提示是否保存护理
/**仅关闭*/
closeTipsSave = () => {
this.setState({
isShowTipsSave: false,
});
};
/**关闭+切换*/
cancelTipsSave = () => {
this.setState({
isShowTipsSave: false,
});
this.modeCurrentFun(this.tempModeCurrent, true); // 不提交护理记录,也不进行校验
};
/**关闭+提交+切换*/
confirmTipsSave = async () => {
this.setState({
isShowTipsSave: false,
});
this.PostNursingLogClock(null, false); // 先提交护理记录
this.modeCurrentFun(this.tempModeCurrent, true); // 不进行校验
};
/** 初次护理信息弹窗 */
firstNurseInfo = async () => {
let { currentDevice } = this.state;
let res = await InstrumentInfo.firstNurseInfo({
instrumentId: currentDevice.id,
});
console.log(res, "接口");
if (res.data.code === 200) {
let isFirstTipShow = getStorageSync(
"first_instrument_" + currentDevice.id
);
console.log(isFirstTipShow, "查看返回值");
if (!isFirstTipShow) {
if (res.data.data.length !== 0) {
// 首次进入页面:自动打开打卡介绍弹窗
this.setState({ nurseInfo: res.data.data, isFirstTipShow: true });
}
setStorageSync("first_instrument_" + currentDevice.id, true);
} else {
this.setState({ nurseInfo: res.data.data });
}
}
};
onTipShowOpen = async () => {
this.setState({ isFirstTipShow: true });
};
onTipShowClose = async () => {
setStorageSync("first_instrument_" + this.state.currentDevice.id, true);
this.setState({ isFirstTipShow: false });
};
/** 初次护理信息弹窗 END */
customBack = () => {
Taro.switchTab({ url: "/pages/index/index" });
};
onModeLockOpen = async () => {
this.setState({ isModeLock: true });
};
onModeLockClose = async () => {
this.setState({ isModeLock: false });
};
// 获取并设置视频时间
GetVideosTime = (event) => {
console.log("获取并设置视频时间GetVideosTime", event?.detail?.duration);
if (event?.detail?.duration) {
let duration = Math.floor(event?.detail?.duration);
let currentTime = s_to_ms(duration);
this.setState({ currentTime, currentVideoTime: currentTime });
}
};
VideoSrcLoad = (video: string = "") => {
this.setState({
currentVideoSrc: "",
});
setTimeout(() => {
this.setState({
currentVideoSrc: video,
});
}, 10);
};
switchVideoPlay = () => {
setTimeout(() => {
let videoRef = Taro.createVideoContext("myVideo", this);
videoRef.play();
}, 100);
};
switchVideoPause = () => {
setTimeout(() => {
let videoRef = Taro.createVideoContext("myVideo", this);
videoRef.pause();
}, 100);
};
render() {
let {
title,
isConnectShow,
GearData,
waterStepList,
waterStepIndex,
isShowStepTips,
isShowNurse,
isStopNurse,
ModeList,
ModeType,
ModeStepIndex,
ActiveModeItem,
currentWorkModeType,
isSwitchActiveMode,
ModeID,
activeModeID,
isShowCountdown,
countdown,
Electricity,
errorTips,
isEndCarePlan,
currentTime,
DeviceConnectStatus,
isShowErrorTipsText,
errorTipsText,
isNotEnoughTime,
isShowNursingSuccess,
currentDevice,
isConnectionBlutoot,
isShowTipsSave,
isFirstTipShow,
nurseInfo,
isRuningTest,
isShowHistoryMsg,
isModeLock,
currentVideoSrc,
currentGear,
showEcharts,
echartsData,
isShowReReadRecordConnect,
currentServiceData,
} = this.state;
return (
<Block>
<Navbar
titleSlot={title}
isBack
isCustomBack
customBack={this.customBack}
/>
<View catchMove>
<PopupAlert
isShow={isModeLock}
zIndex={10020}
myClassName="level-up"
title="提示"
content="该模式即将上线,敬请期待"
confirmButtonText="我知道了"
textAlgin="center"
close={this.onModeLockClose}
confirm={this.onModeLockClose}
/>
<PopupInstrumentUploadTips
isShow={isFirstTipShow}
zIndex={10020}
myClassName="level-up"
title="打卡介绍"
data={nurseInfo}
close={this.onTipShowClose}
confirm={this.onTipShowClose}
/>
<PopupCountdown isShow={isShowCountdown} countdown={countdown} />
<PopupConfirm
isLarge
isClose
isShow={isEndCarePlan}
title="提示"
content="是否结束护理"
textAlgin="center"
cancelButtonText="取消"
confirmButtonText="确定"
close={this.cancelEndBtn}
confirm={this.confirmEndBtn}
/>
<PopupConfirm
isLarge
isClose
isShow={isSwitchActiveMode}
title="护理模式切换"
content={
<ModeListView
ModeID={ModeID}
activeModeID={activeModeID}
isPop
isShowNurse={isShowNurse}
ModeList={ModeList}
ModeType={ModeType}
onEmit={this.switchModeCurrentFun}
onEmitShowAll={this.openModeSwitch}
onModeLockOpen={this.onModeLockOpen}
/>
}
textAlgin="center"
cancelButtonText="取消"
confirmButtonText="确定"
close={this.cancelModeSwitchBtn}
confirm={this.confirmModeSwitchBtn}
/>
{ActiveModeItem.openSourceData.length > 0 && (
<PopupStepTips
isShow={isShowStepTips}
isLarge
isFirstEntry={false}
confirmButtonText="知道了"
data={ActiveModeItem.openSourceData}
close={this.closeStepTips}
/>
)}
<PopupAlert
isShow={isNotEnoughTime}
isClose
title="提示"
content="您的本次护理时间不足,请重新护理"
confirmButtonText="确认"
textAlgin="center"
close={this.closeNotEnoughTime}
confirm={this.closeNotEnoughTime}
/>
<PopupAlert
isShow={isShowErrorTipsText}
isClose
zIndex={10020}
myClassName="level-up"
title="提示"
content={errorTipsText}
confirmButtonText="知道了"
textAlgin="center"
close={this.closeErrorTipsText}
confirm={this.closeErrorTipsText}
/>
<PopupConfirm
isShow={isShowTipsSave}
isClose
zIndex={10020}
myClassName="level-up"
title="提示"
content={
<Block>
<View></View>
<View></View>
</Block>
}
cancelButtonText="取消"
confirmButtonText="确认"
textAlgin="center"
close={this.closeTipsSave}
cancel={this.cancelTipsSave}
confirm={this.confirmTipsSave}
/>
<PopupStatus
isShow={isShowNursingSuccess}
isClose
title="您已结束本次护理"
type="success"
content="正在上传护理记录……"
confirmButtonText="知道了"
textAlgin="center"
close={() => {
/*不需要做处理*/
}}
/>
{isConnectShow && (
<ConnectionBluetoot
deviceInfo={currentDevice}
close={this.connectionClose}
isDisconnect={!isConnectionBlutoot}
offlineChange={() => {}}
pairingChange={this.pairingChange}
upgradeFun={() => {}}
/>
)}
<Popup
show={isShowHistoryMsg}
className="custom-popup"
overlay={false}
>
<View className="sync-history-msg">...</View>
</Popup>
</View>
<View>
<View className="iot-main">
<View className="banner-box">
<View>
<Video
className="video-or-image"
src={currentVideoSrc}
loop
id="myVideo"
objectFit="cover"
enablePlayGesture
showFullscreenBtn={false}
onLoadedMetaData={this.GetVideosTime}
/>
{errorTips && (
<Block>
<View className="msg-tips">
<Image
className="msg-tips-img"
src={require("@/img/tips.png")}
/>
<View className="msg-tips-content">{errorTips}</View>
</View>
</Block>
)}
</View>
<View className="fr200-iot-device">
<View className="item">
<Text className="device-time">
<Text className="time">{currentTime}</Text>
</Text>
</View>
<View className="line" />
<View className="item">
<Text className="gear">{currentGear}</Text>
</View>
<View className="line" />
<ElectricityView
Electricity={Electricity}
DeviceConnectStatus={DeviceConnectStatus}
/>
</View>
</View>
{ModeList.length > 0 && (
<ModeListView
isPop={false}
isShowNurse={isShowNurse}
ModeList={ModeList}
ModeType={ModeType}
ModeID={ModeID}
activeModeID={activeModeID}
onEmit={this.modeCurrentFun}
onEmitShowAll={this.openModeSwitch}
onModeLockOpen={this.onModeLockOpen}
/>
)}
{/* <button onClick={this.look.bind(this)}>显示echarts </button>
<button onClick={this.updata.bind(this)}>添加数据 </button> */}
<View className={classnames({ show: showEcharts })}>
<Echarts data={echartsData}></Echarts>
</View>
{/* {(ActiveModeItem.modeType === "face" ||
ActiveModeItem.modeType === "eyes") && <Echarts></Echarts>} */}
{(ActiveModeItem.modeType === "maskPenetration" ||
ActiveModeItem.modeType === "essence") && (
<Gears
onEmitMinus={this.handleMinus}
onEmitAdd={this.handleAdd}
GearData={GearData}
></Gears>
)}
{ActiveModeItem.modeType === "moistureTest" && (
<WaterTest
isRuningTest={isRuningTest}
stepList={waterStepList}
stepIndex={waterStepIndex}
></WaterTest>
)}
</View>
<Footer
currentWorkModeType={currentWorkModeType}
isRuningTest={isRuningTest}
isStopNurse={isStopNurse}
onEmitStartNurse={this.onStartNurse}
onEmitSwitchChange={this.onSwitchChange}
onEmitEndPlan={this.onEndPlan}
onsuccess={this.onsuccess}
/>
</View>
</Block>
);
}
}
const mapStateToProps = (state) => ({
bluetoothInfo: state.deviceInfo.bluetoothInfo,
});
const mapDispatchToProps = (dispatch) => ({
// userRefresh(data) {
// dispatch(userRefresh(data));
// },
});
export default connect(mapStateToProps, mapDispatchToProps)(IotCarePlanFR200);