Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
04f4f630
authored
Jan 09, 2025
by
Lesan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 完善UserTask审批签名
parent
dd72d35f
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
1 deletions
+117
-1
src/api/bpm/processInstance/index.ts
+1
-0
src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue
+23
-1
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
+9
-0
src/views/bpm/processInstance/detail/SignDialog.vue
+84
-0
No files found.
src/api/bpm/processInstance/index.ts
View file @
04f4f630
...
@@ -36,6 +36,7 @@ export type ApprovalTaskInfo = {
...
@@ -36,6 +36,7 @@ export type ApprovalTaskInfo = {
assigneeUser
:
User
assigneeUser
:
User
status
:
number
status
:
number
reason
:
string
reason
:
string
sign
:
string
}
}
// 审批节点信息
// 审批节点信息
...
...
src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue
View file @
04f4f630
...
@@ -44,6 +44,12 @@
...
@@ -44,6 +44,12 @@
:rows=
"4"
:rows=
"4"
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
v-if=
"runningTask.signEnable"
label=
"签名"
prop=
"sign"
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]"
/>
</el-form-item>
<el-form-item>
<el-form-item>
<el-button
:disabled=
"formLoading"
type=
"success"
@
click=
"handleAudit(true, approveFormRef)"
>
<el-button
:disabled=
"formLoading"
type=
"success"
@
click=
"handleAudit(true, approveFormRef)"
>
{{ getButtonDisplayName(OperationButtonType.APPROVE) }}
{{ getButtonDisplayName(OperationButtonType.APPROVE) }}
...
@@ -471,6 +477,8 @@
...
@@ -471,6 +477,8 @@
<Icon
:size=
"14"
icon=
"ep:refresh"
/>
再次提交
<Icon
:size=
"14"
icon=
"ep:refresh"
/>
再次提交
</div>
</div>
</div>
</div>
<SignDialog
ref=
"signRef"
@
success=
"handleSignFinish"
/>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
useUserStoreWithOut
}
from
'@/store/modules/user'
import
{
useUserStoreWithOut
}
from
'@/store/modules/user'
...
@@ -484,6 +492,7 @@ import {
...
@@ -484,6 +492,7 @@ import {
}
from
'@/components/SimpleProcessDesignerV2/src/consts'
}
from
'@/components/SimpleProcessDesignerV2/src/consts'
import
{
BpmProcessInstanceStatus
,
BpmModelFormType
}
from
'@/utils/constants'
import
{
BpmProcessInstanceStatus
,
BpmModelFormType
}
from
'@/utils/constants'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
SignDialog
from
"./SignDialog.vue"
;
defineOptions
({
name
:
'ProcessInstanceBtnContainer'
})
defineOptions
({
name
:
'ProcessInstanceBtnContainer'
})
const
router
=
useRouter
()
// 路由
const
router
=
useRouter
()
// 路由
...
@@ -522,11 +531,15 @@ const approveFormFApi = ref<any>({}) // approveForms 的 fAPi
...
@@ -522,11 +531,15 @@ const approveFormFApi = ref<any>({}) // approveForms 的 fAPi
// 审批通过意见表单
// 审批通过意见表单
const
approveFormRef
=
ref
<
FormInstance
>
()
const
approveFormRef
=
ref
<
FormInstance
>
()
const
signRef
=
ref
()
const
approveSignFormRef
=
ref
()
const
approveReasonForm
=
reactive
({
const
approveReasonForm
=
reactive
({
reason
:
''
reason
:
''
,
sign
:
''
})
})
const
approveReasonRule
=
reactive
<
FormRules
<
typeof
approveReasonForm
>>
({
const
approveReasonRule
=
reactive
<
FormRules
<
typeof
approveReasonForm
>>
({
reason
:
[{
required
:
true
,
message
:
'审批意见不能为空'
,
trigger
:
'blur'
}],
reason
:
[{
required
:
true
,
message
:
'审批意见不能为空'
,
trigger
:
'blur'
}],
sign
:
[{
required
:
true
,
message
:
'签名不能为空'
,
trigger
:
'change'
}]
})
})
// 拒绝表单
// 拒绝表单
const
rejectFormRef
=
ref
<
FormInstance
>
()
const
rejectFormRef
=
ref
<
FormInstance
>
()
...
@@ -672,6 +685,10 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) =>
...
@@ -672,6 +685,10 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) =>
reason
:
approveReasonForm
.
reason
,
reason
:
approveReasonForm
.
reason
,
variables
// 审批通过, 把修改的字段值赋于流程实例变量
variables
// 审批通过, 把修改的字段值赋于流程实例变量
}
}
// 签名
if
(
runningTask
.
value
.
signEnable
)
{
data
.
sign
=
approveReasonForm
.
sign
}
// 多表单处理,并且有额外的 approveForm 表单,需要校验 + 拼接到 data 表单里提交
// 多表单处理,并且有额外的 approveForm 表单,需要校验 + 拼接到 data 表单里提交
// TODO 芋艿 任务有多表单这里要如何处理,会和可编辑的字段冲突
// TODO 芋艿 任务有多表单这里要如何处理,会和可编辑的字段冲突
const
formCreateApi
=
approveFormFApi
.
value
const
formCreateApi
=
approveFormFApi
.
value
...
@@ -966,6 +983,11 @@ const getUpdatedProcessInstanceVaiables = ()=> {
...
@@ -966,6 +983,11 @@ const getUpdatedProcessInstanceVaiables = ()=> {
return
variables
return
variables
}
}
const
handleSignFinish
=
(
url
)
=>
{
approveReasonForm
.
sign
=
url
approveSignFormRef
.
value
.
validate
(
'change'
)
}
defineExpose
({
loadTodoTask
})
defineExpose
({
loadTodoTask
})
</
script
>
</
script
>
...
...
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
View file @
04f4f630
...
@@ -123,6 +123,15 @@
...
@@ -123,6 +123,15 @@
>
>
审批意见:{{ task.reason }}
审批意见:{{ task.reason }}
</div>
</div>
<div
v-if=
"task.sign && 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]"
/>
</div>
</teleport>
</teleport>
</div>
</div>
<!-- 情况二:遍历每个审批节点下的【候选的】task 任务。例如说,1)依次审批,2)未来的审批任务等 -->
<!-- 情况二:遍历每个审批节点下的【候选的】task 任务。例如说,1)依次审批,2)未来的审批任务等 -->
...
...
src/views/bpm/processInstance/detail/SignDialog.vue
0 → 100644
View file @
04f4f630
<
template
>
<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"
/>
<el-button
style=
"position: absolute; bottom: 20px; right: 10px"
type=
"primary"
text
size=
"small"
@
click=
"signature.clear()"
>
<Icon
icon=
"ep:delete"
class=
"mr-5px"
/>
清除
</el-button>
</div>
<template
#
footer
>
<div
class=
"dialog-footer"
>
<el-button
@
click=
"signDialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"submit"
>
提交
</el-button>
</div>
</
template
>
</el-dialog>
</template>
<
script
setup
lang=
"ts"
>
import
Vue3Signature
from
"vue3-signature"
import
*
as
FileApi
from
'@/api/infra/file'
const
message
=
useMessage
()
// 消息弹窗
const
signDialogVisible
=
ref
(
false
)
const
signature
=
ref
()
const
open
=
async
()
=>
{
signDialogVisible
.
value
=
true
}
defineExpose
({
open
})
const
emits
=
defineEmits
([
'success'
])
const
submit
=
async
()
=>
{
message
.
success
(
'签名上传中请稍等。。。'
)
const
res
=
await
FileApi
.
updateFile
({
file
:
base64ToFile
(
signature
.
value
.
save
(
'image/png'
),
'签名'
)})
emits
(
'success'
,
res
.
data
)
signDialogVisible
.
value
=
false
}
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
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment