diff --git a/package.json b/package.json index 3259076..b1bb931 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "dependencies": { "@antmjs/vantui": "^3.2.2", "@flossom-npm/iot-translater": "^1.0.8", - "@flossom-npm/iot-translater-we100": "^1.0.66", + "@flossom-npm/iot-translater-we100": "^1.1.1", "@reduxjs/toolkit": "^2.0.1", "@taroify/core": "^0.1.1-alpha.8", "@tarojs/components": "3.6.19", diff --git a/src/app.boot.js b/src/app.boot.js new file mode 100644 index 0000000..a2f9302 --- /dev/null +++ b/src/app.boot.js @@ -0,0 +1,53 @@ +import Taro from "@tarojs/taro"; +import { Component, PropsWithChildren } from "react"; +import "./app.less"; +// // html4 +// import "@tarojs/taro/html.css"; +// // html5 +// import "@tarojs/taro/html5.css"; + +import { Provider } from "react-redux"; +import store from "./store"; +import "./iconfont/iconfont.css"; +import "taro-ui/rn/style/components/icon.scss"; + +import { go } from "./utils/traoAPI"; + +class App extends Component { + // 可以使用所有的 React 生命周期方法 + componentDidMount() {} + + // 对应 onLaunch + onLaunch(options) { + // console.log("onLaunch", options); + if (options.scene == 1007 || options.scene == 1008) { + return; + } + + // go("/pages/iotCarePlan/iotCarePlan"); + // go("/pages/instrument_clickin_upload/index"); + // go("/pages/instrument/intro"); + // Taro.switchTab({ + // url: "/pages/user/user", + // }); + go("/pages/index/index"); + } + + onError(error) { + console.log("error 错误捕获", error); + } + + // 对应 onShow + componentDidShow() {} + + // 对应 onHide + componentDidHide() {} + + // this.props.children 是将要会渲染的页面 + render() { + // return this.props.children + return ; + } +} + +export default App; diff --git a/src/components/bluetoot/connection/index.tsx b/src/components/bluetoot/connection/index.tsx index 91e6a77..09eed6b 100644 --- a/src/components/bluetoot/connection/index.tsx +++ b/src/components/bluetoot/connection/index.tsx @@ -32,43 +32,58 @@ import { getofflineData, hex2int, getTimeCode, + isNeedToUpdate, } from "@/utils/util"; -const log = require("@/utils/log"); +// const log = require("@/utils/log"); import commandMap from "@/utils/commandMap"; import { bleCommandSamples } from "./test"; import { DeviceToolKit as DeviceToolKitWE100 } from "@flossom-npm/iot-translater-we100"; -const deviceToolKitInstanceWL200 = new DeviceToolKitWE100("WE100", "WL200"); +const deviceToolKitInstanceWL200 = new DeviceToolKitWE100("WL200", "WL200"); deviceToolKitInstanceWL200.setDebug(true); +// const _deviceToolKitInstanceWL200 = new DeviceToolKitWE100("WE100", "WL200"); + const deviceToolKitInstanceM01 = new DeviceToolKitWE100("WE100", "M01"); deviceToolKitInstanceM01.setDebug(true); const deviceToolKitInstanceFR200 = new DeviceToolKitFR200("FR200"); import { DeviceToolKit as DeviceToolKitFR200 } from "@flossom-npm/iot-translater"; -import { showModal, msg } from "@/utils/traoAPI"; +import { + showModal, + msg, + setStorageSync, + getStorageSync, +} from "@/utils/traoAPI"; // const { InstrumentTypeEnum, OtaDeviceTypeEnum } = app.globalData; import InstrumentTypeEnum from "../InstrumentTypeEnum"; import OtaDeviceTypeEnum from "../OtaDeviceTypeEnum"; +// 定义一个变量,用于存放获取版本定时器 let isGetVersionTimer: any = null; +// 定义一个变量,用于存放获取子设备定时器 let isGetSubDeviceTimer: any = null; +// 定义一个变量,用于存放获取同步录制定时器 let isGetSyncRecordingTimer: any = null; +// 定义一个变量,用于存放超时定时器 let overTimer: any = null; +// 定义一个变量,用于存放获取子设备定时器次数 let isGetSubDeviceTimerNum = 0; +// 定义一个变量,用于存放发送获取版本定时器 let sendgetversionTimer: any = null; +// 定义一个变量,用于存放发送获取版本定时器次数 let sendGetVersionTimerNum = 0; let searchBluetootTimers: any = null; // 搜索蓝牙定时器 -let searchBluetootTimersNum = 0; // 搜索蓝牙秒数 +let searchBluetootTimersNum = 15; // 搜索蓝牙秒数 15秒 let connectionTimer: any = null; // 连接蓝牙定时器 -let connectionTimerNum = 0; +let connectionTimerNumber = 10000; // 连接蓝牙超时毫秒 let sendPairingTimer: any = null; // 发送配对 @@ -99,12 +114,30 @@ class ConnectionBluetoot extends Component { offlineDataindex: 0, //离线记录发送下标index versionInfo: {}, //版本号 offlineDataList: [], //离线数据 + + prefix: "12CAA", // WL200蓝牙搜索前缀 + + // WL200匹配 + tranType: [ + "WE100", // 发箍 + "WE200", // 发箍 + "WL200", // 发箍 + "12CAA", // 面罩前缀名 + ], }; } async onLoad() {} componentDidMount() { - this.connection(); + // 只有非断开状态的弹窗才自动连接蓝牙 + if (!this.props.isDisconnect) { + this.connection(); + } else { + // 断开状态弹窗:自动设置为错误模式 + this.setState({ + error: true, + }); + } } componentWillUnmount() {} @@ -115,15 +148,23 @@ class ConnectionBluetoot extends Component { async initData() {} + isWL200() { + let currentDevicesName = getStorageSync("currentDevicesName"); + if (currentDevicesName.indexOf("12CAA") > -1) { + return true; + } + return false; + } + close() { clearInterval(sendPairingTimer); clearInterval(sendgetversionTimer); clearTimeout(isGetVersionTimer); clearTimeout(isGetSyncRecordingTimer); if (overTimer) clearTimeout(overTimer); + // 重新开始 this.again(); - // this.triggerEvent("close", "connection_guide"); - console.log("this.close"); + // 关闭弹窗 this.onClose(); Taro.closeBluetoothAdapter(); } @@ -260,7 +301,7 @@ class ConnectionBluetoot extends Component { "searchBluetootTimersNum value => ", searchBluetootTimersNum ); - if (searchBluetootTimersNum === 8) { + if (searchBluetootTimersNum === 15) { clearInterval(searchBluetootTimers); this.setState({ error: true, @@ -282,43 +323,36 @@ class ConnectionBluetoot extends Component { onBluetoothDeviceFound() { Taro.onBluetoothDeviceFound((item: any) => { console.log("蓝牙查找item", item, item.devices[0].name); - /* - * 这里增加判断,类型不同识别的设备名称不一样 - * type1 FR200 - * type2 WM100 - * type3 we100 - * type4 FR380 - * */ - // const tranType = { - // 1: "FR200", - // 3: "WE200", // WL200 - // 4: "FR380", - // 5: "FR390", - // 6: "WE200", // M01 - // }; - // let type = this.props.yiqiInfo.model || "FR200"; - let type = "WE200"; - // this.props.yiqiInfo.model = type; - console.log("this.props.yiqiInfo.model", this.props.yiqiInfo.model); console.info("搜索到到蓝牙设备 value => ", item.devices[0]?.name); + console.log(">>>>>>>当前传入设备类型>>>>>", this.props.deviceInfo.model); + // 先匹配到哪个连接哪个 + let tranType = [ + this.props.deviceInfo.model, // 当前传入设备类型 + ...this.state.tranType, + ]; for (let i = 0; i < item.devices.length; i++) { - if ( - item.devices[i].connectable && - (item.devices[i].localName - ? item.devices[i].localName - : item.devices[i].name - ).indexOf(`${type}`) !== -1 - ) { - console.log("连接的设备信息", item.devices[i], type); + let devicesName = item.devices[i].localName || item.devices[i].name; + console.log("devicesName", devicesName); + console.log("tranType", tranType); + // 是否匹配可连接设备 + let isAvailable = tranType.some( + (item) => devicesName && devicesName.indexOf(item) > -1 + ); + console.log("isAvailable", isAvailable); + // 判断设备是否可连接 + if (item.devices[i].connectable && isAvailable) { + // 缓存当前连接设备名 可能是发箍或面罩 + setStorageSync("currentDevicesName", devicesName); + console.log("连接的设备信息", item.devices[i], devicesName); + let params = { deviceId: item.devices[i].deviceId, }; - this.props.setDeviceId(params); + this.props.setDeviceId(params); // 设置蓝牙连接设备ID setTimeout(() => { clearInterval(searchBluetootTimers); Taro.stopBluetoothDevicesDiscovery(); //停止搜索蓝牙 - // app.globalData.deviceInfo.deviceId = item.devices[i].deviceId; this.createBLEConnection(); }, 10); break; @@ -335,11 +369,7 @@ class ConnectionBluetoot extends Component { await closeBLEConnection(this.props.bluetoothInfo.deviceId); } catch (e) {} clearTimeout(connectionTimer); - const { yiqiInfo: deviceInfo } = this.props; - console.log( - "this.props.bluetoothInfo.deviceId", - this.props.bluetoothInfo.deviceId - ); + const { deviceInfo } = this.props; /*********开始主动连接*******/ createBLEConnection(this.props.bluetoothInfo.deviceId) .then((res) => { @@ -347,15 +377,12 @@ class ConnectionBluetoot extends Component { let { errno, errMsg } = res; if (errno == 0) { if (deviceInfo.model === "WL200") { - this.setState({ - connectionStatus: true, - }); connectionTimer = setTimeout(() => { if (!this.state.islian) { if (overTimer) clearTimeout(overTimer); this.failErrorCode(-1, "连接蓝牙失败,请重新开机后重试"); } - }, 10000); + }, connectionTimerNumber); } this.getBLEDeviceServices(); //获取特征 } else { @@ -400,7 +427,7 @@ class ConnectionBluetoot extends Component { /** 7.通知BLE特征值更改 */ notifyBLECharacteristicValueChange() { console.log("7.通知BLE特征值更改"); - const { yiqiInfo: deviceInfo } = this.props; + const { deviceInfo } = this.props; const bluetoothInfo = this.props.bluetoothInfo; notifyBLECharacteristicValueChange({ deviceId: bluetoothInfo.deviceId, @@ -417,39 +444,32 @@ class ConnectionBluetoot extends Component { console.log("onBLECharacteristicValueChange value => ", value); let str = ab2hex(value.value); //转为16进制字符串 console.log("转为16进制字符串 str", str); - let connectionStatus = [ - "FR200", - "WL200", - "FR380", - "FR390", - "M01", - ].includes(deviceInfo.model); let jsonStatus: any = null; let querySubDeviceArrayBuffer; + if (deviceInfo.model == "WL200") { - // querySubDeviceArrayBuffer = - // deviceToolKitInstanceWL200.toBleCommand( - // bleCommandSamples.querySubDevice as any - // ); - // jsonStatus = deviceToolKitInstanceWL200.toJsonStatus( - // value.value - // ); - jsonStatus = deviceToolKitInstanceM01.toJsonStatus(value.value); - querySubDeviceArrayBuffer = deviceToolKitInstanceM01.toBleCommand( - bleCommandSamples.querySubDevice as any - ); // todo + if (this.isWL200()) { + jsonStatus = deviceToolKitInstanceWL200.toJsonStatus( + value.value + ); + querySubDeviceArrayBuffer = + deviceToolKitInstanceWL200.toBleCommand( + bleCommandSamples.querySubDevice as any + ); + } else { + jsonStatus = deviceToolKitInstanceM01.toJsonStatus(value.value); + querySubDeviceArrayBuffer = + deviceToolKitInstanceM01.toBleCommand( + bleCommandSamples.querySubDevice as any + ); + } } else if (deviceInfo.model == "M01") { jsonStatus = deviceToolKitInstanceM01.toJsonStatus(value.value); querySubDeviceArrayBuffer = deviceToolKitInstanceM01.toBleCommand( bleCommandSamples.querySubDevice as any ); } - // log.info( - // commandMap.reciviedBLECommand, - // `仪器模式: ${deviceInfo.model}`, - // jsonStatus - // ); console.log( commandMap.reciviedBLECommand, `仪器模式: ${deviceInfo.model}`, @@ -465,12 +485,11 @@ class ConnectionBluetoot extends Component { if (overTimer) clearTimeout(overTimer); this.setState({ connectionSuccess: true, - connectionStatus, islian: true, // 不需要离线记录,但暂未完全删除这部分逻辑,所以直接设为true }); - this.pairingChange(this.state); // 临时添加,用于跳转 - // this.detectVersionUpdate(); // 获取升级信息 + // this.pairingChange(this.state); // 临时添加,用于跳转 + this.detectVersionUpdate(); // 获取升级信息 // todo 连接成功需删除离线记录,暂时未缓存离线记录 if (this.state.connectionSuccess) return; // 暂时不需要查询是否连接子设备, 直接进入查询版本信息 @@ -482,7 +501,7 @@ class ConnectionBluetoot extends Component { }*/ } break; - case "BleStatusSync": + case "BleStatusSync": // 设备连接状态 if (jsonStatus.connectMessage?.connectType == "CONNECTED") { switch (jsonStatus.connectMessage?.deviceName) { case OtaDeviceTypeEnum.WE100: @@ -518,26 +537,27 @@ class ConnectionBluetoot extends Component { subDeviceConnectedStatus: true, synchronousStatus: true, }); - const deviceVersionNo = jsonStatus.versionNo; - const latestVersionNo = deviceInfo.iot_versions; - // const isNeedToUpdateBl = isNeedToUpdate(deviceVersionNo, latestVersionNo) - // 判断是否需要升级 - // M01和WL200 不需要在这里进行蓝牙更新 - // if (isNeedToUpdateBl) { - // const pages = getCurrentPages(); - // const matchPageList = [{ - // route: 'pages/MatrixWL200/pages/index/index' - // },{ - // route: 'pages/MatrixM01/pages/index/index' - // }]; - // const hadOpen = checkSameKey(pages, matchPageList, 'route'); - // if (!hadOpen) { - // this.triggerEvent("pairingChange", { deviceVersionNo }); - this.pairingChange({ deviceVersionNo }); - // } - // } else { - // this.sendSyncRecording() - // } + + let currentDevicesName = getStorageSync("currentDevicesName"); + let deviceVersionNo = jsonStatus.versionNo; + let latestVersionNo = deviceInfo.iotVersion; + if (currentDevicesName.indexOf("12CAA") === -1) { + latestVersionNo = deviceInfo.we200IotVersion; + } + // 判断版本号是否需要升级 + const isNeedToUpdateBl = isNeedToUpdate( + deviceVersionNo, + latestVersionNo + ); + console.log("isNeedToUpdateBl", isNeedToUpdateBl); + if (isNeedToUpdateBl) { + // 版本号需要更新: 告诉父级页面,关闭连接弹窗,显示更新弹窗 + this.props.upgradeFun(); + } else { + // 不需要升级,跳转进入仪器详情页 + if (isGetVersionTimer) clearTimeout(isGetVersionTimer); + this.pairingChange(this.state); + } break; case "offlineClockSummary": clearTimeout(isGetSyncRecordingTimer); @@ -546,9 +566,12 @@ class ConnectionBluetoot extends Component { hasSyncRecord: true, synchronousStatus: true, }); - console.log("offlineClockSummary value =>", jsonStatus); - // this.triggerEvent("pairingChange", this.state); - this.pairingChange(this.state); + console.log( + "离线汇总offlineClockSummary value =>", + jsonStatus + ); + // this.triggerEvent("pairingChange", this.state); + // this.pairingChange(this.state); // TODO 查询离线记录结果 default: break; @@ -610,7 +633,7 @@ class ConnectionBluetoot extends Component { // 8.发送指令:获取仪器版本号 sendGetVersion() { - const { yiqiInfo: deviceInfo } = this.props; + const { deviceInfo } = this.props; const isFRDevice = ["FR200", "FR380", "FR390"].includes(deviceInfo.model); // log.info(commandMap.sendVersionCommand, `仪器:${deviceInfo.model}`); console.log(commandMap.sendVersionCommand, `仪器:${deviceInfo.model}`); @@ -624,22 +647,21 @@ class ConnectionBluetoot extends Component { value: `dbf0a00300${ccrc8("dbf0a00300")}de`, }); } else { - // const otaDeviceType = deviceInfo.type == instrumentTypeEnum.WL200 ? OtaDeviceTypeEnum.WL200 : OtaDeviceTypeEnum.WE100; - // 通过发箍连 都用we100 - const otaDeviceType = - deviceInfo.model == InstrumentTypeEnum.WL200 - ? OtaDeviceTypeEnum.WE100 - : OtaDeviceTypeEnum.WE100; + const otaDeviceType = this.isWL200() + ? OtaDeviceTypeEnum.WL200 + : OtaDeviceTypeEnum.WE100; const versionCommand = { commandType: "InfoQuery", infoQueryType: "versionInfo", otaDeviceType, }; - const value = - deviceInfo.model == InstrumentTypeEnum.WL200 - ? deviceToolKitInstanceM01.toBleCommand(versionCommand as any) - : deviceToolKitInstanceM01.toBleCommand(versionCommand as any); - // const value = deviceInfo.type == instrumentTypeEnum.WL200 ? deviceToolKitInstanceWL200.toBleCommand(versionCommand) : deviceToolKitInstanceM01.toBleCommand(versionCommand); + console.log("versionCommand", versionCommand); + + // 区分WL200 和 发箍 + const value = this.isWL200() + ? deviceToolKitInstanceWL200.toBleCommand(versionCommand as any) + : deviceToolKitInstanceM01.toBleCommand(versionCommand as any); + sendCommand({ value }); } } @@ -648,7 +670,7 @@ class ConnectionBluetoot extends Component { sendofflist() { // log.info() if (this.state.offlineDataindex == this.state.offlineDataList.length) { - console.log("离线记录获取完成"); + console.log("离线记录获取完成", this.state); // log.info(commandMap.finishOfflineData, this.state.offlineDataList); /**** * 发送同步时间 @@ -658,8 +680,6 @@ class ConnectionBluetoot extends Component { console.log("版本号:" + this.state.versionInfo.version); this.setState({ islian: true }); clearTimeout(connectionTimer); - // this.triggerEvent("offlineChange", this.state); - console.log("this.triggerEvent", this.state); this.offlineChange(this.state); return false; } @@ -693,7 +713,7 @@ class ConnectionBluetoot extends Component { /** 9.发送配对码 */ sendPairingSignal() { console.log("9.发送配对码 sendPairingSignal"); - const { yiqiInfo: deviceInfo } = this.props; + const { deviceInfo } = this.props; // log.info(commandMap.sendMatchCode, `仪器:${deviceInfo.model}发送匹配码`); console.log(commandMap.sendMatchCode, `仪器:${deviceInfo.model}发送匹配码`); let matchArrayBuffer: any = null; @@ -704,14 +724,20 @@ class ConnectionBluetoot extends Component { ); break; case InstrumentTypeEnum.WL200: - // console.log("WL200无法配对,只能用M01"); console.log("正在发送WL200", bleCommandSamples.match); - // matchArrayBuffer = deviceToolKitInstanceWL200.toBleCommand( - // bleCommandSamples.match as any - // ); - matchArrayBuffer = deviceToolKitInstanceM01.toBleCommand( - bleCommandSamples.match as any - ); + let currentDevicesName = getStorageSync("currentDevicesName"); + // 区分面罩和发箍 + if (currentDevicesName.indexOf("12CAA") > -1) { + console.log("12CAA"); + matchArrayBuffer = deviceToolKitInstanceWL200.toBleCommand( + bleCommandSamples.match as any + ); + } else { + matchArrayBuffer = deviceToolKitInstanceM01.toBleCommand( + bleCommandSamples.match as any + ); + } + break; case InstrumentTypeEnum.FR380: writeBLECharacteristicValue({ @@ -752,64 +778,6 @@ class ConnectionBluetoot extends Component { }); } - /** 发送记录 */ - sendOfflistPost(str) { - let facehour = hex2int(str.substring(12, 14)); //脸部小时 - let faceminutes = hex2int(str.substring(14, 16)); //脸部分钟 - let faceseconds = hex2int(str.substring(16, 18)); //脸部秒 - let faceposition1 = hex2int(str.substring(18, 20)); //当前档位 - let facenum = hex2int(str.substring(20, 22)); //次数 - let faceyear = hex2int(str.substring(22, 24)); //年份 - let facemonth = hex2int(str.substring(24, 26)); //月份 - let faceday = hex2int(str.substring(26, 28)); //日期 - - let eyehour = hex2int(str.substring(28, 30)); //眼部小时 - let eyeminutes = hex2int(str.substring(30, 32)); //眼部分钟 - let eyeseconds = hex2int(str.substring(32, 34)); //眼部秒 - let eyeposition1 = hex2int(str.substring(34, 36)); //当前档位 - let eyenum = hex2int(str.substring(36, 38)); //次数 - let eyeyear = hex2int(str.substring(38, 40)); //年份 - let eyemonth = hex2int(str.substring(40, 42)); //月份 - let eyeday = hex2int(str.substring(42, 44)); //日期 - // console.log('脸部小时:' + facehour) - // console.log('脸部分钟:' + faceminutes) - // console.log('脸部秒:' + faceseconds) - // console.log('当前档位:' + faceposition1) - // console.log('脸部次数:' + facenum) - // console.log('年:' + faceyear) - // console.log('月:' + facemonth) - // console.log('日:' + faceday) - // console.log('-------------------') - // console.log('眼部小时:' + eyehour) - // console.log('眼部分钟:' + eyeminutes) - // console.log('眼部秒:' + eyeseconds) - // console.log('当前档位:' + eyeposition1) - // console.log('眼部次数:' + eyenum) - // console.log('年:' + eyeyear) - // console.log('月:' + eyemonth) - // console.log('日:' + eyeday) - let { offlineDataList } = this.state; - offlineDataList.push({ - facehour, - faceminutes, - faceseconds, - faceposition1, - facenum, - faceyear, - facemonth, - faceday, - eyehour, - eyeminutes, - eyeseconds, - eyeposition1, - eyenum, - eyeyear, - eyemonth, - eyeday, - }); - this.setState({ offlineDataList }); - } - /** 同步时间 */ sendAsyncTime() { console.log("同步时间"); @@ -853,9 +821,6 @@ class ConnectionBluetoot extends Component { case 10000: errorText = "未初始化蓝牙适配器"; break; - case 10000: - errorText = "未初始化蓝牙适配器"; - break; case 10001: errorText = "当前蓝牙适配器不可用"; break; @@ -957,7 +922,8 @@ class ConnectionBluetoot extends Component { isGetSubDeviceTimer = setInterval(() => { sendCommand({ value }); isGetSubDeviceTimerNum += 1; - if (isGetSubDeviceTimerNum == 8) { + // 15秒超时 + if (isGetSubDeviceTimerNum === 15) { this.closeQuerySubDevice(); this.setState({ error: true, @@ -973,30 +939,25 @@ class ConnectionBluetoot extends Component { // 获取版本信息 detectVersionUpdate() { this.closeQuerySubDevice(); - this.sendGetVersion(); + this.sendGetVersion(); // 获取版本信息 sendGetVersionTimerNum = 0; // 600毫秒查询一次版本号是否返回,若返回则跳转护理页 if (isGetVersionTimer) clearTimeout(isGetVersionTimer); isGetVersionTimer = setInterval(() => { if (this.state.hasVersionInfo) { if (isGetVersionTimer) clearTimeout(isGetVersionTimer); - // that.sendSyncRecording() } else { sendGetVersionTimerNum += 1; if (sendGetVersionTimerNum >= 10) { // 超时未返回版本号 if (isGetVersionTimer) clearTimeout(isGetVersionTimer); - this.setState({ - connectionStatus: true, - }); - // this.triggerEvent("pairingChange", this.state); - console.log("this.pairingChange", this.state); + console.log("超时未返回版本号 this.pairingChange", this.state); this.pairingChange(this.state); } else { this.sendGetVersion(); } } - }, 600); + }, 1000); // 5秒后没有收到版本返回,直接跳去护理页 // if (isGetVersionTimer) clearTimeout(isGetVersionTimer); @@ -1011,15 +972,14 @@ class ConnectionBluetoot extends Component { /** 发送同步记录 */ sendSyncRecording() { - const { yiqiInfo: deviceInfo } = this.props; + const { deviceInfo } = this.props; const versionCommand = { commandType: "InfoQuery", infoQueryType: "offlineClockSummary", }; - const value = - deviceInfo.model == InstrumentTypeEnum.WL200 - ? deviceToolKitInstanceWL200.toBleCommand(versionCommand as any) - : deviceToolKitInstanceM01.toBleCommand(versionCommand as any); + const value = this.isWL200() + ? deviceToolKitInstanceWL200.toBleCommand(versionCommand as any) + : deviceToolKitInstanceM01.toBleCommand(versionCommand as any); sendCommand({ value }).then(); if (isGetSyncRecordingTimer) clearTimeout(isGetSyncRecordingTimer); isGetSyncRecordingTimer = setTimeout(() => { @@ -1041,6 +1001,15 @@ class ConnectionBluetoot extends Component { onReconnect = () => { console.log("onReconnect"); + // 重置信息并重连 + this.setState({ + error: false, + searchError: false, + errorText: "", + }); + setTimeout(() => { + this.connection(); + }); // this.props.confirm("confirm"); }; @@ -1053,24 +1022,21 @@ class ConnectionBluetoot extends Component { }; render() { - let { name, isConnection, connectionStatus, connectionSuccess, error } = - this.state; - let { yiqiInfo } = this.props; + let { isConnection, connectionSuccess, error } = this.state; + let { deviceInfo, isDisconnect } = this.props; return ( - {name} ); } diff --git a/src/components/bluetoot/device-connection-popup/device-connection-popup.less b/src/components/bluetoot/device-connection-popup/device-connection-popup.less index 2d6f098..e36b80e 100644 --- a/src/components/bluetoot/device-connection-popup/device-connection-popup.less +++ b/src/components/bluetoot/device-connection-popup/device-connection-popup.less @@ -13,12 +13,12 @@ // } .site-close { position: absolute; - right: 36rpx; - top: 36rpx; - color: #fff; + right: 16rpx; + top: 16rpx; + color: #000; font-size: 36rpx; z-index: 100009; - background-color: #ababab; + background-color: transparent; border-radius: 50%; padding: 8rpx; box-sizing: border-box; @@ -64,7 +64,7 @@ display: flex; align-items: center; position: relative; - width: 100%; + width: 84%; box-sizing: border-box; display: flex; // column-gap: 30rpx; @@ -76,6 +76,7 @@ width: 36rpx; min-width: 36rpx; height: 36rpx; + margin-right: 36rpx; image { width: 100%; height: 100%; diff --git a/src/components/bluetoot/device-connection-popup/device-connection-popup.tsx b/src/components/bluetoot/device-connection-popup/device-connection-popup.tsx index 15bd8bb..3dbae7b 100644 --- a/src/components/bluetoot/device-connection-popup/device-connection-popup.tsx +++ b/src/components/bluetoot/device-connection-popup/device-connection-popup.tsx @@ -178,12 +178,13 @@ export default class DeviceConnectPopup extends Component { - - )} @@ -201,7 +202,8 @@ export default class DeviceConnectPopup extends Component { 未搜索到设备 - {data.bluetoothConnectFailContent} + {data.bluetoothConnectFailContent || + "请重启设备后点击重新连接"} diff --git a/src/components/bluetoot/update-wl200/index.less b/src/components/bluetoot/update-wl200/index.less new file mode 100644 index 0000000..5bb8f2a --- /dev/null +++ b/src/components/bluetoot/update-wl200/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-wl200/index.tsx b/src/components/bluetoot/update-wl200/index.tsx new file mode 100644 index 0000000..545910e --- /dev/null +++ b/src/components/bluetoot/update-wl200/index.tsx @@ -0,0 +1,481 @@ +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 InstrumentTypeEnum from "../InstrumentTypeEnum"; +import OtaDeviceTypeEnum from "../OtaDeviceTypeEnum"; + +// 临时替代 +var log = console; + +let deviceToolKitInstance: any = null; +// WE200 M01 M02都是WE200 +let deviceToolKitInstanceM01 = new DeviceToolKitWE100("WE100", "M01"); +// WL200面罩 +let deviceToolKitInstanceWL200 = new DeviceToolKitWE100("WL200", "WL200"); + +import "./index.less"; + +class UpdateIotWL200 extends Component { + constructor(props) { + super(props); + this.state = { + name: "UpdateIotWL200", + 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() {} + componentDidMount() { + this.initData(); + } + + isWL200() { + let currentDevicesName = getStorageSync("currentDevicesName"); + if (currentDevicesName.indexOf("12CAA") > -1) { + return true; + } + return false; + } + + async initData() { + console.log("UpdateIotWL200"); + if (this.isWL200()) { + console.log("WL200更新"); + deviceToolKitInstance = deviceToolKitInstanceWL200; + } else { + console.log("WE100更新"); + deviceToolKitInstance = deviceToolKitInstanceM01; + } + + let objStr = getStorageSync("instrument_detail"); + if (objStr) { + let info = JSON.parse(objStr); + + this.setState({ + currentDevice: info, + }); + } + 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: "", + versionNo: this.$otaDataGroup.versionNo, + }; + // 根据设备类型传 otaDeviceType + if (this.isWL200()) { + jsoncmd.otaDeviceType = OtaDeviceTypeEnum.WL200; + } else { + jsoncmd.otaDeviceType = OtaDeviceTypeEnum.WE100; + } + + 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); + // this.showError(errorMap[errorString] || tipMap[errorString] || '发生错误') + } + }); + } + + /** + * 处理返回的数据 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: !this.isWL200(), + }); + 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) { + if (!this.isWL200()) { + this.quitOTA("shutDownMaskTip"); + } else { + this.quitOTA("updateTimeOut"); + } + } else { + this.$otaDataGroup.countDown--; + } + console.log(this.$otaDataGroup.countDown); + }, 1000); + } + + //升级销毁页面时关闭小程序蓝牙 + onUnload() { + if (this.$checkTimer) clearInterval(this.$checkTimer); + Taro.closeBluetoothAdapter(); + } + + onPullDownRefresh() { + Taro.stopPullDownRefresh(); + } + + onClickStop = (e) => { + e.stopPropagation(); + }; + + // 错误关闭回调 + errorFun = () => { + 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)(UpdateIotWL200); diff --git a/src/components/navbar/navbar.tsx b/src/components/navbar/navbar.tsx index 5109789..780fe29 100644 --- a/src/components/navbar/navbar.tsx +++ b/src/components/navbar/navbar.tsx @@ -36,7 +36,12 @@ export default class Navbar extends Component { } back = () => { - back(); + //判断是否自定义跳转 + if (!this.props.isCustomBack) { + back(); + } else { + this.props.customBack(); + } }; setStatusBar() { @@ -44,7 +49,8 @@ export default class Navbar extends Component { success: (res) => { const statusBarHeight = res.statusBarHeight || 0; // 获取微信胶囊的位置信息 width,height,top,right,left,bottom - const custom = Taro.getMenuButtonBoundingClientRect(); + // const custom = Taro.getMenuButtonBoundingClientRect(); + const custom = { height: 60, top: 20 }; // 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2 const navigationBarHeight = custom.height + (custom.top - statusBarHeight) * 2; diff --git a/src/components/popup/popup-alert.tsx b/src/components/popup/popup-alert.tsx index 92dcb76..65ce4c8 100644 --- a/src/components/popup/popup-alert.tsx +++ b/src/components/popup/popup-alert.tsx @@ -86,17 +86,19 @@ export default class PopupAlert extends Component { isClose, isLarge, myClassName, + zIndex, type, } = this.props; + if (!zIndex) zIndex = 10001; return ( {/* { + constructor(props) { + super(props); + this.state = { + name: "图标状态提示组件", + }; + } + + async onLoad() {} + componentDidMount() {} + + componentWillUnmount() {} + + componentDidShow() {} + + componentDidHide() {} + + async initData() {} + + onClose = () => { + this.props.close(); + }; + + onConfirm = () => { + this.props.confirm(); + }; + + onClickStop = (e) => { + e.stopPropagation(); + }; + + onTouchMove = () => { + return true; + }; + + render() { + let { + title, + content, + confirmButtonText, + textAlgin, + isShow, + isClose, + isBtn, + isLarge, + myClassName, + zIndex, + type, + } = this.props; + if (!zIndex) zIndex = 10001; + return ( + + + + {isClose && ( + + )} + + {title && ( + + {title} + + )} + + + + {type === "success" && ( + + )} + {type === "error" && ( + + )} + + {content} + + + + {isBtn && ( + + + + )} + + + + ); + } +} diff --git a/src/components/popup/popup-step-tips.less b/src/components/popup/popup-step-tips.less index 804bad4..a482350 100644 --- a/src/components/popup/popup-step-tips.less +++ b/src/components/popup/popup-step-tips.less @@ -18,12 +18,12 @@ // } .site-close { position: absolute; - right: 36rpx; - top: 36rpx; - color: #fff; + right: 16rpx; + top: 16rpx; + color: #000; font-size: 36rpx; z-index: 100009; - background-color: #ababab; + background-color: transparent; border-radius: 50%; padding: 8rpx; box-sizing: border-box; diff --git a/src/components/popup/popup-step-tips.tsx b/src/components/popup/popup-step-tips.tsx index 5014d39..d8fa922 100644 --- a/src/components/popup/popup-step-tips.tsx +++ b/src/components/popup/popup-step-tips.tsx @@ -24,6 +24,7 @@ import { go } from "../../utils/traoAPI"; /** props * isLarge 是否大尺寸 * isShow 是否显示 + * isFirstEntry 是否首次进入弹窗(是否允许只显示一次) * data 数据 * title 动态标题 * confirmButtonText 确定关闭按钮 @@ -59,6 +60,9 @@ export default class PopupStepTips extends Component { let { isLocal } = this.state; this.props.close({ isLocal }); }; + onConfirm = () => { + this.props.close({ isLocal: true }); + }; onClickStop = (e) => { e.stopPropagation(); @@ -94,8 +98,15 @@ export default class PopupStepTips extends Component { }; render() { - let { isShow, data, isLarge, title, content, confirmButtonText } = - this.props; + let { + isShow, + data, + isLarge, + isFirstEntry, + title, + content, + confirmButtonText, + } = this.props; let { current, isLocal } = this.state; return ( @@ -123,7 +134,7 @@ export default class PopupStepTips extends Component { "margin-samll": isLarge, })} > - {data.length > 0 ? data[current].openTitle : "暂无数据"} + {data.length > 0 ? data[current].openTitle : "使用教程"} {/* {title && ( { {data.length === 1 && ( - + {isFirstEntry ? ( + + ) : ( + + )} )} {data.length > 1 && current === 0 && ( @@ -191,21 +208,23 @@ export default class PopupStepTips extends Component { )} - - {isLocal ? ( - - ) : ( - - )} - - 以后不再提示准备步骤 - + {!isFirstEntry && ( + + {isLocal ? ( + + ) : ( + + )} + + 以后不再提示准备步骤 + + )} diff --git a/src/components/popup/popup.less b/src/components/popup/popup.less index dc35707..f29f134 100644 --- a/src/components/popup/popup.less +++ b/src/components/popup/popup.less @@ -107,3 +107,12 @@ font-size: 36rpx; z-index: 100009; } + +.level-up { + &.van-overlay { + z-index: 10020 !important; + } + &.van-popup { + z-index: 10021 !important; + } +} diff --git a/src/img/bluetooth.png b/src/img/bluetooth.png new file mode 100644 index 0000000..76b9941 Binary files /dev/null and b/src/img/bluetooth.png differ diff --git a/src/img/qrcode-test.jpg b/src/img/qrcode-test.jpg index 7d3741d..5d13f85 100644 Binary files a/src/img/qrcode-test.jpg and b/src/img/qrcode-test.jpg differ diff --git a/src/img/status/error.png b/src/img/status/error.png new file mode 100644 index 0000000..53295da Binary files /dev/null and b/src/img/status/error.png differ diff --git a/src/img/status/success.png b/src/img/status/success.png new file mode 100644 index 0000000..fb0a084 Binary files /dev/null and b/src/img/status/success.png differ diff --git a/src/pages/face_report/face_report.tsx b/src/pages/face_report/face_report.tsx index 420f567..e6ec885 100644 --- a/src/pages/face_report/face_report.tsx +++ b/src/pages/face_report/face_report.tsx @@ -1,7 +1,7 @@ import Taro from "@tarojs/taro"; import classnames from "classnames"; import { Component, PropsWithChildren, useEffect, useState } from "react"; -import { Progress } from '@antmjs/vantui' +import { Progress } from "@antmjs/vantui"; import { Block, View, Text, Image, Input, Button } from "@tarojs/components"; import { date, getdates, previewImage } from "../../utils/util"; @@ -9,7 +9,7 @@ import { date, getdates, previewImage } from "../../utils/util"; /** 自定义组件 **/ import Navbar from "../../components/navbar/navbar"; import PopupAlert from "../../components/popup/popup-alert"; -import { InstrumentInfo } from '../../utils/Interface' +import { InstrumentInfo } from "../../utils/Interface"; /** 自定义组件 **/ import "./face_report.less"; @@ -21,54 +21,60 @@ export default class Index extends Component { name: "template模板页", statistics: {}, recordList: [], - recordData: {} + recordData: {}, }; } - componentDidMount() { } + componentDidMount() {} - componentWillUnmount() { } + componentWillUnmount() {} // 查询用户护理记录的当月统计信息 async getStatistics(id) { - let data = {} + let data = {}; if (id != null) { - data['instrumentId'] = id + data["instrumentId"] = id; } - let res = await InstrumentInfo.apiNursingLog.getStatistics(data) + let res = await InstrumentInfo.apiNursingLog.getStatistics(data); if (res.data.code === 200) { - this.setState({ statistics: res.data.data }) + this.setState({ statistics: res.data.data }); } } async getRecord(id, recordId) { - let data = {} + console.log("id, recordId", id, recordId); + let data = {}; if (id != null) { - data['instrumentId'] = id + data["instrumentId"] = id; } - let res = await InstrumentInfo.apiNursingLog.getRecord(data) + let res = await InstrumentInfo.apiNursingLog.getRecord(data); if (res.data.code === 200) { - res.data.rows.map(item => { - item.nursingTime = this.getTime(item.nursingTime) - item.createTime = getdates(item.createTime).replace(/-/g, '.') - if (item.id == recordId) { - this.setState({ recordData: item }) - } - }) - this.setState({ recordList: res.data.rows.filter(item => item.id != recordId) }) - + if (recordId) { + res.data.rows.map((item) => { + item.nursingTime = this.getTime(item.nursingTime); + item.createTime = getdates(item.createTime).replace(/-/g, "."); + + if (item.id == recordId) { + this.setState({ recordData: item }); + } + }); + } else { + this.setState({ recordData: res.data.rows[0] }); + } + + this.setState({ + recordList: res.data.rows.filter((item) => item.id != recordId), + }); } } getRouteId() { const searchParams = new URLSearchParams(window.location.search); - const id = searchParams.get('id'); - const recordId = searchParams.get('recordId'); - this.getStatistics(id) - this.getRecord(id, recordId) + const id = searchParams.get("id"); + const recordId = searchParams.get("recordId"); + this.getStatistics(id); + this.getRecord(id, recordId); console.log(recordId); - - } getTime(time) { const hour = time.slice(0, 2); @@ -76,188 +82,156 @@ export default class Index extends Component { const second = time.slice(6, 8); if (hour > 0) { - return hour + '时' + minute + '分' + second + '秒' + return hour + "时" + minute + "分" + second + "秒"; } else { - return minute + '分' + second + '秒' + return minute + "分" + second + "秒"; } } async onLoad() { - this.getRouteId() + this.getRouteId(); } - componentDidShow() { } + componentDidShow() {} - componentDidHide() { } + componentDidHide() {} - async initData() { } + async initData() {} + + GoIndex = () => { + Taro.switchTab({ url: "/pages/index/index" }); + }; render() { let { name, statistics, recordList, recordData } = this.state; return ( - - {/* {{reportData.curDate}} */} - {/* */} - - {/* */} - - - 3 - - - {/* - 本月护理天数 - */} - - 本月护理天数 - - {/* {{options.type == 'led' ? '本月光照天数': '本月促渗天数'}} */} - 本月光照天数 - - - - 28:00 - {/* {{options.type == 'led' ? '本月护理时间': '本月促渗时间'}} */} - 本月护理时间 - - {/* */} - {/* */} - - + + + + {statistics.nursingNum} - - - - 本月护理天数 + + 本月护理天数 - - {statistics.nursingTime} - 本月护理时间 + + {statistics.nursingTime} + 本月护理时间 {/* */} - - {/* */} - - - {recordData.createTime} - {recordData.online == 1 ? '在线' : '离线'} + + + + {recordData.createTime} + + {recordData.online == 1 ? "在线" : "离线"} + - - - - - {recordData.instrumentName} - - 模式:{recordData.modeName} - 护理时间:{recordData.nursingTime} + + + + + {recordData.instrumentName} + + 模式:{recordData.modeName} + + 护理时间:{recordData.nursingTime} + - + 完成度: - - {recordData.completionPercentage * 100}% + 100 + ? 100 + : recordData.completionPercentage * 100 + } + strokeWidth="12" + color="linearGradient(to right, #eecda1, #ffe9c7) !important" + /> + + {" "} + {recordData.completionPercentage * 100 > 100 + ? 100 + : recordData.completionPercentage * 100} + % + - 历史记录 - {recordList.map(item => ( - - - {item.createTime} - {item.online == 1 ? '在线' : '离线'} + 历史记录 + {recordList.map((item) => ( + + + {item.createTime} + + {item.online == 1 ? "在线" : "离线"} + - - - - - {item.instrumentName} - - 模式:{item.modeName} - 护理时间:{item.nursingTime} + + + + + {item.instrumentName} + + 模式:{item.modeName} + 护理时间:{item.nursingTime} - + 完成度: - - {item.completionPercentage * 100}% + 100 + ? 100 + : item.completionPercentage * 100 + } + strokeWidth="12" + color="linearGradient(to right, #eecda1, #ffe9c7) !important" + /> + + {" "} + {item.completionPercentage * 100 > 100 + ? 100 + : item.completionPercentage * 100} + % + ))} - - {/* */} - {/* */} - {/* - - 2024.01.01 - 在线 - - - - - - 光能厂美侧板 - - 模式:维护修复 - 护理时间:10:00 - - - - 完成度: - - 80% - - - - - */} - {/* 历史记录 - - - 2024.01.01 - 在线 - - - - - - 光能厂美侧板 - - 模式:维护修复 - 护理时间:10:00 - - - - 完成度: - - 80% - - - - */} - {/* */} - - 前往打卡 - - 跳过 - + + 前往打卡 + + 跳过 + - - {/* */} - ); } diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index ee9e03e..7dbbcac 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -9,6 +9,7 @@ import { Image, Swiper, SwiperItem, + RichText, } from "@tarojs/components"; /*** redux ***/ @@ -25,10 +26,12 @@ import PopupBinding from "@/components/popup/popup-binding"; import PopupSiteSwiper from "@/components/popup/popup-site-swiper"; import PopupAlert from "@/components/popup/popup-alert"; +import PopupConfirm from "@/components/popup/popup-confirm"; import type CustomTabBar from "@/custom-tab-bar"; import Navbar from "@/components/navbar/navbar"; import ConnectionBluetoot from "@/components/bluetoot/connection"; +import UpdateIotWL200 from "@/components/bluetoot/update-wl200/index"; /** 自定义组件 **/ import { @@ -54,10 +57,10 @@ import { } from "@/utils/traoAPI"; import commandMap from "@/utils/commandMap"; -import InstrumentTypeEnum from "@/components/bluetoot/instrumentTypeEnum"; +import InstrumentTypeEnum from "@/components/bluetoot/InstrumentTypeEnum"; import OtaDeviceTypeEnum from "@/components/bluetoot/OtaDeviceTypeEnum"; -const log = require("@/utils/log"); +// const log = require("@/utils/log"); class Index extends Component { // pageCtx = Taro.getCurrentInstance().page; @@ -131,9 +134,14 @@ class Index extends Component { /** 蓝牙相关 */ isConnectShow: false, - connectInstrument: {}, - yiqiinfo: {}, + connectInstrument: {}, // 当前连接设备 /* END */ + + // 设备升级弹窗 + isShowUpdateVersionTip: false, // 升级提示 + isShowVersionUpgrading: false, // 升级中 + isShowVersionUpgradFinish: false, // 升级完成:升级内容公告 + versionUpgradFinishNodes: "", // 公告内容 }; } @@ -148,16 +156,14 @@ class Index extends Component { } } if (Taro.getStorageSync("skip")) { - this.setState({ showEquipment: true }) - Taro.removeStorageSync('skip'); + this.setState({ showEquipment: true }); + Taro.removeStorageSync("skip"); } } - componentDidMount() { - - } + componentDidMount() {} - componentWillUnmount() { } + componentWillUnmount() {} componentDidShow() { const tabbar = Taro.getTabBar(this.$instance.page); @@ -166,7 +172,7 @@ class Index extends Component { this.showInit(); } - componentDidHide() { } + componentDidHide() {} showInit() { // 判断是否登录 @@ -216,7 +222,7 @@ class Index extends Component { this.isSancQrcodeEnter(); } }, - fail: () => { }, + fail: () => {}, complete: () => { // 授权完成运行页面初始化 }, @@ -374,7 +380,7 @@ class Index extends Component { this.setState({ isShowSiteSwiper: false }); }; - bannerSwiperchange() { } + bannerSwiperchange() {} gobanner(item) { // 跳转类型:0无跳转、1跳转内部链接、3跳转外部链接、4跳转小程序、5导向视频号、6导向视频号直播间', @@ -441,8 +447,6 @@ class Index extends Component { } } closeBinding = () => { - Taro.removeStorageSync("isScan"); // 扫码弹窗显示完后,不需要再判断是否扫码 - Taro.removeStorageSync("serial"); // 扫码弹窗显示完后,删除缓存的扫码序列号 this.setState({ isVisibleBinding: false }); }; confirmBinding = () => { @@ -494,6 +498,9 @@ class Index extends Component { // 获取失败和绑定失败一个弹窗 this.setState({ isBindingError: true }); } + + Taro.removeStorageSync("isScan"); // 扫码弹窗显示完后,不需要再判断是否扫码 + Taro.removeStorageSync("serial"); // 扫码弹窗显示完后,删除缓存的扫码序列号 } }; @@ -558,16 +565,12 @@ class Index extends Component { console.log("exchangeBinding", data); Taro.hideLoading(); this.closeBinding(); - if (data.code === 200) { - } else { - this.closeBinding(); - this.setState({ isBindingError: true }); + if (data.code !== 200) { + //todo } }; // 仪器绑定失败弹窗 onBindErrorClose = () => { - Taro.removeStorageSync("isScan"); // 扫码弹窗显示完后,不需要再判断是否扫码 - Taro.removeStorageSync("serial"); // 扫码弹窗显示完后,删除缓存的扫码序列号 this.setState({ isBindingError: false }); }; onBindErrorConfirm = () => { @@ -575,8 +578,6 @@ class Index extends Component { go("/pages/consultant/consultant"); }; onBeforeBindClose = () => { - Taro.removeStorageSync("isScan"); // 扫码弹窗显示完后,不需要再判断是否扫码 - Taro.removeStorageSync("serial"); // 扫码弹窗显示完后,删除缓存的扫码序列号 this.setState({ isBeforeBinding: false }); }; onBeforeBindConfirm = () => { @@ -647,116 +648,15 @@ class Index extends Component { // return; } onUnloginConfirm() { - this.setState({ showEquipment: false }) + this.setState({ showEquipment: false }); } onUnloginClose() { - this.setState({ showEquipment: false }) + this.setState({ showEquipment: false }); } //连接完成时数据的回调 offlineChange = async (e) => { console.log("offlineChange", e); - // log.info( - // commandMap.versionInfoHome, - // `offlineChange::e::${JSON.stringify(e)}` - // ); - //offlineDataList 离线数据 - //versioninfo 版本号 - let { offlineDataList, versionInfo } = e.detail; - this.setState({ - versionInfo, - }); - let offlinelist: any = []; - offlineDataList.map((item, index) => { - let obj: any = { - clock_day: "", - status: 3, - second: 120, - screne_id: "", - screne_name: "离线打卡", - model_face_ward: 0, - model_face_use: 0, - model_face_type: "", - model_eye_ward: 0, - model_eye_use: 0, - model_eye_type: "", - instrument_id: this.state.connectInstrument.id, - }; - - //判断日期是否正常,如果不正常不处理 --- 脸部 - if ( - item.faceyear > 0 && - item.faceyear <= 99 && - item.facemonth >= 1 && - item.facemonth <= 12 && - item.faceday >= 1 && - item.faceday <= 31 - ) { - if ( - item.facehour > 0 || - (item.faceminutes > 0 && item.faceminutes < 60) || - (item.faceseconds > 0 && item.faceseconds < 60) - ) { - //脸部离线记录有值 - obj.model_face_use = - Number(item.facehour) * 60 * 60 + - Number(item.faceminutes) * 60 + - Number(item.faceseconds); - obj.model_face_ward = item.faceposition1; - obj.clock_day = `20${String(item.faceyear).padStart(2, "0")}-${String( - item.facemonth - ).padStart(2, "0")}-${String(item.faceday).padStart(2, "0")}`; - } - } - //判断日期是否正常,如果不正常不处理 --- 眼部 - if ( - item.eyeyear > 0 && - item.eyeyear <= 99 && - item.eyemonth >= 1 && - item.eyemonth <= 12 && - item.eyeday >= 1 && - item.eyeday <= 31 - ) { - if ( - item.eyehour > 0 || - (item.eyeminutes > 0 && item.eyeminutes < 60) || - (item.eyeseconds > 0 && item.eyeseconds < 60) - ) { - //眼部离线记录有值 - obj.model_eye_use = - Number(item.eyehour) * 60 * 60 + - Number(item.eyeminutes) * 60 + - Number(item.eyeseconds); - obj.model_eye_ward = item.eyeposition1; - obj.clock_day = `20${String(item.eyeyear).padStart(2, "0")}-${String( - item.eyemonth - ).padStart(2, "0")}-${String(item.eyeday).padStart(2, "0")}`; - } - } - - obj.second = obj.model_face_use + obj.model_eye_use; - - if ( - item.faceyear > 0 && - item.faceyear <= 99 && - (item.facemonth == 1 || item.facemonth <= 12) && - (item.faceday == 1 || item.faceday <= 31) - ) { - let dayTime = new Date(`${obj.clock_day.replace(/-/g, "/")}`).getTime(); //离线记录的日期 - let now = new Date( - `${new Date().getFullYear()}/${String( - new Date().getMonth() + 1 - ).padStart(2, "0")}/${String(new Date().getDate()).padStart(2, "0")}` - ).getTime(); //当前日期 - /** - * 过滤7天前的离线记录 - * - */ - if (dayTime <= now && dayTime >= now - 24 * 60 * 60 * 1000 * 6) { - offlinelist.push(obj); - } - } - }); - console.log(offlinelist); + this.pairingChange("offlineChange"); }; connectionOpen = async () => { @@ -768,8 +668,65 @@ class Index extends Component { connectionConfirm = async () => { this.connectionClose(); }; - /*蓝牙 END*/ + + /** 设备iot固件版本升级 */ + // 是否更新弹窗 + upgradeFun = () => { + this.setState({ isShowUpdateVersionTip: true, isConnectShow: false }); + }; + cancelUpdateVersionTip = () => { + // 关闭提示 + this.setState({ isShowUpdateVersionTip: false }); + }; + confirmUpdateVersionTip = () => { + // 提示升级与开始升级 + this.setState({ + isShowUpdateVersionTip: false, + isShowVersionUpgrading: true, + }); + }; + + // 完成升级 + wl200UpgradeFinishFun = (isWL200) => { + let { connectInstrument } = this.state; + console.log("connectInstrument", connectInstrument); + let content = ""; + if (isWL200) { + content = connectInstrument.iotVersionUpgrade; + } else { + content = connectInstrument.we200IotVersionUpgrade; + } + let nodes = decodeURIComponent(content || ""); + nodes = nodes.replace(/\ { + this.setState({ + isShowVersionUpgrading: false, + }); + }; + // 关闭升级完成公告 + onVersionUpgradFinish = () => { + this.setState({ + isShowVersionUpgradFinish: false, + }); + }; + /** iot版本升级 END */ + render() { let { calendarComplete, @@ -794,6 +751,12 @@ class Index extends Component { instrumentList, showEquipment, + // 升级弹窗 + isShowUpdateVersionTip, + isShowVersionUpgrading, + isShowVersionUpgradFinish, + versionUpgradFinishNodes, + // 蓝牙连接 isConnectShow, connectInstrument, @@ -802,23 +765,38 @@ class Index extends Component { return ( + + 序列号信息仍在更新,请联系微信小助理 + 协助您绑定仪器 + + } + confirmButtonText="知道了" + textAlgin="center" + isClose={false} + close={this.onBindErrorClose} + confirm={this.onBindErrorConfirm} + /> @@ -838,42 +816,42 @@ class Index extends Component { /> 序列号信息仍在更新,请联系微信小助理 协助您绑定仪器 } - confirmButtonText='知道了' - textAlgin='center' + confirmButtonText="知道了" + textAlgin="center" isClose={false} close={this.onBindErrorClose} confirm={this.onBindErrorConfirm} - > + /> + /> - 仪器:小紫单美容仪 - 序列号:uniquie14231 - 您需要完成注册登录才能进行一起绑定 + 仪器:小紫单美容仪 + 序列号:uniquie14231 + 您需要完成注册登录才能进行一起绑定 } - confirmButtonText='知道了' - textAlgin='center' + confirmButtonText="知道了" + textAlgin="center" isClose={false} close={this.onUnloginClose.bind(this)} confirm={this.onUnloginConfirm.bind(this)} @@ -887,52 +865,93 @@ class Index extends Component { - - {isConnectShow && ( - + )} + + 检测到设备有升级请求 + 是否进行升级? + + } + textAlgin="center" + confirmButtonText="确定" + close={this.cancelUpdateVersionTip} + confirm={this.confirmUpdateVersionTip} /> - )} - {/* */} + {isShowVersionUpgrading && ( + + )} + + + + + + } + confirmButtonText="知道了" + textAlgin="left" + isClose + close={this.onVersionUpgradFinish} + confirm={this.onVersionUpgradFinish} + /> + {/* IOT相关弹窗 END */} + - {messagecount ? : ""} + {messagecount ? : ""} } /> - - - 护理记录 + + + 护理记录 - + { /> - + {instrumentList.length > 0 && ( - - 前往护理 + + 前往护理 - 添加新设备 + 添加新设备 - - + + {instrumentList.map((item, index) => { if (item.status === 0) { return ( - + {item.name} @@ -991,32 +1010,32 @@ class Index extends Component { )} {instrumentList.length === 0 && ( - - 前往护理 + + 前往护理 - - - + + + - + 添加新设备 - 您暂时还没有绑定任何设备 + 您暂时还没有绑定任何设备 )} - + 假按钮跳转蓝牙调试设备页 - + { key={"banner_" + index} onClick={this.gobanner.bind(this, item)} > - + ); })} - + ); } @@ -1057,3 +1076,4 @@ const mapDispatchToProps = (dispatch) => ({ }, }); export default connect(mapStateToProps, mapDispatchToProps)(Index); +// instrumentId diff --git a/src/pages/instrument/instrument.tsx b/src/pages/instrument/instrument.tsx index 1e82ee1..d70c9d7 100644 --- a/src/pages/instrument/instrument.tsx +++ b/src/pages/instrument/instrument.tsx @@ -18,7 +18,7 @@ import { } from "@tarojs/components"; import { InstrumentInfo } from "@/utils/Interface"; -import { go, back, msg, setStorageSync, getStorageSync } from "@/utils/traoAPI"; +import { go, msg, setStorageSync, getStorageSync } from "@/utils/traoAPI"; import { getImgInfo, contraction } from "@/utils/compressImage"; @@ -63,15 +63,27 @@ export default class Instrument extends Component { fromUrl: "", }; } + $instance = Taro.getCurrentInstance(); + isOnly: boolean = false; + currentDevice: any = null; + id: any = ""; - async onLoad() { - this.unbindingInstrumentInfoList(); - } + async onLoad() {} componentDidMount() {} componentWillUnmount() {} - componentDidShow() {} + componentDidShow() { + let params: any = this.$instance.router?.params; + if (params?.isOnly && params?.id) { + if (params?.isOnly === "true") { + this.isOnly = true; + this.id = params?.id; + } + } + console.log("params", params); + this.unbindingInstrumentInfoList(); + } componentDidHide() {} @@ -85,18 +97,6 @@ export default class Instrument extends Component { this.setState({ channelInfo }); }; - // onScanCode() { - // Taro.scanCode({ - // scanType: ["qrCode"], - // success: (res) => { - // let { channelInfo } = this.state; - // channelInfo.serialCode = res.result; - - // this.setState({ channelInfo }); - // }, - // }); - // } - onTipShow = () => { this.setState({ tipShow: true }); }; @@ -140,88 +140,6 @@ export default class Instrument extends Component { }); }; - // getBindCodeInfo = async () => { - // const { bindCode, instrumentList, channelInfo } = this.state; - // // // 1.查询资料 - // // try { - // // const { data } = await InstrumentCodeCheck({ - // // code: bindCode, - // // }); - // // const bindCodeInfo = { ...data.data.bindCodeInfo }; - // // // 2.判断是否是选中的仪器, 如果不是, 直接弹出scanErrorPopup - // // if (channelInfo.id != bindCodeInfo.instrument_id) { - // // this.setState({ - // // bindPopup: "scanErrorPopup", - // // }); - // // return; - // // } - // // const match = instrumentList.find((item) => { - // // if (item.id == bindCodeInfo.instrument_id && item.serial) { - // // // 找到同一个仪器 - // // bindCodeInfo.hadBindSame = true; - // // if (item.serial == bindCodeInfo.antifakeCode) { - // // // 找到同一个序列号 - // // bindCodeInfo.hadBindSameCode = true; - // // } else { - // // bindCodeInfo.hadBindSameCode = false; - // // } - // // return item; - // // } - // // if (item.id == bindCodeInfo.instrument_id) { - // // const { channelInfo } = this.state; - // // if (channelInfo.id === item.id) return; - // // this.setState({ - // // channelInfo: item, - // // isVideo: isVideo(item.bind_intro_video), - // // }); - // // } - // // }); - // // if (match) { - // // bindCodeInfo.hadBind = true; - // // } else { - // // bindCodeInfo.hadBindSame = false; - // // } - // // this.setState({ - // // bindCodeInfo, - // // }); - // // this.judgeBindCode(); - // // } catch (e) { - // // this.judgeBindCode(); - // // } - // }; - - // judgeBindCode = () => { - // const { bindCode, bindCodeInfo } = this.state; - // const opts: any = {}; - // if (bindCode && !bindCodeInfo) { - // // 有仪器码, 但是没有找到信息时 - // opts.bindPopup = "noFoundPopup"; - // } else if (bindCode && bindCodeInfo && bindCodeInfo.isLabelCode) { - // opts.bindPopup = "labelPopup"; - // } else if ( - // bindCode && - // bindCodeInfo.hadBindSame && - // bindCodeInfo.hadBindSameCode - // ) { - // // 有仪器码, 如果有登录, 判断是绑定了同样的仪器和仪器的序列号是一致 -- 不弹弹窗, 回到首页 - // opts.bindCode = ""; // 重置bindCode - // opts.bindPopup = ""; // 隐藏bindPopup - // } else if ( - // bindCode && - // bindCodeInfo.hadBindSame && - // !bindCodeInfo.hadBindSameCode - // ) { - // // 有仪器码, 如果有登录, 判断是绑定了同样的仪器, 但仪器的序列号不一致 -- 判断换绑 - // opts.bindPopup = "switchBindCodePopup"; - // } else if (bindCode && !bindCodeInfo.hadBindSame) { - // // 有仪器码, 如果有登录, 判断不是绑定了同样的仪器 -- 绑定 - // opts.bindPopup = "toBindPopup"; - // } - // if (Object.keys(opts).length) { - // this.setState(opts); - // } - // }; - onCustomerTap = () => { this.onCancelBind2Tap(); go("/pages/consultant/consultant"); @@ -271,10 +189,6 @@ export default class Instrument extends Component { }); } - public back = () => { - back(); - }; - closeDev = () => { // go("/pages/user/user"); let isInstrumentJump = Taro.getStorageSync("isInstrumentJump"); @@ -297,13 +211,23 @@ export default class Instrument extends Component { let { data } = await InstrumentInfo.unbindingInstrumentInfoList(); if (data.code === 200) { if (data.data.length) { - let item = data.data[0]; - item.serialCode = ""; - this.setState({ - equipmentList: data.data, - channelInfo: item, - isVideo: this.isVideo(item.banner), - }); + if (!this.isOnly) { + let item = data.data[0]; + item.serialCode = ""; + this.setState({ + equipmentList: data.data, + channelInfo: item, + isVideo: this.isVideo(item.banner), + }); + } else { + let item = data.data.find((item) => String(item.id) === this.id); + item.serialCode = ""; + this.setState({ + equipmentList: [item], + channelInfo: item, + isVideo: this.isVideo(item.banner), + }); + } } } }; @@ -385,6 +309,10 @@ export default class Instrument extends Component { this.setState({ isBindingCheckError: false }); }; + customBack = () => { + Taro.switchTab({ url: "/pages/index/index" }); + }; + render() { let { isBindingError, @@ -406,7 +334,12 @@ export default class Instrument extends Component { close={this.closeDev} confirm={this.closeDev} /> */} - + { // this.getInstrumentInfo(params.id); // } - let strObj = getStorageSync("instrument_item"); + let strObj = getStorageSync("instrument_detail"); if (strObj) { let instrument = JSON.parse(strObj); this.getInstrumentInfo(instrument.id); @@ -88,7 +88,7 @@ class Intro extends Component { // setStorageSync("introduceId", info.id); // } const url = "/pages/index/index"; - Taro.switchTab({ + Taro.switchTab({ url, }); } diff --git a/src/pages/instrumentClickinUpload/index.tsx b/src/pages/instrumentClickinUpload/index.tsx index 0838af9..c090427 100644 --- a/src/pages/instrumentClickinUpload/index.tsx +++ b/src/pages/instrumentClickinUpload/index.tsx @@ -70,16 +70,16 @@ export default class InstrumentClickInUpload extends Component { async onLoad() { this.initData(); } - componentDidMount() { } + componentDidMount() {} - componentWillUnmount() { } + componentWillUnmount() {} componentDidShow() { let videoContext = Taro.createVideoContext("myVideo"); this.setState({ videoContext }); } - componentDidHide() { } + componentDidHide() {} async initData() { let objStr = getStorageSync("instrument_detail"); @@ -127,7 +127,7 @@ export default class InstrumentClickInUpload extends Component { // 获取仪器模式列表 modeInfoList = async (id) => { let res = await InstrumentInfo.modeInfoList({ - instrumentId: "84", + instrumentId: id, }); if (res.data.code === 200) { if (res.data.data.length) { @@ -242,15 +242,15 @@ export default class InstrumentClickInUpload extends Component { }); }; - videoBindTimeUpdate = async () => { }; + videoBindTimeUpdate = async () => {}; - videoEnded = async () => { }; + videoEnded = async () => {}; - videoPause = async () => { }; + videoPause = async () => {}; - videoPlay = async () => { }; + videoPlay = async () => {}; - videoLoadedMetaData = async () => { }; + videoLoadedMetaData = async () => {}; handleTextareaInput = async (e) => { let { punchInInfo } = this.state; diff --git a/src/pages/instrument_manage/index.tsx b/src/pages/instrument_manage/index.tsx index f1bbe04..8f00ceb 100644 --- a/src/pages/instrument_manage/index.tsx +++ b/src/pages/instrument_manage/index.tsx @@ -45,13 +45,13 @@ export default class InstrumentManage extends Component { async onLoad() { this.initData(); } - componentDidMount() { } + componentDidMount() {} - componentWillUnmount() { } + componentWillUnmount() {} - componentDidShow() { } + componentDidShow() {} - componentDidHide() { } + componentDidHide() {} async initData() { this.bindingInstrumentList(); @@ -93,7 +93,7 @@ export default class InstrumentManage extends Component { } goBind(item) { let bindid = item.id; - go("/pages/instrument/instrument?id=" + bindid); + go("/pages/instrument/instrument?isOnly=true&id=" + bindid); // 只显示当前仪器内容 } goBindInfo(item) { @@ -127,100 +127,63 @@ export default class InstrumentManage extends Component { - {bindList.length > 0 && + {bindList.length > 0 && ( 我的设备 - - {bindList.map((item: any, index: number) => { - return ( - - - - - 已绑定 - - - 仪器介绍 - - - - - - - - {item.name} - - 查看绑定信息 - - - - - ); - })} - - {/* - {bindList.map((item, index) => { - if (item.status === 0) { + {bindList.length > 0 && ( + + {bindList.map((item: any, index: number) => { return ( - - - - 已绑定 - - - 仪器介绍 - - - + + + + + 已绑定 + + + 仪器介绍 + + + + - - - {item.name} - - 查看绑定信息 + + {item.name} + + 查看绑定信息 + - + ); - } - })} - */} + })} + + )} - } + )} 未绑定的仪器 diff --git a/src/pages/iotCarePlan/components/ElectricityView/index.tsx b/src/pages/iotCarePlan/components/ElectricityView/index.tsx index 0afc8fa..4141899 100644 --- a/src/pages/iotCarePlan/components/ElectricityView/index.tsx +++ b/src/pages/iotCarePlan/components/ElectricityView/index.tsx @@ -17,7 +17,7 @@ function Index({ return ( - + {/* WE200电量 : {matrixElectricity >= 4 && ( @@ -61,7 +61,7 @@ function Index({ )} - + */} {facialMaskConnectStatus === 1 && ( @@ -91,15 +91,7 @@ function Index({ )} - {Electricity === 1 && ( - - - - - - - )} - {Electricity === 0 && ( + {Electricity <= 1 && ( diff --git a/src/pages/iotCarePlan/components/Footer/index.tsx b/src/pages/iotCarePlan/components/Footer/index.tsx index 0061056..fed6aba 100644 --- a/src/pages/iotCarePlan/components/Footer/index.tsx +++ b/src/pages/iotCarePlan/components/Footer/index.tsx @@ -5,20 +5,22 @@ import { useState, useEffect } from "react"; import "./index.less"; interface Props { - isConnectionBlutoot: boolean; + isCanClick: boolean; isShowNurse: boolean; isStopNurse: boolean; onEmitStartNurse: Function; // 每次点击item,回调事件和数据给父组件 onEmitSwitchChange: Function; onEmitEndPlan: Function; + onEmitErrorTips: Function; // 不可点击,提示错误 } function Index({ - isConnectionBlutoot, + isCanClick, isShowNurse, isStopNurse, onEmitStartNurse, onEmitSwitchChange, onEmitEndPlan, + onEmitErrorTips, }: Props) { const onStartNurse = () => { onEmitStartNurse(); @@ -32,12 +34,16 @@ function Index({ onEmitEndPlan(); }; + const onErrorTips = () => { + onEmitErrorTips(); + }; + return ( {!isShowNurse && ( - {isConnectionBlutoot ? ( + {isCanClick ? ( 开始护理 @@ -50,27 +56,58 @@ function Index({ )} {isShowNurse && ( - - {isStopNurse ? ( - - - 开始光照 - - ) : ( - - - 暂停光照 - - )} - + {isCanClick && ( + + {isStopNurse ? ( + + + 启动光照 + + ) : ( + + + 暂停光照 + + )} + + )} + {!isCanClick && ( + + {isStopNurse ? ( + + + + 启动光照 + + + ) : ( + + + + 暂停光照 + + + )} + + )} { this.state = { name: "iotCarePlan", title: "美容仪名字", // 页面标题 - instrument: "WE200", + // 当前设备 currentDevice: { name: "", model: "", - }, // 当前设备 + }, /** 连接设备 */ hasVersion: false, // 是否已查询到版本号 - curDeviceInfo: {}, // 当前设备信息 basicModeList: [], //模式列表 modelActiveIndex: 0, //模式下标 sliderProgress: 22, - isStandStatus: false, // 支架开启状态(支架就是舱体) - facialMaskConnectStatus: 0, // 面罩连接状态 0未连接 1已连接 - workStatus: "", // 工作状态 + facialMaskConnectStatus: 1, // 面罩连接状态 0未连接 1已连接 Electricity: 4, // WL200电量 matrixElectricity: 4, // WE200发箍电量 @@ -170,23 +155,25 @@ class IotCarePlan extends Component { gear: { gear: 1 }, currentShowDialog: "", - // countdown: 3, // 倒计时 step: 1, // 1:选择模式并播放视频, 2:护理中 - isCheckedMaskVersion: false, // 是否检查过固件版本了 - isAskedOta: false, // 询问过用户是否需要OTA showVideoPlayBtn: true, // 视频播放按钮 duration: 0, // 视频总时长 hadShowBreakTips: false, // 是否展示过支架断开提示 popupType: "", // enoughTimePopup: 时间达标提示, endPopup: 结束弹窗 + isConnectShow: false, // 是否弹出连蓝牙弹窗:在蓝牙断开时弹出 /** 连接设备 End */ + /** 护理过程 */ + isCanClick: false, // 是否可以点击开始按钮/启动暂停 + isStandStatus: false, // 当前模式是否舱体/支架模式 isShowStepTips: false, // 是否显示介绍步骤弹窗 - isConnectionBlutoot: false, // 是否已连接蓝牙 + isConnectionBlutoot: true, // 是否已连接蓝牙 isShowNurse: false, // 是否开始并显示护理 isStopNurse: false, // 是否暂停护理 isEndNurse: false, // 是否结束护理 errorTips: "", // 错误提示 + /** 护理过程 END*/ // 模式列表 isSwitchActiveMode: true, // 是否显示弹窗切换模式 @@ -204,42 +191,67 @@ class IotCarePlan extends Component { startSource: "", stopSource: "", }, + // 模式组合 isCombineSuccess: false, // 组合模式是否设置成功 - // 倒计时 isShowCountdown: false, // 倒计时弹窗 countdown: 3, - // 是否结束护理 isEndCarePlan: false, - - // 最后执行步骤位置 - endPlace: "", currentTime: "01:00", + + // 护理时间不够 + isNotEnoughTime: false, + // 通用错误提示 + isShowErrorTipsText: false, // 护理模式切换错误弹窗 + errorTipsText: "", // 护理模式切换错误提示 + + isShowNursingSuccess: false, // 护理成功弹窗 + isShowTipsSave: false, // 切换模式时,提示是否保存部分护理记录 }; } + // 不涉及渲染的页面变量 + jsonStatus: any = {}; // 同步设备返回数据,用于结束 + tempModeCurrent: any = {}; // 临时保存的当前模式 + elapsedTime: any = 0; // 设备已运行时间 + workStatus: any = ""; // 工作状态 + WL200NursingHistory: any = null; // 护理缓存历史 + hadCheckReport = false; // 是否已检查仪器护理记录 + hadGotInstrumentHistoryData = false; // 是否已缓存仪器历史数据 + hadLoadedPage = false; // 判断是否首次进入页面 + async onLoad() { // 保持屏幕常亮 Taro.setKeepScreenOn({ keepScreenOn: true, }); + this.initData(); } - componentDidMount() { - this.setState({ - videoContext: Taro.createVideoContext("myVideo"), - standVideoContext: null, - }); - } + componentDidMount() {} componentWillUnmount() { } componentDidShow() { - this.initData(); + console.log("页面显示了"); + + if (!this.hadLoadedPage) { + this.hadLoadedPage = true; // 二次进入页面(非首次进入) + return; + } + + this.getWL200NursingHistory(); + // 重置初始值,每次进入页面重新检查面罩护理记录 + this.hadCheckReport = false; + this.hadGotInstrumentHistoryData = false; } - componentDidHide() { } + componentDidHide() { + console.log("Hide"); + // 页面隐藏后,下次显示需要重新检查记录 + this.hadCheckReport = false; + } async initData() { let objStr = getStorageSync("instrument_detail"); @@ -250,22 +262,20 @@ class IotCarePlan extends Component { currentDevice: info, }); - this.GetModeList(info.id); + await this.GetModeList(info.id); console.log("info"); // 如果不存在设备模式值,则判断为首次进入,弹窗提示 - let isFirstEntry = getStorageSync("isFirstEntry_" + info.model); + let isFirstEntry = getStorageSync("isFirstEntry_" + info.id); if (!isFirstEntry) { - // this.setState({ isShowStepTips: true }); + this.setState({ isShowStepTips: true }); } } // 开发者工具 const platform = Taro.getSystemInfoSync().platform; - - //开发者工具 if (platform !== "devtools") { - // 初始化蓝牙 + // 仅手机端初始化蓝牙 this.init(); } @@ -330,6 +340,8 @@ class IotCarePlan extends Component { queryInstructionParams ); }); + + // 监听蓝牙连接状态改变 Taro.onBLEConnectionStateChange(this.listener); await this.notifyBLECharacteristicValueChange(); @@ -338,20 +350,20 @@ class IotCarePlan extends Component { listener = (res) => { console.log("listener res", res); if (res?.connected) return; + // 蓝牙未连接才执行下面逻辑 Taro.offBLECharacteristicValueChange((res) => { console.log("offBLECharacteristicValueChange", res); }); clearTimeout(loadingTipsTimer); - // 断开蓝牙关闭倒计时 - this.setState({ - isShowCountdown: false, - }); console.log(commandMap.WL200Command, "监听到蓝牙断开, 打开断开提示"); + + this.workStatus = ""; // 显示蓝牙断开弹窗 - // this.setState({ - // workStatus: "", - // currentShowDialog: "connection_break", - // }); + this.setState({ + isConnectShow: true, // 打开蓝牙链接弹窗 + isConnectionBlutoot: false, // 断开蓝牙 + isShowCountdown: false, // 关闭倒计时,防止倒计时还在运行 + }); }; GetModeList = async (id) => { @@ -366,7 +378,9 @@ class IotCarePlan extends Component { ModeList: res.data.data, }); - this.modeCurrentFun(res.data.data[0]); + setTimeout(() => { + this.modeCurrentFun(res.data.data[0]); + }); } else { this.setState({ ModeList: res.data.data }); } @@ -404,7 +418,25 @@ class IotCarePlan extends Component { } /** 选中护理模式 */ - modeCurrentFun = async (data) => { + modeCurrentFun = async (data, isNotCheck = false) => { + // 是否跳过护理检查 + if (!isNotCheck) { + this.tempModeCurrent = data; + let isReturn = this.modeRuningChange(); + if (isReturn) return; + } + + let { isStandStatus, isShowNurse } = this.state; + // 舱体模式无法对应的时候,置灰开始按钮 + let isCabinMode = data.isCabinMode === 1; + if (isStandStatus === isCabinMode) { + this.setState({ isCanClick: true }); // 是否舱体一致时,可以点击 + } else { + this.setState({ isCanClick: false }); + } + console.log("isStandStatus", isStandStatus, isCabinMode); + console.log("isStandStatus === isCabinMode", isStandStatus === isCabinMode); + let currentServiceData = { startSource: "", stopSource: "", @@ -433,7 +465,46 @@ class IotCarePlan extends Component { this.setCustomMaskData(); } }); + + // 如果是正在运行中切换,则直接准备运行 + if (isShowNurse) { + this.onStartNurse(); + setTimeout(() => { + this.onNursingTap(); + }, 1000); + } }; + /** 设备运行中切换模式 */ + 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; + } + + //对比仪器上报运行的总秒数 和小程序页面运行的已经运行的总秒数,如果不一致就进行校准 + const currentScene = ActiveModeItem; // 获取当前的场景 + let sceneTime = minSecToS(currentScene.modeTimeStr); // 场景最小护理时间 + + if ( + sceneTime <= totalTime && + this.state.step == 2 && + this.state.facialMaskConnectStatus == 1 + ) { + // 提示切换护理模式 + this.hanldeChangeNurseFun(); + return true; + } + } + return false; + } + /** 切换护理模式 */ switchModeCurrentFun = async (data) => { this.setState({ @@ -457,8 +528,33 @@ class IotCarePlan extends Component { }; // 弹窗确定切换护理模式 confirmModeSwitchBtn = () => { - let { SwitchActiveModeItem } = this.state; + let { SwitchActiveModeItem, ActiveModeItem, isStandStatus } = this.state; let modeArray = ["all", "visor", "cabin", "yimeish"]; + // 切换护理模式时,需判断舱体和面罩是否切换 + if (SwitchActiveModeItem.isCabinMode !== ActiveModeItem.isCabinMode) { + if (SwitchActiveModeItem.isCabinMode === 1) { + // 判断舱体是否连接成功 + if (!isStandStatus) { + console.log( + "检测到面罩与舱体未连接成功,请确认面罩是否和舱体连接并接通舱体电源" + ); + this.openErrorTipsText( + "检测到面罩与舱体未连接成功,请确认面罩是否和舱体连接并接通舱体电源" + ); + return; + } + } else { + // 判断舱体是否断开连接 + if (isStandStatus) { + console.log("检测到面罩与舱体仍在连接中,该模式需要分离面罩和舱体"); + this.openErrorTipsText( + "检测到面罩与舱体仍在连接中,该模式需要分离面罩和舱体" + ); + return; + } + } + } + this.setState({ ModeType: modeArray[SwitchActiveModeItem.modeClass], }); @@ -472,27 +568,46 @@ class IotCarePlan extends Component { // //0未定义(全部) 1面罩模式 2舱体模式 3医美术后 let modeArray = ["all", "visor", "cabin", "yimeish"]; let modeClass = this.state.ActiveModeItem.modeClass; + this.workStatus = "pause"; this.setState({ ModeType: modeArray[modeClass], isShowNurse: true, isStopNurse: true, - isStandStatus: this.state.ActiveModeItem.isCabinMode === 1, - workStatus: "pause", step: 2, }); - this.handleWorkStatus(false, MODE_WORKING_ENUM.STANDBY); + setTimeout(() => { + this.handleWorkStatus(false, MODE_WORKING_ENUM.STANDBY); + }); }; /** 开始护理按钮:点击开始,页面进行到下一步 */ onStartNurse = async () => { - this.drawProwerPicture() - this.stepNext(); - return; - let { isConnectionBlutoot } = this.state; - if (isConnectionBlutoot) { + // 开发者工具 + // const platform = Taro.getSystemInfoSync().platform; + // if (platform === "devtools") { + // // 仅开发者工具,直接运行 + // this.stepNext(); + // } + + let { isStandStatus, ActiveModeItem } = this.state; + let isCabinMode = ActiveModeItem.isCabinMode === 1; + if (isStandStatus === isCabinMode) { this.stepNext(); - } else { - // todo 提示未连接蓝牙 + return; + } + this.onEmitErrorTips(); + }; + /** 不可切换光照提示 */ + onEmitErrorTips = async () => { + let { isStandStatus, ActiveModeItem } = this.state; + if (isStandStatus) { + if (ActiveModeItem.isCabinMode === 0) { + this.showTips("检测到面罩与舱体仍在连接中,该模式需要分离面罩和舱体"); + } else { + this.showTips( + "检测到面罩与舱体未连接成功,请确认面罩是否和舱体连接并接通舱体电源" + ); + } } }; @@ -519,61 +634,42 @@ class IotCarePlan extends Component { closeStepTips = (data) => { if (data.isLocal) { - setStorageSync("isFirstEntry_" + this.state.ActiveModeItem.model, true); // 关闭首次进入弹窗 + setStorageSync("isFirstEntry_" + 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({ + facialMaskConnectStatus: true, + }); // log.info(commandMap.WL200Command, "配对成功"); } break; // 附属设备状态主动上报,这种指令是主机主动上报某个附属设备断开或者连上了 case "BleStatusSync": + console.log("BleStatusSync 附属设备状态主动上报", jsonStatus); switch (jsonStatus.connectMessage?.deviceName) { - case "WL200": - console.log( - "BleStatusSync 附属设备状态主动上报,这种指令是主机主动上报某个附属设备断开或者连上", - jsonStatus.connectMessage?.connectType == "CONNECTED" - ); + // 附属设备是否连接支架 + case "Stand": if (jsonStatus.connectMessage?.connectType == "CONNECTED") { - // 已连接WL200 - this.setState({ isConnectionBlutoot: true }); - - // 附属设备连接成功,如何区分是哪个设备? this.setState({ - facialMaskConnectStatus: 1, // 面罩已连接 + isStandStatus: true, + isCanClick: this.state.ActiveModeItem?.isCabinMode === 1, }); - deviceToolKitInstance = deviceToolKitInstanceWL200; - console.log( - "检查版本isCheckedMaskVersion", - this.state.isCheckedMaskVersion - ); - if (!this.state.isCheckedMaskVersion) { - this.checkVersion(); - } } else { - // WL200连接失败 - // deviceToolKitInstance = deviceToolKitInstanceWE100; - // // TODO 护理中(step==2)时, 如果断开, 可能需要暂停 - console.log("WL200连接失败或断开"); + console.log("舱体支架断开连接"); this.setState({ - facialMaskConnectStatus: 0, - }); - } - break; - // 是否附属设备是否连接支架 - case "Stand": - if (jsonStatus.connectMessage?.connectType == "CONNECTED") { - this.setState({ - isStandStatus: true, + isStandStatus: false, + isCanClick: this.state.ActiveModeItem?.isCabinMode !== 1, }); } break; @@ -584,54 +680,36 @@ class IotCarePlan extends Component { //小程序主动问主机,现在链接了哪些附属设备,这时候主机给小程序的回复消息 case "QueryMatchStatus": - const isStandDevice = - jsonStatus?.subDeviceList?.includes("Stand") || false; - const isConnectedMask = - jsonStatus?.subDeviceList?.includes("WL200") || false; - - deviceToolKitInstance = isConnectedMask - ? deviceToolKitInstanceWL200 - : deviceToolKitInstanceWE100; - - console.log("连接and更改成功 deviceToolKitInstance", isConnectedMask); - if (!this.state.isCheckedMaskVersion && isConnectedMask) { - this.checkVersion(); // 检查版本 - } + console.log("QueryMatchStatus 设备回复小程序", jsonStatus); + + const isStandDevice = jsonStatus?.subDeviceList?.includes("Stand"); + deviceToolKitInstance = deviceToolKitInstanceWL200; console.log("支架是否链接", isStandDevice); - console.log("面罩是否链接", isConnectedMask); - if (isConnectedMask) { - this.setState({ - isConnectionBlutoot: true, - facialMaskConnectStatus: 1, + this.setState({ + isStandStatus: isStandDevice, + isCanClick: isStandDevice + ? this.state.ActiveModeItem?.isCabinMode === 1 + : this.state.ActiveModeItem?.isCabinMode !== 1, + }); + + // 连上面罩后, 获取仪器记录, 与缓存信息对比 + if (!this.hadGotInstrumentHistoryData) { + // 查询护理记录 + this.getInstrumentHistoryData(); + + // 查询仪器状态 + const queryDeviceArrayBuffer = deviceToolKitInstance.toBleCommand( + bleCommandSamples.queryDeviceStatus as any + ); + console.log("发送查询设备指令 获取仪器状态"); + sendCommand({ + value: queryDeviceArrayBuffer, }); } - - // 连上面罩后, 获取仪器记录, 与缓存信息对比, - // if ( - // isConnectedMask && - // !this.state.hadGotInstrumentHistoryData - // ) { - // // 如果不延时, 无法获取到仪器状态 - // const queryDeviceArrayBuffer = - // deviceToolKitInstance.toBleCommand( - // bleCommandSamples.queryDeviceStatus as any - // ); - // console.log("发送查询设备指令"); - // sendCommand({ - // value: queryDeviceArrayBuffer, - // }); - // // 打开ota页面需要关闭 - // // that.data.getInstrumentHistoryDataTimer = setTimeout(() => { - // // that.getInstrumentHistoryData(); - // // }, 3000); - // } - // this.setData({ - // isStandStatus: isStandDevice, - // facialMaskConnectStatus: `${isConnectedMask ? 1 : 0}`, - // // currentTime: this.data.standInfo.currentTime - // }); } }; + + // 蓝牙特征更改 notifyBLECharacteristicValueChange = () => { console.log("notifyBLECharacteristicValueChange deviceInfo 参数为=>"); const bluetoothInfo = this.props.bluetoothInfo; @@ -647,11 +725,11 @@ class IotCarePlan extends Component { "onBLECharacteristicValueChange jsonStatus => ", jsonStatus ); - // log.info(commandMap.WL200Command, 'onBLECharacteristicValueChange jsonStatus =>', jsonStatus); if (!jsonStatus || jsonStatus == null) { return; } - // end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而已处理流程都一样 + this.workStatus = jsonStatus.workStatus; // 记录工作状态 + // end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而言处理流程都一样 if (jsonStatus.workStatus && jsonStatus.workStatus == "endWork") { jsonStatus.workStatus = "end"; console.log(jsonStatus.workStatus, "护理结束"); @@ -665,7 +743,7 @@ class IotCarePlan extends Component { break; case "DeviceControl": - console.log("小程序控制设备,给设备发送指令", jsonStatus); + console.log("打印小程序控制设备,给设备发送的指令", jsonStatus); // setTimeout(() => { // console.log("currentTime", this.state.currentTime); // }); @@ -676,11 +754,11 @@ class IotCarePlan extends Component { "设备主动上报给小程序的指令 一般是工作状态改变", jsonStatus ); + this.workStatus = jsonStatus.workStatus; this.setState({ Electricity: jsonStatus.battery, // fr200Electricity: jsonStatus.battery, matrixElectricity: jsonStatus.matrixBattery, - workStatus: jsonStatus.workStatus, workMode: jsonStatus?.workMode, }); // 判断是否在step == 2(护理中) @@ -716,7 +794,7 @@ class IotCarePlan extends Component { switch (jsonStatus.infoQueryType) { // 自定义模式设置 case "customModeSet": - console.log(">>>>>>>>>>>>>>>自定义模式>>>>>>>>>>>>>>>"); + console.log(">>>>>>>>>>>>>>>设置自定义模式>>>>>>>>>>>>>>>"); console.log( "InfoQuery customModeSet responseStatus=====>", jsonStatus @@ -731,36 +809,33 @@ class IotCarePlan extends Component { break; // 自定义模式信息 case "customModeInfo": + console.log(">>>>>>>>>>>>>>>查询自定义模式信息>>>>>>>>>>>>>>>"); console.log( "InfoQuery customModeInfo responseStatus=====>", jsonStatus ); - break; case "versionInfo": - console.log( - "InfoQuery versionInfo responseStatus=====>", - jsonStatus - ); - if (jsonStatus.versionNo) { - // 清理计时器 - if (checkVersionTimeout) clearTimeout(checkVersionTimeout); - if (this.state.hasVersion) return; - this.setState({ - hasVersion: true, - }); - this.checkOta(jsonStatus.versionNo); - } break; // 当前报告 case "currentMaskReportInfo": + // 每次切换模式并开始运行后,生成一个新的自增ID + // commandType: "InfoQuery" + // createDate: "" + // gear: 0 + // id: 73 + // infoQueryType: "currentMaskReportInfo" + // neededTotalSeconds: 900 + // totalSeconds: 0 + // workMode: "BrightenStand" console.log("当前面罩报告 currentMaskReportInfo", jsonStatus); - // if (!this.state.hadCheckReport) { - // this.state.hadCheckReport = true; - // that.checkInstrumentRecord(jsonStatus); - // } else { - // that.setWL200NursingHistory(jsonStatus); - // } + + if (!this.hadCheckReport) { + this.hadCheckReport = true; + this.checkInstrumentRecord(jsonStatus); + } else { + this.setWL200NursingHistory(jsonStatus); + } break; default: @@ -801,53 +876,7 @@ class IotCarePlan extends Component { }); }; - // 检查版本 - checkVersion = () => { - this.sendCheckVersion(); - this.setState({ - isCheckedMaskVersion: true, - }); - if (checkVersionTimeout) clearTimeout(checkVersionTimeout); - checkVersionTimeout = setTimeout(() => { - if (this.state.hasVersion) { - if (checkVersionTimeout) clearTimeout(checkVersionTimeout); - } else { - this.sendCheckVersion(); - } - }, 600); - }; - // 检查版本指令 - sendCheckVersion = () => { - deviceToolKitInstance.setDebug(true); - // 加定时器查询版本 - const queryVersion = deviceToolKitInstance.toBleCommand({ - commandType: "InfoQuery", - infoQueryType: "versionInfo", - otaDeviceType: "WL200", - }); - sendCommand({ - value: queryVersion, - }); - }; - - checkOta = async (versionNo) => { - const { iot_versions } = this.state.curDeviceInfo; - let isNeedToUpdateBl = isNeedToUpdate(versionNo, iot_versions); - console.log( - `设备版本号: ${versionNo}`, - `后台版本号: ${iot_versions}`, - `是否需要升级: ${isNeedToUpdateBl}` - ); - if (isNeedToUpdateBl) { - this.setState({ - isAskedOta: true, - // currentShowDialog: 'offlineDialog', - }); - // this.confirmOta(); - } - }; - - //待完善,以后同步设备数据到小程序的事件,在这个事件里判断是否需要更新页面(是否需要触发setData) + /** 同步设备运行信息:运行时间 */ updateDeviceSyncData = (newData, jsonStatus) => { DeviceSyncData = { ...DeviceSyncData, @@ -873,8 +902,6 @@ class IotCarePlan extends Component { console.log("场景时间 sceneTime", sceneTime); console.log("当前显示时间 currentTime", currentTime); console.log("设备运行时间 totalTime", totalTime); - console.log(" this.state.step", this.state.step); - console.log("sceneTime > totalTime", sceneTime > totalTime); // 更新界面倒计时 this.resetTimer(); @@ -892,13 +919,8 @@ class IotCarePlan extends Component { } else { this.setState({ currentTime: "00:00", - endPlace: "report", }); - this.judgementWorkStatus( - MODE_WORKING_ENUM.END, - jsonStatus.workMode, - jsonStatus - ); + this.judgementWorkStatus(MODE_WORKING_ENUM.END, jsonStatus.workMode); } }, }; @@ -925,15 +947,9 @@ class IotCarePlan extends Component { * 设备上报不同状态 * params 工作状态 工作模式 响应状态 */ - judgementWorkStatus(nWorkStatus, nWorkMode, jsonStatus) { - const { - workStatus, - step, - isStandStatus, - workMode, - ActiveModeItem, - ModeList, - } = this.state; + judgementWorkStatus(nWorkStatus, nWorkMode) { + const { step, isStandStatus, workMode, ActiveModeItem, ModeList } = + this.state; const opts: any = {}; // ActiveModeItem let nowModeItem; @@ -953,9 +969,9 @@ class IotCarePlan extends Component { this.setState({ isShowCountdown: false, }); - if (nowModeItem?.isStandMode && step == 2) { - opts.currentTime = nowModeItem.modeTime; - } else if (!nowModeItem?.isStandMode && step == 2) { + if (nowModeItem?.isCabinMode && step == 2) { + opts.currentTime = nowModeItem.modeTimeStr; + } else if (!nowModeItem?.isCabinMode && step == 2) { // fix: 启动非支架模式倒计时时,连上支架,仪器的状态变为standby opts.step = 1; } @@ -982,7 +998,7 @@ class IotCarePlan extends Component { }); } if (nowModeItem) { - opts.currentTime = nowModeItem.modeTime; + opts.currentTime = nowModeItem.modeTimeStr; } // startSettingCountDown 用于标记打开了倒计时loading if (!this.state.isShowCountdown) { @@ -1015,7 +1031,6 @@ class IotCarePlan extends Component { isShowCountdown: false, }); if (ActiveModeItem.isCabinMode) { - // this.onPauseTap(); this.setState({ title: "暂停护理", isStopNurse: true, @@ -1023,10 +1038,6 @@ class IotCarePlan extends Component { } }, end: () => { - // 仪器返回护理结束, 支架模式不需要了 - // if (modeItem.isStandMode) { - // this.onPauseTap(); - // } // 已进入了报告阶段, 防止重复进入, 主要防止在手动点击结束护理接收到仪器消息 console.log("END 护理结束"); clearInterval(currentTimeTimer); @@ -1056,11 +1067,8 @@ class IotCarePlan extends Component { if (isAuto == true) { // 仪器自动上报完成, 直接上报并跳转报告页 clearInterval(currentTimeTimer); - const isEnough = this.checkTime(); - if (isEnough && !this.state.endPlace) { - this.setState({ - endPlace: "report", - }); + const isEnough = this.checkNurseTime(); + if (isEnough) { this.saveNurseReport(true, "endnursing"); } } else { @@ -1069,30 +1077,12 @@ class IotCarePlan extends Component { } }; - isInTimeScope(start, end, targetMinute, targetSecond) { - const startTime = dayjs().set("minute", start).set("second", 0); - const endTime = dayjs().set("minute", end).set("second", 0); - const targetTime = dayjs() - .set("minute", targetMinute) - .set("second", targetSecond); // 要判断的时间,这里使用当前时间作为示例 - let inTime = false; - if ( - (targetTime.isAfter(startTime) && targetTime.isBefore(endTime)) || - targetTime.isSame(startTime) || - targetTime.isSame(endTime) - ) { - inTime = true; - } - return inTime; - } - - // 重置计时器 + // 重置并同步计时器 resetTimer = () => { // 切换模式后, 需要重新设置计时器, 以防进行中的计时器 currentTimeTimer && clearInterval(currentTimeTimer); currentTimeTimer = setInterval(() => { let { - workStatus, step, facialMaskConnectStatus, currentTime, @@ -1100,17 +1090,18 @@ class IotCarePlan extends Component { ModeStepIndex, ActiveModeItem, } = this.state; + console.log("resetTimer workStatus", this.workStatus); if ( - workStatus == MODE_WORKING_ENUM.WORKING && + this.workStatus == MODE_WORKING_ENUM.WORKING && step == 2 && facialMaskConnectStatus == 1 ) { let totalSeconds = minSecToS(ActiveModeItem.modeTimeStr); let currentSeconds = minSecToS(currentTime); let checkTime = totalSeconds - currentSeconds; - console.log("设备已运行多少秒", checkTime); - console.log("ModeStepTimeArray", ModeStepTimeArray); + this.elapsedTime = checkTime; if (currentSeconds >= 1) { + // 小程序显示倒计时 this.setState({ currentTime: s_to_ms(--currentSeconds), }); @@ -1118,11 +1109,10 @@ class IotCarePlan extends Component { let length = ModeStepTimeArray.length; if (length) { // 模式多个步骤节点切换 - // 已运行时间达到下一节点时,切换 if (checkTime > ModeStepTimeArray[ModeStepIndex]) { - // 已运行时间达到下一节点,步骤切换时更新 - if (ModeStepIndex < length) { + // 已运行时间达到下一节点,且存在下一节点,步骤切换时更新 + if (ModeStepIndex < length - 1) { let index = ModeStepIndex + 1; // 提前步骤+1 let currentServiceData = { startSource: "", @@ -1151,7 +1141,6 @@ class IotCarePlan extends Component { clearInterval(currentTimeTimer); this.setState({ currentTime: "00:00", - endPlace: "report", ModeStepIndex: 0, }); this.saveNurseReport(true, "setTimer"); // 保存护理计划,并且结束 @@ -1166,9 +1155,7 @@ class IotCarePlan extends Component { this.state; let newWorkStatus = workStatus || - (this.state.workStatus == MODE_WORKING_ENUM.WORKING - ? "pause" - : "working"); + (this.workStatus == MODE_WORKING_ENUM.WORKING ? "pause" : "working"); if (isBtnClick && newWorkStatus == "working") { // 舱体模式 if (ActiveModeItem.isCabinMode === 1 && !isStandStatus) { @@ -1185,29 +1172,19 @@ class IotCarePlan extends Component { } } - // // 工作状态,开始组合模式 - // if ( - // this.state.ActiveModeItem.combineData.length && - // this.state.workStatus == MODE_WORKING_ENUM.WORKING - // ) { - // this.startCombinationMode(); - // } - const sendParams = { ...deviceCommandSamples.pause, workMode: ActiveModeItem.modeType, // 使用模式 - // workMode: "MaskCustom", workStatus: newWorkStatus, }; + console.log("准备发送自定义或工作指令", ActiveModeItem, sendParams); const pauseArrayBuffer = deviceToolKitInstance.toBleCommand( sendParams as any ); sendCommand({ value: pauseArrayBuffer, }).then(() => { - this.setState({ - workStatus: newWorkStatus, - }); + this.workStatus = newWorkStatus; this.resetTimer(); console.info( `handleWorkStatus 发送${newWorkStatus}指令成功 参数为 =>`, @@ -1230,35 +1207,28 @@ class IotCarePlan extends Component { hadClickStart: false, }); }, 500); - const { - ActiveModeItem, - workStatus, - isStandStatus, - facialMaskConnectStatus, - customModeData, - } = this.state; - const modelActiveItem = ActiveModeItem; - // log.info( - // commandMap.WL200Command, - // "点击开始护理按钮", - // `当前模式: ${modelActiveIndex}`, - // `当前面罩状态:${facialMaskConnectStatus}`, - // `当前仪器模式:${workStatus}` - // ); + + const { ActiveModeItem, isStandStatus, facialMaskConnectStatus } = + this.state; + + if (isStandStatus === 1 && ActiveModeItem.isCabinMode === 0) { + console.log("已连接舱体,只可选择舱体模式"); + return; + } + if (isStandStatus === 0 && ActiveModeItem.isCabinMode === 1) { + console.log("未连接舱体!"); + return; + } + console.info( commandMap.WL200Command, "点击开始护理按钮", `当前模式: ${ActiveModeItem.modeType}`, `当前面罩状态:${facialMaskConnectStatus}`, - `当前仪器模式:${workStatus}` + `当前仪器模式:${this.workStatus}` ); - console.log(modelActiveItem); + console.log(ActiveModeItem); console.log("isStandStatus:" + isStandStatus); - console.log( - workStatus !== MODE_WORKING_ENUM.WORKING && - workStatus !== MODE_WORKING_ENUM.STANDBY && - workStatus !== MODE_WORKING_ENUM.PAUSE - ); if (facialMaskConnectStatus != 1) { console.log("facialMaskConnectStatus 开始处", facialMaskConnectStatus); @@ -1266,12 +1236,12 @@ class IotCarePlan extends Component { return; } // 如果是强效舒缓,需要判断是否连接支架 - if (modelActiveItem.isStandMode && !isStandStatus) { + if (ActiveModeItem.isCabinMode && !isStandStatus) { this.showTips( `检测到舱体未连接成功,请确认面罩开机后与舱体连接,并接通舱体电源` ); return; - } else if (!modelActiveItem.isStandMode && isStandStatus) { + } else if (!ActiveModeItem.isCabinMode && isStandStatus) { this.showTips(`检测到面罩仍和舱体连接中,请分离后切换`); return; } @@ -1279,48 +1249,52 @@ class IotCarePlan extends Component { ActiveModeItem.modeType === "MaskCustom" && !this.state.isCombineSuccess ) { - this.showTips(`${modelActiveItem.modeName}模式设置失败,请联系小助手`); + this.showTips(`${ActiveModeItem.modeName}模式设置失败,请联系小助手`); return; } + + let downNum = CountDownTime[ActiveModeItem.modeType] || 3; + console.log("downNum", downNum); + this.showCountdownFun(downNum, () => {}); // 倒计时弹窗 + // 开始执行护理 + this.workStatus = MODE_WORKING_ENUM.WORKING; // 不管当前什么状态,直接设为工作状态 this.handleWorkStatus(true, MODE_WORKING_ENUM.WORKING); - this.showCountdownFun(3, () => { }); // 倒计时弹窗 + this.setState({ + isStopNurse: false, + }); } - // 结束护理? + // 结束护理 endNurseFun() { this.handleWorkStatus(false, "end"); - this.PostNursingLogClock(); - // setTimeout(() => { - // //TODO IOS关闭蓝牙太快导致关机指令没发出去,暂时这么解决 - // const isEnough = this.checkTime(); - // if (!isEnough) { - // Taro.showModal({ - // title: "提示", - // content: "护理时间不足,请重新连接护理", - // showCancel: false, - // success: (res) => { - // if (!this.state.endPlace || this.state.endPlace !== "report") { - // // back(); - // console.log("back"); - // } - // // this.state.innerAudioContext.destroy(); - // Taro.closeBluetoothAdapter(); - // }, - // }); - // } else { - // if (!this.state.endPlace || this.state.endPlace !== "report") { - // // back(); - // console.log("back"); - // } - // // this.state.innerAudioContext.destroy(); - // Taro.closeBluetoothAdapter(); - // } - // }, 500); + if (this.checkNurseTime()) { + this.PostNursingLogClock(); + } else { + // 时间不满足,回到主页 + this.handleWorkStatus(false, "end"); + this.setState({ + isEndCarePlan: false, + isNotEnoughTime: true, + }); + } } - // 检查时间是否达标 - checkTime() { + // 手动切换护理 + hanldeChangeNurseFun() { + // 满足时间条件,提示是否保存部分护理记录 + if (this.checkNurseTime()) { + // 打开提示保存护理弹窗 + this.setState({ + isShowTipsSave: true, + }); + } else { + // 不满足条件,直接切换 + } + } + + /** 检查时间是否达标仪器最低护理时间 */ + checkNurseTime() { const { currentDevice, ActiveModeItem } = this.state; const currentScene = ActiveModeItem; let sceneTime = minSecToS(currentScene.modeTimeStr); @@ -1335,9 +1309,223 @@ class IotCarePlan extends Component { return false; } } + /** 检查时间是否达标仪器最低护理时间 */ + isCheckNurseTime(deviceItem, ModeItem) { + const currentScene = ModeItem; + let sceneTime = minSecToS(currentScene.modeTimeStr); + const timeRemaining = sceneTime - minSecToS(this.state.currentTime); // 当前模式已运行时间 + + let nursingTimeStr = deviceItem?.nursingTimeStr; + let nursingTime = nursingTimeStr ? minSecToS(nursingTimeStr) : 60; // 设备生成护理记录至少需要运行时间 - // 删除WL200护理历史 - rmWL200NursingHistory(WL200NursingHistory, hard = false) { } + if (timeRemaining >= nursingTime) { + return true; + } else { + return false; + } + } + + /*** 护理记录 START ***/ + /** 小程序查询护理记录 */ + getInstrumentHistoryData() { + this.hadGotInstrumentHistoryData = true; + console.log("发送指令currentMaskReportInfo 获取设备护理记录"); + setTimeout(() => { + const queryCurrentMaskReportInfoBuffer = + deviceToolKitInstance.toBleCommand({ + ...(bleCommandSamples.queryCurrentMaskReportInfo as any), + }); + sendCommand({ + value: queryCurrentMaskReportInfoBuffer, + }); + }, 3000); + } + /** + * @title 检查护理记录 + * @description + * 1.判断是否存在工作状态:如果不存在,则等待两秒用于连接设备与赋值,再执行后面的代码 + * + * 2.判断是否已存在缓存的护理记录:如果没有历史,则缓存 + * + * 3.判断是否当天(如果不是当天,则删除记录) + * + * 4.判断设备状态-未运行/已完成/待机 + * 4-1.已有缓存护理记录,判断ID一致,同步时间。若主动结束,需判断时间是否满足仪器最低护理时间,满足直接跳转护理报告页;不满足需提示不满足,回到首页 + * 4-2.已有缓存护理记录,判断ID不一致(同步异常)。直接提交,固定设置为一分钟。 + * + * 5.判断设备状态-运行中 + * 正常执行逻辑 + * + * */ + checkInstrumentRecord = async (jsonStatus: any) => { + let { currentDevice, ActiveModeItem, ModeList } = this.state; + if (jsonStatus) { + } + // 1.判断是否存在工作状态:如果不存在,则等待两秒用于连接设备与赋值,再执行后面的代码 + if (!this.workStatus) { + await sleep(2); + } + + // 2.判断是否已存在缓存的护理记录:如果没有历史,则缓存 + let workStatus = this.workStatus; + let WL200NursingHistory = this.WL200NursingHistory; + if (!this.WL200NursingHistory) { + console.log("小程序缓存没有数据, 忽略"); + if ( + workStatus == MODE_WORKING_ENUM.WORKING || + workStatus == MODE_WORKING_ENUM.PAUSE + ) { + // 缓存没有数据, 要存缓存 + this.setWL200NursingHistory(jsonStatus); + } + return; + } + + // 3.判断是否当天(如果不是当天,则删除记录) + if (!dayjs().isSame(WL200NursingHistory?.createDate, "day")) { + console.log("小程序缓存有数据,但是不是当天数据,忽略"); + this.rmWL200NursingHistory(WL200NursingHistory); + return; + } + + // 仪器缓存模式,判断是否存在于现有模式中 + let recordModeItem = ModeList.find((item) => { + return item.id == WL200NursingHistory.id; + }); + if (!WL200NursingHistory || !recordModeItem) { + console.log("仪器有数据, 但是缓存没有数据, 忽略"); + return; + } + + let sceneTime = minSecToS(ActiveModeItem.modeTimeStr); + // 4.判断设备状态-未运行/已完成/待机 + if ( + workStatus == MODE_WORKING_ENUM.STANDBY || + workStatus == MODE_WORKING_ENUM.END || + !workStatus + ) { + // 判断id是否一致, 一致的话则生成护理报表 + if (jsonStatus.id == WL200NursingHistory.id) { + console.log("id一致, 设备没有运行/已完成/待机"); + let totalSeconds = jsonStatus.totalSeconds; // 从仪器上获取的使用时间 + let neededTotalSeconds = jsonStatus.neededTotalSeconds; // 从仪器上获取的使用时间 + console.log( + "从仪器上获取的使用时间 neededTotalSeconds", + neededTotalSeconds + ); + let nursingTimeStr = currentDevice?.nursingTimeStr; + let nursingTime = nursingTimeStr ? minSecToS(nursingTimeStr) : 60; // 设备生成护理记录至少需要运行时间 + + if (totalSeconds < nursingTime) { + console.log("护理时间不足,弹出提示"); + // todo + this.rmWL200NursingHistory(WL200NursingHistory); + 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, + }; + let res: any = await this.PostNursingLogClock(params); + console.log("res", res); + this.rmWL200NursingHistory(WL200NursingHistory); + } else { + // ID不一致,同步异常,统一提交一分钟 + let params = { + instrumentId: currentDevice.id, + instrumentName: currentDevice.name, + modeId: ActiveModeItem.id, + modeName: ActiveModeItem.modeName, + nursingTime: "00:01:00", + }; + let res: any = await this.PostNursingLogClock(params); + console.log("res", res); + this.rmWL200NursingHistory(WL200NursingHistory); + } + } else { + // 5.判断设备状态-运行中 正常逻辑,这里不做处理,如果用户操作,则按正常流程判断 + console.log("同步异常,但设备运行中"); + console.log("同步异常,但设备运行中"); + console.log("同步异常,但设备运行中"); + } + }; + /** 获取小程序本地缓存的历史记录 */ + getWL200NursingHistory() { + this.WL200NursingHistory = Taro.getStorageSync("WL200NursingHistory"); + } + /** 设置WL200护理历史 */ + setWL200NursingHistory = (jsonStatus: any) => { + let { currentDevice, ActiveModeItem, ModeList } = 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: jsonStatus.id, + neededTotalSeconds: jsonStatus.neededTotalSeconds, + jsonStatus, + }; + this.WL200NursingHistory = JSON.parse(JSON.stringify(params)); + Taro.setStorageSync("WL200NursingHistory", params); + console.log("保存setWL200NursingHistory"); + }; + /** 删除WL200护理历史 */ + rmWL200NursingHistory = (WL200NursingHistory, hard = false) => { + const nowWL200NursingHistory = Taro.getStorageSync("WL200NursingHistory"); + if (nowWL200NursingHistory.id == WL200NursingHistory.id) { + Taro.removeStorageSync("WL200NursingHistory"); + } else if (hard) { + Taro.removeStorageSync("WL200NursingHistory"); + } + }; + + /** 提交护理记录 */ + PostNursingLogClock = async (data: any = null, isJump = true) => { + 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) { + if (isJump) { + this.setState({ + isShowNursingSuccess: true, + }); + setTimeout(() => { + this.setState({ + isShowNursingSuccess: false, + }); + this.goFaceReport(); + }, 2000); + } + } + }; + /*** 护理记录 END ***/ //蓝牙断开连接处理 bluetoothDisconnectProcessing() { @@ -1351,27 +1539,24 @@ class IotCarePlan extends Component { } } - // 获取护理时间组合 + /** 获取护理时间组合 */ getServiceTimeData() { const { ActiveModeItem } = this.state; let serviceData = ActiveModeItem.serviceData.map((item) => { - // let totalWorkingMinutes = parseInt(item.modeTimeStr.split(":")[0]); // 仅分钟数 - // let totalWorkingSeconds = parseInt(item.modeTimeStr.split(":")[1]); // 仅秒数 - let totalWorkingMinutes = 1; // 仅分钟数 - let totalWorkingSeconds = 0; // 仅秒数 + let totalWorkingMinutes = parseInt( + item.serviceStartTimeStr.split(":")[0] + ); // 仅分钟数 + let totalWorkingSeconds = parseInt(item.serviceEndTimeStr.split(":")[1]); // 仅秒数 + // let totalWorkingMinutes = 1; // 仅分钟数 + // let totalWorkingSeconds = 0; // 仅秒数 return { totalWorkingMinutes, totalWorkingSeconds, }; }); - console.log( - "组合时间ServiceTimeData", - serviceData, - ActiveModeItem.serviceData - ); return serviceData; } - // 设置护理时间组合 + /** 设置护理时间组合 */ setServiceTimeData() { let ServiceTimeData = this.getServiceTimeData(); @@ -1387,14 +1572,12 @@ class IotCarePlan extends Component { let oldTime = old.totalWorkingMinutes * 60 + old.totalWorkingSeconds; let value = oldTime + curTime; - console.log("value", value); ModeStepTimeArray.push(value); return { totalWorkingMinutes: newTotalWorkingMinutes, totalWorkingSeconds: newTotalWorkingSeconds, }; } - console.log("curTime", curTime); ModeStepTimeArray.push(curTime); return { totalWorkingMinutes: newTotalWorkingMinutes, @@ -1407,17 +1590,9 @@ class IotCarePlan extends Component { }); console.log("组合时间ModeStepTimeArray", ModeStepTimeArray); } + /* 组合模式 */ - // 获取自定义组合模式原数组 - getOriginModesArray = () => { - const { ModeList, ActiveModeItem } = this.state; - const combineIds = ActiveModeItem.combineData.map( - (item) => item.combineModeId - ); - let modesArray = ModeList.filter((item) => combineIds.includes(item.id)); - return modesArray; - }; - // 获取自定义组合模式数组 + /** 获取自定义组合模式数组 */ getCustomModesArray = () => { const { ModeList, ActiveModeItem } = this.state; const combineIds = ActiveModeItem.combineData.map( @@ -1495,8 +1670,17 @@ class IotCarePlan extends Component { }); }; confirmEndBtn = () => { - this.endNurseFun(); - this.cancelEndBtn(); + console.log("confirmEndBtn", this.checkNurseTime()); + if (this.checkNurseTime()) { + this.endNurseFun(); + this.cancelEndBtn(); + } else { + this.handleWorkStatus(false, "end"); + this.setState({ + isEndCarePlan: false, + isNotEnoughTime: true, + }); + } }; cancelEndBtn = () => { this.setState({ @@ -1505,28 +1689,70 @@ class IotCarePlan extends Component { }; /** 弹窗 END*/ - /** 护理记录 */ - // apiClock - PostNursingLogClock = async () => { - let { currentDevice, ActiveModeItem } = this.state; - let params = { - instrumentId: currentDevice.id, - instrumentName: currentDevice.name, - modeId: ActiveModeItem.id, - modeName: ActiveModeItem.modeName, - nursingTime: ActiveModeItem.modeTime, - }; - let res: any = await InstrumentInfo.apiNursingLog.addLog(params); - console.log("PostNursingLogClock", res); + // 打开通用错误弹窗 + openErrorTipsText = (str) => { + this.setState({ + isShowErrorTipsText: true, + errorTipsText: str, + }); + }; + // 关闭通用错误弹窗 + closeErrorTipsText = () => { + this.setState({ + isShowErrorTipsText: false, + }); + }; + + closeNotEnoughTime = () => { + this.setState({ + isNotEnoughTime: false, + }); + Taro.switchTab({ + 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, + }); + }; + connectionClose = () => { + this.setState({ + isConnectShow: false, + }); + }; + + // 手动护理模式切换:提示是否保存护理 + closeTipsSave = () => { + this.setState({ + isShowTipsSave: false, + }); + this.modeCurrentFun(this.tempModeCurrent, false); + }; + confirmTipsSave = async () => { + this.setState({ + isShowTipsSave: false, + }); + this.PostNursingLogClock(null, false); + this.modeCurrentFun(this.tempModeCurrent, false); }; - /** 护理记录 End */ render() { let { name, title, + isConnectShow, isShowStepTips, - isConnectionBlutoot, + isCanClick, isShowNurse, isStopNurse, ModeList, @@ -1539,13 +1765,19 @@ class IotCarePlan extends Component { activeModeID, isShowCountdown, countdown, - ModeStepIndex, Electricity, matrixElectricity, errorTips, isEndCarePlan, currentTime, facialMaskConnectStatus, + isShowErrorTipsText, + errorTipsText, + isNotEnoughTime, + isShowNursingSuccess, + currentDevice, + isConnectionBlutoot, + isShowTipsSave, } = this.state; return ( @@ -1554,23 +1786,24 @@ class IotCarePlan extends Component { + { )} + + + + + + + 当前模式已护理部分时间 + 是否保存护理记录 + + } + cancelButtonText="取消" + confirmButtonText="确认" + textAlgin="center" + close={this.closeTipsSave} + confirm={this.confirmTipsSave} + /> + + { + /*不需要做处理*/ + }} + /> + + {isConnectShow && ( + {}} + pairingChange={this.pairingChange} + upgradeFun={() => {}} + /> + )} @@ -1681,12 +1981,13 @@ class IotCarePlan extends Component {