|
|
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);
|