386 lines
8.9 KiB
Vue
386 lines
8.9 KiB
Vue
<template>
|
||
<!-- 设备卡片组件 -->
|
||
<el-card class="device-card" :body-style="{ padding: '20px' }" :data-status="deviceInfo.devicestatus">
|
||
<div class="card-content">
|
||
<!-- 设备基本信息区域 -->
|
||
<div class="device-info">
|
||
<!-- 设备名称和操作按钮区域 -->
|
||
<div class="name-section">
|
||
<h3 class="device-name">{{ deviceInfo.devicename }}</h3>
|
||
<!-- 详情和数据按钮 -->
|
||
<div class="button-group">
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
class="detail-btn"
|
||
text
|
||
@click="handleAction('details')"
|
||
>
|
||
详情
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
class="data-btn"
|
||
text
|
||
@click="handleAction('data')"
|
||
>
|
||
数据
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
<!-- 设备状态显示 -->
|
||
<p class="device-status" :class="getStatusClass(deviceInfo.devicestatus)">
|
||
{{ getStatusText(deviceInfo.devicestatus) }}
|
||
</p>
|
||
</div>
|
||
<!-- 设备详细信息区域 -->
|
||
<div class="device-details">
|
||
<p class="detail-item">
|
||
<span class="label">设备ID:</span>
|
||
<span class="value">{{ deviceInfo.devicecode }}</span>
|
||
</p>
|
||
<p class="detail-item">
|
||
<span class="label">类型:</span>
|
||
<span class="value">{{ getDeviceTypeName(deviceInfo.devicetype) }}</span>
|
||
</p>
|
||
<p class="detail-item">
|
||
<span class="label">位置:</span>
|
||
<span class="value">{{ deviceInfo.location }}</span>
|
||
</p>
|
||
</div>
|
||
<!-- 分隔线 -->
|
||
<div class="divider"></div>
|
||
<!-- 设备操作按钮区域 -->
|
||
<div class="action-buttons">
|
||
<!-- 启用按钮 -->
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
:disabled="deviceInfo.devicestatus === 1"
|
||
@click="handleAction('enable')"
|
||
>
|
||
启用
|
||
</el-button>
|
||
<!-- 停用按钮 -->
|
||
<el-button
|
||
type="warning"
|
||
size="small"
|
||
:disabled="deviceInfo.devicestatus === 2"
|
||
@click="handleAction('disable')"
|
||
>
|
||
停用
|
||
</el-button>
|
||
<!-- 设置按钮 -->
|
||
<el-button
|
||
type="success"
|
||
size="small"
|
||
@click="handleAction('settings')"
|
||
>
|
||
设置
|
||
</el-button>
|
||
<!-- 删除按钮 -->
|
||
<el-button
|
||
type="danger"
|
||
plain
|
||
size="small"
|
||
@click="handleAction('delete')"
|
||
>
|
||
<el-icon><Delete /></el-icon>
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { defineProps, defineEmits } from 'vue'
|
||
import { Delete } from '@element-plus/icons-vue'
|
||
|
||
// 定义组件属性
|
||
const props = defineProps({
|
||
deviceInfo: {
|
||
type: Object,
|
||
required: true,
|
||
default: () => ({
|
||
id: '', // 设备ID
|
||
devicename: '', // 设备名称
|
||
devicetype: '', // 设备类型
|
||
location: '', // 设备位置
|
||
devicestatus: 0, // 设备状态:0-待激活,1-在线,2-离线,3-禁用
|
||
statusText: '待激活' // 状态文本
|
||
})
|
||
}
|
||
})
|
||
|
||
// 定义事件
|
||
const emit = defineEmits(['action'])
|
||
|
||
/**
|
||
* 获取设备状态文本
|
||
* @param {number} status - 设备状态码
|
||
* @returns {string} 状态文本
|
||
*/
|
||
const getStatusText = (status) => {
|
||
switch (status) {
|
||
case 0:
|
||
return '待激活'
|
||
case 1:
|
||
return '在线'
|
||
case 2:
|
||
return '离线'
|
||
case 3:
|
||
return '禁用'
|
||
default:
|
||
return '未知'
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取设备状态对应的样式类名
|
||
* @param {number} status - 设备状态码
|
||
* @returns {string} 样式类名
|
||
*/
|
||
const getStatusClass = (status) => {
|
||
switch (status) {
|
||
case 0:
|
||
return 'warning' // 待激活状态 - 黄色
|
||
case 1:
|
||
return 'normal' // 在线状态 - 绿色
|
||
case 2:
|
||
return 'error' // 离线状态 - 灰色
|
||
case 3:
|
||
return 'disabled' // 禁用状态 - 红色
|
||
default:
|
||
return ''
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理设备操作事件
|
||
* @param {string} action - 操作类型
|
||
*/
|
||
const handleAction = (action) => {
|
||
emit('action', {
|
||
action,
|
||
deviceId: props.deviceInfo.devicecode
|
||
})
|
||
}
|
||
|
||
// 设备类型映射
|
||
const getDeviceTypeName = (type: string) => {
|
||
const typeMap: Record<string, string> = {
|
||
'ECG': '心电设备',
|
||
'BP': '血压设备',
|
||
'SPO2': '血氧设备',
|
||
'TEMP': '体温设备',
|
||
'WEIGHT': '体重设备'
|
||
}
|
||
return typeMap[type] || type
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 设备卡片基础样式 */
|
||
.device-card {
|
||
width: 300px;
|
||
margin: 10px;
|
||
border-radius: 12px;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||
transition: all 0.3s ease;
|
||
background: linear-gradient(145deg, #ffffff, #f5f7fa);
|
||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||
}
|
||
|
||
/* 卡片悬停效果 */
|
||
.device-card:hover {
|
||
transform: translateY(-5px);
|
||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
||
}
|
||
|
||
/* 卡片内容布局 */
|
||
.card-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
/* 设备信息区域样式 */
|
||
.device-info {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
padding: 5px 0;
|
||
}
|
||
|
||
/* 名称区域样式 */
|
||
.name-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
flex: 1;
|
||
min-width: 0; /* 防止子元素溢出 */
|
||
}
|
||
|
||
/* 设备名称样式 */
|
||
.device-name {
|
||
margin: 0;
|
||
font-size: 20px;
|
||
color: #303133;
|
||
font-weight: 600;
|
||
transition: color 0.3s ease;
|
||
white-space: nowrap; /* 防止文字换行 */
|
||
overflow: hidden; /* 超出部分隐藏 */
|
||
text-overflow: ellipsis; /* 显示省略号 */
|
||
max-width: 150px; /* 最大宽度 */
|
||
}
|
||
|
||
/* 设备名称悬停效果 */
|
||
.device-card:hover .device-name {
|
||
color: #409EFF;
|
||
}
|
||
|
||
/* 设备状态基础样式 */
|
||
.device-status {
|
||
padding: 6px 12px;
|
||
border-radius: 20px;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
transition: all 0.3s ease;
|
||
white-space: nowrap; /* 防止文字换行 */
|
||
}
|
||
|
||
/* 在线状态样式 */
|
||
.device-status.normal {
|
||
background-color: #67C23A;
|
||
color: white;
|
||
box-shadow: 0 2px 8px rgba(103, 194, 58, 0.3);
|
||
}
|
||
|
||
/* 待激活状态样式 */
|
||
.device-status.warning {
|
||
background-color: #F7BA2A;
|
||
color: white;
|
||
box-shadow: 0 2px 8px rgba(247, 186, 42, 0.3);
|
||
}
|
||
|
||
/* 离线状态样式 */
|
||
.device-status.error {
|
||
background-color: #909399;
|
||
color: white;
|
||
box-shadow: 0 2px 8px rgba(144, 147, 153, 0.3);
|
||
}
|
||
|
||
/* 禁用状态样式 */
|
||
.device-status.disabled {
|
||
background-color: #F56C6C;
|
||
color: white;
|
||
box-shadow: 0 2px 8px rgba(245, 108, 108, 0.3);
|
||
}
|
||
|
||
/* 设备详情区域样式 */
|
||
.device-details {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
/* 详情项样式 */
|
||
.detail-item {
|
||
margin: 0;
|
||
font-size: 14px;
|
||
color: #606266;
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
/* 详情项悬停效果 */
|
||
.device-card:hover .detail-item {
|
||
transform: translateX(5px);
|
||
}
|
||
|
||
/* 标签样式 */
|
||
.label {
|
||
color: #909399;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
/* 值样式 */
|
||
.value {
|
||
color: #303133;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 分隔线样式 */
|
||
.divider {
|
||
height: 1px;
|
||
background: linear-gradient(to right, transparent, #DCDFE6, transparent);
|
||
margin: 10px 0;
|
||
}
|
||
|
||
/* 操作按钮区域样式 */
|
||
.action-buttons {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 8px;
|
||
}
|
||
|
||
/* 按钮图标样式 */
|
||
.el-icon {
|
||
margin-right: 4px;
|
||
}
|
||
|
||
/* 在线状态卡片样式 */
|
||
.device-card[data-status="1"] {
|
||
background: linear-gradient(145deg, #e6f3ff, #fafafa);
|
||
border: 1px solid rgba(64, 158, 255, 0.2);
|
||
}
|
||
|
||
/* 在线状态卡片悬停效果 */
|
||
.device-card[data-status="1"]:hover {
|
||
background: linear-gradient(145deg, #d9edff, #fafafa);
|
||
box-shadow: 0 8px 30px rgba(64, 158, 255, 0.15);
|
||
}
|
||
|
||
/* 待激活状态卡片样式 */
|
||
.device-card[data-status="0"] {
|
||
background: linear-gradient(145deg, #f7ecec, #fafafa);
|
||
border: 1px solid rgba(247, 186, 42, 0.2);
|
||
}
|
||
|
||
/* 待激活状态卡片悬停效果 */
|
||
.device-card[data-status="0"]:hover {
|
||
background: linear-gradient(145deg, #f7ecec, #fafafa);
|
||
box-shadow: 0 8px 30px rgba(247, 186, 42, 0.15);
|
||
}
|
||
|
||
/* 离线状态卡片样式 */
|
||
.device-card[data-status="2"] {
|
||
background: linear-gradient(145deg, #e4e4e4, #fafafa);
|
||
border: 1px solid rgba(247, 186, 42, 0.2);
|
||
}
|
||
|
||
/* 离线状态卡片悬停效果 */
|
||
.device-card[data-status="2"]:hover {
|
||
background: linear-gradient(145deg, #e4e4e4, #fafafa);
|
||
box-shadow: 0 8px 30px rgba(247, 186, 42, 0.15);
|
||
}
|
||
/* 禁用状态卡片样式 */
|
||
.device-card[data-status="3"] {
|
||
background: linear-gradient(145deg, #f09393, #fafafa);
|
||
border: 1px solid rgba(245, 108, 108, 0.2);
|
||
}
|
||
|
||
/* 禁用状态卡片悬停效果 */
|
||
.device-card[data-status="3"]:hover {
|
||
background: linear-gradient(145deg, #f09393, #fafafa);
|
||
box-shadow: 0 8px 30px rgba(245, 108, 108, 0.15);
|
||
}
|
||
|
||
.button-group {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
</style>
|