<!DOCTYPE html>
|
<html lang="zh-CN">
|
<head>
|
<meta charset="utf-8">
|
<title>站点颜色配置</title>
|
<meta name="renderer" content="webkit">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<link rel="stylesheet" href="../../static/vue/element/element.css">
|
<link rel="stylesheet" href="../../static/css/cool.css">
|
<style>
|
html, body {
|
height: 100%;
|
margin: 0;
|
background:
|
radial-gradient(circle at top left, rgba(70, 136, 214, 0.14), transparent 34%),
|
radial-gradient(circle at bottom right, rgba(37, 198, 178, 0.12), transparent 28%),
|
linear-gradient(180deg, #eef4fa 0%, #e8eef5 100%);
|
}
|
body {
|
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
|
}
|
[v-cloak] {
|
display: none;
|
}
|
#app {
|
height: 100%;
|
padding: 22px;
|
box-sizing: border-box;
|
display: flex;
|
flex-direction: column;
|
gap: 16px;
|
}
|
.page-hero {
|
padding: 22px 24px;
|
border-radius: 20px;
|
border: 1px solid rgba(255, 255, 255, 0.78);
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.92), rgba(244, 249, 255, 0.82));
|
box-shadow: 0 18px 50px rgba(48, 74, 104, 0.08);
|
}
|
.page-title {
|
font-size: 26px;
|
font-weight: 700;
|
color: #223548;
|
letter-spacing: 0.01em;
|
}
|
.page-subtitle {
|
margin-top: 8px;
|
max-width: 860px;
|
font-size: 13px;
|
line-height: 1.8;
|
color: #66788c;
|
}
|
.page-panel {
|
flex: 1;
|
min-height: 0;
|
display: flex;
|
flex-direction: column;
|
border-radius: 22px;
|
border: 1px solid rgba(221, 231, 242, 0.92);
|
background: rgba(251, 253, 255, 0.88);
|
box-shadow: 0 20px 48px rgba(49, 76, 106, 0.08);
|
overflow: hidden;
|
}
|
.panel-toolbar {
|
padding: 18px 22px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 12px;
|
border-bottom: 1px solid rgba(224, 233, 244, 0.9);
|
background: rgba(255, 255, 255, 0.72);
|
}
|
.panel-tip {
|
font-size: 12px;
|
color: #74879b;
|
line-height: 1.8;
|
}
|
.color-grid {
|
flex: 1;
|
min-height: 0;
|
padding: 20px 22px 24px;
|
overflow: auto;
|
display: grid;
|
grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
|
grid-auto-rows: max-content;
|
align-content: start;
|
gap: 16px;
|
}
|
.color-card {
|
position: relative;
|
border-radius: 18px;
|
border: 1px solid rgba(223, 232, 242, 0.94);
|
background: linear-gradient(180deg, rgba(255,255,255,0.96), rgba(246,250,255,0.92));
|
box-shadow: 0 12px 28px rgba(76, 101, 130, 0.07);
|
padding: 16px;
|
display: flex;
|
flex-direction: column;
|
gap: 10px;
|
overflow: visible;
|
}
|
.color-card::after {
|
content: "";
|
position: absolute;
|
top: -30px;
|
right: -20px;
|
width: 120px;
|
height: 120px;
|
border-radius: 50%;
|
background: rgba(255,255,255,0.42);
|
pointer-events: none;
|
}
|
.color-card-head {
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
gap: 14px;
|
}
|
.color-name {
|
font-size: 16px;
|
font-weight: 700;
|
color: #24374a;
|
}
|
.color-status {
|
margin-top: 4px;
|
font-size: 12px;
|
color: #7a8da2;
|
word-break: break-all;
|
}
|
.color-chip {
|
width: 58px;
|
height: 58px;
|
border-radius: 18px;
|
border: 1px solid rgba(89, 109, 134, 0.18);
|
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.46);
|
flex-shrink: 0;
|
}
|
.color-desc {
|
font-size: 12px;
|
line-height: 1.8;
|
color: #66798d;
|
}
|
.color-editor {
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
}
|
.color-picker-inline {
|
flex-shrink: 0;
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
padding: 0 10px;
|
height: 40px;
|
border-radius: 12px;
|
border: 1px solid rgba(214, 225, 238, 0.95);
|
background: rgba(247, 250, 255, 0.9);
|
color: #567089;
|
font-size: 12px;
|
font-weight: 600;
|
}
|
.color-actions {
|
display: flex;
|
justify-content: flex-end;
|
}
|
.color-default {
|
font-size: 12px;
|
color: #7890a8;
|
}
|
.color-meta {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 10px;
|
}
|
.empty-state {
|
padding: 60px 20px;
|
text-align: center;
|
color: #7b8c9f;
|
font-size: 14px;
|
}
|
.footer-note {
|
padding: 0 22px 18px;
|
font-size: 12px;
|
color: #8696a8;
|
}
|
.el-color-picker__trigger {
|
width: 52px;
|
height: 40px;
|
padding: 0;
|
border-radius: 12px;
|
border-color: rgba(211, 223, 237, 0.95);
|
background: #fff;
|
}
|
.el-input__inner {
|
border-radius: 12px;
|
height: 40px;
|
line-height: 40px;
|
}
|
.el-button + .el-button {
|
margin-left: 10px;
|
}
|
@media (max-width: 900px) {
|
#app {
|
padding: 14px;
|
}
|
.page-hero,
|
.panel-toolbar,
|
.color-grid,
|
.footer-note {
|
padding-left: 16px;
|
padding-right: 16px;
|
}
|
.color-editor,
|
.color-meta {
|
flex-wrap: wrap;
|
}
|
}
|
</style>
|
</head>
|
<body>
|
<div id="app" v-cloak>
|
<div class="page-hero">
|
<div class="page-title">站点颜色配置</div>
|
<div class="page-subtitle">
|
单独维护监控地图里站点状态的显示颜色。颜色通过调色盘任意选择,配置保存在 Redis 中;
|
未配置时默认使用当前地图代码里的颜色值。
|
</div>
|
</div>
|
|
<div class="page-panel">
|
<div class="panel-toolbar">
|
<div class="panel-tip">
|
建议让“启动入库 / 入库任务 / 出库任务 / 堵塞”保持明显区分,避免现场值守时误判。
|
</div>
|
<div>
|
<el-button size="small" @click="reloadData" :loading="loading">刷新</el-button>
|
<el-button size="small" @click="resetDefaults">恢复默认</el-button>
|
<el-button type="primary" size="small" @click="saveConfig" :loading="saving">保存配置</el-button>
|
</div>
|
</div>
|
|
<div v-if="items.length" class="color-grid">
|
<div v-for="item in items" :key="item.status" class="color-card">
|
<div class="color-card-head">
|
<div>
|
<div class="color-name">{{ item.name }}</div>
|
<div class="color-status">{{ item.status }}</div>
|
</div>
|
<div class="color-chip" :style="{ backgroundColor: item.color }"></div>
|
</div>
|
|
<div class="color-desc">{{ item.desc }}</div>
|
|
<div class="color-editor">
|
<div class="color-picker-inline">
|
<el-color-picker
|
v-model="item.color"
|
:predefine="predefineColors"
|
></el-color-picker>
|
<span>调色盘</span>
|
</div>
|
<el-input
|
v-model="item.color"
|
@change="handleColorInput(item)"
|
placeholder="#FFFFFF"
|
></el-input>
|
</div>
|
|
<div class="color-meta">
|
<div class="color-default">默认值:{{ item.defaultColor }}</div>
|
<div class="color-actions">
|
<el-button size="mini" @click="applyDefaultColor(item)">恢复默认</el-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div v-else class="empty-state">暂无站点颜色配置项</div>
|
|
<div class="footer-note">保存后,新打开的监控地图会直接读取 Redis 配置;已打开页面刷新后即可生效。</div>
|
</div>
|
</div>
|
|
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
|
<script type="text/javascript" src="../../static/vue/js/vue.min.js"></script>
|
<script type="text/javascript" src="../../static/vue/element/element.js"></script>
|
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
|
<script type="text/javascript" src="../../static/js/watch/stationColorConfig.js" charset="utf-8"></script>
|
</body>
|
</html>
|