Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
bdc
/
bdcdj-web
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
3b1ebb39
authored
2022-10-18 15:58:57 +0800
by
任超
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
style:权限处理
1 parent
9724faa4
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
319 additions
and
38 deletions
package.json
src/components/processViewer/index.vue
src/layout/components/Sidebar/SidebarItem.vue
src/layout/components/Sidebar/index.vue
src/permission.js
src/router/index.js
src/store/modules/permission.js
src/utils/asyncRouter.js
src/utils/request.js
package.json
View file @
3b1ebb3
...
...
@@ -19,7 +19,9 @@
"nprogress"
:
"0.2.0"
,
"vue"
:
"2.6.10"
,
"vue-router"
:
"3.0.2"
,
"vuex"
:
"3.1.0"
"vuex"
:
"3.1.0"
,
"bpmn-js"
:
"^7.4.0"
,
"diagram-js"
:
"^6.8.2"
},
"devDependencies"
:
{
"@vue/cli-plugin-babel"
:
"4.4.4"
,
...
...
src/components/processViewer/index.vue
0 → 100644
View file @
3b1ebb3
<
template
>
<div
class=
"process-viewer"
>
<div
v-show=
"!isLoading"
ref=
"processCanvas"
class=
"process-canvas"
style=
"height: 100%;"
/>
<!-- 自定义箭头样式,用于成功状态下流程连线箭头 -->
<defs
ref=
"customSuccessDefs"
>
<marker
id=
"sequenceflow-end-white-success"
view-box=
"0 0 20 20"
ref-x=
"11"
ref-y=
"10"
marker-width=
"10"
marker-height=
"10"
orient=
"auto"
>
<path
class=
"success-arrow"
d=
"M 1 5 L 11 10 L 1 15 Z"
style=
"stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1;"
/>
</marker>
<marker
id=
"conditional-flow-marker-white-success"
view-box=
"0 0 20 20"
ref-x=
"-1"
ref-y=
"10"
marker-width=
"10"
marker-height=
"10"
orient=
"auto"
>
<path
class=
"success-conditional"
d=
"M 0 10 L 8 6 L 16 10 L 8 14 Z"
style=
"stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1;"
/>
</marker>
</defs>
<!-- 自定义箭头样式,用于失败状态下流程连线箭头 -->
<defs
ref=
"customFailDefs"
>
<marker
id=
"sequenceflow-end-white-fail"
view-box=
"0 0 20 20"
ref-x=
"11"
ref-y=
"10"
marker-width=
"10"
marker-height=
"10"
orient=
"auto"
>
<path
class=
"fail-arrow"
d=
"M 1 5 L 11 10 L 1 15 Z"
style=
"stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1;"
/>
</marker>
<marker
id=
"conditional-flow-marker-white-fail"
view-box=
"0 0 20 20"
ref-x=
"-1"
ref-y=
"10"
marker-width=
"10"
marker-height=
"10"
orient=
"auto"
>
<path
class=
"fail-conditional"
d=
"M 0 10 L 8 6 L 16 10 L 8 14 Z"
style=
"stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1;"
/>
</marker>
</defs>
<!-- 已完成节点悬浮弹窗 -->
<el-dialog
class=
"comment-dialog"
:title=
"dlgTitle || '审批记录'"
:visible
.
sync=
"dialogVisible"
append-to-body
>
<el-row>
<el-table
:data=
"taskCommentList"
size=
"mini"
border
header-cell-class-name=
"table-header-gray"
>
<el-table-column
label=
"序号"
header-align=
"center"
align=
"center"
type=
"index"
width=
"55px"
/>
<el-table-column
label=
"候选办理"
prop=
"candidate"
width=
"150px"
align=
"center"
/>
<el-table-column
label=
"实际办理"
prop=
"assigneeName"
width=
"100px"
align=
"center"
/>
<el-table-column
label=
"处理时间"
prop=
"createTime"
width=
"140px"
align=
"center"
/>
<el-table-column
label=
"办结时间"
prop=
"finishTime"
width=
"140px"
align=
"center"
/>
<el-table-column
label=
"耗时"
prop=
"duration"
width=
"100px"
align=
"center"
/>
<el-table-column
label=
"审批意见"
align=
"center"
>
<template
slot-scope=
"scope"
>
{{
scope
.
row
.
commentList
&&
scope
.
row
.
commentList
[
0
]?
scope
.
row
.
commentList
[
0
].
fullMessage
:
''
}}
</
template
>
</el-table-column>
</el-table>
</el-row>
</el-dialog>
<div
style=
"position: absolute; top: 0px; left: 0px; width: 100%;"
>
<el-row
type=
"flex"
justify=
"end"
>
<el-button-group
key=
"scale-control"
size=
"medium"
>
<el-button
size=
"medium"
type=
"default"
:plain=
"true"
:disabled=
"defaultZoom <= 0.3"
icon=
"el-icon-zoom-out"
@
click=
"processZoomOut()"
/>
<el-button
size=
"medium"
type=
"default"
style=
"width: 90px;"
>
{{ Math.floor(this.defaultZoom * 10 * 10) + "%"
}}
</el-button>
<el-button
size=
"medium"
type=
"default"
:plain=
"true"
:disabled=
"defaultZoom >= 3.9"
icon=
"el-icon-zoom-in"
@
click=
"processZoomIn()"
/>
<el-button
size=
"medium"
type=
"default"
icon=
"el-icon-c-scale-to-original"
@
click=
"processReZoom()"
/>
<slot
/>
</el-button-group>
</el-row>
</div>
</div>
</template>
<
script
>
import
BpmnViewer
from
'bpmn-js/lib/Viewer'
import
MoveCanvasModule
from
'diagram-js/lib/navigation/movecanvas'
export
default
{
props
:
{
// eslint-disable-next-line vue/require-default-prop
xml
:
{
type
:
String
},
// eslint-disable-next-line vue/require-default-prop
finishedInfo
:
{
type
:
Object
},
// 所有节点审批记录
// eslint-disable-next-line vue/require-default-prop
allCommentList
:
{
type
:
Array
}
},
data
()
{
return
{
dialogVisible
:
false
,
dlgTitle
:
undefined
,
defaultZoom
:
1
,
// 是否正在加载流程图
isLoading
:
false
,
bpmnViewer
:
undefined
,
// 已完成流程元素
processNodeInfo
:
undefined
,
// 当前任务id
selectTaskId
:
undefined
,
// 任务节点审批记录
taskCommentList
:
[],
// 已完成任务悬浮延迟Timer
hoverTimer
:
null
}
},
watch
:
{
xml
:
{
handler
(
newXml
)
{
this
.
importXML
(
newXml
)
},
immediate
:
true
},
finishedInfo
:
{
handler
(
newInfo
)
{
this
.
setProcessStatus
(
newInfo
)
},
immediate
:
true
}
},
created
()
{
this
.
$nextTick
(()
=>
{
this
.
importXML
(
this
.
xml
)
this
.
setProcessStatus
(
this
.
finishedInfo
)
})
},
destroyed
()
{
this
.
clearViewer
()
},
methods
:
{
processReZoom
()
{
this
.
defaultZoom
=
1
this
.
bpmnViewer
.
get
(
'canvas'
).
zoom
(
'fit-viewport'
,
'auto'
)
},
processZoomIn
(
zoomStep
=
0.1
)
{
const
newZoom
=
Math
.
floor
(
this
.
defaultZoom
*
100
+
zoomStep
*
100
)
/
100
if
(
newZoom
>
4
)
{
throw
new
Error
(
'[Process Designer Warn ]: The zoom ratio cannot be greater than 4'
)
}
this
.
defaultZoom
=
newZoom
this
.
bpmnViewer
.
get
(
'canvas'
).
zoom
(
this
.
defaultZoom
)
},
processZoomOut
(
zoomStep
=
0.1
)
{
const
newZoom
=
Math
.
floor
(
this
.
defaultZoom
*
100
-
zoomStep
*
100
)
/
100
if
(
newZoom
<
0.2
)
{
throw
new
Error
(
'[Process Designer Warn ]: The zoom ratio cannot be less than 0.2'
)
}
this
.
defaultZoom
=
newZoom
this
.
bpmnViewer
.
get
(
'canvas'
).
zoom
(
this
.
defaultZoom
)
},
getOperationTagType
(
type
)
{
return
'success'
// switch (type) {
// case this.SysFlowTaskOperationType.AGREE:
// case this.SysFlowTaskOperationType.MULTI_AGREE:
// return 'success';
// case this.SysFlowTaskOperationType.REFUSE:
// case this.SysFlowTaskOperationType.PARALLEL_REFUSE:
// case this.SysFlowTaskOperationType.MULTI_REFUSE:
// return 'warning';
// case this.SysFlowTaskOperationType.STOP:
// return 'danger'
// default:
// return 'primary';
// }
},
// 流程图预览清空
clearViewer
(
a
)
{
if
(
this
.
$refs
.
processCanvas
)
{
this
.
$refs
.
processCanvas
.
innerHTML
=
''
}
if
(
this
.
bpmnViewer
)
{
this
.
bpmnViewer
.
destroy
()
}
this
.
bpmnViewer
=
null
},
// 添加自定义箭头
addCustomDefs
()
{
const
canvas
=
this
.
bpmnViewer
.
get
(
'canvas'
)
const
svg
=
canvas
.
_svg
const
customSuccessDefs
=
this
.
$refs
.
customSuccessDefs
const
customFailDefs
=
this
.
$refs
.
customFailDefs
svg
.
appendChild
(
customSuccessDefs
)
svg
.
appendChild
(
customFailDefs
)
},
// 任务悬浮弹窗
onSelectElement
(
element
)
{
this
.
selectTaskId
=
undefined
this
.
dlgTitle
=
undefined
if
(
this
.
processNodeInfo
==
null
||
this
.
processNodeInfo
.
finishedTaskSet
==
null
)
return
if
(
element
==
null
||
this
.
processNodeInfo
.
finishedTaskSet
.
indexOf
(
element
.
id
)
===
-
1
)
{
return
}
this
.
selectTaskId
=
element
.
id
this
.
dlgTitle
=
element
.
businessObject
?
element
.
businessObject
.
name
:
undefined
// 计算当前悬浮任务审批记录,如果记录为空不显示弹窗
this
.
taskCommentList
=
(
this
.
allCommentList
||
[]).
filter
(
item
=>
{
return
item
.
taskDefKey
===
this
.
selectTaskId
})
this
.
dialogVisible
=
true
},
// 显示流程图
async
importXML
(
xml
)
{
this
.
clearViewer
(
'a'
)
if
(
xml
!=
null
&&
xml
!==
''
)
{
try
{
this
.
bpmnViewer
=
new
BpmnViewer
({
additionalModules
:
[
// 移动整个画布
MoveCanvasModule
],
container
:
this
.
$refs
.
processCanvas
})
// 任务节点悬浮事件
this
.
bpmnViewer
.
on
(
'element.click'
,
({
element
})
=>
{
this
.
onSelectElement
(
element
)
})
this
.
isLoading
=
true
const
c
=
await
this
.
bpmnViewer
.
importXML
(
xml
)
this
.
addCustomDefs
()
}
catch
(
e
)
{
// this.clearViewer('b')
}
finally
{
this
.
isLoading
=
false
this
.
setProcessStatus
(
this
.
processNodeInfo
)
this
.
$nextTick
(()
=>
{
this
.
processReZoom
()
})
}
}
},
// 设置流程图元素状态
setProcessStatus
(
processNodeInfo
)
{
this
.
processNodeInfo
=
processNodeInfo
if
(
this
.
isLoading
||
this
.
processNodeInfo
==
null
||
this
.
bpmnViewer
==
null
)
return
const
{
finishedTaskSet
,
rejectedTaskSet
,
unfinishedTaskSet
,
finishedSequenceFlowSet
}
=
this
.
processNodeInfo
const
canvas
=
this
.
bpmnViewer
.
get
(
'canvas'
)
const
elementRegistry
=
this
.
bpmnViewer
.
get
(
'elementRegistry'
)
if
(
Array
.
isArray
(
finishedSequenceFlowSet
))
{
finishedSequenceFlowSet
.
forEach
(
item
=>
{
if
(
item
!=
null
)
{
canvas
.
addMarker
(
item
,
'success'
)
const
element
=
elementRegistry
.
get
(
item
)
const
conditionExpression
=
element
.
businessObject
.
conditionExpression
if
(
conditionExpression
)
{
canvas
.
addMarker
(
item
,
'condition-expression'
)
}
}
})
}
if
(
Array
.
isArray
(
finishedTaskSet
))
{
finishedTaskSet
.
forEach
(
item
=>
canvas
.
addMarker
(
item
,
'success'
))
}
if
(
Array
.
isArray
(
unfinishedTaskSet
))
{
unfinishedTaskSet
.
forEach
(
item
=>
canvas
.
addMarker
(
item
,
'primary'
))
}
if
(
Array
.
isArray
(
rejectedTaskSet
))
{
rejectedTaskSet
.
forEach
(
item
=>
{
if
(
item
!=
null
)
{
const
element
=
elementRegistry
.
get
(
item
)
if
(
element
.
type
.
includes
(
'Task'
))
{
canvas
.
addMarker
(
item
,
'danger'
)
}
else
{
canvas
.
addMarker
(
item
,
'warning'
)
}
}
})
}
}
}
}
</
script
>
\ No newline at end of file
src/layout/components/Sidebar/SidebarItem.vue
View file @
3b1ebb3
<
template
>
<div
v-if=
"!item.hidden"
>
<template
v-if=
"hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)
&&!item.alwaysShow
"
>
<template
v-if=
"hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)"
>
<app-link
v-if=
"onlyOneChild.meta"
:to=
"resolvePath(onlyOneChild.path)"
>
<el-menu-item
:index=
"resolvePath(onlyOneChild.path)"
:class=
"
{'submenu-title-noDropdown':!isNest}">
<item
:icon=
"onlyOneChild.meta.icon||(item.meta&&item.meta.icon)"
:title=
"onlyOneChild.meta.title"
class=
"menu-icon"
/>
<item
:icon=
"onlyOneChild.meta.icon||(item.meta&&item.meta.icon)"
:title=
"onlyOneChild.meta.title"
class=
"menu-icon"
/>
</el-menu-item>
</app-link>
</
template
>
...
...
@@ -12,14 +13,8 @@
<
template
slot=
"title"
>
<item
v-if=
"item.meta"
:icon=
"item.meta && item.meta.icon"
:title=
"item.meta.title"
/>
</
template
>
<sidebar-item
v-for=
"child in item.children"
:key=
"child.path"
:is-nest=
"true"
:item=
"child"
:base-path=
"resolvePath(child.path)"
class=
"nest-menu"
/>
<sidebar-item
v-for=
"child in item.children"
:key=
"child.path"
:is-nest=
"true"
:item=
"child"
:base-path=
"resolvePath(child.path)"
class=
"nest-menu"
/>
</el-submenu>
</div>
</template>
...
...
@@ -50,14 +45,14 @@ export default {
default
:
''
}
},
data
()
{
data
()
{
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this
.
onlyOneChild
=
null
return
{}
},
methods
:
{
hasOneShowingChild
(
children
=
[],
parent
)
{
hasOneShowingChild
(
children
=
[],
parent
)
{
const
showingChildren
=
children
.
filter
(
item
=>
{
if
(
item
.
hidden
)
{
return
false
...
...
@@ -75,13 +70,13 @@ export default {
// Show parent if there are no child router to display
if
(
showingChildren
.
length
===
0
)
{
this
.
onlyOneChild
=
{
...
parent
,
path
:
''
,
noShowingChildren
:
true
}
this
.
onlyOneChild
=
{
...
parent
,
path
:
''
,
noShowingChildren
:
true
}
return
true
}
return
false
},
resolvePath
(
routePath
)
{
resolvePath
(
routePath
)
{
if
(
isExternal
(
routePath
))
{
return
routePath
}
...
...
src/layout/components/Sidebar/index.vue
View file @
3b1ebb3
...
...
@@ -5,9 +5,9 @@
:unique-opened=
"true"
:active-text-color=
"variables.menuActiveText"
:collapse-transition=
"false"
mode=
"vertical"
>
<!-- 权限菜单 -->
<
!--
<sidebar-item
v-for=
"route in permission_routes"
:key=
"route.path"
:item=
"route"
:base-path=
"route.path"
/>
--
>
<
sidebar-item
v-for=
"route in permission_routes"
:key=
"route.path"
:item=
"route"
:base-path=
"route.path"
/
>
<!-- 菜单全部展示 -->
<
sidebar-item
v-for=
"route in asyncRoutes"
:key=
"route.path"
:item=
"route"
:base-path=
"route.path"
/
>
<
!--
<sidebar-item
v-for=
"route in asyncRoutes"
:key=
"route.path"
:item=
"route"
:base-path=
"route.path"
/>
--
>
</el-menu>
</el-scrollbar>
</div>
...
...
src/permission.js
View file @
3b1ebb3
...
...
@@ -20,17 +20,16 @@ router.beforeEach(async (to, from, next) => {
next
()
}
else
{
const
{
result
:
getMenuData
}
=
await
getMenuInfo
()
cons
ole
.
log
(
getMenuData
);
// const accessRoutes = await store.dispatch('permission/generateRoutes', getMenuData
)
// router.addRoutes(accessRoutes)
next
()
cons
t
accessRoutes
=
await
store
.
dispatch
(
'permission/generateRoutes'
,
getMenuData
)
router
.
addRoutes
(
accessRoutes
)
console
.
log
(
router
);
next
(
{
...
to
,
replace
:
true
}
)
}
NProgress
.
done
()
})
router
.
afterEach
(
to
=>
{
// 解决刷新页面报404问题
sessionStorage
.
setItem
(
'routerTo'
,
to
.
fullPath
)
Cookies
.
set
(
"routerTo"
,
to
.
fullPath
)
NProgress
.
done
()
})
...
...
src/router/index.js
View file @
3b1ebb3
...
...
@@ -25,7 +25,6 @@ export const constantRoutes = [
component
:
()
=>
import
(
'@/views/error-page/404'
),
hidden
:
true
},
{
path
:
'*'
,
redirect
:
'/404'
,
hidden
:
true
},
// 业务流程框架
{
path
:
'/workFrame'
,
...
...
@@ -58,7 +57,7 @@ export const asyncRoutes = [
{
path
:
'home'
,
component
:
()
=>
import
(
'@/views/home/index'
),
name
:
'
Dashboard
'
,
name
:
'
home
'
,
meta
:
{
title
:
'工作台'
,
icon
:
'workbench'
,
affix
:
true
}
}
]
...
...
@@ -273,7 +272,7 @@ export const asyncRoutes = [
const
createRouter
=
()
=>
new
Router
({
scrollBehavior
:
()
=>
({
y
:
0
}),
routes
:
[...
constantRoutes
,
...
asyncRoutes
]
routes
:
[...
constantRoutes
]
})
const
router
=
createRouter
()
...
...
src/store/modules/permission.js
View file @
3b1ebb3
import
{
asyncRoutes
,
constantRoutes
,
resetRouter
}
from
'@/router'
import
asyncRouter
from
'@/utils/asyncRouter.js'
const
state
=
{
routes
:
[],
addRoutes
:
false
,
...
...
@@ -8,26 +8,18 @@ const state = {
const
mutations
=
{
SET_ROUTES
:
(
state
,
routes
)
=>
{
state
.
addRoutes
=
true
state
.
routes
=
constantRoutes
.
concat
(
routes
)
state
.
routes
=
routes
},
RESET_ROUTE
:
(
state
)
=>
{
state
.
addRoutes
=
false
}
}
const
actions
=
{
// 添加全部菜单
generateRoutes
({
commit
},
getMenuInfo
)
{
return
new
Promise
(
resolve
=>
{
// 将路由树数据转成数组结构
let
arr1
=
[]
dfs
(
_
.
cloneDeep
(
asyncRoutes
),
node
=>
arr1
.
push
(
node
))
_
.
each
(
arr1
,
i
=>
{
i
.
parentId
=
i
.
parentId
?
i
.
parentId
:
null
})
let
permission_arr
=
_
.
intersectionBy
(
arr1
,
getMenuInfo
,
'name'
)
// 将权限菜单数组转成路由树数据结构
let
permission_tree
=
a
rray2Tree
(
permission_arr
,
null
)
let
permission_tree
=
a
syncRouter
(
getMenuInfo
)
commit
(
'SET_ROUTES'
,
permission_tree
)
resolve
(
permission_tree
)
})
...
...
src/utils/asyncRouter.js
0 → 100644
View file @
3b1ebb3
import
Layout
from
'@/layout'
export
default
function
filterAsyncRouter
(
routers
)
{
routers
.
forEach
(
item
=>
{
if
(
!
item
.
children
)
{
delete
item
.
children
delete
item
.
redirect
}
if
(
!
item
.
parentId
)
{
item
.
component
=
Layout
}
else
{
item
.
component
=
loadView
(
item
.
uri
)
}
item
.
meta
.
icon
=
item
.
icon
if
(
item
.
children
)
{
item
.
children
=
filterAsyncRouter
(
item
.
children
)
}
})
return
routers
}
function
loadView
(
view
)
{
return
r
=>
require
.
ensure
([],
()
=>
r
(
require
(
`@/views
${
view
}
.vue`
)))
}
\ No newline at end of file
src/utils/request.js
View file @
3b1ebb3
...
...
@@ -11,9 +11,9 @@ const service = axios.create({
withCredentials
:
true
,
//是否允许跨域
headers
:
{
'Content-Type'
:
'application/json; charset=utf-8'
,
//
'Authorization': 'bearer AT-16-oqkOHiUSsDdFA-eAZ49k2rJQDTzQpClO'
'Authorization'
:
'bearer AT-16-oqkOHiUSsDdFA-eAZ49k2rJQDTzQpClO'
//token列表
'Authorization'
:
'bearer AT-12-eRKHta5I8ZWftIU86sSyJ8rUkPhMvMJU'
//
'Authorization': 'bearer AT-12-eRKHta5I8ZWftIU86sSyJ8rUkPhMvMJU'
//renc:bearer AT-30-KHB4LXc8-CZXwBEyaFJa9lRmMTc5sHVI
//tianh:bearer AT-33-3zFTGkhQ4eUv4nXvzAmbgN5RPZppzEY6
//zhangh:bearer AT-7-Tx8dlZH0LNRc33UjD1CX1xwa-1D7kQmQ
...
...
Please
register
or
sign in
to post a comment