Parcourir la source

新增项目结算统计分析

余思翰 il y a 5 mois
Parent
révision
5a43936762

+ 5
- 3
oa-ui/src/views/flowable/form/finance/borrowForm.vue Voir le fichier

@@ -243,7 +243,7 @@
243 243
           </div>
244 244
           <el-divider></el-divider>
245 245
           <el-form-item label="支付凭证" prop="lendDocument">
246
-            <FileUpload v-if="taskName == '财务处理'" :disabled="taskName != '财务处理'" :limit="1" :filePathName="'借款/支付凭证'"
246
+            <FileUpload v-if="taskName == '财务处理'" :disabled="taskName != '财务处理'" :limit="1" :filePathName="'借款/支付凭证'" :isShowTip="false"
247 247
               :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']" @input="getLendPath">
248 248
             </FileUpload>
249 249
             <div v-if="form.lendDocument && taskName != '财务处理'">
@@ -257,9 +257,9 @@
257 257
               </el-link>
258 258
             </div>
259 259
           </el-form-item>
260
-          <el-form-item label="财务部支付备注" prop="cwComment">
260
+          <el-form-item label="财务部支付备注" prop="cwComment" label-width="120px">
261 261
             <el-input type="textarea" v-model="form.cwComment" placeholder="请输入财务部支付备注" :disabled="taskName != '财务处理'"
262
-              :autosize="{ minRows: 4 }" />
262
+              :autosize="{ minRows: 2 }" />
263 263
           </el-form-item>
264 264
           <el-row>
265 265
             <el-col :span="6" :xs="24" :offset="12">
@@ -747,6 +747,8 @@ export default {
747 747
         this.$set(this.taskForm.variables, "approval", userId);
748 748
         this.handleComplete(this.taskForm);
749 749
       } else if (this.deptId == 102) { //如果是经营管理层申请,走总经理审批
750
+        this.form.managerAmount = this.form.applyAmount;
751
+        updateBorrow(this.form);
750 752
         getUserByPost({ postName: '总经理' }).then(res => {
751 753
           this.$set(this.taskForm.variables, "dept", this.deptId);
752 754
           this.$set(this.taskForm.variables, "approval", res.data[0].userId);

+ 28
- 25
oa-ui/src/views/flowable/form/projectContractInfo.vue Voir le fichier

@@ -2,12 +2,12 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-10-10 10:03:14
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2024-10-10 14:37:00
5
+ * @LastEditTime: 2024-10-24 16:45:48
6 6
 -->
7 7
 <template>
8 8
   <div>
9 9
     <el-form-item label="主合同信息" label-width="120px">
10
-      <div v-if="hasContract">
10
+      <div v-if="hasContract" v-loading="contractLoading">
11 11
         <el-descriptions border style="margin-top: 10px" :column="2" v-for="item in contractObjList">
12 12
           <el-descriptions-item label="合同名称">
13 13
             {{ item.contractName }}
@@ -26,13 +26,11 @@
26 26
           </el-descriptions-item>
27 27
           <el-descriptions-item label="合同文件">
28 28
             <div v-if="item.contractDocument" class="upload-list">
29
-              <el-link type="primary"
30
-                @click="reviewWord(`${baseUrl}${'/profile/upload' + item.contractDocument}`)">
29
+              <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + item.contractDocument}`)">
31 30
                 {{ getFileName(item.contractDocument) }}
32 31
               </el-link>
33
-              <el-link class="ml20" type="warning"
34
-                :href="`${baseUrl}${'/profile/upload' + item.contractDocument}`" :underline="false"
35
-                target="_blank">
32
+              <el-link class="ml20" type="warning" :href="`${baseUrl}${'/profile/upload' + item.contractDocument}`"
33
+                :underline="false" target="_blank">
36 34
                 <span class="el-icon-download">下载文件</span>
37 35
               </el-link>
38 36
             </div>
@@ -50,7 +48,7 @@
50 48
       </div>
51 49
     </el-form-item>
52 50
     <el-form-item label="分包合同信息" label-width="120px">
53
-      <div v-if="hasSubContract">
51
+      <div v-if="hasSubContract" v-loading="subContractLoading">
54 52
         <el-descriptions border style="margin-top: 10px" :column="2" v-for="item in subContractObjList">
55 53
           <el-descriptions-item label="分包合同名称">
56 54
             {{ item.subContractName }}
@@ -63,13 +61,11 @@
63 61
           </el-descriptions-item>
64 62
           <el-descriptions-item label="分包合同文件">
65 63
             <div v-if="item.contractDocument" class="upload-list">
66
-              <el-link type="primary"
67
-                @click="reviewWord(`${baseUrl}${'/profile/upload' + item.contractDocument}`)">
64
+              <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + item.contractDocument}`)">
68 65
                 {{ getFileName(item.contractDocument) }}
69 66
               </el-link>
70
-              <el-link class="ml20" type="warning"
71
-                :href="`${baseUrl}${'/profile/upload' + item.contractDocument}`" :underline="false"
72
-                target="_blank">
67
+              <el-link class="ml20" type="warning" :href="`${baseUrl}${'/profile/upload' + item.contractDocument}`"
68
+                :underline="false" target="_blank">
73 69
                 <span class="el-icon-download">下载文件</span>
74 70
               </el-link>
75 71
             </div>
@@ -115,25 +111,30 @@ export default {
115 111
       contractObjList: [],
116 112
       subContractObjList: [],
117 113
       hasContract: true,
118
-      hasSubContract: true
114
+      hasSubContract: true,
115
+      contractLoading: true,
116
+      subContractLoading: true,
119 117
     }
120 118
   },
121 119
   methods: {
122 120
     init() {
123 121
       const projectId = this.projectId;
124
-      Promise.all([listProjectContract({ projectId }), listProjectSubcontract({ projectId })]).then(response => {
122
+      console.log(projectId);
123
+      this.contractLoading = true;
124
+      this.subContractLoading = true;
125
+      Promise.all([listProjectContract({ projectId }), listProjectSubcontract({ projectId })]).then(async response => {
125 126
         let [contractData = null, subContractData = null] = response
126 127
         // 主合同
127 128
         if (contractData.total >= 1) {
128 129
           let list = contractData.rows;
129 130
           this.contractObjList = []
130 131
           for (let l of list) {
131
-            getContract(l.contractId).then(res => {
132
-              if (res.data) {
133
-                this.contractObjList.push(res.data)
134
-              }
135
-            })
132
+            let res = await getContract(l.contractId)
133
+            if (res.data) {
134
+              this.contractObjList.push(res.data)
135
+            }
136 136
           }
137
+          this.hasContract = true;
137 138
         } else if (contractData.total == 0) {
138 139
           this.hasContract = false;
139 140
         }
@@ -143,15 +144,17 @@ export default {
143 144
           let list = subContractData.rows;
144 145
           this.subContractObjList = []
145 146
           for (let l of list) {
146
-            getSubContract(l.subContractId).then(res => {
147
-              if (res.data) {
148
-                this.subContractObjList.push(res.data)
149
-              }
150
-            })
147
+            let res = await getSubContract(l.subContractId)
148
+            if (res.data) {
149
+              this.subContractObjList.push(res.data)
150
+            }
151 151
           }
152
+          this.hasSubContract = true;
152 153
         } else if (subContractData.total == 0) {
153 154
           this.hasSubContract = false;
154 155
         }
156
+        this.contractLoading = false;
157
+        this.subContractLoading = false;
155 158
       })
156 159
     }
157 160
   },

+ 4
- 137
oa-ui/src/views/statistics/components/borrowStatistics.vue Voir le fichier

@@ -1,8 +1,8 @@
1 1
 <!--
2 2
  * @Author: ysh
3 3
  * @Date: 2024-10-18 11:17:48
4
- * @LastEditors: wrh
5
- * @LastEditTime: 2024-10-24 14:54:45
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-10-24 15:53:13
6 6
 -->
7 7
 <template>
8 8
   <div style="width:100%;" v-loading="loading">
@@ -16,10 +16,6 @@
16 16
         <div class="middle-top" id="borrowLine"></div>
17 17
         <div class="middle-top" id="borrowProject"></div>
18 18
       </div>
19
-      <div class="right">
20
-        <div class="right-top" id="settleBar"></div>
21
-        <div class="right-top" id="settleLine"></div>
22
-      </div>
23 19
     </div>
24 20
   </div>
25 21
 </template>
@@ -27,17 +23,13 @@
27 23
 <script>
28 24
 import { ehcartsInit } from '@/utils/echarts'
29 25
 import { getBorrowStatistic } from '@/api/oa/borrow/borrow';
30
-let borrowYearChart, borrowAmountChart, borrowUsageChart, borrowProjectChart, settleYearChart, settleAmountChart
26
+let borrowYearChart, borrowAmountChart, borrowUsageChart, borrowProjectChart
31 27
 export default {
32 28
   props: {
33 29
     borrowData: {
34 30
       type: Object,
35 31
       require: true,
36 32
     },
37
-    settleData: {
38
-      type: Object,
39
-      require: true,
40
-    },
41 33
   },
42 34
   watch: {
43 35
     borrowUsage() {
@@ -54,12 +46,9 @@ export default {
54 46
       borrowUsage: {},
55 47
       borrowUsageAmount: {},
56 48
       borrowYear: {},
57
-      settleYear: {},
58
-      settleAmount: {},
59 49
       yearProjectAmount: {},
60 50
       yearProjectCount: {},
61 51
       sumBorrowAmount: 0,
62
-      sumSettleAmount: 0,
63 52
       dataLoading: false,
64 53
       activeYear: ''
65 54
     }
@@ -75,8 +64,6 @@ export default {
75 64
     this.initBorrowUsagePie('');
76 65
     // this.initBorrowUsageAmountPie('');
77 66
     this.initBorrowProjectLineBar();
78
-    this.initSettleYearBar();
79
-    this.initSettleAmountLine();
80 67
   },
81 68
   methods: {
82 69
     initDatas() {
@@ -90,12 +77,6 @@ export default {
90 77
         let sum = Object.values(this.borrowAmount).reduce((accumulator, currentValue) => accumulator + currentValue, 0);
91 78
         this.sumBorrowAmount = (sum / 10000).toFixed(1)
92 79
       }
93
-      if (Object.keys(this.settleData).length !== 0) {
94
-        this.settleYear = this.settleData.year[0];
95
-        this.settleAmount = this.settleData.amount[0];
96
-        let sum = Object.values(this.settleAmount).reduce((accumulator, currentValue) => accumulator + currentValue, 0);
97
-        this.sumSettleAmount = (sum / 10000).toFixed(1)
98
-      }
99 80
     },
100 81
     clickYear(charts) {
101 82
       let that = this;
@@ -365,120 +346,6 @@ export default {
365 346
       };
366 347
       ehcartsInit(borrowProjectChart, 'borrowProject', option);
367 348
     },
368
-    initSettleYearBar() {
369
-      let option = {
370
-        title: {
371
-          text: '各年结算申请次数',
372
-          subtext: '共计结算次数:' + Object.values(this.settleYear).reduce((accumulator, currentValue) => accumulator + currentValue, 0) + '次'
373
-        },
374
-        grid: {
375
-          left: '1%',
376
-          right: '1%',
377
-          bottom: '0%',
378
-          height: '60%',
379
-          containLabel: true
380
-        },
381
-        graphic: [
382
-          {
383
-            type: 'text',
384
-            name: '',
385
-            right: '0',
386
-            top: '20%',
387
-            style: {
388
-              text: '全部年份',
389
-              fill: '#000', // 文本颜色  
390
-              fontSize: 12, // 文本大小  
391
-              fontWeight: '' // 文本粗细  
392
-            }
393
-          }
394
-        ],
395
-        tooltip: {
396
-          trigger: 'axis',
397
-          axisPointer: {
398
-            type: 'none',
399
-            label: {
400
-              backgroundColor: '#6a7985'
401
-            }
402
-          }
403
-        },
404
-        xAxis: {
405
-          name: '年',
406
-          type: 'category',
407
-          data: Object.keys(this.settleYear),
408
-        },
409
-        yAxis: {
410
-          type: 'value',
411
-          name: '单位:次'
412
-        },
413
-        series: [
414
-          {
415
-            data: Object.values(this.settleYear),
416
-            type: 'bar',
417
-            smooth: true,
418
-            label: {
419
-              show: true,
420
-              position: 'top'
421
-            },
422
-            itemStyle: {
423
-              color: '#00788C'
424
-            }
425
-          }
426
-        ]
427
-      };
428
-      let charts = ehcartsInit(settleYearChart, 'settleBar', option);
429
-    },
430
-    initSettleAmountLine() {
431
-      let option = {
432
-        title: {
433
-          text: '各年结算金额',
434
-          subtext: '结算总额:' + Object.values(this.settleAmount).reduce((accumulator, currentValue) => accumulator + currentValue, 0) + '元' +
435
-            '(约' + this.sumSettleAmount + '万元)'
436
-        },
437
-        grid: {
438
-          left: '1%',
439
-          right: '1%',
440
-          bottom: '0%',
441
-          height: '60%',
442
-          containLabel: true
443
-        },
444
-        tooltip: {
445
-          trigger: 'axis',
446
-          axisPointer: {
447
-            type: 'none',
448
-            label: {
449
-              backgroundColor: '#6a7985'
450
-            }
451
-          }
452
-        },
453
-        xAxis: {
454
-          type: 'category',
455
-          data: Object.keys(this.settleAmount),
456
-        },
457
-        yAxis: {
458
-          type: 'value',
459
-          name: '单位:元'
460
-        },
461
-        series: [
462
-          {
463
-            min: 0,
464
-            data: Object.values(this.settleAmount),
465
-            type: 'line',
466
-            smooth: true,
467
-            label: {
468
-              show: true,
469
-              position: 'top',
470
-              formatter: function (params) {
471
-                let value = params.value;
472
-                if (value >= 10000) {
473
-                  return '约' + (value / 10000).toFixed(1) + '万元'
474
-                }
475
-              }
476
-            }
477
-          }
478
-        ]
479
-      };
480
-      ehcartsInit(settleAmountChart, 'settleLine', option);
481
-    }
482 349
   },
483 350
 }
484 351
 </script>
@@ -518,7 +385,7 @@ export default {
518 385
   }
519 386
 
520 387
   .right {
521
-    flex: 1;
388
+    // flex: 1;
522 389
 
523 390
     .right-top {
524 391
       width: 100%;

+ 1
- 1
oa-ui/src/views/statistics/components/contractStatistics.vue Voir le fichier

@@ -626,7 +626,7 @@ export default {
626 626
   }
627 627
 
628 628
   .right {
629
-    flex: 1;
629
+    // flex: 1;
630 630
   }
631 631
 }
632 632
 </style>

+ 4
- 4
oa-ui/src/views/statistics/components/projectStatistics.vue Voir le fichier

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-10-11 16:41:17
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2024-10-15 17:15:47
5
+ * @LastEditTime: 2024-10-24 16:16:05
6 6
 -->
7 7
 <template>
8 8
   <div style="width:100%;" v-loading="loading">
@@ -377,7 +377,7 @@ export default {
377 377
           data: Object.keys(this.type),
378 378
           axisLabel: {
379 379
             fontSize: 12,
380
-            width: 50,
380
+            width: 130,
381 381
             overflow: 'truncate',
382 382
           }
383 383
         },
@@ -449,8 +449,8 @@ export default {
449 449
   }
450 450
 
451 451
   .right {
452
-    flex: 1;
453
-    display: flex;
452
+    // flex: 1;
453
+    // display: flex;
454 454
   }
455 455
 }
456 456
 </style>

+ 456
- 0
oa-ui/src/views/statistics/components/settleStatistics.vue Voir le fichier

@@ -0,0 +1,456 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-10-18 11:17:48
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-10-24 16:00:44
6
+-->
7
+<template>
8
+  <div style="width:100%;" v-loading="loading">
9
+    <div class="titles">结算和结算统计</div>
10
+    <div class="warpper">
11
+      <div class="left">
12
+        <div class="left-top" id="settleBar"></div>
13
+        <div class="left-top" id="settleTypePie" v-loading="dataLoading"></div>
14
+      </div>
15
+      <div class="middle">
16
+        <div class="middle-top" id="settleLine"></div>
17
+        <div class="middle-top" id="settleProject"></div>
18
+      </div>
19
+    </div>
20
+  </div>
21
+</template>
22
+
23
+<script>
24
+import { ehcartsInit } from '@/utils/echarts'
25
+import { getSettleStatistic } from '@/api/oa/settle/settle';
26
+let settleYearChart, settleAmountChart, settleTypeChart, settleProjectChart
27
+export default {
28
+  props: {
29
+    settleData: {
30
+      type: Object,
31
+      require: true,
32
+    },
33
+  },
34
+  watch: {
35
+    settleType() {
36
+      this.initSettleTypePie(this.activeYear)
37
+    },
38
+    settleData() {
39
+      this.initDatas();
40
+    }
41
+  },
42
+  data() {
43
+    return {
44
+      loading: false,
45
+      settleAmount: {},
46
+      settleType: {},
47
+      settleTypeAmount: {},
48
+      settleYear: {},
49
+      settleYear: {},
50
+      settleAmount: {},
51
+      yearProjectAmount: {},
52
+      yearProjectCount: {},
53
+      sumSettleAmount: 0,
54
+      sumSettleAmount: 0,
55
+      dataLoading: false,
56
+      activeYear: ''
57
+    }
58
+  },
59
+  created() {
60
+    this.loading = true;
61
+    this.initDatas();
62
+  },
63
+  mounted() {
64
+    this.initSettleYearBar();
65
+    this.initSettleAmountLine();
66
+    this.initSettleTypePie('');
67
+    // this.initSettleTypeAmountPie('');
68
+    this.initSettleProjectLineBar();
69
+    this.initSettleAmountLine();
70
+  },
71
+  methods: {
72
+    initDatas() {
73
+      if (Object.keys(this.settleData).length !== 0) {
74
+        this.settleAmount = this.settleData.amount[0];
75
+        this.settleType = this.settleData.type[0];
76
+        this.settleTypeAmount = this.settleData.typeAmount[0];
77
+        this.settleYear = this.settleData.year[0];
78
+        this.yearProjectAmount = this.settleData.yearProjectAmount[0];
79
+        this.yearProjectCount = this.settleData.yearProjectCount[0];
80
+        let sum = Object.values(this.settleAmount).reduce((accumulator, currentValue) => accumulator + currentValue, 0);
81
+        this.sumSettleAmount = (sum / 10000).toFixed(1)
82
+        this.loading = false;
83
+      } else {
84
+        this.loading = true;
85
+      }
86
+    },
87
+    clickYear(charts) {
88
+      let that = this;
89
+      charts.on('click', function (event) {
90
+        if (event) {
91
+          that.activeYear = event.name;
92
+          let year = event.name + '-01-01'
93
+          if (event.name == "") {
94
+            year = ''
95
+          }
96
+          that.dataLoading = true
97
+          getSettleStatistic({ gmTime: year }).then(res => {
98
+            that.settleType = res.data.type[0];
99
+            that.settleTypeAmount = res.data.typeAmount[0];
100
+            that.dataLoading = false
101
+          })
102
+        }
103
+      })
104
+    },
105
+    initSettleYearBar() {
106
+      let option = {
107
+        title: {
108
+          text: '各年结算申请次数',
109
+          subtext: '共计结算次数:' + Object.values(this.settleYear).reduce((accumulator, currentValue) => accumulator + currentValue, 0) + '次'
110
+        },
111
+        grid: {
112
+          left: '1%',
113
+          right: '1%',
114
+          bottom: '0%',
115
+          height: '60%',
116
+          containLabel: true
117
+        },
118
+        graphic: [
119
+          {
120
+            type: 'text',
121
+            name: '',
122
+            right: '0',
123
+            top: '20%',
124
+            style: {
125
+              text: '全部年份',
126
+              fill: '#000', // 文本颜色  
127
+              fontSize: 12, // 文本大小  
128
+              fontWeight: '' // 文本粗细  
129
+            }
130
+          }
131
+        ],
132
+        tooltip: {
133
+          trigger: 'axis',
134
+          axisPointer: {
135
+            type: 'none',
136
+            label: {
137
+              backgroundColor: '#6a7985'
138
+            }
139
+          }
140
+        },
141
+        xAxis: {
142
+          name: '年',
143
+          type: 'category',
144
+          data: Object.keys(this.settleYear),
145
+        },
146
+        yAxis: {
147
+          type: 'value',
148
+          name: '单位:次'
149
+        },
150
+        series: [
151
+          {
152
+            data: Object.values(this.settleYear),
153
+            type: 'bar',
154
+            smooth: true,
155
+            label: {
156
+              show: true,
157
+              position: 'top'
158
+            },
159
+            itemStyle: {
160
+              color: '#3498DB'
161
+            }
162
+          }
163
+        ]
164
+      };
165
+      let charts = ehcartsInit(settleYearChart, 'settleBar', option);
166
+      this.clickYear(charts)
167
+    },
168
+    initSettleAmountLine() {
169
+      let option = {
170
+        title: {
171
+          text: '各年结算金额',
172
+          subtext: '结算总额:' + Object.values(this.settleAmount).reduce((accumulator, currentValue) => accumulator + currentValue, 0) + '元' +
173
+            '(约' + this.sumSettleAmount + '万元)'
174
+        },
175
+        grid: {
176
+          left: '1%',
177
+          right: '1%',
178
+          bottom: '0%',
179
+          height: '60%',
180
+          containLabel: true
181
+        },
182
+        tooltip: {
183
+          trigger: 'axis',
184
+          axisPointer: {
185
+            type: 'none',
186
+            label: {
187
+              backgroundColor: '#6a7985'
188
+            }
189
+          }
190
+        },
191
+        xAxis: {
192
+          type: 'category',
193
+          data: Object.keys(this.settleAmount),
194
+        },
195
+        yAxis: {
196
+          type: 'value',
197
+          name: '单位:元'
198
+        },
199
+        series: [
200
+          {
201
+            min: 0,
202
+            data: Object.values(this.settleAmount),
203
+            type: 'line',
204
+            smooth: true,
205
+            label: {
206
+              show: true,
207
+              position: 'top',
208
+              formatter: function (params) {
209
+                let value = params.value;
210
+                if (value >= 10000) {
211
+                  return '约' + (value / 10000).toFixed(1) + '万元'
212
+                }
213
+              }
214
+            }
215
+          }
216
+        ]
217
+      };
218
+      ehcartsInit(settleAmountChart, 'settleLine', option);
219
+    },
220
+    initSettleTypePie(year) {
221
+      let option = {
222
+        title: {
223
+          text: year + '结算类型占比',
224
+        },
225
+        tooltip: {
226
+          trigger: 'item',
227
+          formatter: '{a} <br/>{b} : {c} ({d}%)'
228
+        },
229
+        legend: {
230
+          top: 'bottom'
231
+        },
232
+        series: [
233
+          {
234
+            name: '占比',
235
+            type: 'pie',
236
+            radius: '30%',
237
+            center: ['25%', '50%'],
238
+            avoidLabelOverlap: false,
239
+            data: Object.entries(this.settleType).map(([key, value]) => {
240
+              return { name: key, value: value }
241
+            }),
242
+            emphasis: {
243
+              itemStyle: {
244
+                shadowBlur: 10,
245
+                shadowOffsetX: 0,
246
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
247
+              }
248
+            },
249
+            label: {
250
+              alignTo: 'none',
251
+              formatter: '{name|{b}}\n{value|{c}个}',
252
+              minMargin: 5,
253
+              edgeDistance: 8,
254
+              lineHeight: 15,
255
+              rich: {
256
+                time: {
257
+                  fontSize: 10,
258
+                  color: '#999'
259
+                }
260
+              }
261
+            },
262
+          },
263
+          {
264
+            name: '占比',
265
+            type: 'pie',
266
+            radius: '30%',
267
+            center: ['65%', '50%'],
268
+            avoidLabelOverlap: false,
269
+            data: Object.entries(this.settleTypeAmount).map(([key, value]) => {
270
+              return { name: key, value: value }
271
+            }),
272
+            emphasis: {
273
+              itemStyle: {
274
+                shadowBlur: 10,
275
+                shadowOffsetX: 0,
276
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
277
+              }
278
+            },
279
+            label: {
280
+              alignTo: 'none',
281
+              formatter: '{name|{b}}\n{value|{c}元}',
282
+              minMargin: 5,
283
+              edgeDistance: 8,
284
+              lineHeight: 15,
285
+              rich: {
286
+                time: {
287
+                  fontSize: 10,
288
+                  color: '#999'
289
+                }
290
+              }
291
+            },
292
+          },
293
+        ]
294
+      };
295
+      ehcartsInit(settleTypeChart, 'settleTypePie', option);
296
+    },
297
+    initSettleProjectLineBar(year) {
298
+      let option = {
299
+        title: {
300
+          text: '项目结算金额',
301
+        },
302
+        tooltip: {
303
+          trigger: 'axis',
304
+        },
305
+        grid: {
306
+          left: '1%',
307
+          right: '1%',
308
+          bottom: '0%',
309
+          containLabel: true
310
+        },
311
+        legend: {
312
+          right: '0%',
313
+          orient: 'vertical'
314
+        },
315
+        xAxis: [
316
+          {
317
+            type: 'category',
318
+            data: Object.keys(this.yearProjectAmount),
319
+            axisPointer: {
320
+              type: 'shadow'
321
+            }
322
+          }
323
+        ],
324
+        yAxis: [
325
+          {
326
+            type: 'value',
327
+            name: '金额',
328
+          }
329
+        ],
330
+        series: [
331
+          {
332
+            type: 'line',
333
+            tooltip: {
334
+              valueFormatter: function (value) {
335
+                return value + ' 元';
336
+              }
337
+            },
338
+            smooth: true,
339
+            data: Object.values(this.yearProjectAmount),
340
+            label: {
341
+              show: true,
342
+              position: 'top',
343
+              formatter: function (params) {
344
+                let value = params.value;
345
+                if (value >= 10000) {
346
+                  return '约' + (value / 10000).toFixed(1) + '万元'
347
+                }
348
+              }
349
+            }
350
+          },
351
+        ]
352
+      };
353
+      ehcartsInit(settleProjectChart, 'settleProject', option);
354
+    },
355
+    initSettleAmountLine() {
356
+      let option = {
357
+        title: {
358
+          text: '各年结算金额',
359
+          subtext: '结算总额:' + Object.values(this.settleAmount).reduce((accumulator, currentValue) => accumulator + currentValue, 0) + '元' +
360
+            '(约' + this.sumSettleAmount + '万元)'
361
+        },
362
+        grid: {
363
+          left: '1%',
364
+          right: '1%',
365
+          bottom: '0%',
366
+          height: '60%',
367
+          containLabel: true
368
+        },
369
+        tooltip: {
370
+          trigger: 'axis',
371
+          axisPointer: {
372
+            type: 'none',
373
+            label: {
374
+              backgroundColor: '#6a7985'
375
+            }
376
+          }
377
+        },
378
+        xAxis: {
379
+          type: 'category',
380
+          data: Object.keys(this.settleAmount),
381
+        },
382
+        yAxis: {
383
+          type: 'value',
384
+          name: '单位:元'
385
+        },
386
+        series: [
387
+          {
388
+            min: 0,
389
+            data: Object.values(this.settleAmount),
390
+            type: 'line',
391
+            smooth: true,
392
+            label: {
393
+              show: true,
394
+              position: 'top',
395
+              formatter: function (params) {
396
+                let value = params.value;
397
+                if (value >= 10000) {
398
+                  return '约' + (value / 10000).toFixed(1) + '万元'
399
+                }
400
+              }
401
+            }
402
+          }
403
+        ]
404
+      };
405
+      ehcartsInit(settleAmountChart, 'settleLine', option);
406
+    }
407
+  },
408
+}
409
+</script>
410
+
411
+<style lang="scss" scoped>
412
+.titles {
413
+  font-family: 'puhuiti';
414
+  font-size: 16px;
415
+  margin-bottom: 16px;
416
+}
417
+
418
+.warpper {
419
+  width: 100%;
420
+  height: 100%;
421
+  display: flex;
422
+
423
+  .left {
424
+    flex: 1;
425
+
426
+    .left-top {
427
+      width: 100%;
428
+      height: 300px;
429
+      padding: 10px;
430
+      border: 1px solid #ececec;
431
+    }
432
+  }
433
+
434
+  .middle {
435
+    flex: 1;
436
+
437
+    .middle-top {
438
+      width: 100%;
439
+      height: 300px;
440
+      padding: 10px;
441
+      border: 1px solid #ececec;
442
+    }
443
+  }
444
+
445
+  .right {
446
+    // flex: 1;
447
+
448
+    .right-top {
449
+      width: 100%;
450
+      height: 300px;
451
+      padding: 10px;
452
+      border: 1px solid #ececec;
453
+    }
454
+  }
455
+}
456
+</style>

+ 106
- 4
oa-ui/src/views/statistics/components/topHead.vue Voir le fichier

@@ -18,7 +18,7 @@
18 18
       </div>
19 19
       <div class="two item-box" @click="$emit('handleClick', 'contract')">
20 20
         <div class="data-left">
21
-          <div class="data-title">{{ thisYear }}年承接合同数</div>
21
+          <div class="data-title">{{ thisYear }}年承接合同数</div>
22 22
           <div class="number">{{ contractNum.toLocaleString('en-US') }}</div>
23 23
           <div>
24 24
             <span class="text-1">较去年</span>
@@ -33,7 +33,7 @@
33 33
       </div>
34 34
       <div class="three item-box" @click="$emit('handleClick', 'device')">
35 35
         <div class="data-left">
36
-          <div class="data-title">{{ thisYear }}年设备申领记录</div>
36
+          <div class="data-title">{{ thisYear }}年设备申领</div>
37 37
           <div class="number">{{ deviceNum.toLocaleString('en-US') }}</div>
38 38
           <div>
39 39
             <span class="text-1">较去年</span>
@@ -59,6 +59,21 @@
59 59
           <div id="thisBorrow"></div>
60 60
         </div>
61 61
       </div>
62
+
63
+      <div class="five item-box" @click="$emit('handleClick', 'settle')">
64
+        <div class="data-left">
65
+          <div class="data-title">{{ thisYear }}结算申请次数</div>
66
+          <div class="number">{{ settleNum.toLocaleString('en-US') }}</div>
67
+          <div>
68
+            <span class="text-1">较去年</span>
69
+            <span class="text-2" :class="{ upColor: isSettleUp, dowColor: !isSettleUp }">{{ settleSubYear }}</span>
70
+            <img :src="isSettleUp ? upImg : downImg" alt="">
71
+          </div>
72
+        </div>
73
+        <div class="chart-box">
74
+          <div id="thisSettle"></div>
75
+        </div>
76
+      </div>
62 77
     </div>
63 78
   </div>
64 79
 </template>
@@ -68,7 +83,7 @@ import upSrc from '@/assets/icons/up.png'
68 83
 import downSrc from '@/assets/icons/down.png'
69 84
 import * as echarts from 'echarts'
70 85
 import { ehcartsInit } from '@/utils/echarts'
71
-let thisYearChart, contractYearChart, deviceYearChart,borrowYearChart
86
+let thisYearChart, contractYearChart, deviceYearChart, borrowYearChart, settleYearChart
72 87
 export default {
73 88
   props: {
74 89
     pDatas: {
@@ -86,6 +101,10 @@ export default {
86 101
     bDatas: {
87 102
       type: Object,
88 103
       require: true,
104
+    },
105
+    sDatas: {
106
+      type: Object,
107
+      require: true,
89 108
     }
90 109
   },
91 110
   data() {
@@ -94,12 +113,14 @@ export default {
94 113
       contractNum: 0,
95 114
       deviceNum: 0,
96 115
       borrowNum: 0,
116
+      settleNum: 0,
97 117
       upImg: upSrc,
98 118
       downImg: downSrc,
99 119
       isProjectUp: false,
100 120
       isContractUp: false,
101 121
       isDeviceUp: false,
102 122
       isBorrowUp: false,
123
+      isSettleUp: false,
103 124
       thisYear: new Date().getFullYear(),
104 125
       year: {},
105 126
       type: {},
@@ -116,10 +137,15 @@ export default {
116 137
       borrowUsage: {},
117 138
       borrowUsageAmount: {},
118 139
       borrowYear: {},
140
+      settleAmount: {},
141
+      settleType: {},
142
+      settleTypeAmount: {},
143
+      settleYear: {},
119 144
       subYear: 0,
120 145
       contractSubYear: 0,
121 146
       deviceSubYear: 0,
122 147
       borrowSubYear: 0,
148
+      settleSubYear: 0,
123 149
       loading: true
124 150
     }
125 151
   },
@@ -133,9 +159,12 @@ export default {
133 159
     deviceYear() {
134 160
       this.initChartThree();
135 161
     },
136
-    borrowYear(){
162
+    borrowYear() {
137 163
       this.initChartFour();
138 164
     },
165
+    settleYear(){
166
+      this.initChartFive();
167
+    },
139 168
     pDatas: {
140 169
       handler(newVal) {
141 170
         if (newVal) {
@@ -172,6 +201,15 @@ export default {
172 201
       immediate: true,  // 在绑定时立即执行一次  
173 202
       deep: true       // 深度监听对象的变化  
174 203
     },
204
+    sDatas: {
205
+      handler(newVal) {
206
+        if (newVal) {
207
+          this.initDatas();
208
+        }
209
+      },
210
+      immediate: true,  // 在绑定时立即执行一次  
211
+      deep: true       // 深度监听对象的变化  
212
+    }
175 213
   },
176 214
   created() {
177 215
   },
@@ -207,6 +245,13 @@ export default {
207 245
         this.borrowYear = this.bDatas.year[0];
208 246
         this.getBorrowYearSub(this.borrowYear);
209 247
       }
248
+      if (Object.keys(this.sDatas).length !== 0) {
249
+        this.settleAmount = this.sDatas.amount[0];
250
+        this.settleType = this.sDatas.type[0];
251
+        this.settleTypeAmount = this.sDatas.typeAmount[0];
252
+        this.settleYear = this.sDatas.year[0];
253
+        this.getSettleYearSub(this.settleYear);
254
+      }
210 255
 
211 256
       this.loading = false
212 257
     },
@@ -375,6 +420,48 @@ export default {
375 420
       };
376 421
       ehcartsInit(borrowYearChart, 'thisBorrow', option);
377 422
     },
423
+    initChartFive() {
424
+      let option = {
425
+        grid: {
426
+          left: '1%',
427
+          right: '1%',
428
+          bottom: '0%',
429
+          height: '60%',
430
+          containLabel: true
431
+        },
432
+        tooltip: {
433
+          trigger: 'axis',
434
+          axisPointer: {
435
+            type: 'none',
436
+            label: {
437
+              backgroundColor: '#6a7985'
438
+            }
439
+          }
440
+        },
441
+        xAxis: {
442
+          type: 'category',
443
+          data: Object.keys(this.settleYear).slice(-6),
444
+          show: false
445
+        },
446
+        yAxis: {
447
+          type: 'value',
448
+          axisLabel: { show: false },
449
+          splitLine: { show: false }
450
+        },
451
+        series: [
452
+          {
453
+            min: 0,
454
+            data: Object.values(this.settleYear).slice(-6),
455
+            type: 'line',
456
+            smooth: true,
457
+            itemStyle: {
458
+              color: '#E74C3C'
459
+            }
460
+          }
461
+        ]
462
+      };
463
+      ehcartsInit(settleYearChart, 'thisSettle', option);
464
+    },
378 465
     getProjectYearSub(year) {
379 466
       let arr = Object.values(year).slice(-2);
380 467
       this.subYear = Number(arr[1]) - Number(arr[0]);
@@ -418,6 +505,17 @@ export default {
418 505
       } else {
419 506
         this.isBorrowUp = true
420 507
       }
508
+    },
509
+    getSettleYearSub(year) {
510
+      let arr = Object.values(year).slice(-2);
511
+      this.settleSubYear = Number(arr[1]) - Number(arr[0]);
512
+      this.settleNum = Number(arr[1])
513
+      if (this.settleSubYear < 0) {
514
+        this.settleSubYear = - this.settleSubYear;
515
+        this.isSettleUp = false
516
+      } else {
517
+        this.isSettleUp = true
518
+      }
421 519
     }
422 520
   },
423 521
 }
@@ -505,6 +603,10 @@ export default {
505 603
   background-color: #F6F6FF;
506 604
 }
507 605
 
606
+.five {
607
+  background-color: #FFF0F5;
608
+}
609
+
508 610
 .upColor {
509 611
   color: #F44C4C;
510 612
 }

+ 6
- 6
oa-ui/src/views/statistics/index.vue Voir le fichier

@@ -2,20 +2,21 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-10-11 09:23:15
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2024-10-23 15:12:55
5
+ * @LastEditTime: 2024-10-24 16:01:43
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container bg">
9 9
     <div class="head" v-loading="dataLoading">
10 10
       <top-head @handleClick="changeClick" :pDatas="projectInfo" :cDatas="contractInfo" :dDatas="deviceInfo"
11
-        :bDatas="borrowInfo"></top-head>
11
+        :bDatas="borrowInfo" :sDatas="settleInfo"></top-head>
12 12
     </div>
13 13
     <div class="content">
14 14
       <project-statistics v-if="isActive == 'project'" :datas="projectInfo"></project-statistics>
15 15
       <contract-statistics v-else-if="isActive == 'contract'" :datas="contractInfo"></contract-statistics>
16 16
       <car-device-statistics v-else-if="isActive == 'device'" :deviceData="deviceInfo"
17 17
         :carData="carInfo"></car-device-statistics>
18
-      <borrow-statistics v-else-if="isActive == 'borrow'" :borrowData="borrowInfo" :settleData="settleInfo"></borrow-statistics>
18
+      <borrow-statistics v-else-if="isActive == 'borrow'" :borrowData="borrowInfo"></borrow-statistics>
19
+      <settle-statistics v-else-if="isActive == 'settle'" :settleData="settleInfo"></settle-statistics>
19 20
     </div>
20 21
   </div>
21 22
 </template>
@@ -32,8 +33,9 @@ import contractStatistics from './components/contractStatistics.vue';
32 33
 import topHead from './components/topHead.vue';
33 34
 import CarDeviceStatistics from './components/carDeviceStatistics.vue';
34 35
 import BorrowStatistics from './components/borrowStatistics.vue';
36
+import SettleStatistics from './components/settleStatistics.vue';
35 37
 export default {
36
-  components: { topHead, ProjectStatistics, contractStatistics, CarDeviceStatistics, BorrowStatistics },
38
+  components: { topHead, ProjectStatistics, contractStatistics, CarDeviceStatistics, BorrowStatistics, SettleStatistics },
37 39
   data() {
38 40
     return {
39 41
       isActive: 'project',
@@ -88,9 +90,7 @@ export default {
88 90
     async getSettleInfo(){
89 91
       let res = await getSettleStatistic();
90 92
       this.settleInfo = res.data;
91
-      
92 93
     },
93
-    
94 94
     changeClick(val) {
95 95
       this.isActive = val
96 96
     }

Loading…
Annuler
Enregistrer