import { MyButtons, MyColumns, MyProTableProps } from '@/common'; import { Selects } from '@/components/Select'; import { Apis } from '@/gen/Apis'; import { ProTable } from '@ant-design/pro-components'; import { message, Progress, Space } from 'antd'; import { saveAs } from 'file-saver'; import JSZip from 'jszip'; import { useState } from 'react'; import Create from './modals/Create'; import Update from './modals/Update'; interface DataType { key?: React.Key; id?: React.Key; } export default function Index({ title = '点位配置' }) { const [count, setCount] = useState(0); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [downloadProgress, setDownloadProgress] = useState(0); const [downloading, setDownloading] = useState(false); const [getSelectedRow, setSelectedRow] = useState([]); const rowSelection: any = { selectedRowKeys, onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => { console.log(selectedRows, 'selectedRows[0]'); if (selectedRowKeys.length > 10) { message.warning('最多批量下载10个'); return; } setSelectedRowKeys(selectedRowKeys); setSelectedRow(selectedRows); }, getCheckboxProps: (record: any) => ({ disabled: !record.is_enabled, }), onSelectAll: (selected: boolean, selectedRows: DataType[]) => { if (selected && selectedRows.length > 10) { message.warning('全选数量超过10个!'); return false; } }, defaultSelectedRowKeys: !count ? [] : getSelectedRow?.map((item: any) => item.id), }; // 模拟获取二维码接口 const getQRCode = async (id?: string) => { let res = await Apis.Patrol.PatrolLocations.PatrolLocationQrCode({ id: Number(id), }); return res?.data?.qr_code; }; // 生成带海报的二维码 const generatePosterQR = async (base64: string, res: any) => { return new Promise((resolve) => { const canvas = document.createElement('canvas'); const ctx: any = canvas.getContext('2d'); canvas.width = 500; canvas.height = 800; // 海报样式 ctx.fillStyle = '#1890ff'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'white'; ctx.font = 'bold 36px Arial'; ctx.textAlign = 'center'; ctx.fillText(`${res?.name}`, canvas.width / 2, 130); const qrImage = new Image(); qrImage.onload = () => { const qrSize = 300; const qrX = (canvas.width - qrSize) / 2; const qrY = 210; ctx.drawImage(qrImage, qrX, qrY, qrSize, qrSize); ctx.font = '20px Arial'; ctx.fillText('扫描二维码完成签到', canvas.width / 2, 570); ctx.font = '16px Arial'; ctx.fillText(res?.code, canvas.width / 2, 605); resolve(canvas.toDataURL('image/png')); }; qrImage.src = base64; }); }; const download = async (type: number) => { if (!getSelectedRow?.length) { message.error('请选择巡逻位置!'); return; } setDownloading(true); setDownloadProgress(0); try { const zip = new JSZip(); const total = getSelectedRow.length; for (let i = 0; i < total; i++) { let res = getSelectedRow?.[i]; if (res?.id) { await new Promise((resolve: any) => { setTimeout(resolve, 1000); }); const qrCode = await getQRCode(res?.id); if (type === 1) { const base64Data = qrCode.split(',')[1]; zip.file(`${res?.name}_${res?.code}.png`, base64Data, { base64: true, }); } if (type === 2) { // 带海报的二维码 const posterData: any = await generatePosterQR(qrCode, res); const fileData = posterData.split(',')[1]; zip.file(`${res?.name}_${res?.code}.png`, fileData, { base64: true, }); } setCount(i + 1); const progress = Math.round(((i + 1) / total) * 100); setDownloadProgress(progress); // 添加延迟 } } const content = await zip.generateAsync({ type: 'blob' }); saveAs(content, `扫码签到二维码.zip`); setTimeout(() => { setCount(0); }, 1000); } catch (error) { console.error('下载失败:', error); message.error('下载失败,请重试'); } finally { setDownloading(false); setDownloadProgress(0); } }; return ( ), }} request={async (params, sort) => MyProTableProps.request(params, sort, Apis.Patrol.PatrolLocations.List) } rowSelection={{ type: 'checkbox', ...rowSelection }} toolBarRender={(action) => [ download(1)} />, download(2)} />, , ]} columns={[ MyColumns.ID({ search: false, }), Selects?.AssetProjects({ title: '选择项目', key: 'asset_projects_id', hidden: true, }), { title: '关联项目', dataIndex: ['asset_project', 'name'], search: { transform: (value) => { return { project_name: value }; }, }, }, { title: '点位名称', dataIndex: 'name', }, { title: '位置编码', dataIndex: 'code', }, MyColumns.Boolean({ dataIndex: 'is_enabled', title: '启用/禁用', search: false, }), MyColumns.CreatedAt(), MyColumns.Option({ render: (_, item: any, index, action) => ( Apis.Patrol.PatrolLocations.Update({ id: item.id ?? 0, is_enabled: item.is_enabled === 1 ? 0 : 1, name: item.name, code: item.code, asset_projects_id: item.asset_projects_id, }).then(() => action?.reload()) } /> Apis.Patrol.PatrolLocations.Delete({ id: item.id }).then(() => action?.reload(), ) } /> ), }), ]} /> ); }