设备卡片封装

This commit is contained in:
Flow 2025-05-29 11:17:04 +08:00
parent c5d4932630
commit 780240d96a
2 changed files with 221 additions and 0 deletions

View File

@ -0,0 +1,172 @@
<template>
<el-card class="device-card" :body-style="{ padding: '20px' }">
<div class="card-content">
<div class="device-info">
<h3 class="device-name">{{ deviceInfo.name }}</h3>
<p class="device-status" :class="deviceInfo.status">
{{ deviceInfo.statusText }}
</p>
</div>
<div class="device-details">
<p class="detail-item">
<span class="label">设备ID</span>
<span class="value">{{ deviceInfo.id }}</span>
</p>
<p class="detail-item">
<span class="label">类型</span>
<span class="value">{{ deviceInfo.type }}</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.status === 'normal'"
@click="handleAction('enable')"
>
启用
</el-button>
<el-button
type="warning"
size="small"
:disabled="deviceInfo.status === 'error'"
@click="handleAction('disable')"
>
停用
</el-button>
<el-button
type="success"
size="small"
@click="handleAction('settings')"
>
设置
</el-button>
<el-button
type="info"
size="small"
@click="handleAction('details')"
>
详情
</el-button>
</div>
</div>
</el-card>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
deviceInfo: {
type: Object,
required: true,
default: () => ({
id: '',
name: '',
type: '',
location: '',
status: 'normal',
statusText: '正常'
})
}
})
const emit = defineEmits(['action'])
const handleAction = (action) => {
emit('action', {
action,
deviceId: props.deviceInfo.id
})
}
</script>
<style scoped>
.device-card {
width: 300px;
margin: 10px;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.card-content {
display: flex;
flex-direction: column;
gap: 15px;
}
.device-info {
display: flex;
justify-content: space-between;
align-items: center;
}
.device-name {
margin: 0;
font-size: 18px;
color: #303133;
}
.device-status {
padding: 4px 8px;
border-radius: 4px;
font-size: 14px;
}
.device-status.normal {
background-color: #67C23A;
color: white;
}
.device-status.warning {
background-color: #E6A23C;
color: white;
}
.device-status.error {
background-color: #F56C6C;
color: white;
}
.device-details {
display: flex;
flex-direction: column;
gap: 8px;
}
.detail-item {
margin: 0;
font-size: 14px;
color: #606266;
}
.label {
color: #909399;
margin-right: 8px;
}
.value {
color: #303133;
}
.divider {
height: 1px;
background-color: #b7b7bb;
}
.action-buttons {
display: flex;
justify-content: space-between;
gap: 8px;
}
.action-buttons .el-button {
flex: 1;
}
</style>

View File

@ -101,6 +101,17 @@
</el-table>
</ContentWrap>
<!-- 设备卡片展示区域 -->
<!-- <ContentWrap>
<div class="device-cards-container">
<device-card
v-for="device in deviceList"
:key="device.id"
:device-info="device"
/>
</div>
</ContentWrap> -->
<!-- 表单弹窗添加/修改 -->
<DeptForm ref="formRef" @success="getList" />
</template>
@ -111,6 +122,7 @@ import { handleTree } from '@/utils/tree'
import * as DeptApi from '@/api/system/dept'
import DeptForm from './DeptForm.vue'
import * as UserApi from '@/api/system/user'
import DeviceCard from '../cards/cards.vue'
defineOptions({ name: 'SystemDept' })
@ -130,6 +142,34 @@ const isExpandAll = ref(true) // 是否展开,默认全部展开
const refreshTable = ref(true) //
const userList = ref<UserApi.UserVO[]>([]) //
//
// const deviceList = ref([
// {
// id: 'Blood001',
// name: '',
// type: '',
// location: '/西/',
// status: 'normal',
// statusText: ''
// },
// {
// id: 'Glucose001',
// name: '',
// type: '',
// location: '//',
// status: 'warning',
// statusText: ''
// },
// {
// id: 'Oxygen001',
// name: '',
// type: '',
// location: '//',
// status: 'error',
// statusText: ''
// }
// ])
/** 查询机构列表 */
const getList = async () => {
loading.value = true
@ -188,3 +228,12 @@ onMounted(async () => {
userList.value = await UserApi.getSimpleUserList()
})
</script>
<style scoped>
.device-cards-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
padding: 20px;
}
</style>