<template>
|
<el-dialog
|
v-model="centerDialogVisible"
|
:title="$t('Person.PersonInfo')"
|
align-center
|
width="800"
|
destroy-on-close
|
center
|
class="person-info-dialog"
|
>
|
<template #header>
|
<div class="dialog-header">
|
<el-icon size="20" style="margin-right: 8px">
|
<User />
|
</el-icon>
|
{{ $t("Person.PersonInfo") }}
|
</div>
|
</template>
|
|
<!-- 个人信息模板 -->
|
<div class="person-info">
|
<el-row :gutter="20">
|
<!-- 左侧图片区域 -->
|
<el-col :span="6">
|
<div class="image-container">
|
<!-- 第一张图片 -->
|
<div class="image-card">
|
<el-image class="person-image" :src="drawerProps.row.baoliu38" @error="handleImageError" fit="cover">
|
<template #error>
|
<div class="image-error">
|
<el-icon size="32">
|
<Picture />
|
</el-icon>
|
<span>{{ $t("PersonInfoCard.noPhoto") }}</span>
|
</div>
|
</template>
|
</el-image>
|
<div class="image-label">
|
<el-icon size="14" style="margin-right: 4px">
|
<Camera />
|
</el-icon>
|
{{ $t("PersonDrawer.photo") }}
|
</div>
|
</div>
|
|
<!-- 第二张图片 -->
|
<div class="image-card">
|
<el-image class="person-image" :src="url" @error="handleImageError" fit="cover">
|
<template #error>
|
<div class="image-error">
|
<el-icon size="32">
|
<Picture />
|
</el-icon>
|
<span>{{ $t("PersonInfoCard.noIcon") }}</span>
|
</div>
|
</template>
|
</el-image>
|
<div class="image-label">
|
<el-icon size="14" style="margin-right: 4px">
|
<Avatar />
|
</el-icon>
|
{{ $t("PersonInfoCard.icon") }}
|
</div>
|
</div>
|
</div>
|
</el-col>
|
|
<!-- 右侧信息区域 -->
|
<el-col :span="18">
|
<div class="info-container">
|
<!-- 基本信息 -->
|
<div class="info-section">
|
<div class="section-header">
|
<el-icon size="16" style="margin-right: 8px">
|
<UserFilled />
|
</el-icon>
|
<span class="section-title">{{ $t("PersonInfoCard.basicInfo") }}</span>
|
</div>
|
<el-row :gutter="16">
|
<el-col :span="8" v-for="(item, index) in personalInfo" :key="index">
|
<div class="info-item">
|
<span class="info-label">{{ item.label }}:</span>
|
<el-tooltip :content="item.value" placement="top" :disabled="item.value.length < 15">
|
<span class="info-value">{{ item.value }}</span>
|
</el-tooltip>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
|
<!-- 位置信息 -->
|
<div class="info-section">
|
<div class="section-header">
|
<el-icon size="16" style="margin-right: 8px">
|
<Location />
|
</el-icon>
|
<span class="section-title">{{ $t("PersonInfoCard.locationInfo") }}</span>
|
</div>
|
<el-row :gutter="16">
|
<el-col :span="8" v-for="(item, index) in locationInfo" :key="index">
|
<div class="info-item">
|
<span class="info-label">{{ item.label }}:</span>
|
<el-tooltip :content="item.value" placement="top" :disabled="item.value.length < 15">
|
<span class="info-value">{{ item.value }}</span>
|
</el-tooltip>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</el-dialog>
|
</template>
|
|
<script lang="ts" setup>
|
import { ref, computed } from "vue";
|
import { FindOneDepartMent } from "@/api/modules/hxzk/department/department";
|
|
import { useI18n } from "vue-i18n";
|
import { User, Picture, Camera, Avatar, UserFilled, Location } from "@element-plus/icons-vue";
|
|
const { t } = useI18n();
|
|
const url = ref("");
|
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 drawerVisible = ref(false);
|
const drawerProps = ref<DrawerProps>({
|
isView: false,
|
initParam: {},
|
title: "",
|
row: {}
|
});
|
|
const formatValue = (val, suffix = "") => {
|
return val === "null" ? "--" : val + suffix;
|
};
|
|
// 默认图片路径(可以是本地或网络图片)
|
|
// 图片加载失败时的处理
|
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("PersonInfoCard.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(drawerProps.value.row.baoliu4, "cm") },
|
{
|
label: t("Person.online"),
|
value: formatValue(drawerProps.value.row.ponline) === "1" ? t("Person.status.online") : t("Person.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("PersonInfoCard.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 acceptParams = (params: DrawerProps) => {
|
centerDialogVisible.value = true;
|
drawerProps.value = params;
|
drawerVisible.value = true;
|
FindOneDepartMent(drawerProps.value.row).then(data => {
|
url.value = data.baoliu3;
|
});
|
};
|
|
defineExpose({
|
acceptParams
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.person-info-dialog {
|
:deep(.el-dialog) {
|
overflow: hidden;
|
border-radius: 12px;
|
.el-dialog__header {
|
padding: 20px 24px;
|
margin: 0;
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
.el-dialog__title {
|
font-size: 18px;
|
font-weight: 600;
|
color: white;
|
}
|
.el-dialog__headerbtn {
|
.el-dialog__close {
|
font-size: 18px;
|
color: white;
|
}
|
}
|
}
|
.el-dialog__body {
|
padding: 24px;
|
background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%);
|
}
|
}
|
}
|
.dialog-header {
|
display: flex;
|
align-items: center;
|
font-size: 18px;
|
font-weight: 600;
|
color: white;
|
}
|
.person-info {
|
padding: 8px;
|
}
|
.image-container {
|
display: flex;
|
flex-direction: column;
|
gap: 24px;
|
align-items: center;
|
}
|
.image-card {
|
padding: 16px;
|
background: white;
|
border-radius: 12px;
|
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
|
transition:
|
transform 0.3s ease,
|
box-shadow 0.3s ease;
|
&:hover {
|
box-shadow: 0 8px 20px rgb(0 0 0 / 15%);
|
transform: translateY(-2px);
|
}
|
}
|
.person-image {
|
width: 120px;
|
height: 120px;
|
border: 2px solid #e4e7ed;
|
border-radius: 8px;
|
transition: border-color 0.3s ease;
|
&:hover {
|
border-color: #409eff;
|
}
|
}
|
.image-error {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
width: 120px;
|
height: 120px;
|
color: #909399;
|
background-color: #f5f7fa;
|
border-radius: 8px;
|
span {
|
margin-top: 8px;
|
font-size: 12px;
|
}
|
}
|
.image-label {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-top: 12px;
|
font-size: 14px;
|
font-weight: 600;
|
color: #606266;
|
text-align: center;
|
}
|
.info-container {
|
padding: 0 16px;
|
}
|
.info-section {
|
margin-bottom: 32px;
|
&:last-child {
|
margin-bottom: 0;
|
}
|
}
|
.section-header {
|
display: flex;
|
align-items: center;
|
padding-bottom: 8px;
|
margin-bottom: 16px;
|
border-bottom: 2px solid #409eff;
|
}
|
.section-title {
|
margin: 0;
|
font-size: 16px;
|
font-weight: 600;
|
color: #303133;
|
}
|
.info-item {
|
display: flex;
|
align-items: center;
|
padding: 12px 16px;
|
margin-bottom: 12px;
|
overflow: hidden;
|
background: white;
|
border-radius: 8px;
|
box-shadow: 0 2px 8px rgb(0 0 0 / 5%);
|
transition: all 0.3s ease;
|
&:hover {
|
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
|
transform: translateX(4px);
|
}
|
}
|
.info-label {
|
flex-shrink: 0;
|
margin-right: 8px;
|
font-size: 14px;
|
font-weight: 600;
|
color: #606266;
|
white-space: nowrap;
|
}
|
.info-value {
|
max-width: 100%;
|
overflow: hidden;
|
font-size: 14px;
|
font-weight: 500;
|
color: #303133;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
|
@media (width <= 768px) {
|
.person-info-dialog {
|
:deep(.el-dialog) {
|
width: 95% !important;
|
}
|
}
|
.image-container {
|
flex-direction: row;
|
gap: 16px;
|
justify-content: center;
|
}
|
.person-image,
|
.image-error {
|
width: 80px;
|
height: 80px;
|
}
|
}
|
</style>
|