Jelajahi Sumber

feat: 添加文档编辑加入签名功能

johnsen 1 Minggu lalu
induk
melakukan
a1a970d7b8
1 mengubah file dengan 155 tambahan dan 3 penghapusan
  1. 155 3
      src/business/platform/file/attachment/editFile/editor.vue

+ 155 - 3
src/business/platform/file/attachment/editFile/editor.vue

@@ -1,11 +1,25 @@
 <!--onlyoffice 编辑器-->
 <template>
-  <div id="editorDiv" ref="editor" class="nav" />
+  <div class="onlyoffice-editor">
+    <div class="title">
+      <span>文件编辑</span>
+      <el-button
+        v-if="imgUrl"
+        size="mini"
+        type="primary"
+        @click="insertResizedSignature"
+        >加入签名</el-button
+      >
+    </div>
+    <div class="editor-container">
+      <div id="editorDiv" ref="editor" class="nav" />
+    </div>
+  </div>
 </template>
 
 <script>
 import { handleDocType } from './editor/editor.js'
-import { showView } from '@/api/platform/file/attachment'
+import { showView, getImage } from '@/api/platform/file/attachment'
 import { getToken } from '@/utils/auth'
 
 export default {
@@ -28,10 +42,13 @@ export default {
   },
   data() {
     return {
+      activeName: 'first',
       doctype: '',
       newId: '',
       timer: '',
-      configKey: ''
+      configKey: '',
+      docEditor: null,
+      imgUrl: ''
     }
   },
   watch: {
@@ -44,6 +61,23 @@ export default {
     }
   },
   mounted() {
+    // console.log()
+    this.$common
+      .request('query', {
+        key: 'getSigImgByUid',
+        params: [this.$store.getters.userId]
+      })
+      .then((res) => {
+        const [imgObj] = res.variables.data
+        if (!imgObj) {
+          this.$message.error(
+            '当前用户签名图片不存在请在个人信息维护中上传签字图文!'
+          )
+          return false
+        }
+        const imgUrl = getImage(imgObj.qian_zi_tu_wen_)
+        this.imgUrl = imgUrl
+      })
     // 调用初始化方法 ,渲染wps
     if (this.option.url) {
       this.setEditor(this.option)
@@ -72,6 +106,86 @@ export default {
     this.clearTimer()
   },
   methods: {
+    resizeImageToBase64(url, maxWidthMm, maxHeightMm) {
+      return new Promise((resolve, reject) => {
+        const img = new Image()
+        // 若图片在服务端且域名不同,需要设置 crossOrigin
+        img.crossOrigin = 'Anonymous'
+
+        img.onload = () => {
+          // 定义缩放基准:1毫米 = 3.779像素(约等于屏幕的DPI)
+          // 目标宽度(毫米转像素)
+          let targetWidthPx = maxWidthMm * 3.779
+          let targetHeightPx = maxHeightMm * 3.779
+
+          // 计算原图和目标尺寸的比例
+          let ratioX = targetWidthPx / img.width
+          let ratioY = targetHeightPx / img.height
+          // 取较小的比例,确保图片整体能够完整地放入目标框内(等比缩放模式)
+          let finalRatio = Math.min(ratioX, ratioY)
+
+          // 计算最终绘制到 canvas 上的尺寸
+          let finalWidth = img.width * finalRatio
+          let finalHeight = img.height * finalRatio
+
+          // 创建 canvas 并设置尺寸
+          const canvas = document.createElement('canvas')
+          canvas.width = finalWidth
+          canvas.height = finalHeight
+
+          // 获取绘图上下文,并开启图像平滑以提高缩放质量
+          const ctx = canvas.getContext('2d')
+          ctx.imageSmoothingEnabled = true
+          ctx.imageSmoothingQuality = 'high'
+
+          // 关键步骤:将原图绘制到 canvas 上,完成缩放
+          ctx.drawImage(img, 0, 0, finalWidth, finalHeight)
+
+          // 将 canvas 内容导出为 Base64 格式的 PNG 图片
+          const resizedBase64 = canvas.toDataURL('image/png')
+          resolve(resizedBase64)
+        }
+
+        img.onerror = (err) => reject(err)
+        img.src = url
+      })
+    },
+
+    // 2. 整合函数:缩放后再插入
+    async insertResizedSignature() {
+      if (!this.imgUrl) {
+        this.$message.error('签名图片不存在,请在个人信息维护中上传!')
+        return
+      }
+      if (!this.docEditor) {
+        this.$message.error('编辑器未就绪')
+        return
+      }
+
+      try {
+        // 等待图片缩放完成,这里设置的目标宽度和高度为 100 毫米 x 50 毫米
+        // 你可以根据实际需求调整这两个数字
+        const resizedBase64 = await this.resizeImageToBase64(
+          this.imgUrl,
+          20,
+          10
+        )
+
+        // 调用你原有的插入方法,此时插入的是缩放后的 Base64 图片
+        this.docEditor.insertImage({
+          c: 'add',
+          images: [
+            {
+              fileType: 'png',
+              url: resizedBase64 // 使用缩放后的 Base64 图片
+            }
+          ]
+        })
+      } catch (error) {
+        console.error('处理或插入签名失败:', error)
+        this.$message.error('处理或插入签名失败,请检查图片地址')
+      }
+    },
     // 清除定时任务
     clearTimer() {
       if (this.timer) {
@@ -148,6 +262,7 @@ export default {
         height: document.body.clientHeight - 63 + 'px'
       }
       const docEditor = new DocsAPI.DocEditor('editorDiv', config)
+      this.docEditor = docEditor
       this.configKey = config.document.key
     },
     handlerFileSave() {
@@ -176,3 +291,40 @@ export default {
   }
 }
 </script>
+<style lang="scss" scoped>
+.onlyoffice-editor {
+  box-sizing: border-box;
+  padding: 8px;
+  height: 100%;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  border-radius: 12px;
+  border: 1px solid #e4e7ed;
+  box-shadow: inset 0px -1px 0px #e4e7ed;
+  .title {
+    margin-bottom: 0;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom: #e4e7ed 1px solid;
+    span {
+      font-size: 16px;
+      color: #409eff;
+      // line-height: 20px;
+      &::after {
+        content: '';
+        display: block;
+        width: 100%;
+        height: 2px;
+        background-color: #409eff;
+        // margin-left: 12px;
+      }
+    }
+  }
+  .editor-container {
+    padding: 8px;
+    flex: 1;
+  }
+}
+</style>