|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
- <div>
|
|
|
+ <div v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
|
|
|
<div class="flex-row" style="margin: 10px;">
|
|
|
<div class="d-flex flex-v-mid">
|
|
|
<div>{{detailInfo.bb_name}}</div>
|
|
@@ -9,15 +9,27 @@
|
|
|
</div>
|
|
|
<div>
|
|
|
<el-button size="medium" type="primary" @click="dialogFormVisible=true">编辑</el-button>
|
|
|
- <el-button size="medium" type="primary" @click="handleDownload">导出</el-button>
|
|
|
+ <!-- <el-button size="medium" type="primary" @click="handleDownload">导出</el-button> -->
|
|
|
+ <el-button size="medium" type="primary" @click="handlePdfDownload">导出Pdf</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <el-table :data="tableData" tooltip-effect="dark" v-loading="loading" style="width: 100%" @selection-change="handleSelectionChange">
|
|
|
+ <el-table :data="tableData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange">
|
|
|
<el-table-column type="selection" align="center" width="55"></el-table-column>
|
|
|
<el-table-column label="序号" align="center" type="index" width="50"></el-table-column>
|
|
|
<el-table-column v-for="(item, index) in columnData" :key="index" :label="item.name" show-overflow-tooltip :prop="item.key" width="auto"></el-table-column>
|
|
|
</el-table>
|
|
|
|
|
|
+ <div class="chartArea">
|
|
|
+ <div class="chartArea_left">
|
|
|
+ <div id="echartsAreaLeftCont"></div>
|
|
|
+ <p class="cahrtName">项目管理各科室完成情况</p>
|
|
|
+ </div>
|
|
|
+ <div class="chartArea_right" id="echartsArea_right">
|
|
|
+ <div id="echartsAreaRightCont"></div>
|
|
|
+ <p class="cahrtName">项目管理各科室项目金额</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<el-dialog title="编辑" :visible.sync="dialogFormVisible" width="600px" @close="handleClose">
|
|
|
<add-and-edit ref="addAndEdit" :currentId="parentId" :selectObj="selectObj" :yearData="yearData" @close="handleClose"></add-and-edit>
|
|
|
<div slot="footer">
|
|
@@ -32,6 +44,9 @@
|
|
|
import { tjbbDetail } from "./api";
|
|
|
import { download } from "@/utils/request";
|
|
|
import AddAndEdit from "./AddAndEdit.vue";
|
|
|
+import * as echarts from "echarts";
|
|
|
+import { useUserStore } from "@/stores/user";
|
|
|
+const { real_name, dept_ids, token } = useUserStore();
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
@@ -48,6 +63,10 @@ export default {
|
|
|
name: "项目类别",
|
|
|
key: "xm_type_name"
|
|
|
},
|
|
|
+ // {
|
|
|
+ // name: "项目未完成数量",
|
|
|
+ // key: "xm_wwc_num"
|
|
|
+ // },
|
|
|
{
|
|
|
name: "项目完成数量",
|
|
|
key: "xm_wc_num"
|
|
@@ -79,6 +98,17 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
yearData: [],
|
|
|
+ leftEchart: null,
|
|
|
+ rightEchart: null,
|
|
|
+ extraParameters: {
|
|
|
+ page: 1,
|
|
|
+ limit: 10000,
|
|
|
+ api: 'pdf',
|
|
|
+ ex2pd: 1,
|
|
|
+ },
|
|
|
+ updateUrl: window.globalVariables.api + 'jdbg/xmgl_tjbb/detail',
|
|
|
+ leftFile: '',
|
|
|
+ rightFile: '',
|
|
|
}
|
|
|
},
|
|
|
components: { AddAndEdit },
|
|
@@ -90,12 +120,189 @@ export default {
|
|
|
this.detailInfo = data.one_info;
|
|
|
this.year = this.detailInfo.bb_year.split(",");
|
|
|
this.tableData = data.one_info.xm_list;
|
|
|
+
|
|
|
+ let arr = [];
|
|
|
+ this.tableData.map(item => {
|
|
|
+ let index = arr.findIndex(val => val.department_id == item.department_id);
|
|
|
+ if (index == -1) {
|
|
|
+ arr.push({
|
|
|
+ department_id: item.department_id,
|
|
|
+ department_name: item.department_name,
|
|
|
+ xm_wc_num: Number(item.xm_wc_num),
|
|
|
+ xm_wwc_num: Number(item.xm_wwc_num),
|
|
|
+ xm_total: Number(item.xm_total),
|
|
|
+ ys: Number(item.ys),
|
|
|
+ zbje: Number(item.zbje),
|
|
|
+ sjzf: Number(item.sjzf),
|
|
|
+ children: [item]
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ arr[index].xm_wc_num += Number(item.xm_wc_num);
|
|
|
+ arr[index].xm_wwc_num += Number(item.xm_wwc_num);
|
|
|
+ arr[index].xm_total += Number(item.xm_total);
|
|
|
+ arr[index].ys += Number(item.ys);
|
|
|
+ arr[index].zbje += Number(item.zbje);
|
|
|
+ arr[index].sjzf += Number(item.sjzf);
|
|
|
+ arr[index].children.push(item);
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ this.initEchartLeft(arr);
|
|
|
+ this.initEchartRight(arr);
|
|
|
this.loading = false;
|
|
|
}
|
|
|
},
|
|
|
handleSelectionChange(val) {
|
|
|
this.multipleSelection = [...val];
|
|
|
},
|
|
|
+ //初始化echartleft
|
|
|
+ initEchartLeft(transData) {
|
|
|
+ var chartDom = document.getElementById("echartsAreaLeftCont");
|
|
|
+ var myChart = this.leftEchart = echarts.init(chartDom);
|
|
|
+ var option;
|
|
|
+
|
|
|
+ let arr = [];
|
|
|
+ transData.map(item => {
|
|
|
+ arr.push([item.department_name, item.xm_wc_num, item.xm_wwc_num]);
|
|
|
+ })
|
|
|
+
|
|
|
+ let source = [
|
|
|
+ ["department", "已完成数量(个)", "未完成数量(个)"],
|
|
|
+ ...arr
|
|
|
+ ];
|
|
|
+
|
|
|
+ option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis'
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ show: true,
|
|
|
+ left: "10%",
|
|
|
+ top: "10%",
|
|
|
+ right: "3%",
|
|
|
+ bottom: "18%",
|
|
|
+ },
|
|
|
+ animation: false,
|
|
|
+ legend: {},
|
|
|
+ calculable: true,
|
|
|
+ xAxis: { type: 'category' },
|
|
|
+ yAxis: { type: 'value' },
|
|
|
+ dataset: {
|
|
|
+ source: source
|
|
|
+ },
|
|
|
+ series: [{
|
|
|
+ type: 'bar', color: '#91cc75',
|
|
|
+ // label: {
|
|
|
+ // normal: {
|
|
|
+ // show: true, //显示数值
|
|
|
+ // position: 'top', // 位置设为top
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ }, {
|
|
|
+ type: 'bar', color: '#ee6666',
|
|
|
+ // label: {
|
|
|
+ // normal: {
|
|
|
+ // show: true, //显示数值
|
|
|
+ // position: 'top', // 位置设为top
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ }],
|
|
|
+ dataZoom: [
|
|
|
+ {
|
|
|
+ type: 'slider',
|
|
|
+ show: true,
|
|
|
+ start: 0,
|
|
|
+ end: 100,
|
|
|
+ handleSize: 8
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'inside',
|
|
|
+ start: 0,
|
|
|
+ end: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'slider',
|
|
|
+ show: true,
|
|
|
+ yAxisIndex: 0,
|
|
|
+ filterMode: 'empty',
|
|
|
+ width: 12,
|
|
|
+ height: '70%',
|
|
|
+ handleSize: 8,
|
|
|
+ showDataShadow: false,
|
|
|
+ left: '93%'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+
|
|
|
+ option && myChart.setOption(option);
|
|
|
+ this.exportCharts("left");
|
|
|
+ },
|
|
|
+ //初始化echartRight
|
|
|
+ initEchartRight(transData) {
|
|
|
+ var chartDom = document.getElementById("echartsAreaRightCont");
|
|
|
+ var myChart = this.rightEchart = echarts.init(chartDom);
|
|
|
+ var option;
|
|
|
+
|
|
|
+ let arr = [];
|
|
|
+ transData.map(item => {
|
|
|
+ arr.push([item.department_name, item.xm_total, item.ys, item.zbje, item.sjzf]);
|
|
|
+ })
|
|
|
+
|
|
|
+ let source = [
|
|
|
+ ["department", "项目总数(个)", "预算总金额(元)", "中标总金额(元)", "实际支付总金额(元)"],
|
|
|
+ ...arr
|
|
|
+ ];
|
|
|
+
|
|
|
+ option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis'
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ show: true,
|
|
|
+ left: "10%",
|
|
|
+ top: "10%",
|
|
|
+ right: "3%",
|
|
|
+ bottom: "18%",
|
|
|
+ },
|
|
|
+ animation: false,
|
|
|
+ legend: {},
|
|
|
+ calculable: true,
|
|
|
+ xAxis: { type: 'category' },
|
|
|
+ yAxis: { type: 'value' },
|
|
|
+ dataset: {
|
|
|
+ source: source
|
|
|
+ },
|
|
|
+ series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }, { type: 'bar' }],
|
|
|
+ dataZoom: [
|
|
|
+ {
|
|
|
+ type: 'slider',
|
|
|
+ show: true,
|
|
|
+ start: 0,
|
|
|
+ end: 100,
|
|
|
+ handleSize: 8
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'inside',
|
|
|
+ start: 0,
|
|
|
+ end: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'slider',
|
|
|
+ show: true,
|
|
|
+ yAxisIndex: 0,
|
|
|
+ filterMode: 'empty',
|
|
|
+ width: 12,
|
|
|
+ height: '70%',
|
|
|
+ handleSize: 8,
|
|
|
+ showDataShadow: false,
|
|
|
+ left: '93%'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+
|
|
|
+ option && myChart.setOption(option);
|
|
|
+ this.exportCharts("right");
|
|
|
+ },
|
|
|
handleDownload() {
|
|
|
if (this.multipleSelection.length == 0) {
|
|
|
this.$message.error("请先选择数据!");
|
|
@@ -114,6 +321,87 @@ export default {
|
|
|
|
|
|
download("jdbg/xmgl_tjbb/detail", obj);
|
|
|
},
|
|
|
+ handlePdfDownload() {
|
|
|
+ if (this.multipleSelection.length == 0) {
|
|
|
+ this.$message.error("请先选择数据!");
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //开启loading
|
|
|
+ this.loading = true;
|
|
|
+
|
|
|
+ let arr = [];
|
|
|
+ this.multipleSelection.map((value) => {
|
|
|
+ arr.push(value.xm_id);
|
|
|
+ });
|
|
|
+
|
|
|
+ let stringExpId = "";
|
|
|
+ if (arr.length > 0) {
|
|
|
+ stringExpId = arr.join();
|
|
|
+ } else {//没有选择任何一个
|
|
|
+ stringExpId = "";
|
|
|
+ }
|
|
|
+
|
|
|
+ let formData = new FormData();
|
|
|
+ formData.append('page', this.extraParameters.page)
|
|
|
+ formData.append('limit', this.extraParameters.limit)
|
|
|
+ formData.append('api', this.extraParameters.api)
|
|
|
+ formData.append('ex2pdf', this.extraParameters.ex2pd)
|
|
|
+ formData.append('bb_id', this.parentId)
|
|
|
+ formData.append('token', token);
|
|
|
+ formData.append('ids', stringExpId);
|
|
|
+ formData.append('pdf_images[0]', this.leftFile);
|
|
|
+ formData.append('pdf_images[1]', this.rightFile);
|
|
|
+
|
|
|
+ //发起axios请求
|
|
|
+ let that = this;
|
|
|
+ that.$axios({
|
|
|
+ method: 'post',
|
|
|
+ url: this.updateUrl,
|
|
|
+ headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
+ data: formData
|
|
|
+ })
|
|
|
+ .then(res => {
|
|
|
+ if (res.data.code == "1") {
|
|
|
+ this.loading = false;
|
|
|
+ console.log("77")
|
|
|
+ let openLink = window.globalVariables.api + res.data.data.pdf;
|
|
|
+ window.open(openLink, "_blank");
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ console.log(error)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ //图片转化为文件流
|
|
|
+ exportCharts(markLabel) {
|
|
|
+ if (markLabel == "left") {
|
|
|
+ const leftBase64 = this.leftEchart.getDataURL({
|
|
|
+ backgroundColor: '#fff'
|
|
|
+ })
|
|
|
+ const leftFile = this.base642File(leftBase64, 'left.png');
|
|
|
+ this.leftFile = this.base642File(leftBase64, 'left.png');
|
|
|
+
|
|
|
+ } else {
|
|
|
+ const rightBase64 = this.rightEchart.getDataURL({
|
|
|
+ backgroundColor: '#fff'
|
|
|
+ })
|
|
|
+ const rightFile = this.base642File(rightBase64, 'right.png');
|
|
|
+ this.rightFile = this.base642File(rightBase64, 'right.png');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ base642File(dataurl, filename) {
|
|
|
+ var arr = dataurl.split(','),
|
|
|
+ mime = arr[0].match(/:(.*?);/)[1],
|
|
|
+ bstr = atob(arr[1]),
|
|
|
+ n = bstr.length,
|
|
|
+ u8arr = new Uint8Array(n);
|
|
|
+ while (n--) {
|
|
|
+ u8arr[n] = bstr.charCodeAt(n);
|
|
|
+ }
|
|
|
+ return new File([u8arr], filename, { type: mime });
|
|
|
+ },
|
|
|
handleClose(type) {
|
|
|
this.dialogFormVisible = false;
|
|
|
this.$refs.addAndEdit && this.$refs.addAndEdit.resetForm();
|
|
@@ -141,5 +429,25 @@ export default {
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
-<style>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.chartArea {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ min-height: 200px;
|
|
|
+}
|
|
|
+.chartArea_left {
|
|
|
+ width: 50%;
|
|
|
+}
|
|
|
+.chartArea_right {
|
|
|
+ width: 50%;
|
|
|
+}
|
|
|
+#echartsAreaLeftCont,
|
|
|
+#echartsAreaRightCont {
|
|
|
+ margin-top: 5%;
|
|
|
+ min-height: 400px;
|
|
|
+}
|
|
|
+.cahrtName {
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 3%;
|
|
|
+}
|
|
|
</style>
|