<template> <el-row class="shipping-makeLadingBill"> <el-row> <div class="title-orderNo">{{$t('订单号')}}:{{orderNo}}</div> </el-row> <el-row class="ueditor-row"> <vue-ueditor-wrap v-model="billContent" :config="editorConfig" editor-id="billUeditor" /> </el-row> <!-- 审核流程 --> <el-row class="process-area"> <div class="process"> <div>{{$t('审批流程')}}</div> <work-flow xmlkey="bill_lading" v-model="selectedUsers"></work-flow> </div> <div v-if="currRow.status === 1"> <el-button type="primary" @click="jumpReviewDetail">{{$t('审核中')}}</el-button> <el-button plain type="primary" @click="canclAudit">{{$t('取消审核')}}</el-button> <el-button plain type="primary" @click="showLoaingTemplate">{{$t('提单预览')}}</el-button> </div> <div v-if="currRow.status !== 1"> <el-button type="primary" @click="createPdf">{{$t('提交审核')}}</el-button> <el-button type="primary" @click="showLoaingTemplate">{{$t('提单预览')}}</el-button> </div> </el-row> <!-- htm2canvas 容器 --> <div style="height:0; overflow: hidden;"> <div id="html2canvas-container" v-html="billContent"></div> </div> <el-dialog :title="dialogCfg.title" :visible.sync="visible" width="1000px" append-to-body class="shippingSea-dialog"> <previewBill v-if="visible" :contentHtml="billContent" :currRow="currRow" :type="dialogCfg.type" /> </el-dialog> </el-row> </template> <script> import VueUeditorWrap from "vue-ueditor-wrap"; import WorkFlow from "@/components/WorkFlow"; import { createBillService, updateBillService, cancelBillService, } from "@/api/ecw/box"; import { serviceMsg, toReviewDetail } from "../shippingSea/utils"; import previewBill from "./previewBill.vue"; import { getToken } from "@/utils/auth"; import html2canvas from 'html2canvas'; import { jsPDF } from "jspdf"; import {uploadFile} from '@/api/infra/file' import FileSaver from 'file-saver' import {getOrder, getOrderDetail} from "@/api/ecw/order"; window.html2canvas = html2canvas export default { name: "makeLadingBill", components: { VueUeditorWrap, WorkFlow, previewBill, }, props: { currData: Object, currRow: Object, dialogCfg: Object, selfNo: String }, data() { return { orderNo: "", billContent: "", editorConfig: { UEDITOR_HOME_URL: "/static/plugins/ueditor/", autoHeightEnabled: false, initialFrameHeight: 500, initialFrameWidth: "100%", zIndex: 9999, toolbars: [ [ "anchor", //锚点 "undo", //撤销 "redo", //重做 "bold", //加粗 "indent", //首行缩进 //"snapscreen", //截图 "italic", //斜体 "underline", //下划线 "strikethrough", //删除线 "subscript", //下标 "fontborder", //字符边框 "superscript", //上标 "formatmatch", //格式刷 "source", //源代码 "blockquote", //引用 "pasteplain", //纯文本粘贴模式 "selectall", //全选 "preview", //预览 "horizontal", //分隔线 "removeformat", //清除格式 //"time", //时间 //"date", //日期 //"unlink", //取消链接 "insertrow", //前插入行 "insertcol", //前插入列 "mergeright", //右合并单元格 "mergedown", //下合并单元格 "deleterow", //删除行 "deletecol", //删除列 "splittorows", //拆分成行 "splittocols", //拆分成列 "splittocells", //完全拆分单元格 "deletecaption", //删除表格标题 "inserttitle", //插入标题 "mergecells", //合并多个单元格 "deletetable", //删除表格 "cleardoc", //清空文档 "insertparagraphbeforetable", //this.$t("表格前插入行") //"insertcode", //代码语言 "fontfamily", //字体 "fontsize", //字号 "paragraph", //段落格式 "simpleupload", //单图上传 "insertimage", //多图上传 "edittable", //表格属性 "edittd", //单元格属性 //"link", //超链接 //"emotion", //表情 "spechars", //特殊字符 //"searchreplace", //查询替换 //"insertvideo", //视频 "justifyleft", //居左对齐 "justifyright", //居右对齐 "justifycenter", //居中对齐 "justifyjustify", //两端对齐 "forecolor", //字体颜色 "backcolor", //背景色 "insertorderedlist", //有序列表 "insertunorderedlist", //无序列表 "fullscreen", //全屏 "directionalityltr", //从左向右输入 "directionalityrtl", //从右向左输入 "rowspacingtop", //段前距 "rowspacingbottom", //段后距 "pagebreak", //分页 //"insertframe", //插入Iframe "imagenone", //默认 "imageleft", //左浮动 "imageright", //右浮动 //"attachment", //附件 "imagecenter", //居中 "wordimage", //图片转存 "lineheight", //行间距 //"edittip ", //编辑提示 "customstyle", //自定义标题 "autotypeset", //自动排版 //"touppercase", //字母大写 //"tolowercase", //字母小写 "background", //背景 //"scrawl", //涂鸦 //"music", //音乐 "inserttable", //插入表格 "drafts", // 从草稿箱加载 //"charts", // 图表 ], ], serverUrl: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/editor?api_token=" + getToken().replace("Bearer ", ""), }, visible: false, selectedUsers: [], }; }, methods: { showLoaingTemplate() { this.visible = true; }, // 先获取订单信息,pdf用 订单号+唛头命名 createPdf(){ // 空运的由接口生成pdf,所以直接提交即可 if(this.$route.fullPath.toLowerCase().indexOf('air') > -1){ return this.submit() } getOrder(this.currRow.orderId).then(res => { this.afterCreatePdf(res.data) }) }, afterCreatePdf(orderData){ let loading = this.$loading() html2canvas(document.querySelector("#html2canvas-container"), {dpi:144, useCORS: true}).then(canvas => { const doc = new jsPDF('p','pt','a4',true); const imgWidth = canvas.width const imgHeight = canvas.height console.log(imgHeight, imgWidth) let _w = 595.28; let _h = 595.28/imgWidth*imgHeight; if(_h>841.89){ _h = 841.89; _w = _h/imgHeight*imgWidth } const _left = (595.28-_w)/2; doc.addImage(canvas, 'PNG', _left, 0, _w,_h, '', 'FAST'); /* doc.save("a4.pdf"); return Promise.reject() */ let form = new FormData() let file = this.selfNo + "-" + this.currRow.tidanNo + ' ' + orderData.marks + '.pdf' //this.selfNo + '-' + this.currRow.tidanNo + '.pdf' form.append('file', new File([doc.output('arraybuffer')], file, {type: 'application/pdf'})) form.append('path', `admin/shipment/${this.selfNo}/pdf/${file}`) // 最前面不能有/,否则返回的url会有两个/ /* let blob = new Blob([doc.output('arraybuffer')], {type: "application/pdf"}) FileSaver.saveAs(blob, file); return */ return uploadFile(form) }).then(res => { return this.submit(res.data) }).finally(res => { loading.close() }) }, submit(imgUrl) { let params = { billContent: this.billContent, orderId: this.currRow.orderId, copyUserId: this.selectedUsers, }; // 有pdf地址则提交,没有则指定后端生成 if(imgUrl){ params.imgUrl = imgUrl }else{ params.needBackend = true } if (["makeBill", "resetBill"].includes(this.dialogCfg.type)) { createBillService({ ...params, status: 1 }).then((res) => { serviceMsg(res, this).then((res) => { this.close("query"); }); }); } else { updateBillService({ ...params, id: this.currRow.id, status: 1, }).then((res) => { serviceMsg(res, this).then((res) => { this.close("query"); }); }); } }, /* 取消审核 */ canclAudit() { cancelBillService(this.currRow.id).then((res) => { serviceMsg(res, this).then(() => { this.close("query"); }); }); }, close(type) { this.$emit("closeDialog", type); }, jumpReviewDetail() { this.close('close') const { bpmProcessId } = this.currData; toReviewDetail.apply(this, [bpmProcessId]); }, }, watch: { currData: { immediate: true, handler(val) { this.billContent = val?.billContent ?? ""; this.orderNo = val.orderNo; }, }, }, }; </script> <style lang="scss" scoped> ::v-deep #html2canvas-container{ padding: 3rem; word-break:initial; p{ margin: 0; } td{ word-break:initial; } } .shipping-makeLadingBill { .title-orderNo { text-align: center; font-size: 18px; font-weight: normal; margin-bottom: 10px; } .process-area { margin-top: 15px; .process { display: flex; flex-direction: column; > :first-child { color: #606266; font-weight: bolder; font-size: 16px; } } > :last-child { text-align: center; } } .ueditor-row { display: flex; justify-content: center; } } .shippingSea-dialog{ ::v-deep .el-dialog__body{ padding-top: 0; } } </style>