新增合立大屏

This commit is contained in:
qiwenli 2026-03-29 18:21:06 +08:00
parent aaedb814d0
commit 86ef8a7ba1
34 changed files with 1791 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View 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;
}
}
}
}

View File

@ -7,6 +7,10 @@ const routes = [{
path: '/', path: '/',
name: 'index', name: 'index',
component: () => import('../views/index.vue') component: () => import('../views/index.vue')
},{
path: '/largescreen',
name: 'largescreen',
component: () => import('../views/largescreen.vue')
}] }]
const router = new VueRouter({ const router = new VueRouter({
routes routes

View File

@ -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 devBaseURL = 'http://5a35a48943.wicp.vip:40709'
// const proBaseURL = 'http://5a35a48943.wicp.vip:40709' // const proBaseURL = 'http://5a35a48943.wicp.vip:40709'
// const devBaseURL = 'http://124.221.23.100:9003' // const devBaseURL = 'http://124.221.23.100:9003'

View 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>

View 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>

View 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>

View 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, // IDdata
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>

View 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, // IDundefined
};
},
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>

View 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>

View 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>

View 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>

View 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>