2025年04月09日18:45:43

This commit is contained in:
luojiayi 2025-04-09 18:45:44 +08:00
parent 347feb8eb5
commit 5f0cda3d45
15 changed files with 519 additions and 263 deletions

4
components.d.ts vendored
View File

@ -9,7 +9,9 @@ declare module '@vue/runtime-core' {
export interface GlobalComponents {
Alarm: typeof import('./src/components/alarm.vue')['default']
BatchImp: typeof import('./src/components/batch-imp.vue')['default']
copy: typeof import('./src/components/upload-img copy.vue')['default']
Countup: typeof import('./src/components/countup.vue')['default']
CustomInput: typeof import('./src/components/CustomInput.vue')['default']
DeviceInfo: typeof import('./src/components/deviceInfo.vue')['default']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton']
@ -54,8 +56,10 @@ declare module '@vue/runtime-core' {
TableEdit: typeof import('./src/components/table-edit.vue')['default']
TableSearch: typeof import('./src/components/table-search.vue')['default']
UploadImg: typeof import('./src/components/upload-img.vue')['default']
UploadImgsa: typeof import('./src/components/upload-imgsa.vue')['default']
}
export interface ComponentCustomProperties {
vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll']
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}

150
src/api/index.d.ts vendored
View File

@ -15,6 +15,86 @@ export interface TRoleList {
createTime: string
}
export interface TStatisticsDevice {
addCount: number
deviceTotal: number
onlineCount: number
warnCount: number
}
export interface TStatisticsCount {
addCount: number
deviceTotal: number
onlineCount: number
warnCount: number
}
export interface statisticsContentReq {
type: string
startDate: string
endDate: string
}
export interface statisticsContentRes {
sosCount: number
railCount: number
destroyCount: number
batteryCount: number
heartRateCount: number
bloodOxygenCount: number
tempCount: number
times: any[],
sosArr: any[],
railArr: any[],
destroyArr: any[],
healthArr: any[],
}
export interface TWarningConfirm {
id?: number | string
name: string
username: string
content: string
images: string[]
}
export interface TDeviceConfigModify {
deviceId: string | string[]
userNumber: string
minHr: number
maxHr: number
minBo: number
minTemp: number
maxTemp: number
contacts: any[]
}
export namespace TDeviceConfig {
interface Treq {
deviceId: string | string[]
}
interface Tcontacts {
name: string
phone: string
}
interface Tres {
deviceId: string | string[]
userNumber: string
minHr: number
minBo: number
minTemp: number
maxTemp: number
maxHr: number
name?: string
phone?: string
contacts: Tcontacts[]
}
}
export namespace TLogin {
export interface Ireq {
username: string;
@ -103,7 +183,7 @@ export namespace TDevice {
}
export interface IRecordReq extends Ipaging {
deviceId?: number;
deviceId?: string | string[];
}
export interface IRecordRes {
id: number
@ -212,42 +292,34 @@ export namespace TWarnRecord {
}
}
export interface TStatisticsDevice {
addCount: number
deviceTotal: number
onlineCount: number
warnCount: number
export namespace TWarningDetail {
interface TParams {
id: number | string
}
interface TRes {
address: string
adminName: string
adminPhone: string
creatUser: string
createTime: string
deviceId: string
healthData: string
id: number
lat: number
lng: number
maxValue: number
minValue: number
rcontent: string
rimg: any
rname: string
status: number
type: number
updateTime: string
updateUser: string
userNumber: string
username: string
value: string
orgName: string
warnType: number
}
}
export interface TStatisticsCount {
addCount: number
deviceTotal: number
onlineCount: number
warnCount: number
}
export interface statisticsContentReq {
type: string
startDate: string
endDate: string
}
export interface statisticsContentRes {
sosCount: number
railCount: number
destroyCount: number
batteryCount: number
heartRateCount: number
bloodOxygenCount: number
tempCount: number
times: any[],
sosArr: any[],
railArr: any[],
destroyArr: any[],
healthArr: any[],
}

View File

@ -1,5 +1,5 @@
import request from '../utils/request';
import { TLogin, TAccount, IpagingRes, TDevice, TOrg, TRoleList, TStatisticsDevice, statisticsContentReq, statisticsContentRes, TStatisticsCount, TWarnRecord } from "./index.d";
import { TLogin, TAccount, IpagingRes, TDevice, TOrg, TRoleList, TStatisticsDevice, statisticsContentReq, statisticsContentRes, TStatisticsCount, TWarnRecord, TWarningDetail, TWarningConfirm, TDeviceConfigModify, TDeviceConfig } from "./index.d";
export const fetchLogin = (p: TLogin.Ireq): Promise<TLogin.IRes> => {
return request({
@ -116,7 +116,7 @@ export const setMode = (p: TDevice.ISetMonitor): Promise<null> => {
// 获取定位
export const deviceGetLocation = (p: TDevice.ISetMonitor): Promise<null> => {
return request({
url: '/v1/web/device/getLocation',
url: '/v1/web/device/getLocate',
method: 'post',
data: p
});
@ -143,7 +143,7 @@ export const deviceUseRecord = (p: TDevice.IRecordReq): Promise<IpagingRes<TDevi
// 预警记录
export const warningRecord = (p: TDevice.IRecordReq): Promise<IpagingRes<TDevice.IWarningRecordRes>> => {
return request({
url: '/v1/web/device/warning/record',
url: '/v1/web/warning/record',
method: 'get',
params: p
});
@ -186,7 +186,7 @@ export const orgDelete = (p?: TOrg.Idel): Promise<null> => {
// 获取角色列表
export const roleList = (): Promise<TRoleList[]> => {
return request({
url: '/v1/web/account/role/list',
url: '/v1/web/role/list',
method: 'get',
});
};
@ -227,10 +227,46 @@ export const statisticsWarningapi = (): Promise<statisticsContentRes> => {
// 预警记录
export const warnRecord = (p: TWarnRecord.IListReq): Promise<IpagingRes<TWarnRecord.IListRes>> => {
return request({
url: '/v1/web/warn/record',
url: '/v1/web/warning/record',
method: 'get',
params: p
});
};
// 预警记录
export const warningDetail = (p: TWarningDetail.TParams): Promise<TWarningDetail.TRes> => {
return request({
url: '/v1/web/warning/detail',
method: 'get',
params: p
});
};
// 预警记录
export const warningConfirm = (p: TWarningConfirm): Promise<null> => {
return request({
url: '/v1/web/warning/confirm',
method: 'post',
data: p
});
};
// 获取专项配置
export const deviceConfig = (p: TDeviceConfig.Treq): Promise<TDeviceConfig.Tres> => {
return request({
url: '/v1/web/device/deviceConfig',
method: 'get',
params: p
});
};
// 修改专项配置
export const deviceConfigModify = (p: TDeviceConfigModify): Promise<null> => {
return request({
url: '/v1/web/device/deviceConfig/modify',
method: 'post',
data: p
});
};

BIN
src/assets/img/location.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,12 +1,17 @@
<template>
<el-upload
v-model:file-list="fileList"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:style="`--width: ${size}px; --height: ${size}px`"
class="upload"
accept="image/*"
list-type="picture-card"
v-model:file-list="fileList"
:action="ACTION"
:headers="HEADERS"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:on-success="handleSuccess"
:limit="9"
:before-upload="beforeUpload"
>
<el-icon><Plus /></el-icon>
</el-upload>
@ -19,31 +24,57 @@
<script lang="ts" setup>
import { ref } from "vue";
import { Plus } from "@element-plus/icons-vue";
import type { UploadProps, UploadUserFile } from "element-plus";
const { size } = defineProps({
import { ElMessage, UploadProps } from "element-plus";
import { useCommonStore } from "@/store/common";
interface Tdata {
code: number;
data: {
imeUrl: string;
};
msg: string;
}
const comm = useCommonStore();
const ACTION = import.meta.env.VITE_APP_URL + "/v1/web/upload/warning/img";
const HEADERS = {
"Access-Token": comm.user.token,
};
const { size, modelValue } = defineProps({
size: {
type: Number,
default: 100,
},
modelValue: {
type: Array,
default: () => [],
},
});
const fileList = ref<UploadUserFile[]>([
{
name: "food.jpeg",
url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
},
const emit = defineEmits(["update:modelValue"]);
{
name: "food.jpeg",
url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
},
]);
const fileList = ref<any[]>([]);
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
console.log(uploadFile, uploadFiles);
const beforeUpload = (rawFile: any) => {
const isLtSize = rawFile.size / 1024 / 1024 < 5;
if (!isLtSize) {
ElMessage.error("上传图片大小不能超过 5MB!");
return false;
}
return true;
};
const handleSuccess = ({ code, data, msg }: Tdata) => {
if (code != 200) return ElMessage.error(msg);
let list = fileList.value.map((item) => item?.response?.data?.imeUrl);
emit("update:modelValue", list);
};
const handleRemove: UploadProps["onRemove"] = () => {
let list = fileList.value.map((item) => item?.response?.data?.imeUrl);
emit("update:modelValue", list);
};
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {

View File

@ -11,15 +11,6 @@
</keep-alive>
</transition>
</router-view>
<!-- <el-scrollbar>
<router-view v-slot="{ Component }">
<transition name="move" mode="out-in">
<keep-alive>
<component :is="Component"></component>
</keep-alive>
</transition>
</router-view>
</el-scrollbar> -->
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@ export class MapCustom {
this.map = new AMap.Map(data.dom, {
version: "1.4.15",
zoom: 13,
center: [116.397428, 39.90923], //初始化地图中心点
center: data.center || [116.397428, 39.90923], //初始化地图中心点
...data,
});
}
@ -102,6 +102,25 @@ export class MapCustom {
})
}
newIcon(url) {
return new AMap.Icon({
size: new AMap.Size(36, 42),
image: url, // Icon的图像
imageSize: new AMap.Size(36, 42)
})
}
// 创建marker
marker({ icon, position }) {
return new AMap.Marker({
icon,
position,
map: this.map,
offset: new AMap.Pixel(-25, -50),
})
}
lngLat(lng, lat) {
return new AMap.LngLat(lng, lat);
}
clearMap() {
this.map.clearMap();

View File

@ -15,7 +15,6 @@ service.interceptors.request.use(
return config;
},
(error: AxiosError) => {
console.log(error);
return Promise.reject();
}
);
@ -38,7 +37,6 @@ service.interceptors.response.use(
},
(error: AxiosError) => {
console.log(error);
return Promise.reject();
}
);

View File

@ -12,7 +12,7 @@
{{ warnTypeEnum[rows.warnType] }}
</template>
<template #operator="{ rows }">
<el-button type="primary" size="small" link @click="toIncidentDispose(rows.deviceId)"> 处理事件 </el-button>
<el-button type="primary" size="small" link @click="toIncidentDispose(rows.id)"> 处理事件 </el-button>
</template>
</TableCustom>
</div>

View File

@ -12,57 +12,61 @@
<el-col :span="7">
<div class="right-content">
<div class="info scrollbar">
<div class="info-text">设备序号05</div>
<div class="info-text">IMEI号860116079430636</div>
<div class="info-text">告警时间2025/03/26 18:33:32</div>
<div class="info-text">告警类型<span style="color: red">体表温度过低</span></div>
<div class="info-text">绑定关联人名称张三</div>
<div class="info-text">绑定关联人警号123456</div>
<div class="info-text">现在状态禁用</div>
<div class="info-text">紧急电话10000000000</div>
<div class="info-text">隶属辖区87</div>
<div class="info-box">
<div class="info-text">设备序号{{ curData.id }}</div>
<div class="info-text">IMEI号{{ curData.deviceId }}</div>
<div class="info-text">告警时间{{ curData.createTime }}</div>
<div class="info-text">
告警类型<span style="color: red">{{ warnTypeEnum[curData.warnType] }}</span>
</div>
<div class="info-text">绑定关联人名称{{ curData.username }}</div>
<div class="info-text">绑定关联人警号{{ curData.userNumber }}</div>
<div class="info-text">状态{{ statusEnum[curData.status] }}</div>
<div class="info-text">紧急电话{{ curData.adminPhone }}</div>
<div class="info-text">隶属辖区{{ curData.orgName }}</div>
<div class="info-box" v-if="curData.type == 1">
<div class="info-box-title">生理指标</div>
<div class="info-box-contetn">
<div class="item">
<div class="label">&nbsp;&nbsp;当前指标</div>
<div class="value">38.4</div>
<div class="value">{{ curData.maxValue }}{{ unitEnum[curData.warnType] }}</div>
</div>
<div class="item">
<div class="item" v-if="curData.warnType == 5">
<div class="label">&nbsp;&nbsp;最大值</div>
<div class="value">38.4</div>
<div class="value">{{ curData.maxValue }}{{ unitEnum[curData.warnType] }}</div>
</div>
<div class="item">
<div class="label">&nbsp;&nbsp;最小值</div>
<div class="value">36.4</div>
<div class="value">{{ curData.maxValue }}{{ unitEnum[curData.warnType] }}</div>
</div>
</div>
</div>
<div class="info-form">
<el-form :model="formInline" label-position="top">
<el-form :model="ruleForm" :rules="rules" ref="ruleFormRef" label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="处理人:">
<el-input v-model="formInline.user" clearable />
<el-form-item label="处理人:" prop="name">
<el-input v-model="ruleForm.name" clearable :disabled="curData.status == 1" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="警号:">
<el-input v-model="formInline.user" clearable />
<el-form-item label="警号:" prop="username">
<el-input v-model="ruleForm.username" clearable :disabled="curData.status == 1" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="处理记录:">
<el-input v-model="formInline.user" clearable :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" />
<el-form-item label="处理记录:" prop="content">
<el-input v-model="ruleForm.content" clearable :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" :disabled="curData.status == 1" />
</el-form-item>
<el-form-item label="处理图片:">
<Upload />
<el-form-item label="处理图片:" prop="images">
<Upload v-model="ruleForm.images" :disabled="curData.status == 1" />
</el-form-item>
</el-form>
</div>
</div>
<div class="right-foot">
<el-button type="primary">保存</el-button>
<el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
</div>
</div>
</el-col>
@ -71,24 +75,39 @@
</template>
<script setup lang="ts" name="incidentDispose">
import handcuffs from "@/assets/img/handcuffs.png";
import location from "@/assets/img/location.png";
import { MapCustom } from "@/utils/mapCustom";
import { onMounted, ref, reactive } from "vue";
import Upload from "@/components/upload-img.vue";
import * as echarts from "echarts";
import { warnRecord } from "@/api/index";
import { TWarnRecord } from "@/api/index.d";
import { warningDetail, warningConfirm } from "@/api/index";
import { TWarningConfirm, TWarningDetail } from "@/api/index.d";
import { useRoute } from "vue-router";
import { ElMessage, FormInstance, FormRules } from "element-plus";
//
enum unitEnum {
"次/分" = 4,
"%",
"℃",
}
enum statusEnum {
"待处理",
"已处理",
}
enum warnTypeEnum {
"SOS告警",
"围栏告警",
"破坏告警",
"低电告警",
"心率告警",
"血氧告警",
"体温告警",
}
const { query } = useRoute();
const chartRef = ref(null);
let tabs = [
{ label: "全部", value: undefined },
{ label: "未处理", value: 0 },
{ label: "已处理", value: 1 },
];
const ruleFormRef = ref<FormInstance>();
let map = null;
const ringOptions = {
title: {
@ -115,45 +134,80 @@ const ringOptions = {
},
],
};
const formInline = reactive({
user: "",
region: "",
date: "",
const ruleForm = reactive<TWarningConfirm>({
id: query.deviceId as string,
name: "",
username: "",
content: "",
images: [],
});
const paging = reactive({
page: 1,
size: 10,
total: 0,
let curData = ref<TWarningDetail.TRes>({
address: "",
adminName: "",
adminPhone: "",
creatUser: "",
createTime: "",
deviceId: "",
status: undefined,
healthData: "",
id: 0,
lat: 0,
lng: 0,
maxValue: 0,
minValue: 0,
rcontent: "",
rimg: [],
rname: "",
status: 0,
type: 0,
updateTime: "",
updateUser: "",
userNumber: "",
username: "",
orgName: "",
value: "",
warnType: 0,
});
const tableData = ref<TWarnRecord.IListRes[]>([]);
const rules = reactive<FormRules<TWarningConfirm>>({
name: [{ required: true, message: "请输入处理人", trigger: "blur" }],
username: [{ required: true, message: "请输入警号", trigger: "blur" }],
content: [{ required: true, message: "请输入处理记录", trigger: "blur" }],
images: [{ required: true, message: "请上传图片", trigger: "blur" }],
});
const getData = async () => {
try {
const res = await warnRecord(paging);
tableData.value = res.records;
paging.total = res.total;
const res = await warningDetail({ id: query.deviceId as string });
curData.value = res;
ruleForm.name = res.rname;
ruleForm.username = res.rname;
ruleForm.content = res.rcontent;
ruleForm.images = JSON.parse(res.rimg);
console.log(ruleForm, "ruleFormruleFormruleFormruleForm");
let icon = map.newIcon(location);
let marker = map.marker({ icon, position: [116.406315, 39.908775] });
marker.setMap(map.map);
} catch (error) {}
};
const load = () => {
paging.page++;
getData();
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
if (valid) {
warningConfirm(ruleForm).then(() => {
ElMessage.success("处理成功");
curData.value.status = 1;
});
}
});
};
const checkTabs = (item: number | undefined) => {
// paging.status = item;
// paging.page = 1;
// getData();
};
onMounted(() => {
getData();
map = new MapCustom({ dom: "mapcontainer", center: [116.406315, 39.908775] });
if (chartRef.value) {
const myChart = echarts.init(chartRef.value);
myChart.setOption(ringOptions);
}
new MapCustom({ dom: "mapcontainer" });
// getData();
});
</script>

View File

@ -54,20 +54,16 @@ const submitForm = async (formEl: FormInstance | undefined) => {
await formEl.validate((valid, fields) => {
if (valid) {
fetchLogin(ruleForm)
.then((res) => {
comm.setUser(res);
ElMessage({
message: "登录成功",
type: "success",
});
setTimeout(() => {
router.push("/");
}, 1000);
})
.catch((err) => {
console.log(err, "err");
fetchLogin(ruleForm).then((res) => {
comm.setUser(res);
ElMessage({
message: "登录成功",
type: "success",
});
setTimeout(() => {
router.push("/");
}, 1000);
});
}
});
};

View File

@ -47,11 +47,15 @@
:currentPage="paging1.page"
:changePage="changeWarningPage"
>
<template #operator>
<el-button link type="primary" size="small"> 处理事件 </el-button>
<template #operator="{ rows }">
<el-button link type="primary" size="small" @click="toIncidentDispose(rows.id)" v-if="rows.status == 0"> 处理事件 </el-button>
<div v-else></div>
</template>
<template #status="{ rows }">
{{ warningStatusEnum[rows.status] }}
<el-tag :type="statusColor[rows.status]">{{ warningStatusEnum[rows.status] }}</el-tag>
</template>
<template #warnType="{ rows }">
{{ warnTypeEnum[rows.status] }}
</template>
</TableCustom>
</el-card>
@ -65,8 +69,9 @@ import TableCustom from "@/components/table-custom.vue";
import { TableItem } from "@/types/table";
import { useRouter, useRoute } from "vue-router";
import { TDevice } from "@/api/index.d";
const router = useRouter();
const { query } = useRoute();
const router = useRouter();
enum statusEnum {
"使用中" = 0,
"在线",
@ -80,7 +85,16 @@ enum recordStatusEnum {
"使用中" = 1,
"结束使用",
}
enum warnTypeEnum {
"SOS告警",
"围栏告警",
"破坏告警",
"低电告警",
"心率告警",
"血氧告警",
"体温告警",
}
const statusColor = ["danger", "success"];
//
let record = ref([
{ type: "index", label: "序号", width: 55, align: "center" },
@ -95,17 +109,19 @@ let columns = ref([
{ type: "index", label: "序号", width: 55, align: "center" },
{ prop: "userNumber", label: "佩戴者" },
{ prop: "warnType", label: "事件类型" },
{ prop: "creatUser", label: "触发时间" },
{ prop: "createTime", label: "触发时间" },
{ prop: "status", label: "处理状态" },
{ prop: "operator", label: "操作" },
]);
const paging = reactive({
deviceId: query.deviceId,
page: 1,
size: 10,
total: 0,
});
const paging1 = reactive({
deviceId: query.deviceId,
page: 1,
size: 10,
total: 0,
@ -134,6 +150,12 @@ const changeWarningPage = (val: number) => {
paging1.page = val;
getWarningData();
};
const toIncidentDispose = (deviceId: string) => {
router.push({
path: "/incidentDispose",
query: { deviceId },
});
};
</script>
<style scoped lang="less">

View File

@ -29,7 +29,7 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="模式选择:">
<el-select placeholder="请选择模式" v-model="modelValue.monitorMode" style="width: 230px" @change="handelControl(5)">
<el-select placeholder="请选择模式" v-model="modelValue.mode" style="width: 230px" @change="handelControl(5)">
<el-option label="常规模式" :value="0" />
<el-option label="审讯模式" :value="1" />
<el-option label="户外押送模式" :value="2" />

View File

@ -10,20 +10,16 @@
<!-- <el-button>导出</el-button> -->
</template>
<template #state="{ rows }">
{{ stateEnum[rows.state] }}
</template>
<template #deviceSwitch="{ rows }">
{{ deviceSwitchEnum[rows.deviceSwitch] }}
<template #status="{ rows }">
<el-tag :type="statusColor[rows.status]">{{ statusEnum[rows.status] }}</el-tag>
</template>
<template #mode="{ rows }">
{{ modeEnum[rows.mode] }}
<el-tag :type="modeColor[rows.mode]">{{ modeEnum[rows.mode] }}</el-tag>
</template>
<template #monitorMode="{ rows }">
{{ monitorModeEnum[rows.monitorMode] }}
<template #deviceSwitch="{ rows }">
<el-switch v-model="rows.deviceSwitch" />
</template>
<template #battery="{ rows }"> {{ rows.battery }}% </template>
<template #operator="{ rows }">
<el-button link type="primary" size="small" @click="toPage('deviceInfo', rows)"> 详细信息 </el-button>
<el-button link type="primary" size="small" @click="toPage('mapLocation', rows)"> 地图位置 </el-button>
@ -46,8 +42,8 @@
</template>
<script setup lang="ts" name="basetable">
import { ref, reactive } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { ref, reactive, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { deviceList, setMode, deviceGetLocation, deviceControl } from "@/api/index";
import { TDevice } from "@/api/index.d";
import TableCustom from "@/components/table-custom.vue";
@ -58,24 +54,21 @@ import { TableItem } from "@/types/table";
import { FormOption, FormOptionList } from "@/types/form-option";
import { useRouter } from "vue-router";
enum stateEnum {
enum statusEnum {
"离线" = 0,
"在线",
"充电中",
}
enum deviceSwitchEnum {
"禁用" = 0,
"启用",
}
enum modeEnum {
"室内" = 0,
"室外",
}
enum monitorModeEnum {
"室内" = 0,
"室外",
"常规",
"审讯模式",
"户外押送",
}
const statusColor = ["danger", "success", "warning"];
const modeColor = ["primary", "danger", "warning"];
const router = useRouter();
// /
let TableEditOptions = ref<FormOption>({
@ -110,14 +103,15 @@ let columns = ref([
{ prop: "deviceId", label: "手铐IMEI" },
{ prop: "name", label: "绑定警察名称" },
{ prop: "username", label: "绑定警察账户" },
{ prop: "state", label: "设备状态" },
{ prop: "mode", label: "当前模式" },
{ prop: "deviceSwitch", label: "开关" },
{ prop: "monitorMode", label: "监测模式" },
{ prop: "battery", label: "电量" },
{ prop: "deviceVersion", label: "版本号" },
{ prop: "createTime", label: "创建时间" },
{ prop: "status", label: "设备状态" },
{ prop: "mode", label: "当前模式" },
{ prop: "deviceSwitch", label: "开关" },
{ prop: "orgName", label: "关联辖区编号" },
{ prop: "createTime", label: "最新通信时间" },
{ prop: "createTime", label: "创建时间" },
{ prop: "operator", label: "操作", width: 400 },
]);
const paging = reactive({
@ -126,7 +120,7 @@ const paging = reactive({
total: 0,
});
const controlForm = reactive({
pattern: 1,
mode: 0,
location: 1,
});
@ -136,7 +130,6 @@ const getData = async () => {
tableData.value = res.records;
paging.total = res.total;
};
getData();
const changePage = (val: number) => {
paging.page = val;
@ -163,6 +156,7 @@ const handleEdit = (row?: TDevice.IListRes) => {
const handelRow = (row?: TDevice.IListRes) => {
rowData.value = { ...row };
controlForm.mode = row.mode;
visible1.value = true;
};
@ -175,6 +169,15 @@ const handelControl = (type: number) => {
ElMessage.success("操作成功");
});
break;
case 5:
setMode({
deviceId: rowData.value.deviceId,
mode: controlForm.mode,
}).then(() => {
getData();
ElMessage.success("操作成功");
});
break;
default:
let cmdEnum = {
1: "poweroff",
@ -192,16 +195,6 @@ const handelControl = (type: number) => {
visible1.value = false;
};
//
const handelDel = (row: TableItem) => {
ElMessageBox.confirm("确定要删除吗?", "提示", {
type: "warning",
})
.then(async () => {
// ElMessage.success("");
})
.catch(() => {});
};
const updateData = () => {
closeDialog();
@ -212,11 +205,13 @@ const closeDialog = () => {
visible.value = false;
isEdit.value = false;
};
console.log(222222);
onMounted(() => {
console.log(111111);
getData();
});
//
const handleDelete = (row: TableItem) => {
ElMessage.success("删除成功");
};
//
const toPage = (path: string, row: TDevice.IListRes) => {
let p;
@ -225,7 +220,7 @@ const toPage = (path: string, row: TDevice.IListRes) => {
} else if (path == "mapLocation") {
p = { id: row.id };
} else if (path == "setting") {
p = { id: row.id };
p = { deviceId: row.deviceId };
}
router.push({
path,

View File

@ -4,100 +4,72 @@
<template #header>
<div class="card-header">
<div class="card-header-text">专项设置</div>
<el-button type="primary">执行</el-button>
<el-button type="primary" @click="submitForm(ruleFormRef)">执行</el-button>
</div>
</template>
<el-form :inline="true" :model="ruleForm" class="demo-form-inline">
<el-form :rules="rules" label-width="200px" :inline="true" :model="ruleForm" ref="ruleFormRef" class="demo-form-inline">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="IMEI号">
<el-input v-model="ruleForm.user" placeholder="请输入IMEI号" clearable />
<el-form-item style="width: 100%" prop="deviceId" label="IMEI号">
<el-input :disabled="true" v-model="ruleForm.deviceId" placeholder="请输入IMEI号" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="佩戴者编号:">
<el-input v-model="ruleForm.user" placeholder="请输入佩戴者编号" clearable />
<el-form-item style="width: 100%" prop="userNumber" label="佩戴者编号:">
<el-input v-model="ruleForm.userNumber" placeholder="请输入佩戴者编号" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="模式选择">
<!-- <el-col :span="12">
<el-form-item style="width: 100%;" prop="age" label="模式选择">
<el-input v-model="ruleForm.user" placeholder="请输入IMEI号" clearable />
</el-form-item>
</el-col> -->
</el-row>
<el-divider />
<el-row :gutter="20" v-for="(item, index) in ruleForm.contacts" :key="index">
<el-col :span="12">
<el-form-item style="width: 100%" :prop="index == 0 ? 'name' : ''" :label="`姓名 ${index + 1}`">
<el-input v-model="item.name" placeholder="请输入姓名" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item style="width: 100%" :prop="index == 0 ? 'phone' : ''" :label="`紧急电话 ${index + 1}`">
<el-input v-model="item.phone" placeholder="请输入紧急电话" clearable />
</el-form-item>
</el-col>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="姓名 1">
<el-input v-model="ruleForm.user" placeholder="请输入姓名" clearable />
<el-form-item style="width: 100%" prop="minHr" label="最低心率(次/分)">
<el-input v-model="ruleForm.minHr" placeholder="请输入最低心率" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="紧急电话 1">
<el-input v-model="ruleForm.user" placeholder="请输入紧急电话" clearable />
<el-form-item style="width: 100%" prop="maxHr" label="最高心率(次/分)">
<el-input v-model="ruleForm.maxHr" placeholder="请输入最高心率" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="姓名 2">
<el-input v-model="ruleForm.user" placeholder="请输入姓名" clearable />
<el-form-item style="width: 100%" prop="minTemp" label="最低体表温度(℃)">
<el-input v-model="ruleForm.minTemp" placeholder="请输入最低体表温度" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="紧急电话 2">
<el-input v-model="ruleForm.user" placeholder="请输入紧急电话" clearable />
<el-form-item style="width: 100%" prop="maxTemp" label="最高体表温度(℃)">
<el-input v-model="ruleForm.maxTemp" placeholder="请输入最高体表温度" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="姓名 3">
<el-input v-model="ruleForm.user" placeholder="请输入姓名" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="紧急电话 3">
<el-input v-model="ruleForm.user" placeholder="请输入紧急电话" clearable />
</el-form-item>
</el-col>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="最小心率(次/分):">
<el-input v-model="ruleForm.user" placeholder="请输入最小心率" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最大心率(次/分):">
<el-input v-model="ruleForm.user" placeholder="请输入最大心率" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="最小血氧(%">
<el-input v-model="ruleForm.user" placeholder="请输入最小血氧" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最大血氧(%">
<el-input v-model="ruleForm.user" placeholder="请输入最大血氧" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="最小体表温度(℃):">
<el-input v-model="ruleForm.user" placeholder="请输入最小体表温度" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="最大体表温度(℃):">
<el-input v-model="ruleForm.user" placeholder="请输入最大体表温度" clearable />
<el-form-item style="width: 100%" prop="minBo" label="最低血氧(%">
<el-input v-model="ruleForm.minBo" placeholder="请输入最低血氧" clearable />
</el-form-item>
</el-col>
</el-row>
@ -107,11 +79,77 @@
</template>
<script setup lang="ts">
import { reactive } from "vue";
const ruleForm = reactive({
user: "",
region: "",
date: "",
import { onMounted, reactive, ref } from "vue";
import { deviceConfig, deviceConfigModify } from "@/api";
import { useRoute } from "vue-router";
import { TDeviceConfig } from "@/api/index.d";
import { ElMessage, FormInstance, FormRules } from "element-plus";
const { query } = useRoute();
const ruleForm = ref<TDeviceConfig.Tres>({
deviceId: query.deviceId,
userNumber: "",
minHr: 0,
minBo: 0,
minTemp: 0,
maxTemp: 0,
maxHr: 0,
contacts: [],
});
const validate = (rule: any, value: any, callback: any) => {
if (rule.field == "name" && !ruleForm.value.contacts[0].name) return callback(new Error("请输入姓名1"));
if (rule.field == "phone" && !ruleForm.value.contacts[0].phone) return callback(new Error("请输入紧急电话1"));
callback();
};
const rules = reactive<FormRules<TDeviceConfig.Tres>>({
userNumber: [{ required: true, message: "请输入佩戴者编号", trigger: "blur" }],
minHr: [{ required: true, message: "请输入最低心率", trigger: "blur" }],
minBo: [{ required: true, message: "请输入最低血氧", trigger: "blur" }],
minTemp: [{ required: true, message: "请输入最低温度", trigger: "blur" }],
maxTemp: [{ required: true, message: "请输入最高温度", trigger: "blur" }],
maxHr: [{ required: true, message: "请输入最高心率", trigger: "blur" }],
name: [{ required: true, validator: validate, trigger: "blur" }],
phone: [{ required: true, validator: validate, trigger: "blur" }],
});
const ruleFormRef = ref<FormInstance>();
const getDeviceConfig = () => {
deviceConfig({ deviceId: query.deviceId }).then((res) => {
let arr = res.contacts
.sort((a: any, b: any) => a.id - b.id)
.map((item) => {
return {
name: item.name,
phone: item.phone,
};
});
ruleForm.value = {
...res,
contacts: arr.length
? arr
: [
{ name: "", phone: "" },
{ name: "", phone: "" },
{ name: "", phone: "" },
],
};
});
};
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
if (valid) {
deviceConfigModify({
...ruleForm.value,
contacts: ruleForm.value.contacts,
}).then(() => {
ElMessage.success("执行成功");
});
}
});
};
onMounted(() => {
getDeviceConfig();
});
</script>