From 3350094fd6a7f771644ab8f89172a89f5447b1e0 Mon Sep 17 00:00:00 2001 From: blak-kong <546598185@qq.com> Date: Mon, 19 Feb 2024 20:35:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E4=BF=9D=E5=AD=98=EF=BC=8C?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E8=AE=BE=E5=A4=87=E5=90=AF=E5=8A=A8=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E8=8B=B1=E6=96=87=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/index/index.tsx | 10 + .../iotCarePlan/components/ModeList/index.tsx | 11 +- src/pages/iotCarePlan/iotCarePlan.less | 27 + src/pages/iotCarePlan/iotCarePlan.tsx | 1221 ++++++++++++++--- src/utils/request.js | 8 +- src/utils/util.js | 1070 ++++++++------- 6 files changed, 1613 insertions(+), 734 deletions(-) diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index f598ffc..10b540a 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -629,6 +629,11 @@ class Index extends Component { // return; } + async goIot() { + go("/pages/iotCarePlan/iotCarePlan"); // 画页面直接跳转 + // return; + } + //连接完成时数据的回调 offlineChange = async (e) => { console.log("offlineChange", e); @@ -918,6 +923,7 @@ class Index extends Component { 添加新设备 + {instrumentList.map((item, index) => { @@ -967,6 +973,10 @@ class Index extends Component { )} + + 假按钮跳转蓝牙调试设备页 + + item.modeClass === 1); // 面罩模式 let CabinList = ModeList.filter((item) => item.modeClass === 2); // 舱体模式 let YimeishList = ModeList.filter((item) => item.modeClass === 3); // 医美术后 @@ -41,7 +48,7 @@ function Index({ ModeList, ModeType, ActiveModeItem, onEmit }: Props) { return ( - {ModeList.length > 0 && ModeType !== "all" && ( + {ModeList.length > 0 && isShowNurse && ( 全部模式 { super(props); this.state = { name: "iotCarePlan", + title: "美容仪名字", + instrument: "WE200", /** 连接设备 */ hasVersion: false, // 是否已查询到版本号 @@ -149,7 +170,7 @@ class IotCarePlan extends Component { basicModeList: [], //模式列表 modelActiveIndex: 0, //模式下标 sliderProgress: 22, - isStandStatus: false, //支架开启状态 + isStandStatus: false, //支架开启状态(支架就是舱体) workStatus: "", //工作状态 Electricity: 0, //fr200电量 matrixElectricity: 0, //matrix电量 @@ -167,7 +188,6 @@ class IotCarePlan extends Component { // countdown: 3, // 倒计时 step: 1, // 1:选择模式并播放视频, 2:护理中 facialMaskConnectStatus: 0, // 面膜连接状态 - errorTips: "", checkedMaskVersion: false, //是否检查过固件版本了 askedOta: false, //询问过用户是否需要OTA showVideoPlayBtn: true, // 视频播放按钮 @@ -187,22 +207,32 @@ class IotCarePlan extends Component { /** 连接设备 End */ + // isMuted: false, // 视频是否静音 isMusicPlay: false, // 声音播放状态 isShowStepTips: false, // 是否显示介绍步骤弹窗 isConnectionBlutoot: false, // 是否已连接蓝牙 isShowNurse: false, // 是否开始并显示护理 isStopNurse: false, // 是否暂停护理 isEndNurse: false, // 是否结束护理 + errorTips: "", // 错误提示 // 模式列表 ModeList: [], - ModeType: "all", // all visor cabin yimeish + ModeType: "all", // all visor面罩 cabin舱体 yimeish医美 + modeClass: "", // 1面罩 2舱体 3医美 ActiveModeItem: {}, // 当前选中模式 ModeStepIndex: 0, // 当前护理功效步骤:每个步骤时间不定,所以时间另外计算,根据步骤显示 // 倒计时 - isShowCountdown: false, + isShowCountdown: false, // 倒计时弹窗 countdown: 6, + // startSettingCountDown: false, // 是否开始倒计时 + + // 音乐 + // innerAudioContext: null, + + // 最后执行步骤位置 + endPlace: "", }; } @@ -212,7 +242,12 @@ class IotCarePlan extends Component { keepScreenOn: true, }); } - componentDidMount() {} + componentDidMount() { + this.setState({ + videoContext: Taro.createVideoContext("myVideo"), + standVideoContext: null, + }); + } componentWillUnmount() {} @@ -257,6 +292,8 @@ class IotCarePlan extends Component { }); Taro.onBLEConnectionStateChange(this.listener); await this.notifyBLECharacteristicValueChange(); + + this.handleWorkStatus(null, MODE_WORKING_ENUM.STANDBY); } listener = (res) => { console.log("listener res", res); @@ -265,9 +302,10 @@ class IotCarePlan extends Component { console.log("offBLECharacteristicValueChange", res); }); clearTimeout(loadingTipsTimer); - // this.setState({ - // startSettingCountDown: false - // }) + // 断开蓝牙关闭倒计时 + this.setState({ + isShowCountdown: false, + }); console.log(commandMap.WL200Command, "监听到蓝牙断开, 打开断开提示"); // 显示蓝牙断开弹窗 // this.setState({ @@ -302,7 +340,7 @@ class IotCarePlan extends Component { this.setState({ isMusicPlay: !isMusicPlay }); }; - // 开始护理按钮:点击开始,页面进行到下一步 + /** 开始护理按钮:点击开始,页面进行到下一步 */ onStartNurse = async () => { this.stepNext(); return; @@ -313,10 +351,17 @@ class IotCarePlan extends Component { // todo 提示未连接蓝牙 } }; + /** 切换光照 */ onSwitchChange = async () => { // todo let { isStopNurse } = this.state; - this.setState({ isStopNurse: !isStopNurse }); + let switchStatus = !isStopNurse; + if (switchStatus) { + // 开始光照逻辑 + } else { + // 暂停光照逻辑 + } + this.setState({ isStopNurse: switchStatus }); }; onEndPlan = async () => { // todo @@ -343,7 +388,126 @@ class IotCarePlan extends Component { }; /** 蓝牙相关 */ + switchBLEMatch = (jsonStatus: any) => { + switch (jsonStatus.bleCommandType) { + // 如果设备配对链接发送配对码的时候,设备应答小程序配对码是否正确。 + case "SendMatchCode": + if (jsonStatus.matchedSuccess) { + // msg('配对成功') + console.log("配对成功"); + // log.info(commandMap.WL200Command, "配对成功"); + } + break; + //附属设备状态主动上报,这种指令是主机主动上报某个附属设备断开或者连上了 + case "BleStatusSync": + switch (jsonStatus.connectMessage?.deviceName) { + case "WL200": + if (jsonStatus.connectMessage?.connectType == "CONNECTED") { + // 已连接WL200 + this.setState({ isConnectionBlutoot: true }); + if ( + !this.state.customModeData.setCustomSuc && + !this.state.customModeData.hadSetCustom + ) { + // this.setCustomMaskData(); + } + // that.setData({ + // facialMaskConnectStatus: 1, + // }); + // this.deviceToolKitInstance = deviceToolKitInstanceWL200; + // console.log( + // "checkedMaskVersion", + // this.data.checkedMaskVersion + // ); + // if (!this.data.checkedMaskVersion) { + // this.checkVersion(); + // } + } else { + // deviceToolKitInstance = deviceToolKitInstanceWE100; + // // TODO 护理中(step==2)时, 如果断开, 可能需要暂停 + // that.setData({ + // facialMaskConnectStatus: 0, + // }); + } + break; + case "Stand": + // that.setData({ + // isStandStatus: + // jsonStatus.connectMessage?.connectType == "CONNECTED", + // }); + + break; + default: + break; + } + break; + //小程序主动问主机,现在链接了哪些附属设备,这时候主机给小程序的回复消息 + case "QueryMatchStatus": + const isStandDevice = + jsonStatus?.subDeviceList?.includes("Stand") || false; + const isConnectedMask = + jsonStatus?.subDeviceList?.includes("WL200") || false; + deviceToolKitInstance = isConnectedMask + ? deviceToolKitInstanceWL200 + : deviceToolKitInstanceWE100; + console.log(isConnectedMask, "更改成功deviceToolKitInstance"); + if (!this.state.checkedMaskVersion && isConnectedMask) { + this.checkVersion(); + } + console.log("支架是否链接", isStandDevice); + console.log("面罩是否链接", isConnectedMask); + //这里bug 先注释掉 bug是拔掉支架之后启动面罩工作就会一直弹 + // let { basicModeList, modelActiveIndex } = that.data; + // if ( + // that.data.step == 2 && + // !isStandDevice && + // basicModeList[modelActiveIndex].isStandMode && + // !that.data.hadShowBreakTips + // ) { + // that.data.hadShowBreakTips = true; + // that.onPauseTap(); + // that.standVideoContext.seek(0); + // // that.showTips('检测到支架未连接成功,请确认面罩开机后与支架连接,并接通支架电源'); + // that.showTips( + // `检测到${that.data.deviceChineseName.WL200Stand}未连接成功,请确认面罩开机后与${that.data.deviceChineseName.WL200Stand}连接,并接通${that.data.deviceChineseName.WL200Stand}电源` + // ); + // 连上面罩后, 设置自定义模式 -- 不在这里设置自定义模式 + if ( + this.state.ActiveModeItem && + isConnectedMask && + !this.state.customModeData.setCustomSuc && + !this.state.customModeData.hadSetCustom && + this.state.ActiveModeItem.isCustomMode + ) { + this.setCustomMaskData(); + } + // 连上面罩后, 获取仪器记录, 与缓存信息对比, + // 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; @@ -355,7 +519,6 @@ class IotCarePlan extends Component { }).then((res) => { Taro.onBLECharacteristicValueChange((value) => { const jsonStatus: any = deviceToolKitInstance.toJsonStatus(value.value); - // end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而已处理流程都一样 console.log( "onBLECharacteristicValueChange jsonStatus => ", jsonStatus @@ -364,151 +527,49 @@ class IotCarePlan extends Component { if (!jsonStatus || jsonStatus == null) { return; } + // end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而已处理流程都一样 if (jsonStatus.workStatus && jsonStatus.workStatus == "endWork") { jsonStatus.workStatus = "end"; - console.log(jsonStatus.workStatus, "改了状态了"); + console.log(jsonStatus.workStatus, "护理结束"); } + + // 指令类型判断 switch (jsonStatus?.commandType) { - //蓝牙相关指令 case "BleMatch": - switch (jsonStatus.bleCommandType) { - //如果设备配对链接发送配对码的时候,设备应答小程序配对码是否正确。 - case "SendMatchCode": - if (jsonStatus.matchedSuccess) { - // msg('配对成功') - console.log("配对成功"); - // log.info(commandMap.WL200Command, "配对成功"); - } - break; - //附属设备状态主动上报,这种指令是主机主动上报某个附属设备断开或者连上了 - case "BleStatusSync": - switch (jsonStatus.connectMessage?.deviceName) { - case "WL200": - if (jsonStatus.connectMessage?.connectType == "CONNECTED") { - // if ( - // !that.data.customModeData.setCustomSuc && - // !that.data.customModeData.hadSetCustom - // ) { - // that.setCustomMaskData(); - // } - // that.setData({ - // facialMaskConnectStatus: 1, - // }); - // this.deviceToolKitInstance = deviceToolKitInstanceWL200; - // console.log( - // "checkedMaskVersion", - // this.data.checkedMaskVersion - // ); - // if (!this.data.checkedMaskVersion) { - // this.checkVersion(); - // } - } else { - // deviceToolKitInstance = deviceToolKitInstanceWE100; - // // TODO 护理中(step==2)时, 如果断开, 可能需要暂停 - // that.setData({ - // facialMaskConnectStatus: 0, - // }); - } - break; - case "Stand": - // that.setData({ - // isStandStatus: - // jsonStatus.connectMessage?.connectType == "CONNECTED", - // }); - - break; - default: - break; - } - break; - //小程序主动问主机,现在链接了哪些附属设备,这时候主机给小程序的回复消息 - case "QueryMatchStatus": - const isStandDevice = - jsonStatus?.subDeviceList?.includes("Stand") || false; - const isConnectedMask = - jsonStatus?.subDeviceList?.includes("WL200") || false; - deviceToolKitInstance = isConnectedMask - ? deviceToolKitInstanceWL200 - : deviceToolKitInstanceWE100; - console.log(isConnectedMask, "更改成功deviceToolKitInstance"); - // if (!this.state.checkedMaskVersion && isConnectedMask) { - // this.checkVersion(); - // } - console.log("支架是否链接", isStandDevice); - console.log("面罩是否链接", isConnectedMask); - //这里bug 先注释掉 bug是拔掉支架之后启动面罩工作就会一直弹 - // let { basicModeList, modelActiveIndex } = that.data; - // if ( - // that.data.step == 2 && - // !isStandDevice && - // basicModeList[modelActiveIndex].isStandMode && - // !that.data.hadShowBreakTips - // ) { - // that.data.hadShowBreakTips = true; - // that.onPauseTap(); - // that.standVideoContext.seek(0); - // // that.showTips('检测到支架未连接成功,请确认面罩开机后与支架连接,并接通支架电源'); - // that.showTips( - // `检测到${that.data.deviceChineseName.WL200Stand}未连接成功,请确认面罩开机后与${that.data.deviceChineseName.WL200Stand}连接,并接通${that.data.deviceChineseName.WL200Stand}电源` - // ); - } - // 连上面罩后, 设置自定义模式 -- 不在这里设置自定义模式 - // if ( - // isConnectedMask && - // !that.data.customModeData.setCustomSuc && - // !that.data.customModeData.hadSetCustom && - // basicModeList[modelActiveIndex].isCustomMode - // ) { - // that.setCustomMaskData(); - // } - // 连上面罩后, 获取仪器记录, 与缓存信息对比, - // 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 - // }); + // 蓝牙相关指令 + this.switchBLEMatch(jsonStatus); break; case "DeviceControl": - console.log("设备控制,给设备发送指令", jsonStatus); + console.log("小程序控制设备,给设备发送指令", jsonStatus); if ( jsonStatus.responseStatus == "OK" && this.state.isSendModeCombination ) { // 发送启动指令 - // this.startCombinationMode() - // const totalTime = this.data.combinationList.reduce((total, item) => { - // return total + minSecToS(item.time) - // }, 0) - // that.setData({ - // showCombinationModeDialog: false, - // combinationModeInfo: { - // time: s_to_hs(totalTime), - // seconds: totalTime, - // }, - // modelActiveIndex: -1, - // currentTime: s_to_hs(totalTime), - // isCurrentModeCombination: true, - // isSendModeCombination: false, - // }) + this.startCombinationMode(); + const totalTime = this.state.combinationList.reduce( + (total, item) => { + return total + minSecToS(item.time); + }, + 0 + ); + + // 设备启动后小程序操作 + this.setState({ + showCombinationModeDialog: false, + combinationModeInfo: { + time: s_to_hs(totalTime), + seconds: totalTime, + }, + modelActiveIndex: -1, + currentTime: s_to_hs(totalTime), + isCurrentModeCombination: true, + isSendModeCombination: false, + }); + setTimeout(() => { + console.log("currentTime", this.state.currentTime); + }); } break; //设备主动上报给小程序的指令 一般是工作状态改变 @@ -523,38 +584,40 @@ class IotCarePlan extends Component { workStatus: jsonStatus.workStatus, workMode: jsonStatus?.workMode, }); - // that.setData({ - // fr200Electricity: jsonStatus.battery, - // matrixElectricity: jsonStatus.matrixBattery, - // workStatus: jsonStatus.workStatus, - // workMode: jsonStatus?.workMode, - // }); + this.setState({ + fr200Electricity: jsonStatus.battery, + matrixElectricity: jsonStatus.matrixBattery, + workStatus: jsonStatus.workStatus, + workMode: jsonStatus?.workMode, + }); // 判断是否在step == 2(护理中) - // if ( - // that.data.step == 2 && - // jsonStatus.workStatus != MODE_WORKING_ENUM.END - // ) { - // that.updateDeviceSyncData({ - // totalWorkingMinutes: jsonStatus.totalWorkingMinutes, - // totalWorkingSeconds: jsonStatus.totalWorkingSeconds, - // }); - // } - // if (jsonStatus.workMode && that.data.step == 2) { - // const { basicModeList, modelActiveIndex } = that.data; - // const item = basicModeList[modelActiveIndex]; - // if ( - // jsonStatus.workMode != WORK_MODE_ENGLISH_NAME[item.model_type] - // ) { - // clearTimeout(loadingTipsTimer); - // that.data.startSettingCountDown = false; - // } - // } + if ( + this.state.step == 2 && + jsonStatus.workStatus !== MODE_WORKING_ENUM.END + ) { + this.updateDeviceSyncData({ + totalWorkingMinutes: jsonStatus.totalWorkingMinutes, + totalWorkingSeconds: jsonStatus.totalWorkingSeconds, + }); + } + if (jsonStatus.workMode && this.state.step == 2) { + const { ActiveModeItem } = this.state; + const item = ActiveModeItem; + if ( + jsonStatus.workMode !== WORK_MODE_ENGLISH_NAME[item.model_type] + ) { + clearTimeout(loadingTipsTimer); + this.setState({ + isShowCountdown: false, + }); + } + } // // 我忘记了为啥要这样传参... 埋坑了... - // this.judgementWorkStatus( - // jsonStatus.workStatus, - // jsonStatus.workMode, - // jsonStatus - // ); + this.judgementWorkStatus( + jsonStatus.workStatus, + jsonStatus.workMode, + jsonStatus + ); if (jsonStatus.workMode && this.state.step == 2) { // this.judgementModel(jsonStatus.workMode); // that.data.startSettingCountDown = false; @@ -563,52 +626,55 @@ class IotCarePlan extends Component { //设备信息查询返回 case "InfoQuery": switch (jsonStatus.infoQueryType) { + // 自定义模式设置 case "customModeSet": console.log( - "responseStatus=====>", - jsonStatus.responseStatus, - 1 - ); - console.log( - "responseStatus=====>", - jsonStatus.responseStatus, - 2 + "InfoQuery customModeSet responseStatus=====>", + jsonStatus ); - console.log( - "responseStatus=====>", - jsonStatus.responseStatus, - 3 - ); - // if (jsonStatus.responseStatus == "OK") { - // that.setData({ - // "customModeData.setCustomSuc": true, - // }); - // console.log("设置成功自定义模式"); - // } else { - // that.setData({ - // "customModeData.hadSetCustom": false, - // "customModeData.setCustomSuc": false, - // }); - // } + let { customModeData } = this.state; + + if (jsonStatus.responseStatus == "OK") { + customModeData.setCustomSuc = true; + this.setState({ + customModeData, + }); + console.log("设置成功自定义模式"); + } else { + customModeData.hadSetCustom = false; + customModeData.setCustomSuc = false; + this.setState({ + customModeData, + }); + } break; + // 自定义模式信息 case "customModeInfo": + console.log( + "InfoQuery customModeInfo responseStatus=====>", + jsonStatus + ); break; case "versionInfo": + console.log( + "InfoQuery versionInfo responseStatus=====>", + jsonStatus + ); if (jsonStatus.versionNo) { // 清理计时器 - // if (checkVersionTimeout) clearTimeout(checkVersionTimeout); - // if (that.data.hasVersion) return; - // that.setData({ - // hasVersion: true, - // }); - // this.checkOta(jsonStatus.versionNo); + if (checkVersionTimeout) clearTimeout(checkVersionTimeout); + if (this.state.hasVersion) return; + this.setState({ + hasVersion: true, + }); + this.checkOta(jsonStatus.versionNo); } break; // 当前报告 case "currentMaskReportInfo": console.log("currentMaskReportInfo", jsonStatus); - // if (!that.data.hadCheckReport) { - // that.data.hadCheckReport = true; + // if (!this.state.hadCheckReport) { + // this.state.hadCheckReport = true; // that.checkInstrumentRecord(jsonStatus); // } else { // that.setWL200NursingHistory(jsonStatus); @@ -653,9 +719,731 @@ class IotCarePlan extends Component { }); }; + // 检查版本 + checkVersion = () => { + this.sendCheckVersion(); + this.setState({ + checkedMaskVersion: 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({ + askedOta: true, + // currentShowDialog: 'offlineDialog', + }); + // this.confirmOta(); + } + }; + + // 发送启动组合模式指令 + startCombinationMode() { + const jsonCommand = { + commandType: "DeviceControl", + workStatus: "working", + workMode: "MaskCustom", + }; + let commandBuffer = deviceToolKitInstance.toBleCommand(jsonCommand as any); + sendCommand({ + value: commandBuffer, + }).then(() => { + console.info("发送启动组合模式指令成功 参数为 =>", jsonCommand); + }); + } + + //待完善,以后同步设备数据到小程序的事件,在这个事件里判断是否需要更新页面(是否需要触发setData) + updateDeviceSyncData = (newData) => { + DeviceSyncData = { + ...DeviceSyncData, + ...newData, + }; + if (newData.hasOwnProperty("totalWorkingSeconds")) { + this.renderDeviceStatus.renderWorkTime(); + } + }; + + // 待完善,以后更新页面状态的方法,在这里执行setData + renderDeviceStatus = { + renderWorkTime() { + // const that = this; + const { totalWorkingMinutes, totalWorkingSeconds } = DeviceSyncData; + const { ActiveModeItem, currentTime } = this.state; + const totalTime = totalWorkingMinutes * 60 + totalWorkingSeconds; + console.log("仪器上报的已经运行的总秒数", totalTime); + // console.log('时间校准频率,默认5秒一次',TIME_CALIBRATION_FREQUENCY) + //对比仪器上报运行的总秒数 和小程序页面运行的已经运行的总秒数,如果不一致就进行校准 + const currentScene = ActiveModeItem; // 获取当前的场景 + let sceneTime = minSecToS(currentScene.time); // 场景时间 + + const timeRemaining = sceneTime - minSecToS(currentTime); // 小程序上已运行的总秒数 + if ( + Math.abs(timeRemaining - totalTime) >= 2 && + this.state.step == 2 && + this.state.facialMaskConnectStatus == 1 + ) { + this.setTimer(); + const t = sceneTime - totalTime; // 场景时间 - 已运行时间 = 剩余时间 + let { ActiveModeItem } = this.state; + ActiveModeItem.seconds = t; //修复时间跳变的问题 + this.setState({ + currentTime: s_to_hs(t), + ActiveModeItem, + }); + } + }, + }; + + // 仪器开始倒计时 + setLoadingTips(time) { + this.setState({ + countdown: time, + }); + if (time >= 0) { + loadingTipsTimer = setTimeout(() => { + this.setLoadingTips(--time); + }, 1000); + } else { + // 停止倒计时 + // that.data.startSettingCountDown = false; + this.setState({ + isShowCountdown: false, + }); + } + } + + // 设备上报不同状态 + judgementWorkStatus(nWorkStatus, nWorkMode, jsonStatus) { + const { + workStatus, + step, + isStandStatus, + workMode, + ActiveModeItem, + ModeList, + } = this.state; + const opts: any = {}; + // ActiveModeItem + const modeItem = ActiveModeItem; + let nowModeItem; + if (nWorkMode) { + const nowModeType = WORK_MODE_TYPE[nWorkMode]; + nowModeItem = ModeList.find((item) => { + return item.model_type == nowModeType; + }); + } + opts.workStatus = nWorkStatus; + const statusF = { + sleep: () => { + this.setState({ + isShowCountdown: false, + }); + }, + standby: () => { + this.setState({ + isShowCountdown: false, + }); + if (nowModeItem?.isStandMode && step == 2) { + opts.currentTime = nowModeItem.time; + } else if (!nowModeItem?.isStandMode && step == 2) { + // fix: 启动非支架模式倒计时时,连上支架,仪器的状态变为standby + opts.step = 1; + } + if (loadingTipsTimer) { + clearTimeout(loadingTipsTimer); + } + // 本来用于更新时间的,但是产生了 ID1000367 bug,先移除 + // if (nowModeItem) { + // opts.currentTime = nowModeItem.time; + // } + }, + setting: () => { + // that.data.hadShowBreakTips = false; + this.setState({ + hadShowBreakTips: false, + }); + if (step != 2 && !modeItem.isStandMode) { + opts.step = 2; + this.setState({ + title: "正在护理", + isStopNurse: false, + }); + // Taro.setNavigationBarTitle({ + // title: "正在护理", + // }); + // 处理音乐 + this.musicStatusChange(); + } else if (step != 2 && modeItem.isStandMode) { + opts.step = 2; + // this.setState({ + // title: "正在护理", + // }); + this.setState({ + title: "正在护理", + isStopNurse: false, + }); + } + if (nowModeItem) { + opts.currentTime = nowModeItem.time; + } + // startSettingCountDown 用于标记打开了倒计时loading + if (!this.state.isShowCountdown) { + this.setState({ + isShowCountdown: true, + }); + this.setLoadingTips(CountDownTime[workMode] || 6); + } + }, + working: () => { + if (this.state.facialMaskConnectStatus != 1) { + opts.workStatus = MODE_WORKING_ENUM.STANDBY; + opts.step = 1; + } else if (step != 2) { + opts.step = 2; + this.setState({ + title: "正在护理", + isStopNurse: false, + }); + // 处理音乐 + // this.musicStatusChange(); + } + // else if (modeItem?.isStandMode) { + // 支架模式也使用gif图, 不需要播放视频了, 所以注释 + // that.onPlayTap(); + // } + + this.setState({ + isShowCountdown: false, + hadShowBreakTips: false, + }); + }, + pause: () => { + this.setState({ + isShowCountdown: false, + }); + if (modeItem.isStandMode) { + // this.onPauseTap(); + this.setState({ + title: "暂停护理", + isStopNurse: true, + }); + } + }, + end: () => { + // 仪器返回护理结束, 支架模式不需要了 + // if (modeItem.isStandMode) { + // that.onPauseTap(); + // } + // 已进入了报告阶段, 防止重复进入, 主要防止在手动点击结束护理接收到仪器消息 + if (this.state.endPlace) return; + // 获取仪器运行时间,更新currentTime, 判断仪器返回时间正常的情况下 + const { totalWorkingSeconds, totalWorkingMinutes } = jsonStatus; + if (totalWorkingSeconds != 0 || totalWorkingMinutes != 0) { + const sceneTime = minSecToS(modeItem.currentTime); // 模式的总时长 + const runTime = totalWorkingMinutes * 60 + totalWorkingSeconds; //仪器运行时长 + const timeRemaining = sceneTime - runTime; // 剩余未运行时间 + this.setState({ + currentTime: s_to_hs(timeRemaining), + }); + } + this.endnursing(null, true); + this.rmWL200NursingHistory(this.state.WL200NursingHistory); + }, + }; + statusF[nWorkStatus] && statusF[nWorkStatus](); + if (Object.keys(opts).length) { + this.setState(opts); + } + } + + /** + * 保存护理报告 + * 1.是否跳转 2.数据 + * */ + saveNurseReport = async (isJump = true, from) => { + const { isStandStatus, standInfo, ActiveModeItem, options } = this.state; + const currentScene = ActiveModeItem; + let sceneTime = minSecToS(currentScene.time); + const timeRemaining = sceneTime - minSecToS(this.state.currentTime); + const form = { + second: timeRemaining, + screne_id: currentScene.screne_id, + screne_name: currentScene.screne_name, + instrument_id: options?.devId, + report: JSON.stringify({ + positionRatio: Math.floor((timeRemaining / sceneTime) * 100), + }), + }; + // log.info(commandMap.WL200Command, '保存护理报告saveNurseReport', '来自方法from:' + from, '护理时间timeRemaining:'+timeRemaining); + console.log("timeRemaining=>", timeRemaining); + console.log("currentScene=>", currentScene); + console.log("form=>", form); + // const { data } = await UserNursingLogAdd(form) + // // 清除缓存 + // that.rmWL200NursingHistory(that.data.WL200NursingHistory, true); + // if (data.code == 200 && isJump) { + // that.setData({ + // showNurseSuccess: true + // }); + // setTimeout(()=>{ + // wx.redirectTo({ url: `/pages/MatrixWL200/pages/nursingRecord/nursingRecord?instrument_id=${options?.devId}&id=${data.data}` }) + // }, 2000); + // } + }; + + /** + * 结束护理 + * param isAuto 是否仪器自动结束 + */ + endnursing(e, isAuto) { + if (isAuto == true) { + // 仪器自动上报完成, 直接上报并跳转报告页 + clearInterval(timer); + const isEnough = this.checkTime(); + if (isEnough && !this.state.endPlace) { + this.setState({ + endPlace: "report", + }); + this.saveNurseReport(true, "endnursing"); + } + // this.handleTimeCheck(that.endNurseFun) + } else { + // 手动点击结束, 弹出弹窗, 看看是否需要结束 + this.setState({ + popupType: "endPopup", + }); + /*showModal({ + t2: "是否结束护理?", + }).then(async () => { + this.handleTimeCheck(that.endNurseFun) + });*/ + } + } + + setCustomModeData() { + const { basicModeList, modelActiveIndex, currentTime } = that.data; + const modeItem = basicModeList[modelActiveIndex]; + const group = modeItem.group; + if (group.length == 1) return; // 只有1项不用管 + + let inTimeScopeIndex = -1; // 选择的index + group.forEach((item, index) => { + let startMinute = item.scope[0]; + let endMinute = item.scope[1]; + let targetMinute = currentTime.split(":")[0]; + let targetSecond = currentTime.split(":")[1]; + const isInTime = this.isInTimeScope( + startMinute, + endMinute, + targetMinute, + targetSecond + ); + if (isInTime) inTimeScopeIndex = index; + }); + if (modeItem.timeScopeIndex !== inTimeScopeIndex) { + // this.setState({ + // [`basicModeList[${modelActiveIndex}].timeScopeIndex`]: inTimeScopeIndex, + // [`basicModeList[${modelActiveIndex}].desc`]: group[inTimeScopeIndex].desc, + // [`basicModeList[${modelActiveIndex}].technique`]: group[inTimeScopeIndex].technique, + // [`basicModeList[${modelActiveIndex}].pause_img`]: group[inTimeScopeIndex].pause_img, + // [`basicModeList[${modelActiveIndex}].running_img`]: group[inTimeScopeIndex].running_img, + // }) + } + } + 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; + } + + setTimer() { + // 切换模式后, 需要重新设置计时器, 以防进行中的计时器 + timer && clearInterval(timer); + timer = setInterval(() => { + if ( + this.state.workStatus == MODE_WORKING_ENUM.WORKING && + this.state.step == 2 && + this.state.facialMaskConnectStatus == 1 + ) { + /*if(that.data.workMode !== WORK_MODE_NAME_ENUM.POWERFULSOOTHING){*/ + let currentSeconds; + if (this.state.isCurrentModeCombination) { + // 组合模式逻辑 + // that.data.combinationModeInfo.seconds -= 1; + // that.setData({ + // currentTime: s_to_hs(that.data.combinationModeInfo.seconds) + // }) + // currentSeconds = that.data.combinationModeInfo.seconds + } else { + const { ActiveModeItem, currentTime } = this.state; + currentSeconds = minSecToS(currentTime); + this.setState({ + currentTime: s_to_hs(--currentSeconds), + }); + console.log(ActiveModeItem.isCustomMode); + if (ActiveModeItem.isCustomMode) { + this.setCustomModeData(); + } + } + if (currentSeconds <= 0) { + clearInterval(timer); + // 统一接收仪器结束指令 + // that.data.endPlace = 'report'; + // that.saveNurseReport(true, 'setTimer'); + } + /*} else { + that.data.standInfo.seconds -= 1; + that.setData({ currentTime: s_to_hs(that.data.standInfo.seconds) }) + if(that.data.standInfo.seconds <= 0){ + clearInterval(timer); + this.showNurseSuccessDialog() + } + }*/ + } + }, 1000); + } + + // 工作状态 + handleWorkStatus = (_, workStatus) => { + const { facialMaskConnectStatus, isStandStatus, ActiveModeItem } = + this.state; + const modeItem = ActiveModeItem; + let newWorkStatus = + workStatus || + (this.state.workStatus == MODE_WORKING_ENUM.WORKING + ? "pause" + : "working"); + if (_ && newWorkStatus == "working") { + if (modeItem.modeClass === 2 && !isStandStatus) { + this.showTips( + `检测到${this.state.deviceChineseName.WL200Stand}未连接成功,请确认面罩开机后与${this.state.deviceChineseName.WL200Stand}连接,并接通${this.state.deviceChineseName.WL200Stand}电源` + ); + return; + } + if (!modeItem.isStandMode && facialMaskConnectStatus != 1) { + this.showTips("检测到面罩未连接成功,请确认面罩开机并佩戴"); + return; + } + } + const curModeData = ActiveModeItem; + const sendParams = { + ...deviceCommandSamples.pause, + workMode: WORK_MODE_ENGLISH_NAME[curModeData.model_type], + workStatus: newWorkStatus, + }; + const pauseArrayBuffer = deviceToolKitInstance.toBleCommand( + sendParams as any + ); + sendCommand({ + value: pauseArrayBuffer, + }).then(() => { + this.setState({ + workStatus: newWorkStatus, + }); + this.setTimer(); + // 支架模式, 暂停, 需暂停视频播放 + if (newWorkStatus == MODE_WORKING_ENUM.PAUSE && modeItem.isStandMode) { + this.onPauseTap(); + } + // 支架模式, 开始播放, 需播放视频 + if (newWorkStatus == MODE_WORKING_ENUM.WORKING && modeItem.isStandMode) { + this.onPlayTap(); + } + console.info( + `handleWorkStatus 发送${newWorkStatus}指令成功 参数为 =>`, + sendParams + ); + }); + }; + + /** + * 点击开始护理 + */ + onNursingTap() { + // 防止多次点击 + if (this.state.hadClickStart) return; + this.setState({ + hadClickStart: true, + }); + setTimeout(() => { + this.setState({ + hadClickStart: false, + }); + }, 500); + const { + ActiveModeItem, + workStatus, + isStandStatus, + facialMaskConnectStatus, + customModeData, + } = this.state; + const modelActiveItem = ActiveModeItem; + // log.info( + // commandMap.WL200Command, + // "点击开始护理按钮", + // `当前模式: ${modelActiveIndex}`, + // `当前面罩状态:${facialMaskConnectStatus}`, + // `当前仪器模式:${workStatus}` + // ); + console.info( + commandMap.WL200Command, + "点击开始护理按钮", + `当前模式: ${ActiveModeItem}`, + `当前面罩状态:${facialMaskConnectStatus}`, + `当前仪器模式:${workStatus}` + ); + console.log(modelActiveItem); + console.log("isStandStatus:" + isStandStatus); + console.log( + workStatus !== MODE_WORKING_ENUM.WORKING && + workStatus !== MODE_WORKING_ENUM.STANDBY && + workStatus !== MODE_WORKING_ENUM.PAUSE + ); + + if (facialMaskConnectStatus != 1) { + this.showTips("检测到面罩未连接成功,请确认面罩开机并佩戴"); + return; + } + if ( + workStatus !== MODE_WORKING_ENUM.WORKING && + workStatus !== MODE_WORKING_ENUM.STANDBY && + workStatus !== MODE_WORKING_ENUM.PAUSE + ) { + this.showTips("检测到面罩未连接成功,请确认面罩开机并佩戴"); + return; + } + // 如果是强效舒缓,需要判断是否连接支架 + if (modelActiveItem.isStandMode && !isStandStatus) { + this.showTips( + `检测到${this.state.deviceChineseName.WL200Stand}未连接成功,请确认面罩开机后与${this.state.deviceChineseName.WL200Stand}连接,并接通${this.state.deviceChineseName.WL200Stand}电源` + ); + // that.showTips('检测到支架未连接成功,请确认面罩开机后与支架连接,并接通支架电源'); + return; + } else if (!modelActiveItem.isStandMode && isStandStatus) { + this.showTips( + `检测到面罩仍和${this.state.deviceChineseName.WL200Stand}连接中,请分离后切换` + ); + return; + } + if (modelActiveItem.isCustomMode && !customModeData.setCustomSuc) { + this.showTips( + `${modelActiveItem.nursing_name}模式设置失败,请联系小助手` + ); + return; + } + // 开始执行护理 + this.handleWorkStatus(null, MODE_WORKING_ENUM.WORKING); + } + + // 结束护理? + endNurseFun() { + // this.handleWorkStatus(null, "end"); + 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); + } + + /** + * 音乐暂停播放时间 + */ + musicStatusChange() { + const { step, ActiveModeItem } = this.state; + const modeItem = ActiveModeItem; + this.setState({ + musicStatus: !this.state.musicStatus, + }); + // if (step == 2 && !modeItem.isStandMode) { + // if (this.state.musicStatus) { + // this.state.innerAudioContext?.play(); // 播放 + // } else { + // this.state.innerAudioContext?.pause(); //暂停 + // } + // } + } + // 检查时间是否达标 + checkTime() { + const { curDeviceInfo, workStatus, ActiveModeItem } = this.state; + const currentScene = ActiveModeItem; + let sceneTime = minSecToS(currentScene.time); + const timeRemaining = sceneTime - minSecToS(this.state.currentTime); + if (timeRemaining >= Number(curDeviceInfo?.times) * 60) { + return true; + } else { + return false; + } + } + + // 开始护理? + onPlayTap() { + const { ActiveModeItem, step } = this.state; + const modeItem = ActiveModeItem; + if (step == 1) { + this.state.videoContext.play(); + this.setState({ + showVideoPlayBtn: false, + }); + } else if (modeItem.isStandMode && step == 2) { + this.setState({ + standVideoContext: Taro.createVideoContext("standVideo"), + }); + setTimeout(() => { + this.state.standVideoContext.play(); + }, 100); + } + } + // 暂停护理? + onPauseTap() { + const { ActiveModeItem, step } = this.state; + const modeItem = ActiveModeItem; + if (step == 1) { + } else if (modeItem.isStandMode && step == 2) { + this.setState({ + standVideoContext: Taro.createVideoContext("standVideo"), + }); + setTimeout(() => { + this.state.standVideoContext.play(); + }, 100); + } + } + + // 删除WL200护理历史 + rmWL200NursingHistory(WL200NursingHistory, hard = false) { + const nowWL200NursingHistory = Taro.getStorageSync("WL200NursingHistory"); + if (nowWL200NursingHistory.id == WL200NursingHistory.id) { + Taro.removeStorageSync("WL200NursingHistory"); + } else if (hard) { + Taro.removeStorageSync("WL200NursingHistory"); + } + } + + //蓝牙断开连接处理 + bluetoothDisconnectProcessing() { + clearInterval(timer); + Taro.offBLEConnectionStateChange(this.listener); // 需传入与监听时同一个的函数对象 + // this.state.innerAudioContext.destroy(); + Taro.offBLECharacteristicValueChange((res) => { + console.log("offBLECharacteristicValueChange", res); + }); + if (!this.state.isToOTA) { + Taro.closeBluetoothAdapter(); + } + } + + /* 组合模式 */ + setCustomMaskData() { + console.log("================"); + console.log("setCustomMaskData"); + console.log("================"); + const { customModeData, ActiveModeItem } = this.state; + const customItem = ActiveModeItem; + if (!customItem.isCustomMode) { + let { customModeData } = this.state; + customModeData.hadSetCustom = false; + customModeData.setCustomSuc = false; + this.setState({ + customModeData, + }); + return; + } + if ( + !customModeData.setCustomSuc && + customItem && + !customModeData.hadSetCustom + ) { + this.state.customModeData.hadSetCustom = true; + // 设置组 + let customModeSetCommand = customItem.customModeSetCommand; + console.log("自定义模式:", customModeSetCommand); + // log.info('自定义模式:', customModeSetCommand); + let commandBuffer = + deviceToolKitInstanceWL200.toBleCommand(customModeSetCommand); + sendCommand({ + value: commandBuffer, + }).then((res) => { + console.info("发送切换组合模式指令成功", res); + }); + } + } + + showTips(ctx) { + if (!ctx) return; + if (showTipsTimer) clearTimeout(showTipsTimer); + this.setState({ + errorTips: ctx, + }); + showTipsTimer = setTimeout(() => { + this.setState({ + errorTips: "", + }); + }, 2000); + } + render() { let { name, + title, isMusicPlay, isShowStepTips, ModeList, @@ -668,10 +1456,11 @@ class IotCarePlan extends Component { countdown, ModeStepIndex, Electricity, + errorTips, } = this.state; return ( - + {ActiveModeItem.openSourceData && ( { )} + + {errorTips && ( + + + + {{ errorTips }} + + + )} @@ -787,6 +1589,7 @@ class IotCarePlan extends Component { diff --git a/src/utils/request.js b/src/utils/request.js index 829b354..f94f0a9 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -69,10 +69,10 @@ export const Ajax = (params) => { } if (res.data.code === 500) { - let msg = - typeof res.data.msg == "string" - ? res.data.msg - : "系统异常,请联系管理人员"; + let msg = "系统异常,请联系管理人员"; + // typeof res.data.msg == "string" + // ? res.data.msg + // : "系统异常,请联系管理人员"; if (msg == "请不要操作太快哦") { reject(res); return false; diff --git a/src/utils/util.js b/src/utils/util.js index 6920a7b..a91ac37 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -4,51 +4,55 @@ * @return {boolean} */ const isVideo = (path) => { - return /\.(mp4|avi|wmv|mpg|mpeg|mov|rm|ram|swf|flv)/.test(path); -} + return /\.(mp4|avi|wmv|mpg|mpeg|mov|rm|ram|swf|flv)/.test(path); +}; /** * @description 图片预览 * @param url data-url="{url}" */ -const previewImage = ({currentTarget: {dataset: { url }}}) => { - if (!url) return; - if (url.indexOf('http') === -1 || url.indexOf('https') === -1) { - url = 'https://oss.flossom.com' + url; - } - wx.previewImage({ - urls: [url] - }) +const previewImage = ({ + currentTarget: { + dataset: { url }, + }, +}) => { + if (!url) return; + if (url.indexOf("http") === -1 || url.indexOf("https") === -1) { + url = "https://oss.flossom.com" + url; + } + wx.previewImage({ + urls: [url], + }); }; const formatTime = (date) => { - const year = date.getFullYear(); - const month = date.getMonth() + 1; - const day = date.getDate(); - const hour = date.getHours(); - const minute = date.getMinutes(); - const second = date.getSeconds(); - - return `${[year, month, day].map(formatNumber).join("/")} ${[ - hour, - minute, - second, - ] - .map(formatNumber) - .join(":")}`; + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const hour = date.getHours(); + const minute = date.getMinutes(); + const second = date.getSeconds(); + + return `${[year, month, day].map(formatNumber).join("/")} ${[ + hour, + minute, + second, + ] + .map(formatNumber) + .join(":")}`; }; const formatNumber = (n) => { - n = n.toString(); - return n[1] ? n : `0${n}`; + n = n.toString(); + return n[1] ? n : `0${n}`; }; const setdata = (that, key, value) => { - that.setData({ - [key]: value, - }); + that.setData({ + [key]: value, + }); }; const filertext = (text) => { - return text.replace(/{/g, "").replace(/}/, "").replace(/"/g, ""); + return text.replace(/{/g, "").replace(/}/, "").replace(/"/g, ""); }; /** @@ -61,42 +65,45 @@ const filertext = (text) => { * @returns {void|string|*} */ const formatRichText = (html) => { - let newContent = html.replace(/]*>/gi, (match) => { - match = match.replace(/style="[^"]+"/gi, '') - return match; - }); - newContent = newContent.replace(/style="[^"]+"/gi, (match) => { - match = match.replace(/width:[^;]+;/gi, 'max-width:100%!important;') - return match; - }); - newContent = newContent.replace(/\]*>/gi, (match) => { + match = match.replace(/style="[^"]+"/gi, ""); + return match; + }); + newContent = newContent.replace(/style="[^"]+"/gi, (match) => { + match = match.replace(/width:[^;]+;/gi, "max-width:100%!important;"); + return match; + }); + newContent = newContent.replace( + /\ { - const year = new Date().getFullYear(); - const month = new Date().getMonth() + 1; - const day = new Date().getDate(); - return ( - year + - "-" + - String(month).padStart("2", 0) + - "-" + - String(day).padStart("2", 0) - ); + const year = new Date().getFullYear(); + const month = new Date().getMonth() + 1; + const day = new Date().getDate(); + return ( + year + + "-" + + String(month).padStart("2", 0) + + "-" + + String(day).padStart("2", 0) + ); }; const getdates = (date) => { - date = date.replace(/-/g, '/'); // 部分iphone new Date不兼容[2023-01-01]格式,需要转换 - const year = new Date(date).getFullYear(); - const month = new Date(date).getMonth() + 1; - const day = new Date(date).getDate(); - const hour = new Date(date).getHours(); - const minute = new Date(date).getMinutes(); - const second = new Date(date).getSeconds(); - - // return `${[year, month, day].map(formatNumber).join('-')} ${[hour, minute, second].map(formatNumber).join(':')}` - return `${[year, month, day].map(formatNumber).join("-")}`; + date = date.replace(/-/g, "/"); // 部分iphone new Date不兼容[2023-01-01]格式,需要转换 + const year = new Date(date).getFullYear(); + const month = new Date(date).getMonth() + 1; + const day = new Date(date).getDate(); + const hour = new Date(date).getHours(); + const minute = new Date(date).getMinutes(); + const second = new Date(date).getSeconds(); + + // return `${[year, month, day].map(formatNumber).join('-')} ${[hour, minute, second].map(formatNumber).join(':')}` + return `${[year, month, day].map(formatNumber).join("-")}`; }; /** @@ -104,16 +111,16 @@ const getdates = (date) => { * @returns {string} 例如 2019-01-01~2019-12-31 */ const getYearFirstLastDay = () => { - let firstDay = new Date(); - firstDay.setDate(1); - firstDay.setMonth(0); - let lastDay = new Date(); - lastDay.setFullYear(lastDay.getFullYear() + 2); - lastDay.setDate(0); - lastDay.setMonth(-1); - firstDay = firstDay.Format("yyyy-MM-dd"); - lastDay = lastDay.Format("yyyy-MM-dd"); - return lastDay; + let firstDay = new Date(); + firstDay.setDate(1); + firstDay.setMonth(0); + let lastDay = new Date(); + lastDay.setFullYear(lastDay.getFullYear() + 2); + lastDay.setDate(0); + lastDay.setMonth(-1); + firstDay = firstDay.Format("yyyy-MM-dd"); + lastDay = lastDay.Format("yyyy-MM-dd"); + return lastDay; }; //日期格式化方法Format()方法 @@ -125,27 +132,27 @@ const getYearFirstLastDay = () => { // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2018-07-02 08:09:04.423 // (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2018-7-2 8:9:4.18 Date.prototype.Format = function (fmt) { - var o = { - "M+": this.getMonth() + 1, //月份 - "d+": this.getDate(), //日 - "h+": this.getHours(), //小时 - "m+": this.getMinutes(), //分 - "s+": this.getSeconds(), //秒 - "q+": Math.floor((this.getMonth() + 3) / 3), //季度 - S: this.getMilliseconds(), //毫秒 - }; - if (/(y+)/.test(fmt)) - fmt = fmt.replace( - RegExp.$1, - (this.getFullYear() + "").substr(4 - RegExp.$1.length) - ); - for (var k in o) - if (new RegExp("(" + k + ")").test(fmt)) - fmt = fmt.replace( - RegExp.$1, - RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) - ); - return fmt; + var o = { + "M+": this.getMonth() + 1, //月份 + "d+": this.getDate(), //日 + "h+": this.getHours(), //小时 + "m+": this.getMinutes(), //分 + "s+": this.getSeconds(), //秒 + "q+": Math.floor((this.getMonth() + 3) / 3), //季度 + S: this.getMilliseconds(), //毫秒 + }; + if (/(y+)/.test(fmt)) + fmt = fmt.replace( + RegExp.$1, + (this.getFullYear() + "").substr(4 - RegExp.$1.length) + ); + for (var k in o) + if (new RegExp("(" + k + ")").test(fmt)) + fmt = fmt.replace( + RegExp.$1, + RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) + ); + return fmt; }; /** @@ -153,10 +160,10 @@ Date.prototype.Format = function (fmt) { * ArrayBuffer转16进制字符串 */ const ab2hex = (buffer) => { - var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) { - return ("00" + bit.toString(16)).slice(-2); - }); - return hexArr.join(""); + var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) { + return ("00" + bit.toString(16)).slice(-2); + }); + return hexArr.join(""); }; /** @@ -164,371 +171,385 @@ const ab2hex = (buffer) => { * */ const hex2int = (hex) => { - var len = hex.length, - a = new Array(len), - code; - for (var i = 0; i < len; i++) { - code = hex.charCodeAt(i); - if (48 <= code && code < 58) { - code -= 48; - } else { - code = (code & 0xdf) - 65 + 10; - } - a[i] = code; + var len = hex.length, + a = new Array(len), + code; + for (var i = 0; i < len; i++) { + code = hex.charCodeAt(i); + if (48 <= code && code < 58) { + code -= 48; + } else { + code = (code & 0xdf) - 65 + 10; } + a[i] = code; + } - return a.reduce(function (acc, c) { - acc = 16 * acc + c; - return acc; - }, 0); + return a.reduce(function (acc, c) { + acc = 16 * acc + c; + return acc; + }, 0); }; const keywordTofilter = (str) => { - let arr = []; - for (let i = 0, len = str.length; i < len; i += 2) { - arr.push(str.slice(i, i + 2)); + let arr = []; + for (let i = 0, len = str.length; i < len; i += 2) { + arr.push(str.slice(i, i + 2)); + } + for (let i = 0; i < arr.length; i++) { + if (i == 0 || i == arr.length - 1) { + continue; } - for (let i = 0; i < arr.length; i++) { - if (i == 0 || i == arr.length - 1) { - continue; - } - if (arr[i] == "db") { - arr[i] = "dccb"; - } - if (arr[i] == "dc") { - arr[i] = "dccc"; - } - if (arr[i] == "de") { - arr[i] = "dcce"; - } + if (arr[i] == "db") { + arr[i] = "dccb"; + } + if (arr[i] == "dc") { + arr[i] = "dccc"; } - return arr.join(""); + if (arr[i] == "de") { + arr[i] = "dcce"; + } + } + return arr.join(""); }; const filterData = (str) => { - let data = str - .replace(/dccc/g, "dc") - .replace(/dccb/g, "db") - .replace(/dcce/g, "de"); - return data; + let data = str + .replace(/dccc/g, "dc") + .replace(/dccb/g, "db") + .replace(/dcce/g, "de"); + return data; }; const filterBleData = (str) => { - let arr = []; - let arr2 = []; - let arr3 = []; - for (let i = 0, len = str.length; i < len; i += 2) { - arr.push(str.slice(i, i + 2)); + let arr = []; + let arr2 = []; + let arr3 = []; + for (let i = 0, len = str.length; i < len; i += 2) { + arr.push(str.slice(i, i + 2)); + } + let index = 0; + arr.map((item, i) => { + if (item == "dc") { + if (i + 1 !== arr.length - 1) { + arr2[index].push("d" + arr[i + 1].substring(1, 2)); + } + return false; } - let index = 0; - arr.map((item, i) => { - if (item == "dc") { - if (i + 1 !== arr.length - 1) { - arr2[index].push("d" + arr[i + 1].substring(1, 2)); - } - return false; - } - if (item == "de") { - arr2[index] = arr2[index].join(""); - index += 1; - } else { - if (!Array.isArray(arr2[index])) { - arr2[index] = []; - } - if (i !== 0) { - if (arr[i - 1] !== "dc") { - arr2[index].push(item); - } - } + if (item == "de") { + arr2[index] = arr2[index].join(""); + index += 1; + } else { + if (!Array.isArray(arr2[index])) { + arr2[index] = []; + } + if (i !== 0) { + if (arr[i - 1] !== "dc") { + arr2[index].push(item); } - }); - arr2.map((item) => { - // console.log(ccrc8('db'+item.substring(0,item.length-2)) , item.substring(item.length-2,item.length)) - if ( - ccrc8("db" + item.substring(0, item.length - 2)) == - item.substring(item.length - 2, item.length) - ) { - arr3.push("db" + item + "de"); - } - }); - return arr3; + } + } + }); + arr2.map((item) => { + // console.log(ccrc8('db'+item.substring(0,item.length-2)) , item.substring(item.length-2,item.length)) + if ( + ccrc8("db" + item.substring(0, item.length - 2)) == + item.substring(item.length - 2, item.length) + ) { + arr3.push("db" + item + "de"); + } + }); + return arr3; }; const ccrc8 = (str) => { - let arr = []; - for (let i = 0, len = str.length; i < len; i += 2) { - arr.push("0x" + str.slice(i, i + 2)); - } - const crc8_854_table = [ - 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, - 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, - 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, - 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, - 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, - 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, - 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, - 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, - 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, - 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, - 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, - 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, - 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, - 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, - 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, - 247, 182, 232, 10, 84, 215, 137, 107, 53, - ]; - let crc = new Uint8Array(1); - crc = 0; - for (let i = 0; i < arr.length; i++) { - crc = crc8_854_table[crc ^ (arr[i] & 0xff & 0xff)]; - } - return (crc & 0xff).toString(16).padStart("2", 0); + let arr = []; + for (let i = 0, len = str.length; i < len; i += 2) { + arr.push("0x" + str.slice(i, i + 2)); + } + const crc8_854_table = [ + 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, + 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, + 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, + 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, + 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, + 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, + 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, + 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, + 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, + 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, + 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, + 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, + 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, + 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, + 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, + 247, 182, 232, 10, 84, 215, 137, 107, 53, + ]; + let crc = new Uint8Array(1); + crc = 0; + for (let i = 0; i < arr.length; i++) { + crc = crc8_854_table[crc ^ (arr[i] & 0xff & 0xff)]; + } + return (crc & 0xff).toString(16).padStart("2", 0); }; +/** 秒数转分秒,返回分秒 */ const s_to_hs = (s) => { - //计算分钟 - //算法:将秒数除以60,然后下舍入,既得到分钟数 - var h; - h = Math.floor(s / 60); - //计算秒 - //算法:取得秒%60的余数,既得到秒数 - s = s % 60; - //将变量转换为字符串 - h += ""; - s += ""; - //如果只有一位数,前面增加一个0 - h = h.length == 1 ? "0" + h : h; - s = s.length == 1 ? "0" + s : s; - return h + ":" + s; + //计算分钟 + //算法:将秒数除以60,然后下舍入,既得到分钟数 + var h; + h = Math.floor(s / 60); + //计算秒 + //算法:取得秒%60的余数,既得到秒数 + s = s % 60; + //将变量转换为字符串 + h += ""; + s += ""; + //如果只有一位数,前面增加一个0 + h = h.length == 1 ? "0" + h : h; + s = s.length == 1 ? "0" + s : s; + return h + ":" + s; }; +/** 秒数转分钟,只返回分钟 */ const s_to_h = (s) => { - //计算分钟 - //算法:将秒数除以60,然后下舍入,既得到分钟数 - var h; - h = Math.floor(s / 60); - //计算秒 - //算法:取得秒%60的余数,既得到秒数 - s = s % 60; - //将变量转换为字符串 - h += ""; - s += ""; - //如果只有一位数,前面增加一个0 - h = h.length == 1 ? "0" + h : h; - s = s.length == 1 ? "0" + s : s; - return h; + //计算分钟 + //算法:将秒数除以60,然后下舍入,既得到分钟数 + var h; + h = Math.floor(s / 60); + //计算秒 + //算法:取得秒%60的余数,既得到秒数 + s = s % 60; + //将变量转换为字符串 + h += ""; + s += ""; + //如果只有一位数,前面增加一个0 + h = h.length == 1 ? "0" + h : h; + s = s.length == 1 ? "0" + s : s; + return h; }; +/** 秒数转分钟,只返回秒数 */ const s_to_s = (s) => { - //计算分钟 - //算法:将秒数除以60,然后下舍入,既得到分钟数 - var h; - h = Math.floor(s / 60); - //计算秒 - //算法:取得秒%60的余数,既得到秒数 - s = s % 60; - //将变量转换为字符串 - h += ""; - s += ""; - //如果只有一位数,前面增加一个0 - h = h.length == 1 ? "0" + h : h; - s = s.length == 1 ? "0" + s : s; - return s; -}; - -// 分秒转换成秒 + //计算分钟 + //算法:将秒数除以60,然后下舍入,既得到分钟数 + var h; + h = Math.floor(s / 60); + //计算秒 + //算法:取得秒%60的余数,既得到秒数 + s = s % 60; + //将变量转换为字符串 + h += ""; + s += ""; + //如果只有一位数,前面增加一个0 + h = h.length == 1 ? "0" + h : h; + s = s.length == 1 ? "0" + s : s; + return s; +}; + +/** 分秒转秒数,返回秒数 */ const minSecToS = (minSecStr) => { - if (!minSecStr) return 0; - let strArr = minSecStr.split(":"); - console.info(strArr, 'strArr') - return strArr.length ? parseInt(strArr[0]) * 60 + parseInt(strArr[1]) : 0; -} + if (!minSecStr) return 0; + let strArr = minSecStr.split(":"); + console.info(strArr, "strArr"); + return strArr.length ? parseInt(strArr[0]) * 60 + parseInt(strArr[1]) : 0; +}; // 将字符串转换成ArrayBufer const string2buffer = (str) => { - let val = ""; - if (!str) return; - let length = str.length; - let index = 0; - let array = []; - while (index < length) { - array.push(str.substring(index, index + 2)); - index = index + 2; - } - val = array.join(","); - // 将16进制转化为ArrayBuffer - return new Uint8Array( - val.match(/[\da-f]{2}/gi).map(function (h) { - return parseInt(h, 16); - }) - ).buffer; + let val = ""; + if (!str) return; + let length = str.length; + let index = 0; + let array = []; + while (index < length) { + array.push(str.substring(index, index + 2)); + index = index + 2; + } + val = array.join(","); + // 将16进制转化为ArrayBuffer + return new Uint8Array( + val.match(/[\da-f]{2}/gi).map(function (h) { + return parseInt(h, 16); + }) + ).buffer; }; const checkEnd = (str) => { - let itotal = 0, - len = str.length, - num = 0; - while (num < len) { - let s = str.substring(num, num + 2); - itotal += parseInt(s, 16); - num = num + 2; - } - let mode = itotal % 256; - let shex = mode.toString(16); - let iLen = shex.length; - if (iLen < 2) { - shex = "0" + shex; - } - return shex.toUpperCase(); + let itotal = 0, + len = str.length, + num = 0; + while (num < len) { + let s = str.substring(num, num + 2); + itotal += parseInt(s, 16); + num = num + 2; + } + let mode = itotal % 256; + let shex = mode.toString(16); + let iLen = shex.length; + if (iLen < 2) { + shex = "0" + shex; + } + return shex.toUpperCase(); }; const getofflineData = () => { - //获取近7天的离线记录 - let arr = []; - for (let i = 0; i <= 6; i++) { - let str1 = "dbf0a00201"; - let num16 = i.toString(16).padStart("2", 0); - let str2 = ccrc8(`${str1}${num16}`); - arr.push(`${str1}${num16}${str2}de`); - } - return arr; + //获取近7天的离线记录 + let arr = []; + for (let i = 0; i <= 6; i++) { + let str1 = "dbf0a00201"; + let num16 = i.toString(16).padStart("2", 0); + let str2 = ccrc8(`${str1}${num16}`); + arr.push(`${str1}${num16}${str2}de`); + } + return arr; }; const getUpgradeData = (info) => { - //解析获取升级包更新数据 - console.log(info); - let arr = []; - for (let i = 0, len = info.data.length; i < len; i += 480) { - arr.push({ - i: info.data.slice(i, i + 480), - }); - } - arr.map((item, index) => { - let num = Number(index + 1) - .toString(16) - .padStart("4", 0); - let baohaodiwei = num.substring(2, 4); - let baohaogaowei = num.substring(0, 2); - let data = `dbf0ab01F7${info.length_low.padStart('2',0)}${info.length_high.padStart('2',0)}${info.bao_low.padStart('2',0)}${ - info.bao_high.padStart('2',0) - }${baohaodiwei.padStart('2',0)}${baohaogaowei.padStart('2',0)}${ - index == arr.length - 1 - ? (arr[index].i.length / 2).toString(16).padStart("2", 0) - : "F0" - }${item.i}`; - item.i = `${data}${ccrc8(data)}de`; + //解析获取升级包更新数据 + console.log(info); + let arr = []; + for (let i = 0, len = info.data.length; i < len; i += 480) { + arr.push({ + i: info.data.slice(i, i + 480), }); - return arr; + } + arr.map((item, index) => { + let num = Number(index + 1) + .toString(16) + .padStart("4", 0); + let baohaodiwei = num.substring(2, 4); + let baohaogaowei = num.substring(0, 2); + let data = `dbf0ab01F7${info.length_low.padStart( + "2", + 0 + )}${info.length_high.padStart("2", 0)}${info.bao_low.padStart( + "2", + 0 + )}${info.bao_high.padStart("2", 0)}${baohaodiwei.padStart( + "2", + 0 + )}${baohaogaowei.padStart("2", 0)}${ + index == arr.length - 1 + ? (arr[index].i.length / 2).toString(16).padStart("2", 0) + : "F0" + }${item.i}`; + item.i = `${data}${ccrc8(data)}de`; + }); + return arr; }; const checkEnd2 = (str) => { - const crc8_854_table = [ - 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, - 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, - 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, - 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, - 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, - 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, - 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, - 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, - 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, - 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, - 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, - 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, - 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, - 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, - 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, - 247, 182, 232, 10, 84, 215, 137, 107, 53, - ]; - let crc = new Uint8Array(1); - crc = 0; - for (let i = 0; i < str.length; i++) { - crc = crc8_854_table[crc ^ (str[i] & 0xff & 0xff)]; - } - return (crc & 0xff).toString(16).toUpperCase().padStart("2", 0); + const crc8_854_table = [ + 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, + 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, + 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, + 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, + 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, + 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, + 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, + 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, + 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, + 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, + 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, + 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, + 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, + 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, + 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, + 247, 182, 232, 10, 84, 215, 137, 107, 53, + ]; + let crc = new Uint8Array(1); + crc = 0; + for (let i = 0; i < str.length; i++) { + crc = crc8_854_table[crc ^ (str[i] & 0xff & 0xff)]; + } + return (crc & 0xff).toString(16).toUpperCase().padStart("2", 0); }; const checkEnd3 = (str) => { - let arr = []; - for (let i = 0, len = str.length; i < len; i += 2) { - arr.push("0x" + str.slice(i, i + 2)); - } - const crc8_854_table = [ - 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, - 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, - 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, - 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, - 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, - 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, - 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, - 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, - 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, - 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, - 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, - 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, - 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, - 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, - 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, - 247, 182, 232, 10, 84, 215, 137, 107, 53, - ]; - let crc = new Uint8Array(1); - crc = 0; - for (let i = 0; i < arr.length; i++) { - crc = crc8_854_table[crc ^ (arr[i] & 0xff & 0xff)]; - } - return (crc & 0xff).toString(16).toUpperCase().padStart("2", 0); + let arr = []; + for (let i = 0, len = str.length; i < len; i += 2) { + arr.push("0x" + str.slice(i, i + 2)); + } + const crc8_854_table = [ + 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, + 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, + 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, + 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, + 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, + 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, + 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, + 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, + 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, + 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, + 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, + 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, + 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, + 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, + 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, + 247, 182, 232, 10, 84, 215, 137, 107, 53, + ]; + let crc = new Uint8Array(1); + crc = 0; + for (let i = 0; i < arr.length; i++) { + crc = crc8_854_table[crc ^ (arr[i] & 0xff & 0xff)]; + } + return (crc & 0xff).toString(16).toUpperCase().padStart("2", 0); }; const chulidata = (str) => { - let data = str - .replace(/dccc/g, "dc") - .replace(/dccb/g, "db") - .replace(/dcce/g, "de"); - return data; + let data = str + .replace(/dccc/g, "dc") + .replace(/dccb/g, "db") + .replace(/dcce/g, "de"); + return data; }; const chulidata2 = (str) => { - let data = str - .replace(/DCCC/g, "dc") - .replace(/DCCB/g, "db") - .replace(/DCCE/g, "de"); - return data; + let data = str + .replace(/DCCC/g, "dc") + .replace(/DCCB/g, "db") + .replace(/DCCE/g, "de"); + return data; }; const getimpedanceList = () => { - let arr = []; - for(let i = 1;i<=10;i++){ - arr.push({ - num: 0, - time: `00:${String(i).padStart('2',0)}` - }) - } - return arr; + let arr = []; + for (let i = 1; i <= 10; i++) { + arr.push({ + num: 0, + time: `00:${String(i).padStart("2", 0)}`, + }); + } + return arr; }; - /** * 处理上报数据,转换成对象 */ -const getreportData = (str) =>{ - let data = {}; - data.status = hex2int(str.substring(10,12));//工作状态 - data.quantity = hex2int(str.substring(20,22));//电量 - data.impedance1 = hex2int(str.substring(24,26));//阻抗低位数据 - data.impedance2 = hex2int(str.substring(26,28));//阻抗低位数据 - data.jiaoer1 = hex2int(str.substring(28,30));//每秒能量N*10 焦耳(N: 0~25.5 - data.mode = hex2int(str.substring(12,14));//模式 - data.position = hex2int(str.substring(14,16));//档位 - //TOREAD 当模式为水份模式 - if(data.mode == 6){ - data.waterLevel = hex2int(str.substring(16,18)) - data.waterPercent = hex2int(str.substring(18,20)) - //模式为水份测试时 档位1~3对应 0x01:测试成功 0x02: 测试中 0x03: 测试错误 - const testResultMap = ['TEST_UNKNOW_STATUS','TEST_SUCCESS','TEST_PROCESSING','TEST_FAIL']; - data.testResult = testResultMap[data.position]||'TEST_UNKNOW_STATUS' - } - return data; -} +const getreportData = (str) => { + let data = {}; + data.status = hex2int(str.substring(10, 12)); //工作状态 + data.quantity = hex2int(str.substring(20, 22)); //电量 + data.impedance1 = hex2int(str.substring(24, 26)); //阻抗低位数据 + data.impedance2 = hex2int(str.substring(26, 28)); //阻抗低位数据 + data.jiaoer1 = hex2int(str.substring(28, 30)); //每秒能量N*10 焦耳(N: 0~25.5 + data.mode = hex2int(str.substring(12, 14)); //模式 + data.position = hex2int(str.substring(14, 16)); //档位 + //TOREAD 当模式为水份模式 + if (data.mode == 6) { + data.waterLevel = hex2int(str.substring(16, 18)); + data.waterPercent = hex2int(str.substring(18, 20)); + //模式为水份测试时 档位1~3对应 0x01:测试成功 0x02: 测试中 0x03: 测试错误 + const testResultMap = [ + "TEST_UNKNOW_STATUS", + "TEST_SUCCESS", + "TEST_PROCESSING", + "TEST_FAIL", + ]; + data.testResult = testResultMap[data.position] || "TEST_UNKNOW_STATUS"; + } + return data; +}; /** * height 高位 @@ -545,142 +566,153 @@ const getreportData = (str) =>{ * <=700 7挡 * >=701 8挡 */ -const DYNAMIC_BONES_OFFSETS = (height,low) =>{ - let total = Number(low)+Number(height)*256; - if(total<=200){ - return 1 - } - if(total<=280){ - return 2 - } - if(total<=360){ - return 3 - } - if(total<=440){ - return 4 - } - if(total<=520){ - return 5 - } - if(total<=600){ - return 6 - } - if(total<=700){ - return 7 - } - if(total>=701){ - return 8 - } -} - -const getTimeCode = () =>{ - let year = new Date().getFullYear(); - let month = String(new Date().getMonth() + 1).padStart("2", 0); - let day = String(new Date().getDate()).padStart("2", 0); - let hour = String(new Date().getHours()).padStart("2", 0); - let points = String(new Date().getMinutes()).padStart("2", 0); - let seconds = String(new Date().getSeconds()).padStart("2", 0); - let value = `dbf0a0010b${Number(String(year).substring(0, 2)).toString(16)}${Number(String(year).substring(2, 4)).toString(16)}${Number(month).toString(16).padStart("2", 0)}${Number(day).toString(16).padStart("2", 0)}${Number(hour).toString(16).padStart("2", 0)}${Number(points).toString(16).padStart("2", 0)}${Number(seconds).toString(16).padStart("2", 0)}00000000`; - value = `${value}${ccrc8(value)}de`; - return value; -} +const DYNAMIC_BONES_OFFSETS = (height, low) => { + let total = Number(low) + Number(height) * 256; + if (total <= 200) { + return 1; + } + if (total <= 280) { + return 2; + } + if (total <= 360) { + return 3; + } + if (total <= 440) { + return 4; + } + if (total <= 520) { + return 5; + } + if (total <= 600) { + return 6; + } + if (total <= 700) { + return 7; + } + if (total >= 701) { + return 8; + } +}; + +const getTimeCode = () => { + let year = new Date().getFullYear(); + let month = String(new Date().getMonth() + 1).padStart("2", 0); + let day = String(new Date().getDate()).padStart("2", 0); + let hour = String(new Date().getHours()).padStart("2", 0); + let points = String(new Date().getMinutes()).padStart("2", 0); + let seconds = String(new Date().getSeconds()).padStart("2", 0); + let value = `dbf0a0010b${Number(String(year).substring(0, 2)).toString( + 16 + )}${Number(String(year).substring(2, 4)).toString(16)}${Number(month) + .toString(16) + .padStart("2", 0)}${Number(day).toString(16).padStart("2", 0)}${Number(hour) + .toString(16) + .padStart("2", 0)}${Number(points).toString(16).padStart("2", 0)}${Number( + seconds + ) + .toString(16) + .padStart("2", 0)}00000000`; + value = `${value}${ccrc8(value)}de`; + return value; +}; /** * @param currentVersionNo * @param latestVersionNo * @returns needToUpdate */ -const isNeedToUpdate = (currentVersionNo,latestVersionNo)=>{ - if (!currentVersionNo || !latestVersionNo) return false; - let needToUpdate = false; - //硬件版本号相同 - let sameHardwareNo = latestVersionNo.substring(0, 2) == currentVersionNo.substring(0, 2); - //软件版本号当前版本比最新版的旧 - let latestValue = parseInt(latestVersionNo.substring(2, 6), 16); - let currentValue = parseInt(currentVersionNo.substring(2, 6), 16); - - let solftwareNoNeedToUpdate = latestValue > currentValue; - needToUpdate = sameHardwareNo && solftwareNoNeedToUpdate - return needToUpdate -} +const isNeedToUpdate = (currentVersionNo, latestVersionNo) => { + if (!currentVersionNo || !latestVersionNo) return false; + let needToUpdate = false; + //硬件版本号相同 + let sameHardwareNo = + latestVersionNo.substring(0, 2) == currentVersionNo.substring(0, 2); + //软件版本号当前版本比最新版的旧 + let latestValue = parseInt(latestVersionNo.substring(2, 6), 16); + let currentValue = parseInt(currentVersionNo.substring(2, 6), 16); + + let solftwareNoNeedToUpdate = latestValue > currentValue; + needToUpdate = sameHardwareNo && solftwareNoNeedToUpdate; + return needToUpdate; +}; /** * @param compareVersion * @returns result 1:SDKVersion > version 0:SDKVersion == version -1:SDKVersion < version */ -const compareVersion = (version)=>{ - const systemInfo = wx.getSystemInfoSync(); - let SDKVersion = systemInfo.SDKVersion.split('.'); - version = version.split('.'); - const len = Math.max(SDKVersion.length, version.length) - - while (SDKVersion.length < len) { - SDKVersion.push('0') +const compareVersion = (version) => { + const systemInfo = wx.getSystemInfoSync(); + let SDKVersion = systemInfo.SDKVersion.split("."); + version = version.split("."); + const len = Math.max(SDKVersion.length, version.length); + + while (SDKVersion.length < len) { + SDKVersion.push("0"); + } + while (version.length < len) { + version.push("0"); + } + + for (let i = 0; i < len; i++) { + const num1 = parseInt(SDKVersion[i]); + const num2 = parseInt(version[i]); + + if (num1 > num2) { + return 1; + } else if (num1 < num2) { + return -1; } - while (version.length < len) { - version.push('0') - } - - for (let i = 0; i < len; i++) { - const num1 = parseInt(SDKVersion[i]) - const num2 = parseInt(version[i]) - - if (num1 > num2) { - return 1 - } else if (num1 < num2) { - return -1 - } - } - return 0 -} + } + return 0; +}; /** * @param checkSameKey * @returns boolean */ -const checkSameKey = (array1, array2, key)=>{ - for (var i = 0; i < array1.length; i++) { - for (var j = 0; j < array2.length; j++) { - if (array1[i][key] === array2[j][key]) { - return true; - } - } +const checkSameKey = (array1, array2, key) => { + for (var i = 0; i < array1.length; i++) { + for (var j = 0; j < array2.length; j++) { + if (array1[i][key] === array2[j][key]) { + return true; + } } - return false; -} + } + return false; +}; module.exports = { - isVideo, - previewImage, - formatTime, - setdata, - filertext, - formatRichText, - date, - getdates, - getYearFirstLastDay, - ab2hex, - hex2int, - filterData, - ccrc8, //crc8校验位 - string2buffer, //将字符串转换成ArrayBufer - s_to_hs, //秒转换成分秒 - checkEnd, //相加和 - filterBleData, - getofflineData, - getUpgradeData, - keywordTofilter, - checkEnd2, - checkEnd3, - chulidata, - chulidata2, - getimpedanceList, - DYNAMIC_BONES_OFFSETS, //阻抗获取值 - getreportData, //解析上报数据 - s_to_h, - s_to_s, - minSecToS, - getTimeCode, //同步时间指令 - isNeedToUpdate, - compareVersion, - checkSameKey + isVideo, + previewImage, + formatTime, + setdata, + filertext, + formatRichText, + date, + getdates, + getYearFirstLastDay, + ab2hex, + hex2int, + filterData, + ccrc8, //crc8校验位 + string2buffer, //将字符串转换成ArrayBufer + s_to_hs, //秒转换成分秒 + checkEnd, //相加和 + filterBleData, + getofflineData, + getUpgradeData, + keywordTofilter, + checkEnd2, + checkEnd3, + chulidata, + chulidata2, + getimpedanceList, + DYNAMIC_BONES_OFFSETS, //阻抗获取值 + getreportData, //解析上报数据 + s_to_h, + s_to_s, + minSecToS, + getTimeCode, //同步时间指令 + isNeedToUpdate, + compareVersion, + checkSameKey, };