This commit is contained in:
lnljyang
2026-01-05 15:07:49 +08:00
parent 4ad393a9a1
commit 3bb5419386
138 changed files with 118289 additions and 0 deletions

21
src/App.vue Normal file
View File

@@ -0,0 +1,21 @@
<!--
* @Author: szy
* @Date: 2022-01-12 14:06:47
* @LastEditors: szy
* @LastEditTime: 2022-03-01 17:55:49
* @FilePath: \web-pc\src\pages\big-screen\App.vue
-->
<template>
<div id="app">
<router-view />
</div>
</template>
<style lang="scss" scoped>
#app {
width: 100vw;
height: 100vh;
background-color: #f8f9fa;
// overflow: hidden;
}
</style>

170
src/api/api.js Normal file
View File

@@ -0,0 +1,170 @@
/*
* @LastEditors: Please set LastEditors
* @LastEditTime: 2023-08-02 14:58:23
*/
import axios from 'axios';
import UtilVar from "@/config/UtilVar";
import router from '@/router'
let baseUrl = UtilVar.baseUrl
const CancelToken = axios.CancelToken;
export { baseUrl };
// axios.defaults.withCredentials = true;
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么 传token
let token = localStorage.getItem("token");
token = "37c816b1b6da4ed587ff5261ae20642e";
config.headers.common['Content-Type'] = "application/json;charset=utf-8";
// config.headers.common['token'] = token; //Authorization
config.headers.common['asoco-token'] = token;
return config;
}, function (error) {
// 对请求错误做些什么
console.log(error)
return Promise.reject(error);
});
/**
* @响应拦截
*/
axios.interceptors.response.use(response => {
if (response.status !== 200) {
return Promise.reject(response)
}
/**
* @code 登录过期 token验证失败 根据后端调
*/
if (response.data.code == UtilVar.code) {
// router.push("/login")
}
return response.data
}, error => {
console.error(error);
let err = {
success: false,
msg: "未知异常,请联系管理员!"
}
return Promise.reject(err)
})
let configs_ENC = {
headers: { 'enc': UtilVar.ENC }
}
//处理是否加密数据
let isEncryptionParam = (params) => {
return params
}
export const GET = async (url, params) => {
try {
params = isEncryptionParam(params)
const data = await axios.get(`${baseUrl}${url}`, {
params: params,
headers: configs_ENC.headers
}, configs_ENC);
return data;
} catch (error) {
return error;
}
}
//没有基地址 访问根目录下文件
export const GETNOBASE = async (url, params) => {
try {
const data = await axios.get(url, {
params: params,
});
return data;
} catch (error) {
return error;
}
}
export const POST = async (url, params) => {
try {
params = isEncryptionParam(params)
const data = await axios.post(`${baseUrl}${url}`, params, configs_ENC);
return data;
} catch (error) {
return error;
}
}
export const PUT = async (url, params) => {
try {
params = isEncryptionParam(params)
const data = await axios.put(`${baseUrl}${url}`, params, configs_ENC);
return data;
} catch (error) {
return error;
}
}
export const DELETE = async (url, params) => {
// console.log(params)
try {
params = isEncryptionParam(params)
const data = await axios.delete(`${baseUrl}${url}`, { data: params, headers: configs_ENC.headers }, configs_ENC);
return data;
} catch (error) {
return error;
}
}
/**
* @文件类型提交方法
*/
let configs = {
headers: { 'Content-Type': 'multipart/form-data' },
}
export const FILESubmit = async (url, params, config) => {
try {
const data = await axios.post(`${baseUrl}${url}`, params, {
...configs,
cancelToken: new CancelToken(function executor(c) {
config.setCancel && config.setCancel(c)
}),
onUploadProgress: (e) => {
if (e.total > 0) {
e.percent = e.loaded / e.total * 100;
}
// console.log(config)
config.onProgress && config.onProgress(e)
},
});
return data;
} catch (err) {
return err;
}
}
/**
* 下载文档流
* @param {config.responseType} 下载文件流根据后端 配置 arraybuffer || blod
*/
export const FILE = async (config = {}, body, params) => {
try {
const data = await axios({
method: config.method || 'get',
url: `${baseUrl}${config.url}`,
data: body,
params: params,
responseType: config.responseType || 'blob',
onDownloadProgress: (e) => {
// console.log(e,e.currentTarget)
// if (e.currentTarget.response.size > 0) {
// e.percent = e.loaded / e.currentTarget.response.size * 100;
// }
// event.srcElement.getResponseHeader('content-length')
config.onProgress && config.onProgress(e)
},
});
return data;
} catch (err) {
return err;
}
}

46
src/api/index.js Normal file
View File

@@ -0,0 +1,46 @@
/*
* @Author: szy
* @Date: 2021-12-09 10:47:56
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-27 16:32:31
* @FilePath: \web-pc\src\api\index.js
*/
import {
currentList,
currentPage,
currentSave,
currentUpdate,
currentDelete,
currentSelect,
currentSelectList,
currentPOST,
currentGET,
currentApi
} from './modules'
import {
GETNOBASE,
GET
} from './api'
export {
GETNOBASE,
GET
}
export {
currentApi,
currentList,
currentPage,
currentSave,
currentUpdate,
currentDelete,
currentSelect,
currentSelectList,
currentPOST,
currentGET
}

103
src/api/modules/index.js Normal file
View File

@@ -0,0 +1,103 @@
/*
* @Author: szy
* @Date: 2021-12-23 11:18:37
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-28 15:10:45
* @FilePath: \web-pc\src\api\modules\index.js
*/
import * as API from "../api";
export const paramType ={
'big1':"/board/getDayTotal", //当日时况
'big2':"/board/getMonthTotal", //月度碳足迹
'big3':"/board/getYearTotal", //年度碳排量
'big4':"/board/getExchangeInfo", //获取交易所信息
'big5':'/board/getTruckModelTotal', //车型分布
'big9':'/board/getMapInfo', //中间地图
'big10':'/board/getMapSiteInfo', //中间地图 加氢站信息
'big13':'/board/getVehicleDayDetail', //每日车辆信息
'big6':'/bigscreen/installationPlan', // 安装计划
'big7':'/bigscreen/ranking', // 报警排名
}
/****************** 通用增删改查 ********************* */
/**
* 通用列表
* @param {*} param
*/
export const currentList = (key,param)=> {
return API.GET(paramType[key], param)
}
export const currentPage = (key,param)=> {
return API.GET(paramType[key]+"/page", param)
}
/**
* 查询可选择的列表
* @param {*} param
*/
export const currentSelectList= (key,param)=> {
return API.GET(paramType[key]+"/selectList", param)
}
/**
* 通用新增
* @param {*} param
*/
export const currentSave= (key,param)=> {
return API.POST(paramType[key]+"/save", param)
}
/**
* 通用修改
* @param {*} param
*/
export const currentUpdate= (key,param) => {
return API.POST(paramType[key]+"/update", param)
}
/**
* 通用删除
* @param {*} param
*/
export const currentDelete= (key,param) => {
return API.POST(paramType[key]+"/delete", param)
}
/**
* 通用获取所有不分页
* @param {*} param
*/
export const currentSelect= (key,param)=> {
return API.GET(paramType[key]+"/select", param)
}
/**
* 通用GET
* @param {*} param
*/
export const currentGET= (key,param)=> {
return API.GET(paramType[key], param)
}
/**
* 通用POST
* @param {*} param
*/
export const currentPOST= (key,param)=> {
return API.POST(paramType[key], param)
}
// 通用接口集合
export const currentApi={
currentList,
currentPage,
currentSave,
currentUpdate,
currentDelete,
currentSelect,
currentSelectList,
currentPOST,
currentGET
}

361
src/assets/css/index.scss Normal file
View File

@@ -0,0 +1,361 @@
@import "./modules/reset.scss";
@import "./modules/variables.scss";
@import './theme/index.css';
@import '../iconfont//iconfont.css';
[class*=" blq-icon-"],
[class^=blq-icon-] {
font-family: iconfont !important;
speak: none;
font-style: normal;
font-weight: 400;
font-variant: normal;
text-transform: none;
line-height: 1;
vertical-align: middle;
display: inline-block;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale
}
*,
:after,
:before {
box-sizing: content-box;
}
.clearfix {
&::after {
content: "";
display: table;
height: 0;
line-height: 0;
visibility: hidden;
clear: both;
}
}
.contents {
width: 100%;
display: flex;
min-height: calc(100% - 60px);
justify-content: space-between;
}
.beautify-scroll-def {
overflow-y: auto;
&::-webkit-scrollbar-thumb {
//滚动条的设置
background-color: rgba(25, 118, 210, 0);
background-clip: padding-box;
border-radius: 4px;
}
&:hover {
&::-webkit-scrollbar-thumb {
//滚动条的设置
background-color: rgba(25, 118, 210, 0.3);
background-clip: padding-box;
border-radius: 4px;
}
}
&::-webkit-scrollbar-track-piece {
//滚动条凹槽的颜色,还可以设置边框属性
background-color: transparent;
}
&::-webkit-scrollbar {
//滚动条的宽度
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb:hover {
background-color: rgba(25, 118, 210, .5);
}
}
.orderNum {
// min-width: 22px;
// height: 22px;
// background: #00b8ff;
// border-radius: 50%;
// text-align: center;
// line-height: 22px;
// font-size: 13px;
// font-weight: 900;
// color: #0f2854;
color: #00b8ff;
}
.yh-big-input {
width: 253px;
height: 14px;
background: transparent;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 4px;
color: #333333;
padding: 6px 10px;
font-size: 14px;
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
&:focus {
outline: none;
border-color: #1976d2;
}
}
.yh-big-el-input {
width: 253px;
font-size: 14px;
.el-input__inner {
padding: 6px 10px;
border: 1px solid rgba(0, 0, 0, .2);
background-color: transparent;
font-size: 14px;
line-height: 1;
color: #333333;
&:hover{
border-color: rgba(0, 0, 0, .3);
}
&:focus {
outline: none;
border-color: #1976d2;
}
}
}
.yh-big-button {
width: 53px;
height: 26px;
background: #1976d2;
border-radius: 4px;
// border-color: #1976d2;
border-width: 1px;
border: none;
cursor: pointer;
color: #fff;
font-size: 15px;
&:hover,
&:focus {
// border-color: #1565c0;
background: #1565c0;
}
}
//浮动
.float-r {
float: right;
}
//浮动
.float-l {
float: left;
}
// 字体加粗
.fw-b {
font-weight: bold;
}
//文章一行显示,多余省略号显示
.title-item {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
//表格样式重置
.ve-table {
$border-color: #e0e0e0;
// $border-color: rgba(0, 0, 0, .15);
box-sizing: border-box;
.ve-table-container {
&::-webkit-scrollbar-track-piece {
//滚动条凹槽的颜色,还可以设置边框属性
background-color: transparent;
}
&::-webkit-scrollbar {
//滚动条的宽度
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
//滚动条的设置
background-color: rgba(25, 118, 210, 0.3);
background-clip: padding-box;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb:hover {
background-color: rgba(25, 118, 210, .5);
}
.ve-table-content {
&::after {
content: "";
position: absolute;
top: 0;
right: 0px;
width: 1px;
height: 100%;
background-color: $border-color;
z-index: 20;
}
}
}
&.ve-table-border-around {
border-color: $border-color;
}
.ve-table-container table.ve-table-content thead.ve-table-header tr.ve-table-header-tr {
height: 34px;
box-sizing: border-box;
th.ve-table-header-th {
background: #f5f7fa;
color: #333333;
border-color: $border-color;
box-sizing: border-box;
line-height: 1;
}
}
.ve-table-container table.ve-table-content tbody.ve-table-body {
tr.ve-table-body-tr td.ve-table-body-td,
tr.ve-table-expand-tr td.ve-table-body-td,
tr.ve-table-body-tr td.ve-table-expand-td,
tr.ve-table-expand-tr td.ve-table-expand-td {
background: transparent;
color: #333333;
border-color: $border-color;
box-sizing: border-box;
}
tr.ve-table-body-tr,
tr.ve-table-expand-tr {
height: 34px;
box-sizing: border-box;
}
&.ve-table-row-hover tr.ve-table-body-tr:hover td {
background-color: rgba(25, 118, 210, 0.08);
box-sizing: border-box;
}
}
.ve-table-container .ve-table-border-x th,
.ve-table-container .ve-table-border-x td {
border-color: $border-color;
box-sizing: border-box;
}
}
//颜色
@each $colorkey,
$color in $colors {
.text-#{$colorkey} {
color: $color;
}
.bg-#{$colorkey} {
background-color: $color;
}
}
//对齐
@each $var in (left, center, right) {
.text-#{$var} {
text-align: $var !important;
}
}
//flex
@each $key,
$value in $flex-jc {
.jc-#{$key} {
justify-content: $value;
}
}
@each $key,
$value in $flex-ai {
.ai-#{$key} {
align-items: $value;
}
}
//字体
@each $fontkey,
$fontvalue in $font-sizes {
.fs-#{$fontkey} {
font-size: $fontvalue * $base-font-size;
}
}
//.mt-1 => margin top
//spacing
@each $typekey,
$type in $spacing-types {
//.m-1
@each $sizekey,
$size in $spacing-sizes {
.#{$typekey}-#{$sizekey} {
#{$type}: $size * $spacing-base-size;
}
}
//.mx-1
@each $sizekey,
$size in $spacing-sizes {
.#{$typekey}x-#{$sizekey} {
#{$type}-left: $size * $spacing-base-size;
#{$type}-right: $size * $spacing-base-size;
}
.#{$typekey}y-#{$sizekey} {
#{$type}-top: $size * $spacing-base-size;
#{$type}-bottom: $size * $spacing-base-size;
}
}
//.mt-1
@each $directionkey,
$direction in $spacing-directions {
@each $sizekey,
$size in $spacing-sizes {
.#{$typekey}#{$directionkey}-#{$sizekey} {
#{$type}-#{$direction}: $size * $spacing-base-size;
}
}
}
.#{$typekey} {
#{$type}: 0;
}
}

View File

@@ -0,0 +1,200 @@
/**
* Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
* http://cssreset.com
*/
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video,
input {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font-weight: normal;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* custom */
a {
color: #7e8c8d;
-webkit-backface-visibility: hidden;
text-decoration: none;
}
li {
list-style: none;
}
body {
-webkit-text-size-adjust: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.olControlScaleLineBottom {
display: none;
}
.olControlScaleLineTop {
color: #000 !important;
border-bottom: solid 3px #000 !important;
border-left: solid 2px #000 !important;
border-right: solid 2px #000 !important;
background-color: rgba(255, 255, 255, .4);
font-size: 10px;
text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff;
}
.olControlScaleLine {
z-index: 900 !important;
}
/*清除浮动*/
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {display: inline-block;}
/* 点击搜索框获取焦点 placeholder消失-开始 */
/* WebKit browsers */
// input:focus::-webkit-input-placeholder {
// color: transparent;
// }
// /* Mozilla Firefox 4 to 18 */
// input:focus:-moz-placeholder {
// color: transparent;
// }
// /* Mozilla Firefox 19+ */
// input:focus::-moz-placeholder {
// color: transparent;
// }
// /* Internet Explorer 10+ */
// input:focus:-ms-input-placeholder {
// color: transparent;
// }
/* 点击搜索框获取焦点 placeholder消失-结束 */

View File

@@ -0,0 +1,98 @@
// 颜色
$colors: (
"primary": #1976d2,
"info-1": #2196f3,
"info": #1e88e5,
"white": #ffffff,
"light": #f5f7fa,
"grey-1": #999999,
"grey": #666666,
"dark-1": #333333,
"dark": #222222,
"black-1": #333333,
"black": #000000,
"icon": #1976d2
);
// 字体大小
$base-font-size: 0.2rem;
$font-sizes: (
xxs: 0.1,
//8px
xs: 0.125,
//10px
sm: 0.2875,
//12px
md: 0.1625,
//13px
lg: 0.175,
//14px
xl: 0.2,
//16px
xxl: 0.225,
//18px
xxxl: 0.25 //20px,,,,
);
// 宽高
.w-100 {
width: 100%;
}
.h-100 {
height: 100%;
}
//flex
.flex {
display: flex;
}
.flex-column {
flex-direction: column;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-nowrap {
flex-wrap: nowrap;
}
$flex-jc: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
evenly: space-evenly,
);
$flex-ai: (
start: flex-start,
end: flex-end,
center: center,
stretch: stretch,
);
.flex-1 {
flex: 1;
}
//.mt-1 => margin top
//spacing
$spacing-types: (
m: margin,
p: padding,
);
$spacing-directions: (
t: top,
r: right,
b: bottom,
l: left,
);
$spacing-base-size: 0.5rem;
$spacing-sizes: (
0: 0,
1: 0.5,
2: 1,
3: 1.5,
4: 2,
5: 2.5,
);

156
src/assets/css/public.scss Normal file
View File

@@ -0,0 +1,156 @@
.flex {
display: flex;
}
.flex-direction {
flex-direction: column;
}
.flex-wrap {
flex-wrap: wrap;
}
.align-start {
align-items: flex-start;
}
.align-end {
align-items: flex-end;
}
.align-center {
align-items: center;
}
.align-stretch {
align-items: stretch;
}
.self-start {
align-self: flex-start;
}
.self-center {
align-self: flex-center;
}
.self-end {
align-self: flex-end;
}
.self-stretch {
align-self: stretch;
}
.align-stretch {
align-items: stretch;
}
.justify-start {
justify-content: flex-start;
}
.justify-end {
justify-content: flex-end;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.justify-around {
justify-content: space-around;
}
@for $i from 0 through 12 {
.rdx-flex-#{$i} {
flex: $i;
}
}
@for $i from 9 to 50 {
.rdx-font-#{$i} {
font-size: $i + px;
}
}
@for $i from 2 to 50 {
.rdx-radius-#{$i} {
border-radius: $i + px;
}
}
@for $i from 10 to 50 {
.rdx-line-height-#{$i} {
line-height: $i + px;
}
}
// 定义内外边距历遍1-80
@for $i from 0 through 80 {
// 只要双数和能被5除尽的数
@if $i % 2 == 0 or $i % 5 == 0 {
// 得出u-margin-30或者u-m-30
.rdx-m-#{$i} {
margin: $i + px !important;
}
// 得出u-padding-30或者u-p-30
.rdx-p-#{$i} {
padding: $i + px !important;
}
@each $short, $long in l left, t top, r right, b bottom {
// 缩写版,结果如: u-m-l-30
// 定义外边距
.rdx-m-#{$short}-#{$i} {
margin-#{$long}: $i + px !important;
}
// 定义内边距
.rdx-p-#{$short}-#{$i} {
padding-#{$long}: $i + px !important;
}
//自定义左右内边距
.rdx-p-lr-#{$i} {
padding-left:$i + px !important;
padding-right:$i + px !important;
}
//自定义上下内边距
.rdx-p-tb-#{$i} {
padding-top:$i + px !important;
padding-bottom:$i + px !important;
}
}
}
}
i{font-style: normal;}
.position-re{position: relative;}
.position-ab{position: absolute; z-index: 9;}
.position-fixed{position: fixed; background: rgba(92, 116, 143, 0.45); width: 100%; height: 100%; left: 0px; top: 0px; z-index: 10;}
.round{border-radius: 50%;}
.font-strong{font-weight: bold;}
.color-del{color:$del-color}
.color-primary{color: $primary-color;}
.color-remark{color: #666666;}
.color-9{color: #999999;}
.color-green{color: #38a800;}
.bg-white{background-color: white;}
.line-bottom{border-bottom: 1px solid #eeeeee;}
.button-pointer{cursor: pointer;}
.box-shadow-item{box-shadow: 0px 0px 4px 0px rgba(45, 45, 46, 0.1);}
.search-form .search-form-item label {text-align: right; padding-right: 6px;}
.break-all{
word-break: break-all;
}
.blocks{
width: 100%;
height: 100%;
}
.cursor-pointer{
cursor: pointer;
}

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,50 @@
// 颜色
$primary-color: #1890ff;
$primary-color-hl: rgb(41, 52, 67);
$default-color: #006569;
$link: #1890ff;
$active-color: rgb(0, 101, 105);
$del-color: #ff1839;
$content-background: #f3f5fa;
$table-header-background: #d8eaff;
$primary-color-rgba: rgba($color: $primary-color,
$alpha: 0.1,
);
//表格上面button按钮颜色
$table-header-button: #18d1ff;
// 阴影
$primary-shadow: 0 2px 4px rgba(0, 0, 0, 0.12),
0 0 6px rgba(0, 0, 0, 0.04);
$primary-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
$baidu-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15);
$gaode-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 2px 6px 0 rgba(0, 0, 0, 0.19);
// box-shadow: 0 2px 6px 0 rgb(114 124 245 / 50%);
$primary-border: $primary-color solid 1px;
$tool-top: 20px;
//header 的高度
$index-height: 60px;
$index-content-height: calc(100% - 60px);
$index-tags-height: 36px;
// 宽度侧边栏
$aside-width: 200px;
$content-padding: 16px;
$default-zindex: 99;
/*文本格式化,超出范围,显示省略号*/
@mixin text-overflow($num: 1) {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: $num;
-webkit-box-orient: vertical;
}

View File

@@ -0,0 +1,18 @@
/* @font-face {
font-family: 'webfont';
font-display: swap;
src: url('//at.alicdn.com/t/webfont_c14qx7m7htb.eot');
src:
url('//at.alicdn.com/t/webfont_c14qx7m7htb.woff2') format('woff2'),
url('//at.alicdn.com/t/webfont_c14qx7m7htb.woff') format('woff'),
}
.number-font{
font-family:"webfont" !important;
font-size:16px;font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
} */

View File

@@ -0,0 +1,23 @@
@font-face {
font-family: "iconfont"; /* Project id 2995337 */
src: url('iconfont.woff2?t=1638871675242') format('woff2'),
url('iconfont.woff?t=1638871675242') format('woff'),
url('iconfont.ttf?t=1638871675242') format('truetype');
}
/* .iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} */
.blq-icon-shezhi01:before {
content: "\e610";
}
.blq-icon-shezhi02:before {
content: "\e611";
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/assets/img/frame.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src/assets/img/guang.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="63px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -73 -261 )">
<image preserveAspectRatio="none" style="overflow:visible" width="54" height="53" xlink:href="data:image/png;base64,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" x="73px" y="261px" />
</g>
<style>svg { filter: drop-shadow(5px 5px 2.5px rgba(0, 0, 0, 0.34901960784313724)); }</style>
</svg>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="63px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -224 -261 )">
<image preserveAspectRatio="none" style="overflow:visible" width="54" height="53" xlink:href="data:image/png;base64,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" x="224px" y="261px" />
</g>
<style>svg { filter: drop-shadow(5px 5px 2.5px rgba(0, 0, 0, 0.34901960784313724)); }</style>
</svg>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="60px" height="59px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -377 -262 )">
<image preserveAspectRatio="none" style="overflow:visible" width="50" height="49" xlink:href="data:image/png;base64,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" x="377px" y="262px" />
</g>
<style>svg { filter: drop-shadow(5px 5px 2.5px rgba(0, 0, 0, 0.34901960784313724)); }</style>
</svg>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="59px" height="58px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -530 -263 )">
<image preserveAspectRatio="none" style="overflow:visible" width="49" height="48" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABShJREFUeF7tm09oHVUUxr9vJi9iSEVQWiwFobYi0eRNyCIUraS6ELRaLBQX0ZX/EF2oUAUXbUpBK8WKC/+gUjdWRPyDbXChRFPRYktt7otkoYiKNBUSF6LUGPPmHpnXvPTl9b3MnZl7p32Ns51z7znfL9+9czL3DXGergGRtj80tiufz9WWEGj5TIhnS+QXeZTGPJLU5wjKsgXA0yA2KJ+LaghCkUq84GP42KvIr13WmDuAIJSnADxfFdUUQBRAzIjGo6U2vuUKQm4A5i3/KoAHasUsCeBs4DP1S8UWkFwA9Iis9AT7IbijvnBDAIDGLlXgkC3h1XmcA+ielet8H/uj9d6oeGMAZwYPKZ+7bEJwCiAoyzYQewCsbVZ0QgDWneAMQG8oeyTa6WOuxACi+SwuB+sAgjkZgI+dEAzEiY/upwJwZuKXlc/HTHIsFWMNQEU4MAAPO5MUlQFA9Jgch+AAPbw9Rp5KkjfTJtg9I2v9ArqF6KagGx5ugmB1mgIyATir4vcIhHh4n8BJRf5iWkusA4pl2Uqin8Q6AdZBsB7ApaYJ4uKsADg3ySyISQC/QjANYBoa0wIcKRX4aW14LICF1jROScr7jgA0raY+33IDcFr57FzODphSPlctXwDEz8rjoqZsuS2BCeXzhuXrAMEx1cb+5QuAGFUeNyUF8CeAFSmfcrHDcn0MpgKgZTJtlxerPtv/AibTL45JBSCU7wFcmzyb2YgL3gHFshwn0WcmJ3lUKwD4ksTG5NLMRlzwAMxktG5UbCPUutLMKv8fgBmnizcq1gFBKNtB3O4KQX1nFmhxdyYo+ET53JuoEyyKbKbGIWcAmp0NOkhIwZaxNh5MBKBXpEs0JhzUU5kyz8egDtE33s4TiQB0TUln+xX462IAQA8rx8joHeHCFbsHRJFBKP8CKLiAkJsDiBnlsaNegymAEoCeFgcwobzFL0MiPWYAyvIhiLtbGQCJQ2Me70rrgBcBPN7KAAC8pHyeo8HIAcWy3EPi3ZYG4GFQke+kckCXSGe7dvMkyGsT1H9j1fgKTqUCEA3q1XJQBHfadkEuAARHVBtvbFS70RKIBhZDeZjAa60IgMCOMZ+7MwEIRNZD44dWBCAat5QKjX93aOyASkOk5TAEN9uEkMMSOHW5h6tHyXImB1QAzMlQ0h9AxMHKAcAbyudDzepI5IA+katCwXGbr8ldA/A8bDhBfmMFgAsXOAZwQPm8dykXJnJANJFtF7gEoD3cOk5+bhWAbRc4A0B8pDxujduDEjvAtgtcAYiatlIbh50AqHSGIo+IxitxCeLuuwAgwO6Szx1xuaP7qRxQnTgI5XUAD5okahZjHQAxrDwat+yZAFRa5Ixnh5YBTCqfa5L8QTIDmP8OYBaAlyRxNdYmAN/D6m/J35LUkRnA/H5QFA2VJLF1ABqbVIGjSWuwAiALBCsOSCk+8yZYTzvNGUJmABnEWwcw74ToIOUwgCtN7JgJQEbxTgAsQBC8B8H1cRBSA7Ag3hmAGghvQhp/K5RlExSNjaUCv4qDa3Lf2ibYKFm/yGX/aOwjcL+tRij0cM135E8m4kxinAKoFlAM5QkC+xoVlGAJTOlZ9I138KSJMNOYXABUOsY5uY0+XqjfF4wACI7Rx+b6g01TkUvF5QYgKqJHZI2nK07YZrwHEMOXEINHyegXq9avXAFUqw9CiT6sir4h7ljKAUJ8cJoY/JGMWm0n13kBUFkSIr3UuE/5fLJWWaDlKAQj9DAyRo44UV0z6X/RxY1fQ+YZrQAAAABJRU5ErkJggg==" x="530px" y="263px" />
</g>
<style>svg { filter: drop-shadow(5px 5px 2.5px rgba(0, 0, 0, 0.34901960784313724)); }</style>
</svg>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="650px" height="62px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="325" y1="0" x2="325" y2="62" id="LinearGradient4683">
<stop id="Stop4684" stop-color="#081c34" offset="0" />
<stop id="Stop4685" stop-color="#0b505f" offset="1" />
</linearGradient>
<pattern id="BGPattern" patternUnits="userSpaceOnUse" alignment="0 0" imageRepeat="None" />
<linearGradient gradientUnits="userSpaceOnUse" x1="325" y1="0" x2="325" y2="62" id="LinearGradient4686">
<stop id="Stop4687" stop-color="#081c34" offset="0" />
<stop id="Stop4688" stop-color="#0b505f" offset="1" />
</linearGradient>
<mask fill="white" id="Clip4689">
<path d="M 0 62 L 21.959459511413698 0 L 626.5765765498896 0 L 650 62 L 0 62 Z " fill-rule="evenodd" />
</mask>
</defs>
<g transform="matrix(1 0 0 1 -3 -286 )">
<path d="M 0 62 L 21.959459511413698 0 L 626.5765765498896 0 L 650 62 L 0 62 Z " fill-rule="nonzero" fill="url(#LinearGradient4683)" stroke="none" transform="matrix(1 0 0 1 3 286 )" class="fill" />
<path d="M 0 62 L 21.959459511413698 0 L 626.5765765498896 0 L 650 62 L 0 62 Z " stroke-width="2" stroke-dasharray="0" stroke="url(#LinearGradient4686)" fill="none" transform="matrix(1 0 0 1 3 286 )" class="stroke" mask="url(#Clip4689)" />
</g>
</svg>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="35px" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="BGPattern" patternUnits="userSpaceOnUse" alignment="0 0" imageRepeat="None" />
<filter x="-50.00%" y="-50.00%" width="200.00%" height="200.00%" filterUnits="objectBoundingBox" id="Filter4701">
<feOffset dx="0" dy="0" in="SourceGraphic" result="offset" id="offset" />
<feMorphology radius="1" operator="erode" in="offset" result="morphology" id="morphology" />
<feGaussianBlur stdDeviation="25" in="morphology" result="blur" id="blur" />
<feComposite in2="blur" operator="out" in="SourceGraphic" result="inverse" id="inverse" />
<feFlood flood-color="rgba(102, 255, 255, 0.34901960784313724)" in="inverse" result="color" id="color" />
<feComposite in2="inverse" operator="in" in="color" result="shadow" id="shadow" />
<feComposite in2="SourceGraphic" operator="over" in="shadow" />
</filter>
<mask fill="white" id="Clip4702">
<path d="M 0 17.5 C 0 7.699999999999999 21.999999999999996 0 50 0 C 78 0 100 7.699999999999999 100 17.5 C 100 27.3 78 35 50 35 C 21.999999999999996 35 0 27.3 0 17.5 Z " fill-rule="evenodd" />
</mask>
</defs>
<g transform="matrix(1 0 0 1 -504 -295 )">
<path d="M 0 17.5 C 0 7.699999999999999 21.999999999999996 0 50 0 C 78 0 100 7.699999999999999 100 17.5 C 100 27.3 78 35 50 35 C 21.999999999999996 35 0 27.3 0 17.5 Z " fill-rule="nonzero" fill="rgba(21, 103, 115, 1)" stroke="none" transform="matrix(1 0 0 1 504 295 )" class="fill" />
<path d="M 0 17.5 C 0 7.699999999999999 21.999999999999996 0 50 0 C 78 0 100 7.699999999999999 100 17.5 C 100 27.3 78 35 50 35 C 21.999999999999996 35 0 27.3 0 17.5 Z " stroke-width="2" stroke-dasharray="0" stroke="rgba(28, 177, 181, 1)" fill="none" transform="matrix(1 0 0 1 504 295 )" class="stroke" mask="url(#Clip4702)" />
</g>
<style>path.fill { filter: url('#Filter4701'); }</style>
</svg>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="119px" height="148px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="59.5" y1="0" x2="59.5" y2="148" id="LinearGradient4703">
<stop id="Stop4704" stop-color="#05021d" offset="0" />
<stop id="Stop4705" stop-color="#66ffff" offset="1" />
</linearGradient>
<pattern id="BGPattern" patternUnits="userSpaceOnUse" alignment="0 0" imageRepeat="None" />
<linearGradient gradientUnits="userSpaceOnUse" x1="59.5" y1="0" x2="59.5" y2="148" id="LinearGradient4706">
<stop id="Stop4707" stop-color="#05021d" offset="0" />
<stop id="Stop4708" stop-color="#66ffff" offset="1" />
</linearGradient>
<mask fill="white" id="Clip4709">
<path d="M 60 134 C 32.997742421624935 134 10.287803805154795 139.69007411103803 0.3608653994567703 148 L 0 148 L 0 0 L 119 0 L 118.9988251371102 147.48208857388 C 108.75972744117394 139.4543923477729 86.43712969315118 134 60 134 Z " fill-rule="evenodd" />
</mask>
</defs>
<g>
<path d="M 60 134 C 32.997742421624935 134 10.287803805154795 139.69007411103803 0.3608653994567703 148 L 0 148 L 0 0 L 119 0 L 118.9988251371102 147.48208857388 C 108.75972744117394 139.4543923477729 86.43712969315118 134 60 134 Z " fill-rule="nonzero" fill="url(#LinearGradient4703)" stroke="none" class="fill" />
<path d="M 60 134 C 32.997742421624935 134 10.287803805154795 139.69007411103803 0.3608653994567703 148 L 0 148 L 0 0 L 119 0 L 118.9988251371102 147.48208857388 C 108.75972744117394 139.4543923477729 86.43712969315118 134 60 134 Z " stroke-width="0" stroke-dasharray="0" stroke="url(#LinearGradient4706)" fill="none" class="stroke" mask="url(#Clip4709)" />
</g>
</svg>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
src/assets/img/ln_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

BIN
src/assets/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
src/assets/img/pageBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/assets/img/top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

18
src/assets/img/u0.svg Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="2108px" height="953px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="1054" y1="0" x2="1054" y2="953" id="LinearGradient4053">
<stop id="Stop4054" stop-color="#031e4f" offset="0" />
<stop id="Stop4055" stop-color="#021136" offset="0.99" />
<stop id="Stop4056" stop-color="#021136" offset="1" />
</linearGradient>
<pattern id="BGPattern" patternUnits="userSpaceOnUse" alignment="0 0" imageRepeat="None" />
<mask fill="white" id="Clip4057">
<path d="M 0 953 L 0 0 L 2108 0 L 2108 953 L 0 953 Z " fill-rule="evenodd" />
</mask>
</defs>
<g transform="matrix(1 0 0 1 -3 -1 )">
<path d="M 0 953 L 0 0 L 2108 0 L 2108 953 L 0 953 Z " fill-rule="nonzero" fill="url(#LinearGradient4053)" stroke="none" transform="matrix(1 0 0 1 3 1 )" class="fill" />
<path d="M 0 953 L 0 0 L 2108 0 L 2108 953 L 0 953 Z " stroke-width="0" stroke-dasharray="0" stroke="rgba(121, 121, 121, 1)" fill="none" transform="matrix(1 0 0 1 3 1 )" class="stroke" mask="url(#Clip4057)" />
</g>
</svg>

13
src/assets/img/u1.svg Normal file
View File

@@ -0,0 +1,13 @@
<svg width="1600" height="1200" xmlns="http://www.w3.org/2000/svg">
<!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
<g>
<title>background</title>
<rect fill="#96dee8" id="canvas_background" height="1202" width="1602" y="-1" x="-1"/>
<g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
<rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
</g>
</g>
<g>
<title>Layer 1</title>
</g>
</svg>

After

Width:  |  Height:  |  Size: 509 B

13
src/assets/img/u2.svg Normal file
View File

@@ -0,0 +1,13 @@
<svg width="1600" height="1200" xmlns="http://www.w3.org/2000/svg">
<!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
<g>
<title>background</title>
<rect fill="#c0c0c0" id="canvas_background" height="1202" width="1602" y="-1" x="-1"/>
<g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
<rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
</g>
</g>
<g>
<title>Layer 1</title>
</g>
</svg>

After

Width:  |  Height:  |  Size: 509 B

BIN
src/assets/img/xieyou.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/img/xiezuo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,70 @@
<!--
* @Author: szy
* @Date: 2022-02-28 16:29:08
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-09-27 15:05:45
* @FilePath: \web-pc\src\pages\big-screen\components\echart\index.vue
-->
<template>
<div :id="id" :class="className" :style="{ height: height, width: width }" />
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'echart',
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '100%'
},
options: {
type: Object,
default: ()=>({})
}
},
data () {
return {
chart: null
}
},
watch: {
options: {
handler (options) {
// 设置true清空echart缓存
this.chart.setOption(options, true)
},
deep: true
}
},
mounted () {
this.initChart();
},
beforeDestroy () {
this.chart.dispose()
this.chart = null
},
methods: {
initChart () {
// 初始化echart
this.chart = echarts.init(this.$el)
this.chart.setOption(this.options, true)
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,97 @@
<!--
* @Author: szy
* @Date: 2022-03-01 09:16:22
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-09-29 15:12:34
* @FilePath: \web-pc\src\pages\big-screen\components\item-wrap\item-wrap.vue
-->
<template>
<dv-border-box-13 class="lr_titles">
<div class="item_title" v-if="title !== ''">
<div class="zuo"></div>
<span class="title-inner"> &nbsp;&nbsp;{{ title }}&nbsp;&nbsp; </span>
<div class="you"></div>
</div>
<div
:class="title !== '' ? 'item_title_content' : 'item_title_content_def'"
>
<slot></slot>
</div>
</dv-border-box-13>
</template>
<script>
export default {
data() {
return {};
},
props: {
title: {
type: String,
default: () => "",
},
},
created() {},
mounted() {},
methods: {},
};
</script>
<style lang='scss' scoped>
$item-title-height: 38px;
$item_title_content-height: calc(100% - 38px);
.lr_titles {
box-sizing: border-box;
:deep(.border-box-content) {
box-sizing: border-box;
padding: 6px 16px 0px;
}
.item_title {
height: $item-title-height;
line-height: $item-title-height;
width: 100%;
color: #1976d2;
text-align: center;
// background: linear-gradient(to right, transparent, #f5f7fa, transparent);
position: relative;
display: flex;
align-items: center;
justify-content: center;
.zuo,
.you {
width: 58px;
height: 14px;
background-image: url("../../assets/img/titles/zuo.png");
}
.you {
transform: rotate(180deg);
}
.title-inner {
font-weight: 900;
letter-spacing: 2px;
background: linear-gradient(
92deg,
#666666 0%,
#1976d2 48.8525390625%,
#1565c0 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.item_title_content {
height: $item_title_content-height;
}
.item_title_content_def {
width: 100%;
height: 100%;
}
}
</style>

43
src/components/kong.vue Normal file
View File

@@ -0,0 +1,43 @@
<template>
<div class='kong'>
<slot></slot>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
};
},
props:{
data:{
type:Array,
default:()=>[]
}
},
computed: {},
methods: {
init(){
},
},
created() {
},
mounted() {
},
beforeDestroy() {
},
}
</script>
<style lang='scss' scoped>
.kong{
width: 100%;
height: 100%;
}
</style>

View File

@@ -0,0 +1,49 @@
/*
* @Author: szy
* @Date: 2022-02-16 17:08:26
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-25 10:12:36
* @FilePath: \yhht-ui\yhht-ui\packagesEle\getXY\src\main.js
*/
import Vue from 'vue';
import Main from './message.vue';
import {isObject,isVNode} from '@/lib/types'
let Message = Vue.extend(Main);
let instance;
var message = function (options) {
if (Vue.prototype.$isServer) return;
if(!instance){
instance = new Message({
data: {
...options
},
});
instance.$mount();
}
instance.destroy=()=>{
document.body.removeChild(instance.$el);
instance&&instance.$destroy()
instance=null
return null
}
instance.init(options)
document.body.appendChild(instance.$el);
return instance;
};
['success', 'warning', 'info', 'error'].forEach(type => {
message[type] = (options) => {
if (isObject(options) && !isVNode(options)) {
return message({
...options,
type
});
}
return message({
type,
text: options
});
};
});
export default message;

View File

@@ -0,0 +1,74 @@
<!--
* @Author: szy
* @Date: 2022-03-02 17:07:40
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-26 11:41:27
* @FilePath: \web-pc\src\pages\big-screen\components\message\message.vue
-->
<template>
<div class="messages" v-if="visible">
<svg fill="none" viewBox="0 0 16 16" width="1em" height="1em" class="message-icon">
<path fill="currentColor" d="M15 8A7 7 0 101 8a7 7 0 0014 0zM8.5 4v5.5h-1V4h1zm-1.1 7h1.2v1.2H7.4V11z"
fill-opacity="0.9" v-if="'warning'==type"></path>
</svg>
{{ text }}
</div>
</template>
<script>
export default {
data() {
return {
visible: false,
text: "",
type:'warning'
};
},
props: {},
created() { },
mounted() { },
methods: {
init(param) {
clearTimeout(this.timer);
this.visible = true;
this.text = param.text || "";
this.type = param.type || "success";
this.timer = setTimeout(() => {
this.visible = false;
clearTimeout(this.timer);
}, 2000);
},
},
};
</script>
<style lang='scss' scoped>
.messages {
position: fixed;
min-width: 200px;
top: 160px;
left: 50%;
transform: translate(-50%, 0);
border: solid 1px #4b4b4b;
// box-shadow: 0 16px 24px rgba(0, 0, 0, 0.14), 0 6px 30px rgba(0, 0, 0, 12%),
// 0 8px 10px rgba(0, 0, 0, 20%), inset 0 0.5px 0 #5e5e5e,
// inset 0.5px 0 0 #5e5e5e, inset 0 -0.5px 0 #5e5e5e, inset -0.5px 0 0 #5e5e5e;
width: fit-content;
border-radius: 6px;
display: flex;
align-items: center;
z-index: 999;
color: rgba(255, 255, 255, 0.9);
background-color: #242424;
line-height: 22px;
font-size: 14px;
padding: 13px 16px;
.message-icon {
color: #cf6e2d;
font-size: 20px;
margin-right: 8px;
fill: currentColor;
}
}
</style>

View File

@@ -0,0 +1,64 @@
<template>
<div class='reacquire flex justify-center blocks cursor-pointer' :style="{ lineHeight: lineHeight }"
@click="getData">
<span>
重新获取
</span>
</div>
</template>
<script>
export default {
components: {},
props: {
lineHeight: {
type: String,
default: '200px'
}
},
data() {
return {
};
},
computed: {},
methods: {
init() {
},
getData(e){
this.$emit("onclick",e)
}
},
created() {
},
mounted() {
},
beforeDestroy() {
},
}
</script>
<style lang='scss' scoped>
.reacquire {
user-select:none;
color: rgb(168, 168, 168);
span:hover{
color:$primary-color ;
text-decoration: underline;
}
}
.blocks {
width: 100%;
height: 100%;
}
.cursor-pointer {
cursor: pointer;
}
</style>

View File

@@ -0,0 +1,253 @@
<!--
* @Author: wei
* @description: 大屏自适应容器组件
* @LastEditTime: 2022-09-09 16:42:40
-->
<template>
<!-- <section class="screen-box" :style="boxStyle"> -->
<div class="screen-wrapper" ref="screenWrapper" :style="wrapperStyle">
<slot></slot>
</div>
<!-- </section> -->
</template>
<script>
/**
* 防抖函数
* @param {T} fn
* @param {number} delay
* @return
*/
function debounce(fn, delay) {
let timer = null;
return function (...args) {
timer = setTimeout(
() => {
typeof fn === "function" && fn.apply(null, args);
clearTimeout(timer);
},
delay > 0 ? delay : 100
);
};
}
export default {
name: "VScaleScreen",
props: {
width: {
type: [String, Number],
default: 1920,
},
height: {
type: [String, Number],
default: 1080,
},
fullScreen: {
type: Boolean,
default: false,
},
autoScale: {
type: [Object, Boolean],
default: true,
},
selfAdaption: {
type: Boolean,
default: true,
},
delay: {
type: Number,
default: 500,
},
boxStyle: {
type: Object,
default: () => ({}),
},
wrapperStyle: {
type: Object,
default: () => ({}),
},
},
data() {
return {
currentWidth: 0,
currentHeight: 0,
originalWidth: 0,
originalHeight: 0,
onResize: null,
observer: null,
};
},
watch: {
selfAdaption(val) {
if (val) {
this.resize();
this.addListener();
} else {
this.clearListener();
this.clearStyle();
}
},
},
computed: {
screenWrapper() {
return this.$refs["screenWrapper"];
},
},
methods: {
initSize() {
return new Promise((resolve, reject) => {
// console.log("初始化样式");
//给父元素设置 overflow:hidden
this.screenWrapper.parentNode.style.overflow = "hidden";
this.screenWrapper.parentNode.scrollLeft = 0;
this.screenWrapper.parentNode.scrollTop = 0;
this.$nextTick(() => {
// region 获取大屏真实尺寸
if (this.width && this.height) {
this.currentWidth = this.width;
this.currentHeight = this.height;
} else {
this.currentWidth = this.screenWrapper.clientWidth;
this.currentHeight = this.screenWrapper.clientHeight;
}
// endregion
// region 获取画布尺寸
if (!this.originalHeight || !this.originalWidth) {
this.originalWidth = window.screen.width;
this.originalHeight = window.screen.height;
}
// endregion
resolve();
});
});
},
updateSize() {
if (this.currentWidth && this.currentHeight) {
this.screenWrapper.style.width = `${this.currentWidth}px`;
this.screenWrapper.style.height = `${this.currentHeight}px`;
} else {
this.screenWrapper.style.width = `${this.originalWidth}px`;
this.screenWrapper.style.height = `${this.originalHeight}px`;
}
},
handleAutoScale(scale) {
if (!this.autoScale) return;
const screenWrapper = this.screenWrapper;
const domWidth = screenWrapper.clientWidth;
const domHeight = screenWrapper.clientHeight;
const currentWidth = document.body.clientWidth;
const currentHeight = document.body.clientHeight;
screenWrapper.style.transform = `scale(${scale},${scale}) `;
let mx = Math.max((currentWidth - domWidth * scale) / 2, 0);
let my = Math.max((currentHeight - domHeight * scale) / 2, 0);
if (typeof this.autoScale === "object") {
// @ts-ignore
!this.autoScale.x && (mx = 0);
// @ts-ignore
!this.autoScale.y && (my = 0);
}
// console.log({
// mx,
// my,
// currentWidth,
// currentHeight,
// domWidth,
// domHeight,
// scale,
// });
this.screenWrapper.style.margin = `${my}px ${mx}px`;
},
updateScale() {
const screenWrapper = this.screenWrapper;
// 获取真实视口尺寸
const currentWidth = document.body.clientWidth;
const currentHeight = document.body.clientHeight;
// 获取大屏最终的宽高onResize
const realWidth = this.currentWidth || this.originalWidth;
const realHeight = this.currentHeight || this.originalHeight;
// 计算缩放比例
const widthScale = currentWidth / realWidth;
const heightScale = currentHeight / realHeight;
// console.log({currentWidth, currentHeight,realWidth,realHeight});
// 若要铺满全屏,则按照各自比例缩放
if (this.fullScreen) {
screenWrapper.style.transform = `scale(${widthScale},${heightScale})`;
return false;
}
// 按照宽高最小比例进行缩放
const scale = Math.min(widthScale, heightScale);
this.handleAutoScale(scale);
},
initMutationObserver() {
const screenWrapper = this.screenWrapper;
const observer = (this.observer = new MutationObserver(() => {
this.onResize();
}));
observer.observe(screenWrapper, {
attributes: true,
attributeFilter: ["style"],
attributeOldValue: true,
});
},
clearListener() {
window.removeEventListener("resize", this.onResize);
},
addListener() {
window.addEventListener("resize", this.onResize);
},
clearStyle() {
// console.log("清除");
const screenWrapper = this.screenWrapper;
screenWrapper.parentNode.style.overflow = "auto";
screenWrapper.style = "";
},
async resize() {
if (!this.selfAdaption) {
return;
}
await this.initSize();
this.updateSize();
this.updateScale();
},
},
mounted() {
this.onResize = debounce(() => {
this.resize();
}, this.delay);
this.$nextTick(() => {
if (this.selfAdaption) {
this.resize();
this.addListener();
}
});
},
beforeDestroy() {
this.clearListener();
// this.observer.disconnect()
},
};
//
</script>
<style scoped>
.screen-box {
overflow: hidden;
background-size: 100% 100%;
background: #000;
width: 100vw;
height: 100vh;
}
.screen-wrapper {
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 500ms;
position: relative;
overflow: hidden;
z-index: 100;
transform-origin: left top;
}
</style>

15
src/config/UtilVar.js Normal file
View File

@@ -0,0 +1,15 @@
/*
* @Author: szy
* @Date: 2021-12-06 10:58:24
* @LastEditTime: 2024-08-29 17:46:49
*/
let UtilVar = {
ENC: false, //返回结果是否加密
baseUrl: process.env.VUE_APP_BASE_API,
code: 401,
}
console.log( process.env);
export default UtilVar

11
src/directives/filters.js Normal file
View File

@@ -0,0 +1,11 @@
/*
* @Author: szy
* @Date: 2022-01-11 15:27:31
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-21 14:32:03
* @FilePath: \web-pc\src\directives\filters.js
*/
export function montionFilter (val) {
// console.log(val);
return val ? Number(val).toFixed(2) : '--'
}

429
src/lib/currency.js Normal file
View File

@@ -0,0 +1,429 @@
/*
* @Author: szy
* @Date: 2021-12-06 15:53:24
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-22 09:31:24
* @FilePath: \web-pc\src\lib\currency.js
*/
import router from '@/router'
import { isString, isHtmlElement } from './types'
import UtilVar from "@/config/UtilVar";
export const returnWeek = () => {
var week = new Date().getDay();
switch (week) {
case 1:
return '周一'
case 2:
return '周二'
case 3:
return '周三'
case 4:
return '周四'
case 5:
return '周五'
case 6:
return '周六'
case 0:
return '周日'
}
}
/**
* 获取uuid
*/
export function getUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
})
}
/**
* 是否有权限
* @param {*} key
*/
export function isAuth(key) {
// console.log("key",key,sessionStorage.getItem('permissions'))
return JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== -1 || false
}
export const rowClassName = ({ row, rowIndex }) => {
if (rowIndex % 2 == 0) {
return 'lightColour';
} else {
return 'DarkColor';
}
}
export const getToken = () => {
return localStorage.getItem("token");
}
//跳转当前页面并传参
export const currentQuery = (param) => {
let newParam = { ...param }
for (let i in newParam) {
if (newParam[i] === "") {
delete newParam[i]
}
}
// console.log(newParam)
router.push({
path: router.currentRoute.path,
query: newParam
})
}
/**
* 树形数据转换
* @param {*} data
* @param {*} id
* @param {*} pid
* @param {*} order
*/
export function treeDataTranslate(data, id, pid, order) {
// console.log(Array.isArray(data))
if (data == null || !Array.isArray(data)) {
return [];
}
if (order) {
data.sort(function (a, b) {
return a[order] - b[order];
})
}
// console.log(data)
var res = []
var temp = {}
for (var i = 0; i < data.length; i++) {
temp[data[i][id]] = data[i]
}
for (var k = 0; k < data.length; k++) {
if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
if (!temp[data[k][pid]]['subs']) {
temp[data[k][pid]]['subs'] = []
}
if (!temp[data[k][pid]]['_level']) {
temp[data[k][pid]]['_level'] = 1
}
data[k]['_level'] = temp[data[k][pid]]._level + 1
temp[data[k][pid]]['subs'].push(data[k])
} else {
res.push(data[k])
}
}
// console.log(outurls)
// console.log(res)
return res
}
//带了一个 margin-left
export const dragss = (e, marginleft) => {
let odiv = e.currentTarget.parentElement;
let disX = e.clientX - odiv.offsetLeft;
let disY = e.clientY - odiv.offsetTop;
document.onmousemove = (e) => {
odiv.style.left = e.clientX - disX + marginleft + 'px';
odiv.style.top = e.clientY - disY + 'px';
return false;
};
document.onmouseup = (e) => {
document.onmousemove = null;
document.onmouseup = null;
};
return false;
}
//转base64
export const turnStr = (data) => {
return window.btoa(window.encodeURI(JSON.stringify(data)));
}
// 验证只能输入数字和小数小数且只能输入2位第一位不能输入小数点
// .replace(/[^\d.]/g, '')
// .replace(/\.{2,}/g, '.')
// .replace('.', '$#$')
// .replace(/\./g, '')
// .replace('$#$', '.')
// .replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
// .replace(/^\./g, '')
/**
* 清除登录信息
*/
export function clearLoginInfo() {
router.options.isAddDynamicMenuRoutes = false;
localStorage.removeItem('token')
sessionStorage.removeItem("menuList")
sessionStorage.removeItem("permissions")
}
//对象拼成路径传参
export const convertObj = (data) => {
var _result = [];
for (var key in data) {
var value = data[key];
if (value.constructor == Array) {
value.forEach(function (_value) {
_result.push(key + "=" + _value);
});
} else {
_result.push(key + '=' + value);
}
}
return _result.join('&');
}
//判断浏览器
function getExplorer() {
var explorer = window.navigator.userAgent;
if (explorer.indexOf('MSIE') >= 0) {
return 'ie'; // ie
} else if (explorer.indexOf('Firefox') >= 0) {
return 'Firefox'; // firefox
} else if (explorer.indexOf('Chrome') >= 0) {
return 'Chrome'; // Chrome
} else if (explorer.indexOf('Opera') >= 0) {
return 'Opera'; // Opera
} else if (explorer.indexOf('Safari') >= 0) {
return 'Safari'; // Safari
} else if (!!explorer.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {
return 'IOS';
} else if (u.indexOf('Android') > -1 || u.indexOf('Adr') > -1) {
return 'Android';
} else {
return explorer
}
};
//导出文档流
export const exportFile = (data, name) => {
return new Promise((resolve, reject) => {
let types = getExplorer()
if (types == 'IOS') {
resolve({
success: false,
msg: "请使用设备自带浏览器导出!"
})
return
}
if (data.type && data.type.indexOf('application/vnd.ms-excel') >= 0) {
// console.log(data)
try {
let blob = new Blob([data], {
type:data.type|| 'application/vnd.ms-excel;charset=UTF-8'
})
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, name);
} else {
const link = document.createElement('a')
link.style.display = 'none';
link.href = URL.createObjectURL(blob);
if (types == 'Safari') {
link.download = `${name || "未命名"}`;
} else {
link.download = `${name || "未命名"}.xlsx`;
}
// Safari thinks _blank anchor are pop ups. We only want to set _blank
// target if the browser does not support the HTML5 download attribute.
// This allows you to download files in desktop safari if pop up blocking
// is enabled.
if (typeof link.download === 'unde fined') {
tempLink.setAttribute('target', '_blank');
}
document.body.appendChild(link)
link.click()
// Fixes "webkit blob resource error 1"
let timer = setTimeout(function () {
document.body.removeChild(link)
window.URL.revokeObjectURL(link.href);
clearTimeout(timer)
}, 200)
}
resolve({
success: true,
msg: "导出成功"
})
} catch (error) {
resolve({
success: false,
msg: "未知异常,请联系管理员!"
})
}
} else {
// console.log(data)
readFile(data).then(res => {
resolve(res)
}).catch(err => {
resolve({
success: false,
msg: "未知异常,请联系管理员!"
})
})
}
})
}
//阅读 blod
export const readFile = (data) => {
return new Promise((resole, reject) => {
if (Object.prototype.toString.call(data)==='[object Blob]') {
let reader = new FileReader()
reader.readAsText(data, 'utf-8')
reader.onload = (e) => {
console.log('--导出--', JSON.parse(reader.result))
let result = JSON.parse(reader.result)
if (result.code == UtilVar.code) {
router.push("/login")
}
resole(result)
}
} else {
resole(data)
}
// reader.readAsText(data)
})
}
//element 时间选择
export const shortcuts = [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 89);
picker.$emit('pick', [start, end]);
}
}]
export const pickerOptions = {
shortcuts: shortcuts
}
/**
* 清除相同
* @param {*} origin
* @param {*} target
*/
export const ArrayCleanRepeat = (origin, target) => {
if (target) origin = origin.concat(target);
const result = []
const tagObj = {}
for (const i of origin) {
if (!tagObj[i]) {
result.push(i)
tagObj[i] = 1
}
}
return result
}
/**
* @description:
* @param {file:Object} 文件
* @return {*}
*/
export const beforeUpoads = (file) => {
// console.log(file)
var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
if (
testmsg != 'png' &&
testmsg != 'jpg' &&
testmsg != 'jpeg' &&
testmsg != 'webp'
) {
// testmsg != 'gif' &&
return {
success: false,
msg: "上传图片格式不正确!"
}
}
const if10M = file.size / 1024 / 1024 < 20
if (!if10M) {
return {
success: false,
msg: "上传图片大小不能超过20M!"
}
}
// console.log("上传前",file, this.filelist)
return {
success: true
}
}
//复制文字
export const copy = (value) => {
let transfer = document.createElement('input')
document.body.appendChild(transfer)
transfer.value = value // 这里表示想要复制的内容
transfer.focus()
transfer.select()
if (document.execCommand('copy')) {
document.execCommand('copy')
}
transfer.blur()
document.body.removeChild(transfer)
//选中文字
// let range = document.createRange()
// let referenceNode = this.$refs.xy
// range.selectNodeContents(referenceNode)
// var selection = window.getSelection()
// selection.removeAllRanges()
// selection.addRange(range)
}
// 取出两个数组的不同元素
export const getArrDifference = (arr1, arr2) => {
return arr1.concat(arr2).filter(function (v, i, arr) {
return arr.indexOf(v) === arr.lastIndexOf(v);
});
}
/**
* 表格最大高度
* @param {ElementDom} dom
* @param {Boolean} isPaging 是否拥有分页 false 没有 || true 有 默认有
* @returns
*/
export const tableHeight = (dom,isPaging=true) => {
//定位父级到文档高度
if (isString(dom)) {
dom = document.querySelector(dom)
// if (dom) {
// return window.innerHeight - top
// }
}
if (isHtmlElement(dom)) {
var parent = dom.offsetParent;
var top = dom.offsetTop
if(isPaging){
top= top+ 63 + 4
}else{
top= top+ 16
}
while (parent != null) {
top += parent.offsetTop;
parent = parent.offsetParent;
};
return window.innerHeight - top
}
return null
}
//

93
src/lib/dd-moment.js Normal file
View File

@@ -0,0 +1,93 @@
/*
* @Author: szy
* @Date: 2021-12-16 14:40:18
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-19 14:44:14
* @FilePath: \web-pc\src\lib\dd-moment.js
*/
const DDmoment = function (date) {
let time;
if (!date) {
time = new Date()
}else if(date){
time=new Date(date);
}
return {
time,
format,
subtract,
getTime,
}
}
/**
* @content 前多少天
* @param days 天 || years 年 || months 月 || weeks 周
* @returns
*/
function subtract(num, type) {
let time = this.time
time.setTime(time.getTime()-getNeedTime(num, type))
time=new Date(time)
return {
time,
format,
getTime
}
}
/**
* @param Yy年 || M 月 || Dd 日 || Hh 时 || m 分 || Ss 秒
* @returns
*/
function format(fmt) {
let date = this.time
let ret;
const opt = {
"Y+": date.getFullYear().toString(), // 年
"y+": date.getFullYear().toString(), // 年
"M+": (date.getMonth() + 1).toString(), // 月
"d+": date.getDate().toString(), // 日
"D+": date.getDate().toString(), // 日
"h+": date.getHours().toString(), // 时
"H+": date.getHours().toString(), // 时
"m+": date.getMinutes().toString(), // 分
"S+": date.getSeconds().toString(), // 秒
"s+": date.getSeconds().toString() // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
};
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) {
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
};
};
return fmt;
}
//时间戳转时间
function getTime() {
return new Date(this.time)
}
//获取需要的时间
function getNeedTime(num, type) {
let time=0
switch (type) {
case "days":
time= 3600 * 1000 * 24 * num;
break;
case "years":
time=3600 * 1000 * 24 *365 *num;
break;
case "months":
time = 3600 * 1000 * 24 *30* num;
break;
case "weeks":
time= 3600 * 1000 * 24 *7* num;
break;
default:
break;
}
return time;
}
export default DDmoment

9
src/lib/index.js Normal file
View File

@@ -0,0 +1,9 @@
import DDmoment from "./dd-moment"
import { colors,colors2 } from "./modules/echarts-options"
import { shortcuts } from "./currency";
export {DDmoment,colors,colors2}
export {
shortcuts
}

46
src/lib/types.js Normal file
View File

@@ -0,0 +1,46 @@
/*
* @Author: szy
* @Date: 2021-12-14 09:15:11
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-25 10:11:04
* @FilePath: \web-pc\src\lib\types.js
*/
export function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key);
};
export function isVNode(node) {
return node !== null && typeof node === 'object' && hasOwn(node, 'componentOptions');
};
// 是否字符串
export function isString2(str) {
return (typeof str == 'string') && str.constructor == String;
}
export function isString(obj) {
return Object.prototype.toString.call(obj) === '[object String]';
}
export function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
export function isNumber(obj) {
return Object.prototype.toString.call(obj) === '[object Number]';
}
// 是否完整的
export function isDef(val) {
return val !== undefined && val !== null;
}
//
export function isKorean(text) {
const reg = /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi;
return reg.test(text);
}
export function isHtmlElement(node) {
return node && node.nodeType === Node.ELEMENT_NODE;
}
export const isUndefined = (val) => {
return val === void 0;
};

52
src/main.js Normal file
View File

@@ -0,0 +1,52 @@
/*
* @Author: szy
* @Date: 2022-01-12 14:05:56
* @LastEditors: Please set LastEditors
* @LastEditTime: 2023-08-07 17:12:07
* @FilePath: \web-pc\src\pages\big-screen\main.js
*/
import Vue from "vue";
import App from "./App.vue";
import router from './router'
import store from './store'
import {loading,borderBox13,digitalFlop,capsuleChart,borderBox8} from '@jiaminghi/data-view'
import { Radio,Button,RadioGroup } from 'element-ui'
import Echart from './components/echart/index.vue'
import ItemWrap from './components/item-wrap/item-wrap.vue'
import Message from './components/message/message.vue'
import Reacquire from './components/reacquire/reacquire.vue'
import Messages from './components/message/message'
import "vue-easytable/libs/theme-default/index.css";
import '@/assets/css/public.scss'
import "@/assets/css/index.scss"
import * as filters from '@/directives/filters'
require('./mock/mock')//是否使用mock
Vue.config.productionTip = false;
// 自定义组件
Vue.component("Echart",Echart)
Vue.component("ItemWrap",ItemWrap)
Vue.component("Message",Message)
Vue.component("Reacquire",Reacquire)
Vue.prototype.$Message = Messages
// element组件
Vue.use(Radio);
Vue.use(Button);
Vue.use(RadioGroup)
// datav组件
Vue.use(loading)
Vue.use(borderBox13)
Vue.use(borderBox8)
Vue.use(digitalFlop)
Vue.use(capsuleChart)
// 全局数据过滤器
Object.keys(filters).forEach(k => Vue.filter(k, filters[k]));
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");

233
src/mock/mock.js Normal file
View File

@@ -0,0 +1,233 @@
import Mock from 'mockjs'
//延时200-600毫秒请求到数据
Mock.setup({
timeout: '200-600'
})
const Random = Mock.Random;
// 用户总览
function countUserNum() {
const a = Mock.mock({
success: true,
data: {
offlineNum:'@integer(1, 100)',
lockNum: '@integer(1, 10)',
totalNum:218
}
})
a.data.onlineNum=a.data.totalNum-a.data.offlineNum-a.data.lockNum
return a
}
// 接口第一个参数url第二个参数请求类型第三个参数响应回调
Mock.mock(new RegExp('countUserNum'), 'get', countUserNum)
// /设备总览
function countDeviceNum() {
const a = Mock.mock({
success: true,
data: {
alarmNum: '@integer(100, 1000)',
offlineNum: '@integer(0, 50)',
totalNum:698
}
})
a.data.onlineNum=a.data.totalNum-a.data.offlineNum
return a
}
Mock.mock(new RegExp('countDeviceNum'), 'get', countDeviceNum)
// /设备总览
function sbtx() {
const a = Mock.mock({
success: true,
data: {
"list|20": [
{
provinceName: "@province()",
cityName: '@city()',
countyName: "@county()",
createTime: "@datetime('yyyy-MM-dd HH:mm:ss')",
deviceId: "6c512d754bbcd6d7cd86abce0e0cac58",
"gatewayno|+1": 10000,
"onlineState|1": [0, 1],
}
]
}
})
return a
}
Mock.mock(new RegExp('sbtx'), 'get', sbtx)
//中间地图
function centermap(options) {
let params = parameteUrl(options.url)
if (params.regionCode && params.regionCode != 'china') {
const a = Mock.mock({
success: true,
data: {
"dataList|30": [
{
name: "@city()",
value: '@integer(1, 1000)'
}
],
regionCode: params.regionCode,//-代表中国
}
})
return a
} else {
const a = Mock.mock({
success: true,
data: {
"dataList|8": [
{
name: "@province()",
value: '@integer(1, 1000)'
}
],
regionCode: 'china',
}
})
return a
}
}
Mock.mock(new RegExp('centermap'), 'get', centermap)
// 报警次数
function alarmNum() {
const a = Mock.mock({
success: true,
data: {
dateList:['2021-11', '2021-12', '2022-01', '2022-02', '2022-03',"2022-04"],
"numList|6":[
'@integer(0, 1000)'
],
"numList2|6":[
'@integer(0, 1000)'
]
}
})
return a
}
Mock.mock(new RegExp('alarmNum'), 'get', alarmNum)
// 实时预警
function ssyj() {
const a = Mock.mock({
success: true,
data: {
"list|40":[{
alertdetail: "@csentence(5,10)",
"alertname|1": ["水浸告警","各种报警"],
alertvalue: "@float(60, 200)",
createtime: "2022-04-19 08:38:33",
deviceid: null,
"gatewayno|+1": 10000,
phase: "A1",
sbInfo: "@csentence(10,18)",
"terminalno|+1": 100,
provinceName: "@province()",
cityName: '@city()',
countyName: "@county()",
}],
}
})
return a
}
Mock.mock(new RegExp('ssyj'), 'get', ssyj)
//安装计划
function installationPlan() {
let num= RandomNumBoth(26,32);
const a = Mock.mock({
["category|"+num]:["@city()"],
["barData|"+num]:["@integer(10, 100)"],
})
let lineData=[],rateData=[];
for (let index = 0; index < num; index++) {
let lineNum = Mock.mock('@integer(0, 100)')+a.barData[index]
lineData.push(lineNum)
let rate = a.barData[index] / lineNum;
rateData.push((rate*100).toFixed(0))
}
a.lineData=lineData
a.rateData=rateData
return {
success: true,
data:a
}
}
Mock.mock(new RegExp('installationPlan'), 'get', installationPlan)
//报警排名
function ranking() {
//多生成几个避免重复 重复会报错
let num =Mock.mock({"list|48":[{ value:"@integer(50,1000)",name:"@city()"}]}).list
// console.log(num);
let newNum =[],numObj={}
num.map(item=>{
if(!numObj[item.name] && newNum.length<8){
numObj[item.name] =true
newNum.push(item)
}
})
let arr = newNum.sort((a,b)=>{
return b.value-a.value
})
let a ={
success:true,
data:arr
}
return a
}
Mock.mock(new RegExp('ranking'), 'get', ranking)
/**
* @description: min ≤ r ≤ max 随机数
* @param {*} Min
* @param {*} Max
* @return {*}
*/
function RandomNumBoth(Min,Max){
var Range = Max - Min;
var Rand = Math.random();
var num = Min + Math.round(Rand * Range); //四舍五入
return num;
}
/**
* @description: 获取路径参数
* @param {*} url
* @return {*}
*/
function parameteUrl(url) {
var json = {}
if (/\?/.test(url)) {
var urlString = url.substring(url.indexOf("?") + 1);
var urlArray = urlString.split("&");
for (var i = 0; i < urlArray.length; i++) {
var urlItem = urlArray[i];
var item = urlItem.split("=");
console.log(item);
json[item[0]] = item[1];
}
return json;
}
return {};
}

41
src/router/index.js Normal file
View File

@@ -0,0 +1,41 @@
/*
* @Author: szy
* @Date: 2022-01-12 14:22:29
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-28 14:53:02
* @FilePath: \web-pc\src\pages\big-screen\router\index.js
*/
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
const routes = [ {
path: '/',
redirect: '/index',
},
{
path: '/home',
name: 'home',
component: () => import(/* webpackChunkName: "LSD.bighome" */ '../views/home.vue'),
children:[
{
path: '/index',
name: 'index',
component: () => import(/* webpackChunkName: "LSD.bighome" */ '../views/indexs/index.vue'),
},
// {
// path: '/test',
// name: 'testMap',
// component: () => import(/* webpackChunkName: "LSD.bighome" */ '../views/test/testMap.vue'),
// }
]
},
];
const router = new VueRouter({
mode: "hash",
// base: process.env.BASE_URL,
routes
});
export default router;

37
src/store/index.js Normal file
View File

@@ -0,0 +1,37 @@
/*
* @Author: your name
* @Date: 2021-07-26 09:32:49
* @LastEditTime: 2022-04-26 09:12:33
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \web-pc\src\pages\big-screen\store\index.js
*/
import Vuex from 'vuex';
import Vue from 'vue';
Vue.use(Vuex)
const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName]=value.default
modules[moduleName].namespaced = true; //打开命名空间
return modules
}, {})
export default new Vuex.Store({
modules,
state: {
},
mutations: {
setCollapsed(state,value){
},
},
actions: {
getUserdata({commit}){
},
},
})

View File

@@ -0,0 +1,56 @@
/*
* @Author: szy
* @Date: 2021-12-06 11:01:16
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-28 15:01:33
* @FilePath: \web-pc\src\store\modules\menus.js
*/
import {isObject} from '@/lib/types'
export default {
state: () => ({
sbtxSwiper: true,//设备提醒轮播
ssyjSwiper:true,//实时预警轮播
isScale:true,//是否进行全局适配
defaultOption: {
step: 4.4, // 数值越大速度滚动越快
hoverStop: true, // 是否开启鼠标悬停stop
openWatch: true, // 开启数据实时监控刷新dom
direction: 1, // 0向下 1向上 2向左 3向右
limitMoveNum: 4, // 开始无缝滚动的数据量 this.dataList.length
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
waitTime: 3000 // 单步运动停止的时间(默认值1000ms)
},
echartsAutoTime:3000,//echarts 图自动请求接口时间
}),
getters: {
//根据菜单路径获取 菜单信息
},
mutations: {
initSwipers(state){
let flags = JSON.parse(localStorage.getItem('settingData'))
// console.log(flags);
if(flags && isObject(flags)){
for (const key in flags) {
if (state.hasOwnProperty.call(flags, key)&&flags.hasOwnProperty.call(flags, key)) {
const element = flags[key];
state[key]=element
}
}
}
},
updateSwiper(state, {val,type}) {
state[type]=val
localStorage.setItem('settingData',JSON.stringify({
sbtxSwiper:state.sbtxSwiper,
ssyjSwiper:state.ssyjSwiper,
aztpSwiper:state.aztpSwiper,
isScale:state.isScale
}))
},
},
actions: {
},
}

75
src/utils/drawMixin.js Normal file
View File

@@ -0,0 +1,75 @@
/*
* @Author: szy
* @Date: 2022-02-28 10:48:02
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-04-26 14:55:41
* @FilePath: \web-pc\src\pages\big-screen\utils\drawMixin.js
*/
// 屏幕适配 mixin 函数
// * 默认缩放值
const scale = {
width: '1',
height: '1',
}
// * 设计稿尺寸px
const baseWidth = 1920
const baseHeight = 1080
// * 需保持的比例默认1.77778
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
export default {
data() {
return {
// * 定时函数
drawTiming: null,
}
},
computed: {
isScale(){
return this.$store.state.setting.isScale
}
},
mounted () {
if(!this.isScale){
return
}
this.calcRate()
window.addEventListener('resize', this.resize)
},
beforeDestroy () {
window.removeEventListener('resize', this.resize)
},
methods: {
calcRate () {
const appRef = this.$refs["appRef"]
if (!appRef) return
// 当前宽高比
const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
if (appRef) {
if (currentRate > baseProportion) {
// 表示更宽
scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
scale.height = (window.innerHeight / baseHeight).toFixed(5)
appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
} else {
// 表示更高
scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)
scale.width = (window.innerWidth / baseWidth).toFixed(5)
appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
}
}
},
resize () {
if(!this.isScale){
return
}
clearTimeout(this.drawTiming)
this.drawTiming = setTimeout(() => {
this.calcRate()
}, 200)
}
},
}

58
src/utils/index.js Normal file
View File

@@ -0,0 +1,58 @@
/*
* @Author: szy
* @Date: 2022-02-23 08:59:26
* @LastEditors: szy
* @LastEditTime: 2022-02-24 17:11:58
* @FilePath: \big-screen-vue-datav\src\utils\index.js
*/
/**
* @param {Function} fn 防抖函数
* @param {Number} delay 延迟时间
*/
export function debounce(fn, delay) {
var timer;
return function () {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
/**
* @param {date} time 需要转换的时间
* @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
*/
export function formatTime(time, fmt) {
if (!time) return '';
else {
const date = new Date(time);
const o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'H+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds(),
'q+': Math.floor((date.getMonth() + 3) / 3),
S: date.getMilliseconds(),
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(
RegExp.$1,
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
);
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length === 1
? o[k]
: ('00' + o[k]).substr(('' + o[k]).length)
);
}
}
return fmt;
}
}

1
src/utils/map/china.json Normal file

File diff suppressed because one or more lines are too long

222
src/utils/map/xzqCode.js Normal file
View File

@@ -0,0 +1,222 @@
/*
* @Author: szy
* @Date: 2022-03-02 09:51:44
* @LastEditors: szy
* @LastEditTime: 2022-03-02 09:51:45
* @FilePath: \web-pc\src\pages\big-screen\utils\map\xzqCode.js
*/
//获取中国行政区 code
// AMap.plugin("AMap.DistrictSearch", function () {
// var districtSearch = new AMap.DistrictSearch({
// // 关键字对应的行政区级别country表示国家
// level: "country",
// // 显示下级行政区级数1表示返回下一级行政区
// subdistrict: 1,
// });
// let xzqCode = {};
// // 搜索所有省/直辖市信息
// districtSearch.search("中国", function (status, result) {
// // console.log(result);
// result.districtList[0].districtList.forEach((item) => {
// // console.log(item);
// xzqCode[item.name] = {
// adcode: item.adcode,
// level: item.level,
// name: item.name,
// };
// });
// });
// xzqCode["中国"] = {
// adcode: "100000",
// level: "country",
// name: "中华人民共和国",
// };
// setTimeout(() => {
// console.log(JSON.stringify(xzqCode),);
// }, 1000);
// });
export default {
"中国": {
"adcode": "100000",
"level": "country",
"name": "中华人民共和国"
},
"新疆维吾尔自治区": {
"adcode": "650000",
"level": "province",
"name": "新疆维吾尔自治区"
},
"湖北省": {
"adcode": "420000",
"level": "province",
"name": "湖北省"
},
"辽宁省": {
"adcode": "210000",
"level": "province",
"name": "辽宁省"
},
"广东省": {
"adcode": "440000",
"level": "province",
"name": "广东省"
},
"内蒙古自治区": {
"adcode": "150000",
"level": "province",
"name": "内蒙古自治区"
},
"黑龙江省": {
"adcode": "230000",
"level": "province",
"name": "黑龙江省"
},
"河南省": {
"adcode": "410000",
"level": "province",
"name": "河南省"
},
"山东省": {
"adcode": "370000",
"level": "province",
"name": "山东省"
},
"陕西省": {
"adcode": "610000",
"level": "province",
"name": "陕西省"
},
"贵州省": {
"adcode": "520000",
"level": "province",
"name": "贵州省"
},
"上海市": {
"adcode": "310000",
"level": "province",
"name": "上海市"
},
"重庆市": {
"adcode": "500000",
"level": "province",
"name": "重庆市"
},
"西藏自治区": {
"adcode": "540000",
"level": "province",
"name": "西藏自治区"
},
"安徽省": {
"adcode": "340000",
"level": "province",
"name": "安徽省"
},
"福建省": {
"adcode": "350000",
"level": "province",
"name": "福建省"
},
"湖南省": {
"adcode": "430000",
"level": "province",
"name": "湖南省"
},
"海南省": {
"adcode": "460000",
"level": "province",
"name": "海南省"
},
"江苏省": {
"adcode": "320000",
"level": "province",
"name": "江苏省"
},
"青海省": {
"adcode": "630000",
"level": "province",
"name": "青海省"
},
"广西壮族自治区": {
"adcode": "450000",
"level": "province",
"name": "广西壮族自治区"
},
"宁夏回族自治区": {
"adcode": "640000",
"level": "province",
"name": "宁夏回族自治区"
},
"浙江省": {
"adcode": "330000",
"level": "province",
"name": "浙江省"
},
// "嘉兴市": {
// "adcode": "330400",
// "level": "city",
// "name": "嘉兴市"
// },
"河北省": {
"adcode": "130000",
"level": "province",
"name": "河北省"
},
"香港特别行政区": {
"adcode": "810000",
"level": "province",
"name": "香港特别行政区"
},
"台湾省": {
"adcode": "710000",
"level": "province",
"name": "台湾省"
},
"澳门特别行政区": {
"adcode": "820000",
"level": "province",
"name": "澳门特别行政区"
},
"甘肃省": {
"adcode": "620000",
"level": "province",
"name": "甘肃省"
},
"四川省": {
"adcode": "510000",
"level": "province",
"name": "四川省"
},
"天津市": {
"adcode": "120000",
"level": "province",
"name": "天津市"
},
"江西省": {
"adcode": "360000",
"level": "province",
"name": "江西省"
},
"云南省": {
"adcode": "530000",
"level": "province",
"name": "云南省"
},
"山西省": {
"adcode": "140000",
"level": "province",
"name": "山西省"
},
"北京市": {
"adcode": "110000",
"level": "province",
"name": "北京市"
},
"吉林省": {
"adcode": "220000",
"level": "province",
"name": "吉林省"
}
}

170
src/views/dishboard.vue Normal file
View File

@@ -0,0 +1,170 @@
<template>
<div class="dashboard">
<!-- 顶部标题 -->
<header class="header">
<h1>碳林</h1>
<span>{{ currentTime }}</span>
</header>
<!-- 主体区域 -->
<div class="main">
<!-- 左侧信息 -->
<div class="panel left-panel">
<div class="card" v-for="(item, index) in leftData" :key="index">
<p>{{ item.title }}</p>
<h2>{{ item.value }}</h2>
</div>
<div class="chart-box">
<v-chart class="chart" :option="carbonFootprintOption" />
</div>
</div>
<!-- 中心地图 -->
<div class="map-container">
<v-chart class="map-chart" :option="mapOption" />
<h2>今日碳减排总量: 8318 kg</h2>
</div>
<!-- 右侧图表 -->
<div class="panel right-panel">
<v-chart class="chart" :option="monthlySpecialLabelOption" />
<v-chart class="chart" :option="monthlyBoxCountOption" />
<v-chart class="chart" :option="boxWeightDistributionOption" />
</div>
</div>
<!-- 底部数据表 -->
<div class="footer">
<el-table :data="tradeData" border>
<el-table-column prop="exchange" label="交易所" />
<el-table-column prop="project" label="项目" />
<el-table-column prop="price" label="价格 (RMB)" />
<el-table-column prop="region" label="地区" />
</el-table>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
import "echarts/map/js/china";
import VChart from "vue-echarts";
export default {
components: { VChart },
data() {
return {
currentTime: new Date().toLocaleString(),
leftData: [
{ title: "在线车数", value: "340 / 569" },
{ title: "当日减碳", value: "334kg" },
{ title: "当日用氢量", value: "334kg" },
{ title: "当日里程", value: "3300km" },
],
tradeData: [
{ exchange: "北京碳交易所", project: "CCER", price: 100, region: "中国·北京" },
{ exchange: "上海环境能源交易所", project: "CCER", price: 98, region: "中国·上海" },
{ exchange: "深圳排放权交易所", project: "CCER", price: 97, region: "中国·深圳" },
{ exchange: "广东碳排放交易所", project: "CCER", price: 96, region: "中国·广东" },
{ exchange: "湖北碳排放交易所", project: "CCER", price: 95, region: "中国·湖北" },
],
// 碳足迹折线图
carbonFootprintOption: {
tooltip: { trigger: "axis" },
legend: { data: ["碳减排量", "行驶里程"] },
xAxis: { type: "category", data: ["1月", "2月", "3月", "4月", "5月", "6月"] },
yAxis: [{ type: "value" }, { type: "value" }],
series: [
{ name: "碳减排量", type: "bar", data: [10000, 20000, 15000, 30000, 25000, 35000] },
{ name: "行驶里程", type: "line", yAxisIndex: 1, data: [10, 20, 18, 25, 22, 28] },
],
},
// 中国地图
mapOption: {
tooltip: { trigger: "item" },
visualMap: { min: 0, max: 100, text: ["高", "低"], calculable: true },
series: [
{
type: "map",
map: "china",
data: [
{ name: "北京", value: 80 },
{ name: "上海", value: 50 },
{ name: "广东", value: 90 },
],
},
],
},
// 特殊标箱情况
monthlySpecialLabelOption: {
tooltip: { trigger: "axis" },
legend: { data: ["空箱", "危险品"] },
xAxis: { type: "category", data: ["1月", "2月", "3月", "4月", "5月"] },
yAxis: { type: "value" },
series: [
{ name: "空箱", type: "line", data: [10, 20, 30, 40, 50] },
{ name: "危险品", type: "line", data: [200, 250, 300, 350, 400] },
],
},
// 月度标箱数
monthlyBoxCountOption: {
tooltip: { trigger: "axis" },
xAxis: { type: "category", data: ["1月", "2月", "3月", "4月", "5月"] },
yAxis: { type: "value" },
series: [{ type: "bar", data: [30000, 40000, 35000, 45000, 38000] }],
},
// 标箱重量分布
boxWeightDistributionOption: {
tooltip: { trigger: "item" },
series: [
{
type: "pie",
radius: ["40%", "70%"],
data: [
{ value: 1234, name: "1~5T" },
{ value: 1234, name: "5~10T" },
{ value: 1234, name: "10~15T" },
],
},
],
},
};
},
mounted() {
this.updateTime();
},
methods: {
updateTime() {
setInterval(() => {
this.currentTime = new Date().toLocaleString();
}, 1000);
},
},
};
</script>
<style scoped>
.dashboard {
background: #0a1931;
color: white;
padding: 20px;
}
.header {
display: flex;
justify-content: space-between;
font-size: 24px;
}
.main {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.map-container {
width: 50%;
text-align: center;
}
.chart {
height: 200px;
}
</style>

278
src/views/home.scss Normal file
View File

@@ -0,0 +1,278 @@
.scale-wrap {
color: #333333;
width: 1920px;
height: 1080px;
overflow: hidden;
// &.pageisScale {
// position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
// transform-origin: left top;
// }
.bg {
width: 100%;
height: 100%;
padding: 16px 16px 10px 16px;
box-sizing: border-box;
background-color: #f5f7fa;
background-image: none;
background-size: cover;
background-position: center center;
}
.host-body {
height: 100%;
.title_wrap {
height: 60px;
background-image: url("../assets/img/top.png");
background-size: cover;
background-position: center center;
position: relative;
margin-bottom: 4px;
.guang {
position: absolute;
bottom: -26px;
background-image: url("../assets/img/guang.png");
background-position: 80px center;
width: 100%;
height: 56px;
.imgs {
width: 320px;
height: 35px;
margin-top: -0.6%;
}
.imgs2 {
width: 236px;
/* height: 60px; */
margin-left: 150px;
margin-top: -9px;
}
}
.zuojuxing,
.youjuxing {
position: absolute;
top: -2px;
width: 140px;
height: 6px;
background-image: url("../assets/img/headers/juxing1.png");
}
.zuojuxing {
left: 11%;
}
.youjuxing {
right: 11%;
transform: rotate(180deg);
}
.timers {
position: absolute;
right: 0;
top: 30px;
font-size: 18px;
display: flex;
align-items: center;
.blq-icon-shezhi02 {
cursor: pointer;
}
}
}
.title {
position: relative;
// width: 500px;
text-align: center;
background-size: cover;
color: transparent;
height: 60px;
line-height: 46px;
.title-text {
font-size: 38px;
font-weight: 900;
letter-spacing: 6px;
width: 100%;
background: linear-gradient(92deg, #2c5aa0 0%, #1e88e5 48.8525390625%, #1976d2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
}
}
.scale-wrap {
.pagetab {
position: absolute;
top: -35px;
display: flex;
.item {
width: 130px;
height: 36px;
border-radius: 18px 0px 0px 18px;
color: #1976d2;
text-indent: 26px;
line-height: 36px;
font-size: 16px;
margin-right: 20px;
background: linear-gradient(to right, rgba(25, 118, 210, 0.15), rgba(25, 118, 210, 0));
}
}
}
.setting {
position: fixed;
width: 100%;
height: 100%;
z-index: 999;
top: 0;
left: 0;
.left_shu {
color: #000;
font-weight: 900;
position: relative;
text-indent: 10px;
padding: 16px 0 10px 0;
&::before {
display: block;
content: " ";
height: 16px;
width: 4px;
border-radius: 2px;
background: #0072FF;
position: absolute;
left: 0px;
}
}
.setting_dislog {
background-color: rgba($color: #000000, $alpha: .3);
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
right: 0;
top: 0;
}
.setting_inner {
box-sizing: border-box;
background: #ffffff;
width: 340px;
height: 100%;
position: absolute;
right: 0px;
top: 0;
z-index: 1;
color: #333333;
box-shadow: 0 8px 10px -5px rgba(0, 0, 0, .1), 0 16px 24px 2px rgba(0, 0, 0, .08), 0 6px 30px 5px rgba(0, 0, 0, .06);
.setting_header {
font-size: 20px;
color: #333333;
font-weight: 900;
text-align: center;
line-height: 40px;
}
.setting_body {
padding: 0px 16px;
box-sizing: border-box;
position: relative;
}
.setting_item {
font-size: 14px;
line-height: 1.5;
// display: flex;
.setting_label {
color: #666666;
}
.setting_label_tip {
font-size: 12px;
color: #999999;
}
}
}
.setting_inner {
animation: rtl-drawer-out .3s;
}
}
.settingShow {
.setting_inner {
animation: rtl-drawer-in .3s 1ms;
}
}
.yh-setting-fade-enter-active {
animation: yh-setting-fade-in .3s;
}
.yh-setting-fade-leave-active {
animation: yh-setting-fade-out .3s;
}
@keyframes yh-setting-fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes yh-setting-fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes rtl-drawer-in {
0% {
transform: translate(100%, 0)
}
100% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0)
}
}
@keyframes rtl-drawer-out {
0% {
transform: translate(0, 0)
}
100% {
transform: translate(100%, 0)
}
}

125
src/views/home.vue Normal file
View File

@@ -0,0 +1,125 @@
<!--
* @Author: szy
* @Date: 2022-01-12 14:23:32
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-09-09 14:47:24
* @FilePath: \web-pc\src\pages\big-screen\view\home.vue
-->
<template>
<!-- <div id="index" ref="appRef" class="index_home" :class="{ pageisScale: isScale }"> -->
<ScaleScreen
:width="1920"
:height="1080"
class="scale-wrap"
:selfAdaption="$store.state.setting.isScale"
>
<div class="bg">
<dv-loading v-if="loading">Loading...</dv-loading>
<div v-else class="host-body">
<!-- 头部 s -->
<div class="d-flex jc-center title_wrap">
<div class="zuojuxing"></div>
<div class="youjuxing"></div>
<div class="guang">
<!-- <p class="title-name">广州开发区交投氢能</p> -->
<!-- <img src="@/assets/img/logo.png" alt="" class="imgs"/> -->
<img src="@/assets/img/ln_logo.png" alt="" class="imgs2" />
</div>
<div class="d-flex jc-center">
<div class="title">
<!--箱箱碳林可视化平台-->
<!--嘉兴海港碳服务平台-->
<!--2025.4.1 szy -->
<span class="title-text">Lingniu ESG Link</span>
</div>
</div>
<div class="timers">
{{ dateYear }} {{ dateWeek }} {{ dateDay }}
<!-- <button class="selectTime">选择日期</button> -->
<i
class="blq-icon-shezhi02"
style="margin-left: 10px"
@click="showSetting"
></i>
</div>
</div>
<!-- 头部 e-->
<!-- 内容 s-->
<router-view></router-view>
<!-- 内容 e -->
</div>
</div>
<Setting ref="setting" />
</ScaleScreen>
<!-- </div> -->
</template>
<script>
import { formatTime } from "../utils/index.js";
import Setting from "./setting.vue";
import ScaleScreen from "@/components/scale-screen/scale-screen.vue";
export default {
components: { Setting, ScaleScreen },
data() {
return {
timing: null,
loading: true,
dateDay: null,
dateYear: null,
dateWeek: null,
weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
};
},
filters: {
numsFilter(msg) {
return msg || 0;
},
},
computed: {},
created() {},
mounted() {
this.timeFn();
this.cancelLoading();
},
beforeDestroy() {
clearInterval(this.timing);
},
methods: {
showSetting() {
this.$refs.setting.init();
},
timeFn() {
this.timing = setInterval(() => {
this.dateDay = formatTime(new Date(), "HH: mm: ss");
this.dateYear = formatTime(new Date(), "yyyy-MM-dd");
this.dateWeek = this.weekday[new Date().getDay()];
}, 1000);
},
cancelLoading() {
let timer = setTimeout(() => {
this.loading = false;
clearTimeout(timer);
}, 500);
},
},
};
</script>
<style lang="scss">
@import "./home.scss";
// 31abe3
.selectTime {
color: #31abe3;
background: transparent;
border: none;
}
.title-name {
color: white;
font-size: 30px;
font-weight: 600;
margin-left: 20px;
font-family: "Microsoft YaHei", "微软雅黑", "SimHei", "PingFang SC",
"Hiragino Sans GB", sans-serif;
}
</style>

View File

@@ -0,0 +1,155 @@
<!-- MapFlyLine.vue -->
<template>
<div class="flyline-container" ref="container">
<canvas ref="canvas" class="flyline-canvas"></canvas>
</div>
</template>
<script>
export default {
name: 'MapFlyLine',
props: {
// 地图实例(需要从父组件传递)
mapData: {
type: Object,
required: true
},
// 飞线数据
data: {
type: Array,
default: () => []
},
// 配置项
config: {
type: Object,
default: () => ({})
}
},
data() {
return {
ctx: null,
animationFrame: null,
defaultConfig: {
color: '#4f99d3',
lineWidth: 1,
animationSpeed: 0.02,
maxLength: 0.3,
curvature: 0.3
}
}
},
computed: {
mergedConfig() {
return { ...this.defaultConfig, ...this.config }
}
},
mounted() {
this.initCanvas()
this.startAnimation()
window.addEventListener('resize', this.handleResize)
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize)
cancelAnimationFrame(this.animationFrame)
},
watch: {
data: {
deep: true,
handler() {
this.drawLines()
}
}
},
methods: {
initCanvas() {
const canvas = this.$refs.canvas
const container = this.$refs.container
canvas.width = container.offsetWidth
canvas.height = container.offsetHeight
this.ctx = canvas.getContext('2d')
this.ctx.globalCompositeOperation = 'lighter'
},
handleResize() {
this.initCanvas()
this.drawLines()
},
startAnimation() {
const animate = () => {
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height)
this.drawLines()
this.animationFrame = requestAnimationFrame(animate)
}
animate()
},
drawLines() {
if (!this.data.length) return
this.data.forEach(line => {
const from = this.mapInstance.convertToPixel(...line.from)
const to = this.mapInstance.convertToPixel(...line.to)
this.drawCurve(
from,
from,
to,
to,
line.color || this.mergedConfig.color
)
})
},
drawCurve(x1, y1, x2, y2, color) {
const ctx = this.ctx
const cp = this.calculateControlPoint(x1, y1, x2, y2)
// 飞线渐变效果
const gradient = ctx.createLinearGradient(x1, y1, x2, y2)
gradient.addColorStop(0, color)
gradient.addColorStop(1, color + '00')
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.quadraticCurveTo(cp.x, cp.y, x2, y2)
// 创建虚线动画效果
ctx.setLineDash([5, 3])
ctx.lineDashOffset = -performance.now() * this.mergedConfig.animationSpeed
ctx.strokeStyle = gradient
ctx.lineWidth = this.mergedConfig.lineWidth
ctx.stroke()
},
calculateControlPoint(x1, y1, x2, y2) {
// 计算曲线控制点(贝塞尔曲线)
const curvature = this.mergedConfig.curvature
const dx = x2 - x1
const dy = y2 - y1
return {
x: (x1 + x2) / 2 + dy * curvature,
y: (y1 + y2) / 2 - dx * curvature
}
}
}
}
</script>
<style scoped>
.flyline-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.flyline-canvas {
width: 100%;
height: 100%;
}
</style>

View File

@@ -0,0 +1,142 @@
<template>
<div>
<div ref="chart" class="chart-container"></div>
</div>
</template>
<script>
import echarts from "echarts";
import { currentGET } from "api/modules";
export default {
data() {
return {
showPercentage: true, // 默认显示数量
chartData: [
[
{ modelName: "冷藏", total: 190 },
{ modelName: "普货", total: 40 },
// { name: '海格20%', value: 160 },
// { name: '宇通20%', value: 260 },
// { name: '其它10%', value: 260 }
],
],
colors: ["#1976d2", "#ff9800"],
//colors: ["#00E5FF", "#FF5733", "#FFBF00", "#5CDB95"]
};
},
mounted() {
this.getData();
},
methods: {
getData() {
currentGET("big5").then((res) => {
if (res.code == 0) {
// 确保接口返回的code正确
// 转换数据结构为饼图需要的格式
this.chartData = [
res.data.map((item) => ({
name: item.modelName,
value: item.total,
})),
];
console.log("车型分布");
console.log(this.chartData);
//未显示成功,没有用到,后台增加模拟数据
//增加模拟数据
// this.chartData.push([{name: '氢能集卡', value: 20}]);
// this.chartData.push({name: '氢能叉车', value: 8});
// this.chartData.push({name: '无人机', value: 5});
// this.chartData.push({name: '装载机', value: 10});
this.initChart();
}
});
},
initChart() {
const myChart = echarts.init(this.$refs.chart); // 修复变量名不一致问题
let option = {
title: {
text: "",
left: "center",
textStyle: {
color: "#666666", // 将原来的 #999 改为更亮的灰色
fontWeight: "normal",
fontSize: 12,
},
},
series: this.chartData.map(function (data, idx) {
var top = idx * 33.3;
return {
type: "pie",
radius: [40, 70],
top: top + "%",
height: "33.33%",
left: "center",
width: "600px",
itemStyle: {
borderColor: "orange",
borderWidth: 1,
},
label: {
alignTo: "edge",
formatter: ({ name, value, percent }) =>
`{name|${name}}\n {value|${value}辆} {percent|${percent}%}`,
minMargin: 5,
edgeDistance: 10,
lineHeight: 20,
rich: {
name: {
// 新增 name 样式
fontSize: 12,
color: "#333333", // 使用深色
padding: [0, 0, 5, 0],
},
value: {
fontSize: 12,
color: "#1976d2",
padding: [0, 5, 0, 0],
},
percent: {
fontSize: 12,
color: "#ff9800", // 保留橙色
},
},
},
labelLine: {
length: 40,
length2: 15,
maxSurfaceAngle: 80,
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < myChart.getWidth() / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points,
};
},
data: data,
};
}),
};
option && myChart.setOption(option);
this.chart = myChart;
},
toggleMode() {
this.showPercentage = !this.showPercentage;
this.initChart(); // 重新渲染图表
},
},
};
</script>
<style scoped>
.chart-container {
width: 100%;
height: 800px;
}
</style>

View File

@@ -0,0 +1,837 @@
<!--
* @Author: szy
* @Date: 2022-03-01 11:17:39
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-09-29 15:50:18
* @FilePath: \web-pc\src\pages\big-screen\view\indexs\center-map.vue
-->
<template>
<div class="centermap">
<div class="maptitle">
<div class="zuo"></div>
<span class="titletextBefore">今年累计碳减排<span class="titletext">{{ maptitle }}</span>{{ maptitle2 }}</span>
<div class="you"></div>
</div>
<div class="mapwrap">
<dv-border-box-13>
<div class="quanguo" @click="getData('china')" v-if="code !== 'china'">
中国
</div>
<div class="quanguo1" @click="goToPage()" v-if="showType === 1">
车辆实况
</div>
<div class="quanguo2" @click="changeShow1()" :style="{ backgroundColor: currentBgColor2 }">
<div >车辆信息</div>
</div>
<div class="quanguo3" @click="changeShow2()" :style="{ backgroundColor: currentBgColor3 }">
<div >加氢站</div>
</div>
<Echart id="CenterMap" :options="options" ref="CenterMap" />
<!-- <dv-flyline-chart :config="config" style="width:100%;height:100%;" /> -->
</dv-border-box-13>
</div>
</div>
</template>
<script>
import xzqCode from "../../utils/map/xzqCode";
import { currentGET } from "api/modules";
import * as echarts from "echarts";
import { GETNOBASE } from "api";
import { currentPOST } from "@/api";
export default {
data() {
return {
maptitle: "2536238",
maptitle2:'',
options: {},
code: "china", //china 代表中国 其他地市是行政编码
//code:"440000",
echartBindClick: false,
isSouthChinaSea: false, //是否要展示南海群岛 修改此值请刷新页面
currentMap : 'china', // 当前显示的地图层级
showType: 1, //显示内容类型: 1车辆信息2加氢站信息
currentBgColor2:'',
currentBgColor3:'',
};
},
created() {},
mounted() {
console.log(xzqCode);
this.getYearData();
this.showType = 1;
this.currentBgColor2 = '#1976d2';
this.getData("china");
//this.getData("440000");
},
methods: {
changeShow1(){
this.showType = 1;
this.currentBgColor2 = '#1976d2';
this.currentBgColor3 = '';
this.getData(this.code);
},
changeShow2(){
this.currentBgColor2 = '';
this.currentBgColor3 = '#1976d2';
this.showType = 2;
this.getData(this.code);
},
goToPage() {
//window.open("http://localhost:9528/vehicle-management/vehicle-state?"+this.code, "_blank");
window.open("http://47.100.49.118:8090/vehicle-lnSituation?"+this.code, "_blank");
//window.open("http://127.0.0.1:9528/vehicle-lnSituation?"+this.code, "_blank");
//window.open("http://192.168.0.219:9528/vehicle-lnSituation?"+this.code, "_blank");
},
parseAdcodeLevel(adcode) {
const codeStr = String(adcode);
if (codeStr.endsWith('0000')) return 'province'; // 省级(如 440000
if (codeStr.endsWith('00')) return 'city'; // 市级(如 440300
return 'district'; // 区县级(如 440305
},
getYearData() {
currentGET("big3").then((res) => {
console.log('年度碳减排量');
console.log(res);
//this.maptitle = res.data.yearCarbon ; //单位kg
this.maptitle = res.data.yearCarbonTon ; //单位吨
this.maptitle2 = '吨';
});
},
getData(code) {
console.log("code", code);
this.currentMap = this.parseAdcodeLevel(code);
//2025.9.10 szy 增加showType 分类处理1时处理车辆信息2时处理加氢站信息
if(this.showType === 1){
currentGET("big9", { regionCode: code, adcodeLevel: this.currentMap }).then((res) => {
console.log("map车辆分布", res);
//if (res.success)
if (res.status) {
this.getGeojson(res.data.regionCode, res.data.dataList);
this.mapclick();
} else {
this.$Message.warning(res.msg);
}
});
}else if(this.showType === 2){
currentGET("big10", { regionCode: code, adcodeLevel: this.currentMap }).then((res) => {
console.log("加氢站_map分布", res);
//if (res.success)
if (res.status) {
this.getGeojson2(res.data.regionCode, res.data.dataList);
this.mapclick();
} else {
this.$Message.warning(res.msg);
}
});
}
},
/**
* @description: 获取geojson
* @param {*} name china 表示中国 其他省份行政区编码
* @param {*} mydata 接口返回列表数据
* @return {*}
*/
async getGeojson(name, mydata) {
this.code = name;
this.currentMap = name;
console.log('当前地图层级');
console.log(this.currentMap);
//如果要展示南海群岛并且展示的是中国的话
let geoname=name
if (this.isSouthChinaSea && name == "china") {
geoname = "chinaNanhai";
}
//如果有注册地图的话就不用再注册 了
let mapjson = echarts.getMap(name);
console.log('已经是否已存在的地图数据');
if (mapjson) {
mapjson = mapjson.geoJson;
}
else
{
//console.log('当前未注册地图');
mapjson = await GETNOBASE(`./map-geojson/${geoname}.json`).then((res) => {
return res;
});
echarts.registerMap(name, mapjson);
}
console.log(mapjson);
let cityCenter = {};
let arr = mapjson.features;
//根据geojson获取省份中心点
arr.map((item) => {
cityCenter[item.properties.name] =
item.properties.centroid || item.properties.center;
});
let newData = [];
mydata.map((item) => {
if (cityCenter[item.name]) {
if(item.vehicleTotal===undefined || item.vehicleTotal===null ){
item.vehicleTotal = 0;
}
if(item.onLineCount===undefined || item.onLineCount===null){
item.onLineCount = 0;
}
if(item.dayMileage===undefined || item.dayMileage===null){
item.dayMileage = 0;
}
if(item.dayHydrogen===undefined || item.dayHydrogen===null){
item.dayHydrogen = 0;
}
if(item.dayCarbon===undefined || item.dayCarbon===null){
item.dayCarbon = 0;
}
newData.push({
name: item.name,
value: cityCenter[item.name].concat(item.vehicleTotal).concat(item.onLineCount).concat(item.dayMileage).concat(item.dayHydrogen).concat(item.dayCarbon),
});
}
});
console.log('开始初始化地图');
console.log(newData);
this.init(name, mydata, newData);
},
/**
* @description: 获取geojson
* @param {*} name china 表示中国 其他省份行政区编码
* @param {*} mydata 接口返回列表数据
* @return {*}
*/
async getGeojson2(name, mydata) {
this.code = name;
this.currentMap = name;
console.log('加氢站_当前地图层级');
console.log(this.currentMap);
//如果要展示南海群岛并且展示的是中国的话
let geoname=name
if (this.isSouthChinaSea && name == "china") {
geoname = "chinaNanhai";
}
//如果有注册地图的话就不用再注册 了
let mapjson = echarts.getMap(name);
console.log('加氢站_已经是否已存在的地图数据');
if (mapjson) {
mapjson = mapjson.geoJson;
}
else
{
//console.log('当前未注册地图');
mapjson = await GETNOBASE(`./map-geojson/${geoname}.json`).then((res) => {
return res;
});
echarts.registerMap(name, mapjson);
}
console.log(mapjson);
let cityCenter = {};
let arr = mapjson.features;
//根据geojson获取省份中心点
arr.map((item) => {
cityCenter[item.properties.name] =
item.properties.centroid || item.properties.center;
});
let newData = [];
mydata.map((item) => {
if (cityCenter[item.name]) {
if(item.siteTotalCount===undefined || item.siteTotalCount===null ){
item.siteTotalCount = 0;
}
if(item.siteCount===undefined || item.siteCount===null){
item.siteCount = 0;
}
newData.push({
name: item.name,
value: cityCenter[item.name].concat(item.siteTotalCount).concat(item.siteCount),
});
}
});
console.log('加氢站_开始初始化地图');
console.log(newData);
this.init2(name, mydata, newData);
},
init(name, data, data2) {
// console.log('init_data');
// console.log(data);
// console.log('init_data2');
// console.log(data2);
let top = 45;
let zoom = 1.05;
let option = {
backgroundColor: "rgba(0,0,0,0)",
tooltip: {
show: false,
},
legend: {
show: false,
},
visualMap: {
left: 20,
bottom: 20,
pieces: [
// { gte: 1000, label: "1000辆以上" }, // 不指定 max表示 max 为无限大Infinity
// { gte: 600, lte: 999, label: "600-999辆" },
// { gte: 200, lte: 599, label: "200-599辆" },
// { gte: 50, lte: 199, label: "49-199辆" },
// { gte: 10, lte: 49, label: "10-49辆" },
// { lte: 9, label: "1-9辆" }, // 不指定 min表示 min 为无限大(-Infinity
{ gte: 500, label: "500 辆以上" }, // 不指定 max表示 max 为无限大Infinity
{ gte: 100, lte: 500, label: "100-500 辆" },
{ gte: 50, lte: 100, label: "50-100 辆" },
{ lte: 50, label: "1-50 辆" },// 不指定 min表示 min 为无限大(-Infinity
],
inRange: {
// 渐变颜色,从小到大
color: [
// "#c3d7df",
// "#5cb3cc",
// "#8abcd1",
// "#66a9c9",
// "#2f90b9",
// "#1781b5",
"#6EC3F7",
"#2196F3",
"#1565C0",
"#0D47A1",
],
},
textStyle: {
color: "#333333",
},
},
geo: {
map: name,
roam: false,
selectedMode: false, //是否允许选中多个区域
zoom: zoom,
top: top,
// aspectScale: 0.78,
show: false,
},
series: [
{
name: "MAP",
type: "map",
map: name,
// zlevel: 2,
// aspectScale: 0.78,
data: data,
//data: [1,100],
selectedMode: false, //是否允许选中多个区域
zoom: zoom,
geoIndex: 1,
top: top,
tooltip: {
show: true,
formatter: function (params) {
//console.log("series 1 formatter");
//console.log(params);
if (params.data) {
//return params.name + "" + params.data["value"][2];
//return params.name + "" + params.data.vehicleTotal + "辆";
return `${params.name}<br>车辆总数: ${params.data.vehicleTotal}<br>GPS在线数: ${params.data.onLineCount}<br>当日里程: ${params.data.dayMileage}km<br>当日用氢量: ${params.data.dayHydrogen}kg<br>当日减碳: ${params.data.dayCarbon}kg`;
} else {
return params.name;
}
},
backgroundColor: "rgba(0,0,0,.6)",
borderColor: "rgba(147, 235, 248, .8)",
textStyle: {
color: "#333333",
},
},
label: {
show: false,
color: "#000",
// position: [-10, 0],
formatter: function (val) {
// console.log(val)
if (val.data !== undefined) {
return val.name.slice(0, 2);
} else {
return "";
}
},
rich: {},
},
emphasis: { //高亮时显示
label: {
show: false,
},
itemStyle: {
areaColor: "#e3f2fd",
borderWidth: 1,
},
},
itemStyle: {
borderColor: "rgba(147, 235, 248, .8)",
borderWidth: 1,
areaColor: {
type: "radial",
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [
{
offset: 0,
color: "rgba(147, 235, 248, 0)", // 0% 处的颜色
},
{
offset: 1,
color: "rgba(147, 235, 248, .2)", // 100% 处的颜色
},
],
globalCoord: false, // 缺为 false
},
shadowColor: "rgba(128, 217, 248, .3)",
shadowOffsetX: -2,
shadowOffsetY: 2,
shadowBlur: 10,
},
},
{
data: data2,
type: "effectScatter",
coordinateSystem: "geo",
symbolSize: function (val) {
return 4;
// return val[2] / 50;
},
legendHoverLink: true,
showEffectOn: "render",
rippleEffect: {
// period: 4,
scale: 6,
color: "rgba(255,255,255, 1)",
brushType: "fill",
},
tooltip: {
show: false,
//trigger: "item",
formatter: function (params) {
//console.log("series 2 formatter");
//console.log(params);
if (params.data) {
console.log("params.data");
console.log(params.data);
console.log(params.data.name + "\n 车辆总数:"+params.data["value"][2] + "\n GPS在线总数" + params.data["value"][3]);
return params.data.name + "<br> 车辆总数:"+params.data["value"][2] + "<br> GPS在线总数" + params.data["value"][3] + "<br>当日里程: " + params.data["value"][4] + "km<br>当日用量: " + params.data["value"][5] + "kg<br>当日减碳: " + params.data["value"][6] + "kg";
//return '${params.name} <br />车辆总数:${params.data[value][2]} <br /> GPS在线总数${ params.data.[value][3]}';
}
},
backgroundColor: "rgba(0,0,0,.6)",
borderColor: "rgba(147, 235, 248, .8)",
textStyle: {
color: "#333333",
},
},
label: {
formatter: (param) => {
//return param.name.slice(0, 2) + "\n 车辆总数:"+param.data["value"][2] + "\n GPS在线数"+param.data["value"][3]; //2025.03.28
//return param.name.slice(0, 2) + "\n "+param.data["value"][2]; //2025.03.31
return param.name.slice(0, 2) ;
},
fontSize: 11,
offset: [0, 2],
position: "bottom",
textBorderColor: "#333333",
textShadowColor: "#000",
textShadowBlur: 10,
textBorderWidth: 0,
color: "#333333",
show: true,
},
// colorBy: "data",
itemStyle: {
color: "rgba(255,255,255,1)",
borderColor: "rgba(2255,255,255,2)",
borderWidth: 4,
shadowColor: "#000",
shadowBlur: 10,
},
},
],
//动画效果
// animationDuration: 1000,
// animationEasing: 'linear',
// animationDurationUpdate: 1000
};
this.options = option;
},
//加氢站信息
init2(name, data, data2) {
// console.log('加氢站init_data');
// console.log(data);
// console.log('加氢站init_data2');
// console.log(data2);
let top = 45;
let zoom = 1.05;
let option = {
backgroundColor: "rgba(0,0,0,0)",
tooltip: {
show: false,
},
legend: {
show: false,
},
visualMap: {
left: 20,
bottom: 20,
pieces: [
{ gte: 100, label: "100 座以上" }, // 不指定 max表示 max 为无限大Infinity
{ gte: 30, lte: 100, label: "30-100 座" },
{ gte: 10, lte: 30, label: "10-30 座" },
{ lte: 10, label: "1-10 座" },// 不指定 min表示 min 为无限大(-Infinity
],
inRange: {
// 渐变颜色,从小到大
color: [
// "#c3d7df",
// "#5cb3cc",
// "#8abcd1",
// "#66a9c9",
// "#2f90b9",
// "#1781b5",
"#6EC3F7",
"#2196F3",
"#1565C0",
"#0D47A1",
],
},
textStyle: {
color: "#333333",
},
},
geo: {
map: name,
roam: false,
selectedMode: false, //是否允许选中多个区域
zoom: zoom,
top: top,
// aspectScale: 0.78,
show: false,
},
series: [
{
name: "MAP",
type: "map",
map: name,
// zlevel: 2,
// aspectScale: 0.78,
data: data,
//data: [1,100],
selectedMode: false, //是否允许选中多个区域
zoom: zoom,
geoIndex: 1,
top: top,
tooltip: {
show: true,
formatter: function (params) {
//console.log("series 1 formatter");
//console.log(params);
if (params.data) {
//return params.name + "" + params.data["value"][2];
//return params.name + "" + params.data.vehicleTotal + "辆";
return `${params.name}<br>加氢站总数: ${params.data.siteTotalCount}<br>当前运营总数: ${params.data.siteCount}`;
} else {
return params.name;
}
},
backgroundColor: "rgba(0,0,0,.6)",
borderColor: "rgba(147, 235, 248, .8)",
textStyle: {
color: "#333333",
},
},
label: {
show: false,
color: "#000",
// position: [-10, 0],
formatter: function (val) {
// console.log(val)
if (val.data !== undefined) {
return val.name.slice(0, 2);
} else {
return "";
}
},
rich: {},
},
emphasis: { //高亮时显示
label: {
show: false,
},
itemStyle: {
areaColor: "#e3f2fd",
borderWidth: 1,
},
},
itemStyle: {
borderColor: "rgba(147, 235, 248, .8)",
borderWidth: 1,
areaColor: {
type: "radial",
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [
{
offset: 0,
color: "rgba(147, 235, 248, 0)", // 0% 处的颜色
},
{
offset: 1,
color: "rgba(147, 235, 248, .2)", // 100% 处的颜色
},
],
globalCoord: false, // 缺为 false
},
shadowColor: "rgba(128, 217, 248, .3)",
shadowOffsetX: -2,
shadowOffsetY: 2,
shadowBlur: 10,
},
},
{
data: data2,
type: "effectScatter",
coordinateSystem: "geo",
symbolSize: function (val) {
return 4;
// return val[2] / 50;
},
legendHoverLink: true,
showEffectOn: "render",
rippleEffect: {
// period: 4,
scale: 6,
color: "rgba(255,255,255, 1)",
brushType: "fill",
},
tooltip: {
show: false,
//trigger: "item",
formatter: function (params) {
//console.log("series 2 formatter");
//console.log(params);
if (params.data) {
console.log("params.data");
console.log(params.data);
console.log(params.data.name + "\n 加氢站总数:"+params.data["value"][2] + "\n 当前运营总数:" + params.data["value"][3]);
return params.data.name + "<br> 加氢站总数:"+params.data["value"][2] + "<br> 当前运营总数: " + params.data["value"][3];
}
},
backgroundColor: "rgba(0,0,0,.6)",
borderColor: "rgba(147, 235, 248, .8)",
textStyle: {
color: "#333333",
},
},
label: {
formatter: (param) => {
//return param.name.slice(0, 2) + "\n 车辆总数:"+param.data["value"][2] + "\n GPS在线数"+param.data["value"][3]; //2025.03.28
//return param.name.slice(0, 2) + "\n "+param.data["value"][2]; //2025.03.31
return param.name.slice(0, 2) ;
},
fontSize: 11,
offset: [0, 2],
position: "bottom",
textBorderColor: "#333333",
textShadowColor: "#000",
textShadowBlur: 10,
textBorderWidth: 0,
color: "#333333",
show: true,
},
// colorBy: "data",
itemStyle: {
color: "rgba(255,255,255,1)",
borderColor: "rgba(2255,255,255,2)",
borderWidth: 4,
shadowColor: "#000",
shadowBlur: 10,
},
},
],
//动画效果
// animationDuration: 1000,
// animationEasing: 'linear',
// animationDurationUpdate: 1000
};
this.options = option;
},
message(text) {
this.$Message({
text: text,
type: "warning",
});
},
mapclick() {
if (this.echartBindClick) return;
//单击切换到级地图当mapCode有值,说明可以切换到下级地图
this.$refs.CenterMap.chart.on("click", (params) => {
console.log(params);
let xzqData = xzqCode[params.name];
if (xzqData) {
this.getData(xzqData.adcode);
} else {
this.message("暂无下级地市!");
}
});
this.echartBindClick = true;
}
},
destroyed() {
// 销毁事件监听
this.$refs.CenterMap.chart.off("click");
if (this.charts) {
this.echarts.dispose();
}
},
};
</script>
<style lang="scss" scoped>
.centermap {
margin-bottom: 30px;
.maptitle {
height: 60px;
display: flex;
justify-content: center;
padding-top: 10px;
box-sizing: border-box;
.titletext {
font-size: 32px;
font-weight: 900;
letter-spacing: 6px;
background: linear-gradient(
92deg,
#0072ff 0%,
#00eaff 48.8525390625%,
#01aaff 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0 10px;
}
.titletextBefore {
font-size: 28px;
font-weight: 900;
letter-spacing: 6px;
color: #333333;
margin: 0 10px;
}
.zuo,
.you {
background-size: 100% 100%;
width: 29px;
height: 20px;
margin-top: 8px;
}
.zuo {
background: url("../../assets/img/xiezuo.png") no-repeat;
}
.you {
background: url("../../assets/img/xieyou.png") no-repeat;
}
}
.mapwrap {
height: 548px;
width: 100%;
// padding: 0 0 10px 0;
box-sizing: border-box;
position: relative;
.quanguo {
position: absolute;
right: 20px;
top: -46px;
width: 80px;
height: 28px;
border: 1px solid #1976d2;
border-radius: 10px;
color: #1976d2;
text-align: center;
line-height: 26px;
letter-spacing: 6px;
cursor: pointer;
box-shadow: 0 2px 4px rgba(0, 237, 237, 0.5),
0 0 6px rgba(0, 237, 237, 0.4);
}
.quanguo1 {
position: absolute;
right: 20px;
top: 24px;
width: 100px;
height: 28px;
border: 1px solid #1976d2;
border-radius: 10px;
color: #333333;
text-align: center;
line-height: 26px;
letter-spacing: 6px;
cursor: pointer;
box-shadow: 0 2px 4px rgba(25, 118, 210, 0.3),
0 0 6px rgba(25, 118, 210, 0.2);
font-family: "微软雅黑", sans-serif;
z-index: 9999;
}
.quanguo2 {
position: absolute;
left: 20px;
top: 24px;
width: 100px;
height: 28px;
border: 1px solid #1976d2;
border-radius: 10px;
color: #333333;
text-align: center;
line-height: 26px;
letter-spacing: 6px;
cursor: pointer;
box-shadow: 0 2px 4px rgba(25, 118, 210, 0.3),
0 0 6px rgba(25, 118, 210, 0.2);
font-family: "微软雅黑", sans-serif;
z-index: 9999;
}
.quanguo3 {
position: absolute;
left: 20px;
top: 60px;
width: 100px;
height: 28px;
border: 1px solid #1976d2;
border-radius: 10px;
color: #333333;
text-align: center;
line-height: 26px;
letter-spacing: 6px;
cursor: pointer;
box-shadow: 0 2px 4px rgba(25, 118, 210, 0.3),
0 0 6px rgba(25, 118, 210, 0.2);
font-family: "微软雅黑", sans-serif;
z-index: 9999;
}
}
}
</style>

View File

@@ -0,0 +1,256 @@
<template>
<div class="chart-block">
<!-- 左侧 柱状+折线图 -->
<div class="chart-container">
<v-chart class="bar-line-chart" :options="barLineOption" style="width: 390px;height: 250px;"/>
</div>
<!-- 右侧 两个环形图 -->
<div class="chart-container-right">
<v-chart class="pie-chart" :options="pieOptionOne" style="width: 140px;height:100px;margin-left: -11%;margin-top: 5%;"/>
<v-chart class="pie-chart" :options="pieOptionTwo" style="width: 140px;height:100px;margin-left: -11%;margin-top: 5%;"/>
</div>
</div>
</template>
<script>
import VChart from 'vue-echarts'
import * as echarts from 'echarts'
import 'echarts/lib/chart/bar'
import 'echarts/lib/chart/line'
import 'echarts/lib/chart/pie'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/tooltip'
import { currentGET } from 'api/modules'
export default {
name: 'ChartBlock',
components: { VChart },
data() {
return {
/* 柱状图 + 折线图 */
barLineOption: {
backgroundColor: 'transparent', // 让背景透明,方便在大屏布局中适配
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(0, 0, 0, 0.8)',
borderColor: '#333333',
textStyle: { color: '#ffffff' },
formatter: (params) => {
console.log(params)
return `碳减排量:${params[0].value}吨<br/>行驶里程:${params[1].value}万km`;
}
},
legend: {
data: ['碳减排量(吨)', '行驶里程(万km)'],
textStyle: { color: '#333333' }
},
grid: {
left: '15%',
right: '15%',
top: '10%',
bottom: '10%'
},
xAxis: {
type: 'category',
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
axisLine: { lineStyle: { color: '#666666' } },
axisLabel: { color: '#333333' }
},
yAxis: [
{
type: 'value',
// name: '碳减排量',
axisLine: { lineStyle: { color: '#666666' } },
axisLabel: { color: '#333333' },
splitLine: { show: false },
axisLabel: {
formatter: '{value}吨'
}
},
{
type: 'value',
// name: '行驶里程',
axisLine: { lineStyle: { color: '#666666' } },
axisLabel: { color: '#333333' },
splitLine: { show: false },
axisLabel: {
formatter: '{value}万km'
}
}
],
series: [
{
name: '碳减排量(吨)',
type: 'bar',
data: [3500, 400, 4200, 3800, 4500, 4800, 4200, 4600, 4900],
itemStyle: { color: '#1976d2' },
barWidth: 14
},
{
name: '行驶里程(万km)',
type: 'line',
yAxisIndex: 1,
data: [10, 15, 18, 12, 20, 25, 18, 22, 30],
itemStyle: { color: '#ff9800' },
smooth: true,
lineStyle: { width: 2 },
symbol: 'circle',
symbolSize: 8
}
]
},
/* 环形图1 - 年度碳减排量 */
pieOptionOne: {
backgroundColor: 'transparent',
tooltip: { show: false },
title: {
text: '0吨',
//subtext: '年度碳减排量',
left: 'center',
top: '40%',
textStyle: { color: '#333333', fontSize: 18 },
subtextStyle: { color: '#666666', fontSize: 14}
},
graphic: [
{
type: 'text',
left: '0px', // 根据需要调整文字与图表的间距
top: 'center', // 垂直居中
style: {
text: '年\n度\n碳\n减\n排\n量', // 每个字符换行显示
fill: '#333333',
font: '16px sans-serif',
}
}
],
series: [
{
name: '年度碳减排量',
type: 'pie',
radius: ['70%', '90%'],
hoverAnimation: false,
label: { show: false },
labelLine: { show: false },
data: [
{ value: 5, name: '碳排放量', itemStyle: { color: '#1976d2' } },
{ value: 95, name: 'other', itemStyle: { color: '#e3f2fd' } }
]
}
]
},
/* 环形图2 - 年度行驶里程 */
pieOptionTwo: {
backgroundColor: 'transparent',
tooltip: { show: false },
title: {
text: '0万',
//subtext: '年度行驶里程',
left: 'center',
top: '40%',
textStyle: { color: '#333333', fontSize: 18 },
subtextStyle: { color: '#666666', fontSize: 14}
},
graphic: [
{
type: 'text',
left: '0px', // 根据需要调整文字与图表的间距
top: 'center', // 垂直居中
style: {
text: '年\n度\n行\n驶\n里\n程', // 每个字符换行显示
fill: '#333333',
font: '16px sans-serif',
}
}
],
series: [
{
name: '年度行驶里程',
type: 'pie',
radius: ['70%', '90%'],
hoverAnimation: false,
label: { show: false },
labelLine: { show: false },
data: [
{ value: 85, name: '行驶里程', itemStyle: { color: '#ff9800' } },
{ value: 15, name: 'other', itemStyle: { color: '#e3f2fd' } }
]
}
]
},
monthItems:[],
monthCarbon:[],
monthMileage:[]
}
},
mounted() {
this.getMonthData();
this.getYearData();
},
methods: {
getMonthData() {
currentGET("big2").then((res) => {
console.log('月度碳足迹');
this.monthItems = res.data;
console.log(this.monthItems);
this.monthItems.forEach((item) => {
console.log(item.monthCarbon);
console.log(item.monthMileage);
this.monthCarbon.push(item.monthCarbon);
this.monthMileage.push((item.monthMileage/10000).toFixed(2));
});
console.log('碳减排:'+ this.monthCarbon);
console.log('里程数:'+ this.monthMileage);
this.barLineOption.series[0].data = this.monthCarbon;
this.barLineOption.series[1].data = this.monthMileage;
});
},
getYearData() {
currentGET("big3").then((res) => {
console.log('年度碳减排量');
console.log(res);
this.pieOptionOne.title.text = res.data.yearCarbonTon + '吨';
this.pieOptionTwo.title.text = res.data.yearMileage + '万km';
});
}
}
}
</script>
<style scoped>
.chart-block {
display: flex;
justify-content: space-around;
align-items: center;
/* 自行控制宽高,若嵌入大屏可由外层决定大小 */
width: 800px;
height: 300px;
/* 背景可保持透明,方便嵌入大屏的背景 */
background: transparent;
}
.chart-container {
margin-left: -30px;
width: 50%;
height: 100%;
}
.bar-line-chart {
width: 100%;
height: 100%;
}
/* 右侧两个环形图的布局 */
.chart-container-right {
width: 45%;
height: 100%;
margin-right: -20px;
}
.pie-chart {
width: 160px;
height: 160px;
}
</style>

175
src/views/indexs/index.vue Normal file
View File

@@ -0,0 +1,175 @@
<!--
* @Author: szy
* @Date: 2022-03-04 09:23:59
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-05-07 11:05:02
* @FilePath: \web-pc\src\pages\big-screen\view\indexs\index.vue
-->
<template>
<div class="contents">
<div class="contetn_left">
<div class="pagetab">
<!-- <div class="item">实时监测</div> -->
</div>
<ItemWrap class="contetn_left-top contetn_lr-item" title="当日实况">
<LeftTop/>
</ItemWrap>
<ItemWrap class="contetn_left-center contetn_lr-item" title="月度碳足迹">
<!-- <LeftCenter /> -->
<base-chart/>
</ItemWrap>
<ItemWrap
class="contetn_left-bottom contetn_lr-item"
title="月度碳减排"
style="padding: 0 10px 16px 10px"
>
<LeftBottom />
</ItemWrap>
</div>
<div class="contetn_center">
<CenterMap class="contetn_center_top" />
<ItemWrap class="contetn_center-bottom" title="">
<!-- <CenterBottom /> -->
<RightBottom />
</ItemWrap>
</div>
<div class="contetn_right">
<!-- <ItemWrap
class="contetn_left-bottom contetn_lr-item"
title="月度特殊标箱情况"
>
<RightTop />
</ItemWrap>
<ItemWrap
class="contetn_left-bottom contetn_lr-item"
title="月度标箱数"
style="padding: 0 10px 16px 10px"
>
<RightCenter />
</ItemWrap> -->
<!-- 2025.8.13 szy 使用当天数据 -->
<ItemWrap class="contetn_right_day_top" title="">
<RightTopDay />
</ItemWrap>
<ItemWrap
class="contetn_left-bottom contetn_lr-item"
title="车型分类 "
>
<CenterBottom />
</ItemWrap>
</div>
</div>
</template>
<script>
import LeftTop from './left-top.vue'
import LeftCenter from "./left-center.vue";
import LeftBottom from "./left-bottom.vue";
import CenterMap from "./center-map.vue";
import CenterBottom from "./center-bottom.vue";
import RightTop from "./right-top.vue";
import RightCenter from "./right-center.vue";
import RightBottom from "./right-bottom.vue";
import BaseChart from "./chart/baseChart.vue"
import RightTopDay from './right-top-day.vue'; //2025.10.15 szy add
export default {
components: {
LeftTop,
LeftCenter,
LeftBottom,
CenterMap,
RightTop,
RightCenter,
RightBottom,
CenterBottom,
BaseChart,
RightTopDay,
},
data() {
return {
};
},
filters: {
numsFilter(msg) {
return msg || 0;
},
},
created() {
},
mounted() {},
methods: {
},
};
</script>
<style lang="scss" scoped>
// 内容
.contents {
.contetn_left,
.contetn_right {
width: 540px;
box-sizing: border-box;
// padding: 16px 0;
}
.contetn_center {
width: 720px;
}
//左右两侧 三个块
.contetn_lr-item {
height: 310px;
}
.contetn_center_top {
width: 100%;
}
// 中间
.contetn_center {
display: flex;
flex-direction: column;
justify-content: space-around;
}
.contetn_center-bottom {
height: 315px;
}
//左边 右边 结构一样
.contetn_left,
.contetn_right {
display: flex;
flex-direction: column;
justify-content: space-around;
position: relative;
}
//右上角,车辆信息
.contetn_right_day_top {
margin-top: 0px;
height: 640px;
}
}
@keyframes rotating {
0% {
-webkit-transform: rotate(0) scale(1);
transform: rotate(0) scale(1);
}
50% {
-webkit-transform: rotate(180deg) scale(1.1);
transform: rotate(180deg) scale(1.1);
}
100% {
-webkit-transform: rotate(360deg) scale(1);
transform: rotate(360deg) scale(1);
}
}
</style>

View File

@@ -0,0 +1,153 @@
<template>
<div ref="chart" class="chart-container"></div>
</template>
<script>
import echarts from "echarts";
import { currentGET } from "api/modules";
export default {
name: "LeftBottomChart",
data() {
return {
monthItems: [],
monthHydrogen: [],
monthMileage: [],
monthCarbon: [],
seriesData: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
};
},
mounted() {
this.getMonthData();
},
methods: {
getMonthData() {
currentGET("big2").then((res) => {
console.log("月度碳减排");
this.monthItems = res.data;
console.log(this.monthItems);
this.monthItems.forEach((item) => {
//console.log(item.monthHydrogen);
//console.log(item.monthMileage);
// this.monthHydrogen.push(item.monthHydrogen);
// this.monthMileage.push(item.monthMileage);
let month = parseInt(item.months.substring(5, 7));
this.monthMileage[month - 1] = item.monthMileage;
this.monthCarbon[month - 1] = item.monthCarbon;
this.monthHydrogen[month - 1] = item.monthHydrogen;
});
//console.log('用氢量:'+ this.monthHydrogen);
//console.log('里程数:'+ this.monthMileage);
this.initChart();
});
},
initChart() {
let chart = echarts.init(this.$refs.chart);
let option = {
grid:{
left:'13%'
},
tooltip: {
trigger: "axis",
backgroundColor: "rgba(0, 0, 0, 0.8)",
borderColor: "#333333",
textStyle: { color: "#ffffff" },
// formatter: (params) => {
// console.log(params)
// return `用氢量:${params[0].value}kg<br/>用电量:${params[1].value}kWh<br/>行驶里程:${params[2].value}km`;
// }
formatter: (params) => {
console.log(params);
return `用氢量:${params[0].value}kg<br/>行驶里程:${params[1].value}km`;
},
},
legend: {
//data: ['用氢量', '用电量', '行驶里程'],
data: ["用氢量", "行驶里程"],
//data: ['用电量', '行驶里程'],
textStyle: { color: "#333333" },
},
xAxis: {
type: "category",
boundaryGap: false,
data: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
axisLine: { lineStyle: { color: "#666666" } },
axisLabel: { color: "#333333" },
},
yAxis: {
type: "value",
axisLine: { lineStyle: { color: "#666666" } },
splitLine: { lineStyle: { color: "#e0e0e0" } },
axisLabel: {
color: "#333333",
//align: 'left',
// margin:70,
//width: 100, //将内容的宽度固定
// overflow: 'truncate', //超出的部分截断
formatter: "{value}kg",
},
},
series: [
{
name: "用氢量",
type: "line",
//data: [5000, 7000, 10000, 8000, 6000, 11000, 9000, 7000, 5000, 7050, 10020, 8900],
data: this.monthHydrogen,
// data: [11865.86,11687.64,18874.66,11311.62, 0, 0, 0, 0, 0, 0, 0, 0],
itemStyle: { color: "#3399FF" },
},
// {
// name: '用电量',
// type: 'line',
// //data: [6000, 8000, 12000, 10000, 5000, 10000, 9500, 7200, 5000, 3000, 10000, 8500],
// data: [60, 80, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0],
// itemStyle: { color: '#3f89ff' }
// },
{
name: "行驶里程",
type: "line",
//data: [4000, 9000, 9500, 7000, 9000, 12000, 10000, 8000, 5000, 7000, 10000, 8000],
data: this.monthMileage,
//data: [20219.1,332767.1,1671592.3,330955, 0, 0, 0, 0, 0, 0, 0, 0],
itemStyle: { color: "#a060ff" },
},
],
};
chart.setOption(option);
},
},
};
</script>
<style scoped>
.chart-container {
width: 110%;
height: 270px;
}
</style>

View File

@@ -0,0 +1,231 @@
<!--
* @Author: szy
* @Date: 2022-02-28 16:16:42
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-10-25 09:18:22
* @FilePath: \web-pc\src\pages\big-screen\view\indexs\left-center.vue
-->
<template>
<Echart id="leftCenter" :options="options" class="left_center_inner" v-if="pageflag" ref="charts" />
<Reacquire v-else @onclick="getData" style="line-height:200px">
重新获取
</Reacquire>
</template>
<script>
import { currentGET } from 'api/modules'
export default {
data() {
return {
options: {},
countUserNumData: {
lockNum: 0,
onlineNum: 0,
offlineNum: 0,
totalNum: 0
},
pageflag: true,
timer: null
};
},
created() {
this.getData()
},
mounted() {
},
beforeDestroy() {
this.clearData()
},
methods: {
clearData() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
getData() {
this.pageflag = true
// this.pageflag =false
currentGET('big1').then(res => {
//只打印一次
if (!this.timer) {
console.log("设备总览", res);
}
if (res.success) {
this.countUserNumData = res.data
this.$nextTick(() => {
this.init()
})
} else {
this.pageflag = false
this.$Message({
text: res.msg,
type: 'warning'
})
}
})
},
//轮询
switper() {
if (this.timer) {
return
}
let looper = (a) => {
this.getData()
};
this.timer = setInterval(looper, this.$store.state.setting.echartsAutoTime);
let myChart = this.$refs.charts.chart
myChart.on('mouseover', params => {
this.clearData()
});
myChart.on('mouseout', params => {
this.timer = setInterval(looper, this.$store.state.setting.echartsAutoTime);
});
},
init() {
let total = this.countUserNumData.totalNum;
let colors = ["#ECA444", "#33A1DB", "#56B557"];
let piedata = {
name: "用户总览",
type: "pie",
radius: ["42%", "65%"],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 4,
borderColor: "rgba(0,0,0,0)",
borderWidth: 2,
},
color: colors,
data: [
// {
// value: 0,
// name: "告警",
// label: {
// shadowColor: colors[0],
// },
// },
{
value: this.countUserNumData.lockNum,
name: "锁定",
label: {
shadowColor: colors[0],
},
},
{
value: this.countUserNumData.onlineNum,
name: "在线",
label: {
shadowColor: colors[2],
},
},
{
value: this.countUserNumData.offlineNum,
name: "离线",
label: {
shadowColor: colors[1],
},
},
],
};
this.options = {
title: {
// zlevel: 0,
text: ["{value|" + total + "}", "{name|总数}"].join("\n"),
top: "center",
left: "center",
textStyle: {
rich: {
value: {
color: "#ffffff",
fontSize: 24,
fontWeight: "bold",
lineHeight: 20,
},
name: {
color: "#ffffff",
lineHeight: 20,
},
},
},
},
tooltip: {
trigger: "item",
backgroundColor: "rgba(0,0,0,.6)",
borderColor: "rgba(147, 235, 248, .8)",
textStyle: {
color: "#FFF",
},
},
legend: {
show: false,
top: "5%",
left: "center",
},
series: [
//展示圆点
{
...piedata,
tooltip: { show: true },
label: {
formatter: " {b|{b}} \n {c|{c}个} {per|{d}%} ",
// position: "outside",
rich: {
b: {
color: "#fff",
fontSize: 12,
lineHeight: 26,
},
c: {
color: "#31ABE3",
fontSize: 14,
},
per: {
color: "#31ABE3",
fontSize: 14,
},
},
},
labelLine: {
length: 20, // 第一段线 长度
length2: 36, // 第二段线 长度
show: true,
},
emphasis: {
show: true,
},
},
{
...piedata,
tooltip: { show: true },
itemStyle: {},
label: {
backgroundColor: "inherit", //圆点颜色auto映射的系列色
height: 0,
width: 0,
lineHeight: 0,
borderRadius: 2.5,
shadowBlur: 8,
shadowColor: "auto",
padding: [2.5, -2.5, 2.5, -2.5],
},
labelLine: {
length: 20, // 第一段线 长度
length2: 36, // 第二段线 长度
show: false,
},
},
],
};
},
},
};
</script>
<style lang='scss' scoped>
</style>

View File

@@ -0,0 +1,332 @@
<template>
<div class="cards-container">
<!-- 四个卡片 -->
<div class="card">
<!-- 数值与文字 -->
<div class="card-info">
<!-- 主数值高亮 -->
<div class="value-line">
<span class="number">{{ cards[0].value }}</span>
<span class="unit">{{ cards[0].unit }}</span>
</div>
<!-- 标签说明 -->
<div class="label">{{ cards[0].label }}</div>
</div>
<!-- 图标及其闪动背景 -->
<div class="icon-wrapper">
<!-- 背后闪动的竖直矩形 -->
<div class="icon-bg icon-bg-0"></div>
<!-- 圆形平台 -->
<div class="platform-circle"></div>
<!-- 图标本身此处用Unicode或自定义图标 -->
<div class="icon">
<img src="@/assets/img/left/1.svg" class="images"/>
</div>
</div>
</div>
<div class="card">
<!-- 数值与文字 -->
<div class="card-info">
<!-- 主数值高亮 -->
<div class="value-line">
<span class="number">{{ cards[1].value }}</span>
<span class="unit">{{ cards[1].unit }}</span>
</div>
<!-- 标签说明 -->
<div class="label">{{ cards[1].label }}</div>
</div>
<!-- 图标及其闪动背景 -->
<div class="icon-wrapper">
<!-- 背后闪动的竖直矩形 -->
<div class="icon-bg icon-bg-1"></div>
<!-- 圆形平台 -->
<div class="platform-circle"></div>
<!-- 图标本身此处用Unicode或自定义图标 -->
<div class="icon">
<img src="@/assets/img/left/2.svg" class="images"/>
</div>
</div>
</div>
<div class="card">
<!-- 数值与文字 -->
<div class="card-info">
<!-- 主数值高亮 -->
<div class="value-line">
<span class="number">{{ cards[2].value }}</span>
<span class="unit">{{ cards[2].unit }}</span>
</div>
<!-- 标签说明 -->
<div class="label">{{ cards[2].label }}</div>
</div>
<!-- 图标及其闪动背景 -->
<div class="icon-wrapper">
<!-- 背后闪动的竖直矩形 -->
<div class="icon-bg icon-bg-2"></div>
<!-- 圆形平台 -->
<div class="platform-circle"></div>
<!-- 图标本身此处用Unicode或自定义图标 -->
<div class="icon">
<img src="@/assets/img/left/3.svg" class="images"/>
</div>
</div>
</div>
<div class="card">
<!-- 数值与文字 -->
<div class="card-info">
<!-- 主数值高亮 -->
<div class="value-line">
<span class="number">{{ cards[3].value }}</span>
<span class="unit">{{ cards[3].unit }}</span>
</div>
<!-- 标签说明 -->
<div class="label">{{ cards[3].label }}</div>
</div>
<!-- 图标及其闪动背景 -->
<div class="icon-wrapper">
<!-- 背后闪动的竖直矩形 -->
<div class="icon-bg icon-bg-3"></div>
<!-- 圆形平台 -->
<div class="platform-circle"></div>
<!-- 图标本身此处用Unicode或自定义图标 -->
<div class="icon">
<img src="@/assets/img/left/4.svg" class="images"/>
</div>
</div>
</div>
</div>
</template>
<script>
import { currentGET } from 'api/modules'
export default {
name: "BlinkingIcons",
data() {
return {
cards: [
{
id: 1,
value: "452/807",
unit: "辆",
label: "在线车数",
srcValue: "@/assets/img/left_top_lv.png",
},
{
id: 2,
value: "561",
unit: "kg",
label: "当日减碳",
srcValue: "@/assets/img/left/1.svg",
},
{
id: 3,
value: "534",
unit: "kg",
label: "当日用氢量",
srcValue: "@/assets/img/left/1.svg",
},
{
id:4,
value: "3300",
unit: "km",
label: "当日里程",
srcValue: "@/assets/img/left/1.svg",
},
],
};
},
mounted() {
this.getData();
},
methods: {
getData() {
currentGET("big1").then((res) => {
console.log('当日实况');
console.log(res);
let onLineCount = 0;
let vehicleCount = 0;
let dayCarbon = 0;
let dayHydrogen = 0;
let dayMileage = 0;
if(res !==null && res.data !==null )
{
if(res.data.onLineCount !== null)
onLineCount = res.data.onLineCount;
if(res.data.vehicleCount !== null)
vehicleCount = res.data.vehicleCount;
if(res.data.dayCarbon !== null)
dayCarbon = res.data.dayCarbon;
if(res.data.dayHydrogen !== null)
dayHydrogen = res.data.dayHydrogen;
if(res.data.dayMileage !== null)
dayMileage = res.data.dayMileage;
}
let change = this.cards[0];
change.value = res.data.onLineCount + "/" + res.data.vehicleCount;
this.$set(this.cards, 0, change);
change = this.cards[1];
change.value = dayCarbon;
this.$set(this.cards, 1, change);
change = this.cards[2];
change.value = dayHydrogen;
this.$set(this.cards, 2, change);
change = this.cards[3];
change.value = dayMileage;
this.$set(this.cards, 3, change);
});
},
}
};
</script>
<style scoped>
/* 整体背景 */
.cards-container {
display: flex;
justify-content: space-around;
align-items: flex-end;
padding-left: 0px;
padding-top: 30px;
padding-bottom: 30px;
background-image: none;
background-color: transparent;
background-repeat: no-repeat;
background-position: 0% 100%;
}
.images{
width: 65px;
height: 70px;
margin-left: 10px;
margin-top: -5px;
}
/* 单个卡片 */
.card {
position: relative;
width: 180px;
text-align: center;
color: #333333;
}
/* 卡片信息区域 */
.card-info {
margin-bottom: 120px; /* 给下方图标区域留出空间 */
margin-left:10px;
}
.value-line {
font-size: 20px;
margin-bottom: 8px;
width:120px;
}
.number {
color: #1976d2; /* 高亮数字颜色 */
margin-right: 6px;
}
.unit {
font-size: 14px;
opacity: 0.8;
}
.label {
font-size: 16px;
color: #666666;
}
/* 图标容器 */
.icon-wrapper {
position: absolute;
bottom: 0;
left: 54%;
transform: translateX(-50%);
width: 100%;
height: 100px;
overflow: visible;
}
/* 背后闪动的竖直矩形 */
.icon-bg {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 90px;
height: 100%;
border-radius: 6px;
background-image: none;
background-color: rgba(25, 118, 210, 0.1);
background-repeat: no-repeat;
animation: blink 1s infinite alternate;
top: -15%;
}
.icon-bg-0 {
animation-delay: 0s;
}
.icon-bg-1 {
animation-delay: 0.2s;
}
.icon-bg-2 {
animation-delay: 0.4s;
}
.icon-bg-3 {
animation-delay: 0.6s;
}
/* 圆形平台 */
.platform-circle {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100px;
height: 20px;
background: radial-gradient(rgba(25, 118, 210, 0.3), transparent 70%);
border-radius: 50%;
box-shadow: 0 0 8px rgba(25, 118, 210, 0.4), 0 0 12px rgba(25, 118, 210, 0.3);
}
/* 图标 */
.icon {
position: absolute;
bottom: -5px;
left: 50%;
transform: translateX(-50%);
font-size: 28px;
color: #1976d2;
}
/* 关键帧动画:闪动 */
@keyframes blink {
0% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
/* 图标模拟,可用 Font Awesome 等替换 */
.icon-phone::before {
content: "☎";
}
.icon-shield::before {
content: "⛨";
}
.icon-star::before {
content: "★";
}
.icon-protect::before {
content: "🛡";
}
</style>

View File

@@ -0,0 +1,232 @@
<!--
* @Author: szy
* @Date: 2022-02-28 16:16:42
* @LastEditors: Please set LastEditors
* @LastEditTime: 2022-07-20 17:57:11
* @FilePath: \web-pc\src\pages\big-screen\view\indexs\left-center.vue
-->
<template>
<ul class="user_Overview flex" v-if="pageflag">
<li class="user_Overview-item" style="color: #00fdfa">
<div class="user_Overview_nums allnum ">
<dv-digital-flop :config="config" style="width:100%;height:100%;" />
</div>
<p>总设备数</p>
</li>
<li class="user_Overview-item" style="color: #07f7a8">
<div class="user_Overview_nums online">
<dv-digital-flop :config="onlineconfig" style="width:100%;height:100%;" />
</div>
<p>在线数</p>
</li>
<li class="user_Overview-item" style="color: #e3b337">
<div class="user_Overview_nums offline">
<dv-digital-flop :config="offlineconfig" style="width:100%;height:100%;" />
</div>
<p>掉线数</p>
</li>
<li class="user_Overview-item" style="color: #f5023d">
<div class="user_Overview_nums laramnum">
<dv-digital-flop :config="laramnumconfig" style="width:100%;height:100%;" />
</div>
<p>告警次数</p>
</li>
</ul>
<Reacquire v-else @onclick="getData" line-height="200px">
重新获取
</Reacquire>
</template>
<script>
import { currentGET } from 'api/modules'
let style = {
fontSize: 24
}
export default {
data() {
return {
options: {},
userOverview: {
alarmNum: 0,
offlineNum: 0,
onlineNum: 0,
totalNum: 0,
},
pageflag: true,
timer: null,
config: {
number: [100],
content: '{nt}',
style: {
...style,
// stroke: "#00fdfa",
fill: "#00fdfa",
},
},
onlineconfig: {
number: [0],
content: '{nt}',
style: {
...style,
// stroke: "#07f7a8",
fill: "#07f7a8",
},
},
offlineconfig: {
number: [0],
content: '{nt}',
style: {
...style,
// stroke: "#e3b337",
fill: "#e3b337",
},
},
laramnumconfig: {
number: [0],
content: '{nt}',
style: {
...style,
// stroke: "#f5023d",
fill: "#f5023d",
},
}
};
},
filters: {
numsFilter(msg) {
return msg || 0;
},
},
created() {
this.getData()
},
mounted() {
},
beforeDestroy() {
this.clearData()
},
methods: {
clearData() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
getData() {
this.pageflag = true;
currentGET("big2").then((res) => {
if (!this.timer) {
console.log("设备总览", res);
}
if (res.success) {
this.userOverview = res.data;
this.onlineconfig = {
...this.onlineconfig,
number: [res.data.onlineNum]
}
this.config = {
...this.config,
number: [res.data.totalNum]
}
this.offlineconfig = {
...this.offlineconfig,
number: [res.data.offlineNum]
}
this.laramnumconfig = {
...this.laramnumconfig,
number: [res.data.alarmNum]
}
this.switper()
} else {
this.pageflag = false;
this.$Message.warning(res.msg);
}
});
},
//轮询
switper() {
if (this.timer) {
return
}
let looper = (a) => {
this.getData()
};
this.timer = setInterval(looper, this.$store.state.setting.echartsAutoTime);
},
},
};
</script>
<style lang='scss' scoped>
.user_Overview {
li {
flex: 1;
p {
text-align: center;
height: 16px;
font-size: 16px;
}
.user_Overview_nums {
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
font-size: 22px;
margin: 50px auto 30px;
background-size: cover;
background-position: center center;
position: relative;
&::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
&.bgdonghua::before {
animation: rotating 14s linear infinite;
}
}
.allnum {
// background-image: url("../../assets/img/left_top_lan.png");
&::before {
background-image: url("../../assets/img/left/1.svg");
background-size: 100% 100%;
background-attachment: fixed;
background-repeat: no-repeat;
}
}
.online {
&::before {
background-image: url("../../assets/img/left_top_lv.png");
}
}
.offline {
&::before {
background-image: url("../../assets/img/left_top_huang.png");
}
}
.laramnum {
&::before {
background-image: url("../../assets/img/left_top_hong.png");
}
}
}
}
</style>

View File

@@ -0,0 +1,142 @@
<template>
<div class="table-container">
<table>
<thead>
<tr>
<th>交易所</th>
<th>项目</th>
<th>价格 (RMB)</th>
<th>地区</th>
</tr>
</thead>
</table>
<div class="scroll-wrapper">
<vue-seamless-scroll :data="tableData" :class-option="scrollOptions" class="scroll-container">
<table>
<tbody>
<tr v-for="(item, index) in tableData" :key="index">
<td :style="{ color: item.exchangeColor }">{{ item.name }}</td>
<td>{{ item.project }}</td>
<td :style="{ color: item.priceColor }">{{ item.price }}</td>
<td :style="{ color: item.regionColor }">{{ item.area }}</td>
</tr>
</tbody>
</table>
</vue-seamless-scroll>
</div>
</div>
</template>
<script>
import vueSeamlessScroll from "vue-seamless-scroll";
import { currentGET } from 'api/modules'
export default {
components: { vueSeamlessScroll },
data() {
return {
scrollOptions: {
step: 0.3, // 滚动速度
limitMoveNum: 2, // 限制单步滚动的条数
hoverStop: true, // 鼠标悬停是否暂停
direction: 1, // 方向1向上滚动
},
tableData: [
// { exchange: "湖北碳排放权交易中心", project: "CER", price: "90", region: "中国-湖北", exchangeColor: "#00ffcc", priceColor: "#ffffff", regionColor: "#ffffff" },
// { exchange: "欧洲碳排放权交易体系", project: "EUA", price: "90", region: "欧盟", exchangeColor: "#00ffcc", priceColor: "#00ffcc", regionColor: "#ffffff" },
// { exchange: "洲际交易所", project: "CERs", price: "89", region: "美国", exchangeColor: "#00ffcc", priceColor: "#00ffcc", regionColor: "#00ffcc" },
// { exchange: "加州碳市场", project: "CER", price: "88", region: "美国-加州", exchangeColor: "#ffcc00", priceColor: "#ffcc00", regionColor: "#ffcc00" },
// { exchange: "英国碳市场", project: "CER", price: "87", region: "英国", exchangeColor: "#ffcc00", priceColor: "#ffcc00", regionColor: "#ffffff" },
// { exchange: "热田碳排放交易所", project: "CER", price: "86", region: "韩国", exchangeColor: "#00ffcc", priceColor: "#ffffff", regionColor: "#ffffff" },
// { exchange: "湖北碳排放权交易中心", project: "CER", price: "90", region: "中国-湖北", exchangeColor: "#00ffcc", priceColor: "#ffffff", regionColor: "#ffffff" },
// { exchange: "欧洲碳排放权交易体系", project: "EUA", price: "90", region: "欧盟", exchangeColor: "#00ffcc", priceColor: "#00ffcc", regionColor: "#ffffff" },
// { exchange: "洲际交易所", project: "CERs", price: "89", region: "美国", exchangeColor: "#00ffcc", priceColor: "#00ffcc", regionColor: "#00ffcc" },
// { exchange: "加州碳市场", project: "CER", price: "88", region: "美国-加州", exchangeColor: "#ffcc00", priceColor: "#ffcc00", regionColor: "#ffcc00" },
// { exchange: "英国碳市场", project: "CER", price: "87", region: "英国", exchangeColor: "#ffcc00", priceColor: "#ffcc00", regionColor: "#ffffff" },
// { exchange: "热田碳排放交易所", project: "CER", price: "86", region: "韩国", exchangeColor: "#00ffcc", priceColor: "#ffffff", regionColor: "#ffffff" },
],
};
},
mounted() {
this.getExchangeData();
},
methods: {
getExchangeData() {
currentGET("big4").then(res => {
console.log("交易所数据:");
//console.log(this.tableData1);
console.log(res.data);
this.tableData = res.data;
this.tableData.forEach((item, index) => {
if(index % 2 !== 0)
{
item.exchangeColor = "#1976d2";
item.priceColor = "#333333";
item.regionColor = "#333333";
this.$set(this.tableData, index, item);
}
else
{
//console.log("偶数index: " + index);
item.exchangeColor = "#ff9800";
item.priceColor = "#ff9800";
item.regionColor = "#ff9800";
this.$set(this.tableData, index, item);
//this.$set(this.tableData, index, modifiedItem);
}
});
});
// console.log("转换后交易所数据:");
// console.log(this.tableData);
},
},
};
</script>
<style scoped>
.table-container {
width: 100%;
border-radius: 5px;
overflow: hidden;
padding-top: 10px; /* 添加顶部内边距 */
}
table {
width: 100%;
border-collapse: collapse;
text-align: left;
}
th, td {
padding: 12px;
color: #333333;
font-size: 14px;
width: 25%;
}
thead {
background: #f5f7fa;
padding: 10%;
}
.scroll-wrapper {
height: 250px; /* 适配大屏,数据较多可增加高度 */
overflow: hidden;
}
.scroll-container table {
width: 100%;
}
tr {
border-bottom: 1px solid #e0e0e0;
}
tr:nth-child(even) {
background: rgba(25, 118, 210, 0.05);
}
</style>

View File

@@ -0,0 +1,71 @@
<template>
<div ref="chart" style="width: 600px; height: 350px;margin-left: -10%;margin-top: -10%;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'BarChart',
mounted() {
this.initChart();
},
methods: {
initChart() {
// 基于准备好的dom初始化echarts实例
const myChart = echarts.init(this.$refs.chart);
// 指定图表的配置项和数据
const option = {
grid:{
left:'14%',
},
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
axisLabel: {
color: 'white'
}
},
yAxis: {
type: 'value',
axisLabel: {
color: 'white',
formatter: '{value}kg'
},
splitLine: {
lineStyle: {
color: '#3399FF'
}
}
},
tooltip: {
trigger: 'axis' ,
formatter: (params) => {
console.log(params)
return `减碳量:${params[0].value}kg`;
}
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 30, 0, 0, 0, 0, 0],
type: 'bar',
itemStyle: {
// 使用线性渐变填充颜色
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#6a99f8' // 起始颜色
}, {
offset: 1,
color: '#0b2149' // 结束颜色
}])
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
}
};
</script>

View File

@@ -0,0 +1,336 @@
<template>
<!-- <transition name="yh-setting-fade"> -->
<div class="table-container">
<table @click="tableClick">
<thead>
<tr>
<th style="width: 24%">车牌号</th>
<th style="width: 19%">当前总里程</th>
<th style="width: 19%">当日里程</th>
<th style="width: 19%">当日用氢量</th>
<th style="width: 19%">当日碳减排</th>
</tr>
</thead>
</table>
<div class="scroll-wrapper">
<vue-seamless-scroll
:data="tableData"
:class-option="scrollOptions"
class="scroll-container"
>
<table @click="tableClick">
<tbody>
<tr v-for="(item, index) in tableData" :key="index">
<td style="width: 24%">{{ item.plateNumber }}</td>
<td style="width: 19%">{{ item.totalMileage }}km</td>
<td style="width: 19%">{{ item.dayMileage }}km</td>
<td style="width: 19%">{{ item.dayHydrogen }}kg</td>
<td style="width: 19%">{{ item.dayCarbon }}kg</td>
</tr>
</tbody>
</table>
</vue-seamless-scroll>
</div>
<div class="dialog-container">
<!-- :body-style="{ maxHeight: 'calc(100vh - 510px)', overflow: 'auto' }" -->
<el-dialog
title="车辆当日信息"
:visible.sync="setVehicleDialog"
class="dialog_el"
height="400px"
width="803px"
center
:lock-scroll="false"
:append-to-body="true"
:modal-append-to-body="true"
>
<!-- width="100%" class="dialog-table" -->
<div class="dialog-body-wrapper">
<el-table
:data="tableData"
border
class="vehicleTable"
height="600px"
width="800px"
:default-sort="{ prop: 'totalMileage', order: 'descending' }"
>
<el-table-column
type="index"
prop="tableIndex"
label="序号"
width="80px"
></el-table-column>
<el-table-column
prop="plateNumber"
label="车牌号"
width="120px"
sortable
></el-table-column>
<el-table-column
prop="totalMileage"
label="当前总里程"
width="140px"
:formatter="formatMileageKm"
sortable
></el-table-column>
<el-table-column
prop="dayMileage"
label="当日里程"
width="130px"
:formatter="formatMileageKm"
sortable
></el-table-column>
<el-table-column
prop="dayHydrogen"
label="当日用氢量"
width="140px"
:formatter="formatHydrogenKg"
sortable
></el-table-column>
<el-table-column
prop="dayCarbon"
label="当日碳减排"
width="140px"
:formatter="formatHydrogenKg"
sortable
></el-table-column>
</el-table>
</div>
<span slot="footer" class="dialog-footer">
<el-button
class="closeButton"
type="primary"
size="small"
@click="closeDialog"
>关闭</el-button
>
</span>
</el-dialog>
</div>
</div>
<!-- </transition> -->
</template>
<script>
import Vue from "vue";
import vueSeamlessScroll from "vue-seamless-scroll";
import { currentGET } from "api/modules";
import { Dialog, Table, TableColumn } from "element-ui";
import "element-ui/lib/theme-chalk/table.css";
import "element-ui/lib/theme-chalk/table-column.css";
Vue.component("el-dialog", Dialog);
Vue.use(Table);
Vue.use(TableColumn);
export default {
components: { vueSeamlessScroll },
data() {
return {
scrollOptions: {
step: 0.3, // 滚动速度
limitMoveNum: 3, // 限制单步滚动的条数
hoverStop: true, // 鼠标悬停是否暂停
direction: 1, // 方向1向上滚动
singleHeight: 50, // 单行高度,用于精确控制滚动
waitTime: 2000, // 等待时间,滚动间隔
},
tableData: [],
setVehicleDialog: false,
};
},
mounted() {
this.getExchangeData();
},
methods: {
tableClick() {
console.log("tableClick");
this.setVehicleDialog = true;
},
closeDialog() {
this.setVehicleDialog = false;
},
getExchangeData() {
currentGET("big13").then((res) => {
console.log("当日汇总数据:");
console.log(res.data);
this.tableData = res.data;
// 限制最多显示20条数据
//this.tableData = res.data.slice(0, 20);
});
},
formatMileageKm(row, column, cellValue, index) {
if (row.nodeName === null) return "0km";
else return cellValue + "km";
},
formatHydrogenKg(row, column, cellValue, index) {
if (row.nodeName === null) return "0kg";
else return cellValue + "kg";
},
},
};
</script>
<style scoped>
.table-container {
width: 100%;
border-radius: 5px;
overflow: hidden;
padding-top: 10px; /* 添加顶部内边距 */
}
table {
width: 100%;
border-collapse: collapse;
text-align: center; /* 修改为居中对齐 */
}
th,
td {
padding: 12px;
color: #2d3748;
font-size: 14px;
width: 24%;
border-right: 1px solid rgba(79, 209, 197, 0.2);
}
th {
color: #000;
font-weight: 600;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
td {
padding: 10px 12px;
color: #000;
font-size: 14px;
width: 20%;
text-align: center; /* 确保单元格内容居中 */
}
thead {
color: #ffffff;
font-weight: 600;
}
.dialog_el >>> .el-dialog__body {
/* //border-top: 1px solid #dcdfe6;
//border-bottom: 1px solid #dcdfe6; */
max-height: 60vh !important;
min-height: 100px;
overflow-y: hidden;
/* background: #013f6a; */
}
.vehicleTable {
/* width: 100%; */
text-align: center; /* 确保单元格内容居中 */
}
.vehicleTable >>> th {
padding: 12px;
font-size: 14px;
/* width: 20%; */
text-align: center; /* 确保单元格内容居中 */
}
.vehicleTable >>> td {
text-align: center; /* 确保单元格内容居中 */
}
.closeButton {
color: #4fd1c5;
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
border: none;
border-radius: 6px;
font-weight: 600;
transition: all 0.3s ease;
}
.closeButton:hover {
background: linear-gradient(135deg, #3bb2ff 0%, #00d4ff 100%);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(79, 209, 197, 0.3);
}
/* 内容容器滚动设置 */
.dialog-body-wrapper {
padding: 1px 1px;
height: 100%;
overflow-y: auto;
/* width: 100%; */
}
.dialog-container {
width: 300px;
height: 0px; /* 适配大屏,数据较多可增加高度 */
overflow: hidden;
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.95) 0%,
rgba(240, 249, 255, 0.95) 100%
);
border-radius: 12px;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(79, 209, 197, 0.15);
}
.dialog_el .el-table {
background-color: transparent !important;
border-radius: 8px;
overflow: hidden;
}
.dialog_el .el-table th {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%) !important;
color: #ffffff !important;
font-weight: 600 !important;
}
.dialog_el .el-table td {
background-color: rgba(255, 255, 255, 0.7) !important;
color: #2d3748 !important;
border-bottom: 1px solid rgba(79, 209, 197, 0.1) !important;
}
.dialog_el .el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: rgba(79, 209, 197, 0.1) !important;
}
/* .dialog-table{
background-color: #ffffff;
} */
/* .dialog-table {
// background: linear-gradient(135deg, #031a47 0%, #e4e8ed 100%);
background-color: #f5f7fa;
// text-align: center;
} */
/* .dialog-table th {
background-color: #e3f2fd !important;
color: white;
}
.dialog-table td {
background-color: rgba(255,255,255,0.8);
} */
.scroll-wrapper {
height: 550px; /*适配大屏,数据较多可增加高度 */
overflow: hidden;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
}
.scroll-container table {
width: 100%;
}
tr {
border-bottom: 1px solid rgba(79, 209, 197, 0.1);
transition: all 0.2s ease;
}
tr:nth-child(even) {
background: rgba(79, 209, 197, 0.05);
}
tr:hover {
background: rgba(79, 209, 197, 0.1);
transform: translateX(2px);
}
</style>

View File

@@ -0,0 +1,119 @@
<template>
<div ref="chart" style="width: 520px; height: 280px;margin-top: 0%;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'DoubleAxisChart',
mounted() {
this.initChart();
},
methods: {
initChart() {
const chartDom = this.$refs.chart;
const myChart = echarts.init(chartDom);
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
formatter: (params) => {
console.log(params)
return `空箱:${params[0].value}标箱<br/>危险品:${params[1].value}标箱`;
}
},
legend: {
data: ['空箱', '危险品'],
left: 'right',
icon: 'line',
itemWidth: 30,
itemHeight: .0,
itemGap: 10,
textStyle: {
color: 'white',
fontSize: 16,
fontWeight: 'normal',
fontFamily: 'Arial, sans-serif'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: ['点1', '点2', '点3', '点4', '点5', '点6', '点7']
}
],
yAxis: [
{
type: 'value',
name: '',
axisLine: {
lineStyle: {
color: 'white'
}
},
splitLine: { lineStyle: { color: '#081b42' } },
axisLabel: {
formatter: '{value}标箱'
}
},
{
type: 'value',
name: '',
axisLine: {
lineStyle: {
color: 'white'
}
},
splitLine: { lineStyle: { color: '#081b42' } },
axisLabel: {
formatter: '{value}标箱'
}
}
],
series: [
{
name: '空箱',
type: 'line',
stack: '总量',
areaStyle: {color: 'orange'},
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210],
lineStyle: {
color: 'orange', // 线条颜色
width: 2, // 线条宽度
},
},
{
name: '危险品',
type: 'line',
yAxisIndex: 1, // 使用第二个Y轴
stack: '总量',
areaStyle: {color: 'blue'},
emphasis: {
focus: 'series'
},
data: [220, 182, 191, 234, 290, 330, 310],
lineStyle: {
color: 'blue', // 线条颜色
width: 2, // 线条宽度
},
}
]
};
myChart.setOption(option);
}
}
};
</script>

128
src/views/setting.vue Normal file
View File

@@ -0,0 +1,128 @@
<template>
<transition name="yh-setting-fade">
<div class="setting" :class="{ settingShow: settingShow }" v-show="settingShow">
<div class="setting_dislog" @click="settingShow = false">
</div>
<div class="setting_inner">
<div class="setting_header">
设置
</div>
<div class="setting_body">
<!-- <div class="left_shu"> 实时监测</div> -->
<div class="left_shu"> 全局设置</div>
<div class="setting_item">
<span class="setting_label">
是否进行自动适配<span class="setting_label_tip">(默认分辨率1920*1080)</span>:
</span>
<div class="setting_content">
<el-radio-group v-model="isScaleradio" @change="(val) => radiochange(val, 'isScale')">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</div>
</div>
<div class="left_shu"> 全屏设置</div>
<div class="setting_item">
<!-- <span class="setting_label">全屏显示:</span> -->
<div class="setting_content">
<!-- <el-button type="primary" round size="mini" @click="toggleFullScreen">全屏</el-button> -->
<el-radio-group v-model="sbtxradio" @change="(val) => radiochange(val, 'isFullScreen')">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</div>
</div>
<!-- <div class="left_shu"> 实时监测</div>
<div class="setting_item">
<span class="setting_label">
设备提醒自动轮询: <span class="setting_label_tip"></span>
</span>
<div class="setting_content">
<el-radio-group v-model="sbtxradio" @change="(val) => radiochange(val, 'sbtxSwiper')">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</div>
</div>
<div class="setting_item">
<span class="setting_label">
实时预警轮播:
</span>
<div class="setting_content">
<el-radio-group v-model="ssyjradio" @change="(val) => radiochange(val, 'ssyjSwiper')">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</div>
</div> -->
<div class="flex justify-center">
<!-- <el-button type="primary" round size="mini">确定</el-button> -->
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
components: {},
data() {
return {
settingShow: false,
sbtxradio:true,
ssyjradio: true,
isScaleradio:true,
isFullScreen: false,
};
},
computed: {},
methods: {
init() {
this.settingShow = true
},
radiochange(val, type) {
this.$store.commit('setting/updateSwiper', { val, type })
if(type==='isFullScreen'){
this.toggleFullScreen()
}
},
toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(err => {
console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
});
this.isFullScreen = true;
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
this.isFullScreen = false;
}
},
},
created() {
this.$store.commit('setting/initSwipers')
this.sbtxradio = this.$store.state.setting.sbtxSwiper,
this.ssyjradio = this.$store.state.setting.ssyjSwiper,
this.isScaleradio = this.$store.state.setting.isScale;
},
mounted() {
document.body.appendChild(this.$el);
},
beforeDestroy() {
},
destroyed() {
if (this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el);
}
}
}
</script>
<style lang='scss' scoped>
</style>

171
src/views/test/testMap.vue Normal file
View File

@@ -0,0 +1,171 @@
<template>
<div class="map" id="map"></div>
</template>
<script>
import * as echarts from "echarts";
import jilin from "./json/jilin.json";
export default {
data() {
return {
weatherMap: {
// "qing": require('@/assets/tq__1.jpg'),
// "qingZhuanDuoyun": require('@/assets/tq__2.jpg'),
// "zhongyu": require('@/assets/tq__3.jpg'),
// "qingZhuanZhongyu": require('@/assets/tq__4.jpg'),
// "zhongxue": require('@/assets/tq__5.jpg'),
// "leidian": require('@/assets/tq__6.jpg'),
// "yin": require('@/assets/tq__7.jpg'),
// "daxue": require('@/assets/tq__8.jpg'),
// "qingZhuanYin": require('@/assets/tq__9.jpg'),
},
testData: [
{
name: '长春市',
value: 'qing',
min: '10',
max: '20',
weather: '晴'
},
{
name: '吉林市',
value: 'qingZhuanDuoyun',
min: '11',
max: '15',
weather: '晴转多云'
},
{
name: '通化市',
value: 'zhongyu',
min: '8',
max: '12',
weather: '中雨'
},
{
name: '四平市',
value: 'qingZhuanZhongyu',
min: '9',
max: '19',
weather: '晴转中雨'
},
{
name: '白山市',
value: 'zhongxue',
min: '-15',
max: '-5',
weather: '中雪'
},
{
name: '辽源市',
value: 'leidian',
min: '13',
max: '17',
weather: '雷电'
},
{
name: '白城市',
value: 'yin',
min: '4',
max: '7',
weather: '阴'
},
{
name: '延边朝鲜族自治州',
value: 'daxue',
min: '-22',
max: '-12',
weather: '大雪'
},
{
name: '松原市',
value: 'qingZhuanYin',
min: '10',
max: '20',
weather: '晴转多云'
}
]
};
},
created() {
},
mounted() {
this.drawMap()
},
methods: {
drawMap() {
// 判断地图是否渲染
let myChart = echarts.getInstanceByDom(document.getElementById("map"))
// 如果渲染则清空地图
if (myChart != null) {
myChart.dispose()
}
// 初始化地图
myChart = echarts.init(document.getElementById("map"));
echarts.registerMap("jilin", jilin)
let rich = {
max: {
color: '#fff',
backgroundColor: '#E6A23C',
width: 44,
height: 26,
},
min: {
color: '#fff',
backgroundColor: '#67C23A',
width: 44,
height: 26,
},
name: {
color: '#F56C6C',
height: 32
},
}
const weatherMap = this.weatherMap
let tempData = this.testData
tempData.forEach(item => {
item.weatherImg = weatherMap[item.value]
rich[item.value] = {
height: 26,
width: 26,
backgroundColor: {
image: weatherMap[item.value]
}
}
})
var option = {
series: [
{
type: 'map',
zoom: 1.2,
map: 'jilin',
label: {
show: true,
formatter: function (params) {
return `{${params.data.value}|} {min|${params.data.min}℃} {max|${params.data.max}℃}\n{name|${params.name}}`
},
rich: rich
},
data: tempData
},
]
}
myChart.setOption(option)
},
},
}
</script>
<style scoped>
.map {
width: 800px;
height: 600px;
position: relative;
}
</style>

37
src/views/tjfx/tjfx.vue Normal file
View File

@@ -0,0 +1,37 @@
<!--
* @Author: szy
* @Date: 2022-03-04 09:52:25
* @LastEditors: szy
* @LastEditTime: 2022-03-04 11:03:40
* @FilePath: \web-pc\src\pages\big-screen\view\tjfx\tjfx.vue
-->
<template>
<div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
created(){
},
mounted() {
},
methods: {
},
}
</script>
<style lang='scss' scoped>
</style>