Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
zrch-risk-39
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Administrator
zrch-risk-39
Commits
78599ce5
提交
78599ce5
authored
3月 29, 2026
作者:
kxjia
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
问题模块
上级
ca1f544f
全部展开
显示空白字符变更
内嵌
并排
正在显示
22 个修改的文件
包含
1115 行增加
和
388 行删除
+1115
-388
definition.js
zrch-risk-client-39/src/components/Process/api/definition.js
+0
-1
ApprovalPanel.vue
zrch-risk-client-39/src/views/common/ApprovalPanel.vue
+0
-0
CurrentFormPanel.vue
zrch-risk-client-39/src/views/common/CurrentFormPanel.vue
+334
-0
HistoryPanel.vue
zrch-risk-client-39/src/views/common/HistoryPanel.vue
+386
-0
TaskAssigneeDrawer.vue
zrch-risk-client-39/src/views/common/TaskAssigneeDrawer.vue
+257
-0
TaskAssigneeSelector.vue
...-risk-client-39/src/views/common/TaskAssigneeSelector.vue
+0
-0
WorkFlowForm.vue
zrch-risk-client-39/src/views/common/WorkFlowForm.vue
+0
-302
WorkFlowFormApprovalDrawer.vue
...client-39/src/views/common/WorkFlowFormApprovalDrawer.vue
+0
-0
WorkFlowFormDrawer.vue
zrch-risk-client-39/src/views/common/WorkFlowFormDrawer.vue
+0
-0
ShowFormModal.vue
...t-39/src/views/flowable/task/components/ShowFormModal.vue
+0
-0
TodoIndex.vue
...-39/src/views/flowable/task/todo/components/TodoIndex.vue
+1
-1
StProblemArchiveList.vue
...9/src/views/project/problemCheck/StProblemArchiveList.vue
+17
-8
StProblemCheck.data.ts
...-39/src/views/project/problemCheck/StProblemCheck.data.ts
+2
-1
StProblemCheckList.vue
...-39/src/views/project/problemCheck/StProblemCheckList.vue
+16
-40
StProblemExecApprovalList.vue
.../views/project/problemCheck/StProblemExecApprovalList.vue
+3
-6
StProblemExecList.vue
...t-39/src/views/project/problemCheck/StProblemExecList.vue
+4
-6
StProblemIndex.vue
...ient-39/src/views/project/problemCheck/StProblemIndex.vue
+95
-23
StProblemPlanApprovalList.vue
.../views/project/problemCheck/StProblemPlanApprovalList.vue
+0
-0
StProblemPlanList.vue
...t-39/src/views/project/problemCheck/StProblemPlanList.vue
+0
-0
StProblemCheckForm.vue
...ws/project/problemCheck/components/StProblemCheckForm.vue
+0
-0
StProblemCheckModal.vue
...s/project/problemCheck/components/StProblemCheckModal.vue
+0
-0
StProblemCheckPlanForm.vue
...roject/problemCheck/components/StProblemCheckPlanForm.vue
+0
-0
没有找到文件。
zrch-risk-client-39/src/components/Process/api/definition.js
浏览文件 @
78599ce5
...
...
@@ -14,7 +14,6 @@ export const listDefinition = async (params) => {
// 部署流程实例
export
function
definitionStart
(
procDefId
,
data
)
{
alert
(
JSON
.
stringify
(
procDefId
))
return
defHttp
.
post
({
url
:
'/flowable/definition/startByProcDefId'
,
data
:
{
...
...
zrch-risk-client-39/src/views/common/ApprovalPanel.vue
0 → 100644
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/common/CurrentFormPanel.vue
0 → 100644
浏览文件 @
78599ce5
<!-- CurrentFormPanel.vue -->
<
template
>
<div
class=
"form-panel"
>
<div
class=
"form-header"
>
<span
class=
"form-title"
>
当前待办
</span>
<a-tag
color=
"green"
v-if=
"editableNode"
>
可编辑
</a-tag>
</div>
<div
class=
"form-content"
v-if=
"editableNode"
>
<a-card
:title=
"editableNode.name"
:bordered=
"false"
class=
"current-form-card"
>
<template
#
extra
>
<a-tag
color=
"processing"
>
待处理
</a-tag>
</
template
>
<component
:is=
"getComponent(editableNode.formUrl || editableNode.formListUrl)"
:ref=
"(el) => setFormRef(el, editableNode.id)"
:disabled=
"false"
:readonly=
"false"
:form-data=
"formData"
:current-flow-node=
"editableNode"
@
update:form-data=
"handleFormDataUpdate"
/>
</a-card>
</div>
<div
v-else
class=
"empty-form-state"
>
<a-empty
description=
"未找到可编辑的表单节点"
/>
</div>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
,
defineAsyncComponent
,
h
,
watch
,
ComponentPublicInstance
,
nextTick
}
from
'vue'
interface
WorkflowNode
{
id
:
string
name
:
string
formUrl
?:
string
formListUrl
?:
string
[
key
:
string
]:
any
}
// 表单组件实例类型
interface
FormComponentInstance
extends
ComponentPublicInstance
{
validate
?:
()
=>
Promise
<
any
>
getFormData
?:
()
=>
any
initFormData
?:
(
dataId
:
string
)
=>
Promise
<
void
>
|
void
formData
?:
any
[
key
:
string
]:
any
}
const
props
=
defineProps
({
editableNode
:
{
type
:
Object
as
()
=>
WorkflowNode
|
null
,
default
:
null
},
dataId
:
{
type
:
String
,
default
:
''
},
externalFormData
:
{
type
:
Object
as
()
=>
Record
<
string
,
any
>
,
default
:
()
=>
({})
}
})
const
emit
=
defineEmits
([
'update:form-data'
,
'form-mounted'
])
// 组件缓存
const
componentCache
=
new
Map
()
const
modules
=
import
.
meta
.
glob
(
'@/views/**/*.vue'
)
// 表单组件实例
const
formComponentRef
=
ref
<
FormComponentInstance
|
null
>
(
null
)
const
formData
=
ref
<
any
>
({})
// 设置表单组件 ref
function
setFormRef
(
el
:
any
,
nodeId
:
string
)
{
if
(
el
)
{
formComponentRef
.
value
=
el
emit
(
'form-mounted'
,
{
nodeId
,
instance
:
el
})
callInitFormData
(
el
)
}
}
// 调用 initFormData
async
function
callInitFormData
(
formComponent
:
FormComponentInstance
)
{
if
(
!
props
.
dataId
)
return
if
(
!
formComponent
)
return
if
(
typeof
formComponent
.
initFormData
===
'function'
)
{
try
{
await
formComponent
.
initFormData
(
props
.
dataId
)
}
catch
(
error
)
{
console
.
error
(
'initFormData 调用失败:'
,
error
)
}
}
}
// 处理表单数据更新
function
handleFormDataUpdate
(
data
:
any
)
{
formData
.
value
=
{
...
formData
.
value
,
...
data
}
emit
(
'update:form-data'
,
formData
.
value
)
}
// 获取当前表单实例
function
getFormInstance
():
FormComponentInstance
|
null
{
return
formComponentRef
.
value
}
// 获取表单数据
async
function
getFormData
():
Promise
<
any
>
{
const
formComponent
=
formComponentRef
.
value
if
(
!
formComponent
)
{
return
formData
.
value
}
if
(
typeof
formComponent
.
getFormData
===
'function'
)
{
try
{
const
data
=
await
formComponent
.
getFormData
()
return
data
}
catch
(
error
)
{
console
.
error
(
'调用 getFormData 失败:'
,
error
)
}
}
if
(
formComponent
.
formData
!==
undefined
)
{
return
formComponent
.
formData
}
return
formData
.
value
}
// 验证表单
async
function
validateForm
():
Promise
<
boolean
>
{
const
formComponent
=
formComponentRef
.
value
if
(
!
formComponent
)
{
return
true
}
if
(
typeof
formComponent
.
validate
===
'function'
)
{
try
{
await
formComponent
.
validate
()
return
true
}
catch
(
error
)
{
return
false
}
}
return
true
}
// 重置表单数据
function
resetFormData
()
{
if
(
props
.
editableNode
&&
props
.
externalFormData
[
props
.
editableNode
.
id
])
{
formData
.
value
=
{
...
props
.
externalFormData
[
props
.
editableNode
.
id
]
}
}
else
{
formData
.
value
=
{}
}
}
// 重新加载表单数据
async
function
reloadFormData
()
{
if
(
formComponentRef
.
value
&&
typeof
formComponentRef
.
value
.
initFormData
===
'function'
)
{
await
formComponentRef
.
value
.
initFormData
(
props
.
dataId
)
}
}
// 监听 dataId 变化
watch
(()
=>
props
.
dataId
,
async
()
=>
{
if
(
formComponentRef
.
value
)
{
await
nextTick
()
await
reloadFormData
()
}
})
// 监听外部数据变化
watch
(()
=>
props
.
externalFormData
,
(
newData
)
=>
{
if
(
newData
&&
props
.
editableNode
&&
newData
[
props
.
editableNode
.
id
])
{
formData
.
value
=
newData
[
props
.
editableNode
.
id
]
}
},
{
deep
:
true
})
// 监听可编辑节点变化
watch
(()
=>
props
.
editableNode
,
()
=>
{
resetFormData
()
})
function
getComponent
(
url
:
string
)
{
if
(
!
url
)
{
return
createEmptyComponent
()
}
if
(
componentCache
.
has
(
url
))
{
return
componentCache
.
get
(
url
)
}
let
componentPath
=
''
if
(
url
.
includes
(
'/views'
))
{
componentPath
=
`/src
${
url
}
`
}
else
{
componentPath
=
`/src/views
${
url
}
`
}
if
(
!
componentPath
.
match
(
/
\.(
vue|js|ts|jsx|tsx
)
$/
))
{
componentPath
+=
'.vue'
}
const
loader
=
modules
[
componentPath
]
if
(
!
loader
)
{
console
.
error
(
'未找到组件:'
,
componentPath
)
const
ErrorComponent
=
createErrorComponent
(
`组件未找到:
${
componentPath
}
`
)
componentCache
.
set
(
url
,
ErrorComponent
)
return
ErrorComponent
}
const
AsyncComponent
=
defineAsyncComponent
({
loader
:
()
=>
loader
()
as
Promise
<
{
default
:
any
}
>
,
loadingComponent
:
{
render
:
()
=>
h
(
'div'
,
{
style
:
'text-align: center; padding: 20px;'
},
'加载中...'
)
},
errorComponent
:
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: red; padding: 20px;'
},
'组件加载失败'
)
},
delay
:
200
,
timeout
:
3000
})
componentCache
.
set
(
url
,
AsyncComponent
)
return
AsyncComponent
}
function
createEmptyComponent
()
{
return
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: #999; padding: 20px; text-align: center;'
},
'该节点未配置表单'
)
}
}
function
createErrorComponent
(
msg
:
string
)
{
return
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: red; padding: 20px;'
},
msg
)
}
}
// 暴露方法给父组件
defineExpose
({
getFormData
,
validateForm
,
getFormInstance
,
resetFormData
,
reloadFormData
})
</
script
>
<
style
scoped
lang=
"scss"
>
.form-panel
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
overflow
:
hidden
;
background-color
:
#fff
;
.form-header
{
padding
:
16px
24px
;
border-bottom
:
1px
solid
#e8eef2
;
background-color
:
#fff
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
flex-shrink
:
0
;
.form-title
{
font-size
:
16px
;
font-weight
:
500
;
color
:
#1f2f3d
;
}
}
.form-content
{
flex
:
1
;
overflow-y
:
auto
;
padding
:
24px
;
&
:
:-
webkit-scrollbar
{
width
:
6px
;
}
&
:
:-
webkit-scrollbar-track
{
background
:
#f1f1f1
;
border-radius
:
3px
;
}
&
:
:-
webkit-scrollbar-thumb
{
background
:
#c1c1c1
;
border-radius
:
3px
;
&
:hover
{
background
:
#a8a8a8
;
}
}
}
.current-form-card
{
border-radius
:
8px
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0
.06
);
border
:
1px
solid
#e8eef2
;
:deep
(
.ant-card-head
)
{
background-color
:
#fafbfc
;
border-bottom
:
1px
solid
#e8eef2
;
padding
:
12px
20px
;
.ant-card-head-title
{
font-size
:
15px
;
font-weight
:
500
;
color
:
#096dd9
;
}
}
:deep
(
.ant-card-body
)
{
padding
:
24px
;
}
}
.empty-form-state
{
flex
:
1
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
}
</
style
>
\ No newline at end of file
zrch-risk-client-39/src/views/common/HistoryPanel.vue
0 → 100644
浏览文件 @
78599ce5
<!-- HistoryPanel.vue -->
<
template
>
<div
class=
"history-panel"
:class=
"
{ 'empty-history': readonlyNodes.length === 0 }">
<div
class=
"history-header"
>
<span
class=
"history-title"
>
历史节点
</span>
<a-tag
color=
"blue"
v-if=
"readonlyNodes.length > 0"
>
{{
readonlyNodes
.
length
}}
个节点
</a-tag>
</div>
<div
class=
"history-content"
:class=
"
{ 'has-scroll': readonlyNodes.length > 3 }">
<div
v-if=
"readonlyNodes.length === 0"
class=
"empty-history-state"
>
<a-empty
description=
"暂无历史节点"
:image=
"simpleImage"
/>
</div>
<a-timeline
v-else
>
<a-timeline-item
v-for=
"(node, index) in readonlyNodes"
:key=
"node.id"
:color=
"index === readonlyNodes.length - 1 ? 'blue' : 'gray'"
>
<template
#
dot
>
<div
class=
"timeline-dot"
>
<check-circle-outlined
v-if=
"index
<
readonlyNodes
.
length
-
1
"
/>
<clock-circle-outlined
v-else
/>
</div>
</
template
>
<a-card
:title=
"node.name"
:bordered=
"false"
size=
"small"
class=
"history-card"
:class=
"{ 'last-card': index === readonlyNodes.length - 1 }"
>
<
template
#
extra
>
<a-tag
:color=
"index === readonlyNodes.length - 1 ? 'orange' : 'green'"
size=
"small"
>
{{
index
===
readonlyNodes
.
length
-
1
?
'已通过'
:
'已完成'
}}
</a-tag>
</
template
>
<div
class=
"history-card-content"
>
<div
class=
"node-info"
>
<span
class=
"node-label"
>
表单名称:
</span>
<span
class=
"node-value"
>
{{ node.formName || node.name }}
</span>
</div>
<div
class=
"node-info"
>
<span
class=
"node-label"
>
处理时间:
</span>
<span
class=
"node-value"
>
{{ node.processTime || '--' }}
</span>
</div>
<div
class=
"node-info"
>
<span
class=
"node-label"
>
处理人:
</span>
<span
class=
"node-value"
>
{{ node.processor || '--' }}
</span>
</div>
<div
class=
"node-info"
>
<span
class=
"node-label"
>
审批意见:
</span>
<span
class=
"node-value"
>
{{ node.comment || '无' }}
</span>
</div>
</div>
<!-- 如果需要显示历史表单数据,可以展开 -->
<
template
v-if=
"showHistoryFormData"
>
<a-divider
style=
"margin: 12px 0"
/>
<div
class=
"history-form-preview"
>
<div
class=
"preview-header"
>
<span>
表单数据预览
</span>
<a-button
type=
"link"
size=
"small"
@
click=
"togglePreview(node.id)"
>
{{
expandedPreviewId
===
node
.
id
?
'收起'
:
'展开'
}}
</a-button>
</div>
<a-collapse
v-model:activeKey=
"expandedPreviewId"
:bordered=
"false"
ghost
>
<a-collapse-panel
:key=
"node.id"
:showArrow=
"false"
>
<component
:is=
"getComponent(node.formUrl)"
:disabled=
"true"
:readonly=
"true"
:form-data=
"
{ dataId: dataId }"
:formId="Number(dataId) || 2035539989"
:current-flow-node="node"
class="history-form-component"
/>
</a-collapse-panel>
</a-collapse>
</div>
</
template
>
</a-card>
</a-timeline-item>
</a-timeline>
</div>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
,
defineAsyncComponent
,
h
}
from
'vue'
import
{
CheckCircleOutlined
,
ClockCircleOutlined
}
from
'@ant-design/icons-vue'
import
{
Empty
}
from
'ant-design-vue'
interface
WorkflowNode
{
id
:
string
name
:
string
formName
?:
string
formUrl
?:
string
formListUrl
?:
string
procDefId
?:
string
dataId
?:
string
processTime
?:
string
processor
?:
string
comment
?:
string
[
key
:
string
]:
any
}
const
props
=
defineProps
({
readonlyNodes
:
{
type
:
Array
as
()
=>
WorkflowNode
[],
required
:
true
,
default
:
()
=>
[]
},
dataId
:
{
type
:
String
,
default
:
''
},
showHistoryFormData
:
{
type
:
Boolean
,
default
:
false
}
})
// 简单空状态图片
const
simpleImage
=
Empty
.
PRESENTED_IMAGE_SIMPLE
// 组件缓存
const
componentCache
=
new
Map
()
const
modules
=
import
.
meta
.
glob
(
'@/views/**/*.vue'
)
// 历史表单预览展开状态
const
expandedPreviewId
=
ref
<
string
>
(
''
)
// 切换预览展开/收起
function
togglePreview
(
nodeId
:
string
)
{
expandedPreviewId
.
value
=
expandedPreviewId
.
value
===
nodeId
?
''
:
nodeId
}
function
getComponent
(
url
:
string
)
{
if
(
!
url
)
{
return
createEmptyComponent
()
}
if
(
componentCache
.
has
(
url
))
{
return
componentCache
.
get
(
url
)
}
let
componentPath
=
''
if
(
url
.
includes
(
'/views'
))
{
componentPath
=
`/src
${
url
}
`
}
else
{
componentPath
=
`/src/views
${
url
}
`
}
if
(
!
componentPath
.
match
(
/
\.(
vue|js|ts|jsx|tsx
)
$/
))
{
componentPath
+=
'.vue'
}
const
loader
=
modules
[
componentPath
]
if
(
!
loader
)
{
console
.
error
(
'未找到组件:'
,
componentPath
)
const
ErrorComponent
=
createErrorComponent
(
`组件未找到:
${
componentPath
}
`
)
componentCache
.
set
(
url
,
ErrorComponent
)
return
ErrorComponent
}
const
AsyncComponent
=
defineAsyncComponent
({
loader
:
()
=>
loader
()
as
Promise
<
{
default
:
any
}
>
,
loadingComponent
:
{
render
:
()
=>
h
(
'div'
,
{
style
:
'text-align: center; padding: 20px;'
},
'加载中...'
)
},
errorComponent
:
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: red; padding: 20px;'
},
'组件加载失败'
)
},
delay
:
200
,
timeout
:
3000
})
componentCache
.
set
(
url
,
AsyncComponent
)
return
AsyncComponent
}
function
createEmptyComponent
()
{
return
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: #999; padding: 20px; text-align: center;'
},
'该节点未配置表单'
)
}
}
function
createErrorComponent
(
msg
:
string
)
{
return
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: red; padding: 20px;'
},
msg
)
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
.history-panel
{
width
:
50%
;
background-color
:
#f5f7fa
;
border-right
:
1px
solid
#e8eef2
;
display
:
flex
;
flex-direction
:
column
;
overflow
:
hidden
;
&
.empty-history
{
.history-content
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
}
.history-header
{
padding
:
16px
20px
;
border-bottom
:
1px
solid
#e8eef2
;
background-color
:
#fff
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
flex-shrink
:
0
;
.history-title
{
font-size
:
16px
;
font-weight
:
500
;
color
:
#1f2f3d
;
}
}
.history-content
{
flex
:
1
;
overflow-y
:
auto
;
padding
:
16px
12px
;
&
.has-scroll
{
padding-right
:
8px
;
}
&
:
:-
webkit-scrollbar
{
width
:
4px
;
}
&
:
:-
webkit-scrollbar-track
{
background
:
#e8eef2
;
border-radius
:
2px
;
}
&
:
:-
webkit-scrollbar-thumb
{
background
:
#c1c1c1
;
border-radius
:
2px
;
&
:hover
{
background
:
#a8a8a8
;
}
}
}
.empty-history-state
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
height
:
100%
;
}
:deep
(
.ant-timeline
)
{
.ant-timeline-item
{
padding-bottom
:
20px
;
}
.ant-timeline-item-tail
{
border-left-color
:
#d9d9d9
;
}
}
.timeline-dot
{
width
:
24px
;
height
:
24px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
background-color
:
#fff
;
border-radius
:
50%
;
font-size
:
14px
;
.anticon
{
font-size
:
14px
;
}
}
.history-card
{
background-color
:
#fff
;
border-radius
:
8px
;
margin-bottom
:
8px
;
box-shadow
:
0
1px
2px
rgba
(
0
,
0
,
0
,
0
.03
);
transition
:
box-shadow
0
.2s
;
&
:hover
{
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0
.08
);
}
&
.last-card
{
border-left
:
3px
solid
#1890ff
;
}
:deep
(
.ant-card-head
)
{
padding
:
12px
16px
;
min-height
:
auto
;
border-bottom
:
1px
solid
#f0f0f0
;
.ant-card-head-title
{
font-size
:
14px
;
font-weight
:
500
;
padding
:
0
;
}
.ant-card-extra
{
padding
:
0
;
}
}
:deep
(
.ant-card-body
)
{
padding
:
12px
16px
;
}
}
.history-card-content
{
.node-info
{
display
:
flex
;
margin-bottom
:
8px
;
font-size
:
13px
;
&
:last-child
{
margin-bottom
:
0
;
}
.node-label
{
width
:
70px
;
color
:
#8c8c8c
;
flex-shrink
:
0
;
}
.node-value
{
color
:
#262626
;
flex
:
1
;
word-break
:
break-all
;
}
}
}
.history-form-preview
{
margin-top
:
8px
;
.preview-header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
font-size
:
12px
;
color
:
#8c8c8c
;
}
:deep
(
.ant-collapse
)
{
background
:
transparent
;
.ant-collapse-item
{
border
:
none
;
}
.ant-collapse-content
{
border
:
none
;
background
:
#fafafa
;
border-radius
:
4px
;
margin-top
:
8px
;
}
.ant-collapse-content-box
{
padding
:
12px
;
font-size
:
12px
;
}
}
}
.history-form-component
{
:deep
(*)
{
font-size
:
12px
;
}
}
}
</
style
>
\ No newline at end of file
zrch-risk-client-39/src/views/common/TaskAssigneeDrawer.vue
0 → 100644
浏览文件 @
78599ce5
<!-- TaskAssigneeDrawer.vue -->
<
template
>
<a-drawer
:title=
"title"
:visible=
"visible"
:width=
"width"
:closable=
"true"
:mask-closable=
"maskClosable"
:destroy-on-close=
"destroyOnClose"
:footer=
"null"
@
close=
"handleClose"
class=
"task-assignee-drawer"
>
<div
class=
"drawer-content"
>
<!-- 任务分配组件 -->
<div
class=
"assignee-section"
>
<TaskAssigneeSelector
ref=
"assigneeSelectorRef"
:title=
"assigneeTitle"
:proc-def-id=
"procDefId"
:task-id=
"taskId"
:form-data=
"formData"
:initial-assignee=
"initialAssignee"
:user-type-options=
"userTypeOptions"
:required=
"required"
:next-api=
"customNextApi"
@
confirm=
"handleAssigneeConfirm"
@
success=
"handleTaskSuccess"
@
error=
"handleTaskError"
@
cancel=
"handleCancel"
/>
</div>
</div>
</a-drawer>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
ref
,
computed
,
watch
}
from
'vue'
import
{
message
}
from
'ant-design-vue'
import
TaskAssigneeSelector
from
'./TaskAssigneeSelector.vue'
interface
AssigneeData
{
userType
:
'user'
|
'role'
assignee
:
string
name
?:
string
remark
?:
string
}
const
props
=
defineProps
({
// 抽屉基础配置
visible
:
{
type
:
Boolean
,
default
:
false
},
title
:
{
type
:
String
,
default
:
'任务分配'
},
width
:
{
type
:
[
Number
,
String
],
default
:
600
},
maskClosable
:
{
type
:
Boolean
,
default
:
false
},
destroyOnClose
:
{
type
:
Boolean
,
default
:
true
},
// 任务信息
taskId
:
{
type
:
String
,
required
:
true
},
procDefId
:
{
type
:
String
,
required
:
true
},
// 表单数据
formData
:
{
type
:
Object
,
default
:
()
=>
({})
},
// 初始分配数据
initialAssignee
:
{
type
:
Object
as
()
=>
AssigneeData
|
null
,
default
:
null
},
// 分配组件配置
assigneeTitle
:
{
type
:
String
,
default
:
'选择处理人'
},
userTypeOptions
:
{
type
:
Array
as
()
=>
Array
<
{
value
:
string
;
label
:
string
}
>
,
default
:
()
=>
[
{
value
:
'user'
,
label
:
'用户'
},
{
value
:
'role'
,
label
:
'角色'
}
]
},
required
:
{
type
:
Boolean
,
default
:
true
},
// 自定义API
customNextApi
:
{
type
:
Function
,
default
:
null
}
})
const
emit
=
defineEmits
([
'update:visible'
,
'success'
,
'error'
,
'close'
,
'assignee-confirm'
])
// 状态
const
assigneeSelectorRef
=
ref
<
InstanceType
<
typeof
TaskAssigneeSelector
>
|
null
>
(
null
)
// 处理分配确认
function
handleAssigneeConfirm
(
assigneeData
:
AssigneeData
)
{
emit
(
'assignee-confirm'
,
assigneeData
)
}
// 处理任务成功
function
handleTaskSuccess
(
response
:
any
)
{
emit
(
'success'
,
response
)
// 成功后自动关闭抽屉
setTimeout
(()
=>
{
handleClose
()
},
500
)
}
// 处理任务失败
function
handleTaskError
(
error
:
any
)
{
emit
(
'error'
,
error
)
}
// 处理取消
function
handleCancel
()
{
handleClose
()
}
// 关闭抽屉
function
handleClose
()
{
emit
(
'update:visible'
,
false
)
emit
(
'close'
)
}
// 重置状态
function
resetDrawer
()
{
if
(
assigneeSelectorRef
.
value
)
{
assigneeSelectorRef
.
value
.
resetForm
()
}
}
// 监听抽屉打开/关闭
watch
(()
=>
props
.
visible
,
(
newVal
)
=>
{
if
(
!
newVal
)
{
resetDrawer
()
}
})
// 暴露方法
defineExpose
({
resetDrawer
,
getAssigneeData
:
()
=>
assigneeSelectorRef
.
value
?.
getAssigneeData
(),
submit
:
()
=>
assigneeSelectorRef
.
value
?.
handleConfirm
()
})
</
script
>
<
style
scoped
lang=
"scss"
>
.task-assignee-drawer
{
:deep
(
.ant-drawer-body
)
{
padding
:
0
;
height
:
100%
;
overflow
:
hidden
;
}
:deep
(
.ant-drawer-header
)
{
background-color
:
#f5f7fa
;
border-bottom
:
1px
solid
#e8eef2
;
padding
:
16px
24px
;
.ant-drawer-title
{
font-size
:
16px
;
font-weight
:
500
;
color
:
#1f2f3d
;
}
.ant-drawer-close
{
color
:
#8c8c8c
;
&
:hover
{
color
:
#1f2f3d
;
}
}
}
}
.drawer-content
{
height
:
100%
;
overflow-y
:
auto
;
padding
:
16px
20px
;
&
:
:-
webkit-scrollbar
{
width
:
4px
;
}
&
:
:-
webkit-scrollbar-track
{
background
:
#f1f1f1
;
border-radius
:
2px
;
}
&
:
:-
webkit-scrollbar-thumb
{
background
:
#c1c1c1
;
border-radius
:
2px
;
&
:hover
{
background
:
#a8a8a8
;
}
}
}
// 分配区域
.assignee-section
{
height
:
100%
;
:deep
(
.task-assignee-selector
)
{
height
:
100%
;
.assignee-card
{
height
:
100%
;
box-shadow
:
0
1px
2px
rgba
(
0
,
0
,
0
,
0
.03
);
:deep
(
.ant-card-head
)
{
background-color
:
#fff
;
border-bottom
:
1px
solid
#f0f0f0
;
}
:deep
(
.ant-card-body
)
{
height
:
calc
(
100%
-
57px
);
}
}
}
}
</
style
>
\ No newline at end of file
zrch-risk-client-39/src/views/common/TaskAssigneeSelector.vue
0 → 100644
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/common/WorkFlowForm.vue
deleted
100644 → 0
浏览文件 @
ca1f544f
<
template
>
<div
class=
"multi-form-preview"
>
<!-- 只读表单列表:前 N-1 个 -->
<div
v-for=
"(node, idx) in previousNodes"
:key=
"`readonly-$
{idx}`" class="form-readonly-item">
<div
class=
"form-header"
>
<span
class=
"form-name"
>
{{
node
.
name
}}
</span>
<a-tag
color=
"blue"
class=
"readonly-tag"
>
只读
</a-tag>
</div>
<div
class=
"form-content readonly"
>
<component
:is=
"loadComponent(node.formUrl)"
:disabled=
"true"
:readonly=
"true"
:form-data=
"formDataMap[node.id]"
:current-flow-node=
"node"
/>
</div>
</div>
<!-- 可编辑表单:第 N 个(当前节点) -->
<div
v-if=
"currentNode"
class=
"form-editable-item"
>
<div
class=
"form-header"
>
<span
class=
"form-name"
>
{{
currentNode
.
name
}}
</span>
<a-tag
color=
"green"
>
可编辑
</a-tag>
</div>
<div
class=
"form-content editable"
>
<component
:is=
"loadComponent(currentNode.formUrl)"
:disabled=
"false"
:readonly=
"false"
:form-data=
"currentFormData"
:current-flow-node=
"currentNode"
@
update:form-data=
"handleFormDataUpdate"
@
submit=
"handleSubmit"
/>
</div>
</div>
<!-- 加载错误提示 -->
<a-empty
v-if=
"!currentNode && previousNodes.length === 0"
description=
"未找到有效表单节点"
/>
</div>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
ref
,
computed
,
onMounted
,
defineAsyncComponent
,
h
,
watch
}
from
'vue'
;
import
{
message
}
from
'ant-design-vue'
;
// 定义组件属性
const
props
=
defineProps
({
// 当前节点在 workflowNodes 中的索引(从 0 开始)
currentNodeIndex
:
{
type
:
Number
,
required
:
true
,
default
:
2
// 默认第三个(索引2)
},
// 工作流节点列表(从父组件传入)
workflowNodes
:
{
type
:
Array
as
()
=>
Array
<
any
>
,
required
:
true
,
default
:
()
=>
[]
},
// 外部传入的表单数据(用于回显)
externalFormData
:
{
type
:
Object
,
default
:
()
=>
({})
}
});
// 定义事件
const
emit
=
defineEmits
([
'form-data-update'
,
'submit'
]);
// 组件缓存
const
componentCache
=
new
Map
();
// 使用 import.meta.glob 预加载所有可能的组件
const
modules
=
import
.
meta
.
glob
(
'@/views/**/*.vue'
);
// 当前节点的表单数据(可编辑)
const
currentFormData
=
ref
<
any
>
({});
// 只读节点的表单数据映射(按节点id存储)
const
formDataMap
=
ref
<
Record
<
string
,
any
>>
({});
// 获取前 N 个节点(只读部分)
const
previousNodes
=
computed
(()
=>
{
if
(
!
props
.
workflowNodes
||
props
.
workflowNodes
.
length
===
0
)
return
[];
const
idx
=
props
.
currentNodeIndex
;
// 取索引小于 idx 的节点(即当前节点之前的所有节点)
return
props
.
workflowNodes
.
slice
(
0
,
idx
);
});
// 获取当前节点(第 N 个,可编辑)
const
currentNode
=
computed
(()
=>
{
if
(
!
props
.
workflowNodes
||
props
.
workflowNodes
.
length
===
0
)
return
null
;
const
idx
=
props
.
currentNodeIndex
;
if
(
idx
<
0
||
idx
>=
props
.
workflowNodes
.
length
)
return
null
;
return
props
.
workflowNodes
[
idx
];
});
// 将 URL 转换为正确的导入路径并动态加载组件
function
loadComponent
(
url
:
string
)
{
if
(
!
url
)
{
console
.
warn
(
'formUrl 为空'
);
return
createEmptyComponent
();
}
if
(
componentCache
.
has
(
url
))
{
return
componentCache
.
get
(
url
);
}
// 构建组件路径(使用 /@/ 格式)
let
componentPath
=
''
;
if
(
url
.
includes
(
'/views'
))
{
componentPath
=
`/src
${
url
}
`
;
}
else
{
componentPath
=
`/src/views
${
url
}
`
;
}
// 确保有文件后缀
if
(
!
componentPath
.
match
(
/
\.(
vue|js|ts|jsx|tsx
)
$/
))
{
componentPath
+=
'.vue'
;
}
console
.
log
(
'加载组件路径:'
,
componentPath
);
// 从预加载的 modules 中获取加载器
let
loader
=
modules
[
componentPath
];
if
(
!
loader
)
{
console
.
error
(
'未找到组件:'
,
componentPath
);
console
.
log
(
'可用路径示例:'
,
Object
.
keys
(
modules
).
slice
(
0
,
5
));
const
ErrorComponent
=
createErrorComponent
(
`组件未找到:
${
componentPath
}
`
);
componentCache
.
set
(
url
,
ErrorComponent
);
return
ErrorComponent
;
}
// 创建异步组件,并注入额外的 props(disabled/readonly 等)
const
AsyncComponent
=
defineAsyncComponent
({
loader
:
()
=>
loader
()
as
Promise
<
{
default
:
any
}
>
,
loadingComponent
:
{
render
:
()
=>
h
(
'div'
,
{
style
:
'text-align: center; padding: 20px;'
},
'加载中...'
)
},
errorComponent
:
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: red; padding: 20px;'
},
'组件加载失败,请刷新页面重试'
)
},
delay
:
200
,
timeout
:
3000
,
onError
(
error
)
{
console
.
error
(
'异步组件加载错误:'
,
error
);
}
});
componentCache
.
set
(
url
,
AsyncComponent
);
return
AsyncComponent
;
}
// 创建空组件(当 formUrl 为空时使用)
function
createEmptyComponent
()
{
return
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: #999; padding: 20px; text-align: center;'
},
'该节点未配置表单'
)
};
}
// 创建错误组件
function
createErrorComponent
(
msg
:
string
)
{
return
{
render
:
()
=>
h
(
'div'
,
{
style
:
'color: red; padding: 20px;'
},
msg
)
};
}
// 处理表单数据更新(来自可编辑组件)
function
handleFormDataUpdate
(
data
:
any
)
{
currentFormData
.
value
=
{
...
currentFormData
.
value
,
...
data
};
emit
(
'form-data-update'
,
currentFormData
.
value
);
}
// 处理提交事件
function
handleSubmit
(
data
:
any
)
{
emit
(
'submit'
,
{
nodeId
:
currentNode
.
value
?.
id
,
nodeName
:
currentNode
.
value
?.
name
,
formData
:
data
||
currentFormData
.
value
});
}
// 初始化只读节点的表单数据(从外部传入或模拟)
function
initReadonlyFormData
()
{
// 如果外部传入了表单数据,则按节点id映射
if
(
props
.
externalFormData
&&
Object
.
keys
(
props
.
externalFormData
).
length
>
0
)
{
// 假设 externalFormData 的结构为 { nodeId: formData, ... }
previousNodes
.
value
.
forEach
(
node
=>
{
if
(
props
.
externalFormData
[
node
.
id
])
{
formDataMap
.
value
[
node
.
id
]
=
props
.
externalFormData
[
node
.
id
];
}
else
{
// 如果没有传入,设置空对象
formDataMap
.
value
[
node
.
id
]
=
{};
}
});
}
else
{
// 初始化空数据
previousNodes
.
value
.
forEach
(
node
=>
{
formDataMap
.
value
[
node
.
id
]
=
{};
});
}
}
// 监听外部表单数据变化
watch
(()
=>
props
.
externalFormData
,
(
newData
)
=>
{
if
(
newData
&&
Object
.
keys
(
newData
).
length
>
0
)
{
previousNodes
.
value
.
forEach
(
node
=>
{
if
(
newData
[
node
.
id
])
{
formDataMap
.
value
[
node
.
id
]
=
newData
[
node
.
id
];
}
});
// 如果当前节点有数据,也更新
if
(
currentNode
.
value
&&
newData
[
currentNode
.
value
.
id
])
{
currentFormData
.
value
=
newData
[
currentNode
.
value
.
id
];
}
}
},
{
deep
:
true
,
immediate
:
true
});
// 组件挂载时初始化
onMounted
(()
=>
{
initReadonlyFormData
();
console
.
log
(
'MultiFormPreview 组件已挂载'
);
console
.
log
(
'当前节点索引:'
,
props
.
currentNodeIndex
);
console
.
log
(
'只读节点数量:'
,
previousNodes
.
value
.
length
);
console
.
log
(
'当前节点:'
,
currentNode
.
value
?.
name
);
});
</
script
>
<
style
scoped
lang=
"scss"
>
.multi-form-preview
{
width
:
100%
;
padding
:
16px
;
background-color
:
#f5f7fa
;
border-radius
:
8px
;
.form-readonly-item
,
.form-editable-item
{
margin-bottom
:
24px
;
background-color
:
#fff
;
border-radius
:
8px
;
overflow
:
hidden
;
box-shadow
:
0
1px
2px
rgba
(
0
,
0
,
0
,
0
.05
);
transition
:
box-shadow
0
.2s
;
&
:hover
{
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0
.1
);
}
.form-header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
12px
16px
;
background-color
:
#fafbfc
;
border-bottom
:
1px
solid
#e8eef2
;
.form-name
{
font-size
:
15px
;
font-weight
:
500
;
color
:
#1f2f3d
;
}
.readonly-tag
,
.ant-tag
{
font-size
:
12px
;
}
}
.form-content
{
padding
:
20px
;
&
.readonly
{
background-color
:
#fefefe
;
// 只读模式下添加半透明遮罩效果,但仍保留交互(如果子组件支持disabled)
opacity
:
0
.95
;
}
&
.editable
{
background-color
:
#fff
;
}
}
}
.form-editable-item
{
border
:
1px
solid
#d9ecff
;
box-shadow
:
0
2px
8px
rgba
(
24
,
144
,
255
,
0
.08
);
.form-header
{
background-color
:
#e6f7ff
;
border-bottom-color
:
#bae7ff
;
.form-name
{
color
:
#096dd9
;
}
}
}
}
</
style
>
\ No newline at end of file
zrch-risk-client-39/src/views/common/WorkFlowFormApprovalDrawer.vue
0 → 100644
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/common/WorkFlowFormDrawer.vue
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/flowable/task/components/ShowFormModal.vue
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/flowable/task/todo/components/TodoIndex.vue
浏览文件 @
78599ce5
...
...
@@ -548,7 +548,7 @@
submitData
.
values
[
'approvalType'
]
=
'role'
;
}
// }
console
.
log
(
"执行发送 "
,
submitData
);
// 执行发送
const
result
=
await
complete
(
submitData
);
...
...
zrch-risk-client-39/src/views/project/problemCheck/StProblemArchiveList.vue
浏览文件 @
78599ce5
...
...
@@ -25,9 +25,22 @@
import
{
list
}
from
'./StProblemCheck.api'
;
import
StProblemCheckExecuteModal
from
'./components/StProblemCheckExecuteModal.vue'
;
import
{
useRoute
}
from
'vue-router'
;
const
route
=
useRoute
();
const
emit
=
defineEmits
([
'callback'
])
const
props
=
defineProps
({
beforeFlowNode
:
{
type
:
Object
,
default
:
()
=>
({})
},
currentFlowNode
:
{
type
:
Object
,
default
:
()
=>
({})
},
nextFlowNode
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
//注册model
...
...
@@ -48,7 +61,7 @@
fieldMapToTime
:
[],
},
beforeFetch
(
params
)
{
params
[
'id'
]
=
route
.
query
.
id
params
[
'bmpNodeId'
]
=
props
.
currentFlowNode
.
id
},
actionColumn
:
{
width
:
200
,
...
...
@@ -60,11 +73,7 @@
const
[
registerTable
,
{
reload
},
{
rowSelection
,
selectedRowKeys
}]
=
tableContext
;
function
handleArchive
(
record
:
Recordable
)
{
openExecuteModal
(
true
,
{
record
,
isUpdate
:
true
,
showFooter
:
true
,
});
emit
(
"callback"
,
record
)
}
function
handleSuccess
()
{
...
...
zrch-risk-client-39/src/views/project/problemCheck/StProblemCheck.data.ts
浏览文件 @
78599ce5
...
...
@@ -46,7 +46,8 @@ export const columns: BasicColumn[] = [
align
:
'center'
,
dataIndex
:
'problemDes'
,
resizable
:
true
,
ifShow
:
true
,
ifShow
:
false
,
},
{
title
:
'风险等级'
,
...
...
zrch-risk-client-39/src/views/project/problemCheck/StProblemCheckList.vue
浏览文件 @
78599ce5
...
...
@@ -25,7 +25,7 @@
</
template
>
</BasicTable>
<!-- 表单区域 -->
<StProblemCheckModal
@
register=
"registerModal"
@
success=
"handleSuccess"
/>
<StProblemCheckModal
@
register=
"registerModal"
@
success=
"handleSuccess"
:center=
"true"
/>
</div>
</template>
...
...
@@ -53,7 +53,7 @@
}
})
const
emit
=
defineEmits
([
'callback'
])
const
emit
=
defineEmits
([
'callback'
,
'startWorkFlow'
,
'sendWorkFlow'
])
//注册model
const
[
registerModal
,
{
openModal
}]
=
useModal
();
...
...
@@ -76,7 +76,7 @@
params
[
'bmpNodeId'
]
=
props
.
currentFlowNode
.
id
},
actionColumn
:
{
width
:
4
00
,
width
:
2
00
,
fixed
:
'right'
,
},
},
...
...
@@ -95,7 +95,7 @@
/**
* 新增事件
*/
function
handleAdd
333333
()
{
function
handleAdd
()
{
openModal
(
true
,
{
isUpdate
:
false
,
showFooter
:
true
,
...
...
@@ -107,12 +107,7 @@
});
}
function
handleAdd
()
{
emit
(
"callback"
,
null
)
}
/**
* 编辑事件
*/
function
handleEdit
(
record
:
Recordable
)
{
openModal
(
true
,
{
record
,
...
...
@@ -120,17 +115,6 @@
showFooter
:
true
,
});
}
function
handlePlan
(
record
:
Recordable
)
{
openPlanModal
(
true
,
{
record
,
isUpdate
:
true
,
showFooter
:
true
,
});
}
/**
* 详情
*/
function
handleDetail
(
record
:
Recordable
)
{
openModal
(
true
,
{
record
,
...
...
@@ -138,27 +122,22 @@
showFooter
:
false
,
});
}
/**
* 删除事件
*/
async
function
handleDelete
(
record
)
{
await
deleteOne
({
id
:
record
.
id
},
handleSuccess
);
}
/**
* 批量删除事件
*/
async
function
batchHandleDelete
()
{
await
batchDelete
({
ids
:
selectedRowKeys
.
value
},
handleSuccess
);
}
/**
* 成功回调
*/
function
handleSuccess
()
{
function
handleSuccess
(
retData
)
{
(
selectedRowKeys
.
value
=
[])
&&
reload
();
if
(
retData
){
emit
(
'startWorkFlow'
,
retData
)
}
/**
* 操作栏
*/
}
function
getTableAction
(
record
)
{
return
[
{
...
...
@@ -189,17 +168,14 @@
}
async
function
handleFlow
(
record
:
Recordable
)
{
//alert(JSON.stringify(props.currentFlowNode))
//alert(JSON.stringify(props.nextFlowNode))
///alert(JSON.stringify(props.beforeFlowNode))
record
[
'deployId'
]
=
props
.
nextFlowNode
.
deployId
record
[
'bmpNodeId'
]
=
props
.
nextFlowNode
.
id
record
[
'bpmStatus'
]
=
2
await
saveOrUpdate
(
record
,
true
).
then
(
res
=>
{
handleSuccess
()
handleSuccess
(
record
)
})
emit
(
"sendWorkFlow"
,
record
)
}
...
...
zrch-risk-client-39/src/views/project/problemCheck/StProblemExecApprovalList.vue
浏览文件 @
78599ce5
...
...
@@ -25,6 +25,7 @@
import
{
list
}
from
'./StProblemCheck.api'
;
import
StProblemCheckExecuteModal
from
'./components/StProblemCheckExecuteModal.vue'
;
const
emit
=
defineEmits
([
'callback'
])
const
props
=
defineProps
({
beforeFlowNode
:
{
...
...
@@ -59,7 +60,7 @@
fieldMapToTime
:
[],
},
beforeFetch
(
params
)
{
params
[
'id'
]
=
route
.
query
.
id
params
[
'bmpNodeId'
]
=
props
.
currentFlowNode
.
id
},
actionColumn
:
{
width
:
200
,
...
...
@@ -71,11 +72,7 @@
const
[
registerTable
,
{
reload
},
{
rowSelection
,
selectedRowKeys
}]
=
tableContext
;
function
handleExecuteApproval
(
record
:
Recordable
)
{
openExecuteModal
(
true
,
{
record
,
isUpdate
:
true
,
showFooter
:
true
,
});
emit
(
"callback"
,
record
)
}
function
handleSuccess
()
{
...
...
zrch-risk-client-39/src/views/project/problemCheck/StProblemExecList.vue
浏览文件 @
78599ce5
...
...
@@ -25,6 +25,8 @@
import
{
list
}
from
'./StProblemCheck.api'
;
import
StProblemCheckExecuteModal
from
'./components/StProblemCheckExecuteModal.vue'
;
const
emit
=
defineEmits
([
'callback'
])
const
props
=
defineProps
({
beforeFlowNode
:
{
type
:
Object
,
...
...
@@ -58,7 +60,7 @@
fieldMapToTime
:
[],
},
beforeFetch
(
params
)
{
params
[
'id'
]
=
route
.
query
.
id
params
[
'bmpNodeId'
]
=
props
.
currentFlowNode
.
id
},
actionColumn
:
{
width
:
200
,
...
...
@@ -70,11 +72,7 @@
const
[
registerTable
,
{
reload
},
{
rowSelection
,
selectedRowKeys
}]
=
tableContext
;
function
handleExecute
(
record
:
Recordable
)
{
openExecuteModal
(
true
,
{
record
,
isUpdate
:
true
,
showFooter
:
true
,
});
emit
(
"callback"
,
record
)
}
function
handleSuccess
()
{
...
...
zrch-risk-client-39/src/views/project/problemCheck/StProblemIndex.vue
浏览文件 @
78599ce5
...
...
@@ -5,6 +5,7 @@
<div
v-if=
"node.formListUrl"
class=
"tab-content"
>
<component
:is=
"loadComponent(node.formListUrl)"
@
startWorkFlow=
"handleDefinitionStart"
@
sendWorkFlow=
"handleDefinitionSend"
:beforeFlowNode=
"workflowNodes[index-1]"
:currentFlowNode=
"node"
:nextFlowNode=
"workflowNodes[index+1]"
...
...
@@ -17,8 +18,6 @@
</div>
</a-tab-pane>
</a-tabs>
<!-- 多表单抽屉组件 -->
<WorkFlowFormDrawer
v-model:visible=
"drawerVisible"
:title=
"drawerTitle"
...
...
@@ -26,22 +25,59 @@
:workflow-nodes=
"workflowNodes"
:external-form-data=
"externalFormData"
:proc-def-id=
"currentProcDefId"
:data-id=
"dataId"
:show-approval-panel=
"isShowApprovalPanel"
@
submit=
"handleMultiFormSubmit"
@
close=
"handleDrawerClose"
@
form-data-update=
"handleMultiFormDataUpdate"
width=
"50%"
width=
"90%"
/>
<TaskAssigneeDrawer
v-model:visible=
"drawerTaskVisible"
:task-id=
"taskId"
:task-name=
"taskName"
:proc-def-id=
"procDefId"
:proc-def-name=
"procDefName"
:form-data=
"formData"
:show-task-info=
"true"
:show-form-data=
"true"
@
success=
"handleSuccess"
@
error=
"handleError"
/>
</div>
</
template
>
<
script
lang=
"ts"
name=
"problem-stProblemCheck"
setup
>
import
{
ref
,
nextTick
,
onMounted
,
defineAsyncComponent
,
h
}
from
'vue'
;
import
{
getNodesByTableName
}
from
'/@/components/Process/api/definition'
;
import
{
definitionStart
,
flowXmlAndNode
}
from
"/@/components/Process/api/definition"
;
import
{
definitionStart
,
definitionStartByDeployId
}
from
"/@/components/Process/api/definition"
;
import
WorkFlowFormDrawer
from
'/@/views/common/WorkFlowFormDrawer.vue'
;
import
TaskAssigneeDrawer
from
'/@/views/common/TaskAssigneeDrawer.vue'
const
workflowNodes
=
ref
<
any
[]
>
([]);
const
activeTab
=
ref
(
1
);
const
dataId
=
ref
(
''
);
const
currentNode
=
ref
<
any
>
({});
const
isShowApprovalPanel
=
ref
(
true
);
// 任务指派抽屉相关状态
const
drawerTaskVisible
=
ref
(
false
);
const
taskId
=
ref
(
'task_123456'
)
const
taskName
=
ref
(
'部门经理审批'
)
const
procDefId
=
ref
(
'process_001'
)
const
procDefName
=
ref
(
'请假流程'
)
const
formData
=
ref
({
申请人
:
'张三'
,
请假类型
:
'年假'
,
开始时间
:
'2024-01-15'
,
结束时间
:
'2024-01-20'
,
请假天数
:
5
,
请假事由
:
'家庭旅游'
})
// 抽屉相关状态
const
drawerVisible
=
ref
(
false
);
...
...
@@ -56,6 +92,7 @@
function
handleTabChange
(
key
)
{
activeTab
.
value
=
key
;
currentMultiFormIndex
.
value
=
key
-
1
;
currentNode
.
value
=
workflowNodes
.
value
[
key
-
1
];
}
function
loadComponent
(
url
:
string
)
{
...
...
@@ -106,12 +143,27 @@
return
AsyncComponent
;
}
const
handleDefinitionStart
=
(
procDefId
:
string
,
submitData
:
any
)
=>
{
return
definitionStart
({
procDefId
,
variables
:
submitData
})
const
handleDefinitionStart
=
async
(
data
)
=>
{
const
formData
=
{
dataId
:
data
.
id
,
dataName
:
'id'
};
const
startResRaw
=
await
definitionStartByDeployId
(
currentNode
.
value
?.
deployId
||
''
,
formData
);
if
(
startResRaw
?.
data
?.
id
)
{
dataId
.
value
=
startResRaw
.
data
.
id
;
}
}
const
handleDefinitionSend
=
async
(
data
)
=>
{
drawerTaskVisible
.
value
=
true
;
taskId
.
value
=
data
.
taskId
;
taskName
.
value
=
data
.
taskName
;
procDefId
.
value
=
data
.
procDefId
;
procDefName
.
value
=
data
.
procDefName
;
}
const
handleOpenMultiForm
=
(
params
:
{
nodeIndex
?:
number
;
title
?:
string
;
...
...
@@ -150,10 +202,12 @@
})
=>
{
console
.
log
(
'多表单提交数据:'
,
submitData
);
try
{
await
definitionStart
({
procDefId
:
submitData
.
procDefId
,
variables
:
submitData
.
formData
});
await
definitionStart
(
currentProcDefId
.
value
,
{
...
submitData
.
formData
}
);
drawerVisible
.
value
=
false
;
const
currentTabKey
=
activeTab
.
value
;
const
currentComponent
=
loadComponent
(
workflowNodes
.
value
[
currentTabKey
-
1
]?.
formListUrl
);
...
...
@@ -180,6 +234,17 @@
});
};
function handleSuccess(response: any) {
console.log('任务处理成功:', response)
// 刷新列表等操作
}
function handleError(error: any) {
console.error('任务处理失败:', error)
}
defineExpose({
openHistoryForms,
openMultiForm: handleOpenMultiForm
...
...
@@ -188,11 +253,8 @@
onMounted(async () => {
await nextTick();
try {
console.log('开始获取工作流节点...');
const nodes = await getNodesByTableName("st_problem_check");
workflowNodes.value = nodes;
console.log('获取到的工作流节点:', workflowNodes.value);
workflowNodes.value.forEach((node, index) => {
console.log(`
节点
$
{
index
+
1
}:
`, node.name, 'formListUrl:', node.formListUrl);
});
...
...
@@ -206,21 +268,31 @@
}
});
}
currentNode.value = workflowNodes.value[0];
} catch (error) {
console.error('获取工作流节点失败:', error);
}
});
function handleCallback(data: any) {
drawerVisible.value = true;
const currentNode = workflowNodes.value[currentMultiFormIndex.value];
currentProcDefId.value = currentNode.procDefId || '';
dataId.value = data.id || '';
currentNode.value = workflowNodes.value[currentMultiFormIndex.value];
currentProcDefId.value = currentNode.value.procDefId || '';
if(currentNode.value.name.indexOf('审') > -1) {
isShowApprovalPanel.value = true;
} else {
isShowApprovalPanel.value = false;
}
const userid = currentNode.assignee || '';
const nodeId = currentNode.id
const deployId = currentNode.deployId || '';
const procDefId = currentNode.procDefId || '';
const attributes = currentNode.attributes || {};
const userid = currentNode.value?.assignee || '';
const nodeId = currentNode.value?.id
const procDefId = currentNode.value?.procDefId || '';
const attributes = currentNode.value?.attributes || {};
const userType = attributes.userType || [];
if (userType.length > 0) {
data['userType'] = userType[0].value || '';
...
...
zrch-risk-client-39/src/views/project/problemCheck/StProblemPlanApprovalList.vue
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/project/problemCheck/StProblemPlanList.vue
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/project/problemCheck/components/StProblemCheckForm.vue
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/project/problemCheck/components/StProblemCheckModal.vue
浏览文件 @
78599ce5
差异被折叠。
点击展开。
zrch-risk-client-39/src/views/project/problemCheck/components/StProblemCheckPlanForm.vue
浏览文件 @
78599ce5
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论