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.

2206 lines
68 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";
// eslint-disable-next-line import/no-named-as-default
import React, {
Component,
PropsWithChildren,
useEffect,
useState,
} from "react";
// import Echarts from "./components/Echart/index";
import Gears from "./components/Gears/index";
import {
Block,
View,
Text,
Image,
Video,
Input,
Button,
} from "@tarojs/components";
/*** redux ***/
import { connect } from "react-redux";
/*** redux end ***/
/* 公共组件 */
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/index";
import ModeListView from "./components/ModeList/FR200";
import ModeContent from "./components/ModeContent/FR200";
import Footer from "./components/Footer/FR200";
/* 本页组件 END */
import { go, getStorageSync, setStorageSync, msg } from "@/utils/traoAPI";
import { InstrumentInfo } from "@/utils/Interface";
import "./FR200.less";
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";
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 = {
powerfulSoothing: 6,
Stability: 3,
Brighten: 3,
FirmSkin: 3,
MaskCustom: 6,
BrightenStand: 6,
FirmSkinStand: 6,
SmallpoxSoothingPro: 6,
SmallpoxSoothing: 4,
MixNursePro: 6,
MixNurse: 4,
ScalpCare: 6,
};
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 },
],
gear: { gear: 1 },
currentShowDialog: "",
showVideoPlayBtn: true, // 视频播放按钮
duration: 0, // 视频总时长
hadShowBreakTips: false, // 是否展示过支架断开提示
isConnectShow: false, // 是否弹出连蓝牙弹窗:在蓝牙断开时弹出
/** 连接设备 End */
/** 护理过程 */
isStandStatus: false, // 当前模式是否舱体/支架模式
isShowStepTips: false, // 是否显示介绍步骤弹窗
isConnectionBlutoot: true, // 是否已连接蓝牙
isShowNurse: true, // 是否开始并显示护理 FR200默认已经开始准备护理
isStopNurse: false, // 是否暂停护理
isEndNurse: false, // 是否结束护理
errorTips: "", // 错误提示
/** 护理过程 END*/
// 模式列表
isModeLock: false, // 模式是否锁定
isSwitchActiveMode: false, // 是否显示弹窗切换模式
ModeList: [],
ModeType: "all", // all
modeClass: "", // 1基础护理 2专区护理 3专研促渗 4敏期护理 5智能测肤
ActiveModeItem: {
openSourceData: [],
}, // 当前选中模式
SwitchActiveModeItem: {}, // 切换选中模式
ModeID: "mode_", // 模式KEY
activeModeID: "", // 当前选中模式ID:用于高亮
ModeStepIndex: 0, // 当前护理功效步骤:每个步骤时间不定,所以时间另外计算,根据步骤显示
ModeStepTimeArray: [], // 护理功效时间步骤用于切换显示GIF
currentServiceData: {
// 当前展示的开启暂停GIF: 因为时间判断不方便,所以单独领出来
startSource: "",
stopSource: "",
},
// 倒计时
isShowCountdown: false, // 倒计时弹窗
countdown: 3,
// 是否结束护理
isEndCarePlan: false,
currentTime: "01:00",
// 护理时间不够
isNotEnoughTime: false,
// 通用错误提示
isShowErrorTipsText: false, // 护理模式切换错误弹窗
errorTipsText: "", // 护理模式切换错误提示
isShowNursingSuccess: false, // 护理成功弹窗
isShowTipsSave: false, // 切换模式时,提示是否保存部分护理记录
// 初次护理弹窗
isFirstTipShow: false,
nurseInfo: [],
// 上一次护理记录未生成,是否继续连接设备
isShowReReadRecordConnect: false,
// 按钮是否不可运行:FR200不可禁用
isFooterBtnDisabled: false,
// isFirstEntryMode: false, // 模式首次打开
isShowHistoryMsg: false, // 是否显示正在同步历史
};
}
// 不涉及渲染的页面变量
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抗阻
};
/** FR200模式类型名称 */
ModeTypeArray: string[] = [
"all",
"Base",
"Zone",
"Permeation",
"Sensitive",
"Intelligence",
];
async onLoad() {
// 保持屏幕常亮
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, // 关闭倒计时,防止倒计时还在运行
});
this.footerIsDisabled();
};
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({
ActiveModeItem: res.data.data[0],
ModeList: res.data.data,
});
setTimeout(() => {
this.modeCurrentFun(res.data.data[0]);
}, 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);
}
/** 选中护理模式 */
modeCurrentFun = async (data, isNotCheck = false) => {
let { isShowNurse } = this.state;
// 护理检查改变模式,是否提示切换护理模式
// isNotCheck为真时不进行校验直接切换
this.tempModeCurrent = data;
// 仅在未开始护理前,切换模式的时候提示模式弹窗
// FR200默认开始护理
if (!isShowNurse) {
this.openStepTips();
}
// 如果按钮不可点击则报错,内部自带检查底部按钮函数
this.onEmitErrorTips();
if (!isNotCheck) {
let isReturn = this.modeRuningChange();
if (isReturn) return;
}
let currentServiceData = {
startSource: "",
stopSource: "",
};
if (data.serviceData.length) {
currentServiceData = data.serviceData[0];
}
let currentTime = data.modeTimeStr;
this.setState({
ActiveModeItem: data,
activeModeID: data.id,
ModeID: "mode_" + data.id,
currentServiceData,
ModeStepIndex: 0,
currentTime,
ModeType: this.ModeTypeArray[data.modeClass],
});
setTimeout(() => {
// 设置时间组合
if (data.serviceData.length > 0) {
this.setServiceTimeData();
}
});
// 开发中,暂时允许直接切换
// 每次切换模式时清空一下历史数据
this.changeItemUpdateFR200NursingHistory();
this.stepNext(); // 如果切换模式,则不执行开始逻辑
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 === true && 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 () => {
// 如果检查通过,可运行,则执行下一步
if (!this.footerIsDisabled()) {
this.stepNext();
setTimeout(() => {
this.onNursingTap();
// 倒计时弹窗: 倒计时完成后,自动开始,并判断弹窗
let downNum = CountDownTime[this.state.ActiveModeItem.modeType] || 3;
this.showCountdownFun(downNum, () => {});
}, 500);
return;
}
// 如果检查失败,则报错
this.onEmitErrorTips();
};
/**
* @name 不可切换光照提示
* @description 检测紧贴肌肤
*/
onEmitErrorTips = async () => {
setTimeout(() => {
let { ActiveModeItem } = this.state;
// 按钮不可点击时,提示报错
let isDisabled = this.footerIsDisabled();
if (isDisabled) {
this.showTips("检测到您的设备没有紧贴肌肤,请紧贴肌肤后重新尝试");
}
});
};
// 绘制能量图
drawProwerPicture() {}
/** 切换光照 */
onSwitchChange = async () => {
// todo
let { isStopNurse } = this.state;
if (isStopNurse) {
// 开始光照逻辑
this.onNursingTap();
} else {
// 暂停光照逻辑
this.handleWorkStatus(false, MODE_WORKING_ENUM.PAUSE);
}
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":
this.setState({
Electricity: jsonStatus.battery,
});
switch (jsonStatus.workStatus) {
case "standby":
//设备的待机状态 可能workMode字段为空
console.log("设备状态同步 待机状态", jsonStatus);
// this.judgementWorkStatus(
// MODE_WORKING_ENUM.STANDBY,
// jsonStatus.workMode
// );
break;
case "pause":
//设备的暂停状态
console.log("设备状态同步 暂停状态", jsonStatus);
// this.judgementWorkStatus(
// MODE_WORKING_ENUM.PAUSE,
// jsonStatus.workMode
// );
break;
case "working":
//设备的运行中状态
console.log("设备状态同步 运行中状态", jsonStatus);
// this.judgementWorkStatus(
// MODE_WORKING_ENUM.WORKING,
// jsonStatus.workMode
// );
break;
default:
break;
}
console.log(
"jsonStatus?.workMode === this.state.ActiveModeItem.modeType",
jsonStatus?.workMode === this.state.ActiveModeItem.modeType
);
console.log(
"this.state.DeviceConnectStatus",
this.state.DeviceConnectStatus
);
console.log("this.isRuning", 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
) {
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));
this.setState({
Electricity: jsonStatus.battery,
matrixElectricity: jsonStatus.matrixBattery,
});
// 判断设备主动上报的关机事件
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 == 2 &&
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);
//对比仪器上报运行的总秒数 和小程序页面运行的已经运行的总秒数,如果不一致就进行校准
const currentScene = ActiveModeItem; // 获取当前的场景
let sceneTime = ActiveModeItem?.breakTimeStr
? minSecToS(ActiveModeItem.breakTimeStr)
: minSecToS(currentScene.modeTimeStr); // 场景时间
console.log("场景时间 sceneTime", sceneTime);
console.log("当前显示时间 currentTime", currentTime);
console.log("设备运行时间 totalTime", totalTime);
// 更新界面倒计时
this.resetTimer();
if (
sceneTime > totalTime &&
this.isRuning === true &&
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 { workMode, ActiveModeItem, ModeList } = this.state;
const opts: any = {};
// ActiveModeItem
let nowModeItem;
if (nWorkMode) {
nowModeItem = ModeList.find((item) => {
return item.modeType === nWorkMode;
});
}
opts.workStatus = nWorkStatus;
let nowCurrentTime = ActiveModeItem.modeTimeStr;
// 完成重连同步则删除重连时间字段
if (ActiveModeItem?.breakTimeStr) {
nowCurrentTime = ActiveModeItem?.breakTimeStr;
}
const statusF = {
sleep: () => {
this.setState({
isShowCountdown: false,
});
},
standby: () => {
this.setState({
isShowCountdown: false,
});
if (nowModeItem?.isCabinMode && this.isRuning === true) {
opts.currentTime = nowCurrentTime;
} else if (!nowModeItem?.isCabinMode && this.isRuning === true) {
// fix: 启动非支架模式倒计时时连上支架仪器的状态变为standby
this.isRuning === false;
}
},
setting: () => {
// that.data.hadShowBreakTips = false;
this.setState({
hadShowBreakTips: false,
});
if (this.isRuning === false && !ActiveModeItem.isCabinMode) {
this.isRuning = true;
this.setState({
title: "正在护理",
isStopNurse: false,
});
} else if (this.isRuning === false && ActiveModeItem.isCabinMode) {
this.isRuning = true;
// this.setState({
// title: "正在护理",
// });
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,
hadShowBreakTips: false,
});
},
pause: () => {
clearInterval(currentTimeTimer);
this.setState({
isShowCountdown: false,
});
if (ActiveModeItem.isCabinMode) {
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,
ModeStepTimeArray,
ModeStepIndex,
ActiveModeItem,
} = this.state;
if (
this.workStatus == MODE_WORKING_ENUM.WORKING &&
this.isRuning &&
DeviceConnectStatus == 1
) {
let totalSeconds = ActiveModeItem?.breakTimeStr
? minSecToS(ActiveModeItem.breakTimeStr)
: minSecToS(ActiveModeItem.modeTimeStr);
// 现在的倒计时剩余时间:同步时检查是否断开重连,如果是,则使用断开的剩余时长,进行倒计时计算
let currentSeconds = minSecToS(currentTime);
let checkTime = totalSeconds - currentSeconds;
// 缓存经过的时间:用于接口提交
this.elapsedTime = checkTime;
// 如果存在中断时间,则要加上间隔的时间
if (ActiveModeItem?.breakTimeStr) {
let intervalTime =
minSecToS(ActiveModeItem.modeTimeStr) -
minSecToS(ActiveModeItem.breakTimeStr);
this.elapsedTime += intervalTime;
}
// 判断剩余时间是否大于1
if (currentSeconds >= 1) {
// 小程序显示倒计时
this.setState({
currentTime: s_to_ms(--currentSeconds),
});
let length = ModeStepTimeArray.length;
if (length) {
// 模式多个步骤节点切换
// 已运行时间达到下一节点时,切换
if (checkTime > ModeStepTimeArray[ModeStepIndex]) {
// 已运行时间达到下一节点,且存在下一节点,步骤切换时更新
if (ModeStepIndex < length - 1) {
let index = ModeStepIndex + 1; // 提前步骤+1
let currentServiceData = {
startSource: "",
stopSource: "",
};
let serviceLength = ActiveModeItem.serviceData.length;
if (serviceLength > index) {
currentServiceData = ActiveModeItem.serviceData[index];
}
console.log("********************");
console.log("********************");
console.log(
"仅在时间达到下一步步骤切换时更新currentServiceData",
currentServiceData
);
this.setState({
ModeStepIndex: index,
currentServiceData,
});
}
}
}
} else {
clearInterval(currentTimeTimer);
this.setState({
currentTime: "00:00",
ModeStepIndex: 0,
});
this.saveNurseReport(true, "setTimer"); // 保存护理计划,并且结束
}
}
}, 1000);
};
// 检测并控制工作状态
handleWorkStatus = (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;
}
}
const sendParams = {
...deviceCommandSamples.pause,
workMode: ActiveModeItem.modeType, // 使用模式
workStatus: newWorkStatus,
};
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 则用于区分是否切换模式的启动
*/
onNursingTap(type = "") {
// 如果已禁止运行,则停止执行后续逻辑
if (this.state.isFooterBtnDisabled) 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, ActiveModeItem } = this.state;
const currentScene = ActiveModeItem;
let sceneTime = minSecToS(currentScene.modeTimeStr);
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 } = 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
);
this.setState({
isFooterBtnDisabled: false,
});
if (this.workJsonStatus.workMode) {
// FR200可能要判断是否水分测试 Test
console.log("this.workJsonStatus.workMode", this.workJsonStatus.workMode);
if (this.workJsonStatus.workMode.indexOf("Stand") > -1) {
console.log(
"this.workJsonStatus.workMode",
this.workJsonStatus.workMode
);
this.setState({
isStandStatus: true,
});
setTimeout(() => this.footerIsDisabled(), 100);
}
}
// 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.currentServiceData.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(recordModeItem.modeTimeStr) -
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");
// 是否同步历史记录
let isSyncHistory = Taro.getStorageSync("isSyncHistory");
if (isSyncHistory) {
let ActiveModeItem = this.FR200NursingHistory.ActiveModeItem;
// 直接进入开始护理状态
this.setState({
isShowNurse: true,
isShowHistoryMsg: true,
currentServiceData: this.FR200NursingHistory.currentServiceData,
tempModeCurrent: ActiveModeItem,
ActiveModeItem: ActiveModeItem,
activeModeID: ActiveModeItem.id,
ModeID: "mode_" + ActiveModeItem.id,
currentTime: this.FR200NursingHistory.currentTime,
});
setTimeout(() => {
// 设置时间组合
if (ActiveModeItem.serviceData.length > 0) {
this.setServiceTimeData();
}
});
}
}
/** 设置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 = null) => {
this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
if (this.FR200NursingHistory) {
let params: any = this.FR200NursingHistory;
// 设置当前时间
params.currentTime = this.state.currentTime;
// 设置正确封面
if (data) {
params.currentServiceData = data;
} else {
let currentServiceData = {
startSource: "",
stopSource: "",
};
let serviceLength = this.state.ActiveModeItem.serviceData.length;
if (serviceLength > 0) {
currentServiceData = this.state.ActiveModeItem.serviceData[0];
}
params.currentServiceData = currentServiceData;
if (jsonStatus) {
// 缓存每秒数据
if (!params.dataArray) params.dataArray = [];
params.dataArray.push(jsonStatus);
params.jsonStatus = jsonStatus;
}
}
Taro.setStorageSync("FR200NursingHistory", params);
console.log("更新updateFR200NursingHistory");
} else {
this.setFR200NursingHistory(jsonStatus);
}
};
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");
Taro.setStorageSync("FR200Echart", nowFR200NursingHistory); // 临时保存用于观看和调试
if (nowFR200NursingHistory.id == FR200NursingHistory.id) {
Taro.removeStorageSync("FR200NursingHistory");
this.FR200NursingHistory.id = "";
} else if (hard) {
Taro.removeStorageSync("FR200NursingHistory");
this.FR200NursingHistory.id = "";
}
};
todoPromise = () => {
return new Promise<void>((resolve, reject) => {
setTimeout(() => {
resolve();
});
});
};
/** 提交护理记录:完成护理后自动调用,会跳转页面 */
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 res: any = await InstrumentInfo.apiNursingLog.addLog(params);
console.log("PostNursingLogClock", res);
if (res.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(); // 跳转
}, 2000);
}
}
};
/*** 护理记录 END ***/
//蓝牙断开连接处理
bluetoothDisconnectProcessing() {
clearInterval(timer);
Taro.offBLEConnectionStateChange(this.listener); // 需传入与监听时同一个的函数对象
Taro.offBLECharacteristicValueChange((res) => {
console.log("offBLECharacteristicValueChange", res);
});
if (!this.state.isToOTA) {
Taro.closeBluetoothAdapter();
}
}
/** 获取护理时间组合 */
getServiceTimeData() {
const { ActiveModeItem } = this.state;
let serviceData = ActiveModeItem.serviceData.map((item) => {
let totalWorkingMinutes = parseInt(
item.serviceStartTimeStr.split(":")[0]
); // 仅分钟数
let totalWorkingSeconds = parseInt(item.serviceEndTimeStr.split(":")[1]); // 仅秒数
// let totalWorkingMinutes = 1; // 仅分钟数
// let totalWorkingSeconds = 0; // 仅秒数
return {
totalWorkingMinutes,
totalWorkingSeconds,
};
});
return serviceData;
}
/** 设置护理时间组合 */
setServiceTimeData() {
let ServiceTimeData = this.getServiceTimeData();
// 组合时间
let ModeStepTimeArray: any = [];
ServiceTimeData.reduce((old, cur) => {
let curTime = cur.totalWorkingMinutes * 60 + cur.totalWorkingSeconds;
let newTotalWorkingMinutes = cur.totalWorkingMinutes;
let newTotalWorkingSeconds = cur.totalWorkingSeconds;
if (old) {
newTotalWorkingMinutes += old.totalWorkingMinutes;
newTotalWorkingSeconds += old.totalWorkingSeconds;
let oldTime = old.totalWorkingMinutes * 60 + old.totalWorkingSeconds;
let value = oldTime + curTime;
ModeStepTimeArray.push(value);
return {
totalWorkingMinutes: newTotalWorkingMinutes,
totalWorkingSeconds: newTotalWorkingSeconds,
};
}
ModeStepTimeArray.push(curTime);
return {
totalWorkingMinutes: newTotalWorkingMinutes,
totalWorkingSeconds: newTotalWorkingSeconds,
};
}, null);
this.setState({
ModeStepTimeArray: ModeStepTimeArray,
ModeStepIndex: 0, // 每次切换组合模式,重置组合步骤
});
console.log("组合时间ModeStepTimeArray", ModeStepTimeArray);
}
/* 组合模式 */
/** 获取自定义组合模式数组 */
getCustomModesArray = () => {
const { ModeList, ActiveModeItem } = this.state;
const combineIds = ActiveModeItem.combineData.map(
(item) => item.combineModeId
);
let modesArray = ModeList.filter((item) =>
combineIds.includes(item.id)
).map((item) => {
let totalWorkingMinutes = parseInt(item.modeTimeStr.split(":")[0]); // 仅分钟数
let totalWorkingSeconds = parseInt(item.modeTimeStr.split(":")[1]); // 仅秒数
return {
workMode: item.modeType,
totalWorkingMinutes,
totalWorkingSeconds,
};
});
return modesArray;
};
// 护理的错误提示
showTips(ctx) {
if (!ctx) return;
if (showTipsTimer) clearTimeout(showTipsTimer);
this.setState({
errorTips: ctx,
});
showTipsTimer = setTimeout(() => {
this.setState({
errorTips: "",
});
}, 2000);
}
/** 结束护理弹窗 */
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 = () => {
// 跳转前置空定时器,防止重复提交
if (currentTimeTimer) clearInterval(currentTimeTimer);
go("/pages/face_report/face_report?id=" + this.state.currentDevice.id);
};
// 完成配对
pairingChange = () => {
this.setState({
isConnectShow: false,
isShowNurse: true,
});
setTimeout(() => {
this.onNursingTap("switch");
});
};
connectionClose = () => {
this.setState({
isConnectShow: false,
});
Taro.reLaunch({ 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 */
/**
* @name 设备运行开关按钮是否禁用
* @description 判断所选模式与设备连接状态是否一致
* @returns 返回true则禁用
*/
footerIsDisabled = () => {
// 默认不禁用FR200无法禁用
let isFooterBtnDisabled = false;
// this.setState({
// isFooterBtnDisabled: isFooterBtnDisabled,
// });
return isFooterBtnDisabled; // 数据更新有延迟,返回用于判断
};
customBack = () => {
Taro.reLaunch({ url: "/pages/index/index" });
};
onModeLockOpen = async () => {
this.setState({ isModeLock: true });
};
onModeLockClose = async () => {
this.setState({ isModeLock: false });
};
render() {
let {
title,
isConnectShow,
GearData,
isShowStepTips,
isShowNurse,
isStopNurse,
ModeList,
ModeType,
ModeStepIndex,
currentServiceData,
ActiveModeItem,
isSwitchActiveMode,
ModeID,
activeModeID,
isShowCountdown,
countdown,
Electricity,
matrixElectricity,
errorTips,
isEndCarePlan,
currentTime,
DeviceConnectStatus,
isShowErrorTipsText,
errorTipsText,
isNotEnoughTime,
isShowNursingSuccess,
currentDevice,
isConnectionBlutoot,
isShowTipsSave,
isFirstTipShow,
nurseInfo,
isShowReReadRecordSave,
isFooterBtnDisabled,
isShowHistoryMsg,
isModeLock,
} = 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>
{!isShowNurse && (
<Video
className="video-or-image"
src={ActiveModeItem.modeVideo}
loop
/>
)}
{isShowNurse && (
<Block>
{isStopNurse ? (
<Image
className="video-or-image"
src={currentServiceData.stopSource}
/>
) : (
<Image
className="video-or-image"
src={currentServiceData.startSource}
/>
)}
</Block>
)}
{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="iot-device">
<View className="item">
<Text className="device-time">
<Text className="time">{currentTime}</Text>
</Text>
</View>
<View className="line" />
<ElectricityView
Electricity={Electricity}
matrixElectricity={matrixElectricity}
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}
/>
)}
{ActiveModeItem.combineData && (
<ModeContent
isShowNurse={isShowNurse}
ActiveModeItem={ActiveModeItem}
ModeStepIndex={ModeStepIndex}
/>
)}
{/* <Echarts></Echarts> */}
<Gears
onEmitMinus={this.handleMinus}
onEmitAdd={this.handleAdd}
GearData={GearData}
></Gears>
</View>
<Footer
isDisabled={isFooterBtnDisabled}
isShowNurse={isShowNurse}
isStopNurse={isStopNurse}
onEmitStartNurse={this.onStartNurse}
onEmitSwitchChange={this.onSwitchChange}
onEmitEndPlan={this.onEndPlan}
onEmitErrorTips={this.onEmitErrorTips}
/>
</View>
</Block>
);
}
}
const mapStateToProps = (state) => ({
bluetoothInfo: state.deviceInfo.bluetoothInfo,
});
const mapDispatchToProps = (dispatch) => ({
// userRefresh(data) {
// dispatch(userRefresh(data));
// },
});
export default connect(mapStateToProps, mapDispatchToProps)(IotCarePlanFR200);