|
|
|
|
@ -1,6 +1,29 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="app-container">
|
|
|
|
|
<el-form :model="queryParams" ref="queryFormRef" size="small" :inline="true" v-show="showSearch" label-width="100px">
|
|
|
|
|
<div class="app-container page-shell">
|
|
|
|
|
<section class="page-hero">
|
|
|
|
|
<div class="hero-copy">
|
|
|
|
|
<span class="hero-eyebrow">IOT DEVICE CENTER</span>
|
|
|
|
|
<h2 class="hero-title">计量设备与阈值联动看板</h2>
|
|
|
|
|
<p class="hero-desc">围绕点位档案、安装位置与采集接入做统一可视化整理,让运维在同一页面快速完成查询、维护与阈值联动。</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="hero-stats">
|
|
|
|
|
<article v-for="item in overviewStats" :key="item.label" class="stat-card">
|
|
|
|
|
<span class="stat-label">{{ item.label }}</span>
|
|
|
|
|
<strong class="stat-value">{{ item.value }}</strong>
|
|
|
|
|
<span class="stat-hint">{{ item.hint }}</span>
|
|
|
|
|
</article>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section v-show="showSearch" class="panel-shell search-shell">
|
|
|
|
|
<div class="panel-head">
|
|
|
|
|
<div>
|
|
|
|
|
<h3>快速筛选</h3>
|
|
|
|
|
<p>按设备、能源类型、状态和安装位置快速定位目标点位。</p>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="panel-badge">档案检索</span>
|
|
|
|
|
</div>
|
|
|
|
|
<el-form :model="queryParams" ref="queryFormRef" size="small" :inline="true" label-width="100px" class="query-form">
|
|
|
|
|
<!-- <el-form-item label="计量设备编号" prop="monitorCode">-->
|
|
|
|
|
<!-- <el-input v-model="queryParams.monitorCode" placeholder="请输入计量设备编号" clearable-->
|
|
|
|
|
<!-- @keyup.enter="handleQuery" />-->
|
|
|
|
|
@ -37,13 +60,23 @@
|
|
|
|
|
<!-- <el-option v-for="dict in dict.type.is_ammeter" :key="dict.value" :label="dict.label" :value="dict.value" />-->
|
|
|
|
|
<!-- </el-select>-->
|
|
|
|
|
<!-- </el-form-item>-->
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-form-item class="query-actions">
|
|
|
|
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
|
|
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<el-row :gutter="10" class="mb8">
|
|
|
|
|
<section class="panel-shell table-shell">
|
|
|
|
|
<div class="panel-head">
|
|
|
|
|
<div>
|
|
|
|
|
<h3>设备结构总览</h3>
|
|
|
|
|
<p>树形结构展示设备层级,支持直接维护阈值、档案与挂接关系。</p>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="panel-badge warm">树形维护</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<el-row :gutter="10" class="toolbar-row">
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['ems/base:baseMonitorInfo:add']"
|
|
|
|
|
>新增</el-button
|
|
|
|
|
@ -62,6 +95,7 @@
|
|
|
|
|
row-key="objId"
|
|
|
|
|
:default-expand-all="isExpandAll"
|
|
|
|
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
|
|
|
|
class="data-table"
|
|
|
|
|
>
|
|
|
|
|
<el-table-column label="序号" type="index" width="60" align="center" v-if="columns[0].visible" />
|
|
|
|
|
<el-table-column label="计量设备编号" align="center" prop="monitorCode" v-if="columns[1].visible" />
|
|
|
|
|
@ -135,10 +169,15 @@
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 添加或修改计量设备信息对话框 -->
|
|
|
|
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
|
|
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
|
|
|
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body class="themed-dialog">
|
|
|
|
|
<div class="dialog-tip">
|
|
|
|
|
<span class="tip-dot"></span>
|
|
|
|
|
设备档案字段较多,这里按业务主数据录入,隐藏技术字段继续保留在提交链路中,避免影响 EMS 现有流程。
|
|
|
|
|
</div>
|
|
|
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" class="dialog-form">
|
|
|
|
|
<el-form-item label="父级编号" prop="parentId">
|
|
|
|
|
<EmsTreeSelect v-model="form.parentId" :options="baseMonitorInfoOptions" :normalizer="normalizer" placeholder="请选择父级编号" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -253,7 +292,7 @@
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 阈值管理对话框 -->
|
|
|
|
|
<el-dialog :title="thresholdTitle" v-model="thresholdOpen" width="1200px" append-to-body>
|
|
|
|
|
<el-dialog :title="thresholdTitle" v-model="thresholdOpen" width="1200px" append-to-body class="themed-dialog threshold-dialog">
|
|
|
|
|
<div class="threshold-container">
|
|
|
|
|
<!-- 设备信息展示 -->
|
|
|
|
|
<el-card class="device-info-card" shadow="never">
|
|
|
|
|
@ -339,8 +378,12 @@
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 阈值规则编辑对话框 -->
|
|
|
|
|
<el-dialog :title="thresholdFormTitle" v-model="thresholdFormOpen" width="500px" append-to-body>
|
|
|
|
|
<el-form ref="thresholdFormRef" :model="thresholdForm" :rules="thresholdRules" label-width="120px">
|
|
|
|
|
<el-dialog :title="thresholdFormTitle" v-model="thresholdFormOpen" width="500px" append-to-body class="themed-dialog">
|
|
|
|
|
<div class="dialog-tip soft">
|
|
|
|
|
<span class="tip-dot"></span>
|
|
|
|
|
阈值规则与点位技术字段自动联动,页面只暴露运维真正需要维护的业务项,减少误配概率。
|
|
|
|
|
</div>
|
|
|
|
|
<el-form ref="thresholdFormRef" :model="thresholdForm" :rules="thresholdRules" label-width="120px" class="dialog-form">
|
|
|
|
|
<el-form-item label="规则名称" prop="ruleName">
|
|
|
|
|
<el-input v-model="thresholdForm.ruleName" placeholder="请输入规则名称" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -777,6 +820,50 @@ const {
|
|
|
|
|
title
|
|
|
|
|
} = toRefs(state);
|
|
|
|
|
|
|
|
|
|
const flattenDeviceTree = (nodes = []) => {
|
|
|
|
|
return nodes.reduce((acc, node) => {
|
|
|
|
|
acc.push(node);
|
|
|
|
|
if (node.children?.length) {
|
|
|
|
|
acc.push(...flattenDeviceTree(node.children));
|
|
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
}, []);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const flatDeviceList = computed(() => flattenDeviceTree(baseMonitorInfoList.value));
|
|
|
|
|
|
|
|
|
|
// 这里用展示型统计卡强化运维感知,不参与任何接口入参与业务判断,确保只提升视觉层体验。
|
|
|
|
|
const overviewStats = computed(() => {
|
|
|
|
|
const devices = flatDeviceList.value;
|
|
|
|
|
const total = devices.length;
|
|
|
|
|
const withCollector = devices.filter((item) => item.collectDeviceId || item.collectDeviceName).length;
|
|
|
|
|
const withLocation = devices.filter((item) => item.locationName).length;
|
|
|
|
|
const withSensor = devices.filter((item) => item.sensorType).length;
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
label: '设备总量',
|
|
|
|
|
value: total,
|
|
|
|
|
hint: '当前树形档案节点'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: '已挂接采集',
|
|
|
|
|
value: withCollector,
|
|
|
|
|
hint: '已关联采集设备'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: '位置已维护',
|
|
|
|
|
value: withLocation,
|
|
|
|
|
hint: '安装位置信息完整'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: '传感已标注',
|
|
|
|
|
value: withSensor,
|
|
|
|
|
hint: '便于运维识别类型'
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const getMonitorTypeLabel = (monitorType) => {
|
|
|
|
|
if (!monitorType || !dict.type.monitor_type) {
|
|
|
|
|
return '未设置';
|
|
|
|
|
@ -1023,7 +1110,8 @@ const resetThresholdForm = () => {
|
|
|
|
|
hysteresis: null,
|
|
|
|
|
durationSec: null,
|
|
|
|
|
alarmLevel: null,
|
|
|
|
|
notifyGroupId: null,
|
|
|
|
|
// 阈值初始化时不再前置通知组,避免配置页继续透出扩展通知能力。
|
|
|
|
|
// notifyGroupId: null,
|
|
|
|
|
isEnable: '0'
|
|
|
|
|
};
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
@ -1044,34 +1132,267 @@ onMounted(() => {
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
.page-shell {
|
|
|
|
|
min-height: 100%;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
background:
|
|
|
|
|
radial-gradient(circle at top left, rgba(14, 165, 233, 0.18), transparent 32%),
|
|
|
|
|
radial-gradient(circle at top right, rgba(34, 197, 94, 0.14), transparent 28%), linear-gradient(180deg, #f3f8ff 0%, #eef4f7 48%, #f7f9fc 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.page-hero {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: minmax(0, 1.35fr) minmax(320px, 1fr);
|
|
|
|
|
gap: 18px;
|
|
|
|
|
margin-bottom: 18px;
|
|
|
|
|
padding: 28px 30px;
|
|
|
|
|
border-radius: 28px;
|
|
|
|
|
background: linear-gradient(135deg, rgba(7, 63, 86, 0.96) 0%, rgba(16, 106, 125, 0.92) 52%, rgba(40, 166, 146, 0.9) 100%);
|
|
|
|
|
box-shadow: 0 24px 50px rgba(17, 75, 95, 0.18);
|
|
|
|
|
color: #fff;
|
|
|
|
|
position: relative;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.page-hero::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
inset: auto -100px -120px auto;
|
|
|
|
|
width: 260px;
|
|
|
|
|
height: 260px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
background: rgba(255, 255, 255, 0.08);
|
|
|
|
|
filter: blur(4px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-copy {
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-eyebrow {
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
padding: 6px 12px;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
background: rgba(255, 255, 255, 0.12);
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
letter-spacing: 0.18em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-title {
|
|
|
|
|
margin: 18px 0 12px;
|
|
|
|
|
font-size: 30px;
|
|
|
|
|
line-height: 1.2;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-desc {
|
|
|
|
|
max-width: 700px;
|
|
|
|
|
margin: 0;
|
|
|
|
|
color: rgba(255, 255, 255, 0.82);
|
|
|
|
|
line-height: 1.75;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-stats {
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
gap: 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-card {
|
|
|
|
|
padding: 18px;
|
|
|
|
|
border-radius: 22px;
|
|
|
|
|
background: rgba(255, 255, 255, 0.12);
|
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.16);
|
|
|
|
|
backdrop-filter: blur(10px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-label,
|
|
|
|
|
.stat-hint {
|
|
|
|
|
display: block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-label {
|
|
|
|
|
color: rgba(255, 255, 255, 0.7);
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-value {
|
|
|
|
|
display: block;
|
|
|
|
|
margin: 10px 0 8px;
|
|
|
|
|
font-size: 30px;
|
|
|
|
|
line-height: 1;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-hint {
|
|
|
|
|
color: rgba(255, 255, 255, 0.7);
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel-shell {
|
|
|
|
|
margin-bottom: 18px;
|
|
|
|
|
padding: 20px 22px;
|
|
|
|
|
border: 1px solid rgba(199, 211, 223, 0.55);
|
|
|
|
|
border-radius: 24px;
|
|
|
|
|
background: rgba(255, 255, 255, 0.84);
|
|
|
|
|
box-shadow: 0 18px 40px rgba(42, 63, 95, 0.08);
|
|
|
|
|
backdrop-filter: blur(14px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel-head {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 18px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel-head h3 {
|
|
|
|
|
margin: 0 0 6px;
|
|
|
|
|
color: #163047;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel-head p {
|
|
|
|
|
margin: 0;
|
|
|
|
|
color: #6b7a90;
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel-badge {
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 8px 14px;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
background: linear-gradient(135deg, #dbeafe, #ecfeff);
|
|
|
|
|
color: #0f5f8d;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel-badge.warm {
|
|
|
|
|
background: linear-gradient(135deg, #fef3c7, #ffedd5);
|
|
|
|
|
color: #a16207;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.query-form {
|
|
|
|
|
padding: 18px;
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
background: linear-gradient(180deg, rgba(248, 251, 255, 0.96) 0%, rgba(255, 255, 255, 0.92) 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.query-actions {
|
|
|
|
|
:deep(.el-form-item__content) {
|
|
|
|
|
gap: 10px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toolbar-row {
|
|
|
|
|
margin-bottom: 14px;
|
|
|
|
|
padding: 14px 16px;
|
|
|
|
|
border-radius: 18px;
|
|
|
|
|
background: linear-gradient(90deg, rgba(16, 185, 129, 0.08), rgba(59, 130, 246, 0.08));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.data-table {
|
|
|
|
|
:deep(.el-table) {
|
|
|
|
|
--el-table-border-color: rgba(208, 219, 229, 0.7);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.el-table__header-wrapper th) {
|
|
|
|
|
background: #f4f9ff;
|
|
|
|
|
color: #17324a;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.el-table__row td) {
|
|
|
|
|
transition: background-color 0.2s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.el-table__body tr:hover > td) {
|
|
|
|
|
background: rgba(37, 99, 235, 0.06) !important;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dialog-tip {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
margin-bottom: 18px;
|
|
|
|
|
padding: 12px 14px;
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
background: linear-gradient(90deg, rgba(14, 165, 233, 0.1), rgba(16, 185, 129, 0.08));
|
|
|
|
|
color: #28506c;
|
|
|
|
|
line-height: 1.65;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dialog-tip.soft {
|
|
|
|
|
background: linear-gradient(90deg, rgba(59, 130, 246, 0.08), rgba(244, 114, 182, 0.08));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tip-dot {
|
|
|
|
|
width: 10px;
|
|
|
|
|
height: 10px;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
background: linear-gradient(135deg, #0ea5e9, #22c55e);
|
|
|
|
|
box-shadow: 0 0 0 5px rgba(14, 165, 233, 0.12);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dialog-form {
|
|
|
|
|
padding: 18px;
|
|
|
|
|
border-radius: 18px;
|
|
|
|
|
background: #f9fbff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.threshold-container {
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-info-card,
|
|
|
|
|
.threshold-rules-card {
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 22px;
|
|
|
|
|
background: linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
|
|
|
|
|
box-shadow: 0 16px 30px rgba(42, 63, 95, 0.08);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-info-card {
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-info-card .el-card__body {
|
|
|
|
|
padding: 15px;
|
|
|
|
|
.device-info-card :deep(.el-card__header),
|
|
|
|
|
.threshold-rules-card :deep(.el-card__header) {
|
|
|
|
|
padding: 18px 20px;
|
|
|
|
|
border-bottom: 1px solid rgba(208, 219, 229, 0.75);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.threshold-rules-card .el-card__body {
|
|
|
|
|
padding: 15px;
|
|
|
|
|
.device-info-card :deep(.el-card__body),
|
|
|
|
|
.threshold-rules-card :deep(.el-card__body) {
|
|
|
|
|
padding: 18px 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-item {
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
padding: 14px 16px;
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
background: linear-gradient(135deg, #f7fbff, #f2f7f6);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-item .label {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: #606266;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
color: #66758d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info-item .value {
|
|
|
|
|
color: #303133;
|
|
|
|
|
color: #17324a;
|
|
|
|
|
margin-left: 5px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1084,4 +1405,61 @@ onMounted(() => {
|
|
|
|
|
.clearfix:after {
|
|
|
|
|
clear: both;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.themed-dialog .el-dialog) {
|
|
|
|
|
border-radius: 26px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
box-shadow: 0 28px 60px rgba(15, 23, 42, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.themed-dialog .el-dialog__header) {
|
|
|
|
|
padding: 22px 24px 14px;
|
|
|
|
|
background: linear-gradient(135deg, rgba(11, 94, 129, 0.96), rgba(26, 142, 126, 0.92));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.themed-dialog .el-dialog__title),
|
|
|
|
|
:deep(.themed-dialog .el-dialog__headerbtn .el-dialog__close) {
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.themed-dialog .el-dialog__body) {
|
|
|
|
|
padding: 22px 24px;
|
|
|
|
|
background: linear-gradient(180deg, #f8fbff 0%, #ffffff 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.themed-dialog .el-dialog__footer) {
|
|
|
|
|
padding: 0 24px 24px;
|
|
|
|
|
background: linear-gradient(180deg, #ffffff 0%, #f8fbff 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 992px) {
|
|
|
|
|
.page-hero {
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-stats {
|
|
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
.page-shell {
|
|
|
|
|
padding: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.page-hero,
|
|
|
|
|
.panel-shell {
|
|
|
|
|
padding: 18px;
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.panel-head {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hero-stats {
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|