Compare commits

...

72 Commits

Author SHA1 Message Date
rongweikang dd73d2af34 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into rwkdev 2 years ago
rongweikang e01aad14ac 修复视频问题 2 years ago
blak-kong 91becf3a69 临时 2 years ago
blak-kong 404e01cc1a 打卡统计样式修复 2 years ago
blak-kong 75bfd27ae7 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
blak-kong f14cb28a59 修复bug 2 years ago
qsj 978142d08f 修改电流 2 years ago
qsj 66b4abc067 修改脸部护理bug 2 years ago
qsj 661bbe18a3 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into qsj 2 years ago
qsj 47757702b0 电流定制 2 years ago
blak-kong 0fc7d07689 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
blak-kong ab3ec7c8c1 临时 2 years ago
rongweikang a6c7fb6eed Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into rwkdev 2 years ago
rongweikang 3589191eef 添加声音控制并修改ui问题 2 years ago
rongweikang 79e7432953 完成echarts表格对接 2 years ago
qsj f06b1d8cc1 修改样式 2 years ago
blak-kong 63a28dba21 we100 前期准备 2 years ago
rongweikang 9af2818990 优化 2 years ago
rongweikang 126d80ba17 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into rwkdev 2 years ago
rongweikang 3f7e7fa9d8 添加弹窗 2 years ago
blak-kong 51051e6bfb fix:横屏 2 years ago
blak-kong a4d2d7a438 . 2 years ago
qsj 62901485e0 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
qsj 21e61acb7d 临时 2 years ago
blak-kong b61a5c4507 模式列表复制问题 2 years ago
blak-kong 44c672c97f . 2 years ago
blak-kong f978e260b6 升级固件 2 years ago
blak-kong 3a3d164762 修复弹窗被删除的问题 2 years ago
rongweikang 1b4607ab01 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into rwkdev 2 years ago
rongweikang 48530fe7b0 添加配置文件 2 years ago
rongweikang 8f043948c8 优化样式 2 years ago
qsj 8bbeb2065d Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into qsj 2 years ago
qsj 8d4cfcd59e 临时推送 2 years ago
blak-kong 32d03bd9ee fix:样式冲突处理 2 years ago
blak-kong c76c055467 测试横屏 2 years ago
blak-kong e909ed328d Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
blak-kong a7e7f63b4d Merge branch 'lzwdev' into dev 2 years ago
blak-kong f6bc35f884 we200 2 years ago
rongweikang 89a76582b9 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
rongweikang aed682c3c0 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
blak-kong 86a194c666 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
blak-kong c6f9dea300 临时 2 years ago
blak-kong 22b0302113 删除意外多出来的代码 2 years ago
blak-kong 71d57fc628 . 2 years ago
qsj c5cf3021f8 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into qsj 2 years ago
qsj 73e792cabb 修改bug 2 years ago
blak-kong 5e402b2013 merge 合并代码 2 years ago
blak-kong fe8fc9fd82 . 2 years ago
blak-kong ffb4910983 merge 合并代码 2 years ago
rongweikang 3bc7def62f Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into dev 2 years ago
rongweikang 74b1901625 echarts图表 2 years ago
blak-kong 30b227b892 fix:修复横向滚动条切换item,页面数据刷新导致横向滚动闪动回初始位置问题 2 years ago
qsj fb65a464f3 修改bug 2 years ago
qsj 8922944ccc 修改bug 2 years ago
qsj 7e5b76ff5e Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into qsj 2 years ago
qsj e148e5c48c 临时提交 2 years ago
blak-kong 722482e8dd 临时 2 years ago
blak-kong cbbaf16a6b merge:合并 2 years ago
blak-kong 5320e0fc35 打卡记录优化 2 years ago
rongweikang 93fdea9c9b 删除多余代码 2 years ago
qsj e0ab75bf02 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into qsj 2 years ago
qsj 041822f2dd 代码优化,样式修改 2 years ago
blak-kong 66a87f249d merge:处理冲突 2 years ago
blak-kong 23ffb520fb 处理冲突 2 years ago
blak-kong 7d399d95d1 fix:设备管理和详情页还原UI设计稿 2 years ago
qsj 4c77ad357c 水分测试护理报告 2 years ago
qsj 7c357bb574 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into qsj 2 years ago
qsj e8468ce3bd 护理报告 2 years ago
rongweikang 7e6046d9eb 添加跳转数据 2 years ago
rongweikang 0bdf48e9a3 Merge branch 'dev' of https://gitee.com/yunqiang_technology/flowsomwechat into rwkdev 2 years ago
rongweikang a3a27ec2c6 对接水分测试报告echarts 2 years ago
qsj 924638c3c9 临时提交 2 years ago

@ -71,13 +71,15 @@ export default defineAppConfig({
navigationBarBackgroundColor: "#fff",
navigationBarTitleText: "WeChat",
navigationBarTextStyle: "black",
// pageOrientation: "auto",
// enablePullDownRefresh: true
},
requiredPrivateInfos: ["getLocation"],
subPackages: [
{
root: "moduleIOT",
pages: ["pages/iotCarePlan/WL200", "pages/iotCarePlan/FR200"],
pages: ["pages/iotCarePlan/WL200", "pages/iotCarePlan/FR200", "pages/iotCarePlan/WE100",],
},
{
root: "recoding",
@ -85,7 +87,7 @@ export default defineAppConfig({
"pages/recording/recording",
"pages/face_report_one/face_report_one",
"pages/moisture_test_report/moisture_test_report",
"pages/face_report/face_report",
],
},
{

@ -41,6 +41,9 @@ export const fr200DeviceControlCommand = {
queryDeviceStatus: {
commandType: "DeviceStatusSync",
deviceSyncCommandType: "onlySyncStatusToDevice",
// totalWorkingSeconds: 55,
// workStatus: "working",
// workMode: 'eyes',
},
/**控制设备暂停 pause暂停 working启动 end关闭*/
pause: {

@ -124,7 +124,7 @@ class ConnectionBluetoot extends Component<any, any> {
// "FR200", // FR200
],
currentDeviceType: "", // 现在的设备类型: WE200 WL200
currentDeviceType: "", // 现在的设备类型: WE200 WL200 FR200当设备为WL200时它还可能是WE200
};
}

@ -0,0 +1,183 @@
/**蓝牙命令合集*/
export const WE100BleCommand = {
/**发送配对码*/
match: {
commandType: "BleMatch",
bleCommandType: "SendMatchCode",
},
/**查询附属设备的配对状态*/
querySubDevice: {
commandType: "BleMatch",
bleCommandType: "QueryMatchStatus",
},
// 查询信息
InfoQuery: {
/**查询版本指令*/
versionInfo: {
commandType: "InfoQuery",
infoQueryType: "versionInfo",
otaDeviceType: "WE100",
},
/**时间同步*/
timeSync: {
commandType: "InfoQuery",
infoQueryType: "timeSync",
date: new Date(),
},
/** 查询 面膜自定义模式信息 */
facialMaskCustomModeInfo: {
commandType: "InfoQuery",
infoQueryType: "facialMaskCustomModeInfo",
},
/**
* @name 查询并设置自定义电流配方模式面膜模式
* @description 部位只是执行顺序所有部位共用三种模式 Pulling(提拉) Moisturize(滋润) Mix(混合)
* */
facialMaskCustomModeSet: {
commandType: "InfoQuery",
infoQueryType: "facialMaskCustomModeSet",
feelingTakeEffectOffline: true,
partitionConfigArray: [
{
feelingType: "Pulling",
pullingSeconds: 1.05,
moisturizeSeconds: 2.25,
},
{
feelingType: "Mix",
pullingSeconds: 1.05,
moisturizeSeconds: 2.25,
},
{
feelingType: "Mix",
pullingSeconds: 1.05,
moisturizeSeconds: 2.25,
},
{
feelingType: "Moisturize",
pullingSeconds: 1.15,
moisturizeSeconds: 0.25,
},
],
neededTotalSeconds: 900, // 设置工作时间
},
/** 离线汇总 */
offlineSummary: {
commandType: "InfoQuery",
infoQueryType: "offlineClockSummary",
},
/** 离线详情 */
offlineDetail: {
commandType: "InfoQuery",
infoQueryType: "offlineClockDetail",
dataIndex: 0,
},
/** 现在的面膜报告信息 */
currentFacialReportInfo: {
commandType: "InfoQuery",
infoQueryType: "currentFacialReportInfo",
},
/** 查询M02自定义面膜信息 */
m02MaskCustomModeInfo: {
commandType: "InfoQuery",
infoQueryType: "m02MaskCustomModeInfo",
workMode: "PreMakeup_Custom",
},
/** 查询并设置:眼雕大师自定义、妆前急救自定义面膜模式 */
m02MaskCustomModeSet: {
commandType: "InfoQuery",
infoQueryType: "m02MaskCustomModeSet",
workMode: "EyeCarving_Custom",
feelingTakeEffectOffline: "OnlyAffectOnce",
partitionConfigArray: [
{
feelingType: ["Moisturize", "EyeSculpt"],
pullingSeconds: 0.05,
moisturizeSeconds: 1.15,
eyeSculptSeconds: 6,
},
{
feelingType: ["Moisturize", "EyeSculpt"],
pullingSeconds: 0,
moisturizeSeconds: 1.15,
eyeSculptSeconds: 6,
},
{
feelingType: ["Pulling", "Moisturize"],
pullingSeconds: 1,
moisturizeSeconds: 2,
eyeSculptSeconds: 0,
},
],
neededTotalSeconds: 900, // 设置工作时间
},
},
};
/**控制设备命令合集*/
export const WE100DeviceControlCommand = {
/**控制设备暂停 pause暂停 working启动 end关闭*/
// '水光精华模式分区档位0-3-2-5离线生效' = 'workByPatitionSet',
// '自定义电流配方模式运行档位1-3-2-2离线不生效' = 'workCustom',
// '控制设备暂停' = 'pause',
// '控制设备继续工作' = 'working',
// '发送APP状态使设备同步-工作时间55秒' = 'onlySyncStatusToDevice',
// '主动查询设备的状态' = 'queryDeviceStatus',
// // m02
// '状前模式运行档位1-3-2档位离线不生效' = 'm02work1',
// '眼雕电流配方模式运行档位1-3-2档位离线生效' = 'm02workCustom2',
// standby: {
// commandType: "DeviceControl",
// workStatus: "standby",
// },
work: {
commandType: "DeviceControl",
workStatus: "working",
},
pause: {
commandType: "DeviceControl",
workStatus: "pause",
},
end: {
commandType: "DeviceControl",
workStatus: "end",
},
working2: { ...working, neededTotalSeconds: 600 }, // 设置工作十分钟
/**
* M01膜布
* WaterLightEssence: 水光精华模式
* ShapeBeautyEssence: 塑颜精华模式
* DiyFacial DIY面膜模式
* ShapeBeautyEssence_Custom 自定义电流配方模式
*
* M02膜布
* EyeCarving_Custom: 眼雕大师配方模式
* PreMakeup_Custom: 妆前急救模式
*/
// 设置工作模式
workByPatitionSet: {
commandType: "DeviceControl",
workStatus: "working",
workMode: "WaterLightEssence", // 工作模式
gearTakeEffectOffline: true, // 是否离线生效
partitionStatus: [{ gear: 0 }, { gear: 3 }, { gear: 2 }, { gear: 5 }], // 0-3-2-5挡位是官配电流模式自定义时可修改?
},
// 发送APP状态使设备同步
onlySyncStatusToDevice: {
commandType: "DeviceStatusSync",
deviceSyncCommandType: "onlySyncStatusToDevice",
totalWorkingSeconds: 55, // 同步工作时间?
workStatus: "working", // 工作状态,与程序同步
workMode: "ShapeBeautyEssence", // 模式,与程序同步
partitionStatus: [{ gear: 0 }, { gear: 3 }, { gear: 2 }, { gear: 5 }], // 挡位,与程序同步,非自定义模式或许可以不传
},
};

@ -110,26 +110,69 @@ export default class DeviceConnectPopup extends Component<any, any> {
<View
className={classnames("common-popup-title", "margin-samll")}
>
{data.bluetoothConnectingTitle}
{data.model === "WL200" && (
<Block>
{currentDeviceType !== "WE200"
? data.bluetoothConnectingTitle
: data.we200BluetoothConnectingTitle}
</Block>
)}
{data.model !== "WL200" && (
<Block>{data.bluetoothConnectingTitle}</Block>
)}
</View>
<View className="device-popup-content-box">
{!this.isImage(data.bluetoothConnecting) ? (
<Video
className="videos"
autoplay
loop
objectFit="cover"
enablePlayGesture
showFullscreenBtn={false}
playBtnPosition="center"
src={encodeURIComponent(data.bluetoothConnecting)}
/>
) : (
<Image
className="images"
src={data.bluetoothConnecting}
mode="aspectFill"
/>
{data.model === "WL200" && (
<Block>
{!this.isImage(data.bluetoothConnecting) ? (
<Video
className="videos"
autoplay
loop
objectFit="cover"
enablePlayGesture
showFullscreenBtn={false}
playBtnPosition="center"
src={
currentDeviceType !== "WE200"
? data.bluetoothConnecting
: data.we200BluetoothConnecting
}
/>
) : (
<Image
className="images"
src={
currentDeviceType !== "WE200"
? data.bluetoothConnecting
: data.we200BluetoothConnecting
}
mode="aspectFill"
/>
)}
</Block>
)}
{data.model !== "WL200" && (
<Block>
{!this.isImage(data.bluetoothConnecting) ? (
<Video
className="videos"
autoplay
loop
objectFit="cover"
enablePlayGesture
showFullscreenBtn={false}
playBtnPosition="center"
src={data.bluetoothConnecting}
/>
) : (
<Image
className="images"
src={data.bluetoothConnecting}
mode="aspectFill"
/>
)}
</Block>
)}
<View className="blue-device-tips">

@ -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;
}

@ -0,0 +1,477 @@
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 DeviceToolKitFR200 } from "@flossom-npm/iot-translater";
// 临时替代
var log = console;
let deviceToolKitInstance: any = null;
const deviceToolKitInstanceFR200 = new DeviceToolKitFR200("FR200");
deviceToolKitInstanceFR200.setDebug(true);
import "./index.less";
class UpdateIotFR200 extends Component<any, any> {
constructor(props) {
super(props);
this.state = {
name: "UpdateIotFR200",
progressbar: 1, // 进度条
currentDevice: {},
hadStartOta: false, // 是否开始ota
};
}
$instance = Taro.getCurrentInstance();
$checkTimer: any = null;
// 与页面渲染无关的数据
$otaDataGroup: any = {
// 包大小面罩设置为100主机设置为240
packageSize: 240, //每个包的大小上限(单位是字节)
otaBin: null, //固件包buffer形式从16进制字符串转换成
otaHexString: "", //固件包的16进制字符串从后端接口返回
packageLength: 0, //升级包的总长度(单位是字节)
packageCount: 0, //分包后的总包数
otaData: [], //分包数组
packageCrc8: "", //总包的校验码
versionNo: "", //包的版本号
otaCurrentPackageIndex: 0, //现在正在传输的分包索引
countDown: 7,
};
async onLoad() {
if (this.$checkTimer) clearInterval(this.$checkTimer);
}
componentDidMount() {
console.log("componentDidMount");
this.initData();
}
componentDidHide() {
console.log("componentDidHide");
this.errorFun();
}
async initData() {
console.log("UpdateIotWL200");
deviceToolKitInstance = deviceToolKitInstanceFR200;
let objStr = getStorageSync("instrument_detail");
if (objStr) {
this.setState({
currentDevice: objStr,
});
}
setTimeout(() => {
this.notifyBLECharacteristicValueChange();
this.getDeviceUpgrade();
});
}
/**
*
*/
async getUpgradeData() {
//解析获取升级包更新数据
const { otaHexString, packageSize } = this.$otaDataGroup;
if (!otaHexString?.length) {
return [];
}
let arr: any = [];
for (let i = 0, len = otaHexString.length; i < len; i += packageSize * 2) {
let index = i + packageSize * 2;
let value = otaHexString.slice(i, index);
arr.push(value);
}
return arr;
}
/**
* OTA
*/
resetOta() {
this.$otaDataGroup = {
...this.$otaDataGroup,
otaCurrentPackageIndex: 0,
otaData: [],
};
}
/**
* ota
*/
startOTA() {
this.resetOta();
let jsoncmd = {
commandType: "OTAStart",
otaDeviceType: "FR200",
versionNo: this.$otaDataGroup.versionNo,
};
console.log("startOTA jsoncmd", jsoncmd);
//@ts-ignore
const value = deviceToolKitInstance.toBleCommand(jsoncmd as any);
console.log(jsoncmd);
sendCommand({ value }).then((res) => {
this.setState({
hadStartOta: true,
});
this.createTimer();
});
}
/**
* ota
*/
preOTA() {
const { packageCount, packageLength, packageCrc8, versionNo } =
this.$otaDataGroup;
let jsoncmd = {
commandType: "OTAPrepare",
packageCount,
packageLength,
packageCrc8,
versionNo,
};
console.info("OTAPrepare json => ", jsoncmd);
//@ts-ignore
const value = deviceToolKitInstance.toBleCommand(jsoncmd as any);
sendCommand({ value });
}
/**
* ota
*/
processOTA(i, data) {
const { packageCount, packageLength } = this.$otaDataGroup;
if (!packageLength) {
this.quitOTA();
}
let jsoncmd = {
commandType: "OTAUpdating",
packageCount,
packageLength,
currentPackageNo: i + 1,
currentPackageLength: data.length / 2,
currentPackageContent: data,
};
console.info("OTAUpdating json => ", jsoncmd);
//@ts-ignore
const value = deviceToolKitInstance.toBleCommand(jsoncmd as any);
sendCommand({ value });
}
/**
* ota
*/
async finishedOTA() {
let jsoncmd = {
commandType: "OTAUpdateFinish",
versionNo: this.$otaDataGroup.versionNo,
};
clearInterval(this.$checkTimer);
log.info("ota成功日志, 清除计时器");
//@ts-ignore
const value = deviceToolKitInstance.toBleCommand(jsoncmd as any);
sendCommand({ value }).then((res) => {
console.log("finishedOTA", res);
this.resetOta();
this.finishFun();
});
}
/**
* ota退
*/
quitOTA(errorString = "") {
// log.info('ota失败日志', errorString);
console.log("ota失败日志", errorString);
const errorMap = {
packageError: "总包错误",
packageNumError: "包号错误",
checkedError: "校验错误",
dataLengthError: "数据总长度错误",
dataCRCError: "数据总数CRC错误",
updateTimeOut: "数据更新超时",
};
let jsoncmd = {
commandType: "OTAQuit",
};
//@ts-ignore
const value = deviceToolKitInstance.toBleCommand(jsoncmd as any);
sendCommand({ value })
.then((res) => {
this.resetOta();
// this.showError(errorMap[errorString] || tipMap[errorString] || '发生错误')
})
.catch((err) => {
if (!this.state.hadShowError) {
this.setState({
hadShowError: true,
});
// log.info('ota失败日志', '发送日志OTAQuit失败', err);
console.info("ota失败日志", "发送日志OTAQuit失败", err);
if (err.errCode === 10000) {
let isDisconnect = getStorageSync("isDisconnectUpdate");
if (isDisconnect) {
if (this.$checkTimer) clearInterval(this.$checkTimer);
}
}
}
});
setTimeout(() => {
this.errorFun();
}, 1000);
}
/**
* OTA
*/
async parseData(json) {
console.log("parseData json.commandType", json.commandType);
if (!json || !json.commandType) return;
switch (json.commandType) {
case "OTAStart":
if (json.responseStatus == "OK") {
const otaData = await this.getUpgradeData();
this.$otaDataGroup = {
...this.$otaDataGroup,
otaData,
};
this.$otaDataGroup.otaCurrentPackageIndex = 0;
this.preOTA();
} else {
this.quitOTA(json.responseStatus);
}
break;
case "OTAPrepare":
if (json.responseStatus == "OK") {
this.processOTA(0, this.$otaDataGroup.otaData[0]);
} else {
this.quitOTA(json.responseStatus);
}
break;
case "OTAUpdating":
if (json.responseStatus == "OK") {
let ota = this.$otaDataGroup;
let progressbar =
(ota.otaCurrentPackageIndex / ota.packageCount) * 100;
this.setState({
progressbar: (progressbar <= 1 ? 1 : progressbar).toFixed(0),
});
if (!json.currentPackageNo) {
return;
}
console.log(
"json.currentPackageNo",
json.currentPackageNo,
this.$otaDataGroup.packageCount
);
if (json.currentPackageNo < this.$otaDataGroup.packageCount) {
this.$otaDataGroup.otaCurrentPackageIndex++;
this.processOTA(
this.$otaDataGroup.otaCurrentPackageIndex,
this.$otaDataGroup.otaData[
this.$otaDataGroup.otaCurrentPackageIndex
]
);
} else {
this.finishedOTA();
}
} else {
this.quitOTA(json.responseStatus);
}
break;
case "OTAUpdateFinish":
console.log("完成OTA传输");
this.setState({
progressbar: 100,
});
this.finishFun();
// quitOTA()
break;
default:
break;
}
}
/**
* ota
*/
getDeviceUpgrade = async () => {
let res: any = await InstrumentInfo.getUpgrade({
instrumentId: this.state.currentDevice.id,
isWe200: false,
});
if (res.data.data == "解析失败") {
// this.showError('文件解析失败');
return;
}
if (res.data.code !== 200) {
return;
}
const otaHexString = res.data.data;
const otaBin = string2buffer(res.data.data);
const packageLength = otaBin?.byteLength || 0;
const packageSize = this.$otaDataGroup.packageSize;
const packageCrc8 = Stringkit.getCrc8CodeByString(otaHexString);
const packageCount = Math.ceil(packageLength / packageSize);
let { iotVersion: versionNo } = this.state.currentDevice;
this.$otaDataGroup = {
...this.$otaDataGroup,
otaHexString,
otaBin,
packageLength,
packageSize,
packageCrc8,
packageCount,
versionNo,
};
console.log("this.$otaDataGroup ", this.$otaDataGroup);
};
notifyBLECharacteristicValueChange = () => {
const bluetoothInfo = this.props.bluetoothInfo;
notifyBLECharacteristicValueChange({
deviceId: bluetoothInfo.deviceId,
servicesuuid: bluetoothInfo.servicesuuid,
characteristicsuuid1: bluetoothInfo.characteristicsuuid1,
characteristicsuuid0: bluetoothInfo.characteristicsuuid0,
}).then((res) => {
Taro.onBLECharacteristicValueChange((value) => {
// let str = ab2hex(value.value); //转为16进制字符串
// console.log('返回',str)
const jsonStatus: any = deviceToolKitInstance.toJsonStatus(value.value);
log.info("OTA页面设备响应数据打印==》", JSON.stringify(jsonStatus));
console.info("onBLECharacteristicValueChange json => ", jsonStatus);
this.$otaDataGroup.currentPackageNo = jsonStatus.currentPackageNo;
this.$otaDataGroup.countDown = 7;
this.parseData(jsonStatus);
});
setTimeout(() => {
this.startOTA();
}, 500);
});
};
createTimer() {
log.info("设备ota计时器创建成功");
this.$checkTimer = setInterval(() => {
// 超过7s没有回包, 直接断开
if (this.$otaDataGroup.countDown <= 0 && this.state.hadStartOta) {
this.quitOTA("shutDownMaskTip");
} else {
this.$otaDataGroup.countDown--;
}
console.log(this.$otaDataGroup.countDown);
}, 1000);
}
//升级销毁页面时关闭小程序蓝牙
onUnload() {
console.log("onUnload");
if (this.$checkTimer) clearInterval(this.$checkTimer);
Taro.closeBluetoothAdapter();
}
onPullDownRefresh() {
Taro.stopPullDownRefresh();
}
onClickStop = (e) => {
e.stopPropagation();
};
// 错误关闭回调
errorFun = () => {
this.resetOta();
if (this.$checkTimer) clearInterval(this.$checkTimer);
this.props.errorFun();
};
// 升级完成回调
finishFun = () => {
if (this.$checkTimer) clearInterval(this.$checkTimer);
this.props.finishFun();
};
render() {
let { isShow } = this.props;
let { progressbar } = this.state;
return (
<Block>
<PageMeta pageStyle={isShow ? "overflow: hidden;" : ""} />
<Popup
show={isShow}
closeOnClickOverlay={false}
round
overlayStyle="width: 100vw;padding: 0;"
onClick={this.onClickStop}
>
<View
className={classnames(
"common-box",
"common-progress-box",
"common-large"
)}
catchMove
>
<View className={classnames("common-popup-title", "margin-samll")}>
</View>
<View className="common-popup-content-box">
<View className={classnames("common-popup-content", "text-left")}>
<View className="progress">
<Progress
percentage={progressbar}
strokeWidth="12"
color="linearGradient(to right, #eecda1, #ffe9c7) !important"
/>
<View className="percent"> {progressbar}%</View>
</View>
<View className="progress-tips"></View>
<View className="progress-tips">1.</View>
<View className="progress-tips">2.</View>
</View>
</View>
</View>
</Popup>
</Block>
);
}
}
const mapStateToProps = (state) => ({
bluetoothInfo: state.deviceInfo.bluetoothInfo,
});
const mapDispatchToProps = (dispatch) => ({});
export default connect(mapStateToProps, mapDispatchToProps)(UpdateIotFR200);

@ -229,6 +229,7 @@ class UpdateIotWL200 extends Component<any, any> {
const value = deviceToolKitInstance.toBleCommand(jsoncmd as any);
sendCommand({ value }).then((res) => {
this.resetOta();
this.finishFun();
});
}
/**
@ -435,6 +436,7 @@ class UpdateIotWL200 extends Component<any, any> {
// 错误关闭回调
errorFun = () => {
this.resetOta();
if (this.$checkTimer) clearInterval(this.$checkTimer);
this.props.errorFun();
};
// 升级完成回调

@ -160,10 +160,12 @@
// 展开高度
.main__body {
height: 400rpx;
transition: height 0.5s ease;
}
// 折叠高度
.main__body.main__body--isFolding {
height: 80px;
transition: height 0.2s ease;
}
}
/* 样式定制 */

@ -91,7 +91,7 @@ export default class AtCalendarController extends React.Component<any, any> {
return (
<Block>
<View className='at-calendar__controller controller flex-justify-sb'>
<View className="at-calendar__controller controller flex-justify-sb">
{hideArrow ? null : (
<View
className={classnames(
@ -103,9 +103,9 @@ export default class AtCalendarController extends React.Component<any, any> {
onClick={this.props.onPreMonth.bind(this, isMinMonth)}
/>
)}
<View className='calendar-top-date-btn'>
<View className="calendar-top-date-btn">
<View
style='display: flex;align-items: center;'
style="display: flex;align-items: center;"
onClick={this.openDate}
>
{/* <Text className="controller__info"></Text> */}
@ -113,10 +113,10 @@ export default class AtCalendarController extends React.Component<any, any> {
<Text style={{ fontSize: "32rpx", fontWeight: "600" }}>
{dayjsDate.format("YYYY.MM.DD")}
</Text>
<View style='margin-left: 34rpx;'>
<View style="margin-left: 34rpx;">
<Image
src={require("../img/calendar.png")}
style='width:28rpx;height:28rpx;'
style="width:28rpx;height:28rpx;"
/>
</View>
</View>
@ -127,33 +127,33 @@ export default class AtCalendarController extends React.Component<any, any> {
<Popup
show={showDatePicker}
position='bottom'
position="bottom"
// close-icon="/img/fr200/close.png"
round
onClick={this.onClickStop}
// onClose={this.onPopupClose}
onClose={this.onPopupClose}
>
<View className='toolbar'>
<View className='toolbar_title'>
<View className="toolbar">
<View className="toolbar_title">
<Text></Text>
<View
style='margin-left: 20rpx;color:#666;font-size: 34rpx'
className='at-icon at-icon-close popup-date-close'
style="margin-left: 20rpx;color:#666;font-size: 34rpx"
className="at-icon at-icon-close popup-date-close"
onClick={this.onPopupClose}
></View>
</View>
<View className='select_box'>
<View className='text'></View>
<View className='date'>{currentDate}</View>
<View className="select_box">
<View className="text"></View>
<View className="date">{currentDate}</View>
</View>
</View>
<DatetimePicker
type='date'
type="date"
value={curDate}
maxDate={maxDate}
onInput={_.throttle(this.onInput.bind(this), 500)}
/>
<View className='btn_confirm' onClick={this.onSelectDate}>
<View className="btn_confirm" onClick={this.onSelectDate}>
</View>
</Popup>

@ -15,65 +15,65 @@
display: flex;
justify-content: center;
}
}
.countdown-popup-loading {
position: relative;
}
.countdown-popup-loading-time {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 50rpx;
height: 50rpx;
line-height: 50rpx;
margin: auto;
font-size: 54rpx;
text-align: center;
color: #ecf0f3;
font-weight: bold;
}
.countdown-popup-loading {
position: relative;
}
.ui-loading__bg {
position: relative;
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background-color: #ecf0f3;
/* background-image: conic-gradient(#3CACFF 100%,#000 0%); */
}
.ui-loading__bg::before {
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 140rpx;
height: 140rpx;
border-radius: 50%;
background-color: #fff;
}
.countdown-popup-loading-time {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 50rpx;
height: 50rpx;
line-height: 50rpx;
margin: auto;
font-size: 54rpx;
text-align: center;
color: #ecf0f3;
font-weight: bold;
}
.ui-loading {
position: absolute;
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background: transparent;
box-sizing: border-box;
border: 10rpx solid #3cacff;
clip-path: polygon(0% 0%, 25% 0%, 50% 50%, 0% 25%);
animation: rotate 1s linear infinite;
}
.ui-loading__bg {
position: relative;
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background-color: #ecf0f3;
/* background-image: conic-gradient(#3CACFF 100%,#000 0%); */
}
.ui-loading__bg::before {
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 140rpx;
height: 140rpx;
border-radius: 50%;
background-color: #fff;
}
@keyframes rotate {
from {
transform: rotateZ(0deg);
.ui-loading {
position: absolute;
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background: transparent;
box-sizing: border-box;
border: 10rpx solid #3cacff;
clip-path: polygon(0% 0%, 25% 0%, 50% 50%, 0% 25%);
animation: countdownRotate 1s linear infinite;
}
to {
transform: rotateZ(360deg);
@keyframes countdownRotate {
from {
transform: rotateZ(0deg);
}
to {
transform: rotateZ(360deg);
}
}
}

@ -213,6 +213,8 @@ page {
display: inline-block;
height: 100%;
text-align: center;
padding-left: 10rpx;
padding-right: 20rpx;
.block1_1 {
height: 100%;
flex-direction: column;
@ -230,14 +232,14 @@ page {
height: 140rpx;
border-radius: 20rpx;
overflow: hidden;
margin-left: 6rpx;
// margin-left: 6rpx;
image {
width: 100%;
height: 100%;
}
}
.tip1 {
margin-top: 20rpx;
margin-top: 16rpx;
font-size: 26rpx;
font-weight: bold;
color: #000000;
@ -253,7 +255,7 @@ page {
border: 3rpx solid #f1f1f1;
width: 30rpx;
height: 30rpx;
margin-top: 15rpx;
margin-top: 10rpx;
&.is-select {
display: flex;
background-color: #fff;

@ -34,8 +34,7 @@ export default class InstrumentClickInUpload extends Component<any, any> {
year: new Date().getFullYear(),
month: String(new Date().getMonth() + 1).padStart(2, "0"),
day: String(new Date().getDate()).padStart(2, "0"),
zkmoshiindex: 0,
modeIndex: null,
modeIndex: 0,
stepIndex: null,
autoPlay: false,
scrollleft: 0,
@ -154,7 +153,7 @@ export default class InstrumentClickInUpload extends Component<any, any> {
this.onModeLockOpen(); // 点击了锁定模式
return;
}
this.setState({ zkmoshiindex: index, currentInfo });
this.setState({ modeIndex: index, currentInfo });
};
// 选择图片上传
@ -192,10 +191,15 @@ export default class InstrumentClickInUpload extends Component<any, any> {
let { punchInInfo, instrumentDetail } = this.state;
let obj = punchInInfo;
if (obj.clockImageList.length === 0) {
msg("至少上传一张图片");
msg("至少上传一张图片!");
return;
}
if (!obj.clockContent) {
msg("请输入打卡心得!");
return;
}
// 批量上传图片
let promiseTasks: any = [];
let imgList: any[] = [];
obj.clockImageList.map((imgUrl: string) => {
@ -227,6 +231,11 @@ export default class InstrumentClickInUpload extends Component<any, any> {
}
}
Taro.showLoading({
title: "请求中...",
mask: true,
});
let clockParmas = {
clockImageList: imgList,
clockContent: obj.clockContent,
@ -239,8 +248,13 @@ export default class InstrumentClickInUpload extends Component<any, any> {
params
);
console.log(instrumentRes, "添加仪器成功");
// 上传护理记录
await this.PostNursingLogClock();
// 上传打卡记录
let res = await InstrumentInfo.apiClock.postInsertClockLog(clockParmas);
Taro.hideLoading();
// 打卡完成
if (res.data.code === 200) {
msg("打卡成功");
setTimeout(() => {
@ -251,6 +265,32 @@ export default class InstrumentClickInUpload extends Component<any, any> {
}
};
/** 提交护理记录 */
PostNursingLogClock = async (data: any = null) => {
let { instrumentDetail, currentInfo } = this.state;
let params = {
instrumentId: instrumentDetail.id,
instrumentName: instrumentDetail.name,
modeId: currentInfo.id,
modeName: currentInfo.modeName,
nursingTime: "00:01:00",
};
let res: any = await InstrumentInfo.apiNursingLog.addLog(params);
console.log("PostNursingLogClock", res);
if (res.data.code === 200) {
let params = {
instrumentId: instrumentDetail.id,
};
// 上传护理完成的仪器ID
let res = await InstrumentInfo.apiClock.addClockInstrument(params);
console.log(res, "护理完成");
}
};
/*** 护理记录 END ***/
onPlayTap = async () => {
let { videoContext } = this.state;
videoContext.play();
@ -300,7 +340,6 @@ export default class InstrumentClickInUpload extends Component<any, any> {
duration,
showVideoPlayBtn,
scrollleft,
zkmoshiindex,
punchInInfo,
isTipShow,
currentInfo,
@ -319,119 +358,119 @@ export default class InstrumentClickInUpload extends Component<any, any> {
} = this.state;
return (
<Block>
<Navbar titleSlot='打卡上传' isBack />
<Navbar titleSlot="打卡上传" isBack />
<Canvas
style='position: fixed;left:-10000px;'
id='compressImage'
canvasId='compressImage'
type='2d'
style="position: fixed;left:-10000px;"
id="compressImage"
canvasId="compressImage"
type="2d"
></Canvas>
<View catchMove>
<PopupAlert
isShow={isModeLock}
title='提示'
content='该模式即将上线,敬请期待'
confirmButtonText='我知道了'
textAlgin='center'
title="提示"
content="该模式即将上线,敬请期待"
confirmButtonText="我知道了"
textAlgin="center"
isClose={false}
close={this.onModeLockClose}
confirm={this.onModeLockClose}
/>
<PopupInstrumentUploadTips
isShow={isTipShow}
title='打卡介绍'
title="打卡介绍"
data={nurseInfo}
close={this.onTipShowClose}
confirm={this.onTipShowClose}
/>
</View>
<View className='infobox1 flex aitems jcenter'>
<View className='img'>
<View className="infobox1 flex aitems jcenter">
<View className="img">
<Video
src={currentInfo.modeVideo}
id='myVideo'
id="myVideo"
enableProgressGesture={false}
controls
// autoplay={false}
direction={0}
loop={false}
showMuteBtn
referrerPolicy='origin'
referrerPolicy="origin"
onTimeUpdate={this.videoBindTimeUpdate}
onEnded={this.videoEnded}
onPause={this.videoPause}
onPlay={this.videoPlay}
showCenterPlayBtn={false}
onLoadedMetaData={this.videoLoadedMetaData}
style='width: 100%; height: 100%;border-radius: 30rpx;'
style="width: 100%; height: 100%;border-radius: 30rpx;"
/>
{showVideoPlayBtn && (
<View className='video-cover'>
<View className="video-cover">
<Image
className='video-cover-icon'
className="video-cover-icon"
src={require("@/img/fr200/play.png")}
onClick={this.onPlayTap}
></Image>
{duration && (
<View className='video-cover-time'>{duration}</View>
<View className="video-cover-time">{duration}</View>
)}
</View>
)}
</View>
</View>
<View className='infobox3'>
<View className="infobox3">
<ScrollView
style='white-space: nowrap; height: 100%;'
style="white-space: nowrap; height: 100%;"
scroll-x
scroll-left={scrollleft}
>
{modeInfo.map((item, index) => {
return (
<View
className='info1'
className="info1"
onClick={this.bindMoshi.bind(this, index)}
key={index}
>
<View
className='flex aitems modebox'
className="flex aitems modebox"
style={{
height: "100%",
background:
zkmoshiindex == index
modeIndex == index
? "linear-gradient(90deg, #EFDCC2, #FFF2DF)"
: "",
}}
>
<View className='block1'>
<View className='block1_1 flex aitems '>
<View className='tip1'>{item.modeName}</View>
<View className='tip2'>{item.modeDesc}</View>
<View className="block1">
<View className="block1_1 flex aitems ">
<View className="tip1">{item.modeName}</View>
<View className="tip2">{item.modeDesc}</View>
{!item.lock && zkmoshiindex !== index && (
<View className='quan1'></View>
{!item.lock && modeIndex !== index && (
<View className="quan1"></View>
)}
{!item.lock && zkmoshiindex == index && (
<View className='quan1 is-select flex aitems jcenter'>
<View className='quan2'></View>
{!item.lock && modeIndex == index && (
<View className="quan1 is-select flex aitems jcenter">
<View className="quan2"></View>
</View>
)}
{item.lock && (
<View className='icon'>
<View className="icon">
<Image
src={require("@/img/fr200/suo.png")}
mode='aspectFill'
mode="aspectFill"
></Image>
</View>
)}
</View>
</View>
{item.modeBanner && index == zkmoshiindex && (
<View className='info1_img'>
<Image src={item.modeBanner} mode='aspectFill' />
{item.modeBanner && index == modeIndex && (
<View className="info1_img">
<Image src={item.modeBanner} mode="aspectFill" />
</View>
)}
</View>
@ -441,32 +480,32 @@ export default class InstrumentClickInUpload extends Component<any, any> {
</ScrollView>
</View>
<View className='infobox2'>
<View className='infobox2_info'>
<View className='info4'>
<View className='upload_header flex aitems sb'>
<View className='upload_title'></View>
<View className='icon' onClick={this.onTipShowOpen}>
<View className="infobox2">
<View className="infobox2_info">
<View className="info4">
<View className="upload_header flex aitems sb">
<View className="upload_title"></View>
<View className="icon" onClick={this.onTipShowOpen}>
<Image
src={require("@/img/clock_in_upload/info.png")}
mode='aspectFill'
mode="aspectFill"
></Image>
</View>
</View>
<View className='imgbox flex aitems'>
<View className="imgbox flex aitems">
{punchInInfo.clockImageList.length > 0 &&
punchInInfo.clockImageList.map((item, index) => {
return (
<View className='img' key={"clickin_" + index}>
<View className="img" key={"clickin_" + index}>
<Image src={item}></Image>
<View
className='close flex aitems jcenter'
className="close flex aitems jcenter"
data-index={index}
onClick={this.handleDeleteImage}
>
<Image
src={require("@/img/fr200/close_white.png")}
mode='widthFix'
mode="widthFix"
></Image>
</View>
</View>
@ -475,23 +514,23 @@ export default class InstrumentClickInUpload extends Component<any, any> {
{punchInInfo.clockImageList.length < 3 && (
<View
className='img2 flex aitems jcenter'
className="img2 flex aitems jcenter"
onClick={this.handleChooseImage}
>
<Image
src={require("@/img/fr200/add-image.png")}
mode='aspectFill'
mode="aspectFill"
></Image>
</View>
)}
</View>
<View className='content'>
<View className="content">
<Textarea
placeholder-className="placeh和给g'holder"
maxlength={100}
onInput={this.handleTextareaInput}
value={punchInInfo.clockContent}
placeholder='请记录一下今天打卡的心得吧~'
placeholder="请记录一下今天打卡的心得吧~"
></Textarea>
{/* {tipshow && (
<View className="Textarea">
@ -500,7 +539,7 @@ export default class InstrumentClickInUpload extends Component<any, any> {
: "请记录一下今天打卡的心得吧~"}
</View>
)} */}
<View className='tips-num'>
<View className="tips-num">
{punchInInfo.clockContent.length}/100
{/* {punchInInfo.clockContent.length}/100 */}
</View>
@ -509,16 +548,16 @@ export default class InstrumentClickInUpload extends Component<any, any> {
</View>
</View>
<View style='height: 150rpx'></View>
<View style="height: 150rpx"></View>
{!isSubmit && (
<View className='confirm_btn flex aitems' onClick={this.handleSubmit}>
<View className='btn'></View>
<View className="confirm_btn flex aitems" onClick={this.handleSubmit}>
<View className="btn"></View>
</View>
)}
{isSubmit && (
<View className='confirm_btn flex aitems'>
<View className='btn'></View>
<View className="confirm_btn flex aitems">
<View className="btn"></View>
</View>
)}
</Block>

@ -3,17 +3,19 @@ page {
padding-bottom: calc(env(safe-area-inset-bottom));
}
.list {
margin: 26rpx 30rpx 0rpx;
margin: 38rpx 30rpx 0 30rpx;
border-radius: 50rpx;
padding-bottom: 0rpx;
overflow: hidden;
position: relative;
height: calc(166rpx * 2);
height: 368rpx;
}
.list > .instrument_img {
position: relative;
height: 100%;
/* top: -250rpx; */
image {
background: #eee;
}
}
.list > .instrument_img .bind_status {
position: absolute;

@ -63,11 +63,11 @@ export default class InstrumentDetail extends Component<any, any> {
<Image src={info.instrumentBanner} />
<View className="bind_status"></View>
<View className="titile">{info.instrumentName}</View>
{/* {info.iot == 2 && (
{info.instrumentIotVersion && (
<View className="iot_versions">
{info.iot_versions}
{info.instrumentIotVersion}
</View>
)} */}
)}
</View>
</View>
</Block>

@ -1,3 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "设备管理",
enablePageMeta: true,
});

@ -4,7 +4,7 @@ page {
}
.instrument_box {
.title {
margin: 35rpx 37rpx;
margin: 34rpx 48rpx;
font-size: 32rpx;
font-weight: bold;
color: #030000;
@ -24,7 +24,7 @@ page {
}
.bind_list {
height: 650rpx;
height: 630rpx;
.wrapper {
display: inline-block;
@ -37,7 +37,7 @@ page {
font-size: 24rpx;
left: 40rpx;
padding: 6rpx 40rpx;
background: linear-gradient(90deg, #fff0da, #ffe4c0);
background: linear-gradient(90deg, #ffe4c0, #ffedce);
border-radius: 30rpx;
}
}
@ -61,7 +61,7 @@ page {
color: #000000;
width: 100%;
line-height: 1;
margin: 30rpx 0;
margin: 30rpx 0 35rpx 0;
box-sizing: border-box;
}
.intro {
@ -100,10 +100,12 @@ page {
font-size: 36rpx;
font-weight: bold;
color: #000000;
margin-top: 60rpx;
}
.bindinfo {
/* display: block; */
margin: 0 auto;
margin-top: 43rpx;
width: 240rpx;
height: 60rpx;
line-height: 60rpx;

@ -12,6 +12,7 @@ import {
ScrollView,
Swiper,
SwiperItem,
PageMeta,
} from "@tarojs/components";
import "./index.less";
@ -54,18 +55,19 @@ export default class InstrumentManage extends Component<any, any> {
componentDidHide() {}
async initData() {
Taro.showLoading({
title: "请求中...",
mask: true,
});
this.bindingInstrumentList();
this.unbindingInstrumentInfoList();
Taro.hideLoading();
}
// 获取已绑定仪器列表
bindingInstrumentList = async () => {
Taro.showLoading({
title: "请求中...",
mask: true,
});
let { data: res } = await InstrumentInfo.bindingInstrumentList();
Taro.hideLoading();
if (res.code === 200) {
this.setState({ bindList: res.data });
} else {
@ -74,12 +76,7 @@ export default class InstrumentManage extends Component<any, any> {
};
// 获取未绑定仪器列表
unbindingInstrumentInfoList = async () => {
Taro.showLoading({
title: "请求中...",
mask: true,
});
let { data: res } = await InstrumentInfo.unbindingInstrumentInfoList();
Taro.hideLoading();
if (res.code === 200) {
this.setState({ unBindList: res.data });
} else {
@ -136,6 +133,7 @@ export default class InstrumentManage extends Component<any, any> {
let { bindList, unBindList, current } = this.state;
return (
<Block>
{/* <PageMeta pageOrientation="landscape"></PageMeta> */}
<Navbar
titleSlot="设备管理"
background="#fff"
@ -208,7 +206,7 @@ export default class InstrumentManage extends Component<any, any> {
<Block>
<View className="title"></View>
<View className="scroll">
<ScrollView scroll-x="true" className="un_bind_list">
<ScrollView scrollX={true} className="un_bind_list">
{unBindList.map((item, index) => {
if (item.status === 0) {
return (

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: 'FR200',
  enablePageMeta: true
})

@ -1,8 +1,20 @@
@import url(./WL200.less);
.music {
width: 54rpx;
height: 54rpx;
background: rgba(255, 255, 255, 0.6);
border-radius: 50%;
position: absolute;
right: 20rpx;
top: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.fr200-iot-device {
width: 690rpx;
height: 150rpx;
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
@ -48,3 +60,7 @@
.show {
display: none;
}
.echart-rotate {
transform: rotate(90deg);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1 @@
@import url(./WL200.less);

File diff suppressed because it is too large Load Diff

@ -10,33 +10,29 @@
height: 790rpx;
background-color: #fff;
border-radius: 30rpx;
.music-btn {
position: absolute;
top: 17rpx;
right: 17rpx;
.music {
width: 54rpx;
height: 54rpx;
background: #f8f8f8;
background: rgba(255, 255, 255, 0.6);
border-radius: 50%;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
.music-btn_icon {
width: 54rpx;
height: 54rpx;
position: absolute;
right: 20rpx;
top: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.video-or-image {
display: block;
width: 690rpx;
height: 640rpx;
height: 690rpx;
border-radius: 30rpx;
animation-iteration-count: 1; // gif只播放一次
}
.iot-device {
width: 690rpx;
height: 150rpx;
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;

@ -272,7 +272,12 @@ class IotCarePlanWL200 extends Component<any, any> {
title: obj.name,
});
Taro.showLoading({
title: "请求中...",
mask: true,
});
await this.GetModeList(obj.id);
Taro.hideLoading();
// 如果不存在设备模式值,则判断为首次进入,弹窗提示
let isFirstTipShow = getStorageSync("first_instrument_" + obj.id);
@ -541,8 +546,11 @@ class IotCarePlanWL200 extends Component<any, any> {
};
// 取消并关闭切换护理模式弹窗
cancelModeSwitchBtn = () => {
let { ActiveModeItem } = this.state;
this.setState({
isSwitchActiveMode: false,
activeModeID: ActiveModeItem?.id,
ModeID: "mode_" + ActiveModeItem?.id,
});
};
// 弹窗确定切换护理模式
@ -1928,7 +1936,10 @@ class IotCarePlanWL200 extends Component<any, any> {
goFaceReport = () => {
// 跳转前置空定时器,防止重复提交
if (currentTimeTimer) clearInterval(currentTimeTimer);
go("/recording/pages/face_report/face_report?id=" + this.state.currentDevice.id);
go(
"/recording/pages/face_report/face_report?id=" +
this.state.currentDevice.id
);
};
// 完成配对
@ -2311,7 +2322,15 @@ class IotCarePlanWL200 extends Component<any, any> {
</Block>
)}
</View>
<View
className="music flex aitems jcenter"
onClick={this.handleClicksound.bind(this)}
>
<Image
src={require(`@/img/${isMuted ? "mute" : "play"}.png`)}
mode="aspectFill"
></Image>
</View>
<View className="iot-device">
<View className="item">
<Text className="device-time">

@ -0,0 +1,344 @@
import Taro from "@tarojs/taro";
import { debounce } from "lodash";
import {
notifyBLECharacteristicValueChange,
sendCommand,
} from "@/utils/bluetoothWXAPI";
import {
deviceCommandSamples,
bleCommandSamples,
} from "@/components/bluetoot/connection/wl200";
/** 基础版:脸部/眼部/PRO 设备使用时,会自动开启暂停 */
const BaseModeType: string[] = [
"face",
"eyes",
"nasolabialFold",
"mandibularLine",
"headLiftingPro",
];
/**
* @name
* @description
*/
export default class BluetoothContainer {
bluetoothInfo: any;
deviceToolKitInstance: any;
that: any;
counter: number = 0; // 初始化后,同步执行次数
constructor(bluetoothInfo: any, deviceToolKitInstance: any, that: any) {
this.bluetoothInfo = bluetoothInfo;
this.deviceToolKitInstance = deviceToolKitInstance;
this.that = that;
}
/** @name 设备响应:待机 */
private syncStandby(jsonStatus) {
if (BaseModeType.includes(jsonStatus.workMode)) {
this.that.openTips("检测到您的设备没有紧贴肌肤,请紧贴肌肤");
}
}
/** @name 设备响应:工作 */
private syncWorking(jsonStatus) {
// 脸部模式
if (BaseModeType.includes(jsonStatus.workMode)) {
this.that.closeTips();
}
}
/** @name 设备响应:暂停 */
private syncPause(jsonStatus) {
if (BaseModeType.includes(jsonStatus.workMode)) {
this.that.openTips(
"检测到您的设备没有紧贴肌肤,请紧贴肌肤后重新尝试"
);
}
}
/** @name 查询信息响应 */
private InfoQuery = {
/** @name 设备响应:离线记录 */
syncOfflineClockInInfo: function (jsonStatus) {
console.log("离线记录", jsonStatus);
},
/** @name 设备响应:版本信息 */
syncVersionInfo: function (jsonStatus) {
console.log("版本信息", jsonStatus);
},
/** @name 设备响应:时间同步 */
syncTimeSync: function (jsonStatus) {
console.log("时间同步", jsonStatus);
}
}
/** @name 设备响应:通用状态响应 */
private syncCommonStatus(jsonStatus) {
// 1.判断是否水分测试
if (jsonStatus.workMode === "moistureTest") {
if (jsonStatus.testStatus === "success") {
let waterStepList = this.that.state.waterStepList;
// 到达第几个step
let waterStepIndex = this.that.state.waterStepIndex;
// 代表5秒以后最后拿到的结果
if (waterStepList[waterStepIndex].finish) {
// 获取等级
waterStepList[waterStepIndex].forehead =
jsonStatus.waterLevel;
// 检测完成
if (waterStepIndex === 2) {
this.that.setState({
isRuningTest: 4,
});
} else {
// 启动检测
this.that.setState({
isRuningTest: 1,
});
}
// 一共有3条数据
let num = waterStepIndex;
if (waterStepIndex < 2) {
num = waterStepIndex + 1;
this.that.waterTestNext(num);
}
this.that.setState({
waterStepIndex: num,
waterStepList,
});
}
} else {
let waterStepList = this.that.state.waterStepList;
let waterStepIndex = this.that.state.waterStepIndex;
// 5秒后获取的结果
if (waterStepList[waterStepIndex].finish) {
// 获取失败后把进度条清理0
waterStepList[waterStepIndex].schedule = 0;
waterStepList[waterStepIndex].finish = false;
this.that.setState({
waterStepList,
isRuningTest: 3,
});
}
}
}
// 2.判断工作状态是否与选中仪器一致
if (jsonStatus?.workMode === this.that.state.ActiveModeItem?.modeType) {
if (this.that.state.workMode !== jsonStatus?.workMode) {
this.that.setState({
workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时,才允许改变小程序变量缓存
});
}
console.log("this.that.isRuning",this.that.isRuning)
// 判断设备是否在运行中(护理中)
// 仅当设备模式与小程序是否一致,才允许更改设备运行时间
if (this.that.isRuning) {
if (
this.that.state.DeviceConnectStatus === 1 &&
jsonStatus.workStatus !== 'end'
) {
// 水分测试手动检测时间,不自动计算倒计时
if (jsonStatus?.workMode !== "moistureTest")
this.that.updateDeviceSyncData(
{
totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
},
jsonStatus
);
}
}
}
}
/** @name 设备响应:控制指令响应 */
private syncDeviceControl(jsonStatus) {
console.log("设备控制响应", jsonStatus);
if (jsonStatus.responseStatus == "OK") {
console.log("发送控制指令成功");
this.that.workJsonStatus = jsonStatus;
this.that.workStatus = jsonStatus.workStatus;
setTimeout(() => console.log("this.workStatus", this.that.workStatus));
if (jsonStatus.battery) {
this.that.setState({
Electricity: jsonStatus.battery,
});
}
// 判断设备主动上报的关机事件
if (jsonStatus.workStatus === 'end') {
// 判断id是否一致, 一致的话则生成护理报表, 并提示
if (jsonStatus.id == this.that.FR200NursingHistory.id) {
debounce(
this.that.checkInstrumentRecord.bind(this, jsonStatus),
500
);
}
return;
}
if (jsonStatus?.workMode === this.that.state.ActiveModeItem?.modeType) {
this.that.setState({
workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时,才允许改变小程序变量缓存
});
// 判断是否在isRuning(护理中)
// 仅当设备模式与小程序是否一致,才允许更改设备运行时间
if (
this.that.state.DeviceConnectStatus === 1 &&
this.that.isRuning &&
jsonStatus.workStatus !== 'end'
) {
this.that.updateDeviceSyncData(
{
totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
},
jsonStatus
);
}
}
if (
jsonStatus.workMode === 'working' &&
this.that.isRuning
) {
const { ActiveModeItem } = this.that.state;
const item = ActiveModeItem;
if (jsonStatus.workMode !== item?.modeType) {
// clearTimeout(loadingTipsTimer);
this.that.setState({
isShowCountdown: false,
});
}
}
}
}
notifyBLECharacteristicValueChange() {
notifyBLECharacteristicValueChange({
deviceId: this.bluetoothInfo.deviceId,
servicesuuid: this.bluetoothInfo.servicesuuid,
characteristicsuuid1: this.bluetoothInfo.characteristicsuuid1,
characteristicsuuid0: this.bluetoothInfo.characteristicsuuid0,
}).then((res) => {
Taro.onBLECharacteristicValueChange((value) => {
const jsonStatus: any = this.deviceToolKitInstance.toJsonStatus(value.value);
console.log("onBLECharacteristicValueChange 订阅改变:", jsonStatus);
if (!jsonStatus || jsonStatus == null) {
return;
}
this.that.workStatus = jsonStatus.workStatus; // 记录工作状态
// end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而言处理流程都一样
if (jsonStatus.workStatus && jsonStatus.workStatus == "endWork") {
jsonStatus.workStatus = "end";
console.log(jsonStatus.workStatus, "护理结束");
}
switch (jsonStatus?.commandType) {
//设备配对和连接的返回
case "BleMatch":
// 蓝牙相关指令
this.that.switchBLEMatch(jsonStatus);
break;
//设备状态同步
case "DeviceStatusSync":
if (jsonStatus.battery) {
// 防止抖动
this.that.setState({
Electricity: jsonStatus.battery,
});
}
switch (jsonStatus.workStatus) {
case "standby":
//设备的待机状态 可能workMode字段为空
this.syncStandby(jsonStatus)
break;
case "pause":
this.syncPause(jsonStatus)
break;
case "working":
this.syncWorking(jsonStatus)
break;
default:
break;
}
this.syncCommonStatus(jsonStatus);
break;
//设备对控制指令的响应
case "DeviceControl":
this.syncDeviceControl(jsonStatus);
break;
// 设备对信息查询指令的响应
case "InfoQuery":
console.log("设备对信息查询指令的响应 InfoQuery", jsonStatus);
switch (jsonStatus.infoQueryType) {
// 离线记录
case "offlineClockInInfo":
this.InfoQuery.syncOfflineClockInInfo(jsonStatus);
break;
// 版本信息
case "versionInfo":
this.InfoQuery.syncVersionInfo(jsonStatus);
break;
// 时间同步
case "timeSync":
this.InfoQuery.syncTimeSync(jsonStatus);
break;
default:
break;
}
break;
default:
break;
}
});
if (this.counter < 3) {
/**
* 500
*/
const queryDeviceArrayBuffer = this.deviceToolKitInstance.toBleCommand(
bleCommandSamples.queryDeviceStatus as any
);
setTimeout(() => {
console.log("发送查询设备电量指令");
sendCommand({
value: queryDeviceArrayBuffer,
});
}, 500);
this.counter++;
} else {
/**
* 500
*/
const queryDeviceArrayBuffer = this.deviceToolKitInstance.toBleCommand(
bleCommandSamples.queryDeviceStatus as any
);
setTimeout(() => {
console.log("发送查询设备电量指令");
sendCommand({
value: queryDeviceArrayBuffer,
});
}, 20000);
}
});
}
}

@ -0,0 +1,418 @@
import Taro from "@tarojs/taro";
import { debounce } from "lodash";
import {
notifyBLECharacteristicValueChange,
sendCommand,
} from "@/utils/bluetoothWXAPI";
import {
WE100BleCommand,
WE100DeviceControlCommand,
} from "@/components/bluetoot/connection/we100";
/**
* @name
* @description
*/
export default class BluetoothContainer {
bluetoothInfo: any;
deviceToolKitInstance: any;
that: any;
counter: number = 0; // 初始化后,同步执行次数
constructor(bluetoothInfo: any, deviceToolKitInstance: any, that: any) {
this.bluetoothInfo = bluetoothInfo;
this.deviceToolKitInstance = deviceToolKitInstance;
this.that = that;
}
// 主动改变状态
public DeviceControl = {
/** @name 设置模式 */
workByPatitionSet: (workMode = '', gearTakeEffectOffline = false, partitionStatus = [{ gear: 0 }, { gear: 3 }, { gear: 2 }, { gear: 5 }]) => {
let sendParams: any = {
...WE100DeviceControlCommand.workByPatitionSet,
workMode: workMode, // 使用模式
gearTakeEffectOffline: gearTakeEffectOffline, // 是否离线生效
partitionStatus: partitionStatus // 默认用官配模式
};
const pauseArrayBuffer = this.deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
}).then(() => {
this.that.workStatus = 'pause';
this.that.resetTimer();
console.info(`发送暂停指令成功 参数为 =>`, sendParams);
});
},
/** @name 设备控制:准备 */
standby: (workMode = '') => {
let sendParams: any = {
...WE100DeviceControlCommand.pause,
workMode: workMode, // 使用模式
};
const pauseArrayBuffer = this.deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
}).then(() => {
this.that.workStatus = 'standby';
this.that.resetTimer();
console.info(`发送暂停指令成功 参数为 =>`, sendParams);
});
},
/** @name 设备控制:暂停 */
pause: (workMode = '') => {
let sendParams: any = {
...WE100DeviceControlCommand.pause,
workMode: workMode, // 使用模式
};
const pauseArrayBuffer = this.deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
}).then(() => {
this.that.workStatus = 'pause';
this.that.resetTimer();
console.info(`发送暂停指令成功 参数为 =>`, sendParams);
});
},
/** @name 设备控制:工作 */
working: (workMode = '') => {
let sendParams: any = {
...WE100DeviceControlCommand.pause,
workMode: workMode, // 使用模式
};
const pauseArrayBuffer = this.deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
}).then(() => {
this.that.workStatus = 'working';
this.that.resetTimer();
console.info(`发送工作指令成功 参数为 =>`, sendParams);
});
},
/** @name 设备控制:结束 */
end: (workMode = '') => {
let sendParams: any = {
...WE100DeviceControlCommand.pause,
workMode: workMode, // 使用模式
};
const pauseArrayBuffer = this.deviceToolKitInstance.toBleCommand(
sendParams as any
);
sendCommand({
value: pauseArrayBuffer,
}).then(() => {
this.that.workStatus = 'end';
this.that.resetTimer();
console.info(`发送结束指令成功 参数为 =>`, sendParams);
});
},
syncOfflineSummary: () => {
const queryOfflineSummary = this.deviceToolKitInstance.toBleCommand({
...WE100BleCommand.InfoQuery.offlineSummary
});
sendCommand({
value: queryOfflineSummary,
});
},
syncOfflineDetail: () => {
const queryOfflineDetail = this.deviceToolKitInstance.toBleCommand({
...WE100BleCommand.InfoQuery.offlineDetail
});
sendCommand({
value: queryOfflineDetail,
});
}
}
// 工作状态改变的相应
/** @name 设备响应:待机 */
private syncStandby(jsonStatus) {
console.log("上报待机", jsonStatus)
}
/** @name 设备响应:工作 */
private syncWorking(jsonStatus) {
console.log("上报工作", jsonStatus)
}
/** @name 设备响应:暂停 */
private syncPause(jsonStatus) {
console.log("上报暂停", jsonStatus)
}
/** @name 查询信息响应 */
private InfoQuery = {
/** @name 离线记录 */
syncOfflineClockSummary: function (jsonStatus) {
console.log("离线记录", jsonStatus);
},
/** @name 离线记录详情 */
syncOfflineClockDetail: function (jsonStatus) {
console.log("离线记录详情", jsonStatus);
},
/** @name 现在的面膜上报信息 */
syncCurrentFacialReportInfo: function (jsonStatus) {
console.log("现在的面膜上报信息", jsonStatus);
},
/** @name 查询响应:自定义电流配方模式面膜模式 */
syncFacialMaskCustomModeInfo: function (jsonStatus) {
console.log("查询响应:自定义电流配方模式面膜模式", jsonStatus);
},
/** @name 设置响应:自定义电流配方模式面膜模式 */
syncFacialMaskCustomModeSet: function (jsonStatus) {
console.log("设置响应:自定义电流配方模式面膜模式", jsonStatus);
},
/** @name 查询响应M02自定义面膜信息 */
syncM02MaskCustomModeInfo: function (jsonStatus) {
console.log("查询响应M02自定义面膜信息", jsonStatus);
},
/** @name 设置响应:眼雕大师自定义、妆前急救自定义面膜模式 */
syncM02MaskCustomModeSet: function (jsonStatus) {
console.log("设置响应:眼雕大师自定义、妆前急救自定义面膜模式", jsonStatus);
},
/** @name 版本信息 */
syncVersionInfo: function (jsonStatus) {
console.log("版本信息", jsonStatus);
},
/** @name 设备响应:时间同步 */
syncTimeSync: function (jsonStatus) {
console.log("时间同步", jsonStatus);
}
}
/** @name 设备响应:通用状态响应 */
private syncCommonStatus(jsonStatus) {
}
/** @name 设备响应:控制指令响应 */
private syncDeviceControl(jsonStatus) {
console.log("设备控制响应", jsonStatus);
if (jsonStatus.responseStatus == "OK") {
console.log("发送控制指令成功");
this.that.workJsonStatus = jsonStatus;
this.that.workStatus = jsonStatus.workStatus;
if (jsonStatus.battery) {
this.that.setState({
Electricity: jsonStatus.battery,
});
}
// 判断设备主动上报的关机事件
if (jsonStatus.workStatus === 'end') {
// 判断id是否一致, 一致的话则生成护理报表, 并提示
if (jsonStatus.id == this.that.WE200NursingHistory.id) {
debounce(
this.that.checkInstrumentRecord.bind(this, jsonStatus),
500
);
}
return;
}
if (jsonStatus?.workMode === this.that.state.ActiveModeItem?.modeType) {
this.that.setState({
workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时,才允许改变小程序变量缓存
});
// 判断是否在isRuning(护理中)
// 仅当设备模式与小程序是否一致,才允许更改设备运行时间
if (
this.that.state.DeviceConnectStatus === 1 &&
this.that.isRuning &&
jsonStatus.workStatus !== 'end'
) {
this.that.updateDeviceSyncData(
{
totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
},
jsonStatus
);
}
}
if (
jsonStatus.workMode === 'working' &&
this.that.isRuning
) {
const { ActiveModeItem } = this.that.state;
const item = ActiveModeItem;
if (jsonStatus.workMode !== item?.modeType) {
// clearTimeout(loadingTipsTimer);
this.that.setState({
isShowCountdown: false,
});
}
}
}
}
notifyBLECharacteristicValueChange() {
notifyBLECharacteristicValueChange({
deviceId: this.bluetoothInfo.deviceId,
servicesuuid: this.bluetoothInfo.servicesuuid,
characteristicsuuid1: this.bluetoothInfo.characteristicsuuid1,
characteristicsuuid0: this.bluetoothInfo.characteristicsuuid0,
}).then((res) => {
Taro.onBLECharacteristicValueChange((value) => {
const jsonStatus: any = this.deviceToolKitInstance.toJsonStatus(value.value);
console.log("onBLECharacteristicValueChange 订阅改变:", jsonStatus);
if (!jsonStatus || jsonStatus == null) {
return;
}
this.that.workStatus = jsonStatus.workStatus; // 记录工作状态
// end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而言处理流程都一样
if (jsonStatus.workStatus && jsonStatus.workStatus == "endWork") {
jsonStatus.workStatus = "end";
console.log(jsonStatus.workStatus, "护理结束");
}
switch (jsonStatus?.commandType) {
//设备配对和连接的返回
case "BleMatch":
// 蓝牙相关指令
this.that.switchBLEMatch(jsonStatus);
break;
//设备状态同步
case "DeviceStatusSync":
if (jsonStatus.battery) {
// 防止抖动
this.that.setState({
Electricity: jsonStatus.battery,
});
}
switch (jsonStatus.workStatus) {
case "standby":
//设备的待机状态 可能workMode字段为空
this.syncStandby(jsonStatus)
break;
case "pause":
this.syncPause(jsonStatus)
break;
case "working":
this.syncWorking(jsonStatus)
break;
default:
break;
}
this.syncCommonStatus(jsonStatus);
break;
//设备对控制指令的响应
case "DeviceControl":
this.syncDeviceControl(jsonStatus);
break;
// 设备对信息查询指令的响应
case "InfoQuery":
console.log("设备对信息查询指令的响应 InfoQuery", jsonStatus);
switch (jsonStatus.infoQueryType) {
// 离线记录
case "offlineClockSummary":
this.InfoQuery.syncOfflineClockSummary(jsonStatus)
break;
// 离线记录详情
case "offlineClockDetail":
this.InfoQuery.syncOfflineClockDetail(jsonStatus);
break;
// 现在的面膜报告信息
case "currentFacialReportInfo":
this.InfoQuery.syncCurrentFacialReportInfo(jsonStatus);
break;
// 查询:自定义电流配方模式面膜模式
case "facialMaskCustomModeInfo":
this.InfoQuery.syncFacialMaskCustomModeInfo(jsonStatus);
break;
// 设置:自定义电流配方模式面膜模式
case "facialMaskCustomModeSet":
this.InfoQuery.syncFacialMaskCustomModeSet(jsonStatus);
break;
// 查询M02自定义面膜信息
case "m02MaskCustomModeInfo":
this.InfoQuery.syncM02MaskCustomModeInfo(jsonStatus);
break;
// 设置:眼雕大师自定义、妆前急救自定义面膜模式
case "m02MaskCustomModeSet":
this.InfoQuery.syncM02MaskCustomModeSet(jsonStatus);
break;
// 版本信息
case "versionInfo":
this.InfoQuery.syncVersionInfo(jsonStatus);
break;
// 时间同步
case "timeSync":
this.InfoQuery.syncTimeSync(jsonStatus);
break;
default:
break;
}
break;
default:
break;
}
});
if (this.counter < 3) {
/**
* 600
*/
const querySubDeviceArrayBuffer = this.deviceToolKitInstance.toBleCommand({
...WE100BleCommand.querySubDevice,
queryType: "WE100",
} as any);
setTimeout(() => {
console.log("发送查询附属设备指令 querySubDeviceArrayBuffer");
sendCommand({
value: querySubDeviceArrayBuffer,
});
}, 600);
/**
* 500
*/
const queryDeviceArrayBuffer = this.deviceToolKitInstance.toBleCommand(
WE100BleCommand.queryDeviceStatus as any
);
setTimeout(() => {
console.log("发送查询设备电量指令");
sendCommand({
value: queryDeviceArrayBuffer,
});
}, 500);
this.counter++;
} else {
/**
* 500
*/
const queryDeviceArrayBuffer = this.deviceToolKitInstance.toBleCommand(
WE100BleCommand.queryDeviceStatus as any
);
setTimeout(() => {
console.log("发送查询设备电量指令");
sendCommand({
value: queryDeviceArrayBuffer,
});
}, 20000);
}
});
}
}

@ -1,4 +1,4 @@
.box {
.echart-component {
width: 690rpx;
height: 320rpx;
margin: 28rpx auto 150rpx;
@ -7,16 +7,6 @@
padding: 35rpx 25rpx 25rpx 35rpx;
box-sizing: border-box;
position: relative;
// writing-mode: vertical-lr;
// text-orientation: upright;
// white-space: nowrap;
// font-size: 18px;
// font-weight: bold;
// background-color: #c2e5f3;
// color: #fff;
// width: 100%;
}
.fullscreen {
@ -33,7 +23,7 @@
// animation: rotate 0s linear;
}
@keyframes rotate {
@keyframes echartRotate {
from {
width: 690rpx;
height: 320rpx;
@ -88,7 +78,16 @@
color: #fff;
}
}
.time_list {
position: absolute;
bottom: 28rpx;
left: 72rpx;
font-family: PingFang-SC;
font-size: 15rpx;
color: #cccccc;
width: 540rpx;
justify-content: space-around;
}
.time {
position: absolute;
bottom: 22rpx;
@ -99,6 +98,17 @@
}
}
.echart-component-full {
width: 690rpx;
height: 320rpx;
margin: 0rpx auto;
background-color: #fff;
border-radius: 30rpx;
padding: 35rpx 25rpx 25rpx 35rpx;
box-sizing: border-box;
position: relative;
}
page {
background: #f8f8f8;
background: #f3f3f3;

@ -9,13 +9,12 @@ import echarts from "@/utils/echarts.min.js";
import "./index.less";
interface Props {
data: any
series: any;
full: any;
time: any
}
function Index({ data }: Props) {
const buttonRef = useRef(null);
function Index({ series, full, time }: Props) {
const echartsRef = useRef<EchartsHandle>(null);
const [options, setOptions] = useState({
animation: false,
@ -51,24 +50,13 @@ function Index({ data }: Props) {
},
axisLabel: {
//坐标轴刻度标签的相关设置
color: "#cccccc",
fontSize: 8,
color: "#fff",
fontSize: 1,
},
axisTick: {
show: false,
},
data: [
"00:01",
"00:02",
"00:03",
"00:04",
"00:05",
"00:06",
"00:07",
"00:08",
"00:09",
"00:10",
],
data: [],
},
yAxis: {
type: "value",
@ -145,210 +133,220 @@ function Index({ data }: Props) {
color: "#ff8410",
},
},
series: [
{
data: [2, 3, 5, 3, 5, 6, 8, 5, 6, 4],
type: "line",
smooth: true,
z: 1,
areaStyle: {},
color: "red",
},
{
data: [2, 3, 5, 3, 5, 6, 8, 5, 6, 4],
type: "line",
smooth: true,
symbolSize: 5,
lineStyle: {
color: "#ff8410",
width: 1,
},
itemStyle: {
color: "#ff8410",
},
},
{
name: "a",
data: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
type: "bar",
barWidth: 12,
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#ffcf56",
},
},
{
name: "b",
data: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
type: "bar",
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#febb22",
},
},
{
name: "c",
data: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
type: "bar",
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#ffac28",
},
},
{
name: "d",
data: [0, 0, 1, 0, 1, 1, 1, 1, 1, 1],
type: "bar",
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#ff8410",
},
},
{
name: "e",
data: [0, 0, 1, 0, 1, 1, 1, 1, 1, 0],
type: "bar",
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#f85804",
},
},
{
name: "f",
data: [0, 0, 0, 0, 0, 1, 1, 0, 1, 0],
type: "bar",
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#e02e14",
},
},
{
name: "h",
data: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
type: "bar",
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#b30016",
},
},
{
name: "i",
data: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
type: "bar",
z: 2,
stack: "x",
visualMap: false,
itemStyle: {
color: "#750010",
},
},
],
series: []
})
// let data = true
// const newParams = {
// animation: false,
// grid: {
// // 让图表占满容器
// // containLabel: true,
// top: "32rpx",
// left: "48rpx",
// right: "86rpx",
// bottom: "38rpx",
// },
// // legend: {
// // itemStyle: {
// // decal: {
// // rotation: 90
// // }
// // }
// // },
// yAxis: {
// // name: '',
// // nameGap: 5,
// // nameTextStyle: {
// // color: '#e4e4e4',
// // fontSize:7
// // },
// type: "category",
// inverse: true,
// axisLine: {
// //坐标轴轴线相关设置。数学上的x轴
// show: true,
// lineStyle: {
// color: "#cccccc",
// },
// },
// axisLabel: {
// //坐标轴刻度标签的相关设置
// color: "#cccccc",
// fontSize: 14,
// rotate: -90,
// margin: 18
// },
// axisTick: {
// show: false,
// },
// data: [
// "00:01",
// "00:02",
// "00:03",
// "00:04",
// "00:05",
// "00:06",
// "00:07",
// "00:08",
// "00:09",
// "00:10",
// ],
// },
// xAxis: {
// type: "value",
// min: 0,
// max: 8,
// splitNumber: 8,
// splitLine: {
// show: true,
// lineStyle: {
// color: "#cccccc",
// type: [4, 2],
// dashOffset: 4,
// },
// },
// axisLine: {
// show: false,
// },
// axisLabel: {
// show: false,
// },
// axisTick: {
// show: false,
// },
// },
// visualMap: {
// z: 1,
// top: 0,
// right: 0,
// seriesIndex: 0,
// show: false,
// dimension: 0,
// pieces: [
// {
// gt: 0,
// lte: 1,
// color: "#fff8c9",
// },
// {
// gt: 1,
// lte: 2,
// color: "#fff0c6",
// },
// {
// gt: 2,
// lte: 3,
// color: "#ffe5c3",
// },
// {
// gt: 3,
// lte: 4,
// color: "#ffdbbf",
// },
// {
// gt: 4,
// lte: 5,
// color: "#ffcfbb",
// },
// {
// gt: 5,
// lte: 6,
// color: "#ffbab5",
// },
// {
// gt: 6,
// lte: 7,
// color: "#ffb4b3",
// },
// {
// gt: 7,
// lte: 8,
// color: "#ffb4b3",
// },
// ],
// outOfRange: {
// color: "#ff8410",
// },
// },
// series: []
// }
const level = [8, 7, 6, 5, 4, 3, 2];
const [newOptions, setNewOptions] = useState(options)
const [newData, setNewData] = useState(0)
const full = useCallback(() => {
// let box = document.getElementById("box");
// box?.classList.add('fullscreen')
const [isFull, setIsfull] = useState(false)
const [data, setData] = useState([
"00:01",
"00:02",
"00:03",
"00:04",
"00:05",
"00:06",
"00:07",
"00:08",
"00:09",
"00:10",
],)
const [newOptions, setNewOptions] = useState(options);
let stop = 0
// let time = setInterval(function () {
// stop++
const updata = useCallback((res, times) => {
if (times.second == 0) {
return
}
// let option
// if (data) {
// option = JSON.parse(JSON.stringify(newParams))
// } else {
// option = JSON.parse(JSON.stringify(options))
// }
let option = JSON.parse(JSON.stringify(options))
let num = Math.floor(Math.random() * 9)
let count = 0
options.series.map(item => {
if (item.type === 'line') {
item.data.splice(0, 1)
item.data.push(num)
}
if (item.type === 'bar') {
count++
item.data.splice(0, 1)
if (count <= num) {
item.data.push(1)
} else {
item.data.push(0)
}
}
})
console.log(option);
let datas = JSON.parse(JSON.stringify(data))
if (times.min > 0 || times.second > 10) {
datas.splice(0, 1)
datas.push(formatTime(times))
}
setData(JSON.parse(JSON.stringify(datas)))
// option.xAxis.data = data
option.series = JSON.parse(JSON.stringify(res))
// 更新图表数据
setNewOptions(option)
// if (stop > 20) {
// clearInterval(time)
// }
// }, 1000)
}, [data])
setNewOptions(option);
}, [data]);
useEffect(() => {
setOptions(newOptions)
}, [newOptions]);
useEffect(() => {
setNewData(data)
}, [data]);
function formatTime(times: any) {
let mins
if (times.min < 10) {
mins = '0' + times.min;
} else {
mins = times.min;
}
let secs
if (times.second < 10) {
secs = '0' + times.second;
} else {
secs = times.second;
}
return `${mins.toString()}:${secs.toString()}`;
}
useEffect(() => {
let option = JSON.parse(JSON.stringify(options))
let num = Math.floor(newData * 9)
let count = 0
options.series.map(item => {
if (item.type === 'line') {
item.data.splice(0, 1)
item.data.push(num)
}
if (item.type === 'bar') {
count++
item.data.splice(0, 1)
if (count <= num) {
item.data.push(1)
} else {
item.data.push(0)
}
}
})
console.log(option, data);
const cancelFull = useCallback((res) => {
full()
setIsfull(!isFull)
// 更新图表数据
setNewOptions(option)
}, [newData])
// 当 someProp 变化时执行
// const quanping = () => {
// T.setPageOrientation({
// orientation: "portrait",
// });
}, [isFull])
// // taro.setPageOrientation({
// // orientation: "landscape",
// // });
// },
useEffect(() => {
setOptions(newOptions);
}, [newOptions]);
useEffect(() => {
updata(series, time);
}, [series]);
return (
<Block>
<View id='box' className='box'>
<View id='box' className={isFull ? "echart-component-full" : "echart-component"}>
<Echarts
force-use-old-canvas='false'
echarts={echarts}
@ -359,7 +357,11 @@ function Index({ data }: Props) {
style={{ width: "630rpx", height: "260rpx", zIndex: 1 }}
/>
<View className='box_background'>
<Image className='full' ref={buttonRef} src={require("@/img/full-scran.png")} onClick={full}></Image>
<Image
className='full'
src={require("@/img/full-scran.png")}
onClick={cancelFull}
></Image>
<View className='power'></View>
{level.map((item) => (
<View className='line' key={item}>
@ -370,10 +372,17 @@ function Index({ data }: Props) {
<View className='line'>
<View className='number'>1</View>
</View>
<View className='time_list flex'>
{
data.map((times, index) => (
<View key={index}>{times}</View>
))
}
</View>
<View className='time'></View>
</View>
</View>
</Block >
</Block>
);
}

@ -0,0 +1,106 @@
.box_full {
width: 690rpx;
height: 83vh;
margin: 28rpx auto 150rpx;
background-color: #fff;
border-radius: 30rpx;
padding: 35rpx 25rpx 25rpx 35rpx;
box-sizing: border-box;
position: relative;
// writing-mode: vertical-lr;
// text-orientation: upright;
// white-space: nowrap;
// font-size: 18px;
// font-weight: bold;
// background-color: #c2e5f3;
// color: #fff;
// width: 100%;
}
.fullscreen {
position: fixed;
top: 450rpx;
left: -450rpx;
right: 0;
bottom: 0;
width: 100vh;
height: 100vw;
z-index: 9999;
background-color: rgba(0, 0, 0, 0.5); /* 背景色 */
transform: rotate(90deg);
// animation: rotate 0s linear;
}
@keyframes rotate {
from {
width: 690rpx;
height: 320rpx;
transform: rotate(0deg);
}
to {
width: 100vh;
height: 100vw;
transform: rotate(0deg);
}
}
.box_background1 {
position: absolute;
top: 330rpx;
left: -326rpx;
width: 83vh;
height: 690rpx;
border-radius: 30rpx;
background-color: rgba(0, 0, 0, 0);
transform: rotate(90deg);
.power {
margin: 56rpx 0 103rpx 38rpx;
font-family: PingFang-SC;
font-weight: 500;
font-size: 36rpx;
color: #cccccc;
}
.part {
width: 48rpx;
height: 48rpx;
position: absolute;
top: 37rpx;
right: 37rpx;
z-index: 100;
transform: rotate(90deg);
}
.line {
margin: 0 30rpx 0 52rpx;
font-family: PingFang-SC;
font-size: 28rpx;
color: #cccccc;
display: flex;
position: relative;
height: 47rpx;
.bottom_line {
// border-bottom: 1rpx #ccc dashed;
width: 550rpx;
margin-left: 20rpx;
position: absolute;
bottom: -6rpx;
right: 74rpx;
height: 4rpx;
color: #fff;
}
}
.time {
position: absolute;
bottom: 62rpx;
right: 44rpx;
font-family: PingFang-SC;
font-size: 36rpx;
color: #cccccc;
}
}
page {
background: #f8f8f8;
background: #f3f3f3;
}

@ -0,0 +1,213 @@
import Taro from "@tarojs/taro";
import classnames from "classnames";
import { Block, View, Image, Text, Input } from "@tarojs/components";
import { Popup, Progress, Slider } from "@antmjs/vantui";
import { useEffect, useRef, useState, useCallback } from "react";
import Echarts, { EChartOption, EchartsHandle } from "taro-react-echarts";
import echarts from "@/utils/echarts.min.js";
import "./index.less";
interface Props {
series: any,
full: any
}
function Index({ series, full }: Props) {
const echartsRef = useRef<EchartsHandle>(null);
const [options, setOptions] = useState({
animation: false,
grid: {
// 让图表占满容器
// containLabel: true,
top: "32rpx",
left: "48rpx",
right: "86rpx",
bottom: "38rpx",
},
// legend: {
// itemStyle: {
// decal: {
// rotation: 90
// }
// }
// },
yAxis: {
// name: '',
// nameGap: 5,
// nameTextStyle: {
// color: '#e4e4e4',
// fontSize:7
// },
type: "category",
inverse: true,
axisLine: {
//坐标轴轴线相关设置。数学上的x轴
show: true,
lineStyle: {
color: "#cccccc",
},
},
axisLabel: {
//坐标轴刻度标签的相关设置
color: "#cccccc",
fontSize: 14,
rotate: -90,
margin: 18
},
axisTick: {
show: false,
},
data: [
"00:01",
"00:02",
"00:03",
"00:04",
"00:05",
"00:06",
"00:07",
"00:08",
"00:09",
"00:10",
],
},
xAxis: {
type: "value",
min: 0,
max: 8,
splitNumber: 8,
splitLine: {
show: true,
lineStyle: {
color: "#cccccc",
type: [4, 2],
dashOffset: 4,
},
},
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
},
visualMap: {
z: 1,
top: 0,
right: 0,
seriesIndex: 0,
show: false,
dimension: 0,
pieces: [
{
gt: 0,
lte: 1,
color: "#fff8c9",
},
{
gt: 1,
lte: 2,
color: "#fff0c6",
},
{
gt: 2,
lte: 3,
color: "#ffe5c3",
},
{
gt: 3,
lte: 4,
color: "#ffdbbf",
},
{
gt: 4,
lte: 5,
color: "#ffcfbb",
},
{
gt: 5,
lte: 6,
color: "#ffbab5",
},
{
gt: 6,
lte: 7,
color: "#ffb4b3",
},
{
gt: 7,
lte: 8,
color: "#ffb4b3",
},
],
outOfRange: {
color: "#ff8410",
},
},
series: []
})
const level = [8, 7, 6, 5, 4, 3, 2];
const [newOptions, setNewOptions] = useState(options)
const updata = useCallback((res) => {
let option = JSON.parse(JSON.stringify(options))
option.series = JSON.parse(JSON.stringify(res))
console.log(echartsRef,'echartsRefechartsRefechartsRef');
// 更新图表数据
setNewOptions(option)
}, [])
const cancelFull = useCallback((res) => {
full()
}, [])
useEffect(() => {
setOptions(newOptions)
}, [newOptions]);
useEffect(() => {
updata(series)
}, [series])
return (
<Block>
<View id='box' className='box_full'>
<Echarts
force-use-old-canvas='false'
echarts={echarts}
option={options}
ref={echartsRef}
// isPage={false}
// style自定义设置echarts宽高
style={{ width: "620rpx", height: "75vh", zIndex: 1 }}
/>
<View className='box_background1'>
<Image className='part' src={require("@/img/part-scran.png")} onClick={cancelFull}></Image>
<View className='power'></View>
{level.map((item) => (
<View className='line' key={item}>
<View className='number'>{item}</View>
<View className='bottom_line'></View>
</View>
))}
<View className='line'>
<View className='number'>1</View>
</View>
<View className='time'></View>
</View>
</View>
</Block >
);
}
export default Index;

@ -7,44 +7,44 @@ import Echarts, { EChartOption, EchartsHandle } from "taro-react-echarts";
// import echarts from "@/utils/echarts.min.js";
import * as echarts from "echarts";
import React, { useState, useEffect,useMemo } from 'react';
import React, { useState, useEffect, useMemo } from 'react';
import "./index.less";
interface Props {
EchartsData:any
EchartsData: any
}
function Index({
EchartsData
}:Props) {
let type =0
}: Props) {
let type = 0
// console.log(EchartsData,'EchartsDataEchartsData');
switch(EchartsData.modeName) {
switch (EchartsData.modeName) {
case '基础班脸部':
type=37
type = 37
break;
case '基础版眼部':
type=25
type = 25
break;
case '法令纹Pro':
type=25
case '法令纹Pro':
type = 25
break;
case '下颌线Pro':
type=19
case '下颌线Pro':
type = 19
break;
case '抬头纹Pro':
type=13
case '抬头纹Pro':
type = 13
break;
default:
}
}
const echartsRef = useRef<EchartsHandle>(null);
function generateColorArray(startColor, endColor, steps) {
var startRGB = hexToRgb(startColor);
var endRGB = hexToRgb(endColor);
@ -81,33 +81,33 @@ function Index({
const steps = 81; // 80个颜色
const colors = generateColorArray(startColor, endColor, steps);
// const xList = [...new Array(type).fill(0).map((item, key) => key)];
let seriesData:any =[]
seriesData = EchartsData?.data?.groupedAa
const xList = [...new Array(type).fill(0).map((item, key) => key)];
// const seriesData = [
// ...xList.map((item) => {
// return Math.random() * 80;
// }),
// ];
const option: EChartOption = {
grid: {
// 让图表占满容器
top: "10rpx",
left: "45rpx",
right: "28rpx",
bottom: "17rpx",
},
xAxis: {
type: "category",
data: [...xList],
axisLabel: {
interval: 5,
formatter: function (value, index) {
return value * 10 + 's';
},
textStyle: {
const colors = generateColorArray(startColor, endColor, steps);
// const xList = [...new Array(type).fill(0).map((item, key) => key)];
let seriesData: any = []
seriesData = EchartsData?.data?.groupedAa
const xList = [...new Array(type).fill(0).map((item, key) => key)];
// const seriesData = [
// ...xList.map((item) => {
// return Math.random() * 80;
// }),
// ];
const option: EChartOption = {
grid: {
// 让图表占满容器
top: "10rpx",
left: "45rpx",
right: "28rpx",
bottom: "17rpx",
},
xAxis: {
type: "category",
data: [...xList],
axisLabel: {
interval: 5,
formatter: function (value, index) {
return value * 10 + 's';
},
textStyle: {
color: '#999999', // 文字颜色
fontSize: 8 // 文字大小
},
@ -173,90 +173,90 @@ const option: EChartOption = {
},
],
}
// 基于 EchartsData 生成 ECharts 配置
// const option: EChartOption ={
// grid: {
// // 让图表占满容器
// top: "10rpx",
// left: "45rpx",
// right: "28rpx",
// bottom: "17rpx",
// },
// xAxis: {
// type: "category",
// data: [...xList],
// axisLabel: {
// interval: 5,
// formatter: function (value, index) {
// return value * 10 + 's';
// },
// textStyle: {
// color: '#999999', // 文字颜色
// fontSize: 8 // 文字大小
// },
// },
// axisTick: {
// // alignWithLabel: true,
// show: false,
// interval: 9,
// },
// // axisLine: {
// // show: false,
// // },
// },
// yAxis: [
// {
// min: 0,
// max: 80,
// splitNumber: 10,
// axisLabel: {
// formatter: function (value, index) {
// const num = value / 10 + 1
// return num === 9 ? '' : num + '级';
// },
// textStyle: {
// color: '#999999', // 文字颜色
// fontSize: 8 // 文字大小
// },
// },
// type: "value",
// splitLine: {
// lineStyle: {
// color: ["#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#fff"],
// type: 'dashed'
// },
// }
// },
// ],
// series: [
// {
// barCategoryGap: '0%',
// data: seriesData,
// type: "bar",
// // barWidth: 15,
// gapWidth: "0%",
// itemStyle: {
// normal: {
// color: function (params) {
// var value = params.data;
// return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: colors[parseInt(value)], // 红色
// },
// {
// offset: 1,
// color: colors[0], // 黄色
// },
// ]);;
// },
// },
// },
// },
// ],
// };
// 基于 EchartsData 生成 ECharts 配置
// const option: EChartOption ={
// grid: {
// // 让图表占满容器
// top: "10rpx",
// left: "45rpx",
// right: "28rpx",
// bottom: "17rpx",
// },
// xAxis: {
// type: "category",
// data: [...xList],
// axisLabel: {
// interval: 5,
// formatter: function (value, index) {
// return value * 10 + 's';
// },
// textStyle: {
// color: '#999999', // 文字颜色
// fontSize: 8 // 文字大小
// },
// },
// axisTick: {
// // alignWithLabel: true,
// show: false,
// interval: 9,
// },
// // axisLine: {
// // show: false,
// // },
// },
// yAxis: [
// {
// min: 0,
// max: 80,
// splitNumber: 10,
// axisLabel: {
// formatter: function (value, index) {
// const num = value / 10 + 1
// return num === 9 ? '' : num + '级';
// },
// textStyle: {
// color: '#999999', // 文字颜色
// fontSize: 8 // 文字大小
// },
// },
// type: "value",
// splitLine: {
// lineStyle: {
// color: ["#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#ccc", "#fff"],
// type: 'dashed'
// },
// }
// },
// ],
// series: [
// {
// barCategoryGap: '0%',
// data: seriesData,
// type: "bar",
// // barWidth: 15,
// gapWidth: "0%",
// itemStyle: {
// normal: {
// color: function (params) {
// var value = params.data;
// return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: colors[parseInt(value)], // 红色
// },
// {
// offset: 1,
// color: colors[0], // 黄色
// },
// ]);;
// },
// },
// },
// },
// ],
// };
return (

@ -11,12 +11,12 @@
// padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
.btn {
width: 690rpx;
height: 90rpx;
width: 695rpx;
height: 75rpx;
background: #000;
border-radius: 45rpx;
color: #fff;
line-height: 90rpx;
line-height: 75rpx;
text-align: center;
margin: 21rpx 49rpx 42rpx 30rpx;
font-size: 32rpx;

@ -9,7 +9,7 @@ interface Props {
onEmitStartNurse: Function; // 每次点击item回调事件和数据给父组件
onEmitSwitchChange: Function;
onEmitEndPlan: Function;
onsuccess:Function
onsuccess: Function;
}
function Index({
currentWorkModeType,
@ -18,7 +18,7 @@ function Index({
onEmitStartNurse,
onEmitSwitchChange,
onEmitEndPlan,
onsuccess
onsuccess,
}: Props) {
const onStartNurse = () => {
onEmitStartNurse();
@ -31,24 +31,31 @@ function Index({
const onEndPlan = () => {
onEmitEndPlan();
};
const onSuccessNurse = () => {
onsuccess();
};
return (
<Block>
<View className="iot-footer">
{currentWorkModeType === 3 && (
<Block>
{isRuningTest === 1 ? (
<View className="btn" onClick={onStartNurse}>
</View>
) : isRuningTest === 2 ? (
<View className="btn">...</View>
) : isRuningTest === 3 ? (
<View className="btn" onClick={onStartNurse}></View>
) : (
<View className="btn" onClick={onsuccess}></View>
)}
</Block>
{isRuningTest === 1 ? (
<View className="btn" onClick={onStartNurse}>
</View>
) : isRuningTest === 2 ? (
<View className="btn">...</View>
) : isRuningTest === 3 ? (
<View className="btn" onClick={onStartNurse}>
</View>
) : (
<View className="btn" onClick={onSuccessNurse}>
</View>
)}
</Block>
)}
{currentWorkModeType === 2 && (

@ -31,7 +31,6 @@ function Index({
let PermeationList = ModeList.filter((item) => item.modeClass === 3); // 专研促渗
let SensitiveList = ModeList.filter((item) => item.modeClass === 4); // 敏感期护理
let IntelligenceList = ModeList.filter((item) => item.modeClass === 5); // 智能测肤
console.log(activeModeID, "查看id", BaseList, ModeList);
const onItemClick = (item) => {
if (item.lock) {
onModeLockOpen(); // 点击了锁定模式
@ -85,7 +84,9 @@ function Index({
<View className="mode-info">
<View className="mode-info-title">{item.modeName}</View>
<View className="mode-info-time">
{item.modeTimeStr}
{item.modeTimeStr === "00:00"
? "--:--"
: item.modeTimeStr}
</View>
<View
className={classnames("mode-info-select", {
@ -239,7 +240,7 @@ function Index({
>
<View className="mode-list">
<View className="mode-item-title"></View>
{PermeationList.map((item: any, index: any) => {
{SensitiveList.map((item: any, index: any) => {
return (
<View
key={"sensitive_" + index}

@ -0,0 +1,108 @@
import Taro from "@tarojs/taro";
import classnames from "classnames";
import { Block, View, ScrollView, Image } from "@tarojs/components";
import { useState, useEffect } from "react";
import "./FR200.less";
interface Props {
isPop: boolean;
activeModeID: any;
ModeList: any;
onEmit: Function; // 每次点击item回调事件和数据给父组件
onEmitShowAll: Function; // 打开弹窗按钮
onModeLockOpen: Function; // 打开锁定弹窗
}
function Index({
isPop,
ModeList,
activeModeID,
onEmit,
onModeLockOpen,
onEmitShowAll,
}: Props) {
const onItemClick = (item) => {
if (item.lock) {
onModeLockOpen(); // 点击了锁定模式
return;
}
onEmit(item);
};
const showAll = () => {
onEmitShowAll();
};
return (
<Block>
<View className="mode-list-main">
{!isPop && ModeList.length > 0 && (
<View className="change-all-mode-btn" onClick={showAll}>
<View className="title"></View>
<Image
className="icon"
src={require("@/img/iot/mode-switch.png")}
/>
</View>
)}
<ScrollView
className="mode-list-box"
scrollX={true}
scrollIntoView={"all_" + activeModeID} // itemID自动滚动到该元素位置
>
<View className="mode-list">
{ModeList.map((item: any, index: any) => {
return (
<View
key={"all_" + index}
id={"all_" + item.id}
className={classnames("mode-item", {
"mode-item-active": activeModeID === item.id,
})}
onClick={onItemClick.bind(this, item)}
>
<View
className={classnames("new", {
"is-new": item.isNew === 1,
})}
>
NEW
</View>
<View className="mode-info">
<View className="mode-info-title">{item.modeName}</View>
<View className="mode-info-time">
{item.modeTimeStr === "00:00"
? "--:--"
: item.modeTimeStr}
</View>
<View
className={classnames("mode-info-select", {
"is-select": activeModeID === item.id,
})}
>
{activeModeID === item.id && (
<View className="mode-info-select-point"></View>
)}
</View>
</View>
{activeModeID === item.id && (
<View className="mode-pic">
<Image
src={item.modeBanner}
mode="aspectFill"
style="animation-iteration-count:1;"
/>
</View>
)}
</View>
);
})}
<View style="width:120rpx;min-width:120rpx;height:40rpx;display:flex"></View>
</View>
</ScrollView>
</View>
</Block>
);
}
export default Index;

@ -9,11 +9,13 @@
height: 160rpx;
background-color: #fff;
border-radius: 30rpx 0rpx 0rpx 30rpx;
box-shadow: 1rpx 2rpx 16rpx 2rpx rgba(97, 97, 97, 0.1);
box-shadow: -60rpx 0 60rpx rgba(240,240,240,1);
text-align: center;
// align-items: center;
z-index: 20;
box-sizing: border-box;
.title {
font-size: 26rpx;
text-align: center;

@ -7,16 +7,11 @@ import "./index.less";
interface Props {
isRuningTest: boolean; // 是否已开始水分测试
TestModeStepIndex: number; // 当前测试步骤
stepList:any
stepIndex:any
stepList: any;
stepIndex: any;
}
function Index({
isRuningTest,
stepList,
stepIndex
}:Props) {
function Index({ isRuningTest, stepList, stepIndex }: Props) {
// const stepIndex = 0;
const testIndex = 1;
@ -106,7 +101,7 @@ function Index({
showPivot={false}
color={stepList[stepIndex].color}
></Progress>
{stepList[stepIndex].finish ? (
{stepList[stepIndex].finish ? (
<Image
className="finish_img"
src={require("@/img/finished.png")}

@ -0,0 +1,209 @@
import classnames from "classnames";
import { Component } from "react";
import {
Block,
View,
Image,
Text,
Button,
PageMeta,
ScrollView,
} from "@tarojs/components";
import { Popup, Checkbox, CheckboxGroup, Steps } from "@antmjs/vantui";
import "@/components/popup/popup.less";
import "@/components/popup/popup-alert.less";
import "./popup-We.less"
import { go } from "@/utils/traoAPI";
/** props
* isLarge
* isShow
* isClose
* title
* content
* confirmButtonText
* textAlgin left right center
* type: 1
* @confirm
*/
class PopupWe extends Component<any, any> {
constructor(props) {
super(props);
this.state = {
name: "确认组件",
// Page:1,
type: "1",
// titleSlogan:'请选择额头区域护理目标'
};
}
async onLoad() {
console.log(this.props, '111111111111');
}
componentDidMount() { }
componentWillUnmount() { }
componentDidShow() { }
componentDidHide() { }
async initData() { }
onClose = () => {
this.props.close();
};
onConfirm = () => {
};
onClickStop = (e) => {
e.stopPropagation();
};
onTouchMove = () => {
return true;
};
html1_3 = () => {
return <View className="img">22222</View>
}
render() {
let {
title,
content,
confirmButtonText,
textAlgin,
isShow,
isClose,
isLarge,
close,
myClassName,
zIndex,
Page,
type,
handlepopupCheck,
WeCurrent,
PreviousStep,
NextStep,
handleSteps,
} = this.props;
if (!zIndex) zIndex = 10001;
return (
<Block>
<PageMeta pageStyle={isShow ? "overflow: hidden;" : ""} />
<Popup
className={myClassName}
overlayStyle={`width: 100vw;padding: 0;z-index: ${zIndex} !important`}
show={isShow}
closeOnClickOverlay={false}
round
onClick={this.onClickStop}
>
<View
className={classnames("common-box Newpop", {
"common-large": isLarge,
})}
catchMove
>
{title && (
<View
className={classnames("common-popup-title-WE", {
"margin-samll": isLarge,
})}
>
{title}
</View>
)}
<View
className="at-icon at-icon-close site-close"
onClick={() =>{
close()
}}
></View>
<View className="center">
<View className="page">
<View className="black">0{Page}</View>/06
</View>
<View className="titleSlogan">{WeCurrent[Page - 1].titleSlogan}</View>
{Page > 3 ? <View>
<View className="img">22222</View>
<View className="drag_box">
<View className="line_left"></View>
<Steps active={WeCurrent[Page - 1].activeinde} onClickStep={(e) => {
handleSteps(e)
}} direction="horizontal"
activeColor="#e6d3b0" inactiveColor="#f7f7f7" steps={[
{ activeIcon: 'circle',},
{ activeIcon: 'circle',},
{ activeIcon: 'circle',},
{ activeIcon: 'circle',},
]}>111111111111111111</Steps><View className={`line_right ${WeCurrent[Page - 1].activeinde === 3 ? 'orange' : ''}`}></View>
<View className="box">
<View className="box_item"></View>
<View className="box_item"></View>
<View className="box_item"></View>
<View className="box_item"></View>
</View>
</View>
</View> : <View>
<View className="img">
111111
</View>
<View className="Checkbox ">
<CheckboxGroup
value={WeCurrent[Page - 1].Checkbox}
onChange={(e) => {
handlepopupCheck(e)
}}
>
<View className="text"><Checkbox name="1" shape="square" iconSize="15px" checkedColor="#0089d2"> {WeCurrent[Page - 1].text1} </Checkbox></View>
<View className="text"><Checkbox name="2" shape="square" iconSize="15px" checkedColor="#0089d2">{WeCurrent[Page - 1].text2}</Checkbox></View>
</CheckboxGroup>
</View>
</View>}
</View>
<View className="alert-popup-btns">
{Page !== 1 ? <Button className="alert-popup-btn whitePop" onClick={(e) => {
PreviousStep()
}}>
</Button> : null}
<Button className="alert-popup-btn" onClick={(e) => {
NextStep()
}}>
</Button>
</View>
</View>
</Popup>
</Block>
);
}
}
export default PopupWe;

@ -0,0 +1,271 @@
.step-popup-content-box {
margin: 0;
.absolutely-img {
width: 100%;
height: 600rpx;
background-color: #eee;
}
}
.van-step--horizontal .van-step__circle-container {
position: absolute;
bottom: 12rpx;
z-index: 1;
-webkit-transform: translate3d(-50%, 50%, 0);
transform: translate3d(-50%, 50%, 0);
background-color: transparent !important;
// background-color: no !important;
padding: 0 16rpx;
padding: 0 var(--padding-xs, 16rpx);
}
.van-step--horizontal .van-step__line {
height: 14rpx;
border-radius: 15rpx;
// background-color: #dedede !important;
}
.van-step--horizontal:first-child .van-step__circle-container {
padding: 0px 0rpx 0 0;
}
.van-step--finish {
// background-color: red;
}
.van-step__circle {
width: 25rpx;
height: 25rpx;
}
.van-steps--horizontal .van-step__wrapper {
overflow: unset;
}
// 图标样式
.van-step--horizontal.van-step--process .van-step__icon {
font-size: var(--step-icon-size, 30rpx);
}
.step-absolutely {
width: 600rpx;
height: 720rpx;
text-align: left;
margin: 0 auto;
}
.step-img {
display: block;
width: 600rpx;
height: 600rpx;
border-radius: 30rpx;
}
.common-popup-title-WE {
font-size: 36rpx;
font-family: PingFang SC;
font-weight: bold;
color: #030000;
text-align: center;
}
.whitePop {
background-color: #fff !important;
color: #000 !important;
}
.Newpop {
.site-close{
position: absolute;
right: 16rpx;
top: 44rpx;
color: #000;
font-size: 36rpx;
z-index: 100009;
background-color: transparent;
border-radius: 50%;
padding: 8rpx;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.center {
// background-color: red;
height: 720rpx;
.page {
color: #dedede;
margin-bottom: 10rpx;
font-size: 25rpx;
}
.titleSlogan {
font-size: 30rpx;
font-family: 700;
margin-bottom: 17rpx;
}
.img {
width: 100%;
height: 500rpx;
background-color: #666;
}
.orange{
background-color: #e6d9bc !important;
}
.drag_box{
position: relative;
.line_left{
position: absolute;
left: 4rpx;
top: 68rpx;
width: 22rpx;
height: 14rpx;
background-color: #e6d9bc;
border-radius: 7rpx;
}
.line_right{
/* position: absolute; */
top: 68rpx;
right: 0rpx;
position: absolute;
/* left: 4rpx; */
/* top: 63rpx; */
width: 35rpx;
height: 14rpx;
background-color: #f7f7f7;
border-radius: 7rpx;
}
}
.box {
display: flex;
.box_item {
width: 25%;
// margin-left: 34rpx;
// .box_item:last-of-type{
// background-color: red;
// }
}
.box_item:nth-child(1) {
padding-left: 30rpx;
}
.box_item:nth-child(2) {
padding-left: 42rpx;
}
.box_item:nth-child(3) {
padding-left: 99rpx;
}
.box_item:nth-child(4) {
text-align: right;
}
}
.text {
margin: 20rpx;
font-size: 23rpx;
font-weight: 700;
background-color: #f8f8f8;
// border: 1rpx solid;
border-radius: 45rpx;
padding: 5rpx 24rpx;
}
.black {
color: #000;
display: inline-block;
}
}
}
.site-close {
position: absolute;
right: 16rpx;
top: 16rpx;
color: #000;
font-size: 36rpx;
z-index: 100009;
background-color: transparent;
border-radius: 50%;
padding: 8rpx;
box-sizing: border-box;
}
.step-popup-btn {
position: absolute;
bottom: 100rpx;
left: calc(50% - 120rpx);
width: 240rpx;
height: 70rpx;
line-height: 70rpx;
font-size: 28rpx;
text-align: center;
border: 1rpx solid #000;
border-radius: 40rpx;
background-color: #000;
color: #fff;
box-sizing: border-box;
}
.step-tips-common-box {
padding: 50rpx 35rpx 74rpx 35rpx;
.tips-message {
margin-top: 70rpx;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
color: #030000;
line-height: 60rpx;
}
}
.popup-btn-one {
display: flex;
margin-top: 60rpx;
justify-content: center;
.popup-btn {
width: 270rpx;
height: 90rpx;
line-height: 90rpx;
font-size: 32rpx;
font-weight: 500;
text-align: center;
border: 1rpx solid #000;
border-radius: 45rpx;
color: #fff;
background-color: #000;
font-family: PingFang SC;
}
}
.setp-footer-btn {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
height: 30rpx;
// padding: 10rpx;
margin-top: 50rpx;
.checked {
width: 30rpx;
height: 30rpx;
margin-right: 26rpx;
}
.text {
font-family: PingFang SC;
font-size: 28rpx;
color: #666;
font-weight: 400;
}
}

@ -1,4 +1,5 @@
export default definePageConfig({
navigationBarTitleText: '首页',
enablePullDownRefresh: false,
enablePageMeta: true
})

@ -13,7 +13,7 @@ page {
height: 0;
color: transparent;
}
.message {
position: relative;
width: 40rpx;
@ -516,7 +516,83 @@ page {
border-radius: 30rpx;
background: #fff;
}
.MembraneCloth {
position: relative;
width: 670rpx;
border-radius: 30rpx;
background: #fff;
padding: 52rpx 20rpx 46rpx;
box-sizing: border-box;
.title {
font-weight: bold;
text-align: center;
font-size: 36rpx;
margin-bottom: 36rpx;
color: #030000;
}
.btn1 {
font-style: normal;
width: 270rpx;
height: 90rpx;
line-height: 90rpx;
background: #000000;
text-align: center;
border-radius: 45rpx;
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
}
.center {
margin-bottom: 44rpx;
.list {
width: 100%;
height: 150rpx;
background: linear-gradient(90deg, #efdcc2, #fff2df);
border-radius: 30rpx;
margin-bottom: 20rpx;
padding: 20rpx 31rpx 20rpx 20rpx;
box-sizing: border-box;
justify-content: space-between;
Image {
width: 120rpx;
height: 120rpx;
border-radius: 20rpx;
}
.name_box {
margin-left: 24rpx;
.name {
font-family: PingFang SC;
font-weight: bold;
font-size: 26rpx;
color: #000000;
margin-bottom: 12rpx;
}
.subTitle {
font-family: PingFang SC;
font-weight: 500;
font-size: 22rpx;
color: #666666;
}
}
.buy {
font-family: PingFang SC;
font-weight: 500;
font-size: 26rpx;
color: #666666;
display: flex;
align-items: center;
Image {
height: 20rpx;
width: 20rpx;
margin-left: 10rpx;
}
}
}
}
}
.popbox .title {
font-weight: bold;
text-align: center;

@ -1,5 +1,4 @@
import classnames from "classnames";
setSerial;
import dayjs from "dayjs";
import Taro from "@tarojs/taro";
import { Component } from "react";
@ -11,8 +10,10 @@ import {
Swiper,
SwiperItem,
RichText,
PageMeta,
Radio
} from "@tarojs/components";
import { Popup } from "@antmjs/vantui";
import { Popup,Toast } from "@antmjs/vantui";
/*** redux ***/
import { connect } from "react-redux";
import { userRefresh, tokenRefresh } from "@/store/features/userInfo";
@ -38,6 +39,11 @@ import Navbar from "@/components/navbar/navbar";
import ConnectionBluetoot from "@/components/bluetoot/connection";
import UpdateIotWL200 from "@/components/bluetoot/update-wl200/index";
import UpdateIotFR200 from "@/components/bluetoot/update-fr200/index";
// import PopupWe from "@/moduleIOT/pages/iotCarePlan/components/popup-We/popup-We";
import PopupWe from "../../moduleIOT/pages/iotCarePlan/components/popup-We/popup-CurrentCustomization";
/** 自定义组件 **/
import {
@ -65,6 +71,7 @@ import {
// const log = require("@/utils/log");
class Index extends Component<any, any> {
onModeLockClose: any;
constructor(props) {
super(props);
this.state = {
@ -72,6 +79,43 @@ class Index extends Component<any, any> {
isCommonError: false, // 是否显示通用错误提示
commonErrorText: [], // 通用错误提示
WeCurrent: [
{
Checkbox: [],
text1: ' 强效提拉额肌,淡化抬头纹',
text2: '密集水光灌注,胶原直达肌底',
titleSlogan: '请选择额头区域的护理目标(可多选)'
},
{
Checkbox: [],
text1: ' 强效提拉额肌,淡化抬头纹',
text2: '密集水光灌注,胶原直达肌底',
titleSlogan: '请选择脸颊区域的护理目标(可多选)'
},
{
Checkbox: [],
text1: ' 强效提拉轮廓,淡化木偶纹',
text2: '密集水光灌注,胶原直达肌底',
titleSlogan: '请选择下颌线区域的护理目标(可多选)'
},
{
Checkbox: [],
activeinde: 0,
titleSlogan: '请选择额头区域的护理目标(可多选)'
},
{
Checkbox: [],
activeinde: 0,
titleSlogan: '请选择额头区域的护理目标(可多选)'
},
{
Checkbox: [],
activeinde: 0,
titleSlogan: '请选择额头区域的护理目标(可多选)'
}
],
isModeLockWE: false,
WeCurrentPage: 1,
showEquipment: false, // 扫码绑定设备弹窗
isRegisterBoolean: false, // 是否已登录
isShowPrivacyPopup: false,
@ -83,6 +127,14 @@ class Index extends Component<any, any> {
mobile: Taro.getStorageSync("mobile"),
},
// 膜布列表
MembraneClothList: [{
name: '集体美容仪'
},
{
name: 'M02美容仪'
}],
checkedMembraneCloth: '',
list: [],
params: "",
messageCount: Taro.getStorageSync("messageCount") || 0,
@ -156,6 +208,7 @@ class Index extends Component<any, any> {
// 设备是否重连弹窗
isShowReConnectDeviceRecordWL200: false,
};
}
async onLoad(options) {
@ -187,7 +240,7 @@ class Index extends Component<any, any> {
}
}
componentDidMount() {}
componentDidMount() { }
componentWillUnmount() {
// 页面卸载监听
@ -261,7 +314,7 @@ class Index extends Component<any, any> {
this.isSancQrcodeEnter();
}
},
fail: () => {},
fail: () => { },
complete: () => {
// 授权完成运行页面初始化
},
@ -518,8 +571,62 @@ class Index extends Component<any, any> {
this.setState({ isShowSiteSwiper: false });
};
bannerSwiperchange() {}
bannerSwiperchange() { }
// 模拟弹窗
handlepopup = () => {
console.log('当前的state:', this.state,);
let isModeLockWE = this.state.isModeLockWE;
console.log('进入模拟弹窗', isModeLockWE);
// 其他操作...
this.setState({ isModeLockWE: !isModeLockWE })
}
// 复选框
handlepopupCheck = (e) => {
let WeCurrent = this.state.WeCurrent
let WeCurrentPage = this.state.WeCurrentPage
WeCurrent[WeCurrentPage - 1].Checkbox = [...e.detail]
this.setState({ WeCurrent })
}
// 进度条
handleSteps = (e) => {
let WeCurrent = this.state.WeCurrent
let WeCurrentPage = this.state.WeCurrentPage
WeCurrent[WeCurrentPage - 1].activeinde = e.detail
// console.log(e,'查看选择');
this.setState({ WeCurrent })
}
// 上一步
PreviousStep = () => {
let WeCurrentPage = this.state.WeCurrentPage
if (WeCurrentPage !== 1) {
WeCurrentPage = WeCurrentPage - 1
this.setState({
WeCurrentPage
})
}
}
// 下一步
NextStep = () => {
let WeCurrentPage = this.state.WeCurrentPage
let WeCurrent = this.state.WeCurrent
if (WeCurrentPage === 1 || WeCurrentPage === 2 || WeCurrentPage === 3) {
if (WeCurrent[WeCurrentPage - 1].Checkbox.length === 0) {
return
}
}
if (WeCurrentPage !== 6) {
WeCurrentPage = WeCurrentPage + 1
this.setState({
WeCurrentPage
})
}
}
gobanner(item) {
// 跳转类型0无跳转、1跳转内部链接、3跳转外部链接、4跳转小程序、5导向视频号、6导向视频号直播间',
/**
@ -855,7 +962,9 @@ class Index extends Component<any, any> {
// return;
if (platform === "devtools") {
setStorageSync("instrument_detail", item);
this.setState({ connectInstrument: item });
this.setState({
connectInstrument: item,
});
if (item.type === 1) {
//非IOT
setTimeout(() => {
@ -934,7 +1043,12 @@ class Index extends Component<any, any> {
this.connectionClose();
};
// 开发者工具跳转函数
async goIot() {
if (this.state.connectInstrument.name.indexOf("WE200") > -1) {
go("/moduleIOT/pages/iotCarePlan/WE200");
return;
}
if (this.state.connectInstrument.model === "FR200") {
go("/moduleIOT/pages/iotCarePlan/FR200"); // 画页面直接跳转
} else {
@ -943,6 +1057,10 @@ class Index extends Component<any, any> {
// return;
}
goTest() {
go("/pages/consultant/consultant");
}
//连接完成时数据的回调
offlineChange = async (e) => {
console.log("offlineChange", e);
@ -1017,6 +1135,26 @@ class Index extends Component<any, any> {
isShowVersionUpgradFinish: false,
});
};
UpgradeFinishFun = () => {
let { connectInstrument } = this.state;
console.log("connectInstrument", connectInstrument);
let content = connectInstrument.iotVersionUpgrade;
let nodes = decodeURIComponent(content || "");
nodes = nodes.replace(/\<img/gi, '<img style="width:100%;height:auto" ');
nodes = nodes.replace(
/\<table/gi,
'<table style="border-spacing: 0;border-collapse: collapse;border: 1px solid #000" '
);
nodes = nodes.replace(
/\<td/gi,
'<td style="border: 1px solid #000;text-align:center" '
);
this.setState({
isShowVersionUpgrading: false,
isShowVersionUpgradFinish: true, // 升级介绍
versionUpgradFinishNodes: nodes,
});
};
/** iot版本升级 END */
/**
@ -1082,6 +1220,10 @@ class Index extends Component<any, any> {
show,
isCommonError,
commonErrorText,
isModeLockWE,
MembraneClothList,
checkedMembraneCloth,
list,
calendarComplete,
calendarInComplete,
currentDate,
@ -1091,7 +1233,8 @@ class Index extends Component<any, any> {
isNotRegister,
isShowSiteSwiper,
isDev,
WeCurrent,
WeCurrentPage,
bannerList,
bannerCurrent,
// 绑定弹窗
@ -1122,10 +1265,11 @@ class Index extends Component<any, any> {
return (
<Block>
{/* <PageMeta pageOrientation="landscape"></PageMeta> */}
<View catchMove>
<PopupAlert
isShow={isCommonError}
title="提示"
title='提示'
content={
<Block>
{commonErrorText.map((item) => {
@ -1133,60 +1277,60 @@ class Index extends Component<any, any> {
})}
</Block>
}
confirmButtonText="知道了"
textAlgin="center"
confirmButtonText='知道了'
textAlgin='center'
close={this.onCommonErrorFun}
confirm={this.onCommonErrorFun}
/>
<PopupConfirm
isShow={isShowReConnectDeviceRecordWL200}
isClose
title="提示"
title='提示'
zIndex={10020}
myClassName="level-up"
myClassName='level-up'
content={
<Block>
<View></View>
<View></View>
</Block>
}
cancelButtonText="取消"
confirmButtonText="连接设备"
textAlgin="center"
cancelButtonText='取消'
confirmButtonText='连接设备'
textAlgin='center'
close={this.closeReConnectDeviceRecordWL200}
confirm={this.confirmReConnectDeviceRecordWL200}
/>
<PopupAlert
isShow={isBindingError}
title="提示"
title='提示'
content={
<Block>
<View></View>
<View></View>
</Block>
}
confirmButtonText="知道了"
textAlgin="center"
confirmButtonText='知道了'
textAlgin='center'
close={this.onBindErrorClose}
confirm={this.onBindErrorConfirm}
/>
<PopupAlert
isShow={isNotRegister}
isClose
title="提示"
content="暂未授权注册,请点击注册"
confirmButtonText="确定"
textAlgin="center"
type="1"
title='提示'
content='暂未授权注册,请点击注册'
confirmButtonText='确定'
textAlgin='center'
type='1'
close={this.closeAlert}
confirm={this.closeAlert}
/>
<PopupAlert
isShow={isDev}
title="提示"
content="页面正在开发中"
confirmButtonText="确定"
textAlgin="center"
title='提示'
content='页面正在开发中'
confirmButtonText='确定'
textAlgin='center'
close={this.closeDev}
confirm={this.closeDev}
/>
@ -1205,54 +1349,54 @@ class Index extends Component<any, any> {
/>
<PopupAlert
isShow={isBindingError}
title="提示"
title='提示'
content={
<Block>
<View></View>
<View></View>
</Block>
}
confirmButtonText="知道了"
textAlgin="center"
confirmButtonText='知道了'
textAlgin='center'
close={this.onBindErrorClose}
confirm={this.onBindErrorConfirm}
/>
<PopupAlert
isShow={isBeforeBindingError}
title="提示"
title='提示'
content={
BeforeBindingErrorText || "您选择的仪器有误,请重新确认选择"
}
confirmButtonText="知道了"
textAlgin="center"
confirmButtonText='知道了'
textAlgin='center'
close={this.onBeforeBindClose}
confirm={this.onBeforeBindConfirm}
/>
<PopupAlert
isShow={isBindingError203}
title="提示"
content="序列码已被别人绑定,请联系微信助手"
confirmButtonText="知道了"
textAlgin="center"
title='提示'
content='序列码已被别人绑定,请联系微信助手'
confirmButtonText='知道了'
textAlgin='center'
close={this.onBindErrorClose203}
confirm={this.onBindErrorConfirm203}
></PopupAlert>
<PopupAlert
isShow={showEquipment}
title="提示"
title='提示'
content={
<Block>
<View className="mb10">
<View className='mb10'>
{instrumentInfo.instrumentName}
</View>
<View className="mb10">{instrumentInfo.serial}</View>
<View className="mb10"></View>
<View className='mb10'>{instrumentInfo.serial}</View>
<View className='mb10'></View>
</Block>
}
confirmButtonText="知道了"
textAlgin="center"
confirmButtonText='知道了'
textAlgin='center'
close={this.onUnloginClose.bind(this)}
confirm={this.onUnloginConfirm.bind(this)}
></PopupAlert>
@ -1260,9 +1404,9 @@ class Index extends Component<any, any> {
<PopupSiteSwiper
isShow={isShowSiteSwiper}
siteData={sitePopupList}
size="middle"
confirmButtonText="确定"
textAlgin="center"
size='middle'
confirmButtonText='确定'
textAlgin='center'
close={this.closeSiteSwiper}
confirm={this.closeSiteSwiper}
/>
@ -1282,37 +1426,49 @@ class Index extends Component<any, any> {
isLarge
isClose
isShow={isShowUpdateVersionTip}
title="提示"
title='提示'
content={
<Block>
<View></View>
<View></View>
</Block>
}
textAlgin="center"
confirmButtonText="确定"
textAlgin='center'
confirmButtonText='确定'
close={this.cancelUpdateVersionTip}
confirm={this.confirmUpdateVersionTip}
/>
{isShowVersionUpgrading && (
<UpdateIotWL200
isShow={isShowVersionUpgrading}
finishFun={this.wl200UpgradeFinishFun}
errorFun={this.wl200UpgradeErrorFun}
/>
<Block>
{connectInstrument.model === "WL200" && (
<UpdateIotWL200
isShow={isShowVersionUpgrading}
finishFun={this.wl200UpgradeFinishFun}
errorFun={this.wl200UpgradeErrorFun}
/>
)}
{connectInstrument.model === "FR200" && (
<UpdateIotFR200
isShow={isShowVersionUpgrading}
finishFun={this.UpgradeFinishFun}
errorFun={this.wl200UpgradeErrorFun}
/>
)}
</Block>
)}
<PopupAlert
isShow={isShowVersionUpgradFinish}
title="升级内容公告"
title='升级内容公告'
content={
<Block>
<View className="nodes">
<View className='nodes'>
<RichText nodes={versionUpgradFinishNodes} />
</View>
</Block>
}
confirmButtonText="知道了"
textAlgin="left"
confirmButtonText='知道了'
textAlgin='left'
isClose
close={this.onVersionUpgradFinish}
confirm={this.onVersionUpgradFinish}
@ -1324,29 +1480,29 @@ class Index extends Component<any, any> {
leftSlot={
<Block>
<View
className="message"
className='message'
onClick={this.gourl}
data-url="/pages/message/message"
data-url='/pages/message/message'
>
<Image
className="message-img"
className='message-img'
src={require("../../img/index/message.png")}
mode="aspectFill"
mode='aspectFill'
/>
{messagecount ? <View className="tip" /> : ""}
{messagecount ? <View className='tip' /> : ""}
</View>
</Block>
}
/>
<View className="index">
<View className="date-title" onClick={this.toNursingRecords}>
<Text className="text"></Text>
<View className='index'>
<View className='date-title' onClick={this.toNursingRecords}>
<Text className='text'></Text>
<Image
src={require("../../img/index/right.png")}
style="width: 20rpx;height: 20rpx;"
style='width: 20rpx;height: 20rpx;'
/>
</View>
<View className="bg-while">
<View className='bg-while'>
<AtCalendar
hideArrow
isSwiper={false}
@ -1358,40 +1514,41 @@ class Index extends Component<any, any> {
/>
</View>
</View>
<View className="index-infobox5">
<View className='index-infobox5'>
{instrumentList.length > 0 && (
<Block>
<View className="nurse_plan_box flex aitems sb">
<View className="title"></View>
<View className='nurse_plan_box flex aitems sb'>
<View className='title'></View>
<View
className="txt_box flex jcenter aitems"
data-url="/instrument/pages/instrument/instrument"
className='txt_box flex jcenter aitems'
data-url='/instrument/pages/instrument/instrument'
onClick={this.gourl}
>
<Image
className="right_icon"
className='right_icon'
src={require("../../img/black-add.png")}
mode="aspectFill"
mode='aspectFill'
/>
<View className="txt"></View>
<View className='txt'></View>
</View>
</View>
<View style="overflow-x: auto;">
<View className="device_list flex">
<View style='overflow-x: auto;'>
<View className='device_list flex'>
{instrumentList.map((item, index) => {
return (
<View
key={"instrumentList" + index}
className="device_item"
className='device_item'
onClick={this.goNursing.bind(this, item)}
>
<Image
className="banner_img"
className='banner_img'
src={item.banner}
mode="aspectFill"
mode='aspectFill'
/>
<View className="device_name ellipsis1">
<View className='device_name ellipsis1'>
{item.name}
</View>
</View>
@ -1401,30 +1558,31 @@ class Index extends Component<any, any> {
</View>
</Block>
)}
{/* <button onClick={this.handlepopup}>点击我</button> */}
{instrumentList.length === 0 && (
<Block>
<View className="nurse_plan_box flex aitems sb">
<View className="title"></View>
<View className='nurse_plan_box flex aitems sb'>
<View className='title'></View>
</View>
<View className="add_device flex jcenter aitems bg-while">
<View className="add_device_btn">
<View className="txt_box flex jcenter aitems">
<View className='add_device flex jcenter aitems bg-while'>
<View className='add_device_btn'>
<View className='txt_box flex jcenter aitems'>
<View
className="at-icon at-icon-add"
style="color: #fff;font-size: 30rpx;"
className='at-icon at-icon-add'
style='color: #fff;font-size: 30rpx;'
></View>
<View className="txt" onClick={this.addNewDevice}>
<View className='txt' onClick={this.addNewDevice}>
</View>
</View>
</View>
<View className="tips"></View>
<View className='tips'></View>
</View>
</Block>
)}
</View>
<View className="infobox3">
<View className='infobox3'>
<Swiper
autoplay
onAnimationFinish={this.bannerSwiperchange.bind(this)}
@ -1436,16 +1594,79 @@ class Index extends Component<any, any> {
key={"banner_" + index}
onClick={this.gobanner.bind(this, item)}
>
<Image style="width:100%;height:100%" src={item.fileUrl} />
<Image style='width:100%;height:100%' src={item.fileUrl} />
</SwiperItem>
);
})}
</Swiper>
</View>
<View style="height:200rpx"></View>
<Popup show={show} className="custom-popup" overlay={false}>
<View className="popBox"></View>
<View style='height:200rpx'></View>
<Popup show={show} className='custom-popup' overlay={false}>
<View className='popBox'></View>
</Popup>
<Popup show={false}>
<View className='MembraneCloth'>
<View className='title'></View>
<View className='center '>
{MembraneClothList.map((item, index) => {
return (
<View
key={index}
className='list flex aitems'
>
<View className='flex aitems'>
<Radio v-model={checkedMembraneCloth} />
<Image src={require('@/img/avater.png')}></Image>
<View className='name_box'>
<View className='name'>
{item.name}
</View>
<View className='subTitle'>
</View>
</View>
</View>
<View className='buy flex aitems'>
<Image src={require('@/img/index-right.png')}></Image>
</View>
</View>
);
})}
</View>
<View className='popbtnbox flex aitems jcenter'>
<View className='btn1' >
</View>
</View>
</View>
</Popup>
<PopupWe
isShow={isModeLockWE}
title='电流定制'
textAlgin='center'
isClose={false}
close={this.handlepopup}
Page={WeCurrentPage}
WeCurrent={WeCurrent}
confirm={this.handlepopup}
handlepopupCheck={this.handlepopupCheck}
handleSteps={this.handleSteps}
PreviousStep={this.PreviousStep}
NextStep={this.NextStep}
/>
{/* </PageMeta> */}
{/* <View
style="position:fixed;width:100vw;height:100vh"
onClick={this.goTest}
>
</View> */}
</Block>
);
}

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

@ -139,6 +139,10 @@ page {
height: 100% !important;
border-radius: 20rpx;
}
.showImg:last-child{
width: 40rpx !important;
height: 40rpx !important;
}
}
.info4 {
position: relative;

@ -67,9 +67,9 @@ export default class Index extends Component<any, any> {
async getStatistics(id) {
let data = {};
if (id != null) {
data["instrumentId"] = id;
data["nursingId"] = id;
}
let res = await InstrumentInfo.apiNursingLog.getStatistics(data);
let res = await InstrumentInfo.apiNursingLog.getStatisticsFace(data);
if (res.data.code === 200) {
this.setState({ statistics: res.data.data });
@ -193,7 +193,6 @@ export default class Index extends Component<any, any> {
};
let res = await InstrumentInfo.apiClock.getList(data);
if (res.data.code === 200) {
console.log(this.state.clockStatistics, 88888);
this.state.clockStatistics.map((item) => {
if (item.id === id) {
@ -241,12 +240,20 @@ export default class Index extends Component<any, any> {
punchInInfo.clockImageList.splice(i, 1);
this.setState({ punchInInfo });
}
getRouteId() {
async getRouteId() {
let punchInInfo =this.state.punchInInfo
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id");
const recordId = searchParams.get("recordId");
this.getStatistics(id);
this.getRecord(id, recordId);
let res1 = await InstrumentInfo.apiClock.getLatestClockRecord();
punchInInfo.clockContent =res1.data.data.clockContent
punchInInfo.clockImageList =res1.data.data.clockImg
this.setState({ punchInInfo });
// 获取图片和文本
console.log(recordId);
}
getTime(time) {
@ -262,7 +269,7 @@ export default class Index extends Component<any, any> {
}
async onLoad(options) {
console.log(options, "查看传过来的参数");
let Bool = JSON.parse(options?.report);
if (!Bool) {
this.setState({

@ -82,6 +82,7 @@ page {
.text-title{
font-size: 18rpx;
color: #999999;
margin: 8rpx 0rpx;
}
.main {
border-radius: 30rpx;
@ -179,6 +180,10 @@ page {
height: 100% !important;
border-radius: 20rpx;
}
.showImg:last-child{
width: 40rpx !important;
height: 40rpx !important;
}
}
.info4 {
position: relative;
@ -309,18 +314,18 @@ page {
// background-color: red;
}
.content {
display: flex;
flex-flow: column;
justify-content: space-between;
background-color: #f8f8f8;
border-radius: 30rpx;
padding: 21rpx;
border-radius: 20rpx;
width: 457rpx;
height: 195rpx;
// .content {
// display: flex;
// flex-flow: column;
// justify-content: space-between;
// background-color: #f8f8f8;
// border-radius: 30rpx;
// padding: 21rpx;
// border-radius: 20rpx;
// width: 457rpx;
// height: 195rpx;
}
// }
.content_top{
height: 140rpx;

@ -1,11 +1,17 @@
import Taro from "@tarojs/taro";
import classnames from "classnames";
import { Component, PropsWithChildren, useEffect, useState } from "react";
import { Progress , Tab, Tabs, Dialog, Popup } from "@antmjs/vantui";
import { Progress, Tab, Tabs, Dialog, Popup } from "@antmjs/vantui";
import { showModal } from "@/utils/traoAPI";
import {
Block, View, Text, Image, Input, Button, Textarea,
Block,
View,
Text,
Image,
Input,
Button,
Textarea,
} from "@tarojs/components";
import { date, getdates, previewImage } from "@/utils/util";
@ -16,9 +22,7 @@ import { InstrumentInfo } from "@/utils/Interface";
// 引入ecahrts图表
// import EchartsForm from '@/moduleIOT/pages/iotCarePlan/components/Echart_face'
import EchartsForm from '../../../moduleIOT/pages/iotCarePlan/components/Echart_face'
import Echarts1 from '../../../moduleIOT/pages/iotCarePlan/components/Echart'
import EchartsForm from "../../../moduleIOT/pages/iotCarePlan/components/Echart_face";
/** 自定义组件 **/
import "./face_report_one.less";
@ -27,19 +31,19 @@ export default class Index extends Component<any, any> {
constructor(props) {
super(props);
this.state = {
EchartsData:{},
EchartsData: {},
reportShow: true,
name: "template模板页",
statistics: {},
recordList: [],
modeImage: require("@/img/face-report/face.png"),
modeImage: require("../../img/face-report/face.png"),
recordData: {
modeName: '基础班脸部',
filtered:111,
faceEnergy:222,
average:2222,
max:33,
min:7
modeName: "基础班脸部",
filtered: 111,
faceEnergy: 222,
average: 2222,
max: 33,
min: 7,
},
year: new Date().getFullYear(),
show: false,
@ -65,9 +69,9 @@ export default class Index extends Component<any, any> {
};
}
componentDidMount() { }
componentDidMount() {}
componentWillUnmount() { }
componentWillUnmount() {}
// 打开/关闭弹窗
setShow(show: boolean) {
@ -75,23 +79,13 @@ export default class Index extends Component<any, any> {
}
// 查询用户护理记录的当月统计信息
async getStatistics(id) {
let ids = Number(id)
let ids = Number(id);
let data = {};
if (ids != null) {
data["nursingId"] = ids;
}
let res = await InstrumentInfo.apiNursingLog.getStatisticsFace(data);
// // 获取echarts数据 这个是获取接口更新echarts页面
// let res2 = await InstrumentInfo.apiNursingLog.getStatiCDE(ids);
// let nursingData=JSON.parse(res2.data.data.nursingData)
// let obj ={
// modeName:res2.data.data.modeName,
// data:nursingData
// }
// this.init({
// obj:JSON.stringify(obj)
// })
if (res.data.code === 200) {
this.setState({ statistics: res.data.data });
}
@ -126,7 +120,9 @@ export default class Index extends Component<any, any> {
// 文本框输入文字
handleTextareaInput = (e) => {
const punchInInfo = this.state.punchInInfo;
this.setState({ punchInInfo: { ...punchInInfo, clockContent: e.detail.value } });
this.setState({
punchInInfo: { ...punchInInfo, clockContent: e.detail.value },
});
};
async submit() {
let punchInInfo = this.state.punchInInfo || {};
@ -149,58 +145,29 @@ export default class Index extends Component<any, any> {
t2: "您已完成今日打卡",
btn1show: false,
}).then(() => {
let data = new Date
Taro.setStorageSync('DayTime', data.toISOString())
let data = new Date();
Taro.setStorageSync("DayTime", data.toISOString());
this.setState({
clockShow: true
})
clockShow: true,
});
this.getClockStatistics();
this.setShow(false);
});
});
}
/**分页获取用户的打卡记录 page size*/
async getClockStatistics(year = this.state.year) {
let res = await InstrumentInfo.apiClock.getClockStatistics({ year });
console.log(res, '查看返回', year);
console.log(res, "查看返回", year);
if (res.data.code === 200) {
res.data.data.reverse();
if (res.data.data.length > 0) {
res.data.data.map((item, index) => {
item.isMore = false;
item.detail = [];
if (index === 0) {
item.isMore = true;
this.getList(item.id, item.year, item.month);
}
this.state.monthTime.map((monthItem) => {
if (monthItem.month == item.month) {
monthItem.time = item.clockNum;
}
});
});
this.setState({ monthTime: this.state.monthTime });
} else {
let monthTime = [
{ month: 1, time: 0 },
{ month: 2, time: 0 },
{ month: 3, time: 0 },
{ month: 4, time: 0 },
{ month: 5, time: 0 },
{ month: 6, time: 0 },
{ month: 7, time: 0 },
{ month: 8, time: 0 },
{ month: 9, time: 0 },
{ month: 10, time: 0 },
{ month: 11, time: 0 },
{ month: 12, time: 0 },
];
this.setState({ monthTime });
let clockStatistics = this.state.clockStatistics;
clockStatistics = res.data.data;
this.setState({ clockStatistics });
}
this.setState({ clockStatistics: res.data.data });
}
}
// 获取当月打卡记录
@ -211,8 +178,6 @@ export default class Index extends Component<any, any> {
};
let res = await InstrumentInfo.apiClock.getList(data);
if (res.data.code === 200) {
console.log(this.state.clockStatistics, 88888);
this.state.clockStatistics.map((item) => {
if (item.id === id) {
item.detail = res.data.data;
@ -259,13 +224,19 @@ export default class Index extends Component<any, any> {
punchInInfo.clockImageList.splice(i, 1);
this.setState({ punchInInfo });
}
getRouteId() {
async getRouteId() {
let punchInInfo = this.state.punchInInfo;
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id");
const recordId = searchParams.get("recordId");
this.getStatistics(id);
// this.getRecord(id, recordId);
// console.log(recordId);
let res1 = await InstrumentInfo.apiClock.getLatestClockRecord();
punchInInfo.clockContent = res1.data.data.clockContent;
punchInInfo.clockImageList = res1.data.data.clockImg;
this.setState({ punchInInfo });
setTimeout(function () {});
}
getTime(time) {
const hour = time.slice(0, 2);
@ -278,200 +249,227 @@ export default class Index extends Component<any, any> {
return minute + "分" + second + "秒";
}
}
onLoad(options) {
let Bool = JSON.parse(options?.report)
onLoad(options) {
let Bool = JSON.parse(options?.report);
if (!Bool) {
this.setState({
reportShow: Bool
})
reportShow: Bool,
});
}
this.init(options)
this.init(options);
this.getRouteId();
// this.getClockStatistics()
this.getClockStatistics();
}
init(options){
init(options) {
let obj = JSON.parse(options.obj);
let obj =JSON.parse(options.obj)
console.log(obj,'obj111111111111111');
let recordData = this.state.recordData;
let modeImage = this.state.modeImage;
let recordData =this.state.recordData
let modeImage =this.state.modeImage
switch(obj.modeName) {
case '基础班脸部':
modeImage =require("@/img/face-report/face.png")
break;
case '基础版眼部':
modeImage =require("@/img/face-report/eye.png")
break;
case '法令纹Pro':
modeImage =require("@/img/face-report/nasolabial_Pro.png")
break;
case '下颌线Pro':
modeImage =require("@/img/face-report/Mandibular_Pro.png")
break;
case '抬头纹Pro':
modeImage =require("@/img/face-report/Head_lift_Pro.png")
break;
switch (obj.modeName) {
case "基础班脸部":
modeImage = require("../../img/face-report/face.png");
break;
case "基础版眼部":
modeImage = require("../../img/face-report/eye.png");
break;
case "法令纹Pro":
modeImage = require("../../img/face-report/nasolabial_Pro.png");
break;
case "下颌线Pro":
modeImage = require("../../img/face-report/Mandibular_Pro.png");
break;
case "抬头纹Pro":
modeImage = require("../../img/face-report/Head_lift_Pro.png");
break;
default:
}
recordData ={
...obj,
...obj.data
}
this.setState({recordData,modeImage,EchartsData:{...obj}})
recordData = {
...obj,
...obj.data,
};
this.setState({ recordData, modeImage, EchartsData: { ...obj } });
}
componentDidShow() { }
componentDidShow() {}
componentDidHide() { }
componentDidHide() {}
async initData() { }
async initData() {}
GoIndex = () => {
Taro.switchTab({ url: "/pages/index/index" });
};
render() {
let { name, statistics, modeImage, recordData, show, clockStatistics, punchInInfo, monthTime, reportShow,EchartsData } = this.state;
let {
name,
statistics,
modeImage,
recordData,
show,
clockStatistics,
punchInInfo,
monthTime,
reportShow,
EchartsData,
} = this.state;
return (
<Block>
<Navbar isBack titleSlot='护理报告'></Navbar>
<View className='statistic m-x-30 flex aitems'>
<View className='statistic_item'>
<View className='statistic_title'>
<Navbar isBack titleSlot="护理报告"></Navbar>
<View className="statistic m-x-30 flex aitems">
<View className="statistic_item">
<View className="statistic_title">
<text>{statistics.nursingNum}</text>
<text className='num'></text>
<text className="num"></text>
</View>
<View className='statistic_desc'></View>
<View className="statistic_desc"></View>
</View>
<View className='statistic_item'>
<View className='statistic_title'>{statistics.nursingTime}</View>
<View className='statistic_desc'></View>
<View className="statistic_item">
<View className="statistic_title">{statistics.nursingTime}</View>
<View className="statistic_desc"></View>
</View>
{/* </block> */}
</View>
<View className='main m-x-30'>
<View className='products_item' style='border: none'>
<View className='products_middle flex'>
<View className='left'>
<View className="main m-x-30">
<View className="products_item" style="border: none">
<View className="products_middle flex">
<View className="left">
<Image
className='cover'
className="cover"
src={modeImage}
mode='aspectFill'
mode="aspectFill"
></Image>
<View className='face_type'>{recordData.modeName}</View>
<View className="face_type">{recordData.modeName}</View>
</View>
<View className='content'>
<View className='content_top'>
<View className='desc_box'>
<View className='desc'>{recordData.modeName === '下颌线Pro'?<View className="itemStyel">[1]</View>:null}&nbsp;&nbsp;{recordData.filtered}</View>
<View className='desc'>
{recordData.modeName === '下颌线Pro'?<View className="itemStyel">[2]</View>:null}&nbsp;&nbsp;{recordData.faceEnergy}
<View className="content">
<View className="content_top">
<View className="desc_box">
<View className="desc">
{recordData.modeName === "下颌线Pro" ? (
<View className="itemStyel">[1]</View>
) : null}
&nbsp;&nbsp;{recordData.filtered}
</View>
<View className="desc">
{recordData.modeName === "下颌线Pro" ? (
<View className="itemStyel">[2]</View>
) : null}
&nbsp;&nbsp;{recordData.faceEnergy}
</View>
<View className='desc'>
&nbsp;&nbsp;<View className="itemStyelone">[3]</View>{recordData.average}
<View className="desc">
&nbsp;&nbsp;
<View className="itemStyelone">[3]</View>
{recordData.average}
</View>
<View className='desc'>
&nbsp;&nbsp;<View className="itemStyel">[4]</View>{recordData.max} &nbsp;&nbsp;<View className="itemStyeltwo">[5]</View>{recordData.min}
<View className="desc">
&nbsp;&nbsp;<View className="itemStyel">[4]</View>
{recordData.max} &nbsp;&nbsp;
<View className="itemStyeltwo">[5]</View>
{recordData.min}
</View>
</View>
</View>
</View>
</View>
</View>
<View className='main_title'>-{recordData.modeName}</View>
<View className='eacharts'>
<EchartsForm EchartsData={EchartsData}></EchartsForm>
{/* <Echarts1></Echarts1> */}
<View className="main_title">-{recordData.modeName}</View>
<View className="eacharts">
<EchartsForm EchartsData={EchartsData}></EchartsForm>
</View>
</View>
<View className='bottom-title'>
<View className='text-title'>[1] :1,使11
<View className="bottom-title">
<View className="text-title">
[1]
:1,使11
</View>
<View className="text-title">
[2]:
使
</View>
<View className="text-title">
[3]:使
<br />
</View>
<View className="text-title">
[4]:
<br />
</View>
<View className="text-title">
[5]:
</View>
<View className='text-title'>[2]: 使</View>
<View className='text-title'>[3]:使<br /></View>
<View className='text-title'>[4]:<br /></View>
<View className='text-title'>
[5]:</View>
</View>
{reportShow ? (
<View className='footer flex aitems'>
<View className='btn' onClick={this.setShow.bind(this, true)}></View>
<View className='text flex aitems'>
<View className="footer flex aitems">
<View className="btn" onClick={this.setShow.bind(this, true)}>
</View>
<View className="text flex aitems">
<View onClick={this.GoIndex}></View>
<Image
src={require("@/img/right.png")}
mode='aspectFill'
></Image>
<Image src={require("@/img/right.png")} mode="aspectFill"></Image>
</View>
</View>
) : null}
<Popup show={show} onClose={() => this.setState({ show: false })}>
<View className='popBox'>
<View className="popBox">
<Image
className='close_icon'
className="close_icon"
src={require("@/img/close.png")}
mode='widthFix'
mode="widthFix"
onClick={this.setShow.bind(this, false)}
></Image>
<View className='popTitle'></View>
<View className='popSubtitle'>
<View className="popTitle"></View>
<View className="popSubtitle">
<View className='bold'>{clockStatistics[0]?.clockNum}</View>{" "}
<View className="bold">{clockStatistics[0]?.clockNum}</View>{" "}
<View className='bold'>
<View className="bold">
{(clockStatistics[0]?.percentage * 100).toFixed(1)}%
</View>
</View>
<View className='img_box'>
<View className="img_box">
{punchInInfo.clockImageList.map((item, index) => (
<View key={item} className='img'>
<Image className='showImg' src={item} mode='widthFix'></Image>
<View key={item} className="img">
<Image className="showImg" src={item} mode="widthFix"></Image>
<Image
className='closeImg'
className="closeImg"
src={require("@/img/close1.png")}
mode='widthFix'
mode="widthFix"
onClick={this.delImg.bind(this, index)}
></Image>
</View>
))}
{punchInInfo.clockImageList.length < 3 && (
<View
className='addBox'
className="addBox"
onClick={this.handleChooseImage.bind(this)}
>
<Image
className='showImg'
className="showImg"
src={require("@/img/clock_in_upload/add-image.png")}
mode='widthFix'
mode="widthFix"
></Image>
</View>
)}
</View>
<View className='info4'>
<View className='content'>
<View className="info4">
<View className="content">
<Textarea
placeholderStyle='color: #ccc; font-size: 26rpx;font-weight: 400;font-family: PingFang SC;'
placeholder='请记录一下今天的护理心得吧'
placeholderStyle="color: #ccc; font-size: 26rpx;font-weight: 400;font-family: PingFang SC;"
placeholder="请记录一下今天的护理心得吧"
maxlength={120}
onInput={this.handleTextareaInput.bind(this)}
value={punchInInfo.clockContent}
></Textarea>
</View>
<View className='tip'>
<View className="tip">
{"" + (punchInInfo.clockContent.length || 0) + "/120"}
</View>
</View>
<View className='popbtnbox flex aitems jcenter'>
<View className='btn1' onClick={this.submit.bind(this)}>
<View className="popbtnbox flex aitems jcenter">
<View className="btn1" onClick={this.submit.bind(this)}>
</View>
</View>

@ -2,18 +2,17 @@ import Taro from "@tarojs/taro";
import classnames from "classnames";
import { Block, View, Image, Text, Input } from "@tarojs/components";
import { Popup, Progress, Slider } from "@antmjs/vantui";
import { useRef } from "react";
import { useEffect, useRef } from "react";
import Echarts, { EChartOption, EchartsHandle } from "taro-react-echarts";
import * as echarts from "echarts";
import "./index.less";
interface Props {
Electricity: any;
matrixElectricity: any;
facialMaskConnectStatus: any;
echartsData: any
}
function Index() {
function Index(echartsData: Props) {
let { gears, eDate } = echartsData.echartsData;
const echartsRef = useRef<EchartsHandle>(null);
const option: EChartOption = {
grid: {
@ -32,7 +31,7 @@ function Index() {
splitLine: {
show: true,
},
data: ['6.17', '6.18', '6.19', '6.20', '6.21', '6.22', '6.23'],
data:eDate,
axisTick: {
show: false
},
@ -76,7 +75,7 @@ function Index() {
}
])
},
data: [5, 3, 4, 6, 3, 4, 3],
data: gears,
}
]
};

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "水分测试",
enablePageMeta: true,
});

@ -1,10 +1,18 @@
import { Block, View, Text, Image, Input, Button } from "@tarojs/components";
import {
Block,
View,
Text,
Image,
Input,
Button,
PageMeta,
} from "@tarojs/components";
import { Component, PropsWithChildren, useEffect, useState } from "react";
import { go } from "@/utils/traoAPI";
import { InstrumentInfo } from "@/utils/Interface";
import "taro-ui/dist/style/components/button.scss"; // 按需引入
import Taro from "@tarojs/taro";
import Taro, { setStorageSync } from "@tarojs/taro";
// 引入 Swiper, SwiperItem 组件
/*** redux ***/
@ -13,6 +21,7 @@ import { setMobile } from "@/store/features/userInfo";
/*** redux end ***/
import Navbar from "@/components/navbar/navbar";
import Echarts from "./Echarts/index";
import "./moisture_test_report.less";
class MoistureTestReport extends Component<any, any> {
@ -20,95 +29,110 @@ class MoistureTestReport extends Component<any, any> {
super(props);
this.state = {
name: "重新登录",
imgUrl: '',
imgUrl: "",
reportShow: true,
reportData: {
curDate: '',
curDate: "",
shuifenLevel: {
head: 2,
leftFace: 3,
rightFace: 7
rightFace: 7,
},
shuifenList: [],
shuifenGear: {
head: 0,
leftFace: 0,
rightFace: 0
}
rightFace: 0,
},
},
isClock: false,
xinde: '',
xinde: "",
imglist: [],
id: 0,
show: false,
modeId: 0
modeId: 0,
echartsData: {},
showEcharts: false,
};
}
componentDidMount() {}
componentDidMount() { }
componentWillUnmount() {}
componentWillUnmount() { }
componentDidShow() {}
componentDidShow() { }
componentDidHide() { }
componentDidHide() {}
onLoad(option) {
console.log(option.data);
let data = JSON.parse(option.data)
console.log(data);
let { reportData } = this.state
reportData.curDate = option.date
data.GearData.map(item => {
if (item.name == '额头') {
reportData.shuifenLevel.head = item.forehead
let gear = Math.ceil((11 - reportData.shuifenLevel.head) / 2)
reportData.shuifenGear.head = gear
} else if (item.name == '左脸颊') {
reportData.shuifenLevel.leftFace = item.forehead
let gear = Math.ceil((11 - reportData.shuifenLevel.leftFace) / 2)
reportData.shuifenGear.leftFace = gear
} else if (item.name == '右脸颊') {
reportData.shuifenLevel.rightFace = item.forehead
let gear = Math.ceil((11 - reportData.shuifenLevel.rightFace) / 2)
reportData.shuifenGear.rightFace = gear
}
})
this.setState({ reportData, modeId: option.modeId });
this.moistureTest(option.id, reportData.curDate)
}
async initData() { }
async moistureTest(id, curDate) {
let data = {
queryDate: curDate,
instrumentId: id
console.log(option);
let Bool = JSON.parse(option?.report);
if (!Bool) {
this.setState({
reportShow: Bool,
});
}
let res = await InstrumentInfo.fr200.moistureTest(data);
let data = JSON.parse(option.data);
let { reportData } = this.state;
reportData.curDate = option.date;
reportData.curDate = option.report;
data.GearData.map((item) => {
if (item.name == "额头") {
reportData.shuifenLevel.head = item.forehead;
let gear = Math.ceil((11 - reportData.shuifenLevel.head) / 2);
reportData.shuifenGear.head = gear;
} else if (item.name == "左脸颊") {
reportData.shuifenLevel.leftFace = item.forehead;
let gear = Math.ceil((11 - reportData.shuifenLevel.leftFace) / 2);
reportData.shuifenGear.leftFace = gear;
} else if (item.name == "右脸颊") {
reportData.shuifenLevel.rightFace = item.forehead;
let gear = Math.ceil((11 - reportData.shuifenLevel.rightFace) / 2);
reportData.shuifenGear.rightFace = gear;
}
});
this.setState({
reportData,
modeId: option.modeId,
echartsData: JSON.parse(option.echartsData),
});
// this.moistureTest(option.id, reportData.curDate)
}
async initData() {}
toIndex() {
Taro.reLaunch({ url: "/pages/index/index" });
}
toNursing() {
go(`/moduleIOT/pages/iotCarePlan/FR200?modeId=${this.state.modeId}`)
go(`/moduleIOT/pages/iotCarePlan/FR200?modeId=${this.state.modeId}`);
}
render() {
let { name, imgUrl, reportData, reportData1, isClock, xinde, imglist, id, show, modeId } = this.state
let {
name,
imgUrl,
reportData,
reportData1,
reportShow,
isClock,
xinde,
imglist,
id,
show,
modeId,
echartsData,
showEcharts,
} = this.state;
const getStatusData = (level) => {
var bgCssData = {
serious: 'background: #FFE3E3',
moderate: 'background: #FFEBDC',
slight: 'background: #F6FCFF',
normal: 'background: #F8F8F8',
sufficient: 'background: #F8F8F8'
}
serious: "background: #FFE3E3",
moderate: "background: #FFEBDC",
slight: "background: #F6FCFF",
normal: "background: #F8F8F8",
sufficient: "background: #F8F8F8",
};
// var progressBgData = {
// serious: 'background: #FF9393',
// moderate: 'background: #FFC58C',
@ -117,90 +141,123 @@ class MoistureTestReport extends Component<any, any> {
// sufficient: 'background: #9FDBF3'
// }
var progressBgData = {
serious: '#FF9393',
moderate: '#FFC58C',
slight: '#E5F3F9',
normal: '#C2E5F3',
sufficient: '#9FDBF3'
}
serious: "#FF9393",
moderate: "#FFC58C",
slight: "#E5F3F9",
normal: "#C2E5F3",
sufficient: "#9FDBF3",
};
if (level >= 1 && level <= 2) {
return {
bg: bgCssData.serious,
title: '严重缺水',
title: "严重缺水",
gear: 5,
img: 'serious',
progressBg: progressBgData.serious
}
img: "serious",
progressBg: progressBgData.serious,
};
} else if (level >= 3 && level <= 4) {
return {
bg: bgCssData.moderate,
title: '中度缺水',
title: "中度缺水",
gear: 4,
img: 'moderate',
progressBg: progressBgData.moderate
}
img: "moderate",
progressBg: progressBgData.moderate,
};
} else if (level >= 5 && level <= 6) {
return {
bg: bgCssData.slight,
title: '轻微缺水',
title: "轻微缺水",
gear: 3,
img: 'slight',
progressBg: progressBgData.slight
}
img: "slight",
progressBg: progressBgData.slight,
};
} else if (level >= 7 && level <= 8) {
return {
bg: bgCssData.normal,
title: '水分正常',
title: "水分正常",
gear: 2,
img: 'normal',
progressBg: progressBgData.normal
}
img: "normal",
progressBg: progressBgData.normal,
};
} else if (level >= 9 && level <= 10) {
return {
bg: bgCssData.sufficient,
title: '水分充足',
title: "水分充足",
gear: 1,
img: 'sufficient',
progressBg: progressBgData.sufficient
}
img: "sufficient",
progressBg: progressBgData.sufficient,
};
}
}
};
return (
<Block>
<Navbar isBack titleSlot='水分测试报告'></Navbar>
<View className='moisture_test_report'>
<View className='time'>{reportData.curDate}</View>
<View className='report_data'>
<View className='forehead moisture_block flex' style={getStatusData(reportData.shuifenLevel.head)!.bg}>
<Image className='moisture_img' src={require(`@/img/fr200/${getStatusData(reportData.shuifenLevel.head)!.img}.png`)} mode='aspectFill'></Image>
<View
className='forehead moisture_block flex'
style={getStatusData(reportData.shuifenLevel.head)!.bg}
>
<Image
className='moisture_img'
src={require(`@/img/fr200/${
getStatusData(reportData.shuifenLevel.head)!.img
}.png`)}
mode='aspectFill'
></Image>
<View className='pos_info'>
<View className='top'></View>
<View className='bottom'>{getStatusData(reportData.shuifenLevel.head)!.title}</View>
<View className='bottom'>
{getStatusData(reportData.shuifenLevel.head)!.title}
</View>
<View className='bottom'></View>
</View>
</View>
<View className='left_face moisture_block flex' style={getStatusData(reportData.shuifenLevel.leftFace)!.bg}>
<Image className='moisture_img' src={require(`@/img/fr200/${getStatusData(reportData.shuifenLevel.leftFace)!.img}.png`)} mode='aspectFill'></Image>
<View
className='left_face moisture_block flex'
style={getStatusData(reportData.shuifenLevel.leftFace)!.bg}
>
<Image
className='moisture_img'
src={require(`@/img/fr200/${
getStatusData(reportData.shuifenLevel.leftFace)!.img
}.png`)}
mode='aspectFill'
></Image>
<View className='pos_info'>
<View className='top'></View>
<View className='bottom'>{getStatusData(reportData.shuifenLevel.leftFace)!.title}</View>
<View className='bottom'>
{getStatusData(reportData.shuifenLevel.leftFace)!.title}
</View>
<View className='bottom'></View>
</View>
</View>
<View className='right_face moisture_block flex' style={getStatusData(reportData.shuifenLevel.rightFace)!.bg}>
<Image className='moisture_img' src={require(`@/img/fr200/${getStatusData(reportData.shuifenLevel.rightFace)!.img}.png`)} mode='aspectFill'></Image>
<View
className='right_face moisture_block flex'
style={getStatusData(reportData.shuifenLevel.rightFace)!.bg}
>
<Image
className='moisture_img'
src={require(`@/img/fr200/${
getStatusData(reportData.shuifenLevel.rightFace)!.img
}.png`)}
mode='aspectFill'
></Image>
<View className='pos_info'>
<View className='top'></View>
<View className='bottom'>{getStatusData(reportData.shuifenLevel.rightFace)!.title}</View>
<View className='bottom'>
{getStatusData(reportData.shuifenLevel.rightFace)!.title}
</View>
<View className='bottom'></View>
</View>
</View>
<View className='example_box'>
<Image className='banner_img' src='@/img/fr200/shuifen.png' mode='aspectFill'></Image>
<Image
className='banner_img'
src='@/img/fr200/shuifen.png'
mode='aspectFill'
></Image>
<View className='line1'></View>
<View className='line2'></View>
<View className='line3'></View>
@ -210,24 +267,54 @@ class MoistureTestReport extends Component<any, any> {
<View className='items flex aitems'>
<View className='pos_name'></View>
<View className='progress'>
<View className='progress_width' style={{ width: `${reportData.shuifenLevel.head * 10}%`, backgroundColor: getStatusData(reportData.shuifenLevel.head)!.progressBg }}></View>
<View
className='progress_width'
style={{
width: `${reportData.shuifenLevel.head * 10}%`,
backgroundColor: getStatusData(
reportData.shuifenLevel.head
)!.progressBg,
}}
></View>
{/* style='{width: {reportData.shuifenLevel.head * 10}%;{util.getStatusData(reportData.shuifenLevel.head).progressBg}}' */}
</View>
<View className='level'>{reportData.shuifenLevel.head}</View>
<View className='level'>
{reportData.shuifenLevel.head}
</View>
</View>
<View className='items flex aitems'>
<View className='pos_name'></View>
<View className='progress'>
<View className='progress_width left_face_progress' style={{ width: `${reportData.shuifenLevel.leftFace * 10}%`, backgroundColor: getStatusData(reportData.shuifenLevel.leftFace)!.progressBg }}></View>
<View
className='progress_width left_face_progress'
style={{
width: `${reportData.shuifenLevel.leftFace * 10}%`,
backgroundColor: getStatusData(
reportData.shuifenLevel.leftFace
)!.progressBg,
}}
></View>
</View>
<View className='level'>
{reportData.shuifenLevel.leftFace}
</View>
<View className='level'>{reportData.shuifenLevel.leftFace}</View>
</View>
<View className='items flex aitems'>
<View className='pos_name'></View>
<View className='progress'>
<View className='progress_width right_face_progress' style={{ width: `${reportData.shuifenLevel.rightFace * 10}%`, backgroundColor: getStatusData(reportData.shuifenLevel.rightFace)!.progressBg }}></View>
<View
className='progress_width right_face_progress'
style={{
width: `${reportData.shuifenLevel.rightFace * 10}%`,
backgroundColor: getStatusData(
reportData.shuifenLevel.rightFace
)!.progressBg,
}}
></View>
</View>
<View className='level'>
{reportData.shuifenLevel.rightFace}
</View>
<View className='level'>{reportData.shuifenLevel.rightFace}</View>
</View>
</View>
<View className='moisture_level'>
@ -257,15 +344,33 @@ class MoistureTestReport extends Component<any, any> {
<View className='txt'>9-10</View>
</View>
</View>
<View className='pour'></View>
<View className='pour'>
</View>
</View>
</View>
</View>
</View>
<View className='report_chart'>
<View className='chart_title common_title'></View>
<View className='container'>
<Echarts echartsData={echartsData}></Echarts>
</View>
</View>
<View className='report_chart'>
<View className='chart_title common_title'></View>
<View className='container'>
<Echarts></Echarts>
<View className='gear_recommend'>
<View className='gear_header flex aitems sb'>
<View className='gear_title common_title'></View>
{reportShow ? <View className='gear_btn'></View> : null}
</View>
<View className='gear_content flex aitems sb'>
<View className='left_content'>
<Image
className='banner_img'
src='@/img/fr200/mian-mo.png'
mode='aspectFill'
></Image>
<View className='type'></View>
</View>
</View>
@ -276,25 +381,53 @@ class MoistureTestReport extends Component<any, any> {
</View>
<View className='gear_content flex aitems sb'>
<View className='left_content'>
<Image className='banner_img' src='@/img/fr200/mian-mo.png' mode='aspectFill'></Image>
<Image
className='banner_img'
src='@/img/fr200/mian-mo.png'
mode='aspectFill'
></Image>
<View className='type'></View>
</View>
<View className='right_content flex aitems'>
<View className='gear_list flex aitems sa'>
<View className='items flex aitems jcenter'>
<Image className='gear_img' src={require(`@/img/fr200/${getStatusData(reportData.shuifenLevel.head)!.gear}.png`)} mode='aspectFill'></Image>
<Image
className='gear_img'
src={require(`@/img/fr200/${
getStatusData(reportData.shuifenLevel.head)!.gear
}.png`)}
mode='aspectFill'
></Image>
<View className='name'></View>
<View className='level'>{reportData.shuifenGear.head}</View>
<View className='level'>
{reportData.shuifenGear.head}
</View>
</View>
<View className='items flex aitems jcenter'>
<Image className='gear_img' src={require(`@/img/fr200/${getStatusData(reportData.shuifenLevel.leftFace)!.gear}.png`)} mode='aspectFill'></Image>
<Image
className='gear_img'
src={require(`@/img/fr200/${
getStatusData(reportData.shuifenLevel.leftFace)!.gear
}.png`)}
mode='aspectFill'
></Image>
<View className='name'></View>
<View className='level'>{reportData.shuifenGear.leftFace}</View>
<View className='level'>
{reportData.shuifenGear.leftFace}
</View>
</View>
<View className='items flex aitems jcenter'>
<Image className='gear_img' src={require(`@/img/fr200/${getStatusData(reportData.shuifenLevel.rightFace)!.gear}.png`)} mode='aspectFill'></Image>
<Image
className='gear_img'
src={require(`@/img/fr200/${
getStatusData(reportData.shuifenLevel.rightFace)!.gear
}.png`)}
mode='aspectFill'
></Image>
<View className='name'></View>
<View className='level'>{reportData.shuifenGear.rightFace}</View>
<View className='level'>
{reportData.shuifenGear.rightFace}
</View>
</View>
</View>
</View>
@ -302,14 +435,17 @@ class MoistureTestReport extends Component<any, any> {
</View>
</View>
<View className='go_clock_in flex sb aitems' >
<View className='go_clock_btn' onClick={this.toNursing.bind(this)}></View>
<View className='jump_box flex aitems' onClick={this.toIndex}>
<View className='txt'></View>
<Image src='@/img/fr200/right.png' mode='aspectFill'></Image>
{reportShow ? (
<View className='go_clock_in flex sb aitems'>
<View className='go_clock_btn' onClick={this.toNursing.bind(this)}>
</View>
<View className='jump_box flex aitems' onClick={this.toIndex}>
<View className='txt'></View>
<Image src='@/img/fr200/right.png' mode='aspectFill'></Image>
</View>
</View>
</View>
) : null}
</Block>
);
}

@ -15,8 +15,15 @@ page {
font-weight: 400;
color: #666;
padding: 0 32rpx;
position: sticky;
position: sticky ;
z-index: 9;
width: 100%;
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
user-select: none; /* 标准语法 */
-webkit-overflow-scrolling:none
}
.tab {
@ -64,6 +71,7 @@ page {
.instrument_list {
padding-bottom: 200rpx;
padding-top: 237rpx;
}
.products_list {
@ -480,13 +488,13 @@ page {
}
.btn {
width: 540rpx;
height: 90rpx;
width: 695rpx;
height: 75rpx;
background: #000000;
border-radius: 45rpx;
color: #fff;
text-align: center;
line-height: 90rpx;
line-height: 75rpx;
font-weight: bold;
font-size: 32rpx;
}

@ -1,5 +1,6 @@
import Taro, { setStorageSync } from "@tarojs/taro";
import classnames from "classnames";
import dayjs from "dayjs";
import { Component, PropsWithChildren, useEffect, useState } from "react";
import {
@ -40,8 +41,11 @@ export default class Recording extends Component<any, any> {
curIndex: null,
clockStatistics: [],
statistics: [],
yearValue: dayjs().format("YYYY-MM-DD"),
year: new Date().getFullYear(),
today: new Date(),
startYear: "2000-01-01",
endYear: dayjs().format("YYYY-MM-DD"),
monthTime: [
{ month: 1, time: 0 },
{ month: 2, time: 0 },
@ -61,14 +65,14 @@ export default class Recording extends Component<any, any> {
clockImageList: [],
clockContent: "",
},
navigationBarHeight: '',
statusBarHeight: ''
navigationBarHeight: "",
statusBarHeight: "",
};
}
componentDidMount() { }
componentDidMount() {}
componentWillUnmount() { }
componentWillUnmount() {}
// 格式化时间
getTime(time) {
const hour = time.slice(0, 2);
@ -264,23 +268,31 @@ export default class Recording extends Component<any, any> {
ViewAddInstrument: ViewAddInstrument,
});
this.getRecord(null);
this.getBindingInstrumentList();
this.getLatestClockRecord();
this.getClockStatistics();
this.DayTime();
this.setStatusBar();
this.initData();
}
componentDidShow() { }
componentDidShow() {}
componentDidHide() { }
componentDidHide() {}
async initData() {
}
initData = async () => {
this.getRecord(null);
Taro.showLoading({
title: "请求中...",
mask: true,
});
await Promise.all([
this.getBindingInstrumentList(),
this.getLatestClockRecord(),
this.getClockStatistics(),
this.DayTime(),
this.setStatusBar(),
]);
Taro.hideLoading();
};
// 选择年份
onChangeYear(event) {
console.log("event", event);
this.setState({ year: event.detail.value });
this.getClockStatistics(event.detail.value);
}
@ -294,13 +306,13 @@ export default class Recording extends Component<any, any> {
};
// 跳转到护理报告
toReport(id, recordId, item) {
this.state.bindingInstrumentList.map(instrument => {
this.state.bindingInstrumentList.map((instrument) => {
if (instrument.id == id) {
setStorageSync("instrument_detail", instrument);
}
})
console.log(item,'查看');
});
console.log(item, "查看");
if ([1, 2, 3, 4, 5].includes(item.jumpType)) {
this.One(item);
} else if (item.jumpType === 0) {
@ -316,24 +328,22 @@ export default class Recording extends Component<any, any> {
}
// 打开第一种类型
One = async (item) => {
let ids =Number(item.id)
// 获取echarts数据 这个是获取接口更新echarts页面
let res2 = await InstrumentInfo.apiNursingLog.getStatiCDE(ids);
let nursingData=JSON.parse(res2.data.data.nursingData)
nursingData.groupedAa.push(50)
let obj ={
modeName:res2.data.data.modeName,
data:nursingData
}
let ids = Number(item.id);
// 获取echarts数据 这个是获取接口更新echarts页面
let res2 = await InstrumentInfo.apiNursingLog.getStatiCDE(ids);
let nursingData = JSON.parse(res2.data.data.nursingData);
let obj = {
modeName: res2.data.data.modeName,
data: nursingData,
};
let report = false;
go(
"/recoding/pages/face_report_one/face_report_one?id=" +
item.id +
"&report=" +
report+ "&obj=" +
report +
"&obj=" +
JSON.stringify(obj)
);
};
@ -344,16 +354,69 @@ export default class Recording extends Component<any, any> {
go(
"/recoding/pages/face_report/face_report?id=" +
item.id +
"&recordId=" + item.instrumentId+
"&recordId=" +
item.instrumentId +
"&report=" +
report
);
};
// 打开第三种类型
three = async (item) => {
go(`/recoding/pages/moisture_test_report/moisture_test_report?data=${item.nursingData}&date=${item.createTime}&modeId=${item.modeId}&id=${item.instrumentId}`);
this.moistureTest(item);
};
async moistureTest(allData) {
let data = {
queryDate: allData.createTime,
instrumentId: allData.instrumentId,
};
let res = await InstrumentInfo.fr200.moistureTest(data);
let echartsData = res.data.rows;
for (let i = 0; i < echartsData.length; i++) {
for (let j = i + 1; j < echartsData.length; j++) {
if (
echartsData[i].createTime.split(" ")[0] ==
echartsData[j].createTime.split(" ")[0]
) {
let result =
Date.parse(echartsData[i].createTime) -
Date.parse(echartsData[j].createTime);
if (result < 0) {
echartsData.splice(i, 1);
} else {
echartsData.splice(j, 1);
}
}
}
}
let gears: any = [];
let eDate: any = [];
echartsData.map((item) => {
const result = item.createTime.split(" ")[0].substring(5);
eDate.push(result);
item.nursingData = JSON.parse(item.nursingData);
let level: any = 0;
item.nursingData?.GearData?.map((gear) => {
level = level + gear.forehead;
});
level = Math.floor(level / 3);
gears.push(level);
});
echartsData = {
gears,
eDate,
};
setStorageSync("moistureEachtsData", JSON.stringify(echartsData));
let report = false;
go(
`/recoding/pages/moisture_test_report/moisture_test_report?data=${
allData.nursingData
}&date=${allData.createTime}&modeId=${allData.modeId}&id=${
allData.instrumentId
}&echartsData=${JSON.stringify(echartsData)}&report=${report}`
);
}
// 打开其他类型
AllDevice = async (item) => {
console.log("打开其他类型", item);
@ -432,7 +495,6 @@ export default class Recording extends Component<any, any> {
}
setStatusBar() {
Taro.getSystemInfoAsync({
success: (res) => {
const statusBarHeight = res.statusBarHeight || 0;
@ -462,22 +524,27 @@ export default class Recording extends Component<any, any> {
clockStatistics,
statistics,
year,
today,
monthTime,
show,
punchInInfo,
navigationBarHeight,
statusBarHeight
statusBarHeight,
startYear,
endYear,
} = this.state;
const statusBarHeightRpx = statusBarHeight * 2;
const navigationBarHeightRpx = navigationBarHeight * 2;
const height = statusBarHeightRpx + navigationBarHeightRpx
const height = statusBarHeightRpx + navigationBarHeightRpx;
return (
<Block>
<Navbar isBack titleSlot='护理记录'></Navbar>
<View className='tabs' style={{
top: height + "rpx", position: 'sticky'
}}
<Navbar isBack titleSlot="护理记录"></Navbar>
<View
className="tabs"
style={{
top: height + "rpx",
position: "fixed",
}}
>
<View
className={classnames("tab", {
@ -498,132 +565,130 @@ export default class Recording extends Component<any, any> {
</View>
</View>
{current === 0 && (
<ScrollView className='products_list' scroll-x='true' style={{
top: height + 110 + 'rpx', position: 'sticky'
}}
>
<View
className={classnames("all", {
products_item_active: !curIndex,
})}
onClick={this.onChangeProduct.bind(this, null)}
>
</View>
{bindingInstrumentList.map((item: any, index: any) => (
<View
key={item.id}
className={classnames("products_item", {
products_item_active: curIndex === item.id,
})}
onClick={this.onChangeProduct.bind(this, item.id)}
<View>
{current === 0 && (
<Block>
<ScrollView
className="products_list"
scrollX={true}
enhanced={true}
bounces={false}
// scrollIntoView={"products_item_" + curIndex}
style={{
top: height + 110 + "rpx",
position: "fixed",
}}
>
<Image
className='products_cover'
src={item.logo}
mode='aspectFill'
></Image>
<View className='products_title'>{item.name}</View>
</View>
))}
</ScrollView>
)}
{current === 0 && recordList.length === 0 && (
<View>
<View className='nodata'>
<Image
className='nodata_img'
src={require("@/img/nodata.png")}
></Image>
<View className='nodata_text'></View>
</View>
</View>
)}
{current === 0 && (
<View style='padding-bottom:200px'>
{/* <View className='instrument_item' >
<View className='instrument_top flex sb aitems'>
<View className='time_box flex aitems'>
<View className='time'>2024.1.23</View>
<View className={classnames("tag", {
tag_active: current === 1,
})}
> 线</View>
</View>
<View className='report_btn flex'>
<View></View>
<Image className='arrow_icon' src={require("../../img/index/right.png")} mode='aspectFill'></Image>
</View>
</View>
<View className='instrument_middle flex'>
<Image className='instrument_cover' src={require("../../img/test/1706667011027.jpg")}></Image>
<View className='instrument_content'>
<View className='instrument_title'></View>
<View className='instrument_desc_box flex fc sb'>
<View className='instrument_desc'></View>
<View className='instrument_desc'>1500</View>
<View>
<View
id={"products_item_0"}
className={classnames("all", {
products_item_active: !curIndex,
})}
onClick={this.onChangeProduct.bind(this, null)}
>
</View>
</View>
</View>
</View> */}
<View className='instrument_list '>
{recordList.map((item: any, index: any) => (
<View className='recording-box' key={item.id}>
<View className='box-top'>
<View className='top-left'>
<View className='date'>{item.createTime}</View>
{bindingInstrumentList.map((item: any, index: any) => {
return (
<View
className={classnames("tip", {
tag_active: item.online === 2,
key={item.id}
id={"products_item_" + item.id}
className={classnames("products_item", {
products_item_active: curIndex === item.id,
})}
onClick={this.onChangeProduct.bind(this, item.id)}
>
{item.online === 1 ? "在线" : "离线"}
</View>
</View>
{item.instrumentType === 2 && (
<View
className='top-right'
onClick={this.toReport.bind(
this,
item.instrumentId,
item.id,
item
)}
>
<Image
className='arrow_icon'
src={require("@/img/index/right.png")}
mode='aspectFill'
className="products_cover"
src={item.logo}
mode="aspectFill"
></Image>
<View className="products_title">{item.name}</View>
</View>
)}
);
})}
</View>
</ScrollView>
<View>
{recordList.length === 0 && (
<View>
<View className="nodata">
<Image
className="nodata_img"
src={require("@/img/nodata.png")}
></Image>
<View className="nodata_text"></View>
</View>
</View>
<View className='box-bottom'>
<Image
className='recording_img'
src={item.modeImage}
></Image>
<View className='bottom-right'>
<View className='title'>{item.instrumentName}</View>
<View className='subtitle-box'>
<View className='subtitle'>{item.modeName}</View>
<View className='subtitle'>
{item.nursingTime}
)}
{recordList.length > 0 && (
<View style="padding-bottom:200px">
<View className="instrument_list ">
{recordList.map((item: any, index: any) => (
<View className="recording-box" key={item.id}>
<View className="box-top">
<View className="top-left">
<View className="date">{item.createTime}</View>
<View
className={classnames("tip", {
tag_active: item.online === 2,
})}
>
{item.online === 1 ? "在线" : "离线"}
</View>
</View>
{item.instrumentType === 2 && (
<View
className="top-right"
onClick={this.toReport.bind(
this,
item.instrumentId,
item.id,
item
)}
>
<Image
className="arrow_icon"
src={require("@/img/index/right.png")}
mode="aspectFill"
></Image>
</View>
)}
</View>
<View className="box-bottom">
<Image
className="recording_img"
src={item.modeImage}
></Image>
<View className="bottom-right">
<View className="title">
{item.instrumentName}
</View>
<View className="subtitle-box">
<View className="subtitle">
{item.modeName}
</View>
<View className="subtitle">
{item.instrumentType === 2 && (
<Text>{item.nursingTime}</Text>
)}
</View>
</View>
</View>
</View>
</View>
</View>
))}
</View>
</View>
</View>
))}
</View>
</View>
)}
)}
</View>
</Block>
)}
</View>
{current === 1 && (
<View style='padding-bottom:200px'>
<View style="padding-bottom:200px">
{/* <View className='nodata'>
<Image
className='nodata_img'
@ -631,52 +696,54 @@ export default class Recording extends Component<any, any> {
></Image>
<View className='nodata_text'></View>
</View> */}
<View style='height: 30rpx; background: #F8F8F8'></View>
<View className='clock_in_statistics m-x-30 flex sb'>
<View className='flex sb ab'>
<View className='clock_in_statistics_title'></View>
<View style="height: 150rpx; background: #F8F8F8"></View>
<View className="clock_in_statistics m-x-30 flex sb">
<View className="flex sb ab">
<View className="clock_in_statistics_title"></View>
<Picker
mode='date'
fields='year'
style="color:#000"
mode="date"
fields="year"
onChange={this.onChangeYear.bind(this)}
value='{{year}}'
end='{{today}}'
value={this.state.yearValue}
start={startYear}
end={endYear}
>
<View className='clock_in_statistics_date flex aitems'>
<View className="clock_in_statistics_date flex aitems">
<View>{year}</View>
<Image
className='more_icon'
className="more_icon"
src={require("@/img/arrow-down.png")}
mode='widthFix'
mode="widthFix"
></Image>
</View>
</Picker>
</View>
<View className='chart flex sb'>
<View className="chart flex sb">
{monthTime.map((item) => (
<View className='flex fc aitems' key={item.month}>
<View className="flex fc aitems" key={item.month}>
{item.time > 0 && (
<View className='buoy'>{item.time}</View>
<View className="buoy">{item.time}</View>
)}
<View
className='column'
className="column"
style={{ height: `calc(186/31*${item.time}rpx)` }}
></View>
<View className='month'>{item.month}</View>
<View className="month">{item.month}</View>
</View>
))}
</View>
</View>
<View style='padding-bottom: env(safe-area-inset-bottom)'>
<View className='month_box m-x-30'>
<View style="padding-bottom: env(safe-area-inset-bottom)">
<View className="month_box m-x-30">
{clockStatistics.map((item) => (
<View className='month_statistics' key={item.id}>
<View className='flex aitems sb'>
<View className='time'>
<View className="month_statistics" key={item.id}>
<View className="flex aitems sb">
<View className="month_item_date">
{item.year}{item.month}
</View>
<View
className='more_box flex aitems'
className="more_box flex aitems"
onClick={this.onChangeMore.bind(
this,
item.id,
@ -684,7 +751,7 @@ export default class Recording extends Component<any, any> {
item.month
)}
>
<View className='more_text'>
<View className="more_text">
{" "}
{!item.isMore ? "展开更多" : "收起更多"}
</View>
@ -694,51 +761,51 @@ export default class Recording extends Component<any, any> {
? "rotate(180deg)"
: "rotate(0deg)",
}}
className='more_icon'
className="more_icon"
src={require("@/img/arrow-down.png")}
mode='widthFix'
mode="widthFix"
></Image>
</View>
</View>
<View style='height: 59rpx'></View>
<View className='statistic'>
<View className='statistic_item'>
<View className='statistic_num'>{item.clockNum}</View>
<View className='statistic_desc'></View>
<View style="height: 59rpx"></View>
<View className="statistic">
<View className="statistic_item">
<View className="statistic_num">{item.clockNum}</View>
<View className="statistic_desc"></View>
</View>
<View className='statistic_item'>
<View className='statistic_num'>
<View className="statistic_item">
<View className="statistic_num">
{(item.percentage * 100).toFixed(2)}%
</View>
<View className='statistic_desc'></View>
<View className="statistic_desc"></View>
</View>
<View className='border'></View>
<View className="border"></View>
</View>
{item.isMore && item.detail && (
<View>
{item.detail.map((obj) => (
<View key={obj.id}>
<View style='height: 57rpx'></View>
<View className='month_item'>
<View className='month_item_date'>
<View style="height: 57rpx"></View>
<View className="month_item">
<View className="month_item_date">
{obj.updateTime}
</View>
<View className='month_image_box flex sb'>
<View className="month_image_box flex sb">
{obj.clockImg.map((img) => (
<Image
key={img}
className='month_item_cover'
className="month_item_cover"
src={img}
></Image>
))}
</View>
<View className='month_item_date'>
<View className="month_item_date">
{/* 小紫弹智能射频仪、花至抗老射频仪PRO{" "} */}
{obj.instrumentName === null
? ""
: obj.instrumentName}
</View>
<View className='month_item_note'>
<View className="month_item_note">
{obj.clockContent}
</View>
</View>
@ -753,8 +820,8 @@ export default class Recording extends Component<any, any> {
</View>
)}
{!clockShow && ViewAddInstrument === "true" && (
<View className='footer flex aitems'>
<View className='btn' onClick={this.setShow.bind(this, true)}>
<View className="footer flex aitems">
<View className="btn" onClick={this.setShow.bind(this, true)}>
</View>
{/* <View className="text" onClick={this.back}>
@ -764,64 +831,64 @@ export default class Recording extends Component<any, any> {
)}
<Popup show={show} onClose={() => this.setState({ show: false })}>
<View className='popBox'>
<View className="popBox">
<Image
className='close_icon'
className="close_icon"
src={require("@/img/close.png")}
mode='widthFix'
mode="widthFix"
onClick={this.setShow.bind(this, false)}
></Image>
<View className='popTitle'></View>
<View className='popSubtitle'>
<View className="popTitle"></View>
<View className="popSubtitle">
<View className='bold'>{clockStatistics[0]?.clockNum}</View>{" "}
<View className="bold">{clockStatistics[0]?.clockNum}</View>{" "}
<View className='bold'>
<View className="bold">
{(clockStatistics[0]?.percentage * 100).toFixed(1)}%
</View>
</View>
<View className='img_box'>
<View className="img_box">
{punchInInfo.clockImageList.map((item, index) => (
<View key={item} className='img'>
<Image className='showImg' src={item} mode='widthFix'></Image>
<View key={item} className="img">
<Image className="showImg" src={item} mode="widthFix"></Image>
<Image
className='closeImg'
className="closeImg"
src={require("@/img/close1.png")}
mode='widthFix'
mode="widthFix"
onClick={this.delImg.bind(this, index)}
></Image>
</View>
))}
{punchInInfo.clockImageList.length < 3 && (
<View
className='addBox'
className="addBox"
onClick={this.handleChooseImage.bind(this)}
>
<Image
className='showImg'
className="showImg"
src={require("@/img/clock_in_upload/add-image.png")}
mode='widthFix'
mode="widthFix"
></Image>
</View>
)}
</View>
<View className='info4'>
<View className='content'>
<View className="info4">
<View className="content">
<Textarea
placeholderStyle='color: #ccc; font-size: 26rpx;font-weight: 400;font-family: PingFang SC;'
placeholder='请记录一下今天的护理心得吧'
placeholderStyle="color: #ccc; font-size: 26rpx;font-weight: 400;font-family: PingFang SC;"
placeholder="请记录一下今天的护理心得吧"
maxlength={120}
onInput={this.handleTextareaInput.bind(this)}
value={punchInInfo.clockContent}
></Textarea>
</View>
<View className='tip'>
<View className="tip">
{"" + (punchInInfo.clockContent.length || 0) + "/120"}
</View>
</View>
<View className='popbtnbox flex aitems jcenter'>
<View className='btn1' onClick={this.submit.bind(this)}>
<View className="popbtnbox flex aitems jcenter">
<View className="btn1" onClick={this.submit.bind(this)}>
</View>
</View>

Loading…
Cancel
Save