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 { 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((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 ( } textAlgin="center" cancelButtonText="取消" confirmButtonText="确定" close={this.cancelModeSwitchBtn} confirm={this.confirmModeSwitchBtn} /> {ActiveModeItem.openSourceData.length > 0 && ( )} 当前模式已护理部分时间 是否保存护理记录 } cancelButtonText="取消" confirmButtonText="确认" textAlgin="center" close={this.closeTipsSave} cancel={this.cancelTipsSave} confirm={this.confirmTipsSave} /> { /*不需要做处理*/ }} /> {isConnectShow && ( {}} pairingChange={this.pairingChange} upgradeFun={() => {}} /> )} 正在同步护理记录... {!isShowNurse && ( 护理时间: {currentTime} {ModeList.length > 0 && ( )} {ActiveModeItem.combineData && ( )} {/* */}