2025年04月10日13:33:36
This commit is contained in:
parent
5f0cda3d45
commit
054d5fb5ca
2
components.d.ts
vendored
2
components.d.ts
vendored
@ -14,6 +14,7 @@ declare module '@vue/runtime-core' {
|
|||||||
CustomInput: typeof import('./src/components/CustomInput.vue')['default']
|
CustomInput: typeof import('./src/components/CustomInput.vue')['default']
|
||||||
DeviceInfo: typeof import('./src/components/deviceInfo.vue')['default']
|
DeviceInfo: typeof import('./src/components/deviceInfo.vue')['default']
|
||||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||||
|
ElButradioton: typeof import('element-plus/es')['ElButradioton']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||||
ElCard: typeof import('element-plus/es')['ElCard']
|
ElCard: typeof import('element-plus/es')['ElCard']
|
||||||
@ -36,6 +37,7 @@ declare module '@vue/runtime-core' {
|
|||||||
ElOption: typeof import('element-plus/es')['ElOption']
|
ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
ElPopover: typeof import('element-plus/es')['ElPopover']
|
||||||
|
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||||
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
|
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
|
||||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||||
ElRow: typeof import('element-plus/es')['ElRow']
|
ElRow: typeof import('element-plus/es')['ElRow']
|
||||||
|
25
src/api/index.d.ts
vendored
25
src/api/index.d.ts
vendored
@ -164,6 +164,10 @@ export namespace TDevice {
|
|||||||
mode: number
|
mode: number
|
||||||
monitorMode: number
|
monitorMode: number
|
||||||
battery: number
|
battery: number
|
||||||
|
adminUsername: string
|
||||||
|
adminPhone: string
|
||||||
|
userNumber: string
|
||||||
|
adminType: string
|
||||||
name: string
|
name: string
|
||||||
username: string
|
username: string
|
||||||
password: string
|
password: string
|
||||||
@ -183,7 +187,7 @@ export namespace TDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IRecordReq extends Ipaging {
|
export interface IRecordReq extends Ipaging {
|
||||||
deviceId?: string | string[];
|
deviceId?: any;
|
||||||
}
|
}
|
||||||
export interface IRecordRes {
|
export interface IRecordRes {
|
||||||
id: number
|
id: number
|
||||||
@ -323,3 +327,22 @@ export namespace TWarningDetail {
|
|||||||
warnType: number
|
warnType: number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export namespace THealthLatestData {
|
||||||
|
|
||||||
|
interface TReq {
|
||||||
|
deviceId: number | string
|
||||||
|
}
|
||||||
|
interface TRes {
|
||||||
|
hr: number
|
||||||
|
hrTime: string
|
||||||
|
hrArr: any[],
|
||||||
|
bo: number
|
||||||
|
boArr: any[],
|
||||||
|
boTime: string
|
||||||
|
temp: number
|
||||||
|
tempTime: string
|
||||||
|
tempArr: any[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import request from '../utils/request';
|
import request from '../utils/request';
|
||||||
import { TLogin, TAccount, IpagingRes, TDevice, TOrg, TRoleList, TStatisticsDevice, statisticsContentReq, statisticsContentRes, TStatisticsCount, TWarnRecord, TWarningDetail, TWarningConfirm, TDeviceConfigModify, TDeviceConfig } from "./index.d";
|
import { TLogin, TAccount, IpagingRes, TDevice, TOrg, TRoleList, TStatisticsDevice, statisticsContentReq, statisticsContentRes, TStatisticsCount, TWarnRecord, TWarningDetail, TWarningConfirm, TDeviceConfigModify, TDeviceConfig, THealthLatestData } from "./index.d";
|
||||||
|
|
||||||
export const fetchLogin = (p: TLogin.Ireq): Promise<TLogin.IRes> => {
|
export const fetchLogin = (p: TLogin.Ireq): Promise<TLogin.IRes> => {
|
||||||
return request({
|
return request({
|
||||||
@ -269,4 +269,13 @@ export const deviceConfigModify = (p: TDeviceConfigModify): Promise<null> => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取最新健康数据
|
||||||
|
export const healthLatestData = (p: THealthLatestData.TReq): Promise<THealthLatestData.TRes> => {
|
||||||
|
return request({
|
||||||
|
url: '/v1/web/health/latestData',
|
||||||
|
method: 'get',
|
||||||
|
params: p
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,12 +68,12 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-if="hasPagination"
|
v-if="hasPagination"
|
||||||
:current-page="currentPage"
|
:current-page="paging.page"
|
||||||
:page-size="pageSize"
|
:page-size="paging.size"
|
||||||
:pager-count="5"
|
:pager-count="5"
|
||||||
:background="true"
|
:background="true"
|
||||||
:layout="layout"
|
:layout="layout"
|
||||||
:total="total"
|
:total="paging.total"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -84,8 +84,23 @@ import { toRefs, PropType, ref } from "vue";
|
|||||||
import { Delete, Edit, View, Refresh } from "@element-plus/icons-vue";
|
import { Delete, Edit, View, Refresh } from "@element-plus/icons-vue";
|
||||||
import { ElMessageBox } from "element-plus";
|
import { ElMessageBox } from "element-plus";
|
||||||
import { TableItem } from "@/types/table";
|
import { TableItem } from "@/types/table";
|
||||||
|
interface TPaging {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
paging: {
|
||||||
|
type: Object as PropType<TPaging>,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
// 表格相关
|
// 表格相关
|
||||||
tableData: {
|
tableData: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<TableCustom :columns="columns" :tableData="tableData" :total="paging.total" :refresh="getData" :currentPage="paging.page" :changePage="changePage">
|
<TableCustom :columns="columns" :tableData="tableData" :paging="paging" :changePage="changePage">
|
||||||
<template #status="{ rows }">
|
<template #status="{ rows }">
|
||||||
<el-tag :type="rows.status == 1 ? 'success' : 'danger'">
|
<el-tag :type="rows.status == 1 ? 'success' : 'danger'">
|
||||||
{{ statusEnum[rows.status] }}
|
{{ statusEnum[rows.status] }}
|
||||||
|
@ -2,16 +2,25 @@
|
|||||||
<div class="deviceStatistics card">
|
<div class="deviceStatistics card">
|
||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
<div class="title">当前设备历史数据</div>
|
<div class="title">当前设备历史数据</div>
|
||||||
<el-button-group>
|
<el-radio-group v-model="radio" @change="change">
|
||||||
<el-button type="primary">心率</el-button>
|
<el-radio-button label="心率" value="1" />
|
||||||
<el-button>血氧</el-button>
|
<el-radio-button label="血氧" value="2" />
|
||||||
<el-button>体表温度</el-button>
|
<el-radio-button label="体表温度" value="3" />
|
||||||
</el-button-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
<slot name="chart"></slot>
|
<slot name="chart"></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup></script>
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const radio = ref("1");
|
||||||
|
const emit = defineEmits(["change"]);
|
||||||
|
|
||||||
|
const change = (e) => {
|
||||||
|
emit("change", e);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.card {
|
.card {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -2,60 +2,56 @@
|
|||||||
<div class="device">
|
<div class="device">
|
||||||
<div class="device-head">
|
<div class="device-head">
|
||||||
<div class="title">设备列表</div>
|
<div class="title">设备列表</div>
|
||||||
<el-select class="select">
|
<el-select class="select" v-model="paging.mode" @change="handelMode">
|
||||||
<el-option label="全部" value="0" />
|
<el-option label="全部" :value="undefined" />
|
||||||
<el-option label="常规模式" value="1" />
|
<el-option label="常规模式" value="0" />
|
||||||
|
<el-option label="审讯模式" value="1" />
|
||||||
<el-option label="户外押送" value="2" />
|
<el-option label="户外押送" value="2" />
|
||||||
<el-option label="审讯模式" value="3" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="device-list noScrollbar">
|
<div v-infinite-scroll="load" :infinite-scroll-immediate="false" class="device-list noScrollbar infinite-list" style="overflow: auto">
|
||||||
<el-popover :width="400" class="box-item" placement="bottom" v-for="item in 4" :key="item">
|
<el-popover :width="350" class="box-item" placement="bottom" v-for="item in list" :key="item.id">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="item-img">
|
<div class="item-img">
|
||||||
<img src="@/assets/img/handcuffs.png" alt="" srcset="" />
|
<img src="@/assets/img/handcuffs.png" alt="" srcset="" />
|
||||||
</div>
|
</div>
|
||||||
<div class="item-content">
|
<div class="item-content">
|
||||||
<div class="item-content-name">手铐-002</div>
|
<div class="item-content-name">手铐-{{ item.id }}</div>
|
||||||
<div class="item-content-num">860116079430636</div>
|
<div class="item-content-num">{{ item.deviceId }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-right">
|
<div class="item-right">
|
||||||
<div class="battery">
|
<div class="battery">
|
||||||
<div class="battery-icon">
|
<div class="battery-icon">
|
||||||
<img src="@/assets/img/battery.png" alt="" srcset="" />
|
<img src="@/assets/img/battery.png" alt="" srcset="" />
|
||||||
</div>
|
</div>
|
||||||
<div class="battery-num">98%</div>
|
<div class="battery-num">{{ item.battery }}%</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="user">admin</div>
|
<div class="user">{{ item.userNumber || "--" }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="demo-rich-conent">
|
<div class="demo-rich-conent">
|
||||||
<div>
|
|
||||||
<span class="lable">手铐关联人:</span>
|
|
||||||
张三
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<span class="lable">类型:</span>
|
<span class="lable">类型:</span>
|
||||||
警察
|
{{ item.adminType }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="lable">警号:</span>
|
<span class="lable">警号:</span>
|
||||||
123456
|
{{ item.adminUsername }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="lable">联系电话:</span>
|
<span class="lable">联系电话:</span>
|
||||||
13007777555
|
{{ item.adminPhone }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="lable">佩戴者编号:</span>
|
<span class="lable">状态:</span>
|
||||||
BJ-0112
|
<el-tag :type="statusColor[item.status]">{{ statusEnum[item.status] }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="lable">阈值:</span>
|
<span class="lable">模式:</span>
|
||||||
12
|
<el-tag :type="modeColor[item.mode]">{{ modeEnum[item.mode] }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -63,21 +59,62 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup></script>
|
<script setup lang="ts">
|
||||||
|
import { TDevice } from "@/api/index.d";
|
||||||
|
|
||||||
|
const statusColor = ["danger", "success", "warning"];
|
||||||
|
const modeColor = ["primary", "danger", "warning"];
|
||||||
|
enum statusEnum {
|
||||||
|
"离线" = 0,
|
||||||
|
"在线",
|
||||||
|
"充电中",
|
||||||
|
}
|
||||||
|
enum modeEnum {
|
||||||
|
"常规",
|
||||||
|
"审讯模式",
|
||||||
|
"户外押送",
|
||||||
|
}
|
||||||
|
|
||||||
|
const { list, paging, api } = defineProps({
|
||||||
|
list: {
|
||||||
|
type: Array<TDevice.IListRes>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
api: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
paging: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handelMode = () => {
|
||||||
|
paging.page += 1;
|
||||||
|
api();
|
||||||
|
};
|
||||||
|
const load = () => {
|
||||||
|
paging.page += 1;
|
||||||
|
api();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.device {
|
.device {
|
||||||
|
width: 100%;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
.device-head {
|
.device-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-top: 14px;
|
margin: 14px 0;
|
||||||
.title {
|
.title {
|
||||||
color: #061451;
|
color: #061451;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@ -97,7 +134,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.device-list {
|
.device-list {
|
||||||
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
list-style: none;
|
||||||
.item {
|
.item {
|
||||||
height: 89px;
|
height: 89px;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
@ -162,10 +201,12 @@
|
|||||||
.demo-rich-conent {
|
.demo-rich-conent {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.lable {
|
.lable {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 90px;
|
width: 90px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -3,53 +3,98 @@
|
|||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
<div class="title">当前设备告警记录</div>
|
<div class="title">当前设备告警记录</div>
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<el-select class="select" style="width: 120px; margin-right: 20px">
|
<el-select class="select" placeholder="请选择事件类型" v-model="paging.warnType" style="width: 150px; margin-right: 20px" @change="handelChange">
|
||||||
<el-option label="户外押送" value="1" />
|
<el-option label="全部" :value="undefined" />
|
||||||
<el-option label="审讯模式" value="2" />
|
<el-option v-for="(item, index) in warnTypeList" :key="index" :label="item" :value="index" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-select class="select" style="width: 120px">
|
<el-select class="select" placeholder="请选择处理状态" v-model="paging.status" style="width: 150px" @change="handelChange">
|
||||||
<el-option label="户外押送" value="1" />
|
<el-option label="全部" :value="undefined" />
|
||||||
<el-option label="审讯模式" value="2" />
|
<el-option label="待处理" value="0" />
|
||||||
|
<el-option label="已处理" value="1" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TableCustom :columns="columns" :tableData="tableData" :total="page.total" :refresh="getData" :currentPage="page.index" :changePage="changePage">
|
<TableCustom :columns="columns" :tableData="tableData" :paging="paging" :changePage="changePage">
|
||||||
<template #state="{ rows }">
|
<template #status="{ rows }">
|
||||||
<el-tag :type="rows.state ? 'success' : 'danger'">
|
<el-tag :type="statusColor[rows.status]">{{ warningStatusEnum[rows.status] }}</el-tag>
|
||||||
{{ rows.state ? "正常" : "异常" }}
|
</template>
|
||||||
</el-tag>
|
<template #warnType="{ rows }">
|
||||||
|
{{ warnTypeEnum[rows.warnType] }}
|
||||||
</template>
|
</template>
|
||||||
</TableCustom>
|
</TableCustom>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
defineProps({
|
import TableCustom from "@/components/table-custom.vue";
|
||||||
tableData: {
|
import { warningRecord } from "@/api/index";
|
||||||
type: Array,
|
import { ref, reactive, watch } from "vue";
|
||||||
default: () => [],
|
import { TDevice } from "@/api/index.d";
|
||||||
},
|
|
||||||
page: {
|
const statusColor = ["danger", "success"];
|
||||||
|
enum warningStatusEnum {
|
||||||
|
"待处理",
|
||||||
|
"已处理",
|
||||||
|
}
|
||||||
|
enum warnTypeEnum {
|
||||||
|
"SOS告警",
|
||||||
|
"围栏告警",
|
||||||
|
"破坏告警",
|
||||||
|
"低电告警",
|
||||||
|
"心率告警",
|
||||||
|
"血氧告警",
|
||||||
|
"体温告警",
|
||||||
|
}
|
||||||
|
const warnTypeList = ["SOS告警", "围栏告警", "破坏告警", "低电告警", "心率告警", "血氧告警", "体温告警"];
|
||||||
|
const paging = reactive({
|
||||||
|
page: 1,
|
||||||
|
size: 4,
|
||||||
|
total: 0,
|
||||||
|
deviceId: undefined,
|
||||||
|
status: undefined,
|
||||||
|
warnType: undefined,
|
||||||
|
});
|
||||||
|
const tableData = ref<TDevice.IWarningRecordRes[]>([]);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
deviceInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: undefined,
|
||||||
},
|
|
||||||
getData: {
|
|
||||||
type: Function,
|
|
||||||
default: () => {},
|
|
||||||
},
|
|
||||||
changePage: {
|
|
||||||
type: Function,
|
|
||||||
default: () => {},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.deviceInfo,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
paging.deviceId = newVal.deviceId;
|
||||||
|
getData && getData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true } // 关键选项
|
||||||
|
);
|
||||||
|
|
||||||
// 表格相关
|
// 表格相关
|
||||||
let columns = [
|
let columns = [
|
||||||
{ type: "index", label: "序号", width: 55, align: "center" },
|
{ type: "index", label: "序号", width: 55, align: "center" },
|
||||||
{ prop: "name", label: "事件类型" },
|
{ prop: "warnType", label: "事件类型" },
|
||||||
{ prop: "name", label: "触发时间" },
|
{ prop: "status", label: "处理状态" },
|
||||||
{ prop: "state", label: "处理状态" },
|
{ prop: "createTime", label: "触发时间" },
|
||||||
];
|
];
|
||||||
|
const getData = async () => {
|
||||||
|
const res = await warningRecord(paging);
|
||||||
|
tableData.value = res.records;
|
||||||
|
paging.total = res.total;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handelChange = () => {
|
||||||
|
paging.page = 1;
|
||||||
|
getData();
|
||||||
|
};
|
||||||
|
const changePage = (val: number) => {
|
||||||
|
paging.page = val;
|
||||||
|
getData();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.card {
|
.card {
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container scrollbar">
|
<div class="container">
|
||||||
<el-row :gutter="20">
|
<el-row class="el-row" :gutter="20">
|
||||||
<el-col :span="7"><DeviceInfo /></el-col>
|
<el-col :span="6" class="el-row-left"><DeviceInfo :paging="devicePaging" :api="getdeviceList" :list="deviceData" /></el-col>
|
||||||
<el-col :span="17">
|
<el-col :span="18" class="el-row-right scrollbar">
|
||||||
<MonitoringTop />
|
<MonitoringTop :funcList="funcList" />
|
||||||
<div v-if="false">
|
<div v-if="deviceInfo?.status != 2">
|
||||||
<div class="monitoringMap" id="mapcontainer"></div>
|
<div class="monitoringMap" id="mapcontainer"></div>
|
||||||
<el-row :gutter="20" style="margin-top: 20px">
|
<el-row :gutter="20" style="margin-top: 20px">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<DeviceHistory>
|
<DeviceHistory @change="handelRadio">
|
||||||
<template #chart>
|
<template #chart>
|
||||||
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
||||||
</template>
|
</template>
|
||||||
</DeviceHistory>
|
</DeviceHistory>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<DeviceRecord :tableData="tableData" :page="page" :getData="getData" :changePage="changePage" />
|
<DeviceRecord :deviceInfo="deviceInfo" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<el-row :gutter="20" style="margin-top: 20px">
|
<el-row :gutter="20" style="margin-top: 20px">
|
||||||
<el-col :span="24" style="height: 400px">
|
<el-col :span="24" style="height: 400px">
|
||||||
<DeviceHistory>
|
<DeviceHistory @change="handelRadio">
|
||||||
<template #chart>
|
<template #chart>
|
||||||
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
||||||
</template>
|
</template>
|
||||||
</DeviceHistory>
|
</DeviceHistory>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" style="margin-top: 20px">
|
<el-col :span="24" style="margin-top: 20px">
|
||||||
<DeviceRecord :tableData="tableData" :page="page" :getData="getData" :changePage="changePage" />
|
<DeviceRecord :deviceInfo="deviceInfo" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@ -44,58 +44,125 @@ import DeviceHistory from "./deviceHistory.vue";
|
|||||||
import DeviceRecord from "./deviceRecord.vue";
|
import DeviceRecord from "./deviceRecord.vue";
|
||||||
import { MapCustom } from "@/utils/mapCustom";
|
import { MapCustom } from "@/utils/mapCustom";
|
||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import { fetchData } from "@/api/index";
|
import { deviceList, healthLatestData, warningRecord } from "@/api/index";
|
||||||
|
import { TDevice, THealthLatestData } from "@/api/index.d";
|
||||||
import { onMounted, onDeactivated, ref, reactive } from "vue";
|
import { onMounted, onDeactivated, ref, reactive } from "vue";
|
||||||
import { TableItem } from "@/types/table";
|
import { debounce, format } from "@/utils";
|
||||||
import { debounce } from "@/utils";
|
import heart from "@/assets/img/heart.png";
|
||||||
|
import temperature from "@/assets/img/temperature.png";
|
||||||
|
import blood from "@/assets/img/blood.png";
|
||||||
|
|
||||||
const chartRef = ref(null);
|
const chartRef = ref(null);
|
||||||
let myChart = null;
|
let myChart = null;
|
||||||
|
let funcList = ref([
|
||||||
|
{ title: "当前心率", en: "DANGQIANXINLV", icon: heart, unit: "次/分", num: 0, color: "#FF0303" },
|
||||||
|
{ title: "当前血氧", en: "DANGQIANXUEYANG", icon: blood, unit: "%", num: 0, color: "#8B51FD" },
|
||||||
|
{ title: "当前体表温度", en: "DANGQIANTIBIAOWENDU", icon: temperature, unit: "次/分", num: 0, color: "#FF6905" },
|
||||||
|
]);
|
||||||
|
|
||||||
const ringOptions = {
|
const options = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: "category",
|
type: "category",
|
||||||
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
data: [],
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: "5%",
|
||||||
|
right: "4%",
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: "value",
|
type: "value",
|
||||||
},
|
},
|
||||||
series: [
|
series: {
|
||||||
{
|
name: "",
|
||||||
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
data: [],
|
||||||
type: "line",
|
type: "line",
|
||||||
|
itemStyle: {
|
||||||
|
color: "#ff4567", // 设置线条颜色
|
||||||
|
},
|
||||||
smooth: true,
|
smooth: true,
|
||||||
},
|
},
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const page = reactive({
|
const paging = reactive({
|
||||||
index: 1,
|
page: 1,
|
||||||
size: 10,
|
size: 10,
|
||||||
total: 200,
|
total: 0,
|
||||||
|
status: undefined,
|
||||||
|
warnType: undefined,
|
||||||
});
|
});
|
||||||
|
const devicePaging = reactive({
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
mode: undefined,
|
||||||
|
});
|
||||||
|
const HealthData = ref<THealthLatestData.TRes>();
|
||||||
|
|
||||||
const tableData = ref<TableItem[]>([]);
|
const deviceInfo = ref<TDevice.IListRes>();
|
||||||
|
const tableData = ref<TDevice.IWarningRecordRes[]>([]);
|
||||||
|
const deviceData = ref<TDevice.IListRes[]>([]);
|
||||||
|
|
||||||
const getData = async () => {
|
const getdeviceList = async () => {
|
||||||
const res = await fetchData();
|
const res = await deviceList(devicePaging);
|
||||||
tableData.value = res.data.list;
|
deviceData.value = res.records;
|
||||||
|
if (res.records.length > 0) {
|
||||||
|
deviceInfo.value = res.records[1];
|
||||||
|
getHealthLatestData();
|
||||||
|
// getData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const getData = async () => {
|
||||||
|
const res = await warningRecord({ ...paging, deviceId: deviceInfo.value.deviceId });
|
||||||
|
tableData.value = res.records;
|
||||||
|
paging.total = res.total;
|
||||||
|
};
|
||||||
|
const getHealthLatestData = () => {
|
||||||
|
healthLatestData({ deviceId: deviceInfo.value.deviceId }).then((res) => {
|
||||||
|
HealthData.value = res;
|
||||||
|
funcList.value[0].num = res.hr;
|
||||||
|
funcList.value[1].num = res.bo;
|
||||||
|
funcList.value[2].num = res.temp;
|
||||||
|
|
||||||
|
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
||||||
|
});
|
||||||
};
|
};
|
||||||
getData();
|
|
||||||
|
|
||||||
const changePage = (val: number) => {
|
const changePage = (val: number) => {
|
||||||
page.index = val;
|
paging.page = val;
|
||||||
getData();
|
getData();
|
||||||
};
|
};
|
||||||
|
const handelRadio = (val: number) => {
|
||||||
|
if (val == 1) {
|
||||||
|
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
||||||
|
} else if (val == 2) {
|
||||||
|
getOptionsData(HealthData.value.boArr, "血氧", "#983AFC");
|
||||||
|
} else if (val == 3) {
|
||||||
|
getOptionsData(HealthData.value.tempArr, "体表温度", "#FFA91F");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const getOptionsData = (list: { time: string; value: number }[], name: string, color: string) => {
|
||||||
|
options.xAxis.data = [];
|
||||||
|
options.series.data = [];
|
||||||
|
list.forEach((item) => {
|
||||||
|
options.xAxis.data.push(format(item.time, "HH:mm:ss"));
|
||||||
|
options.series.data.push(item.value);
|
||||||
|
});
|
||||||
|
options.series.name = name;
|
||||||
|
options.series.itemStyle.color = color;
|
||||||
|
myChart.setOption(options);
|
||||||
|
};
|
||||||
|
|
||||||
const handleResize = debounce(() => {
|
const handleResize = debounce(() => {
|
||||||
myChart.resize();
|
myChart.resize();
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
getdeviceList();
|
||||||
new MapCustom({ dom: "mapcontainer" });
|
new MapCustom({ dom: "mapcontainer" });
|
||||||
if (chartRef.value) {
|
if (chartRef.value) {
|
||||||
myChart = echarts.init(chartRef.value);
|
myChart = echarts.init(chartRef.value);
|
||||||
myChart.setOption(ringOptions);
|
|
||||||
window.addEventListener("resize", handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -104,6 +171,24 @@ onDeactivated(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
.container {
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
.el-row {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
.el-row-left {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.el-row-right {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.monitoringMap {
|
.monitoringMap {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<div class="en">{{ item.en }}</div>
|
<div class="en">{{ item.en }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-left-bottom">
|
<div class="item-left-bottom">
|
||||||
<div class="num" :style="{ color: item.color }">{{ item.num }}</div>
|
<div class="num" :style="{ color: item.color }">{{ item.num || "--" }}</div>
|
||||||
<div class="unit" :style="{ color: item.color }">{{ item.unit }}</div>
|
<div class="unit" :style="{ color: item.color }">{{ item.unit }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -19,15 +19,21 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import heart from "@/assets/img/heart.png";
|
interface TFuncList {
|
||||||
import temperature from "@/assets/img/temperature.png";
|
title: string;
|
||||||
import blood from "@/assets/img/blood.png";
|
en: string;
|
||||||
let funcList = [
|
icon: string;
|
||||||
{ title: "当前心率", en: "DANGQIANXINLV", icon: heart, unit: "次/分", num: 186, color: "#FF0303" },
|
unit: string;
|
||||||
{ title: "当前血氧", en: "DANGQIANXUEYANG", icon: blood, unit: "%", num: 99, color: "#8B51FD" },
|
num: number;
|
||||||
{ title: "当前体表温度", en: "DANGQIANTIBIAOWENDU", icon: temperature, unit: "次/分", num: 86, color: "#FF6905" },
|
color: string;
|
||||||
];
|
}
|
||||||
|
defineProps({
|
||||||
|
funcList: {
|
||||||
|
type: Array<TFuncList>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.monitoring-top {
|
.monitoring-top {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<el-input style="width: 240px" v-model="search" placeholder="搜索设备IMEI号" :suffix-icon="Search" @input="handleInput" />
|
<el-input style="width: 240px" v-model="search" placeholder="搜索设备IMEI号" :suffix-icon="Search" @input="handleInput" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<TableCustom :columns="columns" :tableData="tableData" :total="page.total" :currentPage="page.index" :changePage="changePage">
|
<TableCustom :columns="columns" :tableData="tableData" :paging="page" :changePage="changePage">
|
||||||
<template #location="{ rows }">
|
<template #location="{ rows }">
|
||||||
<el-button type="success" link :icon="View" v-if="rows.warnType == 0 || rows.warnType == 1" @click="toIncidentDispose(rows.deviceId)"> 查看 </el-button>
|
<el-button type="success" link :icon="View" v-if="rows.warnType == 0 || rows.warnType == 1" @click="toIncidentDispose(rows.deviceId)"> 查看 </el-button>
|
||||||
</template>
|
</template>
|
||||||
@ -19,12 +19,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { PropType, ref } from "vue";
|
||||||
import { Search, View } from "@element-plus/icons-vue";
|
import { Search, View } from "@element-plus/icons-vue";
|
||||||
|
import TableCustom from "@/components/table-custom.vue";
|
||||||
import { debounce } from "@/utils";
|
import { debounce } from "@/utils";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { TWarnRecord } from "@/api/index.d";
|
import { TWarnRecord } from "@/api/index.d";
|
||||||
|
|
||||||
|
interface TPaging {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
total: number;
|
||||||
|
deviceId?: number;
|
||||||
|
}
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
enum statusEnum {
|
enum statusEnum {
|
||||||
"待处理",
|
"待处理",
|
||||||
@ -38,8 +46,12 @@ const { tableData, page, getData, changePage } = defineProps({
|
|||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
type: Object,
|
type: Object as PropType<TPaging>,
|
||||||
default: () => ({}),
|
default: () => ({
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
getData: {
|
getData: {
|
||||||
type: Function,
|
type: Function,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<TableCustom :columns="columns" :tableData="tableData" :total="paging.total" :refresh="getData" :currentPage="paging.page" :changePage="changePage">
|
<TableCustom :columns="columns" :tableData="tableData" :paging="paging" :refresh="getData" :changePage="changePage">
|
||||||
<template #toolbarBtn>
|
<template #toolbarBtn>
|
||||||
<el-button type="primary" @click="handleAdd">新增</el-button>
|
<el-button type="primary" @click="handleAdd">新增</el-button>
|
||||||
<!-- <el-button>导出</el-button> -->
|
<!-- <el-button>导出</el-button> -->
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<el-tag :type="statusColor[rows.status]">{{ warningStatusEnum[rows.status] }}</el-tag>
|
<el-tag :type="statusColor[rows.status]">{{ warningStatusEnum[rows.status] }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #warnType="{ rows }">
|
<template #warnType="{ rows }">
|
||||||
{{ warnTypeEnum[rows.status] }}
|
{{ warnTypeEnum[rows.warnType] }}
|
||||||
</template>
|
</template>
|
||||||
</TableCustom>
|
</TableCustom>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<TableCustom :columns="columns" :tableData="tableData" :total="paging.total" :refresh="getData" :currentPage="paging.page" :changePage="changePage">
|
<TableCustom :columns="columns" :tableData="tableData" :paging="paging" :refresh="getData" :changePage="changePage">
|
||||||
<template #toolbarBtn>
|
<template #toolbarBtn>
|
||||||
<!-- <el-button type="primary" @click="handleAdd">新增</el-button> -->
|
<!-- <el-button type="primary" @click="handleAdd">新增</el-button> -->
|
||||||
<el-button @click="handleEdit">手铐关联</el-button>
|
<el-button @click="handleEdit">手铐关联</el-button>
|
||||||
@ -205,10 +205,8 @@ const closeDialog = () => {
|
|||||||
visible.value = false;
|
visible.value = false;
|
||||||
isEdit.value = false;
|
isEdit.value = false;
|
||||||
};
|
};
|
||||||
console.log(222222);
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log(111111);
|
|
||||||
getData();
|
getData();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
<TableSearch :query="query" :options="searchOpt" :search="handleSearch" />
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<TableCustom :columns="columns" :tableData="tableData" :total="paging.total" :refresh="getData" :currentPage="paging.page" :changePage="changePage">
|
<TableCustom :columns="columns" :tableData="tableData" :paging="paging" :refresh="getData" :changePage="changePage">
|
||||||
<template #toolbarBtn>
|
<template #toolbarBtn>
|
||||||
<el-button type="primary" @click="typeVisible = true">类型编辑</el-button>
|
<el-button type="primary" @click="typeVisible = true">类型编辑</el-button>
|
||||||
<el-button type="primary" @click="handelRow('add')">新增用户</el-button>
|
<el-button type="primary" @click="handelRow('add')">新增用户</el-button>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user