2025年05月09日18:28:30
This commit is contained in:
parent
5e52002178
commit
bb0b996c8b
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -13,6 +13,7 @@ declare module '@vue/runtime-core' {
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCascader: typeof import('element-plus/es')['ElCascader']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
|
@ -19,6 +19,16 @@
|
||||
>
|
||||
<el-option v-for="(opt, index) in item.opts" :label="opt.label" :value="opt.value" :key="index"></el-option>
|
||||
</el-select>
|
||||
<el-cascader
|
||||
style="width: 168px"
|
||||
v-model="cascaderValue"
|
||||
v-else-if="item.type === 'cascader'"
|
||||
:options="item.opts"
|
||||
:props="item.props"
|
||||
:show-all-levels="item.showAllLevels"
|
||||
clearable
|
||||
@change="(e) => cascaderChange(e, item.prop, item.showAllLevels)"
|
||||
/>
|
||||
<el-date-picker v-else-if="item.type === 'date'" type="date" v-model="query[item.prop]" :value-format="item.format"></el-date-picker>
|
||||
<el-date-picker
|
||||
style="width: 220px"
|
||||
@ -60,11 +70,20 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const cascaderValue = ref();
|
||||
const searchRef = ref<FormInstance>();
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
props.search();
|
||||
cascaderValue.value = undefined;
|
||||
};
|
||||
const cascaderChange = (e, name, showAllLevels = true) => {
|
||||
if (e) {
|
||||
props.query[name] = showAllLevels ? e : e[e.length - 1];
|
||||
} else {
|
||||
props.query[name] = undefined;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { TLogin, TRoleList } from "@/api/index.d";
|
||||
import { roleList } from '@/api';
|
||||
import { TLogin, TOrg, TRoleList } from "@/api/index.d";
|
||||
import { roleList, orgAllList } from '@/api';
|
||||
|
||||
export const useCommonStore = defineStore('common', {
|
||||
state: () => {
|
||||
return {
|
||||
time: new Date(),
|
||||
user: <TLogin.IRes>{},
|
||||
roleList: <TRoleList[]>[]
|
||||
roleList: <TRoleList[]>[],
|
||||
orgTree: <TOrg.IOrgRecordRes[]>[]
|
||||
};
|
||||
},
|
||||
getters: {},
|
||||
@ -20,6 +21,17 @@ export const useCommonStore = defineStore('common', {
|
||||
this.roleList = res
|
||||
})
|
||||
},
|
||||
getOrgAllList() {
|
||||
orgAllList().then(res => {
|
||||
this.orgTree = this.getTree(res)
|
||||
})
|
||||
},
|
||||
getTree(list) {
|
||||
list.forEach(item => {
|
||||
item.children = list.filter(i => i.parentId === item.id)
|
||||
});
|
||||
return list.filter(item => item.parentId == null)
|
||||
},
|
||||
setUser(data: TLogin.IRes) {
|
||||
this.user = data
|
||||
},
|
||||
|
@ -18,6 +18,8 @@ export interface FormOptionList {
|
||||
activeText?: string;
|
||||
inactiveText?: string;
|
||||
required?: boolean;
|
||||
showAllLevels?: boolean;
|
||||
defalut?: any;
|
||||
validator?: Function;
|
||||
props?: any;
|
||||
}
|
@ -57,6 +57,7 @@ const submitForm = async (formEl: FormInstance | undefined) => {
|
||||
.then((res) => {
|
||||
comm.setUser(res);
|
||||
comm.getRoleList();
|
||||
comm.getOrgAllList();
|
||||
ElMessage({
|
||||
message: "登录成功",
|
||||
type: "success",
|
||||
|
@ -1,26 +1,25 @@
|
||||
<template>
|
||||
<div class="deviceStatistics card">
|
||||
<div class="card-head">
|
||||
<div class="title">当前设备历史数据</div>
|
||||
<el-radio-group v-model="radio" @change="change">
|
||||
<el-radio-button label="心率" value="1" />
|
||||
<el-radio-button label="血氧" value="2" />
|
||||
<el-radio-button label="体表温度" value="3" />
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="card-head">当前设备历史数据</div>
|
||||
<div ref="chartRef" class="card-chart"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { debounce, format } from "@/utils";
|
||||
import { onMounted, onUnmounted, ref } from "vue";
|
||||
import { format } from "@/utils";
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
import { useResize } from "@/utils/hooks";
|
||||
import { THealthLatestData } from "@/api/index.d";
|
||||
|
||||
const radio = ref("1");
|
||||
const chartRef = ref(null);
|
||||
let myChart: any = null;
|
||||
const emit = defineEmits(["change"]);
|
||||
const props = defineProps({
|
||||
HealthData: {
|
||||
type: Object as () => THealthLatestData.TRes,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const options = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
@ -48,6 +47,7 @@ const options = {
|
||||
type: "value",
|
||||
},
|
||||
grid: {
|
||||
top: "5%",
|
||||
left: "5%",
|
||||
right: "4%",
|
||||
bottom: "20%",
|
||||
@ -74,44 +74,66 @@ const options = {
|
||||
},
|
||||
},
|
||||
],
|
||||
series: {
|
||||
name: "",
|
||||
data: [],
|
||||
type: "line",
|
||||
showSymbol: false,
|
||||
itemStyle: {
|
||||
color: "#ff4567", // 设置线条颜色
|
||||
series: [
|
||||
{
|
||||
name: "心率",
|
||||
data: [],
|
||||
type: "line",
|
||||
itemStyle: {
|
||||
color: "#FF4241",
|
||||
},
|
||||
showSymbol: false,
|
||||
},
|
||||
smooth: true,
|
||||
},
|
||||
{
|
||||
name: "血氧",
|
||||
data: [],
|
||||
type: "line",
|
||||
itemStyle: {
|
||||
color: "#12CCA2",
|
||||
},
|
||||
showSymbol: false,
|
||||
},
|
||||
{
|
||||
name: "体表温度",
|
||||
data: [],
|
||||
type: "line",
|
||||
itemStyle: {
|
||||
color: "#FF7D00",
|
||||
},
|
||||
showSymbol: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const getOptionsData = (list: { time: string; value: number }[], name: string, color: string) => {
|
||||
const getOptionsData = (res: THealthLatestData.TRes) => {
|
||||
options.xAxis.data = [];
|
||||
options.series.data = [];
|
||||
|
||||
if (list && list.length) {
|
||||
list.forEach((item) => {
|
||||
options.series[0].data = [];
|
||||
options.series[1].data = [];
|
||||
options.series[2].data = [];
|
||||
if (res && res.hrArr) {
|
||||
res.hrArr.forEach((item, i) => {
|
||||
options.xAxis.data.push(item.time);
|
||||
options.series.data.push(item.value);
|
||||
options.series[0].data.push(item.value);
|
||||
options.series[1].data.push(res.boArr[i].value);
|
||||
options.series[2].data.push(res.tempArr[i].value);
|
||||
});
|
||||
options.series.name = name;
|
||||
options.series.itemStyle.color = color;
|
||||
}
|
||||
myChart.setOption(options);
|
||||
};
|
||||
|
||||
defineExpose({ radio, getOptionsData });
|
||||
watch(
|
||||
() => props.HealthData,
|
||||
(newVal) => {
|
||||
getOptionsData(newVal);
|
||||
}
|
||||
);
|
||||
|
||||
useResize(() => {
|
||||
myChart.resize();
|
||||
});
|
||||
onMounted(() => {
|
||||
myChart = echarts.init(chartRef.value);
|
||||
});
|
||||
|
||||
const change = (e) => {
|
||||
emit("change", e);
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.card {
|
||||
@ -126,24 +148,15 @@ const change = (e) => {
|
||||
.card-head {
|
||||
color: #061451;
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
transform: translateX(-10px);
|
||||
.title {
|
||||
&::before {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
content: "";
|
||||
width: 2px;
|
||||
height: 14px;
|
||||
border-radius: 20px;
|
||||
background: #061451;
|
||||
}
|
||||
}
|
||||
.search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&::before {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
content: "";
|
||||
width: 2px;
|
||||
height: 14px;
|
||||
border-radius: 20px;
|
||||
background: #061451;
|
||||
}
|
||||
}
|
||||
.card-chart {
|
||||
|
@ -94,7 +94,8 @@ const statusColor = ["danger", "success", "warning"];
|
||||
const modeColor = ["primary", "danger", "warning"];
|
||||
|
||||
enum statusEnum {
|
||||
"离线" = 0,
|
||||
"关机" = -1,
|
||||
"离线",
|
||||
"在线",
|
||||
"充电中",
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<DeviceLocationMap :device-id="deviceInfo.deviceId" />
|
||||
<el-row class="box" :gutter="20">
|
||||
<el-col :span="12" :xs="24" :sm="24" :md="24" :lg="24" :xl="12" style="margin-bottom: 20px">
|
||||
<DeviceHistory @change="handleRadio" ref="devHisRef" />
|
||||
<DeviceHistory :HealthData="HealthData" />
|
||||
</el-col>
|
||||
<el-col :span="12" :xs="24" :sm="24" :md="24" :lg="24" :xl="12">
|
||||
<DeviceRecord :deviceInfo="deviceInfo" />
|
||||
@ -19,7 +19,7 @@
|
||||
<div class="el-row-right-content" v-else>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24" style="margin-bottom: 20px">
|
||||
<DeviceHistory @change="handleRadio" ref="devHisRef" />
|
||||
<DeviceHistory :HealthData="HealthData" />
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<DeviceRecord :deviceInfo="deviceInfo" />
|
||||
@ -42,8 +42,6 @@ import heart from "@/assets/img/heart.png";
|
||||
import temperature from "@/assets/img/temperature.png";
|
||||
import blood from "@/assets/img/blood.png";
|
||||
|
||||
const devHisRef = ref(null);
|
||||
|
||||
let Interval = null;
|
||||
let funcList = ref([
|
||||
{ title: "当前心率", en: "DANGQIANXINLV", icon: heart, unit: "次/分", num: 0, color: "#FF0303" },
|
||||
@ -60,18 +58,8 @@ const getHealthLatestData = () => {
|
||||
funcList.value[0].num = res.hr;
|
||||
funcList.value[1].num = res.bo;
|
||||
funcList.value[2].num = res.temp;
|
||||
handleRadio(devHisRef.value.radio);
|
||||
});
|
||||
};
|
||||
const handleRadio = (val: number) => {
|
||||
if (val == 1) {
|
||||
devHisRef.value?.getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
||||
} else if (val == 2) {
|
||||
devHisRef.value?.getOptionsData(HealthData.value.boArr, "血氧", "#983AFC");
|
||||
} else if (val == 3) {
|
||||
devHisRef.value?.getOptionsData(HealthData.value.tempArr, "体表温度", "#FFA91F");
|
||||
}
|
||||
};
|
||||
|
||||
const IntervalFn = () => {
|
||||
Interval = setInterval(() => {
|
||||
@ -80,7 +68,6 @@ const IntervalFn = () => {
|
||||
};
|
||||
|
||||
const handleClickDevice = (val: TDevice.IListRes) => {
|
||||
devHisRef.value.radio = "1";
|
||||
deviceInfo.value = val;
|
||||
getHealthLatestData();
|
||||
if (!Interval) {
|
||||
|
@ -35,6 +35,9 @@ import { TableItem } from "@/types/table";
|
||||
import { FormOptionList } from "@/types/form-option";
|
||||
import Alarm from "@/components/alarm.vue";
|
||||
import { TOrg } from "@/api/index.d";
|
||||
import { useCommonStore } from "@/store/common";
|
||||
|
||||
const comm = useCommonStore();
|
||||
// 0-禁用 1-启用
|
||||
enum StatusEnum {
|
||||
"禁用" = 0,
|
||||
@ -98,6 +101,7 @@ const handleDel = (id: number) => {
|
||||
.then(async () => {
|
||||
orgDelete({ id }).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
comm.getOrgAllList();
|
||||
getData();
|
||||
});
|
||||
})
|
||||
@ -116,6 +120,7 @@ const updateData = (res) => {
|
||||
api(res).then((res) => {
|
||||
ElMessage.success(msg);
|
||||
visible.value = false;
|
||||
comm.getOrgAllList();
|
||||
getData();
|
||||
});
|
||||
};
|
||||
|
@ -62,12 +62,14 @@ import TableSearch from "@/components/table-search.vue";
|
||||
import TableEdit from "@/components/table-edit.vue";
|
||||
import DeviceControl from "./deviceControl.vue";
|
||||
import BindArea from "./bindArea.vue";
|
||||
import { useCommonStore } from "@/store/common";
|
||||
import { TableItem } from "@/types/table";
|
||||
import { FormOption, FormOptionList } from "@/types/form-option";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
enum statusEnum {
|
||||
"离线" = 0,
|
||||
"关机" = -1,
|
||||
"离线",
|
||||
"在线",
|
||||
"充电中",
|
||||
}
|
||||
@ -80,7 +82,7 @@ enum modeEnum {
|
||||
|
||||
const statusColor = ["danger", "success", "warning"];
|
||||
const modeColor = ["primary", "danger", "warning"];
|
||||
|
||||
const comm = useCommonStore();
|
||||
const router = useRouter();
|
||||
// 新增/编辑弹窗相关
|
||||
let TableEditOptions = ref<FormOption>({
|
||||
@ -115,6 +117,7 @@ const searchOpt = ref<FormOptionList[]>([
|
||||
label: "设备状态:",
|
||||
prop: "status",
|
||||
opts: [
|
||||
{ label: "关机", value: -1 },
|
||||
{ label: "离线", value: "0" },
|
||||
{ label: "在线", value: "1" },
|
||||
{ label: "充电中", value: "2" },
|
||||
@ -129,6 +132,18 @@ const searchOpt = ref<FormOptionList[]>([
|
||||
{ label: "使用中", value: "1" },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "cascader",
|
||||
label: "辖区:",
|
||||
prop: "orgId",
|
||||
opts: comm.orgTree,
|
||||
showAllLevels: false,
|
||||
props: {
|
||||
checkStrictly: true,
|
||||
label: "name",
|
||||
value: "id",
|
||||
},
|
||||
},
|
||||
]);
|
||||
const handleSearch = () => {
|
||||
changePage(1);
|
||||
|
@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<template #roleId="{ rows }">
|
||||
{{ roleEnum[rows.roleId] }}
|
||||
{{ getRoleName(rows.roleId) }}
|
||||
</template>
|
||||
<!--
|
||||
<template #password="{ rows }">
|
||||
@ -131,6 +131,18 @@ const searchOpt = ref<FormOptionList[]>([
|
||||
{ label: "启用", value: "1" },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "cascader",
|
||||
label: "辖区:",
|
||||
prop: "orgId",
|
||||
opts: comm.orgTree,
|
||||
showAllLevels: false,
|
||||
props: {
|
||||
checkStrictly: true,
|
||||
label: "name",
|
||||
value: "id",
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// 表格相关
|
||||
@ -151,6 +163,15 @@ let columns = ref([
|
||||
const handleImp = () => {
|
||||
batchImpRef.value.dialogVisible = true;
|
||||
};
|
||||
const getRoleName = (id) => {
|
||||
let name = "--";
|
||||
comm.roleList.forEach((item) => {
|
||||
if (item.id == id) {
|
||||
name = item.name;
|
||||
}
|
||||
});
|
||||
return name;
|
||||
};
|
||||
const handleSearch = () => {
|
||||
paging.page = 1;
|
||||
getData();
|
||||
|
Loading…
x
Reference in New Issue
Block a user