diff --git a/src/api/bpm/processInstance/index.ts b/src/api/bpm/processInstance/index.ts index a0f263de..9a99a91e 100644 --- a/src/api/bpm/processInstance/index.ts +++ b/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 } // 审批节点信息 diff --git a/src/utils/download.ts b/src/utils/download.ts index 5bbfb9fe..bd58845f 100644 --- a/src/utils/download.ts +++ b/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 } } diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue index a4ecee65..402644e9 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue @@ -47,15 +47,15 @@ 点击签名 @@ -553,11 +553,11 @@ const signRef = ref() const approveSignFormRef = ref() const approveReasonForm = reactive({ reason: '', - sign: '' + signPicUrl: '' }) const approveReasonRule = reactive>({ reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }], - sign: [{ required: true, message: '签名不能为空', trigger: 'change' }] + signPicUrl: [{ required: true, message: '签名不能为空', trigger: 'change' }] }) // 拒绝表单 const rejectFormRef = ref() @@ -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') } diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue index 1fd31dcf..fcd5ec89 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue @@ -124,14 +124,14 @@ 审批意见:{{ task.reason }}
签名:
diff --git a/src/views/bpm/processInstance/detail/SignDialog.vue b/src/views/bpm/processInstance/detail/SignDialog.vue index 211cfcda..744a3556 100644 --- a/src/views/bpm/processInstance/detail/SignDialog.vue +++ b/src/views/bpm/processInstance/detail/SignDialog.vue @@ -2,9 +2,8 @@
- 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 -}