From 32d03bd9eec3f2414d3e66460ff0e1a276e75473 Mon Sep 17 00:00:00 2001 From: blak-kong <546598185@qq.com> Date: Wed, 27 Mar 2024 14:25:50 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fix:=E6=A0=B7=E5=BC=8F=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/popup/popup-countdown.less | 110 ++++++------- src/moduleIOT/pages/iotCarePlan/WL200.tsx | 10 +- .../iotCarePlan/components/Echart/index.less | 150 ++++++++---------- .../iotCarePlan/components/Echart/index.tsx | 64 ++++---- src/pages/index/index.tsx | 9 +- 5 files changed, 166 insertions(+), 177 deletions(-) diff --git a/src/components/popup/popup-countdown.less b/src/components/popup/popup-countdown.less index 5b33adf..624f3ee 100644 --- a/src/components/popup/popup-countdown.less +++ b/src/components/popup/popup-countdown.less @@ -15,65 +15,65 @@ display: flex; justify-content: center; } -} - -.countdown-popup-loading { - position: relative; -} -.countdown-popup-loading-time { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - width: 50rpx; - height: 50rpx; - line-height: 50rpx; - margin: auto; - font-size: 54rpx; - text-align: center; - color: #ecf0f3; - font-weight: bold; -} + .countdown-popup-loading { + position: relative; + } -.ui-loading__bg { - position: relative; - width: 160rpx; - height: 160rpx; - border-radius: 50%; - background-color: #ecf0f3; - /* background-image: conic-gradient(#3CACFF 100%,#000 0%); */ -} -.ui-loading__bg::before { - content: ""; - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - width: 140rpx; - height: 140rpx; - border-radius: 50%; - background-color: #fff; -} + .countdown-popup-loading-time { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 50rpx; + height: 50rpx; + line-height: 50rpx; + margin: auto; + font-size: 54rpx; + text-align: center; + color: #ecf0f3; + font-weight: bold; + } -.ui-loading { - position: absolute; - width: 160rpx; - height: 160rpx; - border-radius: 50%; - background: transparent; - box-sizing: border-box; - border: 10rpx solid #3cacff; - clip-path: polygon(0% 0%, 25% 0%, 50% 50%, 0% 25%); - animation: rotate 1s linear infinite; -} + .ui-loading__bg { + position: relative; + width: 160rpx; + height: 160rpx; + border-radius: 50%; + background-color: #ecf0f3; + /* background-image: conic-gradient(#3CACFF 100%,#000 0%); */ + } + .ui-loading__bg::before { + content: ""; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + width: 140rpx; + height: 140rpx; + border-radius: 50%; + background-color: #fff; + } -@keyframes rotate { - from { - transform: rotateZ(0deg); + .ui-loading { + position: absolute; + width: 160rpx; + height: 160rpx; + border-radius: 50%; + background: transparent; + box-sizing: border-box; + border: 10rpx solid #3cacff; + clip-path: polygon(0% 0%, 25% 0%, 50% 50%, 0% 25%); + animation: countdownRotate 1s linear infinite; } - to { - transform: rotateZ(360deg); + + @keyframes countdownRotate { + from { + transform: rotateZ(0deg); + } + to { + transform: rotateZ(360deg); + } } } diff --git a/src/moduleIOT/pages/iotCarePlan/WL200.tsx b/src/moduleIOT/pages/iotCarePlan/WL200.tsx index e9f56c2..32cc37f 100644 --- a/src/moduleIOT/pages/iotCarePlan/WL200.tsx +++ b/src/moduleIOT/pages/iotCarePlan/WL200.tsx @@ -272,7 +272,12 @@ class IotCarePlanWL200 extends Component { title: obj.name, }); + Taro.showLoading({ + title: "请求中...", + mask: true, + }); await this.GetModeList(obj.id); + Taro.hideLoading(); // 如果不存在设备模式值,则判断为首次进入,弹窗提示 let isFirstTipShow = getStorageSync("first_instrument_" + obj.id); @@ -1928,7 +1933,10 @@ class IotCarePlanWL200 extends Component { goFaceReport = () => { // 跳转前置空定时器,防止重复提交 if (currentTimeTimer) clearInterval(currentTimeTimer); - go("/recording/pages/face_report/face_report?id=" + this.state.currentDevice.id); + go( + "/recording/pages/face_report/face_report?id=" + + this.state.currentDevice.id + ); }; // 完成配对 diff --git a/src/moduleIOT/pages/iotCarePlan/components/Echart/index.less b/src/moduleIOT/pages/iotCarePlan/components/Echart/index.less index 8e475ac..2c746aa 100644 --- a/src/moduleIOT/pages/iotCarePlan/components/Echart/index.less +++ b/src/moduleIOT/pages/iotCarePlan/components/Echart/index.less @@ -1,4 +1,4 @@ -.box { +.echart-component { width: 690rpx; height: 320rpx; margin: 28rpx auto 150rpx; @@ -8,94 +8,84 @@ box-sizing: border-box; position: relative; - - // writing-mode: vertical-lr; - // text-orientation: upright; - // white-space: nowrap; - // font-size: 18px; - // font-weight: bold; - // background-color: #c2e5f3; - // color: #fff; - // width: 100%; -} - -.fullscreen { - position: fixed; - top: 450rpx; - left: -450rpx; - right: 0; - bottom: 0; - width: 100vh; - height: 100vw; - z-index: 9999; - background-color: rgba(0, 0, 0, 0.5); /* 背景色 */ - transform: rotate(90deg); - // animation: rotate 0s linear; -} - -@keyframes rotate { - from { - width: 690rpx; - height: 320rpx; - transform: rotate(0deg); - } - to { + .fullscreen { + position: fixed; + top: 450rpx; + left: -450rpx; + right: 0; + bottom: 0; width: 100vh; height: 100vw; - transform: rotate(0deg); + z-index: 9999; + background-color: rgba(0, 0, 0, 0.5); /* 背景色 */ + transform: rotate(90deg); + // animation: rotate 0s linear; } -} -.box_background { - position: absolute; - top: 0; - left: 0; - width: 690rpx; - height: 320rpx; - border-radius: 30rpx; - background-color: #fff; - .power { - margin: 34rpx 0 28rpx 28rpx; - font-family: PingFang-SC; - font-weight: 500; - font-size: 18rpx; - color: #cccccc; + @keyframes echartRotate { + from { + width: 690rpx; + height: 320rpx; + transform: rotate(0deg); + } + to { + width: 100vh; + height: 100vw; + transform: rotate(0deg); + } } - .full { - width: 24rpx; - height: 24rpx; + + .box_background { position: absolute; - top: 32rpx; - right: 26rpx; - z-index: 2; - } - .line { - margin: 0 0 6rpx 35rpx; - font-family: PingFang-SC; - font-size: 14rpx; - color: #cccccc; - display: flex; - position: relative; - height: 18rpx; - .bottom_line { - // border-bottom: 1rpx #ccc dashed; - width: 550rpx; - margin-left: 20rpx; + top: 0; + left: 0; + width: 690rpx; + height: 320rpx; + border-radius: 30rpx; + background-color: #fff; + .power { + margin: 34rpx 0 28rpx 28rpx; + font-family: PingFang-SC; + font-weight: 500; + font-size: 18rpx; + color: #cccccc; + } + .full { + width: 24rpx; + height: 24rpx; position: absolute; - bottom: -6rpx; - right: 74rpx; - height: 4rpx; - color: #fff; + top: 32rpx; + right: 26rpx; + z-index: 2; + } + .line { + margin: 0 0 6rpx 35rpx; + font-family: PingFang-SC; + font-size: 14rpx; + color: #cccccc; + display: flex; + position: relative; + height: 18rpx; + .bottom_line { + // border-bottom: 1rpx #ccc dashed; + width: 550rpx; + margin-left: 20rpx; + position: absolute; + bottom: -6rpx; + right: 74rpx; + height: 4rpx; + color: #fff; + } } - } - .time { - position: absolute; - bottom: 22rpx; - right: 24rpx; - font-family: PingFang-SC; - font-size: 18rpx; - color: #cccccc; + .time { + position: absolute; + bottom: 22rpx; + right: 24rpx; + font-family: PingFang-SC; + font-size: 18rpx; + color: #cccccc; + } } } diff --git a/src/moduleIOT/pages/iotCarePlan/components/Echart/index.tsx b/src/moduleIOT/pages/iotCarePlan/components/Echart/index.tsx index c535cc2..24a6c54 100644 --- a/src/moduleIOT/pages/iotCarePlan/components/Echart/index.tsx +++ b/src/moduleIOT/pages/iotCarePlan/components/Echart/index.tsx @@ -9,13 +9,11 @@ import echarts from "@/utils/echarts.min.js"; import "./index.less"; interface Props { - series: any, - full:any + series: any; + full: any; } - - -function Index({ series ,full}: Props) { +function Index({ series, full }: Props) { const echartsRef = useRef(null); const [options, setOptions] = useState({ animation: false, @@ -145,40 +143,36 @@ function Index({ series ,full}: Props) { color: "#ff8410", }, }, - series: [] - }) + series: [], + }); const level = [8, 7, 6, 5, 4, 3, 2]; - const [newOptions, setNewOptions] = useState(options) + const [newOptions, setNewOptions] = useState(options); const updata = useCallback((res) => { - let option = JSON.parse(JSON.stringify(options)) - option.series = JSON.parse(JSON.stringify(res)) + let option = JSON.parse(JSON.stringify(options)); + option.series = JSON.parse(JSON.stringify(res)); // 更新图表数据 - setNewOptions(option) - }, []) + setNewOptions(option); + }, []); const cancelFull = useCallback((res) => { - full() - }, []) - - + full(); + }, []); useEffect(() => { - setOptions(newOptions) + setOptions(newOptions); }, [newOptions]); - useEffect(() => { - updata(series) - }, [series]) - + updata(series); + }, [series]); return ( - + - - - 实时能量 + + + 实时能量 {level.map((item) => ( - - {item} - + + {item} + ))} - - 1 + + 1 - 时间 + 时间 - + ); } diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 58088f5..10496c3 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -1132,7 +1132,7 @@ class Index extends Component { return ( - {/* */} + {/* */} { 你已绑定所有设备 - {/* - - 横屏了 - */} ); } From 3a3d16476220a3a57fecca8ac03650e8eb4e679f Mon Sep 17 00:00:00 2001 From: blak-kong <546598185@qq.com> Date: Wed, 27 Mar 2024 16:28:21 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BC=B9=E7=AA=97?= =?UTF-8?q?=E8=A2=AB=E5=88=A0=E9=99=A4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/moduleIOT/pages/iotCarePlan/FR200.tsx | 97 +++++++++++++++++++---- 1 file changed, 83 insertions(+), 14 deletions(-) diff --git a/src/moduleIOT/pages/iotCarePlan/FR200.tsx b/src/moduleIOT/pages/iotCarePlan/FR200.tsx index f177a02..8e17b91 100644 --- a/src/moduleIOT/pages/iotCarePlan/FR200.tsx +++ b/src/moduleIOT/pages/iotCarePlan/FR200.tsx @@ -185,8 +185,6 @@ class IotCarePlanFR200 extends Component { SwitchActiveModeItem: {}, // 切换选中模式 ModeID: "mode_", // 模式KEY activeModeID: "", // 当前选中模式ID:用于高亮 - ModeStepIndex: 0, // 当前护理功效步骤:每个步骤时间不定,所以时间另外计算,根据步骤显示 - ModeStepTimeArray: [], // 护理功效时间步骤,用于切换显示GIF // TestModeStepIndex: 0, // 水分测试步骤 EssenceStepIndex: 0, // 精华促渗步骤 @@ -197,12 +195,6 @@ class IotCarePlanFR200 extends Component { MaskModeBuzzingIndex: 0, // 面膜蜂鸣 MaskModeVibrateIndex: 0, // 面膜震动 - currentServiceData: { - // 当前展示的开启暂停GIF: 因为时间判断不方便,所以单独领出来 - startSource: "", - stopSource: "", - }, - // 倒计时 isShowCountdown: false, // 倒计时弹窗 countdown: 3, @@ -382,7 +374,7 @@ class IotCarePlanFR200 extends Component { "intelligence", ]; - /** 基础版:脸部/眼部/PRO 设备使用时,会自动开启暂停 */ + /** 基础版:脸部/眼部/PRO 设备使用时,会自动开启,不能暂停 */ BaseModeType: string[] = [ "face", "eyes", @@ -602,7 +594,6 @@ class IotCarePlanFR200 extends Component { ActiveModeItem: data, activeModeID: data.id, ModeID: "mode_" + data.id, - ModeStepIndex: 0, waterStepIndex: 0, // 水分测试步骤 EssenceStepIndex: 0, // 精华促渗步骤 MaskModeStepIndex: 0, // 面膜促渗步骤 @@ -618,9 +609,10 @@ class IotCarePlanFR200 extends Component { this.changeItemUpdateFR200NursingHistory(); this.stepNext(); // 仅切换模式,不执行开始逻辑 - // FR200水分测试不可自动运行,需手动点击开始测试,手动启动检测 + // FR200 水分测试和促渗不可自动运行,需手动点击开始测试,手动启动检测 // 其他模式可以自动运行 - if (data.modeType !== "moistureTest") { + let notStartArr = ["moistureTest", "maskPenetration", "essence"]; + if (!notStartArr.includes(data.modeType)) { setTimeout(() => { this.onNursingTap("switch"); }, 800); @@ -2317,7 +2309,6 @@ class IotCarePlanFR200 extends Component { isStopNurse, ModeList, ModeType, - ModeStepIndex, ActiveModeItem, currentWorkModeType, isSwitchActiveMode, @@ -2347,7 +2338,6 @@ class IotCarePlanFR200 extends Component { showEcharts, echartsData, isShowReReadRecordConnect, - currentServiceData, series, isFullScreen, } = this.state; @@ -2423,6 +2413,85 @@ class IotCarePlanFR200 extends Component { 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={() => {}} + /> + )} + Date: Wed, 27 Mar 2024 18:23:20 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=9B=BA=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bluetoot/update-fr200/index.less | 36 ++ .../bluetoot/update-fr200/index.tsx | 471 ++++++++++++++++++ src/moduleIOT/pages/iotCarePlan/FR200.tsx | 1 + src/moduleIOT/pages/iotCarePlan/WE200.tsx | 452 +---------------- src/pages/index/index.tsx | 47 +- 5 files changed, 552 insertions(+), 455 deletions(-) create mode 100644 src/components/bluetoot/update-fr200/index.less create mode 100644 src/components/bluetoot/update-fr200/index.tsx diff --git a/src/components/bluetoot/update-fr200/index.less b/src/components/bluetoot/update-fr200/index.less new file mode 100644 index 0000000..5bb8f2a --- /dev/null +++ b/src/components/bluetoot/update-fr200/index.less @@ -0,0 +1,36 @@ +.common-progress-box { + padding: 50rpx; +} +.progress { + display: flex; + margin-top: 10rpx; + font-size: 24rpx; + font-family: PingFang SC; + font-weight: 500; + color: #999999; + align-items: center; + + .van-progress { + width: 440rpx; + .van-progress__portion { + background: linear-gradient(90deg, #ffe9c7, #eecda1); + border-radius: 6rpx; + height: 12rpx; + .van-progress__pivot { + display: none; + } + } + } + + .percent { + margin-left: 52rpx; + } +} + +.progress-tips { + font-family: PingFang SC; + font-weight: 500; + font-size: 26rpx; + color: #666666; + line-height: 60rpx; +} diff --git a/src/components/bluetoot/update-fr200/index.tsx b/src/components/bluetoot/update-fr200/index.tsx new file mode 100644 index 0000000..2a0f1a2 --- /dev/null +++ b/src/components/bluetoot/update-fr200/index.tsx @@ -0,0 +1,471 @@ +import Taro from "@tarojs/taro"; +import classnames from "classnames"; + +import { Component, PropsWithChildren, useEffect, useState } from "react"; +import { Block, View, Text, PageMeta } from "@tarojs/components"; +import { Popup, Progress } from "@antmjs/vantui"; + +import { connect } from "react-redux"; +import { + msg, + back, + showModal, + go, + loading, + getStorageSync, +} from "@/utils/traoAPI"; +import { InstrumentInfo } from "@/utils/Interface"; +import { + notifyBLECharacteristicValueChange, + writeBLECharacteristicValue, + sendCommand, +} from "@/utils/bluetoothWXAPI"; +import { + ab2hex, + ccrc8, + filterBleData, + hex2int, + string2buffer, +} from "@/utils/util"; +import { + Stringkit, + TResponseFromDevice, +} from "@flossom-npm/iot-translater-we100"; + +// 通过设备类型判断给 deviceToolKitInstance 赋值 +import { DeviceToolKit as DeviceToolKitWE100 } from "@flossom-npm/iot-translater-we100"; +import { DeviceToolKit as DeviceToolKitFR200 } from "@flossom-npm/iot-translater"; + +import OtaDeviceTypeEnum from "../OtaDeviceTypeEnum"; + +// 临时替代 +var log = console; + +let deviceToolKitInstance: any = null; + +const deviceToolKitInstanceFR200 = new DeviceToolKitFR200("FR200"); +deviceToolKitInstanceFR200.setDebug(true); + +import "./index.less"; + +class UpdateIotFR200 extends Component { + constructor(props) { + super(props); + this.state = { + name: "UpdateIotFR200", + progressbar: 1, // 进度条 + + currentDevice: {}, + + hadStartOta: false, // 是否开始ota + }; + } + + $instance = Taro.getCurrentInstance(); + $checkTimer: any = null; + // 与页面渲染无关的数据 + $otaDataGroup: any = { + // 包大小,面罩设置为100,主机设置为240 + packageSize: 240, //每个包的大小上限(单位是字节) + otaBin: null, //固件包buffer形式,从16进制字符串转换成 + otaHexString: "", //固件包的16进制字符串,从后端接口返回 + packageLength: 0, //升级包的总长度(单位是字节) + packageCount: 0, //分包后的总包数 + otaData: [], //分包数组 + packageCrc8: "", //总包的校验码 + versionNo: "", //包的版本号 + otaCurrentPackageIndex: 0, //现在正在传输的分包索引 + countDown: 7, + }; + + async onLoad() { + if (this.$checkTimer) clearInterval(this.$checkTimer); + } + componentDidMount() { + console.log("componentDidMount"); + this.initData(); + } + componentDidHide() { + console.log("componentDidHide"); + this.errorFun(); + } + + async initData() { + console.log("UpdateIotWL200"); + deviceToolKitInstance = deviceToolKitInstanceFR200; + + let objStr = getStorageSync("instrument_detail"); + if (objStr) { + this.setState({ + currentDevice: objStr, + }); + } + setTimeout(() => { + this.notifyBLECharacteristicValueChange(); + this.getDeviceUpgrade(); + }); + } + + /** + * 拆分升级包 + */ + async getUpgradeData() { + //解析获取升级包更新数据 + const { otaHexString, packageSize } = this.$otaDataGroup; + if (!otaHexString?.length) { + return []; + } + let arr: any = []; + for (let i = 0, len = otaHexString.length; i < len; i += packageSize * 2) { + let index = i + packageSize * 2; + let value = otaHexString.slice(i, index); + arr.push(value); + } + return arr; + } + /** + * 重置OTA状态 + */ + resetOta() { + this.$otaDataGroup = { + ...this.$otaDataGroup, + otaCurrentPackageIndex: 0, + otaData: [], + }; + } + /** + * 启动ota + */ + startOTA() { + this.resetOta(); + let jsoncmd = { + commandType: "OTAStart", + otaDeviceType: "FR200", + versionNo: this.$otaDataGroup.versionNo, + }; + + console.log("startOTA jsoncmd", jsoncmd); + + //@ts-ignore + const value = deviceToolKitInstance.toBleCommand(jsoncmd as any); + console.log(jsoncmd); + sendCommand({ value }).then((res) => { + this.setState({ + hadStartOta: true, + }); + this.createTimer(); + }); + } + /** + * 准备ota + */ + preOTA() { + const { packageCount, packageLength, packageCrc8, versionNo } = + this.$otaDataGroup; + let jsoncmd = { + commandType: "OTAPrepare", + packageCount, + packageLength, + packageCrc8, + versionNo, + }; + console.info("OTAPrepare json => ", jsoncmd); + //@ts-ignore + const value = deviceToolKitInstance.toBleCommand(jsoncmd as any); + sendCommand({ value }); + } + /** + * ota升级 + */ + processOTA(i, data) { + const { packageCount, packageLength } = this.$otaDataGroup; + if (!packageLength) { + this.quitOTA(); + } + let jsoncmd = { + commandType: "OTAUpdating", + packageCount, + packageLength, + currentPackageNo: i + 1, + currentPackageLength: data.length / 2, + currentPackageContent: data, + }; + console.info("OTAUpdating json => ", jsoncmd); + //@ts-ignore + const value = deviceToolKitInstance.toBleCommand(jsoncmd as any); + sendCommand({ value }); + } + /** + * ota升级完成 + */ + async finishedOTA() { + let jsoncmd = { + commandType: "OTAUpdateFinish", + versionNo: this.$otaDataGroup.versionNo, + }; + clearInterval(this.$checkTimer); + log.info("ota成功日志, 清除计时器"); + //@ts-ignore + const value = deviceToolKitInstance.toBleCommand(jsoncmd as any); + sendCommand({ value }).then((res) => { + this.resetOta(); + }); + } + /** + * ota升级强制退出 + */ + quitOTA(errorString = "") { + // log.info('ota失败日志', errorString); + console.log("ota失败日志", errorString); + const errorMap = { + packageError: "总包错误", + packageNumError: "包号错误", + checkedError: "校验错误", + dataLengthError: "数据总长度错误", + dataCRCError: "数据总数CRC错误", + updateTimeOut: "数据更新超时", + }; + let jsoncmd = { + commandType: "OTAQuit", + }; + //@ts-ignore + const value = deviceToolKitInstance.toBleCommand(jsoncmd as any); + sendCommand({ value }) + .then((res) => { + this.resetOta(); + // this.showError(errorMap[errorString] || tipMap[errorString] || '发生错误') + }) + .catch((err) => { + if (!this.state.hadShowError) { + this.setState({ + hadShowError: true, + }); + // log.info('ota失败日志', '发送日志OTAQuit失败', err); + console.info("ota失败日志", "发送日志OTAQuit失败", err); + if (err.errCode === 10000) { + let isDisconnect = getStorageSync("isDisconnectUpdate"); + if (isDisconnect) { + if (this.$checkTimer) clearInterval(this.$checkTimer); + } + } + } + }); + setTimeout(() => { + this.errorFun(); + }, 1000); + } + + /** + * 处理返回的数据 OTA用 + */ + async parseData(json) { + console.log("parseData json.commandType", json.commandType); + if (!json || !json.commandType) return; + switch (json.commandType) { + case "OTAStart": + if (json.responseStatus == "OK") { + const otaData = await this.getUpgradeData(); + this.$otaDataGroup = { + ...this.$otaDataGroup, + otaData, + }; + this.$otaDataGroup.otaCurrentPackageIndex = 0; + this.preOTA(); + } else { + this.quitOTA(json.responseStatus); + } + break; + case "OTAPrepare": + if (json.responseStatus == "OK") { + this.processOTA(0, this.$otaDataGroup.otaData[0]); + } else { + this.quitOTA(json.responseStatus); + } + break; + case "OTAUpdating": + if (json.responseStatus == "OK") { + let ota = this.$otaDataGroup; + let progressbar = + (ota.otaCurrentPackageIndex / ota.packageCount) * 100; + this.setState({ + progressbar: (progressbar <= 1 ? 1 : progressbar).toFixed(0), + }); + if (!json.currentPackageNo) { + return; + } + if (json.currentPackageNo < this.$otaDataGroup.packageCount) { + this.$otaDataGroup.otaCurrentPackageIndex++; + this.processOTA( + this.$otaDataGroup.otaCurrentPackageIndex, + this.$otaDataGroup.otaData[ + this.$otaDataGroup.otaCurrentPackageIndex + ] + ); + } else { + this.finishedOTA(); + } + } else { + this.quitOTA(json.responseStatus); + } + break; + case "OTAUpdateFinish": + console.log("完成OTA传输"); + this.setState({ + progressbar: 100, + }); + this.finishFun(); + // quitOTA() + break; + default: + break; + } + } + /** + * 从后端拉取固件包,并初始化ota流程的所需对象 + */ + getDeviceUpgrade = async () => { + let res: any = await InstrumentInfo.getUpgrade({ + instrumentId: this.state.currentDevice.id, + isWe200: false, + }); + if (res.data.data == "解析失败") { + // this.showError('文件解析失败'); + return; + } + if (res.data.code !== 200) { + return; + } + const otaHexString = res.data.data; + const otaBin = string2buffer(res.data.data); + const packageLength = otaBin?.byteLength || 0; + const packageSize = this.$otaDataGroup.packageSize; + const packageCrc8 = Stringkit.getCrc8CodeByString(otaHexString); + const packageCount = Math.ceil(packageLength / packageSize); + let { iotVersion: versionNo } = this.state.currentDevice; + this.$otaDataGroup = { + ...this.$otaDataGroup, + otaHexString, + otaBin, + packageLength, + packageSize, + packageCrc8, + packageCount, + versionNo, + }; + console.log("this.$otaDataGroup ", this.$otaDataGroup); + }; + + notifyBLECharacteristicValueChange = () => { + const bluetoothInfo = this.props.bluetoothInfo; + notifyBLECharacteristicValueChange({ + deviceId: bluetoothInfo.deviceId, + servicesuuid: bluetoothInfo.servicesuuid, + characteristicsuuid1: bluetoothInfo.characteristicsuuid1, + characteristicsuuid0: bluetoothInfo.characteristicsuuid0, + }).then((res) => { + Taro.onBLECharacteristicValueChange((value) => { + // let str = ab2hex(value.value); //转为16进制字符串 + // console.log('返回',str) + const jsonStatus: any = deviceToolKitInstance.toJsonStatus(value.value); + log.info("OTA页面设备响应数据打印==》", JSON.stringify(jsonStatus)); + console.info("onBLECharacteristicValueChange json => ", jsonStatus); + + this.$otaDataGroup.currentPackageNo = jsonStatus.currentPackageNo; + this.$otaDataGroup.countDown = 7; + this.parseData(jsonStatus); + }); + setTimeout(() => { + this.startOTA(); + }, 500); + }); + }; + + createTimer() { + log.info("设备ota计时器创建成功"); + this.$checkTimer = setInterval(() => { + // 超过7s没有回包, 直接断开 + if (this.$otaDataGroup.countDown <= 0 && this.state.hadStartOta) { + this.quitOTA("shutDownMaskTip"); + } else { + this.$otaDataGroup.countDown--; + } + console.log(this.$otaDataGroup.countDown); + }, 1000); + } + + //升级销毁页面时关闭小程序蓝牙 + onUnload() { + console.log("onUnload"); + if (this.$checkTimer) clearInterval(this.$checkTimer); + Taro.closeBluetoothAdapter(); + } + + onPullDownRefresh() { + Taro.stopPullDownRefresh(); + } + + onClickStop = (e) => { + e.stopPropagation(); + }; + + // 错误关闭回调 + errorFun = () => { + this.resetOta(); + this.props.errorFun(); + }; + // 升级完成回调 + finishFun = () => { + this.props.finishFun(); + }; + + render() { + let { isShow } = this.props; + let { progressbar } = this.state; + return ( + + + + + + 设备升级中 + + + + + + {progressbar}% + + 注意事项: + 1.保持设备开机状态 + 2.请勿切出该页面 + + + + + + ); + } +} + +const mapStateToProps = (state) => ({ + bluetoothInfo: state.deviceInfo.bluetoothInfo, +}); +const mapDispatchToProps = (dispatch) => ({}); +export default connect(mapStateToProps, mapDispatchToProps)(UpdateIotFR200); diff --git a/src/moduleIOT/pages/iotCarePlan/FR200.tsx b/src/moduleIOT/pages/iotCarePlan/FR200.tsx index 8e17b91..b5fb4f1 100644 --- a/src/moduleIOT/pages/iotCarePlan/FR200.tsx +++ b/src/moduleIOT/pages/iotCarePlan/FR200.tsx @@ -180,6 +180,7 @@ class IotCarePlanFR200 extends Component { ModeList: [], ModeType: "all", // all 1基础护理 2专区护理 3专研促渗 4敏期护理 5智能测肤 ActiveModeItem: { + modeType: "", openSourceData: [], }, // 当前选中模式 SwitchActiveModeItem: {}, // 切换选中模式 diff --git a/src/moduleIOT/pages/iotCarePlan/WE200.tsx b/src/moduleIOT/pages/iotCarePlan/WE200.tsx index cb7e035..06e8123 100644 --- a/src/moduleIOT/pages/iotCarePlan/WE200.tsx +++ b/src/moduleIOT/pages/iotCarePlan/WE200.tsx @@ -738,107 +738,6 @@ class IotCarePlanWE200 extends Component { // 如果检查失败,则报错 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) => { - 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 不可切换光照提示 @@ -852,41 +751,6 @@ class IotCarePlanWE200 extends Component { this.showTips("检测到您的设备没有紧贴肌肤,请紧贴肌肤后重新尝试"); }); }; - updata() { - let that = this; - let stop = 0; - let time = setInterval(function () { - stop++; - let series = JSON.parse(JSON.stringify(that.state.series)); - let num = Math.floor(Math.random() * 9); - let count = 0; - series.map((item) => { - if (item.type === "line") { - item.data.splice(0, 1); - item.data.push(num); - } - if (item.type === "bar") { - count++; - item.data.splice(0, 1); - if (count <= num) { - item.data.push(1); - } else { - item.data.push(0); - } - } - }); - - // 更新图表数据 - that.setState({ series }); - if (stop >= 20) { - clearInterval(time); - } - }, 1000); - } - - full() { - this.setState({ isFullScreen: !this.state.isFullScreen }); - } /** 切换光照 */ onSwitchChange = async () => { @@ -911,37 +775,6 @@ class IotCarePlanWE200 extends Component { isStopNurse: !isStopNurse, }); }; - /** LED切换模式 */ - onSwitchChangeLED = () => { - let { isStopNurse } = this.state; - if (isStopNurse) { - // 开始光照逻辑 - this.onNursingTap(); - this.switchVideoPlay(); // 开始 - } else { - // 暂停光照逻辑 - let sendParams: any = { - ...deviceCommandSamples.pause, - workMode: "led", // 使用模式 - workStatus: "standby", - }; - const pauseArrayBuffer = deviceToolKitInstance.toBleCommand( - sendParams as any - ); - sendCommand({ - value: pauseArrayBuffer, - }).then(() => { - this.workStatus = "pause"; - this.resetTimer(); - console.info(`发送暂停指令成功 参数为 =>`, sendParams); - }); - // this.handleWorkStatus(false, MODE_WORKING_ENUM.PAUSE); - this.switchVideoPause(); // 暂停 - } - this.setState({ - isStopNurse: !isStopNurse, - }); - }; /** * @name 每次进入设备运行页,打开首个模式的介绍弹窗 @@ -1235,265 +1068,11 @@ class IotCarePlanWE200 extends Component { }, 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((resolve) => { - setTimeout(() => { - waterStepList[waterStepIndex].schedule = 100; - that.setState({ - waterStepList, - }); - - resolve(); - }, 3000); - }).then(() => { - return new Promise((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"); @@ -1504,33 +1083,8 @@ class IotCarePlanWE200 extends Component { workStatus: newWorkStatus, }; - // 水分测试需要特殊处理 - // 水分测试准备 水分测试工作 水分测试启动 - 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" || - ActiveModeItem.modeType === "essence" - ) { - sendParams.gear = this.state.currentGear; // 点击开始再开始 - } - console.log("准备发送自定义或工作指令", ActiveModeItem, sendParams); + const pauseArrayBuffer = deviceToolKitInstance.toBleCommand( sendParams as any ); diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 10496c3..88ada76 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -39,6 +39,7 @@ import Navbar from "@/components/navbar/navbar"; import ConnectionBluetoot from "@/components/bluetoot/connection"; import UpdateIotWL200 from "@/components/bluetoot/update-wl200/index"; +import UpdateIotFR200 from "@/components/bluetoot/update-fr200/index"; /** 自定义组件 **/ import { @@ -856,7 +857,9 @@ class Index extends Component { // return; if (platform === "devtools") { setStorageSync("instrument_detail", item); - this.setState({ connectInstrument: item }); + this.setState({ + connectInstrument: item, + }); if (item.type === 1) { //非IOT setTimeout(() => { @@ -1027,6 +1030,26 @@ class Index extends Component { isShowVersionUpgradFinish: false, }); }; + UpgradeFinishFun = () => { + let { connectInstrument } = this.state; + console.log("connectInstrument", connectInstrument); + let content = connectInstrument.iotVersionUpgrade; + let nodes = decodeURIComponent(content || ""); + nodes = nodes.replace(/\ { confirm={this.confirmUpdateVersionTip} /> {isShowVersionUpgrading && ( - + + {connectInstrument.model === "WL200" && ( + + )} + + {connectInstrument.model === "FR200" && ( + + )} + )} Date: Wed, 27 Mar 2024 18:48:23 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/moduleIOT/pages/iotCarePlan/FR200.tsx | 134 ++++++++++++---------- 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/src/moduleIOT/pages/iotCarePlan/FR200.tsx b/src/moduleIOT/pages/iotCarePlan/FR200.tsx index b5fb4f1..e83decc 100644 --- a/src/moduleIOT/pages/iotCarePlan/FR200.tsx +++ b/src/moduleIOT/pages/iotCarePlan/FR200.tsx @@ -183,7 +183,9 @@ class IotCarePlanFR200 extends Component { modeType: "", openSourceData: [], }, // 当前选中模式 - SwitchActiveModeItem: {}, // 切换选中模式 + SwitchActiveModeItem: { + modeType: "", + }, // 切换选中模式 ModeID: "mode_", // 模式KEY activeModeID: "", // 当前选中模式ID:用于高亮 @@ -429,10 +431,10 @@ class IotCarePlanFR200 extends Component { title: obj.name, }); - await this.GetModeList(obj.id); + await this.GetModeList(obj?.id); // 如果不存在设备模式值,则判断为首次进入,弹窗提示 - let isFirstTipShow = getStorageSync("first_instrument_" + obj.id); + let isFirstTipShow = getStorageSync("first_instrument_" + obj?.id); if (!isFirstTipShow) { this.firstNurseInfo(); } @@ -508,19 +510,25 @@ class IotCarePlanFR200 extends Component { }); if (this.state.activeModeID != "") { - let res1 = res.data.data.find((e) => e.id == this.state.activeModeID); - setTimeout(() => { - this.modeCurrentFun(res1); - }, 100); + let res1 = res.data.data.find( + (e) => e?.id == this.state.activeModeID + ); + if (res1) { + 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); + let res1 = res.data.data.find((e) => e?.id == this.state.activeModeID); + if (res1) { + setTimeout(() => { + this.modeCurrentFun(res1); + }, 100); + } } else { this.setState({ ModeList: [] }); } @@ -581,20 +589,20 @@ class IotCarePlanFR200 extends Component { // 根据模式,动态设置底部按钮样式 let currentWorkModeType = 1; - if (data.modeType === "moistureTest") { + if (data?.modeType === "moistureTest") { currentWorkModeType = 3; } else if ( - data.modeType === "maskPenetration" || - data.modeType === "essence" || - data.modeType === "led" + data?.modeType === "maskPenetration" || + data?.modeType === "essence" || + data?.modeType === "led" ) { currentWorkModeType = 2; } this.setState({ ActiveModeItem: data, - activeModeID: data.id, - ModeID: "mode_" + data.id, + activeModeID: data?.id, + ModeID: "mode_" + data?.id, waterStepIndex: 0, // 水分测试步骤 EssenceStepIndex: 0, // 精华促渗步骤 MaskModeStepIndex: 0, // 面膜促渗步骤 @@ -613,7 +621,7 @@ class IotCarePlanFR200 extends Component { // FR200 水分测试和促渗不可自动运行,需手动点击开始测试,手动启动检测 // 其他模式可以自动运行 let notStartArr = ["moistureTest", "maskPenetration", "essence"]; - if (!notStartArr.includes(data.modeType)) { + if (!notStartArr.includes(data?.modeType)) { setTimeout(() => { this.onNursingTap("switch"); }, 800); @@ -673,8 +681,8 @@ class IotCarePlanFR200 extends Component { switchModeCurrentFun = async (data) => { this.setState({ SwitchActiveModeItem: data, - activeModeID: data.id, - ModeID: "mode_" + data.id, + activeModeID: data?.id, + ModeID: "mode_" + data?.id, }); }; // 打开模式切换弹窗 @@ -723,7 +731,7 @@ class IotCarePlanFR200 extends Component { setTimeout(() => { this.onNursingTap(); // // 倒计时弹窗: 倒计时完成后,自动开始,并判断弹窗 - // let downNum = CountDownTime[this.state.ActiveModeItem.modeType] || 3; + // let downNum = CountDownTime[this.state.ActiveModeItem?.modeType] || 3; // this.showCountdownFun(downNum, () => {}); }, 500); @@ -741,9 +749,9 @@ class IotCarePlanFR200 extends Component { let params: any = {}; params = { - instrumentId: currentDevice.id, + instrumentId: currentDevice?.id, instrumentName: currentDevice.name, - modeId: ActiveModeItem.id, + modeId: ActiveModeItem?.id, modeName: ActiveModeItem.modeName, nursingTime: s_to_hms(this.elapsedTime), nursingData: JSON.stringify({ @@ -770,8 +778,8 @@ class IotCarePlanFR200 extends Component { this.moistureTest( params.nursingData, formattedDate, - ActiveModeItem.id, - currentDevice.id + ActiveModeItem?.id, + currentDevice?.id ); }, 2000); }; @@ -885,7 +893,7 @@ class IotCarePlanFR200 extends Component { let { isStopNurse, ActiveModeItem } = this.state; console.log("切换光照,", ActiveModeItem); - if (ActiveModeItem.modeType === "led") { + if (ActiveModeItem?.modeType === "led") { this.onSwitchChangeLED(); return; } @@ -940,7 +948,7 @@ class IotCarePlanFR200 extends Component { */ openStepTips = () => { let isFirstEntryModeNot = getStorageSync( - "isFirstEntryMode_" + this.state.currentDevice.id + "isFirstEntryMode_" + this.state.currentDevice?.id ); // 1.如果没有持久化不再提示,每次进入都会弹窗提示 if (!isFirstEntryModeNot) { @@ -952,7 +960,7 @@ class IotCarePlanFR200 extends Component { }; closeStepTips = (data) => { if (data.isLocal) { - setStorageSync("isFirstEntryMode_" + this.state.currentDevice.id, true); // 关闭首次进入弹窗 + setStorageSync("isFirstEntryMode_" + this.state.currentDevice?.id, true); // 关闭首次进入弹窗 } this.setState({ isShowStepTips: false }); }; @@ -1068,7 +1076,7 @@ class IotCarePlanFR200 extends Component { let nowModeItem; if (nWorkMode) { nowModeItem = ModeList.find((item) => { - return item.modeType === nWorkMode; + return item?.modeType === nWorkMode; }); } opts.workStatus = nWorkStatus; @@ -1208,9 +1216,9 @@ class IotCarePlanFR200 extends Component { }); // 根据不同的模式,切换步骤到下一步 - if (ActiveModeItem.modeType === "essence") { + if (ActiveModeItem?.modeType === "essence") { this.essencePenetrationNext(); - } else if (ActiveModeItem.modeType === "maskPenetration") { + } else if (ActiveModeItem?.modeType === "maskPenetration") { this.maskPenetrationNext(); } } else { @@ -1371,7 +1379,7 @@ class IotCarePlanFR200 extends Component { const { ActiveModeItem, currentGear } = this.state; let sendParams: any = { ...deviceCommandSamples.pause, - workMode: ActiveModeItem.modeType, // 使用模式 + workMode: ActiveModeItem?.modeType, // 使用模式 workStatus: "working", gear: currentGear, }; @@ -1420,7 +1428,7 @@ class IotCarePlanFR200 extends Component { let sendParams: any = { ...deviceCommandSamples.pause, - workMode: ActiveModeItem.modeType, // 使用模式 + workMode: ActiveModeItem?.modeType, // 使用模式 workStatus: "working", gear: gear, }; @@ -1445,7 +1453,7 @@ class IotCarePlanFR200 extends Component { let sendParams: any = { ...deviceCommandSamples.pause, - workMode: ActiveModeItem.modeType, // 使用模式 + workMode: ActiveModeItem?.modeType, // 使用模式 workStatus: "working", gear: currentGear, }; @@ -1492,13 +1500,13 @@ class IotCarePlanFR200 extends Component { let sendParams: any = { ...deviceCommandSamples.pause, - workMode: ActiveModeItem.modeType, // 使用模式 + workMode: ActiveModeItem?.modeType, // 使用模式 workStatus: newWorkStatus, }; // 水分测试需要特殊处理 // 水分测试准备 水分测试工作 水分测试启动 - if (ActiveModeItem.modeType === "moistureTest") { + if (ActiveModeItem?.modeType === "moistureTest") { let that = this; sendParams.testStatus = "standby"; // 切换为准备 @@ -1516,8 +1524,8 @@ class IotCarePlanFR200 extends Component { // 面膜促渗和精华促渗 if ( - ActiveModeItem.modeType === "maskPenetration" || - ActiveModeItem.modeType === "essence" + ActiveModeItem?.modeType === "maskPenetration" || + ActiveModeItem?.modeType === "essence" ) { sendParams.gear = this.state.currentGear; // 点击开始再开始 } @@ -1695,7 +1703,7 @@ class IotCarePlanFR200 extends Component { // 仪器缓存模式,判断是否存在于现有模式中 let recordModeItem = ModeList.find((item) => { - return item.id == FR200NursingHistory.modeId; + return item?.id == FR200NursingHistory.modeId; }); if (!FR200NursingHistory || !recordModeItem) { console.log("仪器有数据, 但是缓存没有数据, 忽略"); @@ -1716,7 +1724,7 @@ class IotCarePlanFR200 extends Component { !workStatus ) { // 判断id是否一致, 一致的话则生成护理报表 - if (jsonStatus.id == FR200NursingHistory.id) { + if (jsonStatus?.id == FR200NursingHistory?.id) { console.log("id一致, 设备没有运行/已完成/待机"); let totalSeconds = jsonStatus.totalSeconds; // 从仪器上获取的使用时间 @@ -1737,9 +1745,9 @@ class IotCarePlanFR200 extends Component { : s_to_hms(this.elapsedTime); let params = { - instrumentId: currentDevice.id, + instrumentId: currentDevice?.id, instrumentName: currentDevice.name, - modeId: ActiveModeItem.id, + modeId: ActiveModeItem?.id, modeName: ActiveModeItem.modeName, nursingTime: timeValue, }; @@ -1750,9 +1758,9 @@ class IotCarePlanFR200 extends Component { } else { // ID不一致,同步异常,统一提交一分钟 let params = { - instrumentId: currentDevice.id, + instrumentId: currentDevice?.id, instrumentName: currentDevice.name, - modeId: ActiveModeItem.id, + modeId: ActiveModeItem?.id, modeName: ActiveModeItem.modeName, nursingTime: "00:01:00", }; @@ -1765,7 +1773,7 @@ class IotCarePlanFR200 extends Component { console.log("id一致, 设备运行中或暂停"); // 5.判断设备状态-运行中 // 同步时间 - if (jsonStatus.id == FR200NursingHistory.id) { + if (jsonStatus?.id == FR200NursingHistory?.id) { if (FR200NursingHistory.currentTime) { this.isRuning = true; this.resetTimer(); @@ -1793,8 +1801,8 @@ class IotCarePlanFR200 extends Component { videoTime: this.FR200NursingHistory.videoTime, tempModeCurrent: ActiveModeItem, ActiveModeItem: ActiveModeItem, - activeModeID: ActiveModeItem.id, - ModeID: "mode_" + ActiveModeItem.id, + activeModeID: ActiveModeItem?.id, + ModeID: "mode_" + ActiveModeItem?.id, currentTime: this.FR200NursingHistory.currentTime, }); } @@ -1805,9 +1813,9 @@ class IotCarePlanFR200 extends Component { const params = { createDate: dayjs().format("YYYY-MM-DD"), workMode: jsonStatus.workMode, - instrumentId: currentDevice.id, + instrumentId: currentDevice?.id, instrumentName: currentDevice.name, - modeId: ActiveModeItem.id, + modeId: ActiveModeItem?.id, modeName: ActiveModeItem.modeName, id: dayjs().format("YYYY-MM-DD HH:mm:ss"), neededTotalSeconds: jsonStatus.neededTotalSeconds, @@ -1837,7 +1845,7 @@ class IotCarePlanFR200 extends Component { params.dataArray.push(jsonStatus); params.jsonStatus = jsonStatus; params.workMode = jsonStatus?.workMode; - params.modeId = this.state.ActiveModeItem.id; + params.modeId = this.state.ActiveModeItem?.id; params.modeName = this.state.ActiveModeItem.modeName; console.log(jsonStatus, 555555555555); @@ -1845,7 +1853,7 @@ class IotCarePlanFR200 extends Component { } else { params.jsonStatus = jsonStatus; params.workMode = jsonStatus?.workMode; - params.modeId = data.id; + params.modeId = data?.id; params.modeName = data.modeName; } @@ -1995,9 +2003,9 @@ class IotCarePlanFR200 extends Component { params = data; } else { params = { - instrumentId: currentDevice.id, + instrumentId: currentDevice?.id, instrumentName: currentDevice.name, - modeId: ActiveModeItem.id, + modeId: ActiveModeItem?.id, modeName: ActiveModeItem.modeName, nursingTime: s_to_hms(this.elapsedTime), }; @@ -2012,7 +2020,7 @@ class IotCarePlanFR200 extends Component { console.log("PostNursingLogClock", res2); if (res2.data.code === 200) { let params = { - instrumentId: currentDevice.id, + instrumentId: currentDevice?.id, }; // 上传护理完成的仪器ID let res = await InstrumentInfo.apiClock.addClockInstrument(params); @@ -2030,9 +2038,9 @@ class IotCarePlanFR200 extends Component { this.goFaceReport( res1, - ActiveModeItem.id, + ActiveModeItem?.id, res2.data.data, - currentDevice.id + currentDevice?.id ); // 跳转 }, 2000); } @@ -2223,13 +2231,13 @@ class IotCarePlanFR200 extends Component { firstNurseInfo = async () => { let { currentDevice } = this.state; let res = await InstrumentInfo.firstNurseInfo({ - instrumentId: currentDevice.id, + instrumentId: currentDevice?.id, }); console.log(res, "接口"); if (res.data.code === 200) { let isFirstTipShow = getStorageSync( - "first_instrument_" + currentDevice.id + "first_instrument_" + currentDevice?.id ); console.log(isFirstTipShow, "查看返回值"); @@ -2239,7 +2247,7 @@ class IotCarePlanFR200 extends Component { this.setState({ nurseInfo: res.data.data, isFirstTipShow: true }); } - setStorageSync("first_instrument_" + currentDevice.id, true); + setStorageSync("first_instrument_" + currentDevice?.id, true); } else { this.setState({ nurseInfo: res.data.data }); } @@ -2249,7 +2257,7 @@ class IotCarePlanFR200 extends Component { this.setState({ isFirstTipShow: true }); }; onTipShowClose = async () => { - setStorageSync("first_instrument_" + this.state.currentDevice.id, true); + setStorageSync("first_instrument_" + this.state.currentDevice?.id, true); this.setState({ isFirstTipShow: false }); }; /** 初次护理信息弹窗 END */ @@ -2576,8 +2584,8 @@ class IotCarePlanFR200 extends Component { > - {(ActiveModeItem.modeType === "maskPenetration" || - ActiveModeItem.modeType === "essence") && ( + {(ActiveModeItem?.modeType === "maskPenetration" || + ActiveModeItem?.modeType === "essence") && ( { > )} - {ActiveModeItem.modeType === "moistureTest" && ( + {ActiveModeItem?.modeType === "moistureTest" && (