Files
2022-01-24 09:19:42 +08:00

900 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<container3 title="民用产业">
<bigScreenTabs
slot="datePicker"
v-model="index"
:titleArr="['总厂情况', '合同及产品生产信息', '本月情况']"
></bigScreenTabs>
<div style="display: flex; height: 100%" v-if="index == 0">
<div
style="
height: 100%;
width: 16%;
display: flex;
flex-direction: column;
justify-content: space-evenly;
"
>
<div class="tag">
<div class="title">收入</div>
<i style="font-size: 24px; font-weight: bold; color: #91d5fe"
>{{ handleMillion(total.realIncome) }}/<i
style="font-size: 18px"
>{{ handleMillion(total.targetIncome) }}</i
></i
>
亿元
</div>
<div class="tag">
<div class="title">利润</div>
<i style="font-size: 24px; font-weight: bold; color: #91d5fe"
>{{ handleMillion(total.realProfit) }}/<i
style="font-size: 18px"
>{{ handleMillion(total.targetProfit) }}</i
></i
>
亿元
</div>
<div class="tag">
<div class="title">新签合同额</div>
<i style="font-size: 24px; font-weight: bold; color: #91d5fe"
>{{ handleMillion(total.newContractAmount)
}}<i style="font-size: 18px"></i
></i>
亿元
</div>
</div>
<div style="height: 100%; width: 84%" ref="chart"></div>
</div>
<div style="height: 100%" v-else-if="index == 1">
<el-row :gutter="20" style="height: 100%">
<el-col :span="5" style="height: 100%">
<div class="_box">
<div class="_item">
<div>
<img src="./img/right2/2.png" alt="" />
</div>
<div style="margin: 5px 0 10px; color: #ccc">签订总数</div>
<div style="font-size: 30px">{{ totalAndAmount.total }}</div>
</div>
<div class="_item">
<div>
<img src="./img/right2/3.png" alt="" />
</div>
<div style="margin: 5px 0 10px; color: #ccc">金额</div>
<div>
<span style="font-size: 30px">{{
handleMillion(totalAndAmount.amount)
}}</span
><span style="color: #ccc">亿元</span>
</div>
</div>
</div>
</el-col>
<el-col :span="13" style="height: 100%">
<div style="height: 100%; width: 100%" ref="chart2"></div>
</el-col>
<el-col :span="6" style="height: 100%">
<div style="height: 100%; width: 100%" ref="chart3"></div>
</el-col>
</el-row>
</div>
<div style="height: 100%" v-else>
<div style="height: 100%; width: 100%" ref="chart4"></div>
</div>
</container3>
</div>
</template>
<script>
import scalseBox from "../components/scaleBox.vue";
import bigScreenHead from "../components/bigScreenHead/index.vue";
import rocketTit from "../components/rocketTit/index.vue";
import container3 from "./components/container3/index.vue";
import bigScreenTabs from "../components/bigScreenTabs/index.vue";
import colorList from "@/utils/colorPalette";
import echarts from "echarts";
import * as echarts5 from "echarts5";
require("echarts/theme/macarons"); // echarts theme
import resize from "../../dashboard/mixins/resize";
export default {
mixins: [resize],
name: "right2",
components: {
scalseBox,
bigScreenHead,
rocketTit,
container3,
bigScreenTabs,
},
data() {
return {
index: 0,
chart: null,
chart2: null,
chart3: null,
chart4: null,
total: {
newContractAmount: 0,
realIncome: 0,
realProfit: 0,
targetIncome: 0,
targetProfit: 0,
},
totalAndAmount: {
amount: 0,
total: 0,
},
};
},
mounted() {
this.$nextTick(() => {
this.initChart();
});
},
watch: {
index(newVal, oldVal) {
if (newVal == 0) {
this.$nextTick(() => {
this.initChart();
});
} else if (newVal == 1) {
this.$nextTick(() => {
this.initChart2();
});
} else {
this.$nextTick(() => {
this.initChart4();
});
}
},
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
initChart() {
this.request({
url: "/hx/operating/getCivilIndustryPic",
method: "get",
params: { type: 1 },
}).then((res) => {
if (200 == res.code) {
let { total, list } = res.data;
if (total) {
this.total = total;
}
this.chart = echarts.init(this.$refs.chart);
this.chart.setOption({
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
legend: {
data: ["利润", "收入", "收入完成率", "利润完成率"],
textStyle: {
color: "#fff", //legend字体颜色
},
},
grid: {
left: 20,
right: 20,
top: 30,
bottom: 50,
containLabel: true,
},
dataZoom: {
type: "slider",
start: 0,
end: this.dataZoomEnd(list.length, 7),
textStyle: {
color: "#fff",
},
},
xAxis: [
{
type: "category",
data: list.map((e) => e.month),
// data: ['2021-01', '2021-02', '2021-03', '2021-04', '2021-05', '2021-06', '2021-07'],
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
},
],
yAxis: [
{
name: "个",
splitLine: {
show: true,
// 改变轴线颜色
lineStyle: {
// 使用深浅的间隔色
color: ["rgba(255, 255, 255,.5)"],
},
},
axisLabel: {
formatter: "{value}",
},
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
},
{
type: "value",
axisLabel: {
formatter: "{value} %",
},
splitLine: {
show: false, //不显示网格线
},
splitArea: {
show: false, //不显示网格区域
},
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
},
],
series: [
{
name: "收入",
type: "bar",
emphasis: {
focus: "series",
},
z: "-1",
barGap: "-100%",
itemStyle: {
color: "#53C19D",
},
barWidth: 30,
data: list.map((e) => e.realIncome),
// data: [100, 232, 201, 154, 190, 330, 410],
},
{
name: "利润",
type: "bar",
emphasis: {
focus: "series",
},
itemStyle: {
color: "#8BB1ED",
},
barWidth: 30,
data: list.map((e) => e.realProfit),
},
{
name: "收入完成率",
type: "line",
smooth: false,
yAxisIndex: 1,
data: list.map((e) => (e.realIncome / e.targetIncome) * 100),
// data: [500, 550, 700, 520, 650, 520, 550],
itemStyle: {
color: "#53C19D",
},
symbol: "none",
},
{
name: "利润完成率",
type: "line",
smooth: false,
itemStyle: {
color: "#8BB1ED",
},
yAxisIndex: 1,
data: list.map((e) => (e.realProfit / e.targetProfit) * 100),
symbol: "none",
},
],
});
}
});
},
setXdata(list, item, i) {
// ["", "", "2021", ""];
let arr = [];
for (let i = 0; i < list.length; i++) {
arr.push("");
}
arr[i] = item;
return arr;
},
initChart2() {
this.request({
url: "/hx/operating/getCivilIndustryPic",
method: "get",
params: { type: 2 },
}).then((res) => {
if (200 == res.code) {
let { totalAndAmount, list, categoryTotal, monthList } = res.data;
this.totalAndAmount = totalAndAmount;
// to do 数据格式不对
// console.log(list.map(e=>(e.filter(e=> e.category == '其他')[0].realQuantity)))
// console.log(list.filter(e => e.category == '其他').map(e => e.realQuantity))
this.initChart3(categoryTotal);
var app = {};
var posList = [
"left",
"right",
"top",
"bottom",
"inside",
"insideTop",
"insideLeft",
"insideRight",
"insideBottom",
"insideTopLeft",
"insideTopRight",
"insideBottomLeft",
"insideBottomRight",
];
app.configParameters = {
rotate: {
min: -90,
max: 90,
},
align: {
options: {
left: "left",
center: "center",
right: "right",
},
},
verticalAlign: {
options: {
top: "top",
middle: "middle",
bottom: "bottom",
},
},
position: {
options: echarts.util.reduce(
posList,
function (map, pos) {
map[pos] = pos;
return map;
},
{}
),
},
distance: {
min: 0,
max: 100,
},
};
app.config = {
rotate: 90,
align: "left",
verticalAlign: "middle",
position: "insideBottom",
distance: 15,
onChange: function () {
var labelOption = {
normal: {
rotate: app.config.rotate,
align: app.config.align,
verticalAlign: app.config.verticalAlign,
position: app.config.position,
distance: app.config.distance,
},
};
myChart.setOption({
series: [
{
label: labelOption,
},
{
label: labelOption,
},
{
label: labelOption,
},
{
label: labelOption,
},
],
});
},
};
var labelOption = {
show: false,
position: app.config.position,
distance: app.config.distance,
align: app.config.align,
verticalAlign: app.config.verticalAlign,
rotate: app.config.rotate,
formatter: "{c} {name|{a}}",
fontSize: 16,
rich: {
name: {
textBorderColor: "#fff",
},
},
};
let newData = [];
for (let i = 0; i < list.length; i++) {
const item = list[i];
const itemLength = item.length;
const listLength = list.length;
if (itemLength > listLength) listLength = itemLength;
for (let j = 0; j < itemLength; j++) {
let arr = Array.apply(null, Array(listLength)).map(() => "");
const item2 = item[j];
if (item2.realQuantity != 0 && item2.realQuantity != null) {
arr[i] = item2.realQuantity;
newData.push({
barMaxWidth: 30,
name: item2.category,
type: "bar",
barGap: 0,
label: labelOption,
xAxisIndex: i,
data: arr.splice(0, i + 1),
});
}
}
}
let newRate = [[], [], []];
for (let i = 0; i < list.length; i++) {
const item = list[i];
for (let j = 0; j < item.length; j++) {
const item2 = item[j];
if (item2.category == "隔热") {
if (item2.quantityRate) {
newRate[0].push(item2.quantityRate);
} else {
newRate[0].push(0);
}
}
if (item2.category == "稀土") {
if (item2.quantityRate) {
newRate[1].push(item2.quantityRate);
} else {
newRate[1].push(0);
}
}
if (item2.category == "其他") {
if (item2.quantityRate) {
newRate[2].push(item2.quantityRate);
} else {
newRate[2].push(0);
}
}
// if (item2.realQuantity != 0 && item.planQuantity != 0) {
// const rate = (item2.realQuantity / item2.planQuantity) * 100;
// newRate[i].push(rate > 100 ? 100 : rate);
// } else {
// newRate[i].push(0);
// }
}
}
console.log(newRate);
this.chart2 = echarts5.init(this.$refs.chart2);
this.chart2.setOption({
color: colorList,
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
// 进行数据处理
formatter: function (params) {
var html = "";
if (params.length != 0) {
// 可以自己打印一下console.info(params[0]);
var getName = params[0].name;
html += getName + "<br/>";
for (var i = 0; i < params.length; i++) {
// 如果为0 为空的数据我们不要了(你们可以直接判断 > 0)
if (
params[i].value != null &&
params[i].value != 0 &&
params[i].value != ""
) {
html += params[i].marker;
html +=
params[i].seriesName + ": " + params[i].value + "<br/>";
}
}
}
return html;
},
},
legend: {
textStyle: {
color: "#fff",
},
data: [
"隔热",
"稀土",
"其他",
"隔热完成率",
"稀土完成率",
"其他完成率",
],
},
// echars 转折线和 echars下载
// toolbox: {
// show: true,
// orient: "vertical",
// left: "right",
// top: "center",
// feature: {
// mark: { show: true },
// dataView: { show: true, readOnly: false },
// magicType: {
// show: true,
// type: ["line", "bar", "stack", "tiled"],
// },
// restore: { show: true },
// saveAsImage: { show: true },
// },
// },
dataZoom: {
type: "slider",
start: 0,
end: 100,
textStyle: {
color: "#fff",
},
},
xAxis: [
...monthList.map((e, i) => {
return {
type: "category",
axisTick: { show: false },
position: "bottom",
data: this.setXdata(monthList, e, i),
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
};
}),
],
yAxis: [
{
min: 0,
splitLine: {
show: true,
// 改变轴线颜色
lineStyle: {
// 使用深浅的间隔色
color: ["rgba(255, 255, 255,.5)"],
},
},
axisLabel: {
formatter: "{value}",
},
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
},
{
type: "value",
min: 0,
max: 100,
// interval: 5,
axisLabel: {
formatter: "{value} %",
},
splitLine: {
show: false, //不显示网格线
},
splitArea: {
show: false, //不显示网格区域
},
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
},
],
series: [
...newData,
{
name: "隔热完成率",
type: "line",
yAxisIndex: 1,
smooth: false,
data: newRate[0],
itemStyle: {
normal: {
color: colorList[0],
},
},
symbol: "none",
},
{
name: "稀土完成率",
type: "line",
yAxisIndex: 1,
smooth: false,
data: newRate[1],
itemStyle: {
normal: {
color: colorList[1],
},
},
symbol: "none",
},
{
name: "其他完成率",
type: "line",
yAxisIndex: 1,
smooth: false,
data: newRate[2],
itemStyle: {
normal: {
color: colorList[2],
},
},
symbol: "none",
},
],
});
}
});
},
initChart3(categoryTotal) {
this.chart3 = echarts.init(this.$refs.chart3);
this.chart3.setOption({
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b}: {c} ({d}%)",
position: "inner",
},
series: [
{
name: "合同金额",
type: "pie",
center: ["45%", "50%"],
radius: ["60%", "80%"],
avoidLabelOverlap: false,
hoverAnimation: false, // hover 效果
label: {
show: false,
position: "center",
},
emphasis: {
label: {
show: false,
fontSize: "40",
fontWeight: "bold",
},
},
labelLine: {
show: false,
},
data: categoryTotal.map((e) => {
return { value: e.amount, name: e.category + "合同" };
}),
itemStyle: {
emphasis: {
shadowBlur: 1,
shadowOffsetX: 0,
shadowColor: "#fff",
},
normal: {
label: {
show: true,
formatter: "{b}",
position: "inner",
},
labelLine: {
show: true,
},
},
},
// color: colorList,
color: ["#5B8FF9", "#5AD8A6", "#5D7092"],
},
{
name: "合同数量",
type: "pie",
radius: ["35%", "55%"],
center: ["45%", "50%"],
avoidLabelOverlap: false,
hoverAnimation: false, // hover 效果
label: {
show: false,
position: "center",
},
emphasis: {
label: {
show: false,
fontSize: "40",
fontWeight: "bold",
},
},
labelLine: {
show: false,
},
data: categoryTotal.map((e) => {
return { value: e.total, name: e.category + "合同" };
}),
// data: [
// { value: 4, name: '合同1' },
// { value: 2, name: '合同2' },
// { value: 6, name: '合同3' },
// ],
itemStyle: {
emphasis: {
shadowBlur: 1,
shadowOffsetX: 0,
shadowColor: "#fff",
},
normal: {
label: {
show: true,
formatter: "{b}",
position: "inner",
},
labelLine: {
show: true,
},
},
},
// color: colorList,
color: ["#5B8FF9", "#5AD8A6", "#5D7092"],
},
],
});
},
initChart4() {
this.request({
url: "/hx/operating/getCivilIndustryPic",
method: "get",
params: { type: 3 },
}).then((res) => {
if (200 == res.code) {
let { list } = res.data;
this.chart4 = echarts.init(this.$refs.chart4);
this.setOptions4(list);
}
});
},
setOptions4(list) {
this.chart4.setOption({
tooltip: {
trigger: "axis",
// formatter: '{a1}<br/>{b1}{c1}',
},
grid: {
containLabel: true,
left: 20,
right: 10,
top: 30,
bottom: 50,
},
dataZoom: {
type: "slider",
start: 0,
end: this.dataZoomEnd(list.length, 7),
textStyle: {
color: "#fff",
},
},
xAxis: {
data: list.map((e) => e.deptName),
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
},
color: ["#ccc", "red"],
yAxis: [
{
min: 0,
max: 100,
interval: 20,
splitLine: {
show: true,
// 改变轴线颜色
lineStyle: {
// 使用深浅的间隔色
color: ["rgba(255, 255, 255,.5)"],
},
},
axisLabel: {
formatter: "{value}",
},
axisLine: {
lineStyle: {
color: "rgb(255, 255, 255)",
},
},
},
],
series: [
{
name: "预测",
type: "bar",
z: "-1",
barGap: "-100%",
barWidth: 30,
itemStyle: {
color: "rgba(246, 217, 126, .2)",
},
data: list.map((e) => e.forecastIncome),
// data: [80, 80, 95, 95, 95, 95, 80, 80, 95, 95, 95, 95],
},
{
name: "数量",
type: "bar",
barWidth: 30,
position: [0, 0],
itemStyle: {
color: "rgba(246, 217, 126, 1)",
},
data: list.map((e) => e.realIncome),
// data: [5, 20, 36, 10, 10, 20, 10, 20, 30, 10, 70, 75],
},
],
});
},
},
};
</script>
<style lang="scss" scoped>
.tag {
.title {
width: 96px;
height: 28px;
line-height: 28px;
text-align: center;
font-size: 14px;
margin-bottom: 10px;
background: linear-gradient(
270deg,
rgba(39, 65, 128, 0.3) 0%,
rgba(4, 169, 191, 0.6) 100%
);
}
}
._box {
width: 162px;
height: 275px;
background-image: url(./img/right2/1.png);
background-size: contain;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
justify-content: space-evenly;
._item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
</style>