Pārlūkot izejas kodu

新增合同统计

余思翰 4 mēnešus atpakaļ
vecāks
revīzija
95650e9ea2

+ 6
- 15
oa-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/oa/CmcContractController.java Parādīt failu

@@ -159,30 +159,21 @@ public class CmcContractController extends BaseController
159 159
         JSONObject jsonObject = new JSONObject();
160 160
         List<CmcContract> cmcContractList = cmcContractService.selectCmcContractStatistic();
161 161
         JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(cmcContractList));
162
-        if (field.equals("")) {
162
+        if (field == null || field.equals("")) {
163 163
             jsonObject.put("sort", jsonArray);
164
-        }
165
-        if (field.equals("amount")) {
166
-            jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("amount").subtract(((JSONObject)a).getBigDecimal("amount")).intValue());
167
-            jsonObject.put("sort", jsonArray);
168
-        }
169
-        if (field.equals("amount")) {
164
+        }else if (field.equals("amount")) {
170 165
             jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("amount").subtract(((JSONObject)a).getBigDecimal("amount")).intValue());
171 166
             jsonObject.put("sort", jsonArray);
172
-        }
173
-        if (field.equals("subAmount")) {
167
+        }else if (field.equals("subAmount")) {
174 168
             jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("subAmount").subtract(((JSONObject)a).getBigDecimal("subAmount")).intValue());
175 169
             jsonObject.put("sort", jsonArray);
176
-        }
177
-        if (field.equals("budgetAmount")) {
170
+        }else if (field.equals("budgetAmount")) {
178 171
             jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("budgetAmount").subtract(((JSONObject)a).getBigDecimal("budgetAmount")).intValue());
179 172
             jsonObject.put("sort", jsonArray);
180
-        }
181
-        if (field.equals("borrowAmount")) {
173
+        }else if (field.equals("borrowAmount")) {
182 174
             jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("borrowAmount").subtract(((JSONObject)a).getBigDecimal("borrowAmount")).intValue());
183 175
             jsonObject.put("sort", jsonArray);
184
-        }
185
-        if (field.equals("settleAmount")) {
176
+        }else if (field.equals("settleAmount")) {
186 177
             jsonArray.sort((a,b)->((JSONObject)b).getBigDecimal("settleAmount").subtract(((JSONObject)a).getBigDecimal("settleAmount")).intValue());
187 178
             jsonObject.put("sort", jsonArray);
188 179
         }

+ 18
- 0
oa-back/ruoyi-system/src/main/java/com/ruoyi/oa/domain/CmcContract.java Parādīt failu

@@ -219,6 +219,15 @@ public class CmcContract extends BaseEntity
219 219
     {
220 220
         return projectSource;
221 221
     }
222
+    public void setProjectName(String projectName)
223
+    {
224
+        this.projectName = projectName;
225
+    }
226
+
227
+    public String getProjectName()
228
+    {
229
+        return projectName;
230
+    }
222 231
     public void setPartyAId(String partyAId)
223 232
     {
224 233
         this.partyAId = partyAId;
@@ -228,6 +237,15 @@ public class CmcContract extends BaseEntity
228 237
     {
229 238
         return partyAId;
230 239
     }
240
+    public void setPartyAName(String partyAName)
241
+    {
242
+        this.partyAName = partyAName;
243
+    }
244
+
245
+    public String getPartyAName()
246
+    {
247
+        return partyAName;
248
+    }
231 249
     public void setPartyA(CmcPartyA partyA)
232 250
     {
233 251
         this.partyA = partyA;

+ 2
- 0
oa-back/ruoyi-system/src/main/resources/mapper/oa/CmcContractMapper.xml Parādīt failu

@@ -105,6 +105,8 @@
105 105
             <if test="signScan != null  and signScan != ''"> and c.sign_scan = #{signScan}</if>
106 106
             <if test="commentType != null  and commentType != ''"> and c.comment_type = #{commentType}</if>
107 107
             <if test="projectSource != null  and projectSource != ''"> and p.project_source = #{projectSource}</if>
108
+            <if test="projectName != null  and projectName != ''"> and p.project_name like concat('%', #{projectName}, '%')</if>
109
+            <if test="partyAName != null  and partyAName != ''"> and pa.party_a_name like concat('%', #{partyAName}, '%')</if>
108 110
         </where>
109 111
         group by c.contract_id
110 112
         order by c.draft_time desc

+ 16
- 2
oa-ui/src/api/oa/contract/contract.js Parādīt failu

@@ -1,3 +1,9 @@
1
+/*
2
+ * @Author: ysh
3
+ * @Date: 2024-06-21 18:51:09
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-12-19 14:46:44
6
+ */
1 7
 import request from '@/utils/request'
2 8
 
3 9
 // 查询cmc合同评审列表
@@ -45,9 +51,17 @@ export function delContract(contractId) {
45 51
 
46 52
 
47 53
 // 合同统计
48
-export function getContractStatistic(query) {
54
+export function getContractStatistic(contractId) {
49 55
   return request({
50
-    url: '/oa/contract/statistic',
56
+    url: '/oa/contract/statistic/' + contractId,
57
+    method: 'get',
58
+  })
59
+}
60
+
61
+// 合同排序
62
+export function getContractStatisticSortByField(query) {
63
+  return request({
64
+    url: '/oa/contract/sort',
51 65
     method: 'get',
52 66
     params: query
53 67
   })

+ 1
- 0
oa-ui/src/assets/icons/svg/FilterSort.svg Parādīt failu

@@ -0,0 +1 @@
1
+<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M2.57 3h18.86l-6.93 9.817V21h-5v-8.183zm3.86 2l5.07 7.183V19h1v-6.817L17.57 5zm11.952 12.351L20 18.974l1.618-1.623l1.416 1.412L20 21.806l-3.034-3.042zm-.002-.714L20 15.015l1.619 1.622l1.415-1.414L20 12.185l-3.034 3.038z"/></svg>

+ 150
- 0
oa-ui/src/views/contractStatistic/components/borrowStatistic.vue Parādīt failu

@@ -0,0 +1,150 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-12-16 17:29:35
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-12-19 14:29:55
6
+-->
7
+<template>
8
+  <div>
9
+    <div class="text-center header">
10
+      <span>借款列表</span>
11
+    </div>
12
+    <div class="content">
13
+      <el-table v-loading="loading" :data="borrowList" height="350px">
14
+        <el-table-column label="序号" align="center" type="index" />
15
+        <el-table-column label="项目编号" align="center" prop="project.projectNumber" />
16
+        <el-table-column label="借款人" align="center" prop="applier">
17
+          <template slot-scope="scope">
18
+            {{ getUserName(scope.row.applier) }}
19
+          </template>
20
+        </el-table-column>
21
+        <el-table-column label="核准金额" align="center" prop="managerAmount" />
22
+        <el-table-column label="操作" align="center">
23
+          <template slot-scope="scope">
24
+            <el-button type="text" @click="rowClickFn(scope.row)">查看</el-button>
25
+          </template>
26
+        </el-table-column>
27
+      </el-table>
28
+      <div class="mt10 mr20 text-right footer">
29
+        <span class="mr20">共{{ total }}个借款申请</span>
30
+        <span>借款总额:{{ sumAmount.toFixed(2) }}</span>
31
+      </div>
32
+    </div>
33
+    <el-dialog title="借款明细" :visible.sync="infoOpen" width="50%" append-to-body>
34
+      <borrow-form :taskForm="taskForm" :taskName="''" :flowDisabled="false"></borrow-form>
35
+    </el-dialog>
36
+  </div>
37
+</template>
38
+
39
+<script>
40
+import { listBorrow, getBorrow, delBorrow, addBorrow, updateBorrow } from "@/api/oa/borrow/borrow";
41
+import borrowData from '../../flowable/form/inProgress/borrowData.vue';
42
+import BorrowForm from '../../flowable/form/finance/borrowForm.vue';
43
+export default {
44
+  components: { borrowData, BorrowForm },
45
+  props: {
46
+    projectId: {
47
+      type: Array,
48
+      default: []
49
+    },
50
+    contractId: {
51
+      type: String,
52
+      default: ''
53
+    }
54
+  },
55
+  data() {
56
+    return {
57
+      borrowList: [],
58
+      queryParams: {
59
+        pageNum: 1,
60
+        pageSize: 999,
61
+        projectId: null,
62
+      },
63
+      total: 0,
64
+      loading: true,
65
+      sumAmount: 0,
66
+      infoOpen: false,
67
+      taskForm: {
68
+        formId: '',
69
+        procDefName: '借款审批'
70
+      }
71
+    }
72
+  },
73
+  watch: {
74
+    projectId: {
75
+      handler(newVal) {
76
+        this.getList(newVal);
77
+      },
78
+      deep: true
79
+    },
80
+    contractId() {
81
+      if (this.projectId.length == 0) {
82
+        this.init();
83
+      }
84
+    },
85
+    sumAmount(val){
86
+      this.$emit('getSumAmount',val)
87
+    }
88
+  },
89
+  created() {
90
+    if (this.projectId.length == 0) {
91
+      this.init();
92
+    }
93
+  },
94
+  methods: {
95
+    async getList(projectId) {
96
+      this.loading = true
97
+      if (projectId.length != 0) {
98
+        this.borrowList = []
99
+        this.sumAmount = 0
100
+        this.total = 0
101
+        for (let id of projectId) {
102
+          let res = await listBorrow({ pageSize: 999, projectId: id })
103
+          if (res.total > 0) {
104
+            res.rows.map(item => this.borrowList.push(item));
105
+            this.total = this.total + res.total;
106
+          }
107
+        }
108
+        this.sumAmount = this.borrowList.reduce((sum, item) => sum + item.managerAmount, 0)
109
+      } else {
110
+        this.init();
111
+      }
112
+      this.loading = false
113
+    },
114
+    init() {
115
+      this.borrowList = []
116
+      this.total = 0
117
+      this.sumAmount = 0
118
+      this.loading = false
119
+    },
120
+    rowClickFn(row) {
121
+      console.log(row);
122
+
123
+      this.taskForm.formId = row.borrowId
124
+      this.infoOpen = true;
125
+    }
126
+  },
127
+}
128
+</script>
129
+
130
+<style lang="scss" scoped>
131
+.header {
132
+  font-family: 'puhuiti';
133
+  font-size: 18px;
134
+  line-height: 30px;
135
+  position: relative;
136
+
137
+  .info {
138
+    position: absolute;
139
+    right: 10px;
140
+    top: 0px;
141
+  }
142
+}
143
+
144
+.footer {
145
+  font-size: 14px;
146
+  font-family: 'puhuiti';
147
+}
148
+
149
+.content {}
150
+</style>

+ 117
- 0
oa-ui/src/views/contractStatistic/components/budgetStatistic.vue Parādīt failu

@@ -0,0 +1,117 @@
1
+<template>
2
+  <div>
3
+    <div class="text-center header">
4
+      预算列表
5
+    </div>
6
+    <el-table v-loading="loading" :data="budgetList" height="350px">
7
+      <el-table-column label="项目编号" align="center" prop="project.projectNumber" />
8
+      <el-table-column label="编制人" align="center" prop="compiler">
9
+        <template slot-scope="scope">
10
+          {{ getUserName(scope.row.compiler) }}
11
+        </template>
12
+      </el-table-column>
13
+      <el-table-column label="预算总额" align="center" prop="totalBudget" />
14
+    </el-table>
15
+    <div class="mt10 mr20 text-right footer">
16
+      <span class="mr20">共{{ total }}个预算申请</span>
17
+      <span>预算总额:{{ sumAmount.toFixed(2) }}</span>
18
+    </div>
19
+  </div>
20
+</template>
21
+
22
+<script>
23
+import { listBudget, getBudget, delBudget, addBudget, updateBudget } from "@/api/oa/budget/budget";
24
+export default {
25
+  props: {
26
+    projectId: {
27
+      type: Array,
28
+      default: []
29
+    },
30
+    contractId: {
31
+      type: String,
32
+      default: ''
33
+    }
34
+  },
35
+  watch: {
36
+    projectId: {
37
+      handler(newVal) {
38
+        this.getList(newVal)
39
+      },
40
+      deep: true
41
+    },
42
+    contractId() {
43
+      if (this.projectId.length == 0) {
44
+        this.budgetList = []
45
+        this.total = 0
46
+        this.sumAmount = 0
47
+        this.loading = false
48
+      }
49
+    },
50
+    sumAmount(val){
51
+      this.$emit('getSumAmount',val)
52
+    }
53
+  },
54
+  created() {
55
+    if (this.projectId.length == 0) {
56
+      this.budgetList = []
57
+      this.total = 0
58
+      this.sumAmount = 0
59
+      this.loading = false
60
+    }
61
+  },
62
+  data() {
63
+    return {
64
+      budgetList: [],
65
+      total: 0,
66
+      loading: true,
67
+      sumAmount: 0,
68
+    }
69
+  },
70
+  methods: {
71
+    async getList(projectId) {
72
+      this.loading = true
73
+      if (projectId.length != 0) {
74
+        this.budgetList = []
75
+        this.sumAmount = 0
76
+        this.total = 0
77
+        for (let id of projectId) {
78
+          let res = await listBudget({ pageSize: 99, projectId: id })
79
+          if (res.total > 0) {
80
+            res.rows.map(item => this.budgetList.push(item));
81
+            this.total = this.total + res.total;
82
+          } else {
83
+            this.budgetList = []
84
+            this.total = 0
85
+            this.sumAmount = 0
86
+          }
87
+        }
88
+        this.sumAmount = this.budgetList.reduce((sum, item) => sum + item.totalBudget, 0)
89
+      } else {
90
+        this.budgetList = []
91
+        this.total = 0
92
+        this.sumAmount = 0
93
+      }
94
+      this.loading = false
95
+    }
96
+  },
97
+}
98
+</script>
99
+
100
+<style lang="scss" scoped>
101
+.header {
102
+  font-family: 'puhuiti';
103
+  font-size: 18px;
104
+  line-height: 30px;
105
+  position: relative;
106
+  .info{
107
+    position: absolute;
108
+    right: 10px;
109
+    top: 0px;
110
+  }
111
+}
112
+
113
+.footer {
114
+  font-size: 14px;
115
+  font-family: 'puhuiti';
116
+}
117
+</style>

+ 104
- 0
oa-ui/src/views/contractStatistic/components/projectStatistic.vue Parādīt failu

@@ -0,0 +1,104 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-12-17 10:32:27
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-12-19 16:25:46
6
+-->
7
+<template>
8
+  <div>
9
+    <div class="text-center header">
10
+      项目列表
11
+    </div>
12
+    <el-table v-loading="loading" :data="projectList" height="220px">
13
+      <el-table-column type="index" width="50"></el-table-column>
14
+      <el-table-column label="项目编号" align="center" key="projectNumber" prop="projectNumber" />
15
+      <el-table-column label="项目名称" align="center" key="projectName" prop="projectName" show-overflow-tooltip />
16
+      <el-table-column label="承担部门" align="center" key="undertakingDeptName" prop="undertakingDeptName" />
17
+      <el-table-column label="项目负责人" align="center" key="projectLeaderName" prop="projectLeaderUser.nickName"
18
+        width="120px" />
19
+      <el-table-column label="操作" align="center">
20
+        <template slot-scope="scope">
21
+          <el-button type="text" @click="rowClickFn(scope.row)">查看</el-button>
22
+        </template>
23
+      </el-table-column>
24
+    </el-table>
25
+    <el-drawer :visible.sync="drawerOpen" title="" :size="'70%'" append-to-body @close="closeDrawerFn">
26
+      <projectInfo :needReturn="false"></projectInfo>
27
+    </el-drawer>
28
+  </div>
29
+</template>
30
+
31
+<script>
32
+import { listProject, getProject, listProjectFuzzy, submitProject, modifyProject, delProject } from "@/api/oa/project/project";
33
+import projectInfo from '@/views/oa/project/info'
34
+export default {
35
+  components:{projectInfo},
36
+  props: {
37
+    projectId: {
38
+      type: Array,
39
+    },
40
+    contractId: {
41
+      type: String,
42
+      default: ''
43
+    }
44
+  },
45
+  watch: {
46
+    projectId: {
47
+      handler(newVal) {
48
+        this.loading = true
49
+        this.projectList = []
50
+        for (let i of newVal) {
51
+          this.getList(i)
52
+        }
53
+        this.total = this.projectList.length;
54
+        this.loading = false
55
+      },
56
+      deep: true
57
+    },
58
+    contractId() {
59
+      if (this.projectId.length == 0) {
60
+        this.projectList = []
61
+        this.loading = false
62
+      }
63
+    }
64
+  },
65
+  created() {
66
+    if (this.projectId.length == 0) {
67
+      this.loading = false
68
+      this.projectList = []
69
+    }
70
+  },
71
+  data() {
72
+    return {
73
+      loading: true,
74
+      projectList: [],
75
+      total: 0,
76
+      drawerOpen: false,
77
+    }
78
+  },
79
+  methods: {
80
+    async getList(projectId) {
81
+      let res = await getProject(projectId)
82
+      if (res.data)
83
+        this.projectList.push(res.data)
84
+    },
85
+    rowClickFn(row) {
86
+      this.$router.replace({ query: { ...this.$route.query, projectId: row.projectId } });
87
+      this.drawerOpen = true;
88
+    },
89
+    closeDrawerFn(){
90
+      console.log(1);
91
+      
92
+      this.$router.replace({ path: '/statistics/contractStatistic' }); 
93
+    }
94
+  },
95
+}
96
+</script>
97
+
98
+<style lang="scss" scoped>
99
+.header {
100
+  font-family: 'puhuiti';
101
+  font-size: 18px;
102
+  line-height: 30px;
103
+}
104
+</style>

+ 148
- 0
oa-ui/src/views/contractStatistic/components/settleStatistic.vue Parādīt failu

@@ -0,0 +1,148 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-12-16 17:33:33
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-12-19 14:29:29
6
+-->
7
+<template>
8
+  <div>
9
+    <div class="text-center header">
10
+      结算列表
11
+    </div>
12
+    <el-table v-loading="loading" :data="settleList" height="350px">
13
+      <el-table-column type="index" label="序号" width="55" align="center" />
14
+      <el-table-column label="项目编号" align="center" prop="project.projectNumber" />
15
+      <el-table-column label="上报人" align="center" prop="reporter">
16
+        <template slot-scope="scope">
17
+          {{ getUserName(scope.row.reporter) }}
18
+        </template>
19
+      </el-table-column>
20
+      <el-table-column label="结算金额" align="center" prop="amount" />
21
+      <el-table-column label="操作" align="center">
22
+        <template slot-scope="scope">
23
+          <el-button type="text" @click="rowClickFn(scope.row)">查看</el-button>
24
+        </template>
25
+      </el-table-column>
26
+    </el-table>
27
+    <div class="mt10 mr20 text-right footer">
28
+      <span class="mr20">共{{ total }}个结算申请</span>
29
+      <span>结算总额:{{ sumAmount.toFixed(2) }}</span>
30
+    </div>
31
+    <el-dialog title="结算明细" :visible.sync="infoOpen" width="70%" append-to-body>
32
+      <settle-form :taskForm="taskForm" :taskName="''" :flowDisabled="false" :disabled="true"></settle-form>
33
+    </el-dialog>
34
+  </div>
35
+</template>
36
+
37
+<script>
38
+import { listSettle, getSettle, delSettle, addSettle, updateSettle } from "@/api/oa/settle/settle";
39
+import { listSettleSummary, getSettleSummary, delSettleSummary, addSettleSummary, updateSettleSummary } from "@/api/oa/settle/settleSummary";
40
+import settleForm from '../../flowable/form/settleForm.vue';
41
+export default {
42
+  components: { settleForm },
43
+  props: {
44
+    projectId: {
45
+      type: Array,
46
+      default: []
47
+    },
48
+    contractId: {
49
+      type: String,
50
+      default: ''
51
+    }
52
+  },
53
+  watch: {
54
+    projectId: {
55
+      handler(newVal) {
56
+        this.getList(newVal)
57
+        if (this.projectId.length == 0) {
58
+          this.settleList = []
59
+          this.total = 0
60
+          this.sumAmount = 0
61
+          this.loading = false
62
+        }
63
+      },
64
+      deep: true
65
+    },
66
+    contractId() {
67
+      if (this.projectId.length == 0) {
68
+        this.settleList = []
69
+        this.total = 0
70
+        this.sumAmount = 0
71
+        this.loading = false
72
+      }
73
+    },
74
+    sumAmount(val) {
75
+      this.$emit('getSumAmount', val)
76
+    }
77
+  },
78
+  created() {
79
+    if (this.projectId.length == 0) {
80
+      this.settleList = []
81
+      this.total = 0
82
+      this.sumAmount = 0
83
+      this.loading = false
84
+    }
85
+  },
86
+  data() {
87
+    return {
88
+      settleList: [],
89
+      total: 0,
90
+      loading: true,
91
+      sumAmount: 0,
92
+      infoOpen: false,
93
+      taskForm: {
94
+        formId: ''
95
+      }
96
+    }
97
+  },
98
+  methods: {
99
+    async getList(projectId) {
100
+      this.loading = true
101
+      if (projectId.length != 0) {
102
+        this.settleList = []
103
+        this.sumAmount = 0
104
+        this.total = 0
105
+        for (let id of projectId) {
106
+          let res = await listSettle({ pageSize: 999, projectId: id });
107
+          if (res.total > 0) {
108
+            res.rows.map(item => this.settleList.push(item));
109
+            this.total = this.total + res.total;
110
+          }
111
+        }
112
+        for (let settle of this.settleList) {
113
+          let resData = await listSettleSummary({ pageSize: 999, settleId: settle.settleId, content: '实际结算总金额' });
114
+          if (resData.total > 0) {
115
+            this.$set(settle, 'amount', resData.rows[0].amount)
116
+          }
117
+        }
118
+        this.sumAmount = this.settleList.reduce((sum, item) => sum + item.amount, 0)
119
+      }
120
+      this.loading = false
121
+    },
122
+    rowClickFn(row) {
123
+      this.taskForm.formId = row.settleId;
124
+      this.infoOpen = true;
125
+    }
126
+  },
127
+}
128
+</script>
129
+
130
+<style lang="scss" scoped>
131
+.header {
132
+  font-family: 'puhuiti';
133
+  font-size: 18px;
134
+  line-height: 30px;
135
+  position: relative;
136
+
137
+  .info {
138
+    position: absolute;
139
+    right: 10px;
140
+    top: 0px;
141
+  }
142
+}
143
+
144
+.footer {
145
+  font-size: 14px;
146
+  font-family: 'puhuiti';
147
+}
148
+</style>

+ 83
- 0
oa-ui/src/views/contractStatistic/components/subStatistic.vue Parādīt failu

@@ -0,0 +1,83 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-12-16 10:42:55
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-12-18 15:38:24
6
+-->
7
+<template>
8
+  <div>
9
+    <div class="text-center header">分包合同列表</div>
10
+    <el-table :data="subContractList" v-loading="loading" :height="220">
11
+      <el-table-column label="序号" type="index"></el-table-column>
12
+      <el-table-column label="分包合同名称" prop="subContractName"></el-table-column>
13
+      <el-table-column label="承接单位" align="center" prop="partner.partnerName" />
14
+      <el-table-column label="分包合同金额" align="center" prop="subAmount" />
15
+    </el-table>
16
+    <div class="mt10 mr20 text-right footer">
17
+      <span class="mr20">共{{ total }}个分包合同</span>
18
+      <span>分包合同额合计:{{ subAmount }}</span>
19
+    </div>
20
+  </div>
21
+</template>
22
+
23
+<script>
24
+import { listSubContract, getSubContract, delSubContract, addSubContract, updateSubContract } from "@/api/oa/contract/subContract";
25
+import { listContractSubcontract, delContractSubcontract, addContractSubcontract } from "@/api/oa/contract/contractSubcontract"
26
+export default {
27
+  props: {
28
+    contract: {
29
+      type: Object,
30
+      default: {}
31
+    }
32
+  },
33
+  data() {
34
+    return {
35
+      subContractList: [],
36
+      loading: true,
37
+      total: 0,
38
+      subAmount:0
39
+    }
40
+  },
41
+  watch: {
42
+    contract: {
43
+      handler() {
44
+        this.getList()
45
+      },
46
+      deep: true
47
+    },
48
+    subAmount(val){
49
+      this.$emit('getSumAmount',val)
50
+    }
51
+  },
52
+  mounted() {
53
+  },
54
+  methods: {
55
+    getList() {
56
+      this.subContractList = []
57
+      this.loading = true;
58
+      listContractSubcontract({ pageNum: 1, pageSize: 999, contractId: this.contract.contractId }).then(async res => {
59
+        let subContractIds = res.rows.map(item => item.subContractId)
60
+        for (let id of subContractIds) {
61
+          let resData = await getSubContract(id);
62
+          this.subContractList.push(resData.data);
63
+        }
64
+        this.subAmount = this.subContractList.reduce((sum,item)=>sum + item.subAmount,0)
65
+        this.total = this.subContractList.length;
66
+        this.loading = false;
67
+      })
68
+    }
69
+  },
70
+}
71
+</script>
72
+
73
+<style lang="scss" scoped>
74
+.header {
75
+  font-family: 'puhuiti';
76
+  font-size: 18px;
77
+  line-height: 30px;
78
+}
79
+.footer{
80
+  font-size: 14px;
81
+  font-family: 'puhuiti';
82
+}
83
+</style>

+ 378
- 0
oa-ui/src/views/contractStatistic/index.vue Parādīt failu

@@ -0,0 +1,378 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-12-16 10:25:17
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-12-19 16:16:51
6
+-->
7
+<template>
8
+  <div class="app-container">
9
+    <el-row :gutter="10">
10
+      <!-- 承接合同 -->
11
+      <el-col :span="6" class="border">
12
+        <div class="text-center header">承接合同列表
13
+          <div class="sort-btn">
14
+            <el-dropdown trigger="click" @command="handleCommand">
15
+              <span style="color:#000;font-size:20px;">
16
+                <svg-icon icon-class="FilterSort"></svg-icon>
17
+              </span>
18
+              <el-dropdown-menu slot="dropdown">
19
+                <el-dropdown-item command="">按拟稿日期</el-dropdown-item>
20
+                <el-dropdown-item command="amount">按主合同额</el-dropdown-item>
21
+                <el-dropdown-item command="subAmount">按分包合同额</el-dropdown-item>
22
+                <el-dropdown-item command="borrowAmount">按借款额</el-dropdown-item>
23
+                <el-dropdown-item command="settleAmount">按结算额</el-dropdown-item>
24
+                <el-dropdown-item command="budgetAmount">按预算额</el-dropdown-item>
25
+              </el-dropdown-menu>
26
+            </el-dropdown>
27
+
28
+          </div>
29
+        </div>
30
+        <div class="query-box">
31
+          <el-input placeholder="请输入内容" v-model="queryInput" clearable class="input-with-select"
32
+            @keyup.enter.native="queryContract()">
33
+            <el-select v-model="queryParams.type" slot="prepend" placeholder="请选择" @change="initType()">
34
+              <el-option label="合同名称" value="contractName"></el-option>
35
+              <el-option label="甲方单位" value="partyAName"></el-option>
36
+              <el-option label="合同编码" value="contractCode"></el-option>
37
+              <el-option label="项目名称" value="projectName"></el-option>
38
+            </el-select>
39
+            <el-button slot="append" icon="el-icon-search" @click="queryContract()"></el-button>
40
+          </el-input>
41
+        </div>
42
+        <el-scrollbar view-style="overflow-x:hidden;" :style="{ height: contractHeight + 'px' }">
43
+          <div v-loading="loading">
44
+            <div class="flex align-center box-item">
45
+              <div class="name">
46
+                <span><b><i class="el-icon-star-on"></i>合同名称</b> ({{ total }})</span>
47
+              </div>
48
+              <div>
49
+                <div class="text-center"><b>{{ sortByField() }}</b></div>
50
+              </div>
51
+              <div class="text-right pl-5"><i class="el-icon-star-on"></i></div>
52
+            </div>
53
+            <div class="flex align-center box-item" :class="{ isActive: item.contractId == contract.contractId }"
54
+              v-for="item in contractList" :key="item.contractId" @click="handleClickContract(item)">
55
+              <div class="name">
56
+                <span>{{ item.contractName }}</span>
57
+              </div>
58
+              <div>
59
+                <el-tag>{{ setAmountByFieId(item).toFixed(2) }}</el-tag>
60
+              </div>
61
+              <div class="text-right pl-5"><i class="el-icon-d-arrow-right"></i></div>
62
+            </div>
63
+          </div>
64
+        </el-scrollbar>
65
+        <div class="text-right pagination">
66
+          <el-pagination small layout="sizes,prev, pager, next" :total="total" :current-page.sync="queryParams.pageNum"
67
+            :page-sizes="[10, 20, 30, 40]" :page-size="queryParams.pageSize" @size-change="handleSizeChange"
68
+            @current-change="changePage()"></el-pagination>
69
+        </div>
70
+      </el-col>
71
+      <el-col :span="18">
72
+        <el-breadcrumb class="pl-5" separator-class="el-icon-arrow-right">
73
+          <el-breadcrumb-item>当前选择合同</el-breadcrumb-item>
74
+          <el-breadcrumb-item>{{ contract.contractName }}</el-breadcrumb-item>
75
+        </el-breadcrumb>
76
+        <div class="pl-5 contract-info">
77
+          <span class="info-title">甲方单位:</span><span class="mr20">{{ contract.partyA ? contract.partyA.partyAName : ''
78
+            }}</span>
79
+          <span class="info-title">合同编码:</span><span class="mr20">{{ contract.contractCode }}</span>
80
+          <span class="info-title">合同额:</span><span class="mr20">{{ contract.amount }}</span>
81
+        </div>
82
+        <el-row :gutter="20">
83
+          <el-col :span="12" class="border">
84
+            <project-statistic :projectId="projectIds" :contractId="contract.contractId"></project-statistic>
85
+          </el-col>
86
+          <el-col :span="12">
87
+            <!-- 分包合同 -->
88
+            <sub-statistic :contract="contract"></sub-statistic>
89
+          </el-col>
90
+        </el-row>
91
+        <el-divider></el-divider>
92
+        <el-row :gutter="10">
93
+          <el-col :span="7" class="border">
94
+            <borrow-statistic :projectId="projectIds" :contractId="contract.contractId"></borrow-statistic>
95
+          </el-col>
96
+          <el-col :span="7" class="border">
97
+            <settle-statistic :projectId="projectIds" :contractId="contract.contractId"></settle-statistic>
98
+          </el-col>
99
+          <el-col :span="7" class="border">
100
+            <budget-statistic :projectId="projectIds" :contractId="contract.contractId"></budget-statistic>
101
+          </el-col>
102
+          <el-col :span="3">
103
+            <div class="text-center header">统计</div>
104
+            <div class="pr-5 pl-5">
105
+              <div class="title">主合同额</div>
106
+              <div class="amount text-right">{{ contract.amount ? contract.amount.toFixed(2) : '0.00' }}</div>
107
+              <div class="title">分包合同额</div>
108
+              <div class="amount text-right">{{ subContractAmount.toFixed(2) }}</div>
109
+              <div class="title">合同额差值</div>
110
+              <div class="amount text-right border-bottom">{{ (contract.amount - subContractAmount).toFixed(2) }}</div>
111
+              <!-- <el-divider></el-divider> -->
112
+              <div class="title">借款总额</div>
113
+              <div class="amount text-right">{{ borrowSumAmount.toFixed(2) }}</div>
114
+              <div class="title">结算总额</div>
115
+              <div class="amount text-right border-bottom">{{ settleSumAmount.toFixed(2) }}</div>
116
+              <div class="title">合同额与结算差值</div>
117
+              <div class="amount text-right">{{ ((contract.amount - subContractAmount) - settleSumAmount).toFixed(2) }}
118
+              </div>
119
+            </div>
120
+          </el-col>
121
+        </el-row>
122
+      </el-col>
123
+    </el-row>
124
+  </div>
125
+</template>
126
+<script>
127
+import { listContract, getContractStatisticSortByField, getContractStatistic } from "@/api/oa/contract/contract";
128
+import { listProjectContract } from "@/api/oa/contract/projectContract";
129
+import SubStatistic from './components/subStatistic.vue';
130
+import BorrowStatistic from "./components/borrowStatistic.vue";
131
+import BudgetStatistic from './components/budgetStatistic.vue';
132
+import SettleStatistic from './components/settleStatistic.vue';
133
+import ProjectStatistic from './components/projectStatistic.vue';
134
+export default {
135
+  components: { SubStatistic, BorrowStatistic, BudgetStatistic, SettleStatistic, ProjectStatistic },
136
+  data() {
137
+    return {
138
+      contractList: [],
139
+      queryInput: '',
140
+      queryParams: {
141
+        pageNum: 1,
142
+        pageSize: 20,
143
+        contractName: '',
144
+        partyAName: '',
145
+        contractCode: '',
146
+        projectName: '',
147
+        type: 'contractName'
148
+      },
149
+      total: 0,
150
+      loading: true,
151
+      contractHeight: 675,
152
+      contract: {},
153
+      projectIds: [],
154
+      subContractAmount: 0,
155
+      borrowSumAmount: 0,
156
+      settleSumAmount: 0,
157
+      budgetSumAmount: 0,
158
+      status: 'normal',
159
+      field: '',
160
+    }
161
+  },
162
+  created() {
163
+    this.getContractList();
164
+  },
165
+  mounted() {
166
+    this.initHeight();// 添加事件监听器,以便在窗口大小改变时更新高度
167
+  },
168
+  methods: {
169
+    initHeight() {
170
+      this.contractHeight = window.innerHeight - 250;
171
+    },
172
+    getContractList() {
173
+      this.loading = true;
174
+      this.status = 'normal'
175
+      listContract(this.queryParams).then(res => {
176
+        this.contractList = res.rows;
177
+        this.total = res.total;
178
+        this.loading = false;
179
+        if (res.total != 0) {
180
+          this.contract = this.contractList[0];
181
+          this.getContractProject(this.contract.contractId);
182
+        }
183
+      })
184
+    },
185
+    handleCommand(command) {
186
+      this.sortFn(command)
187
+    },
188
+    sortFn(field) {
189
+      this.loading = true
190
+      this.status = 'sort'
191
+      this.field = field
192
+      getContractStatisticSortByField({ field }).then(res => {
193
+        let list = res.data.sort;
194
+        let a = list.slice((this.queryParams.pageNum - 1) * this.queryParams.pageSize, this.queryParams.pageNum * this.queryParams.pageSize);
195
+        this.contractList = a;
196
+        this.loading = false;
197
+      })
198
+    },
199
+    sortByField() {
200
+      switch (this.field) {
201
+        case '':
202
+          return '合同金额'
203
+        case 'amount':
204
+          return '合同金额'
205
+        case 'subAmount':
206
+          return '分包合同金额'
207
+        case 'budgetAmount':
208
+          return '预算金额'
209
+        case 'borrowAmount':
210
+          return '借款金额'
211
+        case 'settleAmount':
212
+          return '结算金额'
213
+        default:
214
+          break;
215
+      }
216
+    },
217
+    setAmountByFieId(item) {
218
+      switch (this.field) {
219
+        case '':
220
+          return item.amount
221
+        case 'amount':
222
+          return item.amount
223
+        case 'subAmount':
224
+          return item.subAmount ? item.subAmount : 0
225
+        case 'budgetAmount':
226
+          return item.budgetAmount
227
+        case 'borrowAmount':
228
+          return item.borrowAmount
229
+        case 'settleAmount':
230
+          return item.settleAmount
231
+        default:
232
+          break;
233
+      }
234
+    },
235
+    changePage() {
236
+      if (this.status == 'normal') {
237
+        this.getContractList();
238
+      } else {
239
+        this.sortFn(this.field);
240
+      }
241
+    },
242
+    getStatistic(contractId) {
243
+      getContractStatistic(contractId).then(res => {
244
+        console.log(res);
245
+        this.subContractAmount = res.data.subAmount
246
+        this.budgetSumAmount = res.data.budgetAmount
247
+        this.borrowSumAmount = res.data.borrowAmount
248
+        this.settleSumAmount = res.data.settleAmount
249
+      })
250
+    },
251
+    async getContractProject(contractId) {
252
+      let res = await listProjectContract({ contractId })
253
+      if (res.total > 0) {
254
+        this.projectIds = res.rows.map(item => item.projectId)
255
+      } else {
256
+        this.projectIds = []
257
+
258
+      }
259
+    },
260
+    handleSizeChange(val) {
261
+      this.queryParams.pageSize = val
262
+      this.getContractList();
263
+    },
264
+    queryContract() {
265
+      const type = this.queryParams.type
266
+      this.field = ''
267
+      this.queryParams[type] = this.queryInput;
268
+      this.getContractList();
269
+    },
270
+    initType() {
271
+      this.queryParams.contractName = '';
272
+      this.queryParams.partyAName = '';
273
+      this.queryParams.contractCode = '';
274
+      this.queryParams.projectName = '';
275
+    },
276
+    async handleClickContract(val) {
277
+      this.contract = val;
278
+      await this.getContractProject(val.contractId);
279
+      this.getStatistic(val.contractId);
280
+      this.subContractAmount = 0
281
+      this.borrowSumAmount = 0
282
+      this.settleSumAmount = 0
283
+      this.budgetSumAmount = 0
284
+    },
285
+    // getSubContractAmount(amount) {
286
+    //   this.subContractAmount = amount
287
+    // },
288
+    // getBorrowSumAmount(amount) {
289
+    //   this.borrowSumAmount = amount
290
+    // },
291
+    // getSettleSumAmount(amount) {
292
+    //   this.settleSumAmount = amount
293
+    // },
294
+    // getBudgetSumAmount(amount) {
295
+    //   this.budgetSumAmount = amount
296
+    // },
297
+  }
298
+}
299
+</script>
300
+
301
+<style lang="scss" scoped>
302
+.header {
303
+  font-family: 'puhuiti';
304
+  font-size: 18px;
305
+  line-height: 30px;
306
+  position: relative;
307
+
308
+  .sort-btn {
309
+    cursor: pointer;
310
+    position: absolute;
311
+    right: 0;
312
+    top: 0;
313
+  }
314
+}
315
+
316
+.border {
317
+  border-right: 1px solid #ebeef5;
318
+}
319
+
320
+.border-bottom {
321
+  padding: 5px 0;
322
+  border-bottom: 1px solid #ebeef5;
323
+}
324
+
325
+.box-item {
326
+  cursor: pointer;
327
+  font-size: 14px;
328
+  margin: 10px 0;
329
+  border-top: 1px solid #ebeef5;
330
+  padding: 5px;
331
+}
332
+
333
+.name {
334
+  flex: 2;
335
+}
336
+
337
+.box-item:hover {
338
+  color: var(--current-color);
339
+}
340
+
341
+.isActive {
342
+  color: var(--current-color);
343
+}
344
+
345
+.pagination {
346
+  border-top: 1px solid #ebeef5;
347
+  padding: 20px 0 0;
348
+}
349
+
350
+.contract-info {
351
+  font-size: 14px;
352
+  color: #606266;
353
+
354
+  .info-title {
355
+    font-weight: bold;
356
+    font-family: 'puhuiti';
357
+  }
358
+}
359
+
360
+::v-deep.el-select .el-input {
361
+  width: 110px;
362
+}
363
+
364
+.title {
365
+  font-family: '微软雅黑';
366
+  color: #606266;
367
+  line-height: 30px;
368
+}
369
+
370
+.amount {
371
+  font-family: 'puhuiti';
372
+}
373
+</style>
374
+<style>
375
+.el-scrollbar__wrap {
376
+  overflow-x: hidden;
377
+}
378
+</style>

+ 6
- 0
oa-ui/src/views/flowable/form/components/print/settlePrint.vue Parādīt failu

@@ -95,6 +95,12 @@
95 95
           <td :colspan="2" style="text-align:left;min-width:120px;">签名:<span class="auditor">{{ getUserName(form.zhUserId) }}</span></td>
96 96
           <td :colspan="2" style="text-align:left;width:120px;">日期:{{ form.zhTime }}</td>
97 97
         </tr>
98
+        <tr>
99
+          <td :colspan="2" class="fontbold">综合事务部(车辆排班情况)</td>
100
+          <td :colspan="4" class="conment-width">{{ form.jsbComment }}</td>
101
+          <td :colspan="2" style="text-align:left;min-width:120px;">签名:<span class="auditor">{{ getUserName(form.jsbUserId) }}</span></td>
102
+          <td :colspan="2" style="text-align:left;width:120px;">日期:{{ form.jsbTime }}</td>
103
+        </tr>
98 104
         <tr>
99 105
           <td :colspan="2" class="fontbold">技术质量与安全部(质量及工作量)</td>
100 106
           <td :colspan="4" class="conment-width">{{ form.jsComment }}</td>

+ 44
- 15
oa-ui/src/views/flowable/form/settleForm.vue Parādīt failu

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-04-30 09:03:14
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2024-12-10 13:45:36
5
+ * @LastEditTime: 2024-12-19 15:25:32
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container" v-loading="loading">
@@ -165,16 +165,16 @@
165 165
           <el-form-item label-width="60px">
166 166
             <table border="1">
167 167
               <tr>
168
-                <td style="width: 50px">序号</td>
169
-                <td style="width: 180px">工作内容</td>
170
-                <td style="width: 100px">等级或比例尺</td>
171
-                <td style="width: 100px">单位</td>
172
-                <td style="width: 100px">地类</td>
173
-                <td style="width: 100px">单价</td>
168
+                <td style="width:50px;">序号</td>
169
+                <td style="min-width:140px">工作内容</td>
170
+                <td style="min-width:80px">等级或比例尺</td>
171
+                <td style="min-width:80px">单位</td>
172
+                <td style="min-width:80px">地类</td>
173
+                <td style="min-width:80px">单价</td>
174 174
                 <td>工作量</td>
175
-                <td style="width: 117px">其他系数</td>
176
-                <td style="width: 100px">项目经费</td>
177
-                <td>备注</td>
175
+                <td style="min-width:80px">其他系数</td>
176
+                <td style="min-width:80px">项目经费</td>
177
+                <td style="min-width:200px;">备注</td>
178 178
                 <td>操作</td>
179 179
               </tr>
180 180
               <tr v-for="(work, index) in settleWorkList" :key="index">
@@ -367,6 +367,23 @@
367 367
                 </el-form-item>
368 368
               </el-col>
369 369
             </el-row>
370
+            <el-form-item label="综合事务部(车辆排班情况)">
371
+              <el-input v-model="form.jsbComment" type="textarea" :disabled="taskName != '综合事务部驾驶班处理'" clearable
372
+                :autosize="{ minRows: 4, maxRows: 10 }">
373
+              </el-input>
374
+            </el-form-item>
375
+            <el-row>
376
+              <el-col :span="6" :xs="24" :offset="12">
377
+                <el-form-item label="签名:" label-width="120px">
378
+                  <span class="auditor"> {{ form.jsbUserName ? form.jsbUserName : getUserName(form.jsbUserId) }} </span>
379
+                </el-form-item>
380
+              </el-col>
381
+              <el-col :span="6">
382
+                <el-form-item label="日期:" label-width="120px">
383
+                  <span> {{ form.jsbTime }} </span>
384
+                </el-form-item>
385
+              </el-col>
386
+            </el-row>
370 387
             <el-form-item label="技术质量与安全部(质量及工作量)">
371 388
               <el-input v-model="form.jsComment" type="textarea" :disabled="taskName != '技术质量与安全部审核'" clearable
372 389
                 :autosize="{ minRows: 4, maxRows: 10 }">
@@ -460,7 +477,9 @@
460 477
         <el-button type="success" icon="el-icon-printer" @click="printOpen = true">打印</el-button>
461 478
         <div style="text-align: center" v-if="!disabled">
462 479
           <el-button type="warning" @click="preserve">保存</el-button>
463
-          <el-button type="danger" v-if="taskName == '经营发展部校核' || taskName == '分管审核' || taskName == '总经理审批' || taskName == '董事长批准'" @click="returnOpen = true">退 回</el-button>
480
+          <el-button type="danger"
481
+            v-if="taskName == '经营发展部校核' || taskName == '分管审核' || taskName == '总经理审批' || taskName == '董事长批准'"
482
+            @click="returnOpen = true">退 回</el-button>
464 483
           <el-button type="primary" @click="submitNextFlow" v-if="taskName != '董事长批准'">提交下一个流程</el-button>
465 484
           <el-button type="primary" @click="submitNextFlow" v-else>结算批准</el-button>
466 485
         </div>
@@ -777,7 +796,13 @@ export default {
777 796
         this.form.zhUserName = this.$store.state.user.name;
778 797
         this.form.zhUserId = this.$store.state.user.id;
779 798
         this.form.zhTime = parseTime(new Date(), "{y}-{m}-{d}");
780
-      } else if (this.taskName == "技术质量与安全部审核") {
799
+      }
800
+      else if (this.taskName == "综合事务部驾驶班处理") {
801
+        this.form.jsbUserName = this.$store.state.user.name;
802
+        this.form.jsbUserId = this.$store.state.user.id;
803
+        this.form.jsbTime = parseTime(new Date(), "{y}-{m}-{d}");
804
+      }
805
+      else if (this.taskName == "技术质量与安全部审核") {
781 806
         this.form.jsUserName = this.$store.state.user.name;
782 807
         this.form.jsUserId = this.$store.state.user.id;
783 808
         this.form.jsTime = parseTime(new Date(), "{y}-{m}-{d}");
@@ -831,8 +856,13 @@ export default {
831 856
               });
832 857
             })
833 858
           } else if (this.taskName == "综合事务部处理") {
859
+            getUserByRole({ roleId: 5 }).then((res) => {
860
+              this.getNextFlowNodeFn(res.data[1]);
861
+            });
862
+          } else if (this.taskName == "综合事务部驾驶班处理") {
834 863
             this.getNextFlowNodeFn(null, 109, false);
835
-          } else if (this.taskName == "技术质量与安全部审核") {
864
+          }
865
+          else if (this.taskName == "技术质量与安全部审核") {
836 866
             this.getNextFlowNodeFn(null, 105, true);
837 867
           } else if (this.taskName == "经营发展部校核") {
838 868
             this.getNextFlowNodeFn(null, this.deptId, true);
@@ -953,7 +983,6 @@ export default {
953 983
       });
954 984
     },
955 985
     deletWorkItem(index, arr) {
956
-      // let arr = this.settleWorkList;
957 986
       if (arr.length == 1) {
958 987
         return;
959 988
       }
@@ -965,7 +994,7 @@ export default {
965 994
     },
966 995
     calculateSettle(work) {
967 996
       let sum = work.workload * work.coefficient * work.price;
968
-      if (sum < 600 && sum != 0) {
997
+      if (sum < 600 && sum != 0 && work.priceId != 147) {
969 998
         this.$message.warning('不足600,按600算')
970 999
         work.remark = '不足600,按600算'
971 1000
         sum = 600

Notiek ielāde…
Atcelt
Saglabāt