Commit 192bbb6f2f94865908074ddad8a16b5d14274068
1 parent
f267cff7
feat: 开发业务利润表导出
Showing
1 changed file
with
190 additions
and
57 deletions
src/views/project/finance/financeProfit/ServiceProfit/ServiceProfit/index.vue
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | <BasicTable @register="registerTable" :bordered="true"> | 3 | <BasicTable @register="registerTable" :bordered="true"> |
4 | + <template #headerTop> | ||
5 | + <a-alert type="info" show-icon> | ||
6 | + <template #message> | ||
7 | + <template v-if="checkedKeys.length > 0"> | ||
8 | + <span>已选中{{ checkedKeys.length }}条记录(可跨页)</span> | ||
9 | + <a-button | ||
10 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
11 | + type="link" | ||
12 | + @click="handleClearChoose" | ||
13 | + size="small" | ||
14 | + >清空</a-button | ||
15 | + > | ||
16 | + </template> | ||
17 | + <template v-else> | ||
18 | + <span>未选中任何订单</span> | ||
19 | + </template> | ||
20 | + </template> | ||
21 | + </a-alert> | ||
22 | + </template> | ||
4 | <template #bodyCell="{ column, record }"> | 23 | <template #bodyCell="{ column, record }"> |
5 | <template v-if="column.key === 'action'"> | 24 | <template v-if="column.key === 'action'"> |
6 | <TableAction | 25 | <TableAction |
@@ -8,30 +27,17 @@ | @@ -8,30 +27,17 @@ | ||
8 | :dropDownActions="createDropActions(record)" | 27 | :dropDownActions="createDropActions(record)" |
9 | /> | 28 | /> |
10 | </template> | 29 | </template> |
11 | - <!-- <template v-if="column.key === 'relationValue'"> | ||
12 | - <a-input | ||
13 | - v-if="record.settingValue === 'A01'" | ||
14 | - v-model:value="record.settingValue" | ||
15 | - :max-length="50" | ||
16 | - /> | ||
17 | - <span v-else style="color: red"> | ||
18 | - {{ record.settingValue }} | ||
19 | - </span> | ||
20 | - </template> --> | 30 | + </template> |
31 | + <template #toolbar> | ||
32 | + <a-button | ||
33 | + type="primary" | ||
34 | + @click="handleExport" | ||
35 | + v-if="role == ROLE.ADMIN || role == ROLE.FINANCE" | ||
36 | + :style="{ borderRadius: '5px 5px 5px 5px' }" | ||
37 | + >导出</a-button | ||
38 | + > | ||
21 | </template> | 39 | </template> |
22 | </BasicTable> | 40 | </BasicTable> |
23 | - <!-- <BasicModal | ||
24 | - title="拒绝原因" | ||
25 | - width="30%" | ||
26 | - @register="registerModal" | ||
27 | - @visible-change="handleClose" | ||
28 | - @ok="handleOk" | ||
29 | - wrapClassName="approve-modal" | ||
30 | - > | ||
31 | - <div className="pa-8"> | ||
32 | - <a-textarea :rows="6" placeholder="请输入拒绝原因" v-model:value="message" /> | ||
33 | - </div> | ||
34 | - </BasicModal> --> | ||
35 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> | 41 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
36 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> | 42 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
37 | <HistoryDetail @register="registerHistoryDetail" /> | 43 | <HistoryDetail @register="registerHistoryDetail" /> |
@@ -41,6 +47,7 @@ | @@ -41,6 +47,7 @@ | ||
41 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; | 47 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
42 | import { getServiceProfit } from '@/api/project/invoice'; | 48 | import { getServiceProfit } from '@/api/project/invoice'; |
43 | import { searchFormSchema, COLUMNS } from './data'; | 49 | import { searchFormSchema, COLUMNS } from './data'; |
50 | + import axios from 'axios'; | ||
44 | import { useMessage } from '/@/hooks/web/useMessage'; | 51 | import { useMessage } from '/@/hooks/web/useMessage'; |
45 | import { onMounted, ref, computed, unref } from 'vue'; | 52 | import { onMounted, ref, computed, unref } from 'vue'; |
46 | import { useDrawer } from '/@/components/Drawer'; | 53 | import { useDrawer } from '/@/components/Drawer'; |
@@ -56,6 +63,7 @@ | @@ -56,6 +63,7 @@ | ||
56 | const checkedKeys = ref<string[]>([]); | 63 | const checkedKeys = ref<string[]>([]); |
57 | const invoiceIdKeys = ref<string[]>([]); | 64 | const invoiceIdKeys = ref<string[]>([]); |
58 | const checkIdKeys = ref<string[]>([]); | 65 | const checkIdKeys = ref<string[]>([]); |
66 | + const detailProjectNoKeys = ref<string[]>([]); | ||
59 | const orderStore = useOrderStoreWithOut(); | 67 | const orderStore = useOrderStoreWithOut(); |
60 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); | 68 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
61 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); | 69 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
@@ -66,16 +74,17 @@ | @@ -66,16 +74,17 @@ | ||
66 | return user?.roleSmallVO?.code; | 74 | return user?.roleSmallVO?.code; |
67 | }); | 75 | }); |
68 | const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys }] = useTable({ | 76 | const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys }] = useTable({ |
69 | - | 77 | + title: '', |
70 | api: getServiceProfit, | 78 | api: getServiceProfit, |
71 | bordered: true, | 79 | bordered: true, |
72 | columns: COLUMNS, | 80 | columns: COLUMNS, |
73 | clickToRowSelect: false, | 81 | clickToRowSelect: false, |
74 | - rowKey: 'id', | ||
75 | - formConfig: { | ||
76 | - labelWidth: 120, | ||
77 | - schemas: searchFormSchema, | ||
78 | - autoSubmitOnEnter: true, | 82 | + rowKey: (record) => record.detailProjectNo || record.id || record.serialNumber, |
83 | + rowSelection: { | ||
84 | + type: 'checkbox', | ||
85 | + selectedRowKeys: checkedKeys as any, | ||
86 | + onSelect: onSelect, | ||
87 | + onSelectAll: onSelectAll, | ||
79 | }, | 88 | }, |
80 | useSearchForm: true, | 89 | useSearchForm: true, |
81 | showTableSetting: true, | 90 | showTableSetting: true, |
@@ -97,23 +106,8 @@ | @@ -97,23 +106,8 @@ | ||
97 | label: '财务编辑', | 106 | label: '财务编辑', |
98 | onClick: handleFinanceEdit.bind(null, record), | 107 | onClick: handleFinanceEdit.bind(null, record), |
99 | }, | 108 | }, |
100 | - // { | ||
101 | - // label: '编辑', | ||
102 | - // onClick: handleEdit.bind(null, record), | ||
103 | - // }, | ||
104 | - // { | ||
105 | - // label: '删除', | ||
106 | - // popConfirm: { | ||
107 | - // title: '确认删除?', | ||
108 | - // confirm: handleDelete.bind(null, record), | ||
109 | - // }, | ||
110 | - // }, | ||
111 | { | 109 | { |
112 | label: '申请权限', | 110 | label: '申请权限', |
113 | - // popConfirm: { | ||
114 | - // title: '确认申请?', | ||
115 | - // confirm: handleFalse.bind(null, record), | ||
116 | - // }, | ||
117 | onClick: handleFalse.bind(null, record), | 111 | onClick: handleFalse.bind(null, record), |
118 | }, | 112 | }, |
119 | { | 113 | { |
@@ -173,11 +167,6 @@ | @@ -173,11 +167,6 @@ | ||
173 | return false; | 167 | return false; |
174 | } | 168 | } |
175 | 169 | ||
176 | - // async function handleFalse(record: any) { | ||
177 | - // console.log(record); | ||
178 | - // // openModal(true, { record }); | ||
179 | - // } | ||
180 | - | ||
181 | function handleSuccess() { | 170 | function handleSuccess() { |
182 | setTimeout(() => { | 171 | setTimeout(() => { |
183 | reload(); | 172 | reload(); |
@@ -189,26 +178,17 @@ | @@ -189,26 +178,17 @@ | ||
189 | handleCancel(record); | 178 | handleCancel(record); |
190 | reload(); | 179 | reload(); |
191 | } | 180 | } |
192 | - function handleEdit(record: any) { | ||
193 | - // if (record.settingValue == 'A01') { | ||
194 | - // error('请勿连续点击生成按钮,需要等待三秒再点击生成'); | ||
195 | - // } else { | ||
196 | - record.onEdit?.(true); | ||
197 | - } | ||
198 | 181 | ||
199 | function handleCancel(record) { | 182 | function handleCancel(record) { |
200 | record.onEdit?.(false, false); | 183 | record.onEdit?.(false, false); |
201 | } | 184 | } |
202 | 185 | ||
203 | async function handleDelete(record) { | 186 | async function handleDelete(record) { |
204 | - // await deleteConfig({ ids: [record.id] }); | ||
205 | reload(); | 187 | reload(); |
206 | } | 188 | } |
207 | 189 | ||
208 | async function handleStatus(record, status) { | 190 | async function handleStatus(record, status) { |
209 | try { | 191 | try { |
210 | - // You can implement the API call here | ||
211 | - // await someApiCall({ id: record.id, status }); | ||
212 | reload(); | 192 | reload(); |
213 | } catch (error) { | 193 | } catch (error) { |
214 | console.error('Error updating status:', error); | 194 | console.error('Error updating status:', error); |
@@ -220,5 +200,158 @@ | @@ -220,5 +200,158 @@ | ||
220 | data: record, | 200 | data: record, |
221 | }); | 201 | }); |
222 | } | 202 | } |
203 | + | ||
204 | + function handleExport() { | ||
205 | + console.log(detailProjectNoKeys.value, '5656detailProjectNoKeys.value'); | ||
206 | + if (checkedKeys.value.length <= 0) { | ||
207 | + createMessage.warn('请选择数据!'); | ||
208 | + return; | ||
209 | + } | ||
210 | + const token = userStore.getToken; | ||
211 | + axios | ||
212 | + .post( | ||
213 | + '/basic-api/project/businessProfit/exportExcel', | ||
214 | + { detailProjectNo: detailProjectNoKeys.value }, | ||
215 | + { | ||
216 | + headers: { | ||
217 | + Authorization: `${token}`, // 去掉引号 | ||
218 | + }, | ||
219 | + responseType: 'blob', // 设置响应类型为 'blob' | ||
220 | + }, | ||
221 | + ) | ||
222 | + .then((response) => { | ||
223 | + // 创建一个 Blob 对象来保存二进制数据 | ||
224 | + const blob = new Blob([response.data], { type: 'application/zip' }); | ||
225 | + const getFormattedDate = (): string => { | ||
226 | + const date = new Date(); | ||
227 | + | ||
228 | + const year = date.getFullYear(); | ||
229 | + const month = String(date.getMonth() + 1).padStart(2, '0'); | ||
230 | + const day = String(date.getDate()).padStart(2, '0'); | ||
231 | + | ||
232 | + const hours = String(date.getHours()).padStart(2, '0'); | ||
233 | + const minutes = String(date.getMinutes()).padStart(2, '0'); | ||
234 | + const seconds = String(date.getSeconds()).padStart(2, '0'); | ||
235 | + | ||
236 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | ||
237 | + }; | ||
238 | + const date = getFormattedDate(); | ||
239 | + // 创建一个链接元素用于下载 | ||
240 | + const link = document.createElement('a'); | ||
241 | + link.href = window.URL.createObjectURL(blob); | ||
242 | + link.download = `业务利润分析表${date}.xlsx`; // 你可以为文件命名 | ||
243 | + document.body.appendChild(link); | ||
244 | + link.click(); // 自动点击链接,触发下载 | ||
245 | + document.body.removeChild(link); // 下载完成后移除链接 | ||
246 | + }) | ||
247 | + .catch((error) => { | ||
248 | + console.error(error); | ||
249 | + }); | ||
250 | + reload(); | ||
251 | + } | ||
252 | + | ||
253 | + function handleClearChoose() { | ||
254 | + checkedKeys.value = []; | ||
255 | + detailProjectNoKeys.value = []; | ||
256 | + invoiceIdKeys.value = []; | ||
257 | + checkIdKeys.value = []; | ||
258 | + } | ||
259 | + | ||
260 | + async function onSelect(record, selected: boolean) { | ||
261 | + const rowKey = record.detailProjectNo || record.id || record.serialNumber; | ||
262 | + if (selected) { | ||
263 | + checkedKeys.value = [...checkedKeys.value, rowKey]; | ||
264 | + | ||
265 | + // 如果detailProjectNo是数组,将每个元素添加到detailProjectNoKeys中 | ||
266 | + if (record.detailProjectNo !== undefined) { | ||
267 | + if (Array.isArray(record.detailProjectNo)) { | ||
268 | + record.detailProjectNo.forEach((projectNo) => { | ||
269 | + if (!detailProjectNoKeys.value.includes(projectNo)) { | ||
270 | + detailProjectNoKeys.value.push(projectNo); | ||
271 | + } | ||
272 | + }); | ||
273 | + } else { | ||
274 | + // 如果是单个值,直接添加 | ||
275 | + if (!detailProjectNoKeys.value.includes(record.detailProjectNo)) { | ||
276 | + detailProjectNoKeys.value.push(record.detailProjectNo); | ||
277 | + } | ||
278 | + } | ||
279 | + } | ||
280 | + | ||
281 | + if (record.invoiceId !== undefined) { | ||
282 | + invoiceIdKeys.value = [...invoiceIdKeys.value, record.invoiceId]; | ||
283 | + } | ||
284 | + | ||
285 | + if (record.checkId !== undefined) { | ||
286 | + checkIdKeys.value = [...checkIdKeys.value, record.checkId]; | ||
287 | + } | ||
288 | + } else { | ||
289 | + checkedKeys.value = checkedKeys.value.filter((key) => key !== rowKey); | ||
290 | + | ||
291 | + // 如果detailProjectNo是数组,从detailProjectNoKeys中移除每个元素 | ||
292 | + if (record.detailProjectNo !== undefined) { | ||
293 | + if (Array.isArray(record.detailProjectNo)) { | ||
294 | + detailProjectNoKeys.value = detailProjectNoKeys.value.filter( | ||
295 | + (projectNo) => !record.detailProjectNo.includes(projectNo) | ||
296 | + ); | ||
297 | + } else { | ||
298 | + // 如果是单个值,直接移除 | ||
299 | + detailProjectNoKeys.value = detailProjectNoKeys.value.filter( | ||
300 | + (projectNo) => projectNo !== record.detailProjectNo | ||
301 | + ); | ||
302 | + } | ||
303 | + } | ||
304 | + | ||
305 | + if (record.invoiceId !== undefined) { | ||
306 | + invoiceIdKeys.value = invoiceIdKeys.value.filter( | ||
307 | + (invoiceId) => invoiceId !== record.invoiceId, | ||
308 | + ); | ||
309 | + } | ||
310 | + | ||
311 | + if (record.checkId !== undefined) { | ||
312 | + checkIdKeys.value = checkIdKeys.value.filter((checkId) => checkId !== record.checkId); | ||
313 | + } | ||
314 | + } | ||
315 | + setSelectedRowKeys(checkedKeys.value as any); | ||
316 | + } | ||
317 | + | ||
318 | + function onSelectAll(selected: boolean, selectedRows: any[]) { | ||
319 | + if (selected) { | ||
320 | + selectedRows.forEach((row) => { | ||
321 | + const rowKey = row.detailProjectNo || row.id || row.serialNumber; | ||
322 | + checkedKeys.value = [...checkedKeys.value, rowKey]; | ||
323 | + | ||
324 | + // 如果detailProjectNo是数组,将每个元素添加到detailProjectNoKeys中 | ||
325 | + if (row.detailProjectNo !== undefined) { | ||
326 | + if (Array.isArray(row.detailProjectNo)) { | ||
327 | + row.detailProjectNo.forEach((projectNo) => { | ||
328 | + if (!detailProjectNoKeys.value.includes(projectNo)) { | ||
329 | + detailProjectNoKeys.value.push(projectNo); | ||
330 | + } | ||
331 | + }); | ||
332 | + } else { | ||
333 | + // 如果是单个值,直接添加 | ||
334 | + if (!detailProjectNoKeys.value.includes(row.detailProjectNo)) { | ||
335 | + detailProjectNoKeys.value.push(row.detailProjectNo); | ||
336 | + } | ||
337 | + } | ||
338 | + } | ||
339 | + | ||
340 | + if (row.invoiceId !== undefined) { | ||
341 | + invoiceIdKeys.value = [...invoiceIdKeys.value, row.invoiceId]; | ||
342 | + } | ||
343 | + | ||
344 | + if (row.checkId !== undefined) { | ||
345 | + checkIdKeys.value = [...checkIdKeys.value, row.checkId]; | ||
346 | + } | ||
347 | + }); | ||
348 | + } else { | ||
349 | + checkedKeys.value = []; | ||
350 | + detailProjectNoKeys.value = []; | ||
351 | + invoiceIdKeys.value = []; | ||
352 | + checkIdKeys.value = []; | ||
353 | + } | ||
354 | + setSelectedRowKeys(checkedKeys.value as any); | ||
355 | + } | ||
223 | </script> | 356 | </script> |
224 | <style></style> | 357 | <style></style> |