vue3/src/views/devices/devices_cards.vue

386 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>