Compare commits
3 Commits
2de3df56bd
...
0b14441b71
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b14441b71 | |||
| 3784fc87f4 | |||
| fe08137ea1 |
94
README.md
94
README.md
|
|
@ -1,49 +1,67 @@
|
|||
DEMO
|
||||
===========================
|
||||
# 预警系统 (pre-warning-system)
|
||||
|
||||
###########环境依赖
|
||||
node.js
|
||||
基于Vue 3 + Vite构建的仓库预警管理系统,提供实时监控、数据可视化和异常预警功能。
|
||||
|
||||
###########部署步骤
|
||||
1. 添加系统环境变量
|
||||
export $PORTAL_VERSION="production" // production, test, dev
|
||||
## 功能特点
|
||||
- 实时数据监控仪表盘
|
||||
- 多维度数据可视化图表
|
||||
- 异常事件预警与通知
|
||||
- 历史数据查询与分析
|
||||
- 用户权限管理
|
||||
|
||||
## 技术栈
|
||||
- **前端框架**: Vue 3 (Composition API + <script setup>)
|
||||
- **构建工具**: Vite
|
||||
- **路由管理**: Vue Router
|
||||
- **状态管理**: Vuex
|
||||
- **UI组件**: element-plus (v2.10.1) 和 tdesign-vue-next (v1.13.2)
|
||||
- **图表可视化**: echarts (v5.6.0) 和 @antv/g6 (v4.8.24)
|
||||
|
||||
2. npm install //安装node运行环境
|
||||
## 项目结构
|
||||
```
|
||||
/src
|
||||
/views # 页面组件
|
||||
/components # 通用组件
|
||||
/router # 路由配置
|
||||
/store # 状态管理
|
||||
/assets # 静态资源
|
||||
/escel # 数据文件
|
||||
```
|
||||
|
||||
3. npm run dev //前端编译
|
||||
## 安装与启动
|
||||
|
||||
4. 启动两个配置(已forever为例)
|
||||
eg: forever start app-service.js
|
||||
forever start logger-service.js
|
||||
### 环境要求
|
||||
- Node.js 14.0.0+
|
||||
- npm 6.0.0+ 或 yarn 1.22.0+
|
||||
|
||||
### 安装依赖
|
||||
```bash
|
||||
npm install
|
||||
# 或
|
||||
yarn install
|
||||
```
|
||||
|
||||
###########目录结构描述
|
||||
├── Readme.md // help
|
||||
├── app // 应用
|
||||
├── config // 配置
|
||||
│ ├── default.json
|
||||
│ ├── dev.json // 开发环境
|
||||
│ ├── experiment.json // 实验
|
||||
│ ├── index.js // 配置控制
|
||||
│ ├── local.json // 本地
|
||||
│ ├── production.json // 生产环境
|
||||
│ └── test.json // 测试环境
|
||||
├── data
|
||||
├── doc // 文档
|
||||
├── environment
|
||||
├── gulpfile.js
|
||||
├── locales
|
||||
├── logger-service.js // 启动日志配置
|
||||
├── node_modules
|
||||
├── package.json
|
||||
├── app-service.js // 启动应用配置
|
||||
├── static // web静态资源加载
|
||||
│ └── initjson
|
||||
│ └── config.js // 提供给前端的配置
|
||||
├── test
|
||||
├── test-service.js
|
||||
└── tools
|
||||
### 开发环境启动
|
||||
```bash
|
||||
npm run dev
|
||||
# 或
|
||||
yarn dev
|
||||
```
|
||||
|
||||
### 生产环境构建
|
||||
```bash
|
||||
npm run build
|
||||
# 或
|
||||
yarn build
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
系统配置文件位于 `src/config` 目录下,可根据实际需求修改API地址、预警阈值等参数。
|
||||
|
||||
## 数据导入
|
||||
1. 将数据文件放入 `/escel` 目录
|
||||
2. 在系统设置中选择导入对应文件
|
||||
3. 系统将自动解析并更新数据库
|
||||
|
||||
## 许可证
|
||||
[MIT](LICENSE)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
<template>
|
||||
<div :class="containerClass" ref="scrollContainer">
|
||||
<div v-for="(item, index) in displayData" :key="index" class="containner4-data"
|
||||
:class="{ 'temporary-style': item.showTemporaryStyle }">
|
||||
<img :src="item.avatar" alt="人物头像" />
|
||||
<p1 style="margin-left: 10px;">{{ item.commenter }}</p1>
|
||||
<p style="margin-left: 10px;">{{ item.comment }}</p>
|
||||
<div class="scroll-content">
|
||||
<div v-for="(item, index) in displayData" :key="index" class="containner4-data"
|
||||
:class="{ 'temporary-style': item.showTemporaryStyle }">
|
||||
<img :src="item.avatar" alt="人物头像" />
|
||||
<div class="data-content">
|
||||
<div class="commenter">{{ item.commenter }}</div>
|
||||
<div class="comment">{{ item.comment }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -42,7 +46,6 @@ const initDisplayData = () => {
|
|||
// 开始自动滚动
|
||||
const startAutoScroll = () => {
|
||||
if (!scrollContainer.value) return;
|
||||
|
||||
scrollTimer.value = setInterval(() => {
|
||||
scrollContainer.value.scrollTop += 1;
|
||||
if (scrollContainer.value.scrollTop >= scrollContainer.value.scrollHeight / 2) {
|
||||
|
|
@ -93,32 +96,91 @@ onBeforeUnmount(() => {
|
|||
|
||||
<style scoped>
|
||||
.containner4-alldata {
|
||||
height: 330px;
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
font-weight: 300;
|
||||
height: 300px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 15px;
|
||||
background-color: rgba(4, 20, 33, 0.5);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.containner4-alldata::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
.containner4-alldata::-webkit-scrollbar-track {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.containner4-alldata::-webkit-scrollbar-thumb {
|
||||
background: rgba(78, 162, 245, 0.5);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.containner4-alldata::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(78, 162, 245, 0.8);
|
||||
}
|
||||
|
||||
.scroll-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.containner4-data {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
font-family: "PingFang SC";
|
||||
color: #E1F4FF;
|
||||
font-family: "PingFang SC", sans-serif;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 00;
|
||||
line-height: normal;
|
||||
font-weight: 200;
|
||||
line-height: 22px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
letter-spacing: 0.14px;
|
||||
margin-left: 25px;
|
||||
margin-top: 25px;
|
||||
background-image: linear-gradient(to right,#4ea2f599, #646464);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
background-image: linear-gradient(135deg, #4ea2f566, #1C588F66);
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.containner4-alldata .text-content {
|
||||
margin-left: 100px;
|
||||
}
|
||||
.containner4-data img{
|
||||
width: 24px;
|
||||
height: px;
|
||||
border-radius:88px ;
|
||||
margin-top: 10px;
|
||||
margin-left: 10px;
|
||||
width: 90%;
|
||||
max-width: 90%;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid rgba(78, 162, 245, 0.3);
|
||||
}
|
||||
|
||||
.containner4-data:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(78, 162, 245, 0.3);
|
||||
background-image: linear-gradient(135deg, #4ea2f588, #1C588F88);
|
||||
}
|
||||
|
||||
.containner4-data img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
margin-right: 12px;
|
||||
object-fit: cover;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.data-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.commenter {
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.comment {
|
||||
font-size: 13px;
|
||||
color: rgba(225, 244, 255, 0.9);
|
||||
max-width: 80%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,23 +2,15 @@
|
|||
<template>
|
||||
<div style="width: 100%; height: 100%;">
|
||||
<div class="graph-box" id="graph-container"></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="slider-box">
|
||||
<div class="slider-container">
|
||||
<div class="play-controls">
|
||||
<button @click="togglePlay" class="play-button">
|
||||
{{ isPlaying ? '暂停' : '播放' }}
|
||||
</button>
|
||||
</div>
|
||||
<el-slider style="" v-model="state.sliderValue" @input="sliderChange" :marks="state.marks" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import axios from "axios";
|
||||
import { onMounted,onUnmounted, reactive,ref } from "vue";
|
||||
|
|
@ -27,7 +19,6 @@ import { ElLoading } from 'element-plus';
|
|||
|
||||
const isPlaying = ref(false);
|
||||
const playTimer = ref(null);
|
||||
|
||||
const state = reactive({
|
||||
graph: null,
|
||||
marks: {
|
||||
|
|
@ -65,15 +56,6 @@ const setStateSliderValue = (value) => {
|
|||
sliderChange(value);
|
||||
};
|
||||
|
||||
// 自动播放相关方法
|
||||
const togglePlay = () => {
|
||||
if (isPlaying.value) {
|
||||
stopAutoPlay();
|
||||
} else {
|
||||
startAutoPlay();
|
||||
}
|
||||
};
|
||||
|
||||
const startAutoPlay = () => {
|
||||
isPlaying.value = true;
|
||||
// 获取排序后的mark键
|
||||
|
|
@ -84,13 +66,12 @@ const startAutoPlay = () => {
|
|||
if (currentIndex < markKeys.length - 1) {
|
||||
currentIndex++;
|
||||
} else {
|
||||
stopAutoPlay();
|
||||
return;
|
||||
currentIndex = 0; // 滑到最后重置
|
||||
}
|
||||
const nextValue = markKeys[currentIndex];
|
||||
state.sliderValue = nextValue;
|
||||
sliderChange(nextValue);
|
||||
}, 3000); // 3秒切换一次
|
||||
sliderChange(nextValue, true); // 传入isAuto参数标记为自动触发
|
||||
}, 6000); // 6秒切换一次
|
||||
};
|
||||
|
||||
const stopAutoPlay = () => {
|
||||
|
|
@ -101,16 +82,17 @@ const stopAutoPlay = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const sliderChange = (val) => {
|
||||
const sliderChange = (val, isAuto = false) => {
|
||||
// 拖动时暂停自动播放
|
||||
if (isPlaying.value) {
|
||||
stopAutoPlay();
|
||||
}
|
||||
if (state.marks[val]) {
|
||||
// 只有手动操作时才暂停自动播放
|
||||
if (!isAuto && isPlaying.value) {
|
||||
stopAutoPlay();
|
||||
}
|
||||
|
||||
if (state.marks[val]) {
|
||||
getData(state.marks[val]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 根据日期获取图谱数据
|
||||
|
|
@ -222,6 +204,7 @@ onUnmounted(() => {
|
|||
});
|
||||
|
||||
onMounted(() => {
|
||||
startAutoPlay(); // 页面加载时自动开始滑动
|
||||
getData('2024-01-03')
|
||||
})
|
||||
</script>
|
||||
|
|
@ -260,9 +243,11 @@ onMounted(() => {
|
|||
.slider-box {
|
||||
flex: 1;
|
||||
margin-top: 0;
|
||||
width: 90%;
|
||||
width: 95%;
|
||||
margin-top: -230px;
|
||||
margin-left: 10px;
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
<div class="tooltip-containner-data">
|
||||
<li><img :src="currentItem.img" alt="" style=""></li>
|
||||
<li v-if="currentItem.title.includes('中国海警首次登检菲律宾运补船只')"><chart32_-inspection /></li>
|
||||
<<<<<<< HEAD
|
||||
<li v-else-if="currentItem.title.includes('中方回应菲称我海警挥舞刀具')"> <Chart33_WavingBlades /></li>
|
||||
<li v-else-if="currentItem.title.includes('中国海警夺回菲方盗窃赃物')"><Chart34_RecoveredGoods /></li>
|
||||
<li v-else-if="currentItem.title.includes('菲自曝被中国海警缴枪的是顶级特种部队')"><Chart35_SpecialForces /></li>
|
||||
|
|
@ -16,22 +15,11 @@
|
|||
<li style="margin-left: 10px; margin-top:20px;"><img src="../assets/images/logo/point.png"
|
||||
alt="" style="margin-bottom: -7px;">最初首发者: {{ currentItem.earler }} </li>
|
||||
<li style="margin-left: 10px;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">积极评论者:{{ currentItem.comenter
|
||||
=======
|
||||
<li v-else-if="currentItem.title.includes('中方回应菲称我海警挥舞刀具')">
|
||||
<Chart33_WavingBlades />
|
||||
</li>
|
||||
<li v-else-if="currentItem.title.includes('中国海警夺回菲方盗窃赃物')">
|
||||
<Chart34_RecoveredGoods />
|
||||
</li>
|
||||
<li style="margin-left: 10px; margin-top: 20px;"><img src="../assets/images/logo/point.png"
|
||||
alt="">最初首发者: {{ currentItem.earler }} </li>
|
||||
<li style="margin-left: 10px;"><img src="../assets/images/logo/point.png" alt="">积极评论者:{{ currentItem.comenter
|
||||
>>>>>>> 33171231818e20d0f810df4ae56f3620727af4df
|
||||
}}</li>
|
||||
<li style="margin-left: 200px;margin-top: -45px;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">锚点用户{{
|
||||
currentItem.keyuser }}</li>
|
||||
<li style="margin-left: 200px;;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">积极转发者: {{
|
||||
<li style="margin-left: 220px;margin-top: -45px;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">积极转发者:{{
|
||||
currentItem.switcher }}</li>
|
||||
<li style="margin-left: 220px;;"><img src="../assets/images/logo/point.png" alt="" style="margin-bottom: -7px;">锚点用户: {{
|
||||
currentItem.keyuser}}</li>
|
||||
</div>
|
||||
<img src="../assets/images/logo/cancel.png" alt=""
|
||||
style="float: right;margin-right: 10px;margin-top: -520px;cursor: pointer;" @click="showTooltip = false">
|
||||
|
|
@ -122,12 +110,10 @@
|
|||
</div>
|
||||
<div class="suggestion-containner">
|
||||
<ul>
|
||||
<!-- 只显示第一个按钮 -->
|
||||
|
||||
<li v-for="(item, index) in filteredData" :key="item.id" @click="openDetailModal(item)"
|
||||
@mouseenter="handleMouseEnter(item.id)" @mouseleave="handleMouseLeave()"
|
||||
:class="{ 'hover-item': hoverItemId === item.id }">
|
||||
<img :src="item.avatar">
|
||||
<img :src="item.avatar" style="width: 38px;margin-left: 20px;margin-top: 5px;border-radius: 5px;">
|
||||
<!-- 显示其他信息 -->
|
||||
<div class="span-data">
|
||||
<span class="span-1">{{ item.name }}</span>
|
||||
|
|
@ -135,9 +121,10 @@
|
|||
<span class="span-3">推荐监控频率{{ item.transmit }}</span>
|
||||
</div>
|
||||
<button v-if="index === 0"
|
||||
style="background-image: url('src/assets/images/logo/定位.png'); background-size: cover; background-repeat: no-repeat; background-position: center;margin-left: 340px;margin-top: -100px;width: 20px;height: 20px;border-radius: 0px;border: 0;cursor: pointer;"
|
||||
style="background-image: url('src/assets/images/logo/定位.png'); background-size: cover; background-repeat: no-repeat; background-position: center;margin-left: 370px;margin-top: -90px;width: 20px;height: 20px;border-radius: 0px;border: 0;cursor: pointer;"
|
||||
@click.stop="handleLocateMark"></button>
|
||||
</li>
|
||||
<li v-if="index < filteredData.length - 1" class="divider"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -239,11 +226,8 @@ import { useActionStore } from '@/store';
|
|||
import Chart32_Inspection from '@/components/Chart32_Inspection(1).vue';
|
||||
import Chart33_WavingBlades from '@/components/Chart33_WavingBlades(1).vue';
|
||||
import Chart34_RecoveredGoods from '@/components/Chart34_RecoveredGoods(1).vue';
|
||||
<<<<<<< HEAD
|
||||
import Chart35_SpecialForces from '@/components/Chart35_SpecialForces(1).vue';
|
||||
import Chart36_Dialogue from '@/components/Chart36_Dialogue(1).vue';
|
||||
=======
|
||||
>>>>>>> 33171231818e20d0f810df4ae56f3620727af4df
|
||||
|
||||
|
||||
let myChart = null;
|
||||
|
|
@ -1071,9 +1055,40 @@ const updateChart = () => {
|
|||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
center: ['40%', '50%'],
|
||||
padAngle: 5,
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
borderRadius: 0,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 1
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'outside'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: data
|
||||
}
|
||||
,
|
||||
{
|
||||
name: currentChartType.value === 'registration' ? '注册时间分布' : '行为模式分布',
|
||||
type: 'pie',
|
||||
radius: ['20%', '30%'],
|
||||
center: ['40%', '50%'],
|
||||
padAngle: 10,
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 0,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
|
|
@ -1093,8 +1108,7 @@ const updateChart = () => {
|
|||
show: false
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -1169,10 +1183,20 @@ onMounted(() => {
|
|||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['活跃预警事件', '高风险事件']
|
||||
data: ['活跃预警事件', '高风险事件'],
|
||||
textStyle: {
|
||||
fontSize: 14, // 字体大小
|
||||
fontWeight: 'bold', // 字体粗细(normal/bold/bolder/lighter/100-900)
|
||||
color: '#E1F4FF', // 字体颜色
|
||||
fontFamily: '微软雅黑, Arial, sans-serif', // 字体族
|
||||
fontWeight:200,
|
||||
fontStyle: 'normal' // 字体风格(normal/italic/oblique)
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: '5%',
|
||||
top: '30%', // 距离容器顶部
|
||||
bottom: '1%',
|
||||
containLabel: true
|
||||
},
|
||||
toolbox: {
|
||||
|
|
@ -1195,9 +1219,9 @@ onMounted(() => {
|
|||
// margin:15,
|
||||
textStyle: {
|
||||
color: '#a8aab0',
|
||||
fontStyle: 'normal',
|
||||
fontFamily: '微软雅黑',
|
||||
fontSize: 12,
|
||||
fontStyle: 'normal',
|
||||
fontFamily: '微软雅黑',
|
||||
fontSize: 12,
|
||||
},
|
||||
formatter: function (params) {
|
||||
var newParamsName = "";
|
||||
|
|
@ -1228,16 +1252,15 @@ onMounted(() => {
|
|||
show: false,
|
||||
},
|
||||
axisLine: {//坐标轴轴线相关设置
|
||||
lineStyle: {
|
||||
color: '#E5E9ED',
|
||||
// opacity:0.2
|
||||
}
|
||||
show: false
|
||||
},
|
||||
splitLine: { //坐标轴在 grid 区域中的分隔线。
|
||||
show: false,
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#E5E9ED',
|
||||
// opacity:0.1
|
||||
color: 'rgba(229, 233, 237, 0.3)', // 半透明浅灰色
|
||||
type: 'dashed', // 虚线样式
|
||||
width: 1, // 线条宽度
|
||||
opacity: 0.7 // 线条透明度
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1263,8 +1286,10 @@ onMounted(() => {
|
|||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#E5E9ED',
|
||||
// opacity:0.1
|
||||
color: 'rgba(229, 233, 237, 0.3)', // 半透明浅灰色
|
||||
type: 'dashed', // 虚线样式
|
||||
width: 1, // 线条宽度
|
||||
opacity: 0.7 // 线条透明度
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1495,12 +1520,11 @@ onUnmounted(() => {
|
|||
.containner4 {
|
||||
width: 457px;
|
||||
height: 394px;
|
||||
margin-left: 16px;
|
||||
margin-left: 10px;
|
||||
margin-top: 30px;
|
||||
background-color: #04142166;
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-image: linear-gradient(to bottom, #3AA1F8, #3AA1F833) 1;
|
||||
border-radius: 2px;
|
||||
/* 添加内阴影 */
|
||||
box-shadow: 0px 0px 18px 0px #0A2E55 inset;
|
||||
|
|
@ -1511,9 +1535,9 @@ onUnmounted(() => {
|
|||
}
|
||||
|
||||
.temporary-style {
|
||||
background-image: linear-gradient(to right, #003F7D, #5DB9FF7A);
|
||||
border-image: linear-gradient(to bottom, #95CEFF, #3AA1F833);
|
||||
border: 0px solid;
|
||||
background-image: linear-gradient(to right, #003F7D, #003F7D);
|
||||
border-image: linear-gradient(to bottom, #003F7D, #003F7D);
|
||||
border: 1px solid;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -1652,23 +1676,17 @@ onUnmounted(() => {
|
|||
}
|
||||
|
||||
.suggestion li {
|
||||
width: 360px;
|
||||
height: 48px;
|
||||
width: 395px;
|
||||
height: 52px;
|
||||
color: #FFFFFF;
|
||||
margin-top: 15px;
|
||||
margin-left: 30px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.suggestion li img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 10px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
margin-left: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.suggestion li:hover {
|
||||
background-image: linear-gradient(to bottom, #07293D, #050B23);
|
||||
background-image: linear-gradient(to bottom, #07293D, #07293D);
|
||||
}
|
||||
|
||||
.suggestion-containner {
|
||||
|
|
@ -1695,20 +1713,20 @@ onUnmounted(() => {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 80px;
|
||||
margin-top: -50px;
|
||||
margin-top: -45px;
|
||||
}
|
||||
|
||||
.span-1 {
|
||||
font-family: OPPOSans;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
margin-top: -5px;
|
||||
font-size: 14px;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.span-2 {
|
||||
font-family: PingFang SC;
|
||||
font-weight: 200;
|
||||
font-size: 14px;
|
||||
font-weight: 100;
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
|
|
@ -1720,7 +1738,13 @@ onUnmounted(() => {
|
|||
margin-left: 150px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px; /* 必须设置高度才能显示 */
|
||||
background-color: #e5e5e5; /* 确保颜色与背景有对比度 */
|
||||
margin: 8px 0; /* 上下间距 */
|
||||
list-style: none; /* 移除默认列表样式 */
|
||||
width: 100%; /* 确保宽度足够 */
|
||||
}
|
||||
.suggestions li {
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
|
|
@ -1806,43 +1830,6 @@ onUnmounted(() => {
|
|||
height: 200px;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.color-block1 {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: #D83D6C;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.color-block2 {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: #00CEFF;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.color-block3 {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: #D3ADF7;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.color-block4 {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: #1890FF;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.intime li {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
|
|
@ -1875,7 +1862,7 @@ onUnmounted(() => {
|
|||
}
|
||||
|
||||
.containner3-img {
|
||||
margin-top: 70px;
|
||||
margin-top:5px;
|
||||
}
|
||||
|
||||
.focus-events {
|
||||
|
|
@ -1979,7 +1966,7 @@ onUnmounted(() => {
|
|||
background-color: #04142166;
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-image: linear-gradient(to bottom, #67A4E199, #3AA1F833) 1;
|
||||
|
||||
border-radius: 2px;
|
||||
/* 添加内阴影 */
|
||||
box-shadow: 0px 0px 18px 0px #0A2E55 inset;
|
||||
|
|
@ -2339,21 +2326,42 @@ onUnmounted(() => {
|
|||
}
|
||||
|
||||
.chart-tabs button {
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
width: 80px;
|
||||
height: 25px;
|
||||
margin-top: 60px;
|
||||
margin-left: 10px;
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
background-color: #333;
|
||||
background-color: #04142166;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-family: OPPOSans;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
color: #E1F4FF;
|
||||
border: 1px solid #1C588F;
|
||||
line-height: 18px;
|
||||
letter-spacing: 0%;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* 为第一个按钮设置左侧圆角 */
|
||||
.chart-tabs button:first-child {
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
|
||||
/* 为最后一个按钮设置右侧圆角 */
|
||||
.chart-tabs button:last-child {
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
/* 为中间按钮取消所有圆角 */
|
||||
.chart-tabs button:not(:first-child):not(:last-child) {
|
||||
border-radius: 0;
|
||||
}
|
||||
.chart-tabs button.active-tab {
|
||||
margin-top: 60px;
|
||||
background-color: #1890ff;
|
||||
background-color: #236291;
|
||||
box-shadow: 0 0 10px rgba(24, 144, 255, 0.5);
|
||||
}
|
||||
|
||||
|
|
@ -2361,7 +2369,7 @@ onUnmounted(() => {
|
|||
#categoryChart {
|
||||
width: 80%;
|
||||
height: 400px;
|
||||
margin-left: -40px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user