3b1ebb39 by 任超

style:权限处理

1 parent 9724faa4
......@@ -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",
......
<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
<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
}
......
......@@ -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>
......
......@@ -20,17 +20,16 @@ router.beforeEach(async (to, from, next) => {
next()
} else {
const { result: getMenuData } = await getMenuInfo()
console.log(getMenuData);
// const accessRoutes = await store.dispatch('permission/generateRoutes', getMenuData)
// router.addRoutes(accessRoutes)
next()
const 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()
})
......
......@@ -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()
......
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 = array2Tree(permission_arr, null)
let permission_tree = asyncRouter(getMenuInfo)
commit('SET_ROUTES', permission_tree)
resolve(permission_tree)
})
......
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
......@@ -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
......