2025年04月10日19:00:16
This commit is contained in:
parent
054d5fb5ca
commit
3346134b9a
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -49,6 +49,7 @@ declare module '@vue/runtime-core' {
|
|||||||
ElTag: typeof import('element-plus/es')['ElTag']
|
ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||||
Header: typeof import('./src/components/header.vue')['default']
|
Header: typeof import('./src/components/header.vue')['default']
|
||||||
|
InfoWindow: typeof import('./src/components/InfoWindow.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
Sidebar: typeof import('./src/components/sidebar.vue')['default']
|
Sidebar: typeof import('./src/components/sidebar.vue')['default']
|
||||||
|
67
src/api/index.d.ts
vendored
67
src/api/index.d.ts
vendored
@ -9,12 +9,19 @@ export interface IpagingRes<T> {
|
|||||||
pages: number
|
pages: number
|
||||||
records: T[]
|
records: T[]
|
||||||
}
|
}
|
||||||
export interface TRoleList {
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
createTime: string
|
|
||||||
}
|
|
||||||
|
|
||||||
|
interface TRoleMenu {
|
||||||
|
id?: number
|
||||||
|
type?: number
|
||||||
|
name?: string
|
||||||
|
createTime?: string
|
||||||
|
}
|
||||||
|
export interface TRoleList {
|
||||||
|
id?: number
|
||||||
|
name: string
|
||||||
|
createTime?: string
|
||||||
|
roleMenu: TRoleMenu[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface TStatisticsDevice {
|
export interface TStatisticsDevice {
|
||||||
@ -72,6 +79,14 @@ export interface TDeviceConfigModify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export namespace TRoleModify {
|
||||||
|
export interface Ireq {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
roleMenu: TRoleMenu[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export namespace TDeviceConfig {
|
export namespace TDeviceConfig {
|
||||||
|
|
||||||
interface Treq {
|
interface Treq {
|
||||||
@ -160,6 +175,7 @@ export namespace TDevice {
|
|||||||
accountId: number
|
accountId: number
|
||||||
orgId: number
|
orgId: number
|
||||||
status: number
|
status: number
|
||||||
|
useStatus: number
|
||||||
deviceSwitch: number
|
deviceSwitch: number
|
||||||
mode: number
|
mode: number
|
||||||
monitorMode: number
|
monitorMode: number
|
||||||
@ -345,4 +361,45 @@ export namespace THealthLatestData {
|
|||||||
tempArr: any[]
|
tempArr: any[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export namespace TLocateRecord {
|
||||||
|
|
||||||
|
interface TReq {
|
||||||
|
deviceId: number | string
|
||||||
|
startDate: string
|
||||||
|
endDate: string
|
||||||
|
}
|
||||||
|
interface TRes {
|
||||||
|
id: number
|
||||||
|
deviceId: string
|
||||||
|
lat: number
|
||||||
|
lng: number
|
||||||
|
locationType: number
|
||||||
|
adCode: string
|
||||||
|
place: string
|
||||||
|
address: string
|
||||||
|
locationTime: string
|
||||||
|
createTime: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace TSetUseStatus {
|
||||||
|
interface TReq {
|
||||||
|
status: number
|
||||||
|
deviceId: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export namespace TRoleMenuList {
|
||||||
|
interface TMenus {
|
||||||
|
id: number
|
||||||
|
type: number
|
||||||
|
name: string
|
||||||
|
createTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TRes {
|
||||||
|
name: string
|
||||||
|
type: number
|
||||||
|
menus: TMenus[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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, THealthLatestData } from "./index.d";
|
import { TLogin, TAccount, IpagingRes, TDevice, TOrg, TRoleList, TStatisticsDevice, statisticsContentReq, statisticsContentRes, TStatisticsCount, TWarnRecord, TWarningDetail, TWarningConfirm, TDeviceConfigModify, TDeviceConfig, THealthLatestData, TLocateRecord, TSetUseStatus, TRoleMenuList, TRoleModify } 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({
|
||||||
@ -191,6 +191,15 @@ export const roleList = (): Promise<TRoleList[]> => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 修改角色信息
|
||||||
|
export const roleModify = (p: TRoleModify.Ireq): Promise<null> => {
|
||||||
|
return request({
|
||||||
|
url: '/v1/web/role/modify',
|
||||||
|
method: 'post',
|
||||||
|
data: p
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 设备在线统计
|
// 设备在线统计
|
||||||
export const statisticsDevice = (): Promise<TStatisticsDevice> => {
|
export const statisticsDevice = (): Promise<TStatisticsDevice> => {
|
||||||
return request({
|
return request({
|
||||||
@ -278,4 +287,39 @@ export const healthLatestData = (p: THealthLatestData.TReq): Promise<THealthLate
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 设备定位记录
|
||||||
|
export const locateRecord = (p: TLocateRecord.TReq): Promise<TLocateRecord.TRes[]> => {
|
||||||
|
return request({
|
||||||
|
url: '/v1/web/device/locate/record',
|
||||||
|
method: 'get',
|
||||||
|
params: p
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置使用状态
|
||||||
|
export const setUseStatus = (p: TSetUseStatus.TReq): Promise<null> => {
|
||||||
|
return request({
|
||||||
|
url: '/v1/web/device/set/useStatus',
|
||||||
|
method: 'post',
|
||||||
|
data: p
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置禁用状态
|
||||||
|
export const setStatus = (p: TSetUseStatus.TReq): Promise<null> => {
|
||||||
|
return request({
|
||||||
|
url: '/v1/web/device/set/status',
|
||||||
|
method: 'post',
|
||||||
|
data: p
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取菜单列表
|
||||||
|
export const roleMenuList = (): Promise<TRoleMenuList.TRes[]> => {
|
||||||
|
return request({
|
||||||
|
url: '/v1/web/role/menu/list',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,26 +2,28 @@
|
|||||||
<div class="infoBox">
|
<div class="infoBox">
|
||||||
<div class="infoBox-head">
|
<div class="infoBox-head">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="span">姓名:</div>
|
<div class="span">手铐:</div>
|
||||||
<div class="span">{{ value.username }}</div>
|
<div class="span">{{ value.id }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item" style="cursor: pointer" @click="emit('close')">
|
||||||
<i class="el-icon-close" style="font-size: 24px; cursor: pointer" @click="$emit('close')" />
|
<svg t="1744273365398" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8493" width="24" height="24">
|
||||||
|
<path
|
||||||
|
d="M576 512l277.333333 277.333333-64 64-277.333333-277.333333L234.666667 853.333333 170.666667 789.333333l277.333333-277.333333L170.666667 234.666667 234.666667 170.666667l277.333333 277.333333L789.333333 170.666667 853.333333 234.666667 576 512z"
|
||||||
|
fill="#444444"
|
||||||
|
p-id="8494"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
<!-- <i class="el-icon-close" style="font-size: 24px; cursor: pointer" @click="emit('close')" /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="infoBox-content">
|
<div class="infoBox-content">
|
||||||
2
|
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="item-left">IMEI号</div>
|
<div class="item-left">IMEI号</div>
|
||||||
<div class="item-right">{{ value.deviceId }}</div>
|
<div class="item-right">{{ value.deviceId }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
|
||||||
<div class="item-left">定位方式</div>
|
|
||||||
<div class="item-right">{{ locateEnum[value.locateType == -1 ? 3 : value.locateType] }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="item-left">定位时间</div>
|
<div class="item-left">定位时间</div>
|
||||||
<div class="item-right">{{ value.locateTime }}</div>
|
<div class="item-right">{{ value.locationTime }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="item-left">位置</div>
|
<div class="item-left">位置</div>
|
||||||
@ -40,6 +42,8 @@ defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["close"]);
|
||||||
|
|
||||||
enum locateEnum {
|
enum locateEnum {
|
||||||
"WIFI" = 0,
|
"WIFI" = 0,
|
||||||
"LBS",
|
"LBS",
|
||||||
@ -48,7 +52,7 @@ enum locateEnum {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="less" scoped>
|
||||||
.infoBox {
|
.infoBox {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
background: #fff;
|
background: #fff;
|
@ -6,7 +6,7 @@
|
|||||||
<div class="app-main" :class="{ 'content-collapse': sidebar.collapse }">
|
<div class="app-main" :class="{ 'content-collapse': sidebar.collapse }">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<transition name="move" mode="out-in">
|
<transition name="move" mode="out-in">
|
||||||
<keep-alive>
|
<keep-alive :include="[]">
|
||||||
<component :is="Component"></component>
|
<component :is="Component"></component>
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
@ -19,9 +19,24 @@
|
|||||||
import { useSidebarStore } from "@/store/sidebar";
|
import { useSidebarStore } from "@/store/sidebar";
|
||||||
import vHeader from "@/components/header.vue";
|
import vHeader from "@/components/header.vue";
|
||||||
import vSidebar from "@/components/sidebar.vue";
|
import vSidebar from "@/components/sidebar.vue";
|
||||||
|
import { routes } from "@/router/index";
|
||||||
|
|
||||||
const sidebar = useSidebarStore();
|
const sidebar = useSidebarStore();
|
||||||
console.log(sidebar);
|
|
||||||
|
const getInclude = (routeList: any) => {
|
||||||
|
if (!routeList) return [];
|
||||||
|
let list = [];
|
||||||
|
routeList.forEach((item) => {
|
||||||
|
if (item.meta && item.meta.keepAlive) {
|
||||||
|
list.push(item.name);
|
||||||
|
}
|
||||||
|
if (item.children && item.children.length) {
|
||||||
|
list = [...list, ...getInclude(item.children)];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
// const include = getInclude(routes[0].children);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@ -22,7 +22,7 @@ export const mix = (color1: string, color2: string, weight: number = 0.5): strin
|
|||||||
* @param {*} fmStr 格式化格式 YYYY-MM-DD HH:mm:ss
|
* @param {*} fmStr 格式化格式 YYYY-MM-DD HH:mm:ss
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function format(time: Date | string, fmStr: string = "YYYY-MM-DD HH:mm:ss") {
|
export function format(time: Date | string | number, fmStr: string = "YYYY-MM-DD HH:mm:ss") {
|
||||||
if (!time) return "";
|
if (!time) return "";
|
||||||
return dayjs(typeof time == 'string' ? new Date(time) : time).format(fmStr);
|
return dayjs(typeof time == 'string' ? new Date(time) : time).format(fmStr);
|
||||||
}
|
}
|
||||||
|
@ -115,12 +115,36 @@ export class MapCustom {
|
|||||||
icon,
|
icon,
|
||||||
position,
|
position,
|
||||||
map: this.map,
|
map: this.map,
|
||||||
offset: new AMap.Pixel(-25, -50),
|
offset: new AMap.Pixel(-20, -40),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
lngLat(lng, lat) {
|
lngLat(lng, lat) {
|
||||||
return new AMap.LngLat(lng, lat);
|
return new AMap.LngLat(lng, lat);
|
||||||
}
|
}
|
||||||
|
infoWindow(option = {
|
||||||
|
anchor: 'bottom-center',
|
||||||
|
isCustom: true, //使用自定义窗体
|
||||||
|
content: document.querySelector('.infoBox'),
|
||||||
|
offset: new AMap.Pixel(-2, -40),
|
||||||
|
}) {
|
||||||
|
return new AMap.InfoWindow(option)
|
||||||
|
|
||||||
|
}
|
||||||
|
//绘制轨迹线条
|
||||||
|
polyline(list) {
|
||||||
|
this.clearMap()
|
||||||
|
let Polyline = new AMap.Polyline({
|
||||||
|
map: this.map,
|
||||||
|
path: list.map((item) => [item.lng, item.lat]),
|
||||||
|
showDir: true,
|
||||||
|
strokeColor: '#0088F6', //线颜色
|
||||||
|
strokeWeight: 4 //线宽
|
||||||
|
})
|
||||||
|
this.map.setFitView(Polyline);
|
||||||
|
}
|
||||||
|
setCenter(position) {
|
||||||
|
this.map.setCenter(position)
|
||||||
|
}
|
||||||
|
|
||||||
clearMap() {
|
clearMap() {
|
||||||
this.map.clearMap();
|
this.map.clearMap();
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<div v-infinite-scroll="load" :infinite-scroll-immediate="false" class="device-list noScrollbar infinite-list" style="overflow: auto">
|
<div v-infinite-scroll="load" :infinite-scroll-immediate="false" class="device-list noScrollbar infinite-list" style="overflow: auto">
|
||||||
<el-popover :width="350" class="box-item" placement="bottom" v-for="item in list" :key="item.id">
|
<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" :class="{ active: deviceId === item.deviceId }" @click="emit('click', 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>
|
||||||
@ -74,8 +74,8 @@ enum modeEnum {
|
|||||||
"审讯模式",
|
"审讯模式",
|
||||||
"户外押送",
|
"户外押送",
|
||||||
}
|
}
|
||||||
|
const emit = defineEmits(["click"]);
|
||||||
const { list, paging, api } = defineProps({
|
const { list, paging, api, deviceId } = defineProps({
|
||||||
list: {
|
list: {
|
||||||
type: Array<TDevice.IListRes>,
|
type: Array<TDevice.IListRes>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
@ -88,6 +88,10 @@ const { list, paging, api } = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
|
deviceId: {
|
||||||
|
type: Number || String,
|
||||||
|
default: () => "",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handelMode = () => {
|
const handelMode = () => {
|
||||||
@ -145,6 +149,9 @@ const load = () => {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-bottom: 1px solid #dedede;
|
border-bottom: 1px solid #dedede;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
&.active {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<el-row class="el-row" :gutter="20">
|
<el-row class="el-row" :gutter="20">
|
||||||
<el-col :span="6" class="el-row-left"><DeviceInfo :paging="devicePaging" :api="getdeviceList" :list="deviceData" /></el-col>
|
<el-col :span="6" class="el-row-left"
|
||||||
|
><DeviceInfo :deviceId="deviceInfo?.deviceId" :paging="devicePaging" :api="getdeviceList" :list="deviceData" @click="handelClickDevice"
|
||||||
|
/></el-col>
|
||||||
<el-col :span="18" class="el-row-right scrollbar">
|
<el-col :span="18" class="el-row-right scrollbar">
|
||||||
<MonitoringTop :funcList="funcList" />
|
<MonitoringTop :funcList="funcList" />
|
||||||
<div v-if="deviceInfo?.status != 2">
|
<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">
|
||||||
@ -44,16 +46,18 @@ 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 { deviceList, healthLatestData, warningRecord } from "@/api/index";
|
import { deviceList, healthLatestData, warningRecord, locateRecord } from "@/api/index";
|
||||||
import { TDevice, THealthLatestData } from "@/api/index.d";
|
import { TDevice, THealthLatestData } from "@/api/index.d";
|
||||||
import { onMounted, onDeactivated, ref, reactive } from "vue";
|
import { onMounted, onDeactivated, ref, reactive } from "vue";
|
||||||
import { debounce, format } from "@/utils";
|
import { debounce, format } from "@/utils";
|
||||||
import heart from "@/assets/img/heart.png";
|
import heart from "@/assets/img/heart.png";
|
||||||
import temperature from "@/assets/img/temperature.png";
|
import temperature from "@/assets/img/temperature.png";
|
||||||
import blood from "@/assets/img/blood.png";
|
import blood from "@/assets/img/blood.png";
|
||||||
|
import location from "@/assets/img/location.png";
|
||||||
|
|
||||||
const chartRef = ref(null);
|
const chartRef = ref(null);
|
||||||
let myChart = null;
|
let myChart = null;
|
||||||
|
let newMap = null;
|
||||||
let funcList = ref([
|
let funcList = ref([
|
||||||
{ title: "当前心率", en: "DANGQIANXINLV", icon: heart, unit: "次/分", num: 0, color: "#FF0303" },
|
{ title: "当前心率", en: "DANGQIANXINLV", icon: heart, unit: "次/分", num: 0, color: "#FF0303" },
|
||||||
{ title: "当前血氧", en: "DANGQIANXUEYANG", icon: blood, unit: "%", num: 0, color: "#8B51FD" },
|
{ title: "当前血氧", en: "DANGQIANXUEYANG", icon: blood, unit: "%", num: 0, color: "#8B51FD" },
|
||||||
@ -86,13 +90,6 @@ const options = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const paging = reactive({
|
|
||||||
page: 1,
|
|
||||||
size: 10,
|
|
||||||
total: 0,
|
|
||||||
status: undefined,
|
|
||||||
warnType: undefined,
|
|
||||||
});
|
|
||||||
const devicePaging = reactive({
|
const devicePaging = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
size: 10,
|
size: 10,
|
||||||
@ -101,7 +98,6 @@ const devicePaging = reactive({
|
|||||||
const HealthData = ref<THealthLatestData.TRes>();
|
const HealthData = ref<THealthLatestData.TRes>();
|
||||||
|
|
||||||
const deviceInfo = ref<TDevice.IListRes>();
|
const deviceInfo = ref<TDevice.IListRes>();
|
||||||
const tableData = ref<TDevice.IWarningRecordRes[]>([]);
|
|
||||||
const deviceData = ref<TDevice.IListRes[]>([]);
|
const deviceData = ref<TDevice.IListRes[]>([]);
|
||||||
|
|
||||||
const getdeviceList = async () => {
|
const getdeviceList = async () => {
|
||||||
@ -110,29 +106,20 @@ const getdeviceList = async () => {
|
|||||||
if (res.records.length > 0) {
|
if (res.records.length > 0) {
|
||||||
deviceInfo.value = res.records[1];
|
deviceInfo.value = res.records[1];
|
||||||
getHealthLatestData();
|
getHealthLatestData();
|
||||||
// getData();
|
getLocateRecord();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const getData = async () => {
|
|
||||||
const res = await warningRecord({ ...paging, deviceId: deviceInfo.value.deviceId });
|
|
||||||
tableData.value = res.records;
|
|
||||||
paging.total = res.total;
|
|
||||||
};
|
|
||||||
const getHealthLatestData = () => {
|
const getHealthLatestData = () => {
|
||||||
healthLatestData({ deviceId: deviceInfo.value.deviceId }).then((res) => {
|
healthLatestData({ deviceId: deviceInfo.value.deviceId }).then((res) => {
|
||||||
HealthData.value = res;
|
HealthData.value = res;
|
||||||
funcList.value[0].num = res.hr;
|
funcList.value[0].num = res.hr;
|
||||||
funcList.value[1].num = res.bo;
|
funcList.value[1].num = res.bo;
|
||||||
funcList.value[2].num = res.temp;
|
funcList.value[2].num = res.temp;
|
||||||
|
|
||||||
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const changePage = (val: number) => {
|
|
||||||
paging.page = val;
|
|
||||||
getData();
|
|
||||||
};
|
|
||||||
const handelRadio = (val: number) => {
|
const handelRadio = (val: number) => {
|
||||||
if (val == 1) {
|
if (val == 1) {
|
||||||
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
||||||
@ -145,22 +132,49 @@ const handelRadio = (val: number) => {
|
|||||||
const getOptionsData = (list: { time: string; value: number }[], name: string, color: string) => {
|
const getOptionsData = (list: { time: string; value: number }[], name: string, color: string) => {
|
||||||
options.xAxis.data = [];
|
options.xAxis.data = [];
|
||||||
options.series.data = [];
|
options.series.data = [];
|
||||||
|
if (list && list.length) {
|
||||||
list.forEach((item) => {
|
list.forEach((item) => {
|
||||||
options.xAxis.data.push(format(item.time, "HH:mm:ss"));
|
options.xAxis.data.push(format(item.time, "HH:mm:ss"));
|
||||||
options.series.data.push(item.value);
|
options.series.data.push(item.value);
|
||||||
});
|
});
|
||||||
options.series.name = name;
|
options.series.name = name;
|
||||||
options.series.itemStyle.color = color;
|
options.series.itemStyle.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
myChart.setOption(options);
|
myChart.setOption(options);
|
||||||
};
|
};
|
||||||
|
const getLocateRecord = () => {
|
||||||
|
let d = new Date();
|
||||||
|
locateRecord({
|
||||||
|
deviceId: deviceInfo.value.deviceId,
|
||||||
|
startDate: `${format(d, "YYYY-MM-DD")} 00:00:00`,
|
||||||
|
endDate: `${format(d, "YYYY-MM-DD")} 23:59:59`,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res && res.length) {
|
||||||
|
let list = res;
|
||||||
|
newMap.clearMap();
|
||||||
|
newMap.setCenter([list[0].lng, list[0].lat]);
|
||||||
|
newMap.polyline(list);
|
||||||
|
let icon = newMap.newIcon(location);
|
||||||
|
list.forEach((item) => {
|
||||||
|
let marker = newMap.marker({ icon, position: [item.lng, item.lat] });
|
||||||
|
marker.setMap(newMap.map);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
const handleResize = debounce(() => {
|
const handleResize = debounce(() => {
|
||||||
myChart.resize();
|
myChart.resize();
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
|
const handelClickDevice = (val: TDevice.IListRes) => {
|
||||||
|
deviceInfo.value = val;
|
||||||
|
getHealthLatestData();
|
||||||
|
getLocateRecord();
|
||||||
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getdeviceList();
|
getdeviceList();
|
||||||
new MapCustom({ dom: "mapcontainer" });
|
newMap = new MapCustom({ dom: "mapcontainer" });
|
||||||
if (chartRef.value) {
|
if (chartRef.value) {
|
||||||
myChart = echarts.init(chartRef.value);
|
myChart = echarts.init(chartRef.value);
|
||||||
window.addEventListener("resize", handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
|
@ -39,14 +39,7 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">当前设备告警记录</div>
|
<div class="card-header">当前设备告警记录</div>
|
||||||
</template>
|
</template>
|
||||||
<TableCustom
|
<TableCustom :hasToolbar="false" :columns="columns" :tableData="warningTableData" :paging="paging1" :changePage="changeWarningPage">
|
||||||
:hasToolbar="false"
|
|
||||||
:columns="columns"
|
|
||||||
:tableData="warningTableData"
|
|
||||||
:total="paging1.total"
|
|
||||||
:currentPage="paging1.page"
|
|
||||||
:changePage="changeWarningPage"
|
|
||||||
>
|
|
||||||
<template #operator="{ rows }">
|
<template #operator="{ rows }">
|
||||||
<el-button link type="primary" size="small" @click="toIncidentDispose(rows.id)" v-if="rows.status == 0"> 处理事件 </el-button>
|
<el-button link type="primary" size="small" @click="toIncidentDispose(rows.id)" v-if="rows.status == 0"> 处理事件 </el-button>
|
||||||
<div v-else></div>
|
<div v-else></div>
|
||||||
|
@ -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" :paging="paging" :refresh="getData" :changePage="changePage">
|
<TableCustom :columns="columns" :tableData="tableData" :paging="paging" :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>
|
||||||
@ -13,11 +13,14 @@
|
|||||||
<template #status="{ rows }">
|
<template #status="{ rows }">
|
||||||
<el-tag :type="statusColor[rows.status]">{{ statusEnum[rows.status] }}</el-tag>
|
<el-tag :type="statusColor[rows.status]">{{ statusEnum[rows.status] }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #mode="{ rows }">
|
<template #useStatus="{ rows }">
|
||||||
<el-tag :type="modeColor[rows.mode]">{{ modeEnum[rows.mode] }}</el-tag>
|
<el-switch v-model="rows.useStatus" :active-value="1" :inactive-value="0" @click="handelSwitch(rows, 1)" />
|
||||||
</template>
|
</template>
|
||||||
<template #deviceSwitch="{ rows }">
|
<template #deviceSwitch="{ rows }">
|
||||||
<el-switch v-model="rows.deviceSwitch" />
|
<el-switch v-model="rows.deviceSwitch" :active-value="1" :inactive-value="0" @click="handelSwitch(rows, 2)" />
|
||||||
|
</template>
|
||||||
|
<template #mode="{ rows }">
|
||||||
|
<el-tag :type="modeColor[rows.mode]">{{ modeEnum[rows.mode] }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #battery="{ rows }"> {{ rows.battery }}% </template>
|
<template #battery="{ rows }"> {{ rows.battery }}% </template>
|
||||||
<template #operator="{ rows }">
|
<template #operator="{ rows }">
|
||||||
@ -44,7 +47,7 @@
|
|||||||
<script setup lang="ts" name="basetable">
|
<script setup lang="ts" name="basetable">
|
||||||
import { ref, reactive, onMounted } from "vue";
|
import { ref, reactive, onMounted } from "vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { deviceList, setMode, deviceGetLocation, deviceControl } from "@/api/index";
|
import { deviceList, setMode, deviceGetLocation, deviceControl, setUseStatus, setStatus } from "@/api/index";
|
||||||
import { TDevice } from "@/api/index.d";
|
import { TDevice } from "@/api/index.d";
|
||||||
import TableCustom from "@/components/table-custom.vue";
|
import TableCustom from "@/components/table-custom.vue";
|
||||||
import TableSearch from "@/components/table-search.vue";
|
import TableSearch from "@/components/table-search.vue";
|
||||||
@ -107,7 +110,8 @@ let columns = ref([
|
|||||||
{ prop: "deviceVersion", label: "版本号" },
|
{ prop: "deviceVersion", label: "版本号" },
|
||||||
{ prop: "status", label: "设备状态" },
|
{ prop: "status", label: "设备状态" },
|
||||||
{ prop: "mode", label: "当前模式" },
|
{ prop: "mode", label: "当前模式" },
|
||||||
{ prop: "deviceSwitch", label: "开关" },
|
{ prop: "useStatus", label: "使用状态" },
|
||||||
|
{ prop: "deviceSwitch", label: "启用开关" },
|
||||||
{ prop: "orgName", label: "关联辖区编号" },
|
{ prop: "orgName", label: "关联辖区编号" },
|
||||||
{ prop: "createTime", label: "最新通信时间" },
|
{ prop: "createTime", label: "最新通信时间" },
|
||||||
{ prop: "createTime", label: "创建时间" },
|
{ prop: "createTime", label: "创建时间" },
|
||||||
@ -159,7 +163,16 @@ const handelRow = (row?: TDevice.IListRes) => {
|
|||||||
controlForm.mode = row.mode;
|
controlForm.mode = row.mode;
|
||||||
visible1.value = true;
|
visible1.value = true;
|
||||||
};
|
};
|
||||||
|
const handelSwitch = (val: TDevice.IListRes, type: number) => {
|
||||||
|
let api = type == 1 ? setUseStatus : setStatus;
|
||||||
|
api({
|
||||||
|
deviceId: val.deviceId,
|
||||||
|
status: type == 1 ? val.useStatus : val.deviceSwitch,
|
||||||
|
}).then(() => {
|
||||||
|
getData();
|
||||||
|
ElMessage.success("操作成功");
|
||||||
|
});
|
||||||
|
};
|
||||||
const handelControl = (type: number) => {
|
const handelControl = (type: number) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 4:
|
case 4:
|
||||||
@ -216,7 +229,7 @@ const toPage = (path: string, row: TDevice.IListRes) => {
|
|||||||
if (path == "deviceInfo") {
|
if (path == "deviceInfo") {
|
||||||
p = { ...row };
|
p = { ...row };
|
||||||
} else if (path == "mapLocation") {
|
} else if (path == "mapLocation") {
|
||||||
p = { id: row.id };
|
p = { deviceId: row.deviceId };
|
||||||
} else if (path == "setting") {
|
} else if (path == "setting") {
|
||||||
p = { deviceId: row.deviceId };
|
p = { deviceId: row.deviceId };
|
||||||
}
|
}
|
||||||
|
@ -17,23 +17,11 @@
|
|||||||
range-separator="-"
|
range-separator="-"
|
||||||
start-placeholder="开始时间"
|
start-placeholder="开始时间"
|
||||||
end-placeholder="结束时间"
|
end-placeholder="结束时间"
|
||||||
|
v-model="time"
|
||||||
|
@change="timeChange"
|
||||||
/>
|
/>
|
||||||
<el-date-picker v-else type="week" value-format="YYYY-MM-DD/ww" placeholder="请选择周" @change="weekChange" />
|
<el-date-picker v-model="week" v-else type="week" value-format="YYYY-MM-DD" placeholder="请选择周" @change="weekChange" />
|
||||||
</div>
|
</div>
|
||||||
<el-select
|
|
||||||
v-model="value"
|
|
||||||
multiple
|
|
||||||
filterable
|
|
||||||
remote
|
|
||||||
reserve-keyword
|
|
||||||
placeholder="请输入设备IMEI"
|
|
||||||
:remote-method="remoteMethod"
|
|
||||||
:loading="loading"
|
|
||||||
style="width: 240px"
|
|
||||||
>
|
|
||||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
|
||||||
</el-select>
|
|
||||||
|
|
||||||
<!-- <span>位置样式:</span>
|
<!-- <span>位置样式:</span>
|
||||||
<el-radio-group v-model="styleType">
|
<el-radio-group v-model="styleType">
|
||||||
<el-radio-button :value="1">点</el-radio-button>
|
<el-radio-button :value="1">点</el-radio-button>
|
||||||
@ -66,49 +54,76 @@
|
|||||||
<el-col :span="24" class="container-right">
|
<el-col :span="24" class="container-right">
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row> -->
|
</el-row> -->
|
||||||
|
<div :style="{ display: 'none' }">
|
||||||
|
<InfoWindow class="infoBox" :value="deviceInfo" @close="InfoWin.close()" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import handcuffs from "@/assets/img/handcuffs.png";
|
import { onMounted, reactive } from "vue";
|
||||||
import { onMounted } from "vue";
|
|
||||||
import { MapCustom } from "@/utils/mapCustom";
|
import { MapCustom } from "@/utils/mapCustom";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
interface ListItem {
|
import { locateRecord } from "@/api";
|
||||||
value: string;
|
import { format } from "@/utils";
|
||||||
label: string;
|
import { TLocateRecord } from "@/api/index.d";
|
||||||
}
|
import { useRoute } from "vue-router";
|
||||||
let tabs = [
|
import location from "@/assets/img/location.png";
|
||||||
{ label: "全部", value: "0" },
|
import InfoWindow from "@/components/InfoWindow.vue";
|
||||||
{ label: "未处理", value: "1" },
|
|
||||||
{ label: "已处理", value: "2" },
|
const { query } = useRoute();
|
||||||
];
|
let d = new Date();
|
||||||
|
let newMap = null;
|
||||||
|
let time = ref([new Date(`${format(d, "YYYY-MM-DD")} 00:00:00`), new Date(`${format(d, "YYYY-MM-DD")} 23:59:59`)]);
|
||||||
|
let week = ref(d);
|
||||||
|
let deviceInfo = ref({});
|
||||||
let sectionType = ref(1);
|
let sectionType = ref(1);
|
||||||
let styleType = ref(1);
|
let InfoWin = null;
|
||||||
|
|
||||||
const list = ref<ListItem[]>([]);
|
const params = reactive<TLocateRecord.TReq>({
|
||||||
const options = ref<ListItem[]>([]);
|
deviceId: query.deviceId as string,
|
||||||
const value = ref<string[]>([]);
|
// startDate: `${format(d, "YYYY-MM-DD")} 00:00:00`,
|
||||||
const loading = ref(false);
|
// endDate: `${format(d, "YYYY-MM-DD")} 23:59:59`,
|
||||||
|
startDate: "2021-04-14 00:00:00",
|
||||||
//处理展示数据
|
endDate: "2025-05-14 23:59:59",
|
||||||
const weekChange = (value: any) => {};
|
});
|
||||||
const remoteMethod = (query: string) => {
|
|
||||||
if (query) {
|
const weekChange = (val: any) => {
|
||||||
loading.value = true;
|
let endTime = new Date(val).getTime() + 6 * 24 * 60 * 60 * 1000;
|
||||||
setTimeout(() => {
|
params.startDate = `${val} 00:00:00`;
|
||||||
loading.value = false;
|
params.endDate = `${format(endTime, "YYYY-MM-DD")} 23:59:59`;
|
||||||
options.value = list.value.filter((item) => {
|
getLocateRecord();
|
||||||
return item.label.toLowerCase().includes(query.toLowerCase());
|
};
|
||||||
|
const timeChange = (val: any) => {
|
||||||
|
params.startDate = `${format(val[0], "YYYY-MM-DD")} 00:00:00`;
|
||||||
|
params.endDate = `${format(val[1], "YYYY-MM-DD")} 23:59:59`;
|
||||||
|
getLocateRecord();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getLocateRecord = () => {
|
||||||
|
locateRecord(params).then((res) => {
|
||||||
|
if (res && res.length) {
|
||||||
|
let list = res;
|
||||||
|
newMap.clearMap();
|
||||||
|
newMap.setCenter([list[0].lng, list[0].lat]);
|
||||||
|
newMap.polyline(list);
|
||||||
|
let icon = newMap.newIcon(location);
|
||||||
|
list.forEach((item) => {
|
||||||
|
let marker = newMap.marker({ icon, position: [item.lng, item.lat] });
|
||||||
|
marker.setMap(newMap.map);
|
||||||
|
marker.on("click", () => {
|
||||||
|
deviceInfo.value = item;
|
||||||
|
InfoWin = newMap.infoWindow();
|
||||||
|
InfoWin.open(newMap.map, marker.getPosition());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, 200);
|
|
||||||
} else {
|
|
||||||
options.value = [];
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
new MapCustom({ dom: "mapcontainer" });
|
newMap = new MapCustom({ dom: "mapcontainer" });
|
||||||
|
getLocateRecord();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -41,16 +41,16 @@
|
|||||||
<TableEdit :form-data="rowData" :options="options" :edit="isEdit" :update="updateData" @close="closeDialog" />
|
<TableEdit :form-data="rowData" :options="options" :edit="isEdit" :update="updateData" @close="closeDialog" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog title="编辑类型" v-model="typeVisible" width="800px" destroy-on-close :close-on-click-modal="false" @close="closeDialog">
|
<el-dialog title="编辑类型" v-model="typeVisible" width="800px" destroy-on-close :close-on-click-modal="false" @close="closeDialog">
|
||||||
<UserType />
|
<UserType :typeHeadList="typeHeadList" :roleListData="roleListData" @complete="saveType" @addType="addType" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<BatchImp ref="batchImpRef" @success="handleSearch" />
|
<BatchImp ref="batchImpRef" @success="handleSearch" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="basetable">
|
<script setup lang="ts" name="basetable">
|
||||||
import { ref, reactive } from "vue";
|
import { ref, reactive, onMounted } from "vue";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { accountAdd, accountModify, accountList, accountDeletet, passwordReset, roleList } from "@/api/index";
|
import { accountAdd, accountModify, accountList, accountDeletet, passwordReset, roleList, roleMenuList, roleModify } from "@/api/index";
|
||||||
import TableCustom from "@/components/table-custom.vue";
|
import TableCustom from "@/components/table-custom.vue";
|
||||||
import TableSearch from "@/components/table-search.vue";
|
import TableSearch from "@/components/table-search.vue";
|
||||||
import TableEdit from "@/components/table-edit.vue";
|
import TableEdit from "@/components/table-edit.vue";
|
||||||
@ -59,7 +59,7 @@ import { useCommonStore } from "@/store/common";
|
|||||||
import UserType from "./userType.vue";
|
import UserType from "./userType.vue";
|
||||||
import { TableItem } from "@/types/table";
|
import { TableItem } from "@/types/table";
|
||||||
import { FormOption, FormOptionList } from "@/types/form-option";
|
import { FormOption, FormOptionList } from "@/types/form-option";
|
||||||
import { TAccount, TRoleList } from "@/api/index.d";
|
import { TAccount, TRoleList, TRoleMenuList } from "@/api/index.d";
|
||||||
// import { Hide, View } from "@element-plus/icons-vue";
|
// import { Hide, View } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
enum roleEnum {
|
enum roleEnum {
|
||||||
@ -75,7 +75,8 @@ const typeVisible = ref(false);
|
|||||||
const isEdit = ref(false);
|
const isEdit = ref(false);
|
||||||
const dialogTitle = ref("");
|
const dialogTitle = ref("");
|
||||||
const rowData = ref<TAccount.IListRes | undefined>();
|
const rowData = ref<TAccount.IListRes | undefined>();
|
||||||
|
// 类型列表头列表
|
||||||
|
let typeHeadList = ref<TRoleMenuList.TRes[]>([]);
|
||||||
// 查询相关
|
// 查询相关
|
||||||
const query = reactive({
|
const query = reactive({
|
||||||
name: "",
|
name: "",
|
||||||
@ -182,6 +183,7 @@ const changePage = (val: number) => {
|
|||||||
};
|
};
|
||||||
const roleListFn = () => {
|
const roleListFn = () => {
|
||||||
roleList().then((res) => {
|
roleList().then((res) => {
|
||||||
|
roleListData.value = res;
|
||||||
let opts = res?.map((item) => {
|
let opts = res?.map((item) => {
|
||||||
return { label: item.name, value: item.id };
|
return { label: item.name, value: item.id };
|
||||||
});
|
});
|
||||||
@ -196,8 +198,6 @@ const getData = async () => {
|
|||||||
});
|
});
|
||||||
paging.total = res.total;
|
paging.total = res.total;
|
||||||
};
|
};
|
||||||
roleListFn();
|
|
||||||
getData();
|
|
||||||
|
|
||||||
// 删除相关
|
// 删除相关
|
||||||
const handelDel = (row: TableItem) => {
|
const handelDel = (row: TableItem) => {
|
||||||
@ -229,7 +229,16 @@ const updateData = (res) => {
|
|||||||
getData();
|
getData();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const saveType = (row: TRoleList) => {
|
||||||
|
roleModify(row).then(() => {
|
||||||
|
ElMessage.success("保存成功");
|
||||||
|
roleListFn();
|
||||||
|
typeVisible.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const addType = () => {
|
||||||
|
roleListData.value.push({ name: "", roleMenu: [] });
|
||||||
|
};
|
||||||
const closeDialog = () => {
|
const closeDialog = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
isEdit.value = false;
|
isEdit.value = false;
|
||||||
@ -254,6 +263,16 @@ const handelRow = (name: string, row?: TAccount.IListRes) => {
|
|||||||
}
|
}
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
};
|
};
|
||||||
|
const getRoleMenuList = () => {
|
||||||
|
roleMenuList().then((res) => {
|
||||||
|
typeHeadList.value = res;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
roleListFn();
|
||||||
|
getData();
|
||||||
|
getRoleMenuList();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -1,51 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-table :data="tableData" style="width: 100%">
|
<el-table :data="roleListData" style="width: 100%">
|
||||||
<el-table-column prop="name" label="" width="150" align="center">
|
<el-table-column prop="name" label="" width="150" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox value="Value 1" size="large" v-if="row.flag" />
|
<el-input v-model="row.name" />
|
||||||
<el-input v-model="row.name" v-else />
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="date" label="web管理权限" width="150" align="center">
|
<el-table-column :label="item.name" align="center" v-for="(item, index) in typeHeadList" :key="index">
|
||||||
|
<el-table-column prop="name" :label="ite.name" align="center" v-for="(ite, ide) in item.menus" :key="`${index}_${ide}`">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox size="large" v-model="row.check" disabled>
|
<el-checkbox value="Value 1" size="large">
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="box box1" v-if="!row.check">
|
<div class="box box1" v-if="!isCheck(ite, row)" @click="clickItem(ite, row)">
|
||||||
<el-icon><CloseBold style="color: red" /></el-icon>
|
<el-icon><CloseBold style="color: red" /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="box box2" v-else>
|
<div class="box box2" v-else @click="clickItem(ite, row)">
|
||||||
<el-icon><Select style="color: #fff" /></el-icon>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column label="APP权限" align="center">
|
|
||||||
<el-table-column prop="name" label="手铐管理权限" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-checkbox value="Value 1" size="large" disabled>
|
|
||||||
<template #default>
|
|
||||||
<div class="box box1" v-if="!row.check">
|
|
||||||
<el-icon><CloseBold style="color: red" /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="box box2" v-else>
|
|
||||||
<el-icon><Select style="color: #fff" /></el-icon>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-checkbox>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="name" label="告警管理权限" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-checkbox value="Value 1" size="large" disabled>
|
|
||||||
<template #default>
|
|
||||||
<div class="box box1" v-if="!row.check">
|
|
||||||
<el-icon><CloseBold style="color: red" /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="box box2" v-else>
|
|
||||||
<el-icon><Select style="color: #fff" /></el-icon>
|
<el-icon><Select style="color: #fff" /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -55,50 +25,47 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="date" label="操作" width="200" align="center">
|
<el-table-column prop="date" label="操作" width="200" align="center">
|
||||||
<template #default="scope">
|
<template #default="{ row }">
|
||||||
<el-button link type="primary" size="small">锁定</el-button>
|
<el-button link type="primary" size="small" @click="emit('complete', row)">保存</el-button>
|
||||||
<el-button link type="primary" size="small">修改</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-button class="mt-4" style="width: 100%" @click="addType"> 添加类型 </el-button>
|
<el-button class="mt-4" style="width: 100%" @click="emit('addType')"> 添加类型 </el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { TRoleList, TRoleMenuList } from "@/api/index.d";
|
||||||
|
import { PropType, ref } from "vue";
|
||||||
|
|
||||||
const tableData = ref([
|
const { roleListData, typeHeadList } = defineProps({
|
||||||
{
|
typeHeadList: {
|
||||||
name: "管理员",
|
type: Array as PropType<TRoleMenuList.TRes[]>,
|
||||||
flag: false,
|
default: () => [],
|
||||||
check: false,
|
|
||||||
},
|
},
|
||||||
{
|
roleListData: {
|
||||||
name: "警察",
|
type: Array as PropType<TRoleList[]>,
|
||||||
flag: false,
|
default: () => [],
|
||||||
check: false,
|
|
||||||
},
|
},
|
||||||
{
|
});
|
||||||
name: "辅警",
|
|
||||||
flag: false,
|
|
||||||
check: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "协警",
|
|
||||||
flag: false,
|
|
||||||
check: true,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const addType = () => {
|
const emit = defineEmits(["complete", "addType"]);
|
||||||
tableData.value = [
|
|
||||||
...tableData.value,
|
const isCheck = (ite, row) => {
|
||||||
{
|
let flag = false;
|
||||||
name: "",
|
row.roleMenu.forEach((item) => {
|
||||||
flag: false,
|
if (ite.id == item.id) {
|
||||||
check: false,
|
flag = true;
|
||||||
},
|
}
|
||||||
];
|
});
|
||||||
|
return flag;
|
||||||
|
};
|
||||||
|
const clickItem = (val, e) => {
|
||||||
|
let flag = e.roleMenu.some((item) => val.id == item.id);
|
||||||
|
if (!flag) {
|
||||||
|
e.roleMenu.push(val);
|
||||||
|
} else {
|
||||||
|
e.roleMenu = e.roleMenu.filter((item) => item.id != val.id);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user