|
|
@@ -0,0 +1,112 @@
|
|
|
+import { downloadUrl } from '@/api/file'
|
|
|
+
|
|
|
+function escapeHtml(str) {
|
|
|
+ return String(str).replace(/[&<>"']/g, s => ({
|
|
|
+ '&': '&',
|
|
|
+ '<': '<',
|
|
|
+ '>': '>',
|
|
|
+ '"': '"',
|
|
|
+ "'": '''
|
|
|
+ })[s] || s)
|
|
|
+}
|
|
|
+
|
|
|
+export function printImages(attachList = [], vueCtx) {
|
|
|
+ const ctx = vueCtx || {}
|
|
|
+ const msg = (type, text) => {
|
|
|
+ if (ctx.$message && ctx.$message[type]) ctx.$message[type](text)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!attachList || !attachList.length) {
|
|
|
+ msg('warning', '没有可打印的图片文件')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
|
|
|
+ const items = attachList
|
|
|
+ .filter(a => a && a.fileName && imageExts.includes(a.fileName.split('.').pop().toLowerCase()) && a.url)
|
|
|
+ .map(a => ({ name: a.fileName, url: /^(https?:)?\/\//i.test(a.url) ? a.url : (downloadUrl + a.url) }))
|
|
|
+
|
|
|
+ if (!items.length) {
|
|
|
+ msg('warning', '附件中没有图片类型文件')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const win = window.open('', '_blank')
|
|
|
+ if (!win) {
|
|
|
+ msg('error', '浏览器阻止了打印预览窗口,请允许弹窗')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 替换地址,避免打印页脚显示 about:blank
|
|
|
+ try {
|
|
|
+ win.history.replaceState(null, '', '/print-drawings')
|
|
|
+ } catch (e) { /* 忽略 */ }
|
|
|
+
|
|
|
+ const html = `<!DOCTYPE html>
|
|
|
+ <html>
|
|
|
+ <head>
|
|
|
+ <meta charset="utf-8" />
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
+ <title>打印图纸</title>
|
|
|
+ <style>
|
|
|
+ html, body { height: 100%; }
|
|
|
+ html, body { margin: 0; padding: 0; background: #fff; color: #333; font: 14px/1.4 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; }
|
|
|
+ .viewport { position: fixed; inset: 0 0 0 0; overflow: auto; background: #fafafa; }
|
|
|
+ .page { box-sizing: border-box; margin: 12px auto; padding: 12px; max-width: 95vw; background: #fff; border: 1px solid #eee; box-shadow: 0 2px 6px rgba(0,0,0,.04); }
|
|
|
+ .title { font-weight: 600; margin: 0 0 8px 0; font-size: 14px; color: #222; text-align: center; }
|
|
|
+ .canvas { position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; background: #fff; }
|
|
|
+ .canvas img { display: block; max-width: 100%; max-height: calc(100vh - 160px); transform-origin: center center; image-rendering: auto; }
|
|
|
+ .hint { color: #999; font-size: 12px; margin-left: auto; }
|
|
|
+ /* 屏幕预览时隐藏内容,直接弹出打印,不让用户看到页面 */
|
|
|
+ @media screen { body { opacity: 0; } }
|
|
|
+ @media print {
|
|
|
+ .viewport { position: static; }
|
|
|
+ .viewport { overflow: visible; }
|
|
|
+ .page { page-break-after: always; border: none; box-shadow: none; margin: 0; padding: 10mm 10mm 0 10mm; max-width: 100%; }
|
|
|
+ .title { margin-bottom: 6mm; font-size: 12pt; }
|
|
|
+ .canvas img { max-height: none; width: 100%; }
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body>
|
|
|
+ <div class="viewport" id="viewport">
|
|
|
+ ${items.map((it, i) => `
|
|
|
+ <div class="page">
|
|
|
+ <h3 class="title">${escapeHtml(it.name)}</h3>
|
|
|
+ <div class="canvas"><img data-idx="${i}" src="${it.url}" /></div>
|
|
|
+ </div>
|
|
|
+ `).join('')}
|
|
|
+ </div>
|
|
|
+ <script>
|
|
|
+ (function(){
|
|
|
+ function allImagesLoaded(imgs){
|
|
|
+ if (!imgs || !imgs.length) return true;
|
|
|
+ return imgs.every(function(img){ return img.complete; });
|
|
|
+ }
|
|
|
+ function triggerPrint(){
|
|
|
+ try { window.focus(); } catch(e){}
|
|
|
+ window.print();
|
|
|
+ setTimeout(function(){ try { window.close(); } catch(e){} }, 100);
|
|
|
+ }
|
|
|
+ var imgs = Array.prototype.slice.call(document.querySelectorAll('img'));
|
|
|
+ if (allImagesLoaded(imgs)) { triggerPrint(); return; }
|
|
|
+ var remain = imgs.length;
|
|
|
+ function done(){ if(--remain <= 0) triggerPrint(); }
|
|
|
+ imgs.forEach(function(img){
|
|
|
+ if (img.complete) { done(); }
|
|
|
+ else {
|
|
|
+ img.addEventListener('load', done);
|
|
|
+ img.addEventListener('error', done);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 兜底超时,防止某些图片不触发事件
|
|
|
+ setTimeout(triggerPrint, 3000);
|
|
|
+ })();
|
|
|
+ </script>
|
|
|
+ </body>
|
|
|
+ </html>`
|
|
|
+
|
|
|
+ win.document.open()
|
|
|
+ win.document.write(html)
|
|
|
+ win.document.close()
|
|
|
+}
|