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 | 1 | <template> |
2 | 2 | <div> |
3 | 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 | 23 | <template #bodyCell="{ column, record }"> |
5 | 24 | <template v-if="column.key === 'action'"> |
6 | 25 | <TableAction |
... | ... | @@ -8,30 +27,17 @@ |
8 | 27 | :dropDownActions="createDropActions(record)" |
9 | 28 | /> |
10 | 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 | 39 | </template> |
22 | 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 | 41 | <CheckDetail @register="checkModalRegister" :onGoFormDetail="handleGoFormDetail" /> |
36 | 42 | <FinanceEdit @register="registerFinanceEdit" @success="handleSuccess" /> |
37 | 43 | <HistoryDetail @register="registerHistoryDetail" /> |
... | ... | @@ -41,6 +47,7 @@ |
41 | 47 | import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
42 | 48 | import { getServiceProfit } from '@/api/project/invoice'; |
43 | 49 | import { searchFormSchema, COLUMNS } from './data'; |
50 | + import axios from 'axios'; | |
44 | 51 | import { useMessage } from '/@/hooks/web/useMessage'; |
45 | 52 | import { onMounted, ref, computed, unref } from 'vue'; |
46 | 53 | import { useDrawer } from '/@/components/Drawer'; |
... | ... | @@ -56,6 +63,7 @@ |
56 | 63 | const checkedKeys = ref<string[]>([]); |
57 | 64 | const invoiceIdKeys = ref<string[]>([]); |
58 | 65 | const checkIdKeys = ref<string[]>([]); |
66 | + const detailProjectNoKeys = ref<string[]>([]); | |
59 | 67 | const orderStore = useOrderStoreWithOut(); |
60 | 68 | const [checkModalRegister, { openDrawer: openCheckDetailDrawer }] = useDrawer(); |
61 | 69 | const [registerFinanceEdit, { openDrawer: openFinanceEdit }] = useDrawer(); |
... | ... | @@ -66,16 +74,17 @@ |
66 | 74 | return user?.roleSmallVO?.code; |
67 | 75 | }); |
68 | 76 | const [registerTable, { reload, getSelectRowKeys, getDataSource, setSelectedRowKeys }] = useTable({ |
69 | - | |
77 | + title: '', | |
70 | 78 | api: getServiceProfit, |
71 | 79 | bordered: true, |
72 | 80 | columns: COLUMNS, |
73 | 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 | 89 | useSearchForm: true, |
81 | 90 | showTableSetting: true, |
... | ... | @@ -97,23 +106,8 @@ |
97 | 106 | label: '财务编辑', |
98 | 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 | 110 | label: '申请权限', |
113 | - // popConfirm: { | |
114 | - // title: '确认申请?', | |
115 | - // confirm: handleFalse.bind(null, record), | |
116 | - // }, | |
117 | 111 | onClick: handleFalse.bind(null, record), |
118 | 112 | }, |
119 | 113 | { |
... | ... | @@ -173,11 +167,6 @@ |
173 | 167 | return false; |
174 | 168 | } |
175 | 169 | |
176 | - // async function handleFalse(record: any) { | |
177 | - // console.log(record); | |
178 | - // // openModal(true, { record }); | |
179 | - // } | |
180 | - | |
181 | 170 | function handleSuccess() { |
182 | 171 | setTimeout(() => { |
183 | 172 | reload(); |
... | ... | @@ -189,26 +178,17 @@ |
189 | 178 | handleCancel(record); |
190 | 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 | 182 | function handleCancel(record) { |
200 | 183 | record.onEdit?.(false, false); |
201 | 184 | } |
202 | 185 | |
203 | 186 | async function handleDelete(record) { |
204 | - // await deleteConfig({ ids: [record.id] }); | |
205 | 187 | reload(); |
206 | 188 | } |
207 | 189 | |
208 | 190 | async function handleStatus(record, status) { |
209 | 191 | try { |
210 | - // You can implement the API call here | |
211 | - // await someApiCall({ id: record.id, status }); | |
212 | 192 | reload(); |
213 | 193 | } catch (error) { |
214 | 194 | console.error('Error updating status:', error); |
... | ... | @@ -220,5 +200,158 @@ |
220 | 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 | 356 | </script> |
224 | 357 | <style></style> | ... | ... |