<template>
|
<!-- 搜索框区域 -->
|
<div class="transparent-search-container">
|
<el-input
|
v-model="searchText"
|
:placeholder="t('messageInfo.searchPlaceholder')"
|
clearable
|
class="transparent-input"
|
@clear="handleSearchClear"
|
/>
|
<el-button class="transparent-search-btn" @click="handleSearch">
|
<img src="../images/search.png" width="20" style="margin-right: 5px" />
|
<span class="cell">{{ t("messageInfo.search") }}</span>
|
</el-button>
|
</div>
|
<el-table :data="tableData" :show-overflow-tooltip="true" class="alarmTable" :row-style="rowStyle">
|
<el-table-column :label="t('Person.name')" width="110" align="center">
|
<template #default="scope">
|
<el-image style="width: 15px; height: 15px; margin-top: 0" :src="my" />
|
<span @click="PersonInfoMessage(scope)">
|
{{ getSafeValue(scope.row.pname) }}
|
</span>
|
</template>
|
</el-table-column>
|
|
<el-table-column :label="t('Person.tagid')" width="70" align="center">
|
<template #default="scope">
|
<span>
|
{{ getSafeValue(scope.row.ptagid) }}
|
</span>
|
</template>
|
</el-table-column>
|
|
<el-table-column :label="t('PersonInfoCard.status')" width="60" align="center">
|
<template #default="scope">
|
<template v-if="scope.row.ponline">
|
<img
|
:src="scope.row.ponline === '0' ? offlineImgUrl : onlineImgUrl"
|
:title="t('PersonInfoCard.status')"
|
:style="{ width: '25px', height: '25px' }"
|
/>
|
</template>
|
<span v-else>--</span>
|
</template>
|
</el-table-column>
|
|
<el-table-column :label="t('Person.power')" width="70" align="center">
|
<template #default="scope">
|
<span>
|
{{ getSafeValue(scope.row.ppower) }}
|
</span>
|
</template>
|
</el-table-column>
|
|
<el-table-column :label="t('messageInfo.position')" width="90" align="center">
|
<template #default="scope">
|
<span @click="sendDataToParent(scope)">
|
<img
|
:src="scope.row.ponline === '0' ? position1 : position"
|
:title="t('messageInfo.position')"
|
:style="{ width: '25px', height: '25px' }"
|
/>
|
</span>
|
</template>
|
</el-table-column>
|
</el-table>
|
<el-dialog
|
v-model="centerDialogVisible"
|
:title="t('Person.PersonInfo')"
|
align-center
|
width="800"
|
destroy-on-close
|
center
|
style="background-size: 100% 100%"
|
>
|
<template #header="">
|
<div class="my-header" style="color: white">{{ t("Person.PersonInfo") }}</div>
|
</template>
|
<!-- 个人信息模板 -->
|
<div class="person-info">
|
<el-row>
|
<!-- 左侧图片区域 -->
|
<el-col :span="4">
|
<div class="image-container">
|
<!-- 第一张图片 -->
|
<el-image class="person-image" :src="drawerProps.row.baoliu38" @error="handleImageError">
|
<template #error>
|
<el-image class="person-image" :src="defaultImage" />
|
</template>
|
</el-image>
|
<p style="color: white" class="stroke-with-shadow">【 {{ t("Person.photo") }} 】</p>
|
|
<!-- 第二张图片 -->
|
<el-image class="person-image" :src="url" @error="handleImageError">
|
<template #error>
|
<el-image class="person-image" :src="defaultImage" />
|
</template>
|
</el-image>
|
<p class="image-label stroke-with-shadow" style="color: white">【 {{ t("PersonInfoCard.icon") }} 】</p>
|
</div>
|
</el-col>
|
<!-- 右侧信息区域 -->
|
<el-col :span="20">
|
<div class="info-list">
|
<!-- 上部分:个人信息 -->
|
<div class="info-section">
|
<h4 class="section-title" style="color: white">{{ t("PersonInfoCard.basicInfo") }}</h4>
|
<el-row :gutter="9">
|
<el-col :span="9" v-for="(item, index) in personalInfo" :key="index">
|
<p class="stroke-with-shadow">
|
<span>{{ item.label }}:</span> {{ item.value }}
|
</p>
|
</el-col>
|
</el-row>
|
</div>
|
|
<!-- 下部分:位置/状态信息 -->
|
<div class="info-section">
|
<h4 class="section-title" style="color: white">{{ t("PersonInfoCard.locationInfo") }}</h4>
|
<el-row :gutter="16">
|
<el-col :span="8" v-for="(item, index) in locationInfo" :key="index">
|
<p class="stroke-with-shadow">
|
<span>{{ item.label }}:</span> {{ item.value }}
|
</p>
|
</el-col>
|
</el-row>
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</el-dialog>
|
</template>
|
<script lang="ts">
|
import { defineComponent, onMounted, reactive, ref, toRefs, nextTick, onUnmounted, computed } from "vue";
|
import { getPersonList } from "@/api/modules/hxzk/person/person";
|
import trBackground from "../images/map/trbackground.png";
|
import position from "../images/map/position.png";
|
import position1 from "../images/map/position1.png";
|
import my from "../images/map/my.png";
|
import onlineImgUrl from "../images/map/zaixian.png";
|
import { FindOneDepartMent } from "@/api/modules/hxzk/department/department";
|
import offlineImgUrl from "../images/map/lixianimage.png";
|
import { Search } from "@element-plus/icons-vue"; // 引入搜索图标
|
import infoBack from "@/views/hxzk/images/map/infoBack.png";
|
import notData from "@/assets/images/notData1.png";
|
import { getSafeValue } from "@/views/hxzk/utils/common";
|
import { useI18n } from "vue-i18n";
|
|
export default defineComponent({
|
emits: ["personPostionClick"], // 声明自定义事件
|
|
setup(props, { emit }) {
|
const { t } = useI18n({ useScope: "global" });
|
|
// 表格的数据类型
|
interface tableType {
|
name: string;
|
money: number;
|
}
|
const centerDialogVisible = ref(false);
|
interface DrawerProps {
|
title: string;
|
isView: boolean;
|
initParam: Partial<User.ResUserList>;
|
row: Partial<User.ResUserList>;
|
api?: (params: any) => Promise<any>;
|
getTableList?: () => void;
|
}
|
const drawerProps = ref<DrawerProps>({
|
isView: false,
|
initParam: {},
|
title: "",
|
row: {}
|
});
|
const data = reactive({
|
tableData: [] as Array<tableType>, // 表格的数据
|
currentPage: 1, // 当前展示的页码
|
pageSize: 6, // 当前表格一页展示多少条数据
|
tableDom: {} as HTMLElement // 表格内容的dom
|
});
|
let timeInterval: NodeJS.Timer; // 定时器的对象
|
let tableScroll = ref(false); // 是否需要滚动
|
|
// 定时器 ID,用于在组件卸载时清除定时器
|
let intervalId: number | null = null;
|
|
onMounted(() => {
|
// 初始化表格的数据
|
list();
|
// 每秒执行一次 list 函数
|
intervalId = setInterval(list, 20000);
|
scrollTable();
|
});
|
|
onUnmounted(() => {
|
clearInterval(timeInterval);
|
// 组件卸载时清除定时器,避免内存泄漏
|
if (intervalId) {
|
clearInterval(intervalId);
|
}
|
});
|
const searchText = ref(""); // 搜索文本
|
const formatValue = (val, suffix = "") => {
|
return val === "null" ? "--" : val + suffix;
|
};
|
|
// 默认图片路径(可以是本地或网络图片)
|
const defaultImage = notData;
|
|
// 图片加载失败时的处理
|
const handleImageError = e => {
|
console.error(t("PersonInfoCard.imageLoadError"), e);
|
};
|
|
// 个人信息字段标签翻译
|
const personalInfo = computed(() => [
|
{ label: t("Person.name"), value: formatValue(drawerProps.value.row.pname) },
|
{ label: t("Person.tagid"), value: formatValue(drawerProps.value.row.ptagid) },
|
{ label: t("Person.department"), value: formatValue(drawerProps.value.row.pdepartment) },
|
{ label: t("Person.company"), value: formatValue(drawerProps.value.row.company) },
|
{ label: t("Person.power"), value: formatValue(drawerProps.value.row.ppower, "%") },
|
{ label: t("Person.phone"), value: formatValue(drawerProps.value.row.pphone) },
|
{ label: t("dayCount.type"), value: formatValue(drawerProps.value.row.baoliu19) },
|
{ label: t("Person.cardNumber"), value: formatValue(drawerProps.value.row.baoliu1) }
|
]);
|
|
// 位置信息字段标签翻译
|
const locationInfo = computed(() => [
|
{ label: t("PersonInfoCard.longitude"), value: formatValue(drawerProps.value.row.baoliu2) },
|
{ label: t("PersonInfoCard.latitude"), value: formatValue(drawerProps.value.row.baoliu3) },
|
{ label: t("PersonInfoCard.elevation"), value: formatValue(Number(drawerProps.value.row.baoliu4).toFixed(2), "cm") },
|
{
|
label: t("Person.status"),
|
value: formatValue(drawerProps.value.row.ponline) === "1" ? t("status.online") : t("status.offline")
|
},
|
{ label: t("PersonInfoCard.xCoordinate"), value: formatValue(drawerProps.value.row.px) },
|
{ label: t("PersonInfoCard.yCoordinate"), value: formatValue(drawerProps.value.row.py) },
|
{ label: t("PersonInfoCard.floor"), value: formatValue(drawerProps.value.row.pfloor) },
|
{ label: t("Person.status"), value: formatValue(drawerProps.value.row.baoliu13) },
|
{ label: t("PersonInfoCard.heartRate"), value: "--" },
|
{ label: t("PersonInfoCard.bloodOxygen"), value: "--" },
|
{ label: t("PersonInfoCard.temperature"), value: "--" },
|
{ label: t("Config.time"), value: formatValue(drawerProps.value.row.paddtiem) }
|
]);
|
|
// 计算属性:过滤表格数据
|
const filteredTableData = computed(() => {
|
if (!searchText.value) {
|
return data.tableData;
|
}
|
const search = searchText.value.toLowerCase();
|
return data.tableData.filter(
|
item =>
|
(item.pname && item.pname.toLowerCase().includes(search)) || (item.ptagid && item.ptagid.toString().includes(search))
|
);
|
});
|
// 在setup中添加原始数据引用
|
const originalTableData = ref<Array<tableType>>([]); // 用于存储原始数据
|
|
// 修改搜索处理函数
|
const handleSearch = () => {
|
if (!searchText.value) {
|
// 如果搜索内容为空,显示全部原始数据
|
data.tableData = [...originalTableData.value];
|
return;
|
}
|
|
const search = searchText.value.toLowerCase();
|
data.tableData = originalTableData.value.filter(
|
item =>
|
(item.pname && item.pname.toLowerCase().includes(search)) || (item.ptagid && item.ptagid.toString().includes(search))
|
);
|
};
|
|
// 修改清除搜索函数
|
const handleSearchClear = () => {
|
searchText.value = "";
|
data.tableData = [...originalTableData.value]; // 恢复原始数据
|
};
|
|
// 初始化表格的数据
|
const list = () => {
|
const params = {
|
pageNum: 1,
|
pageSize: 1000
|
};
|
getPersonList(params).then(dt => {
|
data.tableData = dt.data.list;
|
originalTableData.value = [...dt.data.list]; // 保存原始数据的副本
|
});
|
};
|
|
// 表格的数据滚动
|
const scrollTable = () => {
|
nextTick(() => {
|
// 获取当前表格内容的dom
|
let table = document.getElementsByClassName("alarmTable")[0];
|
data.tableDom = table.getElementsByClassName("el-scrollbar__wrap")[0]! as HTMLElement;
|
// 鼠标放在表格内容,暂停滚动
|
data.tableDom.addEventListener("mouseover", () => {
|
tableScroll.value = false;
|
});
|
// 鼠标移出表格内容,继续滚动
|
// data.tableDom.addEventListener("mouseout", () => {
|
// tableScroll.value = true;
|
// });
|
//
|
timeInterval = setInterval(() => {
|
if (tableScroll.value) {
|
// 每次内容滚动的距离
|
data.tableDom.scrollTop += 1;
|
if (data.tableDom.clientHeight + data.tableDom.scrollTop == data.tableDom.scrollHeight) {
|
data.tableDom.scrollTop = 0;
|
}
|
}
|
}, 10);
|
});
|
};
|
const rowStyle = ({}) => {
|
// 设置统一的背景图片,这里假设图片路径为 'path/to/your-background-image.jpg'
|
// 可以根据实际情况修改图片路径
|
return {
|
backgroundImage: `url('${trBackground}')`,
|
backgroundSize: "100% 150%", // 可根据需求调整背景图片的显示方式
|
backgroundRepeat: "no-repeat"
|
};
|
};
|
|
//定位
|
const sendDataToParent = person => {
|
emit("personPostionClick", person.row); // 触发自定义事件并传递数据
|
};
|
const url = ref("");
|
// 暴露给模板的方法
|
const PersonInfoMessage = data => {
|
drawerProps.value.row = data.row;
|
FindOneDepartMent(drawerProps.value.row).then(data => {
|
url.value = data.baoliu3;
|
});
|
centerDialogVisible.value = true;
|
};
|
|
return {
|
position,
|
...toRefs(data),
|
rowStyle,
|
my,
|
onlineImgUrl,
|
infoBack,
|
offlineImgUrl,
|
sendDataToParent,
|
PersonInfoMessage,
|
drawerProps,
|
url,
|
centerDialogVisible,
|
handleSearch,
|
handleSearchClear,
|
filteredTableData,
|
searchText,
|
Search,
|
personalInfo,
|
locationInfo,
|
handleImageError,
|
defaultImage,
|
getSafeValue,
|
position1,
|
t
|
};
|
}
|
});
|
</script>
|
<style lang="scss" scoped>
|
.transparent-search-container {
|
position: relative;
|
top: 30px;
|
display: flex;
|
align-items: center;
|
width: 370px;
|
padding: 2px 0;
|
margin: auto;
|
margin-bottom: 15px;
|
overflow: hidden;
|
background: rgb(69 148 204 / 10%); /* 半透明背景 */
|
backdrop-filter: blur(5px); /* 毛玻璃效果 */
|
border: 1px solid rgb(41 199 255); /* 半透明边框 */
|
}
|
.transparent-input {
|
flex: 1;
|
:deep(.el-input__wrapper) {
|
background: transparent;
|
border: none;
|
box-shadow: none;
|
.el-input__inner {
|
color: #eeeeee; /* 浅色文字 */
|
&::placeholder {
|
color: rgb(238 238 238 / 60%); /* 半透明占位符 */
|
}
|
}
|
}
|
}
|
.transparent-search-btn {
|
display: flex;
|
gap: 6px;
|
align-items: center;
|
width: 80px;
|
height: 32px;
|
padding: 0 15px;
|
color: #ffffff;
|
background: transparent;
|
border: none;
|
border: 1px solid rgb(69 148 204 / 0%); /* 半透明边框 */
|
border-radius: 0;
|
&:hover {
|
color: #ffffff;
|
background: rgb(69 148 204 / 10%); /* 半透明边框 */
|
}
|
&:active {
|
background: rgb(69 148 204 / 10%); /* 半透明边框 */
|
}
|
.el-icon {
|
font-size: 16px;
|
}
|
}
|
.alarmTable {
|
height: 85%;
|
padding: 10px 0;
|
margin-top: 10px;
|
overflow: hidden;
|
font-size: 14px;
|
font-weight: bolder;
|
text-shadow:
|
-1px -1px 0 #000000,
|
1px -1px 0 #000000,
|
-1px 1px 0 #000000,
|
1px 1px 0 #000000;
|
scroll-behavior: smooth;
|
}
|
.person-info {
|
padding: 2px;
|
}
|
.image-container {
|
display: flex;
|
flex-direction: column;
|
gap: 20px;
|
align-items: center;
|
}
|
.person-image {
|
width: 120px;
|
height: 120px;
|
border-radius: 10px;
|
box-shadow: 0 0 8px rgb(0 0 0 / 20%);
|
}
|
.info-list {
|
padding: 0 20px;
|
}
|
.info-list p {
|
margin: 8px 0;
|
font-size: 14px;
|
}
|
.info-list p span {
|
margin-right: 10px;
|
font-weight: bold;
|
}
|
.stroke-with-shadow {
|
color: white;
|
|
/* 从四个方向添加阴影来模拟描边 */
|
text-shadow:
|
-1px -1px 0 rgb(12 12 12),
|
1px -1px 0 rgb(0 0 0),
|
-1px 1px 0 rgb(0 0 0),
|
1px 1px 0 rgb(17 17 17);
|
}
|
.section-title {
|
padding-bottom: 5px;
|
margin-bottom: 10px;
|
color: white;
|
border-bottom: 1px solid #444444;
|
}
|
</style>
|