新增合立大屏
BIN
mes-ui/mes-echarts/src/assets/image/img/bg.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/bg_left.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/bg_right.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/bg_title.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/bot-design.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/bottom-assembly.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/bottom-bg.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/bottom-production.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/icon_away.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/icon_fullscreen.png
Normal file
|
After Width: | Height: | Size: 378 B |
BIN
mes-ui/mes-echarts/src/assets/image/img/icon_make.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/icon_onboard.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/icon_project.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/icon_screen.png
Normal file
|
After Width: | Height: | Size: 399 B |
BIN
mes-ui/mes-echarts/src/assets/image/img/order-bg.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/order-title.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/quality-bg.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/quality-icon.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/quality-title.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/title.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/year-bg.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
mes-ui/mes-echarts/src/assets/image/img/year-title.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
159
mes-ui/mes-echarts/src/assets/scss/largcss/largindex.scss
Normal file
@ -0,0 +1,159 @@
|
||||
#index {
|
||||
color: #d3d6dd;
|
||||
width: 1900px;
|
||||
height: 1060px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transform-origin: left top;
|
||||
overflow: hidden;
|
||||
|
||||
.bg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 16px 16px 0 16px;
|
||||
background-color: rgba(0, 0, 51, 1);
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.frame {
|
||||
height: 100%;
|
||||
background: url('../assets/image/img/bg.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.frame::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 36px;
|
||||
height: 652px;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translate(0, -50%);
|
||||
background: url('../assets/image/img/bg_left.png') no-repeat;
|
||||
background-size: cover;
|
||||
z-index: 1;
|
||||
|
||||
}
|
||||
|
||||
.frame::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 36px;
|
||||
height: 652px;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
transform: translate(0, -50%);
|
||||
background: url('../assets/image/img/bg_right.png') no-repeat;
|
||||
background-size: cover;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.host-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.bg-title {
|
||||
background: url('../assets/image/img/bg_title.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
height: 120px;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
background: url('../assets/image/img/title.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 300px;
|
||||
height: 56px;
|
||||
margin-left: -40px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-box {
|
||||
padding: 0 50px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 120px;
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 22px;
|
||||
|
||||
.timersty {
|
||||
font-weight: 800;
|
||||
font-size: 34px;
|
||||
color: #ffffff;
|
||||
margin-right: 10px;
|
||||
font-family: D-DIN-PRO, D-DIN-PRO;
|
||||
}
|
||||
}
|
||||
|
||||
.navkk1 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
border-left: 1px solid #78789F;
|
||||
padding-left: 20px;
|
||||
|
||||
.navktext {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-img {
|
||||
width: 167px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.F11 {
|
||||
margin-left: 20px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.full {
|
||||
background: url('../assets/image/img/icon_fullscreen.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.screen {
|
||||
background: url('../assets/image/img/icon_screen.png') no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.body-box {
|
||||
width: 100%;
|
||||
height: 870px;
|
||||
padding: 0 30px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.mainTop {
|
||||
width: 100%;
|
||||
height: 90px;
|
||||
margin: 28px auto;
|
||||
}
|
||||
|
||||
.mainCenter {
|
||||
width: 100%;
|
||||
height: 358px;
|
||||
margin: 28px auto;
|
||||
}
|
||||
|
||||
.mainBtm {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,10 @@ const routes = [{
|
||||
path: '/',
|
||||
name: 'index',
|
||||
component: () => import('../views/index.vue')
|
||||
},{
|
||||
path: '/largescreen',
|
||||
name: 'largescreen',
|
||||
component: () => import('../views/largescreen.vue')
|
||||
}]
|
||||
const router = new VueRouter({
|
||||
routes
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const devBaseURL = 'http://localhost:8080'
|
||||
// const devBaseURL = 'http://localhost:8080'
|
||||
const devBaseURL = 'http://218.75.46.166:8889'
|
||||
// const devBaseURL = 'http://5a35a48943.wicp.vip:40709'
|
||||
// const proBaseURL = 'http://5a35a48943.wicp.vip:40709'
|
||||
// const devBaseURL = 'http://124.221.23.100:9003'
|
||||
|
||||
116
mes-ui/mes-echarts/src/views/largebox/botProgressEcharts.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="progress-container">
|
||||
<div v-for="(item, index) in projectList" :key="index" class="progress-item">
|
||||
<div class="progress-label">
|
||||
<span class="label-text">{{ item.name }}</span>
|
||||
<span class="percent-text" :class="{ 'isExten': item.isExten }">
|
||||
<span v-if="item.isExten" class="isExten-tag">(已延期)</span>{{ item.percent }}%
|
||||
</span>
|
||||
</div>
|
||||
<div class="progress-bar-bg">
|
||||
<div class="progress-bar-fill" :class="{ 'isExten': item.isExten }" :style="{ width: item.percent + '%' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ProjectProgress',
|
||||
props: {
|
||||
progressData: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
projectList: [
|
||||
// { name: '项目名称项目名称 (2026.03.11)', percent: 64, isExten: false, },
|
||||
// { name: '项目名称项目名称 (2026.03.11)', percent: 91, isExten: false, },
|
||||
]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
progressData(newVal) {
|
||||
if (newVal) {
|
||||
this.projectList = newVal
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.progress-container {
|
||||
/* background-color: #071534; */
|
||||
padding: 20px 30px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.progress-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* 高亮项蓝色边框 */
|
||||
.progress-item.highlight {
|
||||
/* border: 2px solid #00ccff;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
margin: -10px 0 18px -10px; */
|
||||
}
|
||||
|
||||
.progress-label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.label-text {
|
||||
color: #ffffff;
|
||||
/* font-weight: 500; */
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.percent-text {
|
||||
color: #ffffff;
|
||||
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 延期文字样式 */
|
||||
.percent-text.isExten {
|
||||
color: #ff4444;
|
||||
}
|
||||
|
||||
.isExten-tag {
|
||||
margin-right: 6px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* 进度条背景 */
|
||||
.progress-bar-bg {
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
background-color: #0a2455;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 进度条填充 */
|
||||
.progress-bar-fill {
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(90deg, #3CFFCD 0%, #25D1FF 100%);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
/* 延期进度条颜色 */
|
||||
.progress-bar-fill.isExten {
|
||||
background: linear-gradient(90deg, #FA2B17 0%, #FF7725 100%);
|
||||
}
|
||||
</style>
|
||||
130
mes-ui/mes-echarts/src/views/largebox/botdesignEcharts.vue
Normal file
@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="echarts" id="botdesignecharts"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
export default {
|
||||
props: {
|
||||
designData: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timerId: null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
designData(newVal) {
|
||||
if (newVal && newVal.projectProcess) {
|
||||
this.echarts();
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// this.echarts();
|
||||
},
|
||||
beforeUnmount() {
|
||||
clearInterval(this.timerId);
|
||||
},
|
||||
methods: {
|
||||
echarts() {
|
||||
const myChart = echarts.init(document.getElementById("botdesignecharts"));
|
||||
let chartData = [
|
||||
// { value: 20, label: { color: '#fff' } },
|
||||
// { value: 50, label: { color: '#fff' } },
|
||||
];
|
||||
if (this.designData.projectProcess) {
|
||||
this.designData.projectProcess.map((value, index) => {
|
||||
if (value.isExten == 1) {
|
||||
chartData.push({ value: value.projectProcess, label: { color: '#f00', isExten: value.isExten } });
|
||||
} else {
|
||||
chartData.push({ value: value.projectProcess, label: { color: '#fff', isExten: value.isExten } });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var option = {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0)',
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '8%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: this.designData.projectName,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: { color: "#D8D6D6", width: 1 }
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLabel: {
|
||||
textStyle: { color: "#FFF" }, interval: 0, inside: false,
|
||||
rotate: 10,
|
||||
},
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisLabel: { formatter: '{value}%', color: "#FFF" },
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
splitLine: {
|
||||
lineStyle: { type: 'dashed', color: 'rgba(216,214,214,0.5)' }
|
||||
},
|
||||
interval: 25,
|
||||
}],
|
||||
series: [{
|
||||
type: 'bar',
|
||||
data: chartData,
|
||||
barWidth: 24,
|
||||
label: {
|
||||
show: true,
|
||||
position: "top",
|
||||
fontSize: 14,
|
||||
// formatter: "{c}%",
|
||||
formatter: function (params) {
|
||||
const value = params.value;
|
||||
if (params.data.label.isExten == 1) {
|
||||
return `${value}%\n(已延期)`;
|
||||
}
|
||||
return `${value}%`;
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: function (params) {
|
||||
if (params.data.label.isExten == 1) {
|
||||
return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#FF6666' },
|
||||
{ offset: 1, color: '#FF0000' }
|
||||
]);
|
||||
} else {
|
||||
return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#3CFFCD' },
|
||||
{ offset: 1, color: '#25D1FF' }
|
||||
]);
|
||||
}
|
||||
},
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
window.addEventListener('resize', () => myChart.resize());
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.echarts {
|
||||
width: 98%;
|
||||
height: 280px;
|
||||
}
|
||||
</style>
|
||||
248
mes-ui/mes-echarts/src/views/largebox/botproductionEcharts.vue
Normal file
@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<div class="echarts-container" :style="{ width: width, height: height }">
|
||||
<div ref="chartRef" class="bot-production-chart"></div>
|
||||
<div class="project-name">{{ productname }}</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
|
||||
export default {
|
||||
name: "BotProductionEcharts", // 公共组件名称
|
||||
props: {
|
||||
// 百分比数值(核心展示值)
|
||||
productname: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
percent: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
validator: (val) => val >= 0 && val <= 100 // 限制0-100
|
||||
},
|
||||
isExten: {
|
||||
type: String,
|
||||
default: "0" // 是否延期,默认不延期
|
||||
},
|
||||
// 中间圆环宽度(内外半径差,值越大越宽)
|
||||
ringWidth: {
|
||||
type: Number,
|
||||
default: 10, // 默认宽度,可自定义
|
||||
validator: (val) => val > 0
|
||||
},
|
||||
// 图表宽度
|
||||
width: {
|
||||
type: String,
|
||||
default: "98%"
|
||||
},
|
||||
// 图表高度
|
||||
height: {
|
||||
type: String,
|
||||
default: "200px"
|
||||
},
|
||||
// 极坐标内/外半径(控制整体圆环大小)
|
||||
polarRadius: {
|
||||
type: Array,
|
||||
default: () => ["52%", "70%"] // 扩大内层半径,增加圆环宽度
|
||||
},
|
||||
// 外层装饰饼图半径(可自定义)
|
||||
outerPieRadius: {
|
||||
type: Array,
|
||||
default: () => ["75%", "76%"]
|
||||
},
|
||||
// 最外层装饰饼图半径
|
||||
outermostPieRadius: {
|
||||
type: Array,
|
||||
default: () => ["77%", "80%"]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myChart: null, // 图表实例
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.initChart();
|
||||
window.addEventListener("resize", this.handleResize);
|
||||
},
|
||||
beforeUnmount() {
|
||||
// 销毁实例,防止内存泄漏
|
||||
window.removeEventListener("resize", this.handleResize);
|
||||
if (this.myChart) {
|
||||
this.myChart.dispose();
|
||||
this.myChart = null;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听百分比变化,更新图表
|
||||
isExten: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
if (this.myChart) {
|
||||
this.initChart();
|
||||
}
|
||||
}
|
||||
},
|
||||
percent: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
if (this.myChart) {
|
||||
this.initChart();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
const chartDom = this.$refs.chartRef;
|
||||
this.myChart = echarts.init(chartDom);
|
||||
const option = this.getChartOption();
|
||||
this.myChart.setOption(option);
|
||||
},
|
||||
getChartOption() {
|
||||
const _this = this;
|
||||
return {
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
title: [
|
||||
{
|
||||
text: '(已延期)',
|
||||
show: _this.isExten == "1",
|
||||
x: 'center',
|
||||
top: '53%',
|
||||
textStyle: {
|
||||
color: '#FA2317',
|
||||
fontSize: 14,
|
||||
fontWeight: '400',
|
||||
}
|
||||
},
|
||||
{
|
||||
text: `${this.percent}%`,
|
||||
x: "center",
|
||||
top: _this.isExten == "1" ? "36%" : "42%",
|
||||
textStyle: {
|
||||
fontSize: "28",
|
||||
color: _this.isExten == "1" ? "#FA2317" : "#F9F9F9",
|
||||
fontFamily: "Lato",
|
||||
fontWeight: "600"
|
||||
}
|
||||
}
|
||||
],
|
||||
polar: {
|
||||
// 极坐标半径(内半径越小/外半径越大,圆环越宽)
|
||||
radius: this.polarRadius,
|
||||
center: ["50%", "50%"]
|
||||
},
|
||||
angleAxis: {
|
||||
max: 100,
|
||||
show: false
|
||||
},
|
||||
radiusAxis: {
|
||||
type: "category",
|
||||
show: true,
|
||||
axisLabel: { show: false },
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "",
|
||||
type: "bar",
|
||||
radius: this.polarRadius, // 和极坐标半径保持一致
|
||||
showBackground: true,
|
||||
backgroundStyle: { color: "#082458" },
|
||||
data: [this.percent],
|
||||
coordinateSystem: "polar",
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: function (params) {
|
||||
if (_this.isExten == "1") {
|
||||
return new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
[
|
||||
{ offset: 0, color: "#FF7825" },
|
||||
{ offset: 1, color: "#FA2317" }
|
||||
]
|
||||
)
|
||||
} else {
|
||||
return new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
[
|
||||
{ offset: 0, color: "#3CFFCD" },
|
||||
{ offset: 1, color: "#25D1FF" }
|
||||
]
|
||||
);
|
||||
}
|
||||
},
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
// 外层装饰饼图1
|
||||
{
|
||||
name: "",
|
||||
type: "pie",
|
||||
radius: this.outerPieRadius,
|
||||
hoverAnimation: false,
|
||||
center: ["50%", "50%"],
|
||||
itemStyle: {
|
||||
normal: {
|
||||
labelLine: { show: false },
|
||||
color: "#082458"
|
||||
}
|
||||
},
|
||||
data: [{ value: 100 }]
|
||||
},
|
||||
// 外层装饰饼图2
|
||||
{
|
||||
name: "",
|
||||
type: "pie",
|
||||
radius: this.outermostPieRadius,
|
||||
hoverAnimation: false,
|
||||
center: ["50%", "50%"],
|
||||
itemStyle: {
|
||||
normal: {
|
||||
labelLine: { show: false },
|
||||
color: "#082458"
|
||||
}
|
||||
},
|
||||
data: [{ value: 100 }]
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
handleResize() {
|
||||
if (this.myChart) {
|
||||
this.myChart.resize();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.echarts-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bot-production-chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.project-name {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
176
mes-ui/mes-echarts/src/views/largebox/bottombox.vue
Normal file
@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<div id="center">
|
||||
<div class="bot-left bot-bg">
|
||||
<div class="bot-top d-flex">
|
||||
<img src="../../assets/image/img/bot-design.png" alt="" class="order-title" />
|
||||
</div>
|
||||
<botdesignEcharts class="order-box" :designData="designData" />
|
||||
</div>
|
||||
<div class="bot-box bot-bg">
|
||||
<div class="bot-top d-flex">
|
||||
<img src="../../assets/image/img/bottom-production.png" alt="" class="order-title" />
|
||||
</div>
|
||||
<div class="bot-production d-flex">
|
||||
<botproductionEcharts :percent="projectProcess2[0]" :chartRef="'chart1'" :ringWidth="15"
|
||||
:productname="productionData[0]" :isExten="projectisExten[0]" />
|
||||
<botproductionEcharts :percent="projectProcess2[1]" :chartRef="'chart2'" :ringWidth="15"
|
||||
:productname="productionData[1]" :isExten="projectisExten[1]" />
|
||||
<botproductionEcharts :percent="projectProcess2[2]" :chartRef="'chart3'" :ringWidth="15"
|
||||
:productname="productionData[2]" :isExten="projectisExten[2]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bot-right bot-bg">
|
||||
<div class="bot-top d-flex">
|
||||
<img src="../../assets/image/img/bottom-assembly.png" alt="" class="order-title" />
|
||||
</div>
|
||||
<div>
|
||||
<botProgressEcharts :progressData="progressData" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request } from "@/utils/request.js";
|
||||
import botdesignEcharts from "./botdesignEcharts.vue";
|
||||
import botproductionEcharts from "./botproductionEcharts.vue";
|
||||
import botProgressEcharts from "./botProgressEcharts.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
botdesignEcharts,
|
||||
botproductionEcharts,
|
||||
botProgressEcharts,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
designData: {},
|
||||
productionData: [],
|
||||
projectProcess2: [],
|
||||
projectisExten: [],
|
||||
progressData: [],
|
||||
intervalId: null, // 定时器ID声明在data中,避免属性丢失
|
||||
isLoading: false, // 请求加载状态
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
await this.fetchAllData(); // 初次加载
|
||||
this.startInterval(); // 开启定时器
|
||||
},
|
||||
methods: {
|
||||
async fetchAllData() {
|
||||
if (this.isLoading) return; // 防抖:避免重复请求
|
||||
this.isLoading = true;
|
||||
try {
|
||||
// 并行请求 type=1/2/3
|
||||
const [res1, res2, res3] = await Promise.all([
|
||||
this.getSetdata(1),
|
||||
this.getSetdata(2),
|
||||
this.getSetdata(3)
|
||||
]);
|
||||
|
||||
const res2Data = res2.data?.slice(0, 3) || []; // slice返回新数组,原数组不变
|
||||
|
||||
const { projectName: name1 = [], projectProcess: process1 = [] } = {};
|
||||
res1.data?.forEach(item => {
|
||||
name1.push(item.projectName);
|
||||
process1.push({ projectProcess: item.projectProcess, isExten: item.isExten });
|
||||
});
|
||||
this.designData = { projectName: name1, projectProcess: process1 };
|
||||
|
||||
// 处理type=2数据
|
||||
const projectName2 = [], projectProcess2 = [], projectisExten2 = [];
|
||||
res2Data.forEach(item => {
|
||||
projectName2.push(item.projectName || '');
|
||||
projectProcess2.push(item.projectProcess || 0);
|
||||
projectisExten2.push(item.isExten || false);
|
||||
});
|
||||
this.productionData = projectName2;
|
||||
this.projectProcess2 = projectProcess2;
|
||||
this.projectisExten = projectisExten2;
|
||||
|
||||
// 处理type=3数据
|
||||
const res3Data = res3.data?.slice(0, 5) || [];
|
||||
const progressData = res3Data.map(item => ({
|
||||
name: item.projectName || '',
|
||||
percent: item.projectProcess || 0,
|
||||
isExten: item.isExten === 1 ? true : false
|
||||
}));
|
||||
this.progressData = progressData;
|
||||
|
||||
} catch (err) {
|
||||
console.error("数据请求失败:", err);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 开启定时器
|
||||
startInterval() {
|
||||
const refreshTime = 5 * 60 * 1000;
|
||||
// 双重防护:清除旧定时器
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
}
|
||||
this.intervalId = setInterval(() => {
|
||||
this.fetchAllData(); // 调用封装的完整请求逻辑
|
||||
}, refreshTime);
|
||||
},
|
||||
|
||||
getSetdata(type) {
|
||||
return request({
|
||||
url: "/admin-api/heli/screen/searchProgress",
|
||||
method: "get",
|
||||
params: { type },
|
||||
headers: { "tenant-id": 2 }
|
||||
});
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 销毁时强制清除定时器,避免内存泄漏
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
this.intervalId = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
#center {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.bot-left {
|
||||
width: 586px;
|
||||
}
|
||||
|
||||
|
||||
.bot-production {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.bot-bg {
|
||||
background: linear-gradient(180deg, rgba(23, 67, 157, 0.1) 0%, rgba(35, 81, 140, 0.2) 100%), radial-gradient(103% 15% at 50% 100%, rgba(39, 115, 255, 0.1) 0%, rgba(39, 115, 255, 0) 100%), radial-gradient(59% 3% at 50% 100%, rgba(39, 115, 255, 0.2) 0%, rgba(39, 115, 255, 0) 100%), radial-gradient(42% 1% at 50% 100%, rgba(39, 115, 255, 0.5) 0%, rgba(39, 115, 255, 0) 100%);
|
||||
border: 1px solid;
|
||||
border-image: linear-gradient(180deg, rgba(82, 93, 255, 0), rgba(82, 93, 255, 1)) 1 1;
|
||||
|
||||
.bot-top {
|
||||
background: url('../../assets/image/img/bottom-bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 586px;
|
||||
height: 56px;
|
||||
align-items: center;
|
||||
|
||||
.order-title {
|
||||
width: 130px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
262
mes-ui/mes-echarts/src/views/largebox/centerbox.vue
Normal file
@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<div id="center">
|
||||
<div class="center-left center-bg">
|
||||
<div class="center-top d-flex">
|
||||
<img src="../../assets/image/img/order-title.png" alt="" class="order-title" />
|
||||
</div>
|
||||
<orderEcharts class="order-box" :orderData="orderData" />
|
||||
</div>
|
||||
<div class="center-box center-bg">
|
||||
<div class="center-top d-flex">
|
||||
<img src="../../assets/image/img/year-title.png" alt="" class="order-title" />
|
||||
</div>
|
||||
<yearCharts class="" :yearData="yearData" />
|
||||
</div>
|
||||
|
||||
<div class="center-right center-bg">
|
||||
<div class="center-top d-flex">
|
||||
<img src="../../assets/image/img/quality-title.png" alt="" class="order-title" />
|
||||
</div>
|
||||
<div class="d-flex jc-center al-center">
|
||||
<div class="d-flex js-center num-box">
|
||||
<span class="count-num" v-count-up="{ target: countObj.deliRate, duration: 1500 }">%</span>
|
||||
<span class="percent">%</span>
|
||||
</div>
|
||||
<div class="quality-box"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { request } from "@/utils/request.js";
|
||||
import orderEcharts from "./orderEcharts.vue";
|
||||
import yearCharts from "./yearCharts.vue";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
countObj: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
},
|
||||
components: {
|
||||
orderEcharts,
|
||||
yearCharts,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
orderData: {},
|
||||
yearData: {},
|
||||
intervalId: null, // 初始化定时器ID,防止undefined
|
||||
};
|
||||
},
|
||||
directives: {
|
||||
countUp: {
|
||||
inserted(el, binding) {
|
||||
const { target = 0, duration = 1500 } = binding.value
|
||||
let start = 0
|
||||
const step = target / (duration / 16) // 16ms 一帧
|
||||
const timer = setInterval(() => {
|
||||
start += step
|
||||
if (start >= target) {
|
||||
el.textContent = target
|
||||
clearInterval(timer)
|
||||
} else {
|
||||
el.textContent = Math.floor(start)
|
||||
}
|
||||
}, 16)
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setData(); // 首次加载立即请求
|
||||
this.startInterval(); // 开启定时器(取消注释)
|
||||
},
|
||||
// 组件销毁时清理定时器,防止内存泄漏
|
||||
beforeDestroy() {
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
this.intervalId = null;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
startInterval() {
|
||||
const _this = this;
|
||||
const time = 5 * 60 * 1000;
|
||||
// 先清理旧定时器(避免重复创建)
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
}
|
||||
// 重新创建定时器
|
||||
this.intervalId = setInterval(() => {
|
||||
_this.setData();
|
||||
}, time);
|
||||
},
|
||||
setData() {
|
||||
const _this = this;
|
||||
request({
|
||||
url: "/admin-api/heli/screen/searchOrderInformation",
|
||||
method: "get",
|
||||
headers: {
|
||||
"tenant-id": 2
|
||||
}
|
||||
}).then((res) => {
|
||||
var countdata = res.data.sort((a, b) => a.month - b.month);
|
||||
var month = [], blackMold = [], coloredMold = [];
|
||||
countdata.forEach(item => {
|
||||
month.push(item.month + "月");
|
||||
blackMold.push(item.blackMold);
|
||||
coloredMold.push(item.coloredMold);
|
||||
});
|
||||
_this.orderData = { month, blackMold, coloredMold };
|
||||
});
|
||||
|
||||
request({
|
||||
url: "/admin-api/heli/screen/searchOrderByYear",
|
||||
method: "get",
|
||||
headers: {
|
||||
"tenant-id": 2
|
||||
}
|
||||
}).then((res) => {
|
||||
var date = [], numOrder = [];
|
||||
res.data.forEach(item => {
|
||||
date.push(item.date);
|
||||
numOrder.push(item.numOrder);
|
||||
});
|
||||
_this.yearData = { date, numOrder };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#center {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.center-left {
|
||||
width: 895px;
|
||||
|
||||
.center-top {
|
||||
background: url('../../assets/image/img/order-bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 895px;
|
||||
height: 56px;
|
||||
align-items: center;
|
||||
|
||||
.order-title {
|
||||
width: 180px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center-box {
|
||||
width: 550px;
|
||||
|
||||
.center-top {
|
||||
background: url('../../assets/image/img/year-bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 550px;
|
||||
height: 56px;
|
||||
align-items: center;
|
||||
|
||||
.order-title {
|
||||
width: 190px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.center-right {
|
||||
width: 334px;
|
||||
|
||||
.center-top {
|
||||
background: url('../../assets/image/img/quality-bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 334px;
|
||||
height: 56px;
|
||||
align-items: center;
|
||||
|
||||
.order-title {
|
||||
width: 150px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
.al-center {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 60px;
|
||||
|
||||
.num-box {
|
||||
font-family: D-DIN-PRO, D-DIN-PRO;
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
color: #F9F9F9;
|
||||
line-height: 28px;
|
||||
letter-spacing: 1px;
|
||||
text-shadow: 0px 0px 20px rgba(0, 133, 255, 0.72);
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
background: linear-gradient(180deg, #FFFFFF 0%, #97D6FF 65%, #5EC0FF 87%, #8DD2FF 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
align-items: flex-end;
|
||||
// height: 28px;
|
||||
}
|
||||
|
||||
.count-num {
|
||||
font-size: 28px;
|
||||
|
||||
}
|
||||
|
||||
.percent {
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.quality-box {
|
||||
width: 215px;
|
||||
height: 152px;
|
||||
background: url('../../assets/image/img/quality-icon.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
animation: floatMove 3s infinite ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.order-box {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.center-bg {
|
||||
background: linear-gradient(180deg, rgba(23, 67, 157, 0.1) 0%, rgba(35, 81, 140, 0.2) 100%), radial-gradient(103% 15% at 50% 100%, rgba(39, 115, 255, 0.1) 0%, rgba(39, 115, 255, 0) 100%), radial-gradient(59% 3% at 50% 100%, rgba(39, 115, 255, 0.2) 0%, rgba(39, 115, 255, 0) 100%), radial-gradient(42% 1% at 50% 100%, rgba(39, 115, 255, 0.5) 0%, rgba(39, 115, 255, 0) 100%);
|
||||
border: 1px solid;
|
||||
border-image: linear-gradient(180deg, rgba(82, 93, 255, 0), rgba(82, 93, 255, 1)) 1 1;
|
||||
}
|
||||
|
||||
@keyframes floatMove {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(-12px);
|
||||
/* 向上飘6px */
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
216
mes-ui/mes-echarts/src/views/largebox/orderEcharts.vue
Normal file
@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="echarts" id="orderEcharts"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
export default {
|
||||
props: {
|
||||
orderData: Object,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
watch: {
|
||||
// 监听数据变化
|
||||
orderData(newVal) {
|
||||
if (newVal) {
|
||||
this.echarts();
|
||||
}
|
||||
},
|
||||
},
|
||||
created() { },
|
||||
mounted() {
|
||||
// this.echarts();
|
||||
},
|
||||
methods: {
|
||||
echarts() {
|
||||
var myChart = echarts.init(document.getElementById("orderEcharts"));
|
||||
|
||||
var option = {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0)',
|
||||
grid: {
|
||||
top: '10%',
|
||||
bottom: '15%',
|
||||
left: '7%',
|
||||
right: '4%',
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
icon: 'rect',
|
||||
align: 'left',
|
||||
itemWidth: 8,
|
||||
itemHeight: 8,
|
||||
itemStyle: {
|
||||
borderWidth: 0,
|
||||
borderColor: "transparent",
|
||||
},
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: '#fff' // 字体白色(不是黑色)
|
||||
},
|
||||
x: 'center',
|
||||
y: 'top',
|
||||
data: ['黑色', '有色'],
|
||||
},
|
||||
xAxis: {
|
||||
boundaryGap: true, //默认,坐标轴留白策略
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
color: '#D8D6D6',
|
||||
width: 1 // 线条粗细
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
alignWithLabel: true,
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
},
|
||||
data: this.orderData.month,
|
||||
},
|
||||
yAxis: {
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: 'rgba(216,214,214,0.5)',
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '黑色',
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
symbolSize: 7,
|
||||
lineStyle: {
|
||||
color: '#FFB305',
|
||||
shadowBlur: 12,
|
||||
// shadowColor: 'rgb(33,148,246,0.9)',
|
||||
shadowOffsetX: 1,
|
||||
shadowOffsetY: 1,
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
[
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(255,179,5,0.4)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(255,179,5,0.1)',
|
||||
},
|
||||
],
|
||||
false
|
||||
),
|
||||
shadowColor: 'rgba(255,122,140, 0.1)',
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#FFB305',
|
||||
borderWidth: 1,
|
||||
borderColor: '#FFF',
|
||||
},
|
||||
|
||||
data: this.orderData.blackMold,
|
||||
},
|
||||
{
|
||||
name: '有色',
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
symbolSize: 7,
|
||||
lineStyle: {
|
||||
color: '#3CFFCD',
|
||||
shadowBlur: 12,
|
||||
shadowColor: 'rgb(33,148,246,0.9)',
|
||||
shadowOffsetX: 1,
|
||||
// shadowOffsetY: 1,
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
[
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0,241,200,0.4)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0,241,200,0.1)',
|
||||
},
|
||||
],
|
||||
false
|
||||
),
|
||||
shadowColor: 'rgba(82, 193, 245, 0.1)',
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#3CFFCD',
|
||||
borderWidth: 1,
|
||||
borderColor: '#FFF',
|
||||
},
|
||||
|
||||
data: this.orderData.coloredMold,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
option && myChart.setOption(option);
|
||||
// 设置定时器, 每隔2s判断是否滚动到末尾, 是则重置为初始状态, 否则向前滚动一位
|
||||
// this.timerId = setInterval(() => {
|
||||
// if (option.dataZoom[0].endValue == dataX.length - 1) {
|
||||
// option.dataZoom[0].endValue = 3;
|
||||
// option.dataZoom[0].startValue = 0;
|
||||
// } else {
|
||||
// option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1;
|
||||
// option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1;
|
||||
// }
|
||||
// myChart.setOption(option);
|
||||
// }, 2000);
|
||||
},
|
||||
},
|
||||
//组件
|
||||
components: {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.echarts {
|
||||
width: 98%;
|
||||
height: 290px;
|
||||
}
|
||||
</style>
|
||||
163
mes-ui/mes-echarts/src/views/largebox/topbox.vue
Normal file
@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div id="center">
|
||||
<div class="dv-itbox">
|
||||
<div class="itbox-left">
|
||||
<span>今日到岗人数</span>
|
||||
<div class="num-box">
|
||||
<span class="count-num" v-count-up="{ target: countObj.numPresent, duration: 1500 }"></span>
|
||||
<span class="increase">{{ countObj.relativetoyesterdayPresent || 0 }}</span>
|
||||
<!-- 较昨日增加 -->
|
||||
</div>
|
||||
</div>
|
||||
<img src="../../assets/image/img/icon_onboard.png" alt="" class="img-icon" />
|
||||
</div>
|
||||
|
||||
<div class="dv-itbox">
|
||||
<div class="itbox-left">
|
||||
<span>今日出差人数</span>
|
||||
<div class="num-box">
|
||||
<span class="count-num" v-count-up="{ target: countObj.numBusinessTrip, duration: 1500 }"></span>
|
||||
<span class="increase">{{ countObj.relativetoyesterdayBusinessTrip || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<img src="../../assets/image/img/icon_away.png" alt="" class="img-icon" />
|
||||
</div>
|
||||
|
||||
<div class="dv-itbox">
|
||||
<div class="itbox-left">
|
||||
<span>当前设计项目数量</span>
|
||||
<div class="num-box">
|
||||
<span class="count-num" v-count-up="{ target: countObj.numDesign, duration: 1500 }"></span>
|
||||
<span class="increase">{{ countObj.relativetoyesterdayDesign || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<img src="../../assets/image/img/icon_project.png" alt="" class="img-icon" />
|
||||
</div>
|
||||
|
||||
<div class="dv-itbox">
|
||||
<div class="itbox-left">
|
||||
<span>当前在制项目数量</span>
|
||||
<div class="num-box">
|
||||
<span class="count-num" v-count-up="{ target: countObj.numInProcess, duration: 1500 }"></span>
|
||||
<span class="increase">{{ countObj.relativetoyesterdayInProcess || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<img src="../../assets/image/img/icon_make.png" alt="" class="img-icon" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
countObj: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
},
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
directives: {
|
||||
countUp: {
|
||||
inserted(el, binding) {
|
||||
const { target = 0, duration = 1500 } = binding.value
|
||||
let start = 0
|
||||
const step = target / (duration / 16) // 16ms 一帧
|
||||
const timer = setInterval(() => {
|
||||
start += step
|
||||
if (start >= target) {
|
||||
el.textContent = target
|
||||
clearInterval(timer)
|
||||
} else {
|
||||
el.textContent = Math.floor(start)
|
||||
}
|
||||
}, 16)
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#center {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.dv-itbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 442px;
|
||||
// height: 90px;
|
||||
background: linear-gradient(270deg, #031243 0%, #0F2D7B 100%);
|
||||
border-radius: 4px;
|
||||
border: 1px solid;
|
||||
border-image: linear-gradient(180deg, rgba(55, 211, 236, 0.32), rgba(8, 31, 64, 0), rgba(55, 212, 236, 0.4)) 1 1;
|
||||
justify-content: space-between;
|
||||
|
||||
.itbox-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 180px;
|
||||
padding: 10px 0 0 20px;
|
||||
|
||||
span {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.num-box {}
|
||||
|
||||
.count-num {
|
||||
width: 40px;
|
||||
height: 28px;
|
||||
font-family: D-DIN-PRO, D-DIN-PRO;
|
||||
font-weight: 600;
|
||||
font-size: 28px;
|
||||
color: #F9F9F9;
|
||||
line-height: 28px;
|
||||
letter-spacing: 1px;
|
||||
text-shadow: 0px 0px 20px rgba(0, 133, 255, 0.72);
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
background: linear-gradient(180deg, #FFFFFF 0%, #97D6FF 65%, #5EC0FF 87%, #8DD2FF 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.increase {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #F9F9F9;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.img-icon {
|
||||
width: 133px;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
151
mes-ui/mes-echarts/src/views/largebox/yearCharts.vue
Normal file
@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="echarts" id="yearecharts"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from "echarts";
|
||||
import { Col } from "element-ui";
|
||||
export default {
|
||||
props: {
|
||||
yearData: Object,
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() { },
|
||||
watch: {
|
||||
// 监听数据变化
|
||||
yearData(newVal) {
|
||||
this.echarts();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.echarts();
|
||||
},
|
||||
methods: {
|
||||
|
||||
echarts() {
|
||||
var myChart = echarts.init(document.getElementById("yearecharts"));
|
||||
|
||||
var option = {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0)',
|
||||
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
// tooltip: {
|
||||
// trigger: "axis",
|
||||
// padding: [8, 10],
|
||||
// backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
// axisPointer: {
|
||||
// type: "shadow",
|
||||
// textStyle: {
|
||||
// color: "#fff"
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: this.yearData.date,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#D8D6D6",
|
||||
width: 1,
|
||||
type: "solid"
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
color: "#FFF",
|
||||
}
|
||||
},
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
// formatter: '{value} %',
|
||||
color: "#FFF",
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: "#00c7ff",
|
||||
width: 1,
|
||||
type: "solid"
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: 'rgba(216,214,214,0.5)',
|
||||
},
|
||||
}
|
||||
}],
|
||||
series: [{
|
||||
type: 'bar',
|
||||
data: this.yearData.numOrder,
|
||||
barWidth: 24, //柱子宽度
|
||||
// barGap: 68, //柱子之间间距
|
||||
label: {
|
||||
show: true,
|
||||
position: "top",
|
||||
// distance: 10,
|
||||
color: "#fff", // 纯白色
|
||||
fontSize: 14,
|
||||
// fontWeight: 500, // 更清晰
|
||||
// textShadow: "none" // 关闭所有文字阴影(彻底解决重影)
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: '#4CC1FF'
|
||||
}, {
|
||||
offset: 1,
|
||||
color: '#258EFF'
|
||||
}]),
|
||||
opacity: 1,
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
// // 设置定时器, 每隔2s判断是否滚动到末尾, 是则重置为初始状态, 否则向前滚动一位
|
||||
// this.timerId = setInterval(() => {
|
||||
// if (option.dataZoom[0].endValue == dataX.length - 1) {
|
||||
// option.dataZoom[0].endValue = 3;
|
||||
// option.dataZoom[0].startValue = 0;
|
||||
// } else {
|
||||
// option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1;
|
||||
// option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1;
|
||||
// }
|
||||
// myChart.setOption(option);
|
||||
// }, 2000);
|
||||
},
|
||||
},
|
||||
//组件
|
||||
components: {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.echarts {
|
||||
width: 98%;
|
||||
height: 290px;
|
||||
}
|
||||
</style>
|
||||
164
mes-ui/mes-echarts/src/views/largescreen.vue
Normal file
@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div id="index" ref="appRef">
|
||||
<div class="bg">
|
||||
<dv-loading v-if="loading">Loading...</dv-loading>
|
||||
<div v-else class="host-body">
|
||||
<div class="frame">
|
||||
<!--头标-->
|
||||
<div class="d-flex jc-center bg-title nav-box">
|
||||
<div class="nav">
|
||||
<span class="timersty">{{ dateDay }}</span>
|
||||
<div class="navkk1">
|
||||
<span>{{ dateWeek }}</span>
|
||||
<span class="navktext">{{ dateYear }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex jc-center">
|
||||
<div class="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav">
|
||||
<span><img src="../assets/image/u1623.png" alt="" class="nav-img"></span>
|
||||
<div class="F11" @click="F11" :class="isFullscreen ? 'screen' : 'full'"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 主体部分 -->
|
||||
<div class="body-box">
|
||||
<div class="mainTop">
|
||||
<!-- 第一行 数据展示 -->
|
||||
<topbox :countObj="countObj" />
|
||||
</div>
|
||||
|
||||
<div class="mainCenter">
|
||||
<centerbox :countObj="countObj" />
|
||||
</div>
|
||||
|
||||
<div class="mainBtm">
|
||||
<bottombox />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import drawMixin from "../utils/drawMixin";
|
||||
import { formatTime } from "../utils/index.js";
|
||||
import topbox from "./largebox/topbox.vue";
|
||||
import centerbox from "./largebox/centerbox.vue";
|
||||
import bottombox from "./largebox/bottombox.vue";
|
||||
import { request } from "@/utils/request.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
topbox,
|
||||
centerbox,
|
||||
bottombox,
|
||||
},
|
||||
mixins: [drawMixin],
|
||||
data() {
|
||||
return {
|
||||
isFullscreen: false,
|
||||
timing: null,
|
||||
loading: true,
|
||||
dateDay: null,
|
||||
dateYear: null,
|
||||
dateWeek: null,
|
||||
weekday: [
|
||||
"星期日",
|
||||
"星期一",
|
||||
"星期二",
|
||||
"星期三",
|
||||
"星期四",
|
||||
"星期五",
|
||||
"星期六",
|
||||
],
|
||||
countObj: {},
|
||||
intervalId: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.timeFn();
|
||||
this.cancelLoading();
|
||||
this.setData();
|
||||
this.startInterval(); // 开启定时器(取消注释)
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timing);
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
this.intervalId = null;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
F11() {
|
||||
this.isFullscreen = !this.isFullscreen;
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement.requestFullscreen();
|
||||
} else {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
}
|
||||
},
|
||||
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() {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
}, 500);
|
||||
},
|
||||
startInterval() {
|
||||
const _this = this;
|
||||
const time = 5 * 60 * 1000;
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
}
|
||||
this.intervalId = setInterval(() => {
|
||||
_this.setData();
|
||||
}, time);
|
||||
},
|
||||
// 根据自己的业务情况修改
|
||||
setData() {
|
||||
const _this = this;
|
||||
request({
|
||||
url: "/admin-api/heli/screen/searchUnfinished",
|
||||
method: "get",
|
||||
headers: {
|
||||
"tenant-id": 2
|
||||
}
|
||||
}).then((res) => {
|
||||
_this.countObj = res.data
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../assets/scss/largcss/largindex.scss";
|
||||
|
||||
.bototm-box {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.F11 {
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||