ソースを参照

承接合同和分包合同新增开票进度和收票进度;

合同导出可选择字段名动态输出
余思翰 1ヶ月前
コミット
d8fe53a5ec

+ 1
- 1
oa-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/oa/CmcContractController.java ファイルの表示

286
                 paidPercentage = "0%";
286
                 paidPercentage = "0%";
287
             }
287
             }
288
             else {
288
             else {
289
-                paidPercentage = paidAmount.divide(contract.getAmount().multiply(new BigDecimal(100))).setScale(2, RoundingMode.HALF_UP) + "%";
289
+                paidPercentage = paidAmount.divide(contract.getAmount(), RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP) + "%";
290
             }
290
             }
291
             contract.setPaidAmount(paidAmount);
291
             contract.setPaidAmount(paidAmount);
292
             contract.setPaidPercentage(paidPercentage);
292
             contract.setPaidPercentage(paidPercentage);

+ 50
- 0
oa-ui/src/api/oa/contract/contractInvoice.js ファイルの表示

1
+/*
2
+ * @Author: ysh
3
+ * @Date: 2025-02-12 10:55:08
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-07-23 16:46:53
6
+ */
7
+import request from '@/utils/request'
8
+
9
+// 查询开票列表
10
+export function listContractInvoice(query) {
11
+  return request({
12
+    url: '/oa/contractInvoice/list',
13
+    method: 'get',
14
+    params: query
15
+  })
16
+}
17
+
18
+// 查询开票详细
19
+export function getContractInvoice(invoiceId) {
20
+  return request({
21
+    url: '/oa/contractInvoice/' + invoiceId,
22
+    method: 'get'
23
+  })
24
+}
25
+
26
+// 新增开票记录
27
+export function addContractInvoice(data) {
28
+  return request({
29
+    url: '/oa/contractInvoice',
30
+    method: 'post',
31
+    data: data
32
+  })
33
+}
34
+
35
+// 修改开票记录
36
+export function updateContractInvoice(data) {
37
+  return request({
38
+    url: '/oa/contractInvoice',
39
+    method: 'put',
40
+    data: data
41
+  })
42
+}
43
+
44
+// 删除开票记录
45
+export function delContractInvoice(contractId) {
46
+  return request({
47
+    url: '/oa/contractInvoice/' + contractId,
48
+    method: 'delete'
49
+  })
50
+}

+ 119
- 18
oa-ui/src/views/oa/contract/components/paymentProgress.vue ファイルの表示

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2025-02-12 13:40:48
3
  * @Date: 2025-02-12 13:40:48
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-02-14 15:32:51
5
+ * @LastEditTime: 2025-07-23 16:51:15
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div>
8
   <div>
9
-    <el-form ref="form" :model="form" label-width="130px" :disabled="isDisabled">
9
+    <el-form ref="form" :model="form" label-width="130px">
10
       <el-form-item label="合同名称" prop="contractName">
10
       <el-form-item label="合同名称" prop="contractName">
11
         <el-input style="width: 100%;" disabled v-model="form.contractName" placeholder="请输入合同名称"></el-input>
11
         <el-input style="width: 100%;" disabled v-model="form.contractName" placeholder="请输入合同名称"></el-input>
12
       </el-form-item>
12
       </el-form-item>
35
       <el-form-item label="合同备注" prop="remark">
35
       <el-form-item label="合同备注" prop="remark">
36
         <el-input type="textarea" disabled v-model="form.remark" :autosize="{ minRows: 4 }" />
36
         <el-input type="textarea" disabled v-model="form.remark" :autosize="{ minRows: 4 }" />
37
       </el-form-item>
37
       </el-form-item>
38
+      <el-form-item style="text-align: left;" label="开票进度">
39
+        <table border="1" style="width:100%" v-loading="loading">
40
+          <tr>
41
+            <td style="width: 50px;">序号</td>
42
+            <td>开票金额</td>
43
+            <td>开票比例(%)</td>
44
+            <td>开票时间</td>
45
+            <td style="width: 150px;">备注</td>
46
+          </tr>
47
+          <tr v-for="(invoice, index) in invoiceList" :key="index">
48
+            <td>
49
+              {{ index + 1 }}
50
+            </td>
51
+            <td>
52
+              <el-input-number style="width:100%" :controls="false" v-model="invoice.invoiceAmount" clearable
53
+                @blur="changeInvoiceAmount(invoice)"
54
+                :disabled="!$store.getters.roles.includes('business')"></el-input-number>
55
+            </td>
56
+            <td>
57
+              {{ invoice.invoicePercentage }}
58
+            </td>
59
+            <td>
60
+              <el-date-picker style="width:100%" v-model="invoice.invoiceTime" value-format="yyyy-MM-dd" type="date"
61
+                placeholder="选择日期" :disabled="!$store.getters.roles.includes('business')">
62
+              </el-date-picker>
63
+            </td>
64
+            <td>
65
+              <el-input v-model="invoice.remark" type="textarea" clearable :autosize="{ minRows: 2 }"
66
+                :disabled="!$store.getters.roles.includes('business')"></el-input>
67
+            </td>
68
+            <td v-show="$store.getters.roles.includes('business')">
69
+              <div class="delete-btn" @click="deletInvoiceItem(index)">
70
+                <i class="el-icon-circle-close"></i>
71
+              </div>
72
+            </td>
73
+          </tr>
74
+          <tr>
75
+            <td>
76
+              合计
77
+            </td>
78
+            <td>
79
+              {{ invoiceSumAmount.toFixed(2) }}
80
+            </td>
81
+            <td>
82
+              {{ invoiceSumPercent.toFixed(2) }}
83
+            </td>
84
+          </tr>
85
+        </table>
86
+        <el-button icon="el-icon-plus" size="mini" @click="addInvoiceList()" type="primary" plain></el-button>
87
+      </el-form-item>
38
       <el-form-item style="text-align: left;" label="回款进度">
88
       <el-form-item style="text-align: left;" label="回款进度">
39
         <table border="1" style="width:100%" v-loading="loading">
89
         <table border="1" style="width:100%" v-loading="loading">
40
           <tr>
90
           <tr>
50
             </td>
100
             </td>
51
             <td>
101
             <td>
52
               <el-input-number style="width:100%" :controls="false" v-model="paid.paidAmount" clearable
102
               <el-input-number style="width:100%" :controls="false" v-model="paid.paidAmount" clearable
53
-                @blur="changePercentage(paid)"></el-input-number>
103
+                @blur="changePercentage(paid)"
104
+                :disabled="!$store.getters.roles.includes('finance', 'nfinance')"></el-input-number>
54
             </td>
105
             </td>
55
             <td>
106
             <td>
56
-              <!-- <el-input-number style="width:100%" :controls="false" v-model="paid.paidPercentage" clearable
57
-                @blur=""></el-input-number> -->
58
               {{ paid.paidPercentage }}
107
               {{ paid.paidPercentage }}
59
             </td>
108
             </td>
60
             <td>
109
             <td>
61
               <el-date-picker style="width:100%" v-model="paid.paidTime" value-format="yyyy-MM-dd" type="date"
110
               <el-date-picker style="width:100%" v-model="paid.paidTime" value-format="yyyy-MM-dd" type="date"
62
-                placeholder="选择日期">
111
+                placeholder="选择日期" :disabled="!$store.getters.roles.includes('finance', 'nfinance')">
63
               </el-date-picker>
112
               </el-date-picker>
64
             </td>
113
             </td>
65
             <td>
114
             <td>
66
-              <el-input v-model="paid.remark" type="textarea" clearable :autosize="{ minRows: 2 }"></el-input>
115
+              <el-input v-model="paid.remark" type="textarea" clearable :autosize="{ minRows: 2 }"
116
+                :disabled="!$store.getters.roles.includes('finance', 'nfinance')"></el-input>
67
             </td>
117
             </td>
68
-            <td v-show="!isDisabled">
118
+            <td v-show="$store.getters.roles.includes('finance', 'nfinance')">
69
               <div class="delete-btn" @click="deletPaiItem(index)">
119
               <div class="delete-btn" @click="deletPaiItem(index)">
70
                 <i class="el-icon-circle-close"></i>
120
                 <i class="el-icon-circle-close"></i>
71
               </div>
121
               </div>
96
 <script>
146
 <script>
97
 import { listPartyA } from "@/api/oa/partyA/partyA";
147
 import { listPartyA } from "@/api/oa/partyA/partyA";
98
 import { listContractPaid, getContractPaid, addContractPaid, updateContractPaid, delContractPaid } from "@/api/oa/contract/contractPaid";
148
 import { listContractPaid, getContractPaid, addContractPaid, updateContractPaid, delContractPaid } from "@/api/oa/contract/contractPaid";
149
+import { listContractInvoice, addContractInvoice, delContractInvoice } from "@/api/oa/contract/contractInvoice";
99
 export default {
150
 export default {
100
   props: {
151
   props: {
101
     form: {
152
     form: {
115
       sumPercent: 0,
166
       sumPercent: 0,
116
       loading: true,
167
       loading: true,
117
       isDisabled: true,
168
       isDisabled: true,
169
+      invoiceList: [{
170
+        invoiceAmount: 0,
171
+        invoicePercentage: 0,
172
+        invoiceTime: '',
173
+        remark: ''
174
+      }],
175
+      invoiceSumAmount: 0,
176
+      invoiceSumPercent: 0,
118
     }
177
     }
119
   },
178
   },
120
   watch: {
179
   watch: {
121
     'form.contractId'(newVal) {
180
     'form.contractId'(newVal) {
122
       this.getPaidList();
181
       this.getPaidList();
182
+      this.getInvoiceList();
123
     }
183
     }
124
   },
184
   },
125
   created() {
185
   created() {
126
     this.getPartyAList();
186
     this.getPartyAList();
127
     this.getPaidList();
187
     this.getPaidList();
128
-    this.isDisabledFn();
188
+    this.getInvoiceList();
129
   },
189
   },
130
   methods: {
190
   methods: {
131
-    isDisabledFn() {
132
-      let roles = ['finance', 'nfinance']
133
-      if (this.$store.getters.roles.some(e => roles.includes(e))) {
134
-        this.isDisabled = false
135
-      } else {
136
-        this.isDisabled = true
137
-      }
138
-    },
139
     // 查询业主单位列表
191
     // 查询业主单位列表
140
     getPartyAList() {
192
     getPartyAList() {
141
       listPartyA({
193
       listPartyA({
162
         this.loading = false;
214
         this.loading = false;
163
       })
215
       })
164
     },
216
     },
217
+    getInvoiceList() {
218
+      this.loading = true;
219
+      listContractInvoice({ contractId: this.form.contractId }).then(res => {
220
+        if (res.total > 0) {
221
+          this.invoiceList = res.rows;
222
+        } else {
223
+          this.invoiceList = [{
224
+            invoiceAmount: 0,
225
+            invoicePercentage: 0,
226
+            invoiceTime: '',
227
+            remark: ''
228
+          }]
229
+        }
230
+        this.getInvoiceSum();
231
+        this.loading = false;
232
+      })
233
+    },
165
     getSum() {
234
     getSum() {
166
       this.sumAmount = this.paidList.reduce((sum, item) => sum + Number(item.paidAmount), 0);
235
       this.sumAmount = this.paidList.reduce((sum, item) => sum + Number(item.paidAmount), 0);
167
       this.sumPercent = this.paidList.reduce((sum, item) => sum + Number(item.paidPercentage), 0);
236
       this.sumPercent = this.paidList.reduce((sum, item) => sum + Number(item.paidPercentage), 0);
168
     },
237
     },
238
+    getInvoiceSum() {
239
+      this.invoiceSumAmount = this.invoiceList.reduce((sum, item) => sum + Number(item.invoiceAmount), 0);
240
+      this.invoiceSumPercent = this.invoiceList.reduce((sum, item) => sum + Number(item.invoicePercentage), 0);
241
+    },
242
+    addInvoiceList() {
243
+      this.invoiceList.push({
244
+        invoiceAmount: 0,
245
+        invoicePercentage: 0,
246
+        invoiceTime: '',
247
+        remark: ''
248
+      });
249
+    },
169
     addPaiList() {
250
     addPaiList() {
170
       this.paidList.push({
251
       this.paidList.push({
171
         paidPercentage: 0,
252
         paidPercentage: 0,
184
       }
265
       }
185
       this.getSum();
266
       this.getSum();
186
     },
267
     },
268
+    deletInvoiceItem(index) {
269
+      let arr = this.invoiceList;
270
+      if (arr.length == 1) {
271
+        return;
272
+      }
273
+      if (index >= 0 && index < arr.length) {
274
+        arr.splice(index, 1);
275
+      }
276
+      this.getInvoiceSum();
277
+    },
187
     changePercentage(paid) {
278
     changePercentage(paid) {
188
       let percent = ((paid.paidAmount / this.form.amount) * 100).toFixed(2);
279
       let percent = ((paid.paidAmount / this.form.amount) * 100).toFixed(2);
189
       paid.paidPercentage = Number(percent);
280
       paid.paidPercentage = Number(percent);
190
       this.getSum();
281
       this.getSum();
191
     },
282
     },
283
+    changeInvoiceAmount(invoice) {
284
+      let percent = ((invoice.invoiceAmount / this.form.amount) * 100).toFixed(2);
285
+      invoice.invoicePercentage = Number(percent);
286
+      this.getInvoiceSum();
287
+    },
192
     async confirm() {
288
     async confirm() {
193
       const contractId = this.form.contractId
289
       const contractId = this.form.contractId
194
       await delContractPaid(contractId);
290
       await delContractPaid(contractId);
196
         p.contractId = contractId
292
         p.contractId = contractId
197
         await addContractPaid(p);
293
         await addContractPaid(p);
198
       }
294
       }
199
-      this.$message.success('回款进度已更新');
295
+      await delContractInvoice(contractId);
296
+      for (let i of this.invoiceList) {
297
+        i.contractId = contractId
298
+        await addContractInvoice(i);
299
+      }
300
+      this.$message.success('更新成功');
200
       this.$emit('cancel')
301
       this.$emit('cancel')
201
       this.$emit('getList')
302
       this.$emit('getList')
202
     }
303
     }

+ 121
- 19
oa-ui/src/views/oa/contract/components/subProgress.vue ファイルの表示

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2025-02-12 13:40:48
3
  * @Date: 2025-02-12 13:40:48
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-02-14 15:34:18
5
+ * @LastEditTime: 2025-07-23 16:54:28
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div>
8
   <div>
9
-    <el-form ref="form" :model="form" label-width="130px" :disabled="isDisabled">
9
+    <el-form ref="form" :model="form" label-width="130px">
10
       <el-form-item label="合同名称" prop="subContractName">
10
       <el-form-item label="合同名称" prop="subContractName">
11
         <el-input style="width: 100%;" v-model="form.subContractName" disabled placeholder="请输入合同名称"></el-input>
11
         <el-input style="width: 100%;" v-model="form.subContractName" disabled placeholder="请输入合同名称"></el-input>
12
       </el-form-item>
12
       </el-form-item>
26
         <el-input-number :controls="false" disabled v-model="form.subAmount" placeholder="请输入分包合同金额" />(元)
26
         <el-input-number :controls="false" disabled v-model="form.subAmount" placeholder="请输入分包合同金额" />(元)
27
       </el-form-item>
27
       </el-form-item>
28
       <el-form-item label="合同备注" prop="remark">
28
       <el-form-item label="合同备注" prop="remark">
29
-        <el-input type="textarea" disabled v-model="form.remark" :autosize="{minRows:4}" />
29
+        <el-input type="textarea" disabled v-model="form.remark" :autosize="{ minRows: 4 }" />
30
+      </el-form-item>
31
+      <el-form-item style="text-align: left;" label="收票进度">
32
+        <table border="1" style="width:100%" v-loading="loading">
33
+          <tr>
34
+            <td style="width: 50px;">序号</td>
35
+            <td>收票金额</td>
36
+            <td>收票比例(%)</td>
37
+            <td>收票时间</td>
38
+            <td style="width: 150px;">备注</td>
39
+          </tr>
40
+          <tr v-for="(invoice, index) in invoiceList" :key="index">
41
+            <td>
42
+              {{ index + 1 }}
43
+            </td>
44
+            <td>
45
+              <el-input-number style="width:100%" :controls="false" v-model="invoice.invoiceAmount" clearable
46
+                @blur="changeInvoiceAmount(invoice)"
47
+                :disabled="!$store.getters.roles.includes('business')"></el-input-number>
48
+            </td>
49
+            <td>
50
+              {{ invoice.invoicePercentage }}
51
+            </td>
52
+            <td>
53
+              <el-date-picker style="width:100%" v-model="invoice.invoiceTime" value-format="yyyy-MM-dd" type="date"
54
+                placeholder="选择日期" :disabled="!$store.getters.roles.includes('business')">
55
+              </el-date-picker>
56
+            </td>
57
+            <td>
58
+              <el-input v-model="invoice.remark" type="textarea" clearable :autosize="{ minRows: 2 }"
59
+                :disabled="!$store.getters.roles.includes('business')"></el-input>
60
+            </td>
61
+            <td v-show="$store.getters.roles.includes('business')">
62
+              <div class="delete-btn" @click="deletInvoiceItem(index)">
63
+                <i class="el-icon-circle-close"></i>
64
+              </div>
65
+            </td>
66
+          </tr>
67
+          <tr>
68
+            <td>
69
+              合计
70
+            </td>
71
+            <td>
72
+              {{ invoiceSumAmount.toFixed(2) }}
73
+            </td>
74
+            <td>
75
+              {{ invoiceSumPercent.toFixed(2) }}
76
+            </td>
77
+          </tr>
78
+        </table>
79
+        <el-button icon="el-icon-plus" size="mini" @click="addInvoiceList()" type="primary" plain></el-button>
30
       </el-form-item>
80
       </el-form-item>
31
       <el-form-item style="text-align: left;" label="付款进度">
81
       <el-form-item style="text-align: left;" label="付款进度">
32
         <table border="1" style="width:100%" v-loading="loading">
82
         <table border="1" style="width:100%" v-loading="loading">
43
             </td>
93
             </td>
44
             <td>
94
             <td>
45
               <el-input-number style="width:100%" :controls="false" v-model="paid.paidAmount" clearable
95
               <el-input-number style="width:100%" :controls="false" v-model="paid.paidAmount" clearable
46
-                @blur="changePercentage(paid)"></el-input-number>
96
+                @blur="changePercentage(paid)"
97
+                :disabled="!$store.getters.roles.includes('finance', 'nfinance')"></el-input-number>
47
             </td>
98
             </td>
48
             <td>
99
             <td>
49
               <!-- <el-input-number style="width:100%" :controls="false" v-model="paid.paidPercentage" clearable
100
               <!-- <el-input-number style="width:100%" :controls="false" v-model="paid.paidPercentage" clearable
52
             </td>
103
             </td>
53
             <td>
104
             <td>
54
               <el-date-picker style="width:100%" v-model="paid.paidTime" value-format="yyyy-MM-dd" type="date"
105
               <el-date-picker style="width:100%" v-model="paid.paidTime" value-format="yyyy-MM-dd" type="date"
55
-                placeholder="选择日期">
106
+                placeholder="选择日期" :disabled="!$store.getters.roles.includes('finance', 'nfinance')">
56
               </el-date-picker>
107
               </el-date-picker>
57
             </td>
108
             </td>
58
             <td>
109
             <td>
59
-              <el-input v-model="paid.remark" type="textarea" clearable :autosize="{ minRows: 2 }"></el-input>
110
+              <el-input v-model="paid.remark" type="textarea" clearable :autosize="{ minRows: 2 }"
111
+                :disabled="!$store.getters.roles.includes('finance', 'nfinance')"></el-input>
60
             </td>
112
             </td>
61
-            <td v-show="!isDisabled">
113
+            <td v-show="$store.getters.roles.includes('finance', 'nfinance')">
62
               <div class="delete-btn" @click="deletPaiItem(index)">
114
               <div class="delete-btn" @click="deletPaiItem(index)">
63
                 <i class="el-icon-circle-close"></i>
115
                 <i class="el-icon-circle-close"></i>
64
               </div>
116
               </div>
89
 <script>
141
 <script>
90
 import { listPartner } from "@/api/oa/partner/partner";
142
 import { listPartner } from "@/api/oa/partner/partner";
91
 import { listContractPaid, addContractPaid, delContractPaid } from "@/api/oa/contract/contractPaid";
143
 import { listContractPaid, addContractPaid, delContractPaid } from "@/api/oa/contract/contractPaid";
144
+import { listContractInvoice, addContractInvoice, delContractInvoice } from "@/api/oa/contract/contractInvoice";
92
 export default {
145
 export default {
93
   props: {
146
   props: {
94
     form: {
147
     form: {
107
       sumAmount: 0,
160
       sumAmount: 0,
108
       sumPercent: 0,
161
       sumPercent: 0,
109
       loading: true,
162
       loading: true,
110
-      isDisabled:true,
163
+      isDisabled: true,
164
+      invoiceList: [{
165
+        invoiceAmount: 0,
166
+        invoicePercentage: 0,
167
+        invoiceTime: '',
168
+        remark: ''
169
+      }],
170
+      invoiceSumAmount: 0,
171
+      invoiceSumPercent: 0,
111
     }
172
     }
112
   },
173
   },
113
   watch: {
174
   watch: {
114
     'form.subContractId'(newVal) {
175
     'form.subContractId'(newVal) {
115
       this.getPaidList();
176
       this.getPaidList();
177
+      this.getInvoiceList();
116
     }
178
     }
117
   },
179
   },
118
   created() {
180
   created() {
119
     this.getPartnerList();
181
     this.getPartnerList();
120
     this.getPaidList();
182
     this.getPaidList();
121
-    this.isDisabledFn();
122
-    
183
+    this.getInvoiceList();
123
   },
184
   },
124
   methods: {
185
   methods: {
125
-    isDisabledFn(){
126
-      let roles = ['finance', 'nfinance']
127
-      if(this.$store.getters.roles.some(e => roles.includes(e))){
128
-        this.isDisabled = false
129
-      }else{
130
-        this.isDisabled = true
131
-      }
132
-    },
133
     // 查询承接单位列表
186
     // 查询承接单位列表
134
     getPartnerList() {
187
     getPartnerList() {
135
       listPartner({
188
       listPartner({
156
         this.loading = false;
209
         this.loading = false;
157
       })
210
       })
158
     },
211
     },
212
+    getInvoiceList() {
213
+      this.loading = true;
214
+      listContractInvoice({ contractId: this.form.subContractId }).then(res => {
215
+        if (res.total > 0) {
216
+          this.invoiceList = res.rows;
217
+        } else {
218
+          this.invoiceList = [{
219
+            invoiceAmount: 0,
220
+            invoicePercentage: 0,
221
+            invoiceTime: '',
222
+            remark: ''
223
+          }]
224
+        }
225
+        this.getInvoiceSum();
226
+        this.loading = false;
227
+      })
228
+    },
159
     getSum() {
229
     getSum() {
160
       this.sumAmount = this.paidList.reduce((sum, item) => sum + Number(item.paidAmount), 0);
230
       this.sumAmount = this.paidList.reduce((sum, item) => sum + Number(item.paidAmount), 0);
161
       this.sumPercent = this.paidList.reduce((sum, item) => sum + Number(item.paidPercentage), 0);
231
       this.sumPercent = this.paidList.reduce((sum, item) => sum + Number(item.paidPercentage), 0);
162
     },
232
     },
233
+    getInvoiceSum() {
234
+      this.invoiceSumAmount = this.invoiceList.reduce((sum, item) => sum + Number(item.invoiceAmount), 0);
235
+      this.invoiceSumPercent = this.invoiceList.reduce((sum, item) => sum + Number(item.invoicePercentage), 0);
236
+    },
237
+    addInvoiceList() {
238
+      this.invoiceList.push({
239
+        invoiceAmount: 0,
240
+        invoicePercentage: 0,
241
+        invoiceTime: '',
242
+        remark: ''
243
+      });
244
+    },
163
     addPaiList() {
245
     addPaiList() {
164
       this.paidList.push({
246
       this.paidList.push({
165
         paidPercentage: 0,
247
         paidPercentage: 0,
178
       }
260
       }
179
       this.getSum();
261
       this.getSum();
180
     },
262
     },
263
+    deletInvoiceItem(index) {
264
+      let arr = this.invoiceList;
265
+      if (arr.length == 1) {
266
+        return;
267
+      }
268
+      if (index >= 0 && index < arr.length) {
269
+        arr.splice(index, 1);
270
+      }
271
+      this.getInvoiceSum();
272
+    },
181
     changePercentage(paid) {
273
     changePercentage(paid) {
182
       let percent = ((paid.paidAmount / this.form.subAmount) * 100).toFixed(2);
274
       let percent = ((paid.paidAmount / this.form.subAmount) * 100).toFixed(2);
183
       paid.paidPercentage = Number(percent);
275
       paid.paidPercentage = Number(percent);
184
       this.getSum();
276
       this.getSum();
185
     },
277
     },
278
+    changeInvoiceAmount(invoice) {
279
+      let percent = ((invoice.invoiceAmount / this.form.subAmount) * 100).toFixed(2);
280
+      invoice.invoicePercentage = Number(percent);
281
+      this.getInvoiceSum();
282
+    },
186
     async confirm() {
283
     async confirm() {
187
       const contractId = this.form.subContractId
284
       const contractId = this.form.subContractId
188
       await delContractPaid(contractId);
285
       await delContractPaid(contractId);
190
         p.contractId = contractId
287
         p.contractId = contractId
191
         await addContractPaid(p);
288
         await addContractPaid(p);
192
       }
289
       }
193
-      this.$message.success('付款进度已更新');
290
+      await delContractInvoice(contractId);
291
+      for (let i of this.invoiceList) {
292
+        i.contractId = contractId
293
+        await addContractInvoice(i);
294
+      }
295
+      this.$message.success('更新成功');
194
       this.$emit('cancel')
296
       this.$emit('cancel')
195
       this.$emit('getList')
297
       this.$emit('getList')
196
     }
298
     }

+ 57
- 40
oa-ui/src/views/oa/contract/index.vue ファイルの表示

1
 <!--
1
 <!--
2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2024-06-21 18:52:00
3
  * @Date: 2024-06-21 18:52:00
4
- * @LastEditors: wrh
5
- * @LastEditTime: 2025-07-17 10:57:14
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-07-23 17:17:19
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div class="app-container">
8
   <div class="app-container">
22
             :value="partyA.partyAId">
22
             :value="partyA.partyAId">
23
           </el-option>
23
           </el-option>
24
         </el-select>
24
         </el-select>
25
-      </el-form-item>      
25
+      </el-form-item>
26
       <el-form-item label="工作内容" prop="queryString">
26
       <el-form-item label="工作内容" prop="queryString">
27
-          <el-input v-model="queryParams.queryString" placeholder="请输入关键字" clearable
28
-            @keyup.enter.native="handleQuery" />
29
-        </el-form-item>
27
+        <el-input v-model="queryParams.queryString" placeholder="请输入关键字" clearable @keyup.enter.native="handleQuery" />
28
+      </el-form-item>
30
       <el-form-item>
29
       <el-form-item>
31
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
30
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
32
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
31
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
39
           v-hasPermi="['oa:contract:add']">登记承接合同</el-button>
38
           v-hasPermi="['oa:contract:add']">登记承接合同</el-button>
40
       </el-col>
39
       </el-col>
41
       <el-col :span="1.5">
40
       <el-col :span="1.5">
42
-        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
41
+        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="exportOpen = true"
43
           v-hasPermi="['oa:contract:export']">导出</el-button>
42
           v-hasPermi="['oa:contract:export']">导出</el-button>
44
       </el-col>
43
       </el-col>
45
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
44
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
53
       <el-table-column label="甲方单位" align="center" prop="partyA.partyAName" width="220px" />
52
       <el-table-column label="甲方单位" align="center" prop="partyA.partyAName" width="220px" />
54
       <el-table-column label="合同编码(公司)" align="center" prop="contractCode" />
53
       <el-table-column label="合同编码(公司)" align="center" prop="contractCode" />
55
       <el-table-column label="合同编号(业主)" align="center" prop="contractNumber" />
54
       <el-table-column label="合同编号(业主)" align="center" prop="contractNumber" />
56
-      <!-- <el-table-column label="履约保证金" align="center" prop="deposit" /> -->
57
-      <!-- <el-table-column label="合同文件" align="center" prop="contractDocument" show-overflow-tooltip>
58
-        <template slot-scope="scope">
59
-          <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + scope.row.contractDocument}`)">
60
-            {{ getFileName(scope.row.contractDocument) }}
61
-          </el-link>
62
-        </template>
63
-      </el-table-column> -->
64
-      <el-table-column label="拟稿日期" align="center" prop="draftTime">
55
+      <el-table-column label="拟稿日期" align="center" prop="draftTime" width="110px">
65
         <template slot-scope="scope">
56
         <template slot-scope="scope">
66
           <span>{{ parseTime(scope.row.draftTime, '{y}-{m}-{d}') }}</span>
57
           <span>{{ parseTime(scope.row.draftTime, '{y}-{m}-{d}') }}</span>
67
         </template>
58
         </template>
68
       </el-table-column>
59
       </el-table-column>
69
-      <el-table-column label="签订日期" align="center" prop="signDate">
60
+      <el-table-column label="签订日期" align="center" prop="signDate" width="110px">
70
         <template slot-scope="scope">
61
         <template slot-scope="scope">
71
           <span>{{ parseTime(scope.row.signDate, '{y}-{m}-{d}') }}</span>
62
           <span>{{ parseTime(scope.row.signDate, '{y}-{m}-{d}') }}</span>
72
         </template>
63
         </template>
73
       </el-table-column>
64
       </el-table-column>
74
-      <el-table-column prop="percentage" align="center" label="回款进度" width="120px" sortable>
65
+      <el-table-column prop="percentage" align="center" label="开票/回款进度" width="130px" sortable>
75
         <template slot-scope="scope">
66
         <template slot-scope="scope">
76
-          <el-progress :text-inside="true" :stroke-width="26" :status="formatStatus(scope.row.percentage)"
77
-            :percentage="scope.row.percentage" text-color="#fff"></el-progress>
67
+          <div class="mb10">
68
+            <el-progress :text-inside="true" :stroke-width="26" :status="formatStatus(scope.row.percentage)"
69
+              :percentage="scope.row.percentage" text-color="#fff"></el-progress>
70
+            <div>
71
+              {{ scope.row.paidAmount }}
72
+            </div>
73
+          </div>
74
+          <div>
75
+            <el-progress :text-inside="true" :stroke-width="26" :status="formatStatus(scope.row.percentage)"
76
+              :percentage="scope.row.percentage" text-color="#fff"></el-progress>
78
             <div>
77
             <div>
79
-              {{scope.row.paidAmount}}
78
+              {{ scope.row.paidAmount }}
80
             </div>
79
             </div>
80
+          </div>
81
         </template>
81
         </template>
82
       </el-table-column>
82
       </el-table-column>
83
-      <!-- <el-table-column label="签订备注" align="center" prop="signRemark" /> -->
84
-      <!-- <el-table-column label="签订扫描件" align="center" prop="signScan" show-overflow-tooltip>
85
-        <template slot-scope="scope">
86
-          <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + scope.row.signScan}`)">
87
-            {{ getFileName(scope.row.signScan) }}
88
-          </el-link>
89
-        </template>
90
-      </el-table-column> -->
91
-      <!-- <el-table-column label="评审方式" align="center" prop="commentType">
92
-        <template slot-scope="scope">
93
-          <el-tag :type="scope.row.commentType == '2' ? 'success' : 'warning'">
94
-            {{ getCommentType(scope.row.commentType) }}
95
-          </el-tag>
96
-        </template>
97
-      </el-table-column> -->
98
-      <!-- <el-table-column label="合同备注" align="center" prop="remark" /> -->
99
-      <el-table-column label="拟稿人" align="center" prop="drafter">
83
+      <el-table-column label="拟稿人" align="center" prop="drafter" width="110px">
100
         <template slot-scope="scope">
84
         <template slot-scope="scope">
101
           {{ getUserName(scope.row.drafter) }}
85
           {{ getUserName(scope.row.drafter) }}
102
         </template>
86
         </template>
128
     <el-dialog :title="title" :visible.sync="progressOpen" width="50%" append-to-body>
112
     <el-dialog :title="title" :visible.sync="progressOpen" width="50%" append-to-body>
129
       <payment-progress :form="progressContract" @cancel="progressOpen = false" @getList="getList"></payment-progress>
113
       <payment-progress :form="progressContract" @cancel="progressOpen = false" @getList="getList"></payment-progress>
130
     </el-dialog>
114
     </el-dialog>
115
+    <!-- 导出对话框 -->
116
+    <el-dialog :title="title" :visible.sync="exportOpen" width="50%" append-to-body>
117
+      <el-form>
118
+        <el-form-item label="导出字段名" label-width="100px">
119
+          <el-checkbox-group v-model="selectedFields">
120
+            <el-checkbox v-for="field in fieldsObj" :key="field.value" :label="field.value">
121
+              {{ field.label }}
122
+            </el-checkbox>
123
+          </el-checkbox-group>
124
+        </el-form-item>
125
+      </el-form>
126
+      <div slot="footer" class="dialog-footer">
127
+        <el-button type="primary" @click="handleExport">导出</el-button>
128
+        <el-button @click="exportOpen = false">取消</el-button>
129
+      </div>
130
+    </el-dialog>
131
   </div>
131
   </div>
132
 </template>
132
 </template>
133
 
133
 
198
       queryLoading: true,
198
       queryLoading: true,
199
       progressContract: {},
199
       progressContract: {},
200
       progressOpen: false,
200
       progressOpen: false,
201
+      exportOpen: false,
202
+      fieldsObj: [
203
+        { label: '合同名称', value: 'contractName' },
204
+        { label: '合同金额', value: 'amount' },
205
+        { label: '甲方单位', value: 'partyAName' },
206
+        { label: '合同编码(公司)', value: 'contractCode' },
207
+        { label: '合同编号(业主)', value: 'contractNumber' },
208
+        { label: '拟稿人', value: 'drafter' },
209
+        { label: '拟稿日期', value: 'draftTime' },
210
+        { label: '签订日期', value: 'signDate' },
211
+        { label: '实际回款金额', value: 'paidAmount' },
212
+        { label: '实际回款比例', value: 'paidPercentage' },
213
+      ],
214
+      selectedFields: []
201
     };
215
     };
202
   },
216
   },
203
   created() {
217
   created() {
425
     },
439
     },
426
     /** 导出按钮操作 */
440
     /** 导出按钮操作 */
427
     handleExport() {
441
     handleExport() {
428
-      this.download('oa/contract/export', {
429
-        ...this.queryParams
442
+      let selectFields = this.selectedFields.join(',');
443
+      console.log(selectFields);
444
+      this.download('oa/contract/exportSelectFields', {
445
+        ...this.queryParams,
446
+        selectFields: selectFields
430
       }, `contract_${new Date().getTime()}.xlsx`)
447
       }, `contract_${new Date().getTime()}.xlsx`)
431
     },
448
     },
432
     remoteMethod(val) {
449
     remoteMethod(val) {

読み込み中…
キャンセル
保存