Эх сурвалжийг харах

feat: 审批签名代码评审

Lesan 7 сар өмнө
parent
commit
37964e740f

+ 1 - 1
src/api/bpm/processInstance/index.ts

@@ -36,7 +36,7 @@ export type ApprovalTaskInfo = {
   assigneeUser: User
   status: number
   reason: string
-  sign: string // TODO @lesan:字段改成 signPicUrl 签名照片。只有 sign 感觉是签名文本哈。
+  signPicUrl: string
 }
 
 // 审批节点信息

+ 27 - 0
src/utils/download.ts

@@ -65,6 +65,33 @@ const download = {
       a.download = 'image.png'
       a.click()
     }
+  },
+  base64ToFile: (base64, fileName) => {
+    // 将base64按照 , 进行分割 将前缀  与后续内容分隔开
+    const data = base64.split(',')
+    // 利用正则表达式 从前缀中获取图片的类型信息(image/png、image/jpeg、image/webp等)
+    const type = data[0].match(/:(.*?);/)[1]
+    // 从图片的类型信息中 获取具体的文件格式后缀(png、jpeg、webp)
+    const suffix = type.split('/')[1]
+    // 使用atob()对base64数据进行解码  结果是一个文件数据流 以字符串的格式输出
+    const bstr = window.atob(data[1])
+    // 获取解码结果字符串的长度
+    let n = bstr.length
+    // 根据解码结果字符串的长度创建一个等长的整形数字数组
+    // 但在创建时 所有元素初始值都为 0
+    const u8arr = new Uint8Array(n)
+    // 将整形数组的每个元素填充为解码结果字符串对应位置字符的UTF-16 编码单元
+    while (n--) {
+      // charCodeAt():获取给定索引处字符对应的 UTF-16 代码单元
+      u8arr[n] = bstr.charCodeAt(n)
+    }
+    // 利用构造函数创建File文件对象
+    // new File(bits, name, options)
+    const file = new File([u8arr], `${fileName}.${suffix}`, {
+      type: type
+    })
+    // 将File文件对象返回给方法的调用者
+    return file
   }
 }
 

+ 8 - 8
src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue

@@ -47,15 +47,15 @@
           <el-form-item
             v-if="runningTask.signEnable"
             label="签名"
-            prop="sign"
+            prop="signPicUrl"
             ref="approveSignFormRef"
           >
             <el-button @click="signRef.open()">点击签名</el-button>
             <el-image
               class="w-90px h-40px ml-5px"
-              v-if="approveReasonForm.sign"
-              :src="approveReasonForm.sign"
-              :preview-src-list="[approveReasonForm.sign]"
+              v-if="approveReasonForm.signPicUrl"
+              :src="approveReasonForm.signPicUrl"
+              :preview-src-list="[approveReasonForm.signPicUrl]"
             />
           </el-form-item>
           <el-form-item>
@@ -553,11 +553,11 @@ const signRef = ref()
 const approveSignFormRef = ref()
 const approveReasonForm = reactive({
   reason: '',
-  sign: ''
+  signPicUrl: ''
 })
 const approveReasonRule = reactive<FormRules<typeof approveReasonForm>>({
   reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }],
-  sign: [{ required: true, message: '签名不能为空', trigger: 'change' }]
+  signPicUrl: [{ required: true, message: '签名不能为空', trigger: 'change' }]
 })
 // 拒绝表单
 const rejectFormRef = ref<FormInstance>()
@@ -705,7 +705,7 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) =>
       }
       // 签名
       if (runningTask.value.signEnable) {
-        data.sign = approveReasonForm.sign
+        data.signPicUrl = approveReasonForm.signPicUrl
       }
       // 多表单处理,并且有额外的 approveForm 表单,需要校验 + 拼接到 data 表单里提交
       // TODO 芋艿 任务有多表单这里要如何处理,会和可编辑的字段冲突
@@ -1002,7 +1002,7 @@ const getUpdatedProcessInstanceVariables = () => {
 
 /** 处理签名完成 */
 const handleSignFinish = (url: string) => {
-  approveReasonForm.sign = url
+  approveReasonForm.signPicUrl = url
   approveSignFormRef.value.validate('change')
 }
 

+ 3 - 3
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue

@@ -124,14 +124,14 @@
                 审批意见:{{ task.reason }}
               </div>
               <div
-                v-if="task.sign && activity.nodeType === NodeType.USER_TASK_NODE"
+                v-if="task.signPicUrl && activity.nodeType === NodeType.USER_TASK_NODE"
                 class="text-#a5a5a5 text-13px mt-1 w-full bg-#f8f8fa p2 rounded-md"
               >
                 签名:
                 <el-image
                   class="w-90px h-40px ml-5px"
-                  :src="task.sign"
-                  :preview-src-list="[task.sign]"
+                  :src="task.signPicUrl"
+                  :preview-src-list="[task.signPicUrl]"
                 />
               </div>
             </teleport>

+ 3 - 32
src/views/bpm/processInstance/detail/SignDialog.vue

@@ -2,9 +2,8 @@
   <el-dialog v-model="signDialogVisible" title="签名" width="935">
     <div class="position-relative">
       <Vue3Signature class="b b-solid b-gray" ref="signature" w="900px" h="400px" />
-      <!-- @lesan:建议改成 unocss 哈 -->
       <el-button
-        style="position: absolute; bottom: 20px; right: 10px"
+        class="pos-absolute bottom-20px right-10px"
         type="primary"
         text
         size="small"
@@ -26,6 +25,7 @@
 <script setup lang="ts">
 import Vue3Signature from 'vue3-signature'
 import * as FileApi from '@/api/infra/file'
+import download from '@/utils/download'
 
 const message = useMessage() // 消息弹窗
 const signDialogVisible = ref(false)
@@ -40,40 +40,11 @@ const emits = defineEmits(['success'])
 const submit = async () => {
   message.success('签名上传中请稍等。。。')
   const res = await FileApi.updateFile({
-    file: base64ToFile(signature.value.save('image/png'), '签名')
+    file: download.base64ToFile(signature.value.save('image/png'), '签名')
   })
   emits('success', res.data)
   signDialogVisible.value = false
 }
-
-// TODO @lesan:这个要不抽到 download.js 里,让这个组件更简洁干净?
-const base64ToFile = (base64, fileName) => {
-  // 将base64按照 , 进行分割 将前缀  与后续内容分隔开
-  let data = base64.split(',')
-  // 利用正则表达式 从前缀中获取图片的类型信息(image/png、image/jpeg、image/webp等)
-  let type = data[0].match(/:(.*?);/)[1]
-  // 从图片的类型信息中 获取具体的文件格式后缀(png、jpeg、webp)
-  let suffix = type.split('/')[1]
-  // 使用atob()对base64数据进行解码  结果是一个文件数据流 以字符串的格式输出
-  const bstr = window.atob(data[1])
-  // 获取解码结果字符串的长度
-  let n = bstr.length
-  // 根据解码结果字符串的长度创建一个等长的整形数字数组
-  // 但在创建时 所有元素初始值都为 0
-  const u8arr = new Uint8Array(n)
-  // 将整形数组的每个元素填充为解码结果字符串对应位置字符的UTF-16 编码单元
-  while (n--) {
-    // charCodeAt():获取给定索引处字符对应的 UTF-16 代码单元
-    u8arr[n] = bstr.charCodeAt(n)
-  }
-  // 利用构造函数创建File文件对象
-  // new File(bits, name, options)
-  const file = new File([u8arr], `${fileName}.${suffix}`, {
-    type: type
-  })
-  // 将File文件对象返回给方法的调用者
-  return file
-}
 </script>
 
 <style scoped></style>