Browse Source

显示电量 温度 倾斜度

feature/rail
zhangjiming 5 months ago
parent
commit
dc83169d37
  1. 8
      src/App.tsx
  2. 1
      src/assets/icon_battery.svg
  3. 129
      src/components/Header.tsx
  4. 65
      src/services/wsTypes.ts
  5. 12
      src/store/device/deviceState.ts
  6. 16
      src/store/features/contextSlice.ts

8
src/App.tsx

@ -10,6 +10,7 @@ import { createWebSocket, sharedWsUrl } from "./services/socket";
import { useAppDispatch } from "./utils/hooks";
import { updateDeviceState } from "./store/device/deviceState";
import zhCN from 'antd/lib/locale/zh_CN'; // 引入中文语言包
import { updateDevice } from "./store/features/contextSlice";
const { Header, Footer, Sider, Content } = Layout;
function App() {
@ -27,8 +28,11 @@ function App() {
// } else {
// navigate("/login");
// }
} else if (data.messageType === "STATE") {
} else if (data.messageType === "STATE" && data.path === "/subdevice/uartchanel/get-channel-state") {
dispatch(updateDeviceState(data.data));
} else if (data.messageType === "STATE" && data.path === "/profiler-state/get-state") {
// console.log(data.data);
dispatch(updateDevice(data.data));
}
});
wsClient.connect();
@ -60,7 +64,7 @@ function App() {
return (
<div className="">
<ConfigProvider locale={zhCN}>
<Layout style={layoutStyle} >
<Layout style={layoutStyle}>
<Sider width="200px">
<SideMenu />
</Sider>

1
src/assets/icon_battery.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="60" height="30" viewBox="0 0 60 30"><g><path d="M57.8572,8.85957L57.1875,8.85957L57.1875,2.04255C57.1875,0.914483,56.2281,0,55.0446,0L2.14286,0C0.95939,0,0,0.914483,0,2.04255L0,27.9574C0,29.0855,0.95939,30,2.14286,30L55.0446,30C56.2281,30,57.1875,29.0855,57.1875,27.9574L57.1875,21.1404L57.8572,21.1404C59.0406,21.1404,60,20.2259,60,19.0979L60,10.9021C60,9.77406,59.0406,8.85957,57.8572,8.85957ZM52.3661,25.4043L4.82143,25.4043L4.82143,4.59574L52.3661,4.59574L52.3661,25.4043Z" fill="#2759C2" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>

129
src/components/Header.tsx

@ -2,6 +2,7 @@ import { useSelector } from "react-redux";
import bluetooth_nc from "../assets/bluetooth_nc.svg";
import bluetooth_c from "../assets/bluetooth_c.svg";
import icon_usb from "../assets/icon_usb.svg";
import icon_battery from "../assets/icon_battery.svg";
import icon_avatar from "../assets/icon_avatar.svg";
import icon_logout from "../assets/icon_logout.svg";
import check_mark from "../assets/check_mark.svg";
@ -9,17 +10,17 @@ import { useState, useEffect } from "react";
import { Dropdown, MenuProps, message, Button, Popover } from "antd";
import { logout } from "../services/user/user";
import { useNavigate } from "react-router";
import { useAppDispatch } from "../utils/hooks";
import { useAppDispatch, useAppSelector } from "../utils/hooks";
import { updateUser } from "../store/features/contextSlice";
import "./bluetooth.scss";
import { loginUser } from '../services/wsTypes';
import { loginUser } from "../services/wsTypes";
export default function Header() {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const deviceInfo = useAppSelector(store => store.context.device);
//@ts-ignoref
const deviceState = useSelector(store => store.deviceState);
let [isConnect, setIsConnect] = useState(deviceState.isConnect)//
let [isConnect, setIsConnect] = useState(deviceState.isConnect)
const [bluetoothInfo, setBluetoothInfo] = useState(deviceState)
//获取当前websocet的状态
const showBlueImg = () => {
@ -41,36 +42,39 @@ export default function Header() {
// }
}
let list = [{
name:'Kdkow_1',
id:'1',
},{
name:'llwoa_2',
id:'2',
}]
let [bluetoothList, setbluetoothList] = useState(list)
let list = [
{
name: "Kdkow_1",
id: "1",
},
{
name: "llwoa_2",
id: "2",
},
];
let [bluetoothList, setbluetoothList] = useState(list);
//获取mock数据
useEffect(()=>{
useEffect(() => {
// getDeviceInfo().then(res => {
// console.log('res===', res)
// //@ts-ignore
// setbluetoothList(res.data.list)
// })
if(context.user.loginUser && context.user.loginUser.nickName){
setNickname(context.user.loginUser.nickName)
}else{
const user = localStorage.getItem('user')
if(user){
let userData = JSON.parse( user || '')
setNickname(userData.nickname)
if (context.user.loginUser && context.user.loginUser.nickName) {
setNickname(context.user.loginUser.nickName);
} else {
const user = localStorage.getItem("user");
if (user) {
let userData = JSON.parse(user || "");
setNickname(userData.nickname);
}
}
})
});
//@ts-ignore
const context = useSelector(store => store.context);
const [messageApi, contextHolder] = message.useMessage();
const [nickname, setNickname] = useState()
const [nickname, setNickname] = useState();
const items: MenuProps["items"] = [
// {
// key: "1",
@ -87,34 +91,39 @@ export default function Header() {
onClick: () => {
logout({}).then(res => {
if (res.status !== 0) {
messageApi.error(res.data.info)
}else{
localStorage.setItem('user','')
dispatch(updateUser({
loginFlag:false,
loginUser:{}
}));
messageApi.error(res.data.info);
} else {
localStorage.setItem("user", "");
dispatch(
updateUser({
loginFlag: false,
loginUser: {},
})
);
navigate("/login");
}
})
}
});
},
},
];
const getBtList = () => {
let Dom = null
if(!isConnect){
Dom = <div>
let Dom = null;
if (!isConnect) {
Dom = (
<div>
{bluetoothList.map(item => {
return <div className="mt-[1rem]" onClick={connectBt}>
return (
<div className="mt-[1rem]" onClick={connectBt}>
<Button type="link">{item.name}</Button>
</div>
);
})}
</div>
);
}
return Dom
}
return Dom;
};
//设备已连接
const getBtContent = ()=> {
@ -131,35 +140,47 @@ export default function Header() {
</div>
</div>
</div>
}
);
};
//断开蓝牙连接
const onDisconnectBt = ()=> {
setIsConnect(false)
}
const onDisconnectBt = () => {
setIsConnect(false);
};
const connectBt = () => {
setIsConnect(true)
setTimeout(()=>{
},1000)
}
setIsConnect(true);
setTimeout(() => {}, 1000);
};
return (
<>
{contextHolder}
<div className="bg-[--bgColor] h-full flex items-center">
<section className="ml-auto rounded-md h-9 mr-4 flex items-center bg-white gap-4 px-4">
<span>{deviceInfo.temperature.toFixed(1)} </span>
<span>X轴倾斜{deviceInfo.inclinatorX}</span>
<span>Y轴倾斜{deviceInfo.inclinatorY}</span>
</section>
<section className="bg-white rounded-md h-9 w-12 relative mr-3 flex justify-center items-center">
<img
src={icon_battery}
className="absolute h-8 w-10 left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
alt=""
/>
<p className="text-primary text-xs">{deviceInfo.power.toFixed()}%</p>
</section>
<section className="bg-white rounded-md h-9 w-10 flex justify-center items-center mr-3">
<img src={icon_usb} className="w-6" alt="icon" />
</section>
<div className="ml-auto mr-8 flex items-center">
<div className="ml-auto mr-8 flex items-center w-[5rem]">
<div className="mr-8 flex items-center w-[5rem]">
{showBlueImg()}
</div>
</div>
<Dropdown menu={{ items }} trigger={["click"]}>
<section className="flex items-center">
<img src={icon_avatar} alt="" className="h-8" />
<p className="text-base ml-2">{ nickname || "未登录"}</p>
<p className="text-base ml-2">{nickname || "未登录"}</p>
</section>
</Dropdown>
</div>

65
src/services/wsTypes.ts

@ -1,7 +1,17 @@
// 开始、停止绘制
export type TaskState = {
messageType: "EVENT";
data: "START_RECORD_SIG" | "END_RECORD_SIG" | "FINISHED" | "START_RECORD_LEFT" | "FINISH_RECORD_RIGHT" | "FINISH_RECORD" | "FINISH_RECORD_LEFT" | "END_RECORD_SIG" | "END_RECORD" | "START_RECORD_RIGHT";
data:
| "START_RECORD_SIG"
| "END_RECORD_SIG"
| "FINISHED"
| "START_RECORD_LEFT"
| "FINISH_RECORD_RIGHT"
| "FINISH_RECORD"
| "FINISH_RECORD_LEFT"
| "END_RECORD_SIG"
| "END_RECORD"
| "START_RECORD_RIGHT";
// data: {
// event: "START_RECORD_SIG" | "END_RECORD_SIG" | "FINISHED" | "START_RECORD_LEFT" | "FINISH_RECORD_RIGHT" | "FINISH_RECORD" | "FINISH_RECORD_LEFT" | "END_RECORD_SIG" | "END_RECORD" | "START_RECORD_RIGHT";
// };
@ -47,11 +57,11 @@ export type ContextMessage = {
};
export type loginUser = Partial<{
id: 3, //数据主键id
account: "test001", //用户账户
nickname: "测试账户001", //用户昵称
userRole: "User", //用户角色,可用值:User,Admin,Dev
isBuiltInUser: false, //是否内置用户(内置用户不可删除)
id: 3; //数据主键id
account: "test001"; //用户账户
nickname: "测试账户001"; //用户昵称
userRole: "User"; //用户角色,可用值:User,Admin,Dev
isBuiltInUser: false; //是否内置用户(内置用户不可删除)
}>;
export const taskStatusDescMap: { [k in MeasureState["data"]["taskStatus"]]: string } = {
@ -59,19 +69,30 @@ export const taskStatusDescMap: { [k in MeasureState["data"]["taskStatus"]]: str
MEASURING: "测量中",
WAITING_FOR_MEASURING: "等待测量",
FINISHED: "测量完成",
START_RECORD_LEFT: '',
FINISH_RECORD_RIGHT: '',
FINISH_RECORD:'',
FINISH_RECORD_LEFT: '',
END_RECORD_SIG: '',
END_RECORD: '',
START_RECORD_RIGHT : ''
START_RECORD_LEFT: "",
FINISH_RECORD_RIGHT: "",
FINISH_RECORD: "",
FINISH_RECORD_LEFT: "",
END_RECORD_SIG: "",
END_RECORD: "",
START_RECORD_RIGHT: "",
};
// 测量任务状态
export type MeasureState = {
messageType: "STATE";
data: {
taskStatus: "IDLE" | "MEASURING" | "WAITING_FOR_MEASURING" | "FINISHED" | "START_RECORD_LEFT" | "FINISH_RECORD_RIGHT" | "FINISH_RECORD" | "FINISH_RECORD_LEFT" | "END_RECORD_SIG" | "END_RECORD" | "START_RECORD_RIGHT";
taskStatus:
| "IDLE"
| "MEASURING"
| "WAITING_FOR_MEASURING"
| "FINISHED"
| "START_RECORD_LEFT"
| "FINISH_RECORD_RIGHT"
| "FINISH_RECORD"
| "FINISH_RECORD_LEFT"
| "END_RECORD_SIG"
| "END_RECORD"
| "START_RECORD_RIGHT";
measureSideCnt: 0 | 1 | 2; //已测量数量,0,1,2 最多两边(左边和右边)
isMeasuringLeftEnd: boolean; //测量左侧完成
isMeasuringRightEnd: boolean; //测量右侧完成
@ -97,9 +118,21 @@ export type ChannelMessage = {
isConnect: boolean;
connectPort: string;
sn: string;
descriptivePortName:string;
descriptivePortName: string;
};
path: "/subdevice/uartchanel/get-channel-state";
};
export type Datagram = TrackRecordSig | TaskState | ContextMessage | MeasureState | ChannelMessage;
export type DeviceStatus = {
messageType: "STATE";
data: {
isConnected: boolean; //是否链接
power: number; //电量
inclinatorX: number; //x轴倾斜
inclinatorY: number; //y轴倾斜
temperature: number; //温度
};
path: "/profiler-state/get-state";
};
export type Datagram = TrackRecordSig | TaskState | ContextMessage | MeasureState | ChannelMessage | DeviceStatus;

12
src/store/device/deviceState.ts

@ -4,10 +4,10 @@ import { createSlice } from "@reduxjs/toolkit";
import { ChannelMessage } from "../../services/wsTypes";
const initialState: ChannelMessage["data"] = {
"isConnect": false, //是否连接
"connectPort": "COM4",//串口名
"sn": "",//连接的设备ID
"descriptivePortName": "COM4 serial ch340" //用于详细系
isConnect: false, //是否连接
connectPort: "COM4", //串口名
sn: "", //连接的设备ID
descriptivePortName: "COM4 serial ch340", //用于详细系
};
// 创建一个 Slice
@ -20,8 +20,8 @@ export const deviceStateSlice = createSlice({
updateDeviceState: (state, { payload }) => {
state.isConnect = payload.isConnect;
state.connectPort = payload.connectPort;
state.sn = payload.sn;
state.descriptivePortName = payload.descriptivePortName;
state.sn = payload.sn;
state.descriptivePortName = payload.descriptivePortName;
},
},
});

16
src/store/features/contextSlice.ts

@ -1,15 +1,23 @@
// counterSlice.ts 文件
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { ContextMessage } from "../../services/wsTypes";
import type { ContextMessage, DeviceStatus } from "../../services/wsTypes";
interface ContextSlice {
user: ContextMessage["data"];
newMeasureAfterSave: boolean;
device: DeviceStatus["data"];
}
const initialState: ContextSlice = {
user: { loginFlag: false, loginUser: {} },
newMeasureAfterSave: false,
device: {
isConnected: true, //是否链接
power: 60, //电量
inclinatorX: 0.276, //x轴倾斜
inclinatorY: 3.019, //y轴倾斜
temperature: 32.026, //温度
},
};
export const contextSlice = createSlice({
@ -19,16 +27,18 @@ export const contextSlice = createSlice({
reducers: {
updateUser: (state, action: PayloadAction<ContextMessage["data"]>) => {
state.user.loginFlag = action.payload.loginFlag;
//@ts-ignore
state.user.loginUser = action.payload.loginUser;
},
switchMeasureAfterSave: (state, action: PayloadAction<boolean>) => {
state.newMeasureAfterSave = action.payload;
},
updateDevice: (state, action: PayloadAction<DeviceStatus["data"]>) => {
state.device = action.payload;
},
},
});
export const { updateUser, switchMeasureAfterSave } = contextSlice.actions;
export const { updateUser, switchMeasureAfterSave, updateDevice } = contextSlice.actions;
// 默认导出
export default contextSlice.reducer;
Loading…
Cancel
Save