Browse Source

项目管理导出pdf

bzkf30 2 years ago
parent
commit
ddf7991806
2 changed files with 2191 additions and 4350 deletions
  1. 312 4
      src/views/xmgl/bbtj/components/detail.vue
  2. 1879 4346
      yarn.lock

+ 312 - 4
src/views/xmgl/bbtj/components/detail.vue

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

File diff suppressed because it is too large
+ 1879 - 4346
yarn.lock