|
|
|
|
@ -204,66 +204,116 @@
|
|
|
|
|
class="grid-card"
|
|
|
|
|
@click="openDetailForm(item?.id,item?.deviceName)"
|
|
|
|
|
>
|
|
|
|
|
<!-- attributeDeviceId.value = row?.id
|
|
|
|
|
attributeDeviceName.value = row?.deviceName ?? ''-->
|
|
|
|
|
|
|
|
|
|
<!-- 设备状态指示 status-${item.deviceStatus} -->
|
|
|
|
|
<div class="status-indicator" :class="getStatusText(item.operatingStatus)"></div>
|
|
|
|
|
|
|
|
|
|
<!-- 设备图标 -->
|
|
|
|
|
<!-- <div class="card-icon">
|
|
|
|
|
<el-icon :size="32" :color="getEquipmentColor(item.type)">
|
|
|
|
|
<component :is="getEquipmentIcon(item.type)"/>
|
|
|
|
|
</el-icon>
|
|
|
|
|
</div>-->
|
|
|
|
|
<!-- 设备基本信息 -->
|
|
|
|
|
<div class="card-content">
|
|
|
|
|
<!-- 设备状态 -->
|
|
|
|
|
<div class="card-status">
|
|
|
|
|
<el-tag
|
|
|
|
|
:type="getStatusTag(item.operatingStatus)"
|
|
|
|
|
size="small"
|
|
|
|
|
class="status-tag"
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
<div class="device-card">
|
|
|
|
|
<div class="header">
|
|
|
|
|
<div class="device-icon">
|
|
|
|
|
<i>📊</i>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="device-info">
|
|
|
|
|
<div class="device-name">{{ item.deviceName }}</div>
|
|
|
|
|
<div class="device-id">{{ item.deviceCode }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="status-badge" :class="getStatusText(item.operatingStatus)">
|
|
|
|
|
<span class="status-dot" :class="getStatusText(item.operatingStatus)"></span>
|
|
|
|
|
{{ item.operatingStatus }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="card-title"> {{ t('DataCollection.Device.deviceName') }}:{{ item.deviceName }}</div>
|
|
|
|
|
<div class="card-code"> {{ t('DataCollection.Device.deviceCode') }}:{{ item.deviceCode }}</div>
|
|
|
|
|
<div class="card-model"> {{ t('DataCollection.Device.collectionTime') }}:{{ item.collectionTime }}</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="content">
|
|
|
|
|
<div class="info-row">
|
|
|
|
|
<div class="info-label">
|
|
|
|
|
<i>📡</i>
|
|
|
|
|
采集协议
|
|
|
|
|
</div>
|
|
|
|
|
<div class="info-value">
|
|
|
|
|
<dict-tag :type="DICT_TYPE.IOT_PROTOCOL" :value="item.protocol" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="info-row">
|
|
|
|
|
<div class="info-label">
|
|
|
|
|
<i>⏱️</i>
|
|
|
|
|
采集时间
|
|
|
|
|
</div>
|
|
|
|
|
<div class="info-value">
|
|
|
|
|
{{ item.collectionTime }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- <!– 运行信息 –>
|
|
|
|
|
<div v-if="item.runningHours" class="card-running">
|
|
|
|
|
<span>运行: {{ formatRunningHours(item.runningHours) }}</span>
|
|
|
|
|
<div class="toggle-container" @click.stop>
|
|
|
|
|
<div class="toggle-label">
|
|
|
|
|
<i>🔘️</i>
|
|
|
|
|
是否启用
|
|
|
|
|
</div>
|
|
|
|
|
<el-switch
|
|
|
|
|
:model-value="isDeviceEnabled(item)"
|
|
|
|
|
@change="(val) => handleDeviceEnableChange(item, val)"
|
|
|
|
|
/>
|
|
|
|
|
<!-- <label class="toggle-switch">
|
|
|
|
|
<input type="checkbox" v-model="item.operatingStatus" @change.stop="enabledChange(item,item?.id)" />
|
|
|
|
|
<span class="slider"></span>
|
|
|
|
|
</label>-->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!– 位置信息 –>
|
|
|
|
|
<div v-if="item.location" class="card-location">
|
|
|
|
|
<el-icon :size="12">
|
|
|
|
|
<Location/>
|
|
|
|
|
</el-icon>
|
|
|
|
|
<span>{{ item.location }}</span>
|
|
|
|
|
</div>-->
|
|
|
|
|
<div class="footer" @click.stop>
|
|
|
|
|
<div class="action-icons">
|
|
|
|
|
<el-button class="action-btn btn-primary" @click.stop="openDetailForm(item?.id,item?.deviceName)" >
|
|
|
|
|
<i>📍</i>
|
|
|
|
|
{{ t('DataCollection.Device.attributeModuleName') }}
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button class="action-btn btn-success" @click.stop="openForm('setting', item?.id)" v-hasPermi="['iot:device:update']">
|
|
|
|
|
<i>⚙️</i>
|
|
|
|
|
{{ t('DataCollection.Device.settingDialogTitle') }}
|
|
|
|
|
</el-button>
|
|
|
|
|
|
|
|
|
|
<el-tooltip
|
|
|
|
|
:content="t('action.copy')"
|
|
|
|
|
placement="top"
|
|
|
|
|
effect="dark"
|
|
|
|
|
>
|
|
|
|
|
<el-button
|
|
|
|
|
class="icon-btn"
|
|
|
|
|
link
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="handleCopy(item?.id)"
|
|
|
|
|
v-hasPermi="['iot:device:create']"
|
|
|
|
|
>
|
|
|
|
|
📋
|
|
|
|
|
</el-button>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<el-tooltip
|
|
|
|
|
:content="t('action.edit')"
|
|
|
|
|
placement="top"
|
|
|
|
|
effect="dark"
|
|
|
|
|
>
|
|
|
|
|
<el-button
|
|
|
|
|
link
|
|
|
|
|
type="primary"
|
|
|
|
|
@click.stop="handleEdit(item)"
|
|
|
|
|
v-hasPermi="['iot:device:update']"
|
|
|
|
|
>
|
|
|
|
|
✏️
|
|
|
|
|
</el-button>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<el-tooltip
|
|
|
|
|
:content="t('DataCollection.Device.gridView')"
|
|
|
|
|
placement="top"
|
|
|
|
|
effect="dark"
|
|
|
|
|
>
|
|
|
|
|
<el-button class="icon-btn" @click.stop="changeTable">🏠</el-button>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<Pagination
|
|
|
|
|
:total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
|
|
|
|
|
@pagination="getList"/>
|
|
|
|
|
<!-- 分页 -->
|
|
|
|
|
<!-- <div class="simple-pagination">
|
|
|
|
|
<el-pagination
|
|
|
|
|
v-model:current-page="queryParams.pageNo"
|
|
|
|
|
v-model:page-size="queryParams.pageSize"
|
|
|
|
|
:page-sizes="[12, 24, 48, 96]"
|
|
|
|
|
layout="total, sizes, prev, pager, next"
|
|
|
|
|
:total="total"
|
|
|
|
|
@size-change="handleSizeChange"
|
|
|
|
|
@current-change="handlePageChange"
|
|
|
|
|
/>
|
|
|
|
|
</div>-->
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -763,7 +813,7 @@
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 表单弹窗:弹出设备属性 -->
|
|
|
|
|
<DetailForm ref="detailFormRef" />
|
|
|
|
|
<DetailForm ref="detailFormRef" />
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
@ -849,6 +899,13 @@ const toggleView = () => {
|
|
|
|
|
// 保存视图偏好
|
|
|
|
|
localStorage.setItem('equipment-view', currentView.value)
|
|
|
|
|
}
|
|
|
|
|
// 切回表格
|
|
|
|
|
const changeTable = () => {
|
|
|
|
|
currentView.value = 'table'
|
|
|
|
|
ifShow.value=true;
|
|
|
|
|
// 保存视图偏好
|
|
|
|
|
localStorage.setItem('equipment-view', currentView.value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 物联设备 列表 */
|
|
|
|
|
defineOptions({ name: 'Device' })
|
|
|
|
|
@ -859,6 +916,7 @@ const { t } = useI18n() // 国际化
|
|
|
|
|
const tableRef = ref()
|
|
|
|
|
|
|
|
|
|
const loading = ref(true) // 列表的加载中
|
|
|
|
|
const showDetailForm =ref(true)
|
|
|
|
|
const list = ref<DeviceVO[]>([]) // 列表的数据
|
|
|
|
|
const total = ref(0) // 列表的总页数
|
|
|
|
|
const queryParams = reactive({
|
|
|
|
|
@ -972,6 +1030,24 @@ const openDetailForm = (id?: number,deviceName?:string) => {
|
|
|
|
|
//formRef.value.open(id,deviceName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const enabledChange = (row: DeviceVO, value: boolean) => {
|
|
|
|
|
showDetailForm.value=false
|
|
|
|
|
if (!row.id) return
|
|
|
|
|
const oldValue = (row as any).isEnable
|
|
|
|
|
;(row as any).isEnable = value
|
|
|
|
|
try {
|
|
|
|
|
DeviceApi.updateDeviceEnabled(row.id, value ? 'true' : 'false')
|
|
|
|
|
const name = (row as any).deviceName ?? (row as any).deviceCode ?? ''
|
|
|
|
|
const suffix = value ? '已启用' : '已停用'
|
|
|
|
|
if (name) {
|
|
|
|
|
message.success(`${name}${suffix}`)
|
|
|
|
|
} else {
|
|
|
|
|
message.success(suffix)
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
;(row as any).is
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 删除按钮操作 */
|
|
|
|
|
const buildIdsParam = (ids: number | number[]) => {
|
|
|
|
|
@ -1884,7 +1960,7 @@ const handleShowDeviceAlarmHistory = async () => {
|
|
|
|
|
position: relative;
|
|
|
|
|
border: 1px solid #ebeef5;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
padding: 18px;
|
|
|
|
|
|
|
|
|
|
background-color: #fafafa;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
@ -1940,62 +2016,6 @@ const handleShowDeviceAlarmHistory = async () => {
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-content {
|
|
|
|
|
flex: 1;
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
|
|
.card-title {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #303133;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
margin-left: 50px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-code {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
margin-bottom: 2px;
|
|
|
|
|
margin-left: 50px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-model {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #606266;
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
margin-left: 50px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-status {
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
|
|
|
|
.status-tag {
|
|
|
|
|
width: 50px;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-running {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #606266;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-location {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
|
|
|
|
|
.el-icon {
|
|
|
|
|
color: #909399;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -2069,5 +2089,339 @@ const handleShowDeviceAlarmHistory = async () => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.device-card {
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.header {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 12px 16px;
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-icon {
|
|
|
|
|
width: 40px;
|
|
|
|
|
height: 40px;
|
|
|
|
|
background-color: #f0f7ff;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-info {
|
|
|
|
|
flex: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-name {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #333;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-id {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #999;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.content {
|
|
|
|
|
padding: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-row {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 6px 0;
|
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-label {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
color: #666;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-label i {
|
|
|
|
|
margin-right: 6px;
|
|
|
|
|
color: #1890ff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-value {
|
|
|
|
|
color: #333;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toggle-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 6px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toggle-label {
|
|
|
|
|
color: #666;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toggle-switch {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 44px;
|
|
|
|
|
height: 24px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toggle-switch input {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
width: 0;
|
|
|
|
|
height: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.slider {
|
|
|
|
|
position: absolute;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
background-color: #ccc;
|
|
|
|
|
transition: .4s;
|
|
|
|
|
border-radius: 24px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.slider:before {
|
|
|
|
|
position: absolute;
|
|
|
|
|
content: "";
|
|
|
|
|
height: 18px;
|
|
|
|
|
width: 18px;
|
|
|
|
|
left: 3px;
|
|
|
|
|
bottom: 3px;
|
|
|
|
|
background-color: white;
|
|
|
|
|
transition: .4s;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input:checked + .slider {
|
|
|
|
|
background-color: #1890ff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input:checked + .slider:before {
|
|
|
|
|
transform: translateX(20px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.footer {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
padding: 16px 20px;
|
|
|
|
|
border-top: 1px solid #eee;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.action-btn {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 2px 4px;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
//cursor: pointer;
|
|
|
|
|
border: none;
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn-primary {
|
|
|
|
|
color: #1890ff;
|
|
|
|
|
border: 1px solid #1890ff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn-success {
|
|
|
|
|
color: #28a745;
|
|
|
|
|
border: 1px solid #28a745;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.action-btn i {
|
|
|
|
|
margin-right: 6px;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.action-icons {
|
|
|
|
|
display: flex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-btn {
|
|
|
|
|
width: 32px;
|
|
|
|
|
height: 32px;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
background-color: #f5f7fa;
|
|
|
|
|
color: #666;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 基础样式 */
|
|
|
|
|
.status-badge {
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 4px 10px;
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-dot {
|
|
|
|
|
width: 8px;
|
|
|
|
|
height: 8px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
margin-right: 6px;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 在线状态 */
|
|
|
|
|
.status-online {
|
|
|
|
|
background-color: #e6f7e6;
|
|
|
|
|
color: #67c23a;
|
|
|
|
|
border: 1px solid rgba(40, 167, 69, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-online {
|
|
|
|
|
background-color: #28a745;
|
|
|
|
|
box-shadow: 0 0 4px rgba(40, 167, 69, 0.5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 离线状态 */
|
|
|
|
|
.status-offline {
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
color: #909399;
|
|
|
|
|
border: 1px solid rgba(108, 117, 125, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-offline {
|
|
|
|
|
background-color: #6c757d;
|
|
|
|
|
box-shadow: 0 0 4px rgba(108, 117, 125, 0.3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 运行中 */
|
|
|
|
|
.status-running {
|
|
|
|
|
background-color: #67c23a;
|
|
|
|
|
color: white;
|
|
|
|
|
border: 1px solid rgba(24, 144, 255, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-running {
|
|
|
|
|
background-color: #67c23a;
|
|
|
|
|
animation: pulse 2s infinite;
|
|
|
|
|
box-shadow: 0 0 4px rgba(24, 144, 255, 0.5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes pulse {
|
|
|
|
|
0% { opacity: 1; }
|
|
|
|
|
50% { opacity: 0.5; }
|
|
|
|
|
100% { opacity: 1; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 已停止 */
|
|
|
|
|
.status-stopped {
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
color: #999;
|
|
|
|
|
border: 1px solid rgba(153, 153, 153, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-stopped {
|
|
|
|
|
background-color: #999;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 待机中 */
|
|
|
|
|
.status-standby {
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
color: #999;
|
|
|
|
|
border: 1px solid rgba(153, 153, 153, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-stopped {
|
|
|
|
|
background-color: #999;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 故障 */
|
|
|
|
|
.status-fault {
|
|
|
|
|
background-color: #fde8e8;
|
|
|
|
|
color: #f5222d;
|
|
|
|
|
border: 1px solid rgba(245, 34, 45, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-fault {
|
|
|
|
|
background-color: #f5222d;
|
|
|
|
|
box-shadow: 0 0 4px rgba(245, 34, 45, 0.5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 报警 */
|
|
|
|
|
.status-alarm {
|
|
|
|
|
background-color: #fff7e6;
|
|
|
|
|
color: #fa8c16;
|
|
|
|
|
border: 1px solid rgba(250, 140, 22, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-alarm {
|
|
|
|
|
background-color: #fa8c16;
|
|
|
|
|
animation: blink 1s infinite;
|
|
|
|
|
box-shadow: 0 0 4px rgba(250, 140, 22, 0.5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes blink {
|
|
|
|
|
0%, 100% { opacity: 1; }
|
|
|
|
|
50% { opacity: 0.3; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 维护中 */
|
|
|
|
|
.status-maintenance {
|
|
|
|
|
background-color: #f0f7ff;
|
|
|
|
|
color: #1890ff;
|
|
|
|
|
border: 1px solid rgba(24, 144, 255, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-maintenance {
|
|
|
|
|
background-color: #1890ff;
|
|
|
|
|
animation: maintenance 3s infinite;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes maintenance {
|
|
|
|
|
0%, 100% { transform: scale(1); }
|
|
|
|
|
50% { transform: scale(1.2); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 未启用 */
|
|
|
|
|
.status-disabled {
|
|
|
|
|
background-color: #fafafa;
|
|
|
|
|
color: #bfbfbf;
|
|
|
|
|
border: 1px solid rgba(191, 191, 191, 0.2);
|
|
|
|
|
text-decoration: line-through;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-disabled {
|
|
|
|
|
background-color: #bfbfbf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 默认状态 */
|
|
|
|
|
.status-default {
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
color: #666;
|
|
|
|
|
border: 1px solid rgba(102, 102, 102, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dot-default {
|
|
|
|
|
background-color: #666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|
|