2025年04月10日13:33:36

This commit is contained in:
luojiayi 2025-04-10 13:33:38 +08:00
parent 5f0cda3d45
commit 054d5fb5ca
15 changed files with 361 additions and 116 deletions

2
components.d.ts vendored
View File

@ -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
View File

@ -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[]
}
}

View File

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

View File

@ -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,

View File

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

View File

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

View File

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

View File

@ -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 {

View File

@ -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",
smooth: true, itemStyle: {
color: "#ff4567", // 线
}, },
], 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;

View File

@ -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 {

View File

@ -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,

View File

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

View File

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

View File

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

View File

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