commit:支持flowable工作流

This commit is contained in:
Jerry
2021-09-27 15:37:18 +08:00
parent d8831c7598
commit a2fbe479d8
849 changed files with 217544 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<el-breadcrumb-item :to="{name: 'welcome'}" :replace="true">
<i class="el-icon-s-home" style="margin-right: 5px;" />主页
</el-breadcrumb-item>
<el-breadcrumb-item v-for="item in menuPathList" :key="item.menuId">
{{item.menuName}}
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex';
export default {
created () {
this.getBreadcrumb();
},
data () {
return {
menuPathList: null
};
},
watch: {
$route (newValue) {
if (newValue.name === 'welcome') this.setCurrentMenuId(null);
this.getBreadcrumb();
}
},
methods: {
getBreadcrumb () {
this.menuPathList = this.getMultiColumn ? null : this.getCurrentMenuPath;
},
...mapMutations(['setCurrentMenuId'])
},
computed: {
...mapGetters(['getCurrentMenuPath', 'getMultiColumn'])
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 60px;
margin-left: 10px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>

View File

@@ -0,0 +1,98 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formModifyPassword" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="120px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="旧密码" prop="oldPassword">
<el-input class="input-item" v-model.trim="formData.oldPassword"
type="password" show-password
:clearable="true" placeholder="旧密码" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="新密码" prop="password">
<el-input class="input-item" v-model.trim="formData.password"
type="password" show-password
:clearable="true" placeholder="新密码" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="新密码确认" prop="repeatPassword">
<el-input class="input-item" v-model.trim="formData.repeatPassword"
type="password" show-password
:clearable="true" placeholder="新密码确认" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onSave()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { SystemController } from '@/api';
import { encrypt } from '@/utils';
export default {
data () {
return {
formData: {
oldPassword: undefined,
password: undefined,
repeatPassword: undefined
},
rules: {
'oldPassword': [
{required: true, message: '请输入旧密码', trigger: 'blur'}
],
'password': [
{required: true, message: '请输入新密码', trigger: 'blur'}
],
'repeatPassword': [
{required: true, message: '请输入新密码', trigger: 'blur'}
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSave () {
this.$refs.formModifyPassword.validate((valid) => {
if (!valid) return;
if (this.formData.password !== this.formData.repeatPassword) {
this.$message.error('两次密码输入不一致,请核对!');
return;
}
let params = {
oldPass: encrypt(this.formData.oldPassword),
newPass: encrypt(this.formData.password)
};
SystemController.changePassword(this, params).then(res => {
this.$message.success('密码修改成功');
this.onCancel(true);
}).catch(e => {});
});
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,59 @@
<template>
<div class="menu-wrapper">
<el-menu-item ref="item" :index="menu.menuId + ''" :key="menu.menuId" v-if="menu.children == null || menu.children.length <= 0">
<template slot="title">
<i v-if="menu.icon" :class="menu.icon" style="margin-right: 5px; font-size: 18px;" :style="getIconStyle(menu.icon)"></i>
<span slot="title" :style="getTextStyle(!menu.icon)">{{menu.menuName}}</span>
</template>
</el-menu-item>
<el-submenu v-else :index="menu.menuId + ''" :key="menu.menuId">
<template slot="title">
<i v-if="menu.icon" :class="menu.icon" style="margin-right: 5px; font-size: 18px;" :style="getIconStyle(menu.icon)"></i>
<span slot="title" :style="getTextStyle(!menu.icon)" v-show="!getCollapse">{{menu.menuName}}</span>
</template>
<template v-for="child in menu.children">
<menu-item class="nest-menu" :menu="child" :isChild="true" :key="child.menuId" />
</template>
</el-submenu>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: 'menuItem',
props: {
menu: {
type: Object,
required: true,
default: undefined
},
isChild: {
type: Boolean,
default: false
}
},
methods: {
getIconStyle (isShow) {
if (isShow && this.isChild) {
return [
{ 'margin-left': '13px' }
]
}
},
getTextStyle (isShow) {
if (isShow && this.isChild) {
return [
{ 'padding-left': '13px' }
]
}
}
},
computed: {
showText () {
return !this.getCollapse;
},
...mapGetters(['getCollapse'])
}
}
</script>

View File

@@ -0,0 +1,82 @@
<template>
<div style="height: 100%; position: relative;" class="sidebar-bg">
<div class="sidebar-title">
<img :src="logoImage" style="width: 32px; height: 32px; border-radius: 50%;" />
<p class="sidebar-title-text">{{getProjectName()}}</p>
</div>
<div class="left-menu" style="height: 100%; padding-bottom: 60px;">
<el-scrollbar wrap-class="scrollbar_dropdown__wrap" style="height: 100%;">
<el-menu ref="menu" mode="vertical" :default-active="getCurrentMenuId" :unique-opened="true" @select="selectMenu"
:active-text-color="activeTextColor" :collapse="getCollapse" >
<template v-for="menu in getMenuList">
<menu-item :menu="menu" :key="menu.menuId" />
</template>
</el-menu>
</el-scrollbar>
</div>
</div>
</template>
<script>
import menuItem from './menu-item.vue';
import { mapGetters, mapMutations } from 'vuex';
import projectConfig from '@/core/config';
export default {
data () {
return {
isCollapse: false,
collapseLeft: '200px',
showCollapseBtn: true,
logoImage: require('../../../../assets/img/logo.png')
}
},
components: {
'menu-item': menuItem
},
computed: {
activeTextColor () {
return undefined;
},
getCollapseStyle () {
return [{
left: this.collapseLeft
}]
},
...mapGetters(['getMultiTags', 'getMenuList', 'getCollapse', 'getCurrentMenuPath', 'getCurrentMenuId', 'getMultiColumn'])
},
methods: {
onCollapseChange () {
this.showCollapseBtn = false;
setTimeout(() => {
this.setCollapse(!this.getCollapse);
this.collapseLeft = this.getCollapse ? '65px' : '200px';
this.showCollapseBtn = true;
}, 100);
},
getProjectName () {
if (this.getCollapse) {
return projectConfig.projectName.substr(0, 1);
} else {
return projectConfig.projectName;
}
},
selectMenu (index, path) {
if (this.getCurrentMenuId === index) return;
// 单页面清空所有tags和cachePage
if (!this.getMultiTags) {
this.clearAllTags();
}
this.setCurrentMenuId(index);
},
...mapMutations(['setCollapse', 'clearAllTags', 'setCurrentMenuId'])
}
};
</script>
<style scoped>
.sidebar-title-text {
font-size: 18px;
font-weight: bold;
}
</style>

View File

@@ -0,0 +1,79 @@
<template>
<div class="tags-item">
<span class="title">{{title}}</span>
<i :class="{'el-icon-close close': !enterClose, 'el-icon-error close hover-close': enterClose}"
v-if="supportClose" @click.stop="onClose"
@mouseenter="() => enterClose = true" @mouseleave="() => enterClose = false" />
</div>
</template>
<script>
export default {
props: {
title: String,
supportClose: {
type: Boolean,
default: true
}
},
data () {
return {
enterClose: false
}
},
methods: {
onClose () {
this.$emit('close');
}
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/element-variables.scss';
.tags-item {
height: 30px;
line-height: 30px;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 3px;
box-sizing: border-box;
display: inline-block;
cursor: pointer;
background: white;
padding: 0px 20px;
color: $--color-text-primary;
}
.tags-item .title {
font-size: 13px;
}
.close {
height: 28px;
line-height: 28px;
display: none;
}
.tags-item.active .close {
margin-left: 10px;
display: inline-block;
}
.close.hover-close {
color: $--color-text-secondary;
}
.tags-item:hover {
color: $--color-primary;
}
.tags-item.active {
color: $--color-primary;
border-color: $--color-primary-light-5;
background-color: $--color-primary-light-9;
}
.tags-item + .tags-item {
margin-left: 5px;
}
</style>

View File

@@ -0,0 +1,213 @@
<template>
<div class="tags-panel">
<i class="el-icon-arrow-left arrow left" @click="beginPos > 0 && beginPos--" />
<i class="el-icon-arrow-right arrow right" @click="getEndTagPos >= panelWidth && beginPos++" />
<div class="main-panel">
<div class="scroll-box">
<TagItem class="item" title="主页" :class="{active: getCurrentMenuId == null}" v-show="0 >= beginPos" :supportClose="false"
@click.native="onTagItemClick(null)" @contextmenu.prevent.native="openMenu(null, $event)" />
<TagItem class="item" v-for="(item, index) in tagList" :key="item.menuId" :title="item.menuName"
:class="{active: item.menuId === getCurrentMenuId}" v-show="(index + 1) >= beginPos"
@close="onTagItemClose(item)" @click.native="onTagItemClick(item)"
@contextmenu.prevent.native="openMenu(item, $event)" />
</div>
</div>
<div v-show="visible" @click.stop="onMenuMaskClick" @contextmenu="openMaskMenu"
style="z-index: 99999; position: fixed; background: rgba(0, 0, 0, 0.01); width: 100vw; height: 100vh; top: 0px; left: 0px">
<ul class="contextmenu" style="z-index: 99999; background: white;" :style="{left: left + 'px', top: top + 'px'}">
<li @click="closeSelectTag">关闭</li>
<li @click="closeOthersTags">关闭其他</li>
</ul>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex';
import TagItem from './tagItem.vue';
export default {
props: {
tagList: Array
},
components: {
TagItem
},
data () {
return {
panelWidth: 0,
beginPos: 0,
visible: false,
top: 0,
left: 0,
selectedItem: undefined
}
},
methods: {
openMenu (item, e) {
this.visible = true;
this.selectedItem = item;
this.left = e.clientX;
this.top = e.clientY;
},
openMaskMenu (e) {
e.preventDefault();
},
onMenuMaskClick () {
this.visible = false;
},
closeSelectTag () {
if (this.selectedItem != null) this.onTagItemClose(this.selectedItem);
this.visible = false;
},
closeOthersTags () {
this.selectedItem ? this.closeOtherTags(this.selectedItem.menuId) : this.clearAllTags();
this.visible = false;
},
onTagItemClose (item) {
this.removeTag(item.menuId);
},
onTagItemClick (item) {
this.setCurrentMenuId(item ? item.menuId : undefined);
},
setCurrentTag (id) {
if (id == null) {
this.beginPos = 0;
return;
}
let curPos = -1;
for (let i = 0; i < this.tagList.length; i++) {
if (this.tagList[i].menuId === id) {
curPos = (i + 1);
break;
}
}
if (curPos > 0) {
if (curPos > this.getEndPos()) {
let timer = null;
timer = setInterval(() => {
let endPos = this.getEndPos();
if (endPos >= curPos) {
clearInterval(timer);
} else {
this.beginPos++;
}
}, 10);
}
if (curPos < this.beginPos) this.beginPos = curPos;
}
},
getEndPos () {
let width = 0;
let childList = this.$children;
let endPos = 0;
for (let i = this.beginPos; i < childList.length; i++) {
width += childList[i].$el.offsetWidth;
if (width >= this.panelWidth) break;
endPos = i;
}
return endPos;
},
onSizeChange () {
this.$nextTick(() => {
this.panelWidth = this.$el.offsetWidth - 60;
});
},
...mapMutations(['removeTag', 'setCurrentMenuId', 'closeOtherTags', 'clearAllTags'])
},
computed: {
getEndTagPos () {
let width = 0;
let childList = this.$children;
for (let i = this.beginPos; i < childList.length; i++) {
width += childList[i].$el.offsetWidth;
// 间隔距离
width += 5;
if (width > this.panelWidth) {
break;
}
}
return width;
},
...mapGetters(['getCurrentMenuId'])
},
mounted () {
this.panelWidth = this.$el.offsetWidth - 60;
window.addEventListener('resize', this.onSizeChange);
// this.getLastPosition();
},
destroyed () {
window.removeEventListener('resize', this.onSizeChange);
},
watch: {
getCurrentMenuId: {
handler (newValue) {
this.setCurrentTag(newValue);
},
immediate: true
}
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/element-variables.scss';
.tags-panel {
}
.main-panel {
margin: 0px 30px;
}
.scroll-box {
overflow: hidden;
white-space: nowrap;
display: flex;
flex-wrap: nowrap;
align-items: center;
width: 100%;
height: 50px;
}
.arrow {
height: 50px;
line-height: 50px;
width: 30px;
text-align: center;
font-size: 14px;
cursor: pointer;
z-index: 100;
box-sizing: border-box;
}
.arrow.left {
float: left;
}
.arrow.right {
float: right;
}
.contextmenu {
margin: 0px;
z-index: 2;
position: fixed;
list-style-type: none;
padding: 5px 0px;
border-radius: 5px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
}
.contextmenu li {
margin: 0px;
padding: 7px 16px;
cursor: pointer;
}
.contextmenu li:hover {
background: #eee;
}
</style>

View File

@@ -0,0 +1,212 @@
<template>
<el-container :style="getMainStyle">
<el-aside width='250px' class="sidebar">
<side-bar style="overflow: hidden"></side-bar>
</el-aside>
<el-container style="background-color: #F5F8F9">
<el-header class="header" style="box-shadow: 0px 2px 4px 0px rgba(206, 206, 206, 0.5);">
<breadcrumb class="breadcrumb-container" />
<div class="menu-column" v-if="getMultiColumn" style="margin-left: 20px;">
<el-menu mode="horizontal" :default-active="getCurrentColumnId" @select="onColumnChange">
<el-menu-item v-for="column in getColumnList" :key="column.columnId" :index="column.columnId">{{column.columnName}}</el-menu-item>
</el-menu>
</div>
<div class="header-menu" style="flex-grow: 1;">
<el-dropdown class="user-dropdown" trigger="click" @command="handleCommand">
<span class="el-dropdown-link">{{(getUserInfo || {}).showName}}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item class="user-dropdown-item" command="modifyPassword">修改密码</el-dropdown-item>
<el-dropdown-item class="user-dropdown-item" command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<img :src="header" class="header-img" />
</div>
</el-header>
<el-main :style="{'padding-bottom': '15px', 'padding-top': (getMultiTags ? '0px' : '15px')}">
<tag-panel v-if="getMultiTags" :tagList="getTagList" style="margin: 0px 20px;" />
<el-scrollbar :style="getContextStyle" wrap-class="scrollbar_dropdown__wrap">
<transition name="fade" mode="out-in">
<keep-alive :include="getCachePages">
<router-view style="margin: 0px 15px; background-color: white; overflow: hidden; padding: 20px;" :style="getRouterViewStyle" />
</keep-alive>
</transition>
</el-scrollbar>
</el-main>
</el-container>
</el-container>
</template>
<script>
import '@/staticDict/onlineStaticDict.js';
import SideBar from './components/sidebar/sidebar.vue';
import { mapGetters, mapMutations } from 'vuex';
import Breadcrumb from './components/breadcrumb';
import TagPanel from './components/tags/tagPanel.vue';
import formModifyPassword from './components/formModifyPassword/index.vue';
import { SystemController } from '@/api';
import { getToken, setToken } from '@/utils';
export default {
data () {
return {
header: require('../../assets/img/default-header.jpg')
};
},
components: {
'side-bar': SideBar,
'breadcrumb': Breadcrumb,
'tag-panel': TagPanel
},
methods: {
toggleSideBar () {
this.setCollapse(!this.getCollapse);
},
onColumnChange (columnId) {
this.setCurrentColumnId(columnId);
this.clearCachePage();
this.$router.replace({
name: 'welcome'
});
},
resetDocumentClientHeight () {
let timerID;
let _this = this;
return function () {
clearTimeout(timerID);
timerID = setTimeout(() => {
var h = document.documentElement['clientHeight'];
var w = document.documentElement['clientWidth'];
_this.setClientHeight(h);
_this.setClientWidth(w);
}, 50);
}
},
handleCommand (command) {
if (command === 'logout') {
this.$confirm('是否退出登录?', '', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let options = {
headers: {
Authorization: getToken()
},
showMask: false
}
SystemController.logout(this, {}, options).catch(e => {});
this.clearAllTags();
setToken();
window.sessionStorage.removeItem('isUaaLogin');
this.$router.replace({name: 'login'});
}).catch(e => {});
} else if (command === 'modifyPassword') {
this.$dialog.show('修改密码', formModifyPassword, {
area: ['500px']
}, {}).catch(e => {});
}
},
...mapMutations([
'setClientHeight',
'setClientWidth',
'setCurrentColumnId',
'clearCachePage',
'clearAllTags',
'setUserInfo',
'clearOnlineFormCache',
'setMenuList'
])
},
computed: {
getMainStyle () {
return [
{'height': this.getClientHeight + 'px'}
]
},
getContextStyle () {
return [
{'height': this.getMainContextHeight + 'px'}
]
},
getRouterViewStyle () {
return [
{'min-height': this.getMainContextHeight + 'px'}
]
},
...mapGetters([
'getMultiTags',
'getClientHeight',
'getUserInfo',
'getCollapse',
'getCachePages',
'getTagList',
'getMultiColumn',
'getCurrentColumnId',
'getColumnList',
'getMenuItem',
'getMainContextHeight'
])
},
mounted () {
let resetHeight = this.resetDocumentClientHeight();
resetHeight();
window.onresize = () => {
resetHeight();
}
// 重新获取登录信息
if (getToken() != null && getToken() !== '' && this.getUserInfo == null) {
SystemController.getLoginInfo(this, {}).then(data => {
this.setMenuList(data.data.menuList);
delete data.data.menuList;
this.setUserInfo(data.data);
}).catch(e => {});
}
},
watch: {
getMenuItem: {
handler (newValue) {
if (newValue == null) {
if (this.$route.name !== 'welcome') {
this.$router.replace({
name: 'welcome'
});
}
} else {
if (newValue.onlineFormId == null) {
this.$router.replace({
name: newValue.formRouterName
});
} else {
this.clearOnlineFormCache();
if (newValue.onlineFlowEntryId == null) {
this.$router.replace({
name: 'onlineForm',
query: {
formId: newValue.onlineFormId,
formType: this.SysOnlineFormType.QUERY
}
});
} else {
this.$router.replace({
name: 'onlineForm',
query: {
formId: newValue.onlineFormId,
entryId: newValue.onlineFlowEntryId,
formType: this.SysOnlineFormType.WORK_ORDER
}
});
}
}
}
},
immediate: true
}
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,130 @@
<template>
<div class="login-form">
<div class="login-box">
<img :src="bkImg" style="height: 100%; flex-shrink: 0" />
<div class="login-input">
<img :src="logoImg" />
<span class="title">中台化低代码生成工具</span>
<el-form :model="dataForm" :rules="dataRule" size="medium" ref="dataForm" @keyup.enter.native="dataFormSubmit()" style="width: 356px; margin-top: 4vh;">
<el-col :span="24">
<el-form-item prop="mobilePhone">
<el-input v-model="dataForm.mobilePhone" style="width: 100%;" placeholder="帐号"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="password">
<el-input v-model="dataForm.password" style="width: 100%;" type="password" placeholder="密码" show-password></el-input>
</el-form-item>
</el-col>
<el-button class="login-btn-submit" type="warning" style="width: 100%;"
@click="dataFormSubmit()"
:loading="isHttpLoading">
登录
</el-button>
</el-form>
</div>
</div>
</div>
</template>
<script>
import { SystemController } from '@/api';
import { mapMutations } from 'vuex';
import projectConfig from '@/core/config';
import { encrypt, setToken } from '@/utils';
export default {
data () {
return {
bkImg: require('@/assets/img/login.png'),
logoImg: require('@/assets/img/login_logo.png'),
dataForm: {
mobilePhone: 'admin',
password: '123456'
},
dataRule: {
mobilePhone: [
{ required: true, message: '帐号不能为空', trigger: 'blur' }
],
password: [
{ required: true, message: '密码不能为空', trigger: 'blur' }
]
},
projectName: projectConfig.projectName
};
},
methods: {
dataFormSubmit () {
this.$refs['dataForm'].validate(valid => {
if (valid) {
let params = {
loginName: this.dataForm.mobilePhone,
password: encrypt(this.dataForm.password)
};
SystemController.login(this, params, null, {showMask: false}).then(data => {
this.setMenuList(data.data.menuList);
delete data.data.menuList;
this.setUserInfo(data.data);
setToken(data.data.tokenData);
this.setCurrentMenuId(null);
this.$router.replace({ name: 'main' });
}).catch(e => {});
}
});
},
...mapMutations(['setUserInfo', 'setMenuList', 'setCurrentMenuId'])
},
mounted () {
this.setMenuList([]);
this.setUserInfo({});
setToken();
}
};
</script>
<style lang="scss">
.login-form {
width: 100vw;
height: 100vh;
background: #292D36;
display: flex;
justify-content: center;
align-items: center;
.login-box {
display: flex;
align-items: center;
height: 70vh;
padding: 7vh;
border-radius: 3px;
background: white;
.login-input {
height: 100%;
width: 420px;
display: flex;
align-items: center;
flex-direction: column;
img {
width: 356px;
height: 42px;
margin-top: 6vh;
}
.title {
color: #232323;
font-size: 20px;
margin-top: 2vh;
}
}
}
}
.login-form .el-input__inner {
height: 45px!important;
}
.login-form .el-button {
height: 45px!important;
font-size: 20px;
}
</style>

View File

@@ -0,0 +1,154 @@
<template>
<el-form-item :label="widgetConfig.showName + ''" :prop="widgetConfig.variableName">
<el-input v-if="widgetConfig.widgetType === SysCustomWidgetType.Input"
class="filter-item" clearable
:type="widgetConfig.type"
:autosize="{minRows: widgetConfig.minRows || 1, maxRows: widgetConfig.maxRows || 1}"
:disabled="widgetConfig.disabled"
:value="value" @input="handlerWidgetInput"
:placeholder="widgetConfig.placeholder"
/>
<el-input-number v-if="widgetConfig.widgetType === SysCustomWidgetType.NumberInput"
class="filter-item" clearable
:disabled="widgetConfig.disabled"
:min="widgetConfig.min"
:max="widgetConfig.max"
:step="widgetConfig.step"
:precision="widgetConfig.precision"
:controls="widgetConfig.controlVisible === 1"
:controls-position="widgetConfig.controlPosition === 1 ? 'right' : undefined"
:value="value" @input="handlerWidgetInput"
:placeholder="widgetConfig.placeholder"
/>
<el-select v-if="widgetConfig.widgetType === SysCustomWidgetType.Select"
class="filter-item" clearable filterable
:disabled="widgetConfig.disabled"
:value="value" @input="handlerWidgetInput"
:placeholder="widgetConfig.placeholder"
:loading="dropdownWidget.loading"
@visible-change="dropdownWidget.onVisibleChange"
@change="handlerWidgetChange"
>
<el-option v-for="item in dropdownWidget.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
<el-cascader v-if="widgetConfig.widgetType === SysCustomWidgetType.Cascader"
class="filter-item" filterable
:options="dropdownWidget.dropdownList"
:value="cascaderValue" @input="handlerWidgetInput"
:clearable="true" :show-all-levels="false"
:placeholder="widgetConfig.placeholder"
:props="{value: 'id', label: 'name', checkStrictly: true}"
@visible-change="(isShow) => dropdownWidget.onVisibleChange(isShow).catch(e => {})"
@change="handlerWidgetChange"
/>
<date-range v-if="widgetConfig.widgetType === SysCustomWidgetType.DateRange"
class="filter-item" :value="value" @input="handlerWidgetInput"
:clearable="true" :allowTypes="['day']" align="left"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss"
/>
<input-number-range v-if="widgetConfig.widgetType === SysCustomWidgetType.NumberRange"
class="filter-item" :value="value" @input="handlerWidgetInput"
:clearable="true" startPlaceholder="最小值" endPlaceholder="最大值" />
</el-form-item>
</template>
<script>
import { DropdownWidget } from '@/utils/widget.js';
import { findTreeNodePath } from '@/utils';
import { getDictDataList } from '../utils';
export default {
props: {
widgetConfig: {
type: Object,
required: true
},
dictList: {
type: Object,
default: () => {}
},
value: {
type: [String, Number, Date, Object, Array]
},
getDropdownParams: {
type: Function
}
},
inject: ['preview'],
data () {
return {
cascaderValue: [],
dropdownWidget: (this.widgetConfig.widgetType === this.SysCustomWidgetType.Select || this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader)
? new DropdownWidget(this.loadDropdwonList, this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader) : undefined
}
},
methods: {
reset () {
this.handlerWidgetInput(undefined);
this.cascaderValue = [];
if (this.dropdownWidget) this.dropdownWidget.dirty = true;
},
handlerWidgetInput (value) {
if (this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader) {
if (Array.isArray(value) && value.length > 0) {
this.cascaderValue = value;
this.$emit('input', value[value.length - 1], this.widgetConfig);
} else {
this.$emit('input', undefined, this.widgetConfig);
}
} else {
this.$emit('input', value, this.widgetConfig);
}
},
handlerWidgetChange (value) {
this.$emit('change', value);
},
loadDropdwonList () {
if (this.preview()) {
return Promise.resolve([]);
}
return new Promise((resolve, reject) => {
if (this.widgetConfig.column != null && this.widgetConfig.column.dictInfo != null) {
let params = {};
let dictInfo = this.widgetConfig.column.dictInfo;
if (dictInfo.dictType === this.SysOnlineDictType.TABLE ||
dictInfo.dictType === this.SysOnlineDictType.URL) {
params = this.getDropdownParams ? this.getDropdownParams(this.widgetConfig) : {};
}
if (params == null) {
resolve([]);
} else {
getDictDataList(this, dictInfo, params).then(res => {
resolve(res);
}).catch(e => {
console.log(e);
reject(e);
});
}
} else {
reject();
}
});
},
getDropdownImpl () {
return this.dropdownWidget;
},
onVisibleChange () {
if (this.dropdownWidget) {
this.dropdownWidget.onVisibleChange(true).then(res => {
// 级联组件获取下拉数据计算组件显示path
if (this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader) {
this.cascaderValue = findTreeNodePath(res, this.value, 'id');
}
});
}
}
},
mounted () {
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,28 @@
<template>
<el-col :span="widgetConfig.span || 24">
<img :src="widgetConfig.src" :height="widgetConfig.height" :width="widgetConfig.width"
style="max-width: 100%;" :style="getImageStyle"
/>
</el-col>
</template>
<script>
export default {
props: {
widgetConfig: {
type: Object,
required: true
}
},
computed: {
getImageStyle () {
return {
'object-fit': this.widgetConfig.fit
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,529 @@
<template>
<el-col :span="widgetConfig.span">
<el-row :style="{'margin-bottom': widgetConfig.supportBottom === 1 ? '20px' : undefined}">
<el-col :span="24" style="margin-bottom: 10px;" v-if="formType !== SysOnlineFormType.QUERY && formType !== SysOnlineFormType.WORK_ORDER">
<el-row type="flex" justify="space-between">
<div class="table-title" :style="{'border-left': '3px solid ' + widgetConfig.titleColor}">
{{widgetConfig.showName}}
</div>
<div>
<el-button size="mini"
v-for="operation in getTableOperation(false)" :key="operation.id"
:plain="operation.plain"
:type="operation.btnType"
@click.stop="onOperationClick(operation)">
{{operation.name}}
</el-button>
</div>
</el-row>
</el-col>
<el-col :span="24">
<el-table size="mini" header-cell-class-name="table-header-gray" ref="tableImpl"
:style="{height: (widgetConfig.tableInfo.height != null && widgetConfig.tableInfo.height !== '') ? widgetConfig.tableInfo.height + 'px' : undefined}"
:height="(widgetConfig.tableInfo.height != null && widgetConfig.tableInfo.height !== '') ? widgetConfig.tableInfo.height + 'px' : undefined"
:data="tableWidget.dataList" :row-key="primaryColumnName"
@sort-change="tableWidget.onSortChange">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="tableWidget.getTableIndex" />
<template v-for="tableColumn in widgetConfig.tableColumnList">
<!-- Boolean类型的字段使用el-tag去显示 -->
<el-table-column v-if="(tableColumn.column || {}).objectFieldType === 'Boolean'" :key="tableColumn.dataFieldName"
:label="tableColumn.showName" :width="tableColumn.columnWidth + 'px'"
:prop="tableColumn.column.columnName"
:sortable="tableColumn.sortable ? 'custom' : false"
>
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row[tableColumn.dataFieldName] ? 'success' : 'danger'">
{{scope.row[tableColumn.dataFieldName] ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<!-- 普通非字典字段 -->
<template v-else-if="(tableColumn.column || {}).dictInfo == null">
<el-table-column :label="tableColumn.showName"
v-if="tableColumn.column &&
(tableColumn.column.fieldKind === SysOnlineFieldKind.UPLOAD ||
tableColumn.column.fieldKind === SysOnlineFieldKind.UPLOAD_IMAGE)"
:key="(tableColumn.column || {}).objectFieldName"
:width="tableColumn.columnWidth + 'px'"
>
<template slot-scope="scope">
<template v-if="tableColumn.column.fieldKind === SysOnlineFieldKind.UPLOAD_IMAGE">
<el-image
v-for="item in parseTableUploadData(tableColumn, scope.row)"
:preview-src-list="getTablePictureList(tableColumn, scope.row)"
class="table-cell-image" :key="item.url" :src="item.url" fit="fill">
<div slot="error" class="table-cell-image">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</template>
<template v-else>
<a v-for="item in parseTableUploadData(tableColumn, scope.row)"
:key="item.url" href="javascript:void(0);" @click="downloadFile(item.url, item.name)">
{{item.name}}
</a>
</template>
</template>
</el-table-column>
<el-table-column v-else :key="(tableColumn.column || {}).objectFieldName"
:label="tableColumn.showName" :prop="tableColumn.dataFieldName"
:width="tableColumn.columnWidth + 'px'"
:sortable="tableColumn.sortable ? 'custom' : false"
/>
</template>
<!-- 字典字段 -->
<el-table-column v-else :key="(tableColumn.column || {}).objectFieldName"
:label="tableColumn.showName" :width="tableColumn.columnWidth + 'px'"
:prop="tableColumn.column.columnName"
:sortable="tableColumn.sortable ? 'custom' : false"
>
<template slot-scope="scope">
<span>
{{getDictValue(tableColumn, scope.row)}}
</span>
</template>
</el-table-column>
</template>
<el-table-column v-if="formType === SysOnlineFormType.WORK_ORDER" label="流程创建时间" width="180px" prop="createTime" />
<el-table-column v-if="formType === SysOnlineFormType.WORK_ORDER" label="流程状态" width="100px" prop="flowStatus" />
<el-table-column
v-if="getTableOperation(true).length > 0 || formType === SysOnlineFormType.WORK_ORDER"
label="操作" :width="(widgetConfig.tableInfo.optionColumnWidth || 150) + 'px'" fixed="right"
>
<template slot-scope="scope">
<el-button v-for="operation in getTableOperation(true)" :key="operation.id"
:class="operation.btnClass"
type="text" size="mini"
@click.stop="onOperationClick(operation, scope.row)"
>
{{operation.name}}
</el-button>
<el-button type="text" size="mini"
v-if="formType === SysOnlineFormType.WORK_ORDER && (scope.row.initTaskInfo || {}).taskKey !== (scope.row.runtimeTaskInfo || {}).taskKey"
@click.stop="onViewWorkOrder(scope.row)">
详情
</el-button>
<el-button type="text" size="mini"
v-if="formType === SysOnlineFormType.WORK_ORDER && (scope.row.initTaskInfo || {}).taskKey === (scope.row.runtimeTaskInfo || {}).taskKey"
@click.stop="onHandlerWorkOrder(scope.row)">
办理
</el-button>
<el-button type="text" size="mini" class="table-btn error"
v-if="formType === SysOnlineFormType.WORK_ORDER"
@click.stop="onCancelWorkOrder(scope.row)">
撤销
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
<!-- 分页组件 -->
<el-col :span="24" v-if="widgetConfig.tableInfo.paged && !this.isNew"
:style="{'margin-bottom': widgetConfig.supportBottom === 1 ? '20px' : undefined}"
>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="tableWidget.totalCount"
:current-page="tableWidget.currentPage"
:page-size="tableWidget.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="tableWidget.onCurrentPageChange"
@size-change="tableWidget.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</el-col>
</template>
<script>
import { mapGetters } from 'vuex';
import { TableWidget } from '@/utils/widget.js';
import { uploadMixin } from '@/core/mixins';
import { getDictDataList, getDictDataByUrl } from '../utils/index.js';
export default {
props: {
formType: {
type: Number,
required: true
},
widgetConfig: {
type: Object,
required: true
},
getTableQueryParams: {
type: Function
},
loadTableDataFunc: {
type: Function
},
flowData: {
type: Object
},
// 是否是新建表格,如果为新建,增删改不会调用后台接口,直接把数据放到表格中
isNew: {
type: Boolean,
default: false
}
},
inject: ['preview'],
mixins: [uploadMixin],
data () {
return {
// 表格用到的字典数据
tableDictValueListMap: new Map(),
tableWidget: new TableWidget(
this.loadTableData,
this.loadTableVerify,
this.widgetConfig.tableInfo.paged && !this.isNew,
false,
this.widgetConfig.tableInfo.orderFieldName,
this.widgetConfig.tableInfo.ascending
)
}
},
methods: {
onViewWorkOrder (row) {
this.$emit('viewWOrkOrder', row, this.widgetConfig);
},
onHandlerWorkOrder (row) {
this.$emit('handlerWOrkOrder', row, this.widgetConfig);
},
onCancelWorkOrder (row) {
this.$emit('cancelWOrkOrder', row, this.widgetConfig);
},
getTableWidget () {
return this.tableWidget;
},
setTableWidget (tableWidget) {
// 如果正在读取数据,等待读取完毕再刷新
let timer = setInterval(() => {
if (!this.tableWidget.loading) {
this.tableWidget.totalCount = tableWidget.totalCount;
this.tableWidget.currentPage = tableWidget.currentPage;
this.tableWidget.pageSize = tableWidget.pageSize;
this.tableWidget.refreshTable();
clearInterval(timer);
}
}, 30);
},
onOperationClick (operation, row) {
this.$emit('operationClick', operation, row, this.widgetConfig);
},
loadTableDictValue (tableData) {
return new Promise((resolve, reject) => {
// URL字典数据获取列表
let httpCallInfoList = [];
let dictIdMap = new Map();
this.widgetConfig.tableColumnList.forEach(tableColumn => {
let column = tableColumn.column;
// URL字典字典值数据分组
if (column && column.dictInfo && column.dictInfo.dictType === this.SysOnlineDictType.URL) {
let fieldName = tableColumn.dataFieldName;
let urlDictIdInfo = dictIdMap.get(column.dictInfo.dictId);
if (urlDictIdInfo == null) {
let dictValueMap = this.tableDictValueListMap.get(column.dictInfo.dictId);
urlDictIdInfo = {
column,
dictInfo: column.dictInfo,
dictValueMap,
paramSet: new Set()
}
httpCallInfoList.push(urlDictIdInfo);
dictIdMap.set(column.dictInfo.dictId, urlDictIdInfo)
}
if (Array.isArray(tableData.dataList)) {
tableData.dataList.forEach(row => {
let value = row[fieldName];
urlDictIdInfo.paramSet.add(value);
});
}
}
});
Promise.all(httpCallInfoList.map(dictInfoItem => {
if (dictInfoItem.dictInfo.dictIdsUrl == null || this.preview()) {
if (!this.preview()) {
this.$message.error('数据表字段 [' + dictInfoItem.column.columnName + '] 绑定字典 [' + dictInfoItem.dictInfo.dictName + '] 未发现获取指定ids数据url');
}
resolve([]);
} else {
let dictIds = [];
dictInfoItem.paramSet.forEach(item => {
dictIds.push(item);
});
let params = {
dictIds: dictIds
}
return getDictDataByUrl(dictInfoItem.dictInfo.dictIdsUrl, params, dictInfoItem.dictInfo, 'post');
}
})).then((dictValueDataList) => {
dictValueDataList.forEach((dictDataList, index) => {
dictDataList.forEach(data => {
httpCallInfoList[index].dictValueMap.set(data.id, data);
});
});
resolve(tableData);
}).catch(e => {
reject(e);
});
});
},
loadTableData (params) {
if (this.widgetConfig.datasource == null || this.isNew) {
return Promise.resolve({
dataList: this.tableWidget.dataList,
totalCount: 0
});
}
if (params == null) params = {};
let queryParams = this.getTableQueryParams ? this.getTableQueryParams(this.widgetConfig) : undefined;
params = {
datasourceId: this.widgetConfig.datasource.datasourceId,
relationId: this.widgetConfig.relation ? this.widgetConfig.relation.relationId : undefined,
...params,
filterDtoList: queryParams
}
return new Promise((resolve, reject) => {
if (typeof this.loadTableDataFunc === 'function') {
return this.loadTableDataFunc(params).then(res => {
// 获取表格字典数据
return this.loadTableDictValue(res);
}).then(res => {
resolve(res);
}).catch(e => {
reject(e);
});
}
let httpCall = null;
if (params.relationId) {
httpCall = this.doUrl('/admin/online/onlineOperation/listByOneToManyRelationId/' + this.widgetConfig.datasource.variableName, 'post', params);
} else {
httpCall = this.doUrl('/admin/online/onlineOperation/listByDatasourceId/' + this.widgetConfig.datasource.variableName, 'post', params);
}
httpCall.then(res => {
// 获取表格字典数据
return this.loadTableDictValue(res.data);
}).then(res => {
resolve({
dataList: res.dataList,
totalCount: res.totalCount
});
}).catch(e => {
reject(e);
});
});
},
loadTableVerify () {
return true;
},
// 页面是否是返回状态
isResume () {
let key = this.$route.fullPath;
let cacheFormData = this.getOnlineFormCache[key];
return cacheFormData != null;
},
/**
* 刷新表格数据
* row表格数据如果表格数据为空则重新获取
* operatorType表格数据操作类型
*/
refresh (row, operatorType) {
if (this.isResume()) return;
if (!this.isNew) {
// 重新获取表格数据
this.tableWidget.refreshTable();
} else {
if (operatorType === this.SysCustomWidgetOperationType.ADD) this.tableWidget.dataList.push(row);
if (operatorType === this.SysCustomWidgetOperationType.EDIT) {
this.tableWidget.dataList = this.tableWidget.dataList.map(item => {
if (item[this.primaryColumnName] === row[this.primaryColumnName]) {
return {
...row
}
} else {
return item;
}
});
}
if (operatorType === this.SysCustomWidgetOperationType.DELETE) {
this.tableWidget.dataList = this.tableWidget.dataList.filter(item => {
return item !== row;
});
}
}
},
getTableOperation (rowOperation) {
if (this.widgetConfig.readOnly) return [];
let tempList = this.widgetConfig.operationList.filter(operation => {
return operation.rowOperation === rowOperation && operation.enabled;
});
// 自定义操作前置
if (rowOperation) {
let customOperation = [];
return customOperation.concat(tempList.filter(item => {
if (item.type === this.SysCustomWidgetOperationType.CUSTOM) customOperation.push(item);
return item.type !== this.SysCustomWidgetOperationType.CUSTOM;
}));
}
return tempList;
},
/**
* 获取表格列字段在后端返回的接口中字段名
*/
getTableColumnFieldName (tableColumn) {
if (tableColumn.column == null) return null;
let fieldName = tableColumn.column.columnName || tableColumn.column.objectFieldName;
// 工单列表
if (this.formType === this.SysOnlineFormType.WORK_ORDER) {
fieldName = 'masterTable__' + fieldName;
} else {
if (tableColumn.relation != null) {
fieldName = tableColumn.relation.variableName + '__' + fieldName;
}
/*
if (tableColumn.column.dictInfo && tableColumn.column.dictInfo.dictType === this.SysOnlineDictType.TABLE) {
fieldName = fieldName + '__DictMap';
}
*/
}
return fieldName;
},
/**
* 获取表格cell数据字典值
*/
getDictValue (tableColumn, row) {
let dictData = null;
let value = row[tableColumn.dataFieldName];
// 如果有DictMap信息优先使用DictMap信息
if (tableColumn.column.dictInfo != null) {
if (row[tableColumn.dataFieldName + '__DictMap']) {
return row[tableColumn.dataFieldName + '__DictMap'].name;
}
}
let dictValueList = this.tableDictValueListMap.get(tableColumn.column.dictInfo.dictId);
if (dictValueList != null) {
dictData = dictValueList.get(value);
}
return dictData ? dictData.name : undefined;
},
getDownloadUrl (tableColumn) {
let downloadUrl = null;
if (this.flowData != null) {
downloadUrl = '/admin/flow/flowOnlineOperation/download';
} else {
if (tableColumn.relationId) {
downloadUrl = '/admin/online/onlineOperation/downloadOneToManyRelation/' + (this.widgetConfig.datasource || {}).variableName;
} else {
downloadUrl = '/admin/online/onlineOperation/downloadDatasource/' + (this.widgetConfig.datasource || {}).variableName;
}
}
return downloadUrl;
},
parseTableUploadData (tableColumn, row) {
let jsonData = row[tableColumn.dataFieldName];
if (jsonData == null) return [];
let downloadParams = {
...this.buildFlowParam,
datasourceId: this.widgetConfig.datasource.datasourceId,
relationId: tableColumn.relationId,
fieldName: tableColumn.column.columnName,
asImage: tableColumn.column.fieldKind === this.SysOnlineFieldKind.UPLOAD_IMAGE
}
if (this.primaryColumnName != null) {
downloadParams.dataId = row[this.primaryColumnName] || '';
}
let downloadUrl = this.getDownloadUrl(tableColumn);
let temp = JSON.parse(jsonData).map(item => {
return {
...item,
downloadUri: downloadUrl
}
})
return this.parseUploadData(JSON.stringify(temp), downloadParams);
},
getTablePictureList (tableColumn, row) {
let temp = this.parseTableUploadData(tableColumn, row);
if (Array.isArray(temp)) {
return temp.map(item => item.url);
}
}
},
mounted () {
if (Array.isArray(this.widgetConfig.tableColumnList)) {
// 字典数据获取信息,包含静态字典和自定义字典信息
let httpCallInfoList = [];
this.widgetConfig.tableColumnList.forEach(tableColumn => {
tableColumn.dataFieldName = this.getTableColumnFieldName(tableColumn);
let column = tableColumn.column;
if (column && column.dictInfo && column.dictInfo.dictType !== this.SysOnlineDictType.TABLE) {
if (!this.tableDictValueListMap.has(column.dictInfo.dictId)) {
let tempMap = new Map();
this.tableDictValueListMap.set(column.dictInfo.dictId, tempMap);
if (column.dictInfo.dictType !== this.SysOnlineDictType.URL) {
httpCallInfoList.push({
valueMap: tempMap,
httpCall: getDictDataList(this, column.dictInfo)
});
}
}
}
});
// 获取所有静态字典和自定义字典数据
Promise.all(httpCallInfoList.map(item => item.httpCall)).then(dictValueList => {
dictValueList.forEach((dictDataList, index) => {
if (Array.isArray(dictDataList)) {
dictDataList.forEach(data => {
httpCallInfoList[index].valueMap.set(data.id, data);
});
}
});
this.refresh();
}).catch(e => {
this.$message.error('获取表格字典数据失败!');
});
} else {
this.refresh();
}
},
computed: {
buildFlowParam () {
let flowParam = {};
if (this.flowData) {
if (this.flowData.processDefinitionKey) flowParam.processDefinitionKey = this.flowData.processDefinitionKey;
if (this.flowData.processInstanceId) flowParam.processInstanceId = this.flowData.processInstanceId;
if (this.flowData.taskId) flowParam.taskId = this.flowData.taskId;
}
return flowParam;
},
primaryColumnName () {
if (this.widgetConfig && this.widgetConfig.table && Array.isArray(this.widgetConfig.table.columnList)) {
for (let i = 0; i < this.widgetConfig.table.columnList.length; i++) {
let column = this.widgetConfig.table.columnList[i];
if (column.primaryKey) {
return (this.widgetConfig.relation ? this.widgetConfig.relation.variableName + '__' : '') + column.columnName;
}
}
}
return null;
},
...mapGetters(['getOnlineFormCache'])
}
}
</script>
<style scoped>
.table-title {
padding: 0px 5px;
height: 22px;
line-height: 22px;
margin: 3px 0px;
}
</style>

View File

@@ -0,0 +1,35 @@
<template>
<el-row>
<el-col :span="widgetConfig.span || 24">
<div :style="getTextStyle">{{widgetConfig.showName}}</div>
</el-col>
</el-row>
</template>
<script>
export default {
props: {
widgetConfig: {
type: Object,
required: true
}
},
computed: {
getTextStyle () {
return {
'color': this.widgetConfig.color,
'background-color': this.widgetConfig.backgroundColor,
'font-size': this.widgetConfig.fontSize != null ? this.widgetConfig.fontSize + 'px' : undefined,
'line-height': this.widgetConfig.lineHeight != null ? this.widgetConfig.lineHeight + 'px' : undefined,
'text-indent': this.widgetConfig.indent != null ? this.widgetConfig.indent + 'em' : undefined,
'text-decoration': this.widgetConfig.decoration,
'text-align': this.widgetConfig.align,
'padding': this.widgetConfig.padding + 'px'
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,187 @@
<template>
<el-col :span="widgetConfig.span || 24">
<el-form-item :label="widgetConfig.showName + ''"
:prop="(widgetConfig.relation ? (widgetConfig.relation.variableName + '__') : '') + (widgetConfig.column || {}).columnName">
<el-upload v-if="!widgetConfig.readOnly"
:class="{
'upload-image-item': widgetConfig.isImage,
'upload-image-multi': widgetConfig.column.maxFileCount !== 1
}"
:name="widgetConfig.fileFieldName"
:headers="getUploadHeaders"
:action="getActionUrl"
:data="getUploadData"
:on-success="onUploadSuccess"
:on-remove="onRemoveFile"
:on-error="onUploadError"
:on-exceed="onUploadLimit"
:limit="widgetConfig.column.maxFileCount"
:show-file-list="widgetConfig.column.maxFileCount !== 1 || !widgetConfig.isImage"
:list-type="getUploadListType"
:file-list="getUploadFileList"
:disabled="widgetConfig.disabled"
>
<!-- 上传图片 -->
<template v-if="widgetConfig.isImage && widgetConfig.column.maxFileCount === 1">
<div v-if="getUploadFileList && getUploadFileList[0] != null" style="position: relative">
<img class="upload-image-show" :src="getUploadFileList[0].url" />
<div class="upload-img-del el-icon-close" @click.stop="onRemoveFile(null, null)" />
</div>
<i v-else class="el-icon-plus upload-image-item"></i>
</template>
<!-- 上传文件 -->
<template v-else-if="!widgetConfig.isImage">
<el-button size="mini" type="primary">点击上传</el-button>
</template>
</el-upload>
<template v-else>
<template v-for="item in uploadWidgetImpl.fileList">
<img class="table-cell-image" v-if="widgetConfig.isImage" :key="item.url" :src="item.url" />
<a v-else :key="item.url" href="javascript:void(0);" @click="downloadFile(item.url, item.name)">
{{item.name}}
</a>
</template>
</template>
</el-form-item>
</el-col>
</template>
<script>
// import { buildGetUrl } from '@/core/http/requestUrl.js';
import { UploadWidget } from '@/utils/widget.js';
import { uploadMixin } from '@/core/mixins';
export default {
props: {
widgetConfig: {
type: Object,
required: true
},
flowData: {
type: Object
},
value: {
type: String
},
getDataId: {
type: Function
}
},
mixins: [uploadMixin],
data () {
return {
uploadWidgetImpl: new UploadWidget(this.widgetConfig.column.maxFileCount)
}
},
methods: {
onValueChange () {
this.$emit('input', this.fileListToJson(this.uploadWidgetImpl.fileList), this.widgetConfig);
},
onUploadSuccess (response, file, fileList) {
if (response.success) {
file.filename = response.data.filename;
file.url = URL.createObjectURL(file.raw);
this.uploadWidgetImpl.onFileChange(file, fileList);
this.onValueChange();
} else {
this.$message.error(response.message);
}
},
onRemoveFile (file, fileList) {
this.uploadWidgetImpl.onFileChange(file, fileList);
this.onValueChange();
},
onUploadError (e, file, fileList) {
this.$message.error('文件上传失败');
},
onUploadLimit (files, fileList) {
if (this.widgetConfig.column.maxFileCount != null && this.widgetConfig.column.maxFileCount > 0) {
this.$message.error('已经超出最大上传个数限制');
}
}
},
computed: {
buildFlowParam () {
let flowParam = {};
if (this.flowData) {
if (this.flowData.processDefinitionKey) flowParam.processDefinitionKey = this.flowData.processDefinitionKey;
if (this.flowData.processInstanceId) flowParam.processInstanceId = this.flowData.processInstanceId;
if (this.flowData.taskId) flowParam.taskId = this.flowData.taskId;
}
return flowParam;
},
getActionUrl () {
if (this.widgetConfig.actionUrl == null || this.widgetConfig.actionUrl === '') {
if (this.widgetConfig.relation) {
return this.getUploadActionUrl('/admin/online/onlineOperation/uploadOneToManyRelation/' + (this.widgetConfig.datasource || {}).variableName);
} else {
return this.getUploadActionUrl('/admin/online/onlineOperation/uploadDatasource/' + (this.widgetConfig.datasource || {}).variableName);
}
} else {
return this.getUploadActionUrl(this.widgetConfig.actionUrl);
}
},
getDownloadUrl () {
if (this.widgetConfig.downloadUrl == null || this.widgetConfig.downloadUrl === '') {
if (this.widgetConfig.relation) {
return '/admin/online/onlineOperation/downloadOneToManyRelation/' + (this.widgetConfig.datasource || {}).variableName;
} else {
return '/admin/online/onlineOperation/downloadDatasource/' + (this.widgetConfig.datasource || {}).variableName;
}
} else {
return this.widgetConfig.downloadUrl;
}
},
getUploadData () {
let temp = {
...this.buildFlowParam,
datasourceId: (this.widgetConfig.datasource || {}).datasourceId,
asImage: this.widgetConfig.isImage,
fieldName: (this.widgetConfig.column || {}).columnName
}
if ((this.widgetConfig.relation || {}).relationId) temp.relationId = (this.widgetConfig.relation || {}).relationId;
return temp;
},
getUploadListType () {
if (this.widgetConfig.column.maxFileCount !== 1 && this.widgetConfig.isImage) {
return 'picture-card';
}
return 'text';
},
getUploadFileList () {
return this.uploadWidgetImpl ? this.uploadWidgetImpl.fileList : [];
}
},
mounted () {
},
watch: {
value: {
handler (newValue) {
this.uploadWidgetImpl.fileList = [];
if (newValue != null) {
let downloadParams = {
...this.buildFlowParam,
datasourceId: this.widgetConfig.datasourceId,
fieldName: this.widgetConfig.column.columnName,
asImage: this.widgetConfig.isImage,
dataId: this.getDataId(this.widgetConfig) || ''
}
if (this.widgetConfig.relationId) downloadParams.relationId = this.widgetConfig.relationId;
let temp = JSON.parse(newValue).map(item => {
return {
...item,
downloadUri: this.getDownloadUrl
}
})
this.uploadWidgetImpl.fileList = this.parseUploadData(JSON.stringify(temp), downloadParams);
}
},
immediate: true
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,227 @@
<template>
<el-col :span="widgetConfig.span || 24">
<!-- 表单输入组件 -->
<template v-if="widgetConfig.widgetKind === SysCustomWidgetKind.Form">
<!-- 只读或者文本字段 -->
<template v-if="widgetConfig.widgetType === SysCustomWidgetType.Label || widgetConfig.readOnly">
<el-form-item :label="widgetConfig.showName + ''">
<span v-if="widgetConfig.widgetType === SysCustomWidgetType.Label ||
widgetConfig.widgetType === SysCustomWidgetType.NumberInput ||
widgetConfig.widgetType === SysCustomWidgetType.Input ||
widgetConfig.widgetType === SysCustomWidgetType.Date"
>
{{value}}
</span>
<span v-else-if="widgetConfig.widgetType === SysCustomWidgetType.Select">{{getDictValue(value)}}</span>
<div v-else-if="widgetConfig.widgetType === SysCustomWidgetType.RichEditor" v-html="value" />
<span v-else-if="widgetConfig.widgetType === SysCustomWidgetType.Switch">{{value ? '是' : '否'}}</span>
</el-form-item>
</template>
<template v-else>
<el-form-item :label="widgetConfig.showName + ''"
:prop="(widgetConfig.relation ? (widgetConfig.relation.variableName + '__') : '') + (widgetConfig.column || {}).columnName">
<el-input v-if="widgetConfig.widgetType === SysCustomWidgetType.Input"
class="input-class" clearable
:type="widgetConfig.type"
:autosize="{minRows: widgetConfig.minRows || 1, maxRows: widgetConfig.maxRows || 1}"
:disabled="widgetConfig.disabled"
:value="value" @input="handlerWidgetInput"
:placeholder="widgetConfig.placeholder"
/>
<el-input-number v-if="widgetConfig.widgetType === SysCustomWidgetType.NumberInput"
class="input-item" clearable
:disabled="widgetConfig.disabled"
:min="widgetConfig.min"
:max="widgetConfig.max"
:step="widgetConfig.step"
:precision="widgetConfig.precision"
:controls="widgetConfig.controlVisible === 1"
:controls-position="widgetConfig.controlPosition === 1 ? 'right' : undefined"
:value="value" @input="handlerWidgetInput"
:placeholder="widgetConfig.placeholder"
/>
<el-select v-if="widgetConfig.widgetType === SysCustomWidgetType.Select"
class="input-item" clearable filterable
:disabled="widgetConfig.disabled"
:value="value" @input="handlerWidgetInput"
:placeholder="widgetConfig.placeholder"
:loading="dropdownWidget.loading"
@visible-change="(isShow) => dropdownWidget.onVisibleChange(isShow).catch(e => {})"
@change="handlerWidgetChange"
>
<el-option v-for="item in dropdownWidget.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
<el-cascader v-if="widgetConfig.widgetType === SysCustomWidgetType.Cascader"
class="input-item" filterable
:options="dropdownWidget.dropdownList"
:value="cascaderValue" @input="handlerWidgetInput"
:clearable="true" :show-all-levels="false"
:placeholder="widgetConfig.placeholder"
:props="{value: 'id', label: 'name', checkStrictly: true}"
@visible-change="(isShow) => dropdownWidget.onVisibleChange(isShow).catch(e => {})"
@change="handlerWidgetChange"
/>
<el-date-picker v-if="widgetConfig.widgetType === SysCustomWidgetType.Date"
:format="widgetConfig.format || 'yyyy-MM-dd'" :value-format="widgetConfig.valueFormat || 'yyyy-MM-dd 00:00:00'"
class="input-item" clearable :type="widgetConfig.type || 'date'" align="left"
:disabled="widgetConfig.disabled"
:value="value" @input="handlerWidgetInput"
:placeholder="widgetConfig.placeholder"
@change="handlerWidgetChange"
/>
<rich-editor v-if="widgetConfig.widgetType === SysCustomWidgetType.RichEditor"
class="input-item" :value="value" @input="handlerWidgetInput" />
<el-switch v-if="widgetConfig.widgetType === SysCustomWidgetType.Switch"
class="input-item" :value="value" @input="handlerWidgetInput" />
</el-form-item>
</template>
</template>
<!-- 数据展示组件 -->
<template v-else-if="widgetConfig.widgetKind === SysCustomWidgetKind.Data">
<el-divider v-if="widgetConfig.widgetType === SysCustomWidgetType.Divider"
:content-position="widgetConfig.position">
{{widgetConfig.showName}}
</el-divider>
<CustomText v-else-if="widgetConfig.widgetType === SysCustomWidgetType.Text" :widgetConfig="widgetConfig" />
<CustomImage v-else-if="widgetConfig.widgetType === SysCustomWidgetType.Image" :widgetConfig="widgetConfig" />
</template>
<!-- 容器组件 -->
<template v-else-if="widgetConfig.widgetKind === SysCustomWidgetKind.Container">
<el-card v-if="widgetConfig.widgetType === SysCustomWidgetType.Card"
class="base-card" :shadow="widgetConfig.shadow" :body-style="{padding: widgetConfig.padding ? widgetConfig.padding + 'px' : '0px'}"
:style="{
height: (widgetConfig.height != null && widgetConfig.height !=='') ? widgetConfig.height + 'px' : undefined,
'margin-bottom': widgetConfig.supportBottom === 1 ? '20px' : undefined
}">
<div slot="header" class="base-card-header">
<span>{{widgetConfig.showName}}</span>
</div>
<el-row :gutter="widgetConfig.gutter">
<slot></slot>
</el-row>
</el-card>
</template>
</el-col>
</template>
<script>
import { DropdownWidget } from '@/utils/widget.js';
import { getDictDataList } from '../utils';
import { findItemFromList, findTreeNodePath } from '@/utils';
import CustomText from './customText.vue';
import CustomImage from './customImage.vue';
export default {
props: {
formConfig: {
type: Object,
required: true
},
widgetConfig: {
type: Object,
required: true
},
value: {
type: [String, Number, Date, Object, Array, Boolean]
},
getDropdownParams: {
type: Function
}
},
inject: ['preview'],
components: {
CustomText,
CustomImage
},
data () {
return {
cascaderValue: [],
dropdownWidget: (this.widgetConfig.widgetType === this.SysCustomWidgetType.Select || this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader)
? new DropdownWidget(this.loadDropdwonList, this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader) : undefined
}
},
methods: {
reset () {
this.handlerWidgetInput(undefined);
this.cascaderValue = [];
if (this.dropdownWidget) this.dropdownWidget.dirty = true;
},
loadDropdwonList () {
if (this.preview()) {
return Promise.resolve([]);
}
return new Promise((resolve, reject) => {
if (this.widgetConfig.column != null && this.widgetConfig.column.dictInfo != null) {
let params = {};
let dictInfo = this.widgetConfig.column.dictInfo;
if (dictInfo.dictType === this.SysOnlineDictType.TABLE ||
dictInfo.dictType === this.SysOnlineDictType.URL) {
params = this.getDropdownParams ? this.getDropdownParams(this.widgetConfig) : {};
}
if (params == null) {
reject();
} else {
getDictDataList(this, dictInfo, params).then(res => {
resolve(res);
}).catch(e => {
console.log(e);
reject(e);
});
}
} else {
reject();
}
});
},
getDropdownImpl () {
return this.dropdownWidget;
},
onVisibleChange () {
if (this.dropdownWidget) {
this.dropdownWidget.onVisibleChange(true).then(res => {
// 级联组件获取下拉数据计算组件显示path
if (this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader) {
this.cascaderValue = findTreeNodePath(res, this.value, 'id');
}
});
}
},
handlerWidgetInput (value) {
if (this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader) {
this.cascaderValue = value;
if (Array.isArray(value) && value.length > 0) {
this.$emit('input', value[value.length - 1], this.widgetConfig);
} else {
this.$emit('input', undefined, this.widgetConfig);
}
} else {
this.$emit('input', value, this.widgetConfig);
}
},
handlerWidgetChange (value) {
if (this.widgetConfig.widgetType === this.SysCustomWidgetType.Cascader) {
if (Array.isArray(value) && value.length > 0) {
this.$emit('change', value[value.length - 1], this.widgetConfig);
} else {
this.$emit('change', undefined, this.widgetConfig);
}
} else {
this.$emit('change', value, this.widgetConfig);
}
},
// 获得字典值
getDictValue (id) {
if (this.dropdownWidget && Array.isArray(this.dropdownWidget.dropdownList)) {
return (findItemFromList(this.dropdownWidget.dropdownList, id, 'id') || {}).name;
} else {
return '';
}
}
},
mounted () {
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,142 @@
<template>
<Draggable class="flex-box" draggable=".draggable-item" :list="list" group="componentsGroup">
<slot />
<div v-for="item in tempDomCount" :key="item" :style="{width: tempDomWidth}" />
<el-row type="flex" :justify="operatorPosition" :style="getMenuBoxStyle">
<slot name="operator" />
</el-row>
</Draggable>
</template>
<script>
import $ from 'jquery';
import Draggable from 'vuedraggable';
export default {
name: 'FilterBox',
components: {
Draggable
},
props: {
list: {
type: Array,
default: () => []
},
/**
* 每一个过滤项宽度(包含标题和输入框宽度总和)
*/
itemWidth: {
type: Number,
required: true
},
/**
* 每一项下间距
*/
marginBottom: {
type: String,
default: '18px'
},
/**
* 按钮块最小宽度默认350当每一行剩余空间大于此值按钮块将不会折行
*/
minMenuWidth: {
type: Number,
default: 350
},
/**
* 按钮位置默认为end可选值为start/end/center/space-around/space-between
*/
operatorPosition: {
type: String,
default: 'end'
}
},
data () {
return {
tempDomCount: 0,
tempDomWidth: undefined,
operatorWidth: undefined,
oldFilterItemCount: 0,
oldHasOperator: false,
oldWidth: 0,
rowJustify: 'space-between'
}
},
computed: {
getMenuBoxStyle () {
return {
'width': this.operatorWidth,
'margin-bottom': this.marginBottom,
'flex-grow': this.operatorWidth ? undefined : '1'
}
}
},
methods: {
onUpdate () {
setTimeout(() => {
let filterItemCount = Array.isArray(this.$slots.default) ? this.$slots.default.filter(item => item.context).length : 0;
let hasOperator = Array.isArray(this.$slots.operator) && this.$slots.operator.length > 0;
let width = $(this.$el).width();
if (filterItemCount === this.oldFilterItemCount && hasOperator === this.oldHasOperator && width === this.oldWidth) {
return;
}
let lineCount = this.itemWidth > 0 ? parseInt(width / this.itemWidth) : 1;
lineCount = Math.max(1, lineCount);
let residueCount = filterItemCount % lineCount;
this.tempDomCount = 0;
this.tempDomWidth = undefined;
this.rowJustify = 'space-between';
let tempCount = residueCount === 0 ? 0 : (lineCount - residueCount);
if (hasOperator) {
let residueWidth = width - ((Math.min(lineCount, filterItemCount) - residueCount) * this.itemWidth) - ((tempCount >= 1) ? 20 : 0);
// 判断剩余的空间是否够放下操作按钮
if (residueWidth >= this.minMenuWidth && residueCount === 0) {
this.rowJustify = 'start';
this.operatorWidth = undefined;
} else {
// 剩余空位数大于1需要占位dom
if (tempCount >= 1) {
if (residueWidth >= this.minMenuWidth) {
this.tempDomCount = tempCount - 1;
this.tempDomWidth = this.tempDomCount > 0 ? (20 / this.tempDomCount) + 'px' : undefined;
this.operatorWidth = this.tempDomCount > 0 ? (((tempCount * this.itemWidth) - 20) + 'px') : (this.itemWidth + 'px');
} else {
this.tempDomCount = tempCount;
this.tempDomWidth = (residueWidth / this.tempDomCount) + 'px';
this.operatorWidth = '100%';
}
} else {
this.operatorWidth = '100%';
}
}
} else {
this.tempDomCount = tempCount;
this.tempDomWidth = this.itemWidth + 'px';
}
this.oldFilterItemCount = filterItemCount;
this.oldHasOperator = hasOperator;
this.oldWidth = width;
});
}
},
beforeUpdate () {
this.onUpdate();
},
mounted () {
setTimeout(() => {
this.onUpdate();
});
},
created () {
window.addEventListener('resize', this.onUpdate);
},
beforeDestroy () {
window.removeEventListener('resize', this.onUpdate);
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,148 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row>
<el-col :span="24">
<el-form-item label="参数名称">
<el-input class="input-item" v-model="formData.dictParamName" readonly />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="参数值类型" prop="dictValueType">
<el-select class="input-item" v-model="formData.dictValueType"
:clearable="true" placeholder="参数值类型" @change="onDictValueTypeChange">
<el-option v-for="item in SysOnlineParamValueType.getList()" :key="item.id"
:label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.dictValueType === SysOnlineParamValueType.FORM_PARAM">
<el-form-item label="参数值" prop="dictValue">
<el-select class="input-item" v-model="formData.dictValue" key="FORM_PARAM"
:clearable="true" placeholder="参数值">
<el-option v-for="item in formParamList" :key="item.objectFieldName"
:label="item.objectFieldName" :value="item.objectFieldName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.dictValueType === SysOnlineParamValueType.TABLE_COLUMN">
<el-form-item label="参数值" prop="dictValue">
<el-select class="input-item" v-model="formData.dictValue" key="TABLE_COLUMN"
:clearable="true" placeholder="参数值">
<el-option v-for="item in columnList" :key="item.columnId"
:label="item.objectFieldName" :value="item.columnId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.dictValueType === SysOnlineParamValueType.STATIC_DICT">
<el-form-item label="参数值" prop="dictValue">
<el-cascader v-model="formData.dictValue" :options="staticData" :props="staticPops" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.dictValueType === SysOnlineParamValueType.INPUT_VALUE">
<el-form-item label="参数值" prop="dictValue">
<el-input v-model="formData.dictValue" placeholder="请输入参数值" clearable />
</el-form-item>
</el-col>
<el-col :span="24" style="margin-top: 15px;">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import * as StaticDict from '@/staticDict';
export default {
props: {
rowData: {
type: Object,
required: true
},
formParamList: {
type: Array,
required: true
},
columnList: {
type: Array,
required: true
}
},
data () {
return {
formData: {
dictParamName: undefined,
dictValue: undefined,
dictValueType: undefined
},
staticPops: {
label: 'name',
value: 'id'
},
staticData: [],
rules: {
dictValueType: [
{ required: true, message: '请选择参数值类型', trigger: 'blur' }
],
dictValue: [
{ required: true, message: '请选择参数值', trigger: 'blur' }
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess, this.formData);
}
},
onSubmit () {
this.$refs.form.validate(valid => {
if (!valid) return;
if (this.formData.dictValueType === this.SysOnlineParamValueType.STATIC_DICT && this.formData.dictValue.length !== 2) {
this.$message.error('静态字典类型的参数值必须选择静态字典的值!');
return;
}
this.onCancel(true);
});
},
onDictValueTypeChange (value) {
this.formData.dictValue = undefined;
this.$refs.form.clearValidate();
},
loadStaticData () {
this.staticData = Object.keys(StaticDict).map(key => {
if (key === 'DictionaryBase') return undefined;
let dictItem = StaticDict[key];
return {
id: key,
name: dictItem.showName,
children: dictItem.getList()
}
}).filter(item => item != null);
}
},
mounted () {
this.formData = {
...this.formData,
...this.rowData
};
this.loadStaticData();
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,77 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row>
<el-col :span="24">
<el-form-item label="表单参数" prop="objectFieldName">
<el-select v-model="formData.objectFieldName" placeholder="请选择要添加的表单参数" clearable
@change="onParamChange">
<el-option v-for="item in columnList" :key="item.objectFieldName"
:label="item.objectFieldName" :value="item.objectFieldName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" style="margin-top: 15px;">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findItemFromList } from '@/utils';
export default {
props: {
columnList: {
type: Array,
required: true
}
},
data () {
return {
formData: {
objectFieldName: undefined,
primaryKey: false,
builtin: false
},
rules: {
objectFieldName: [
{ required: true, message: '表单参数不能为空', trigger: 'blur' }
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess, this.formData);
}
},
onSubmit () {
this.$refs.form.validate(valid => {
if (!valid) return;
this.onCancel(true);
});
},
onParamChange (value) {
let paramColumn = findItemFromList(this.columnList, value, 'objectFieldName');
if (paramColumn != null) this.formData.primaryKey = paramColumn.primaryKey;
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,211 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="120px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="过滤数据表" prop="tableId">
<el-select class="input-item" v-model="formData.tableId"
:clearable="true" placeholder="字段数据表"
@change="onTableChange" >
<el-option v-for="(table, index) in tableList" :key="table.tableId"
:label="table.tableName" :value="table.tableId">
<el-row type="flex" justify="space-between" align="middle">
<span>{{table.tableName}}</span>
<el-tag
:type="table.relationType == null ? 'success' : 'parimary'"
style="margin-left: 30px;" size="mini" effect="dark" >
{{(table.relationType == null || index === 0) ? '主表' : '一对一关联'}}
</el-tag>
</el-row>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="过滤数据表字段" prop="columnId">
<el-select class="input-item" v-model="formData.columnId"
:clearable="true" placeholder="字段数据表" @change="onColumnChange">
<el-option v-for="column in getTableColumnList" :key="column.columnId"
:label="column.columnName" :value="column.columnId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="参数值类型" prop="paramValueType">
<el-select class="input-item" v-model="formData.paramValueType"
:clearable="true" placeholder="参数值类型" @change="onParamValueTypeChange">
<el-option v-for="item in SysOnlineParamValueType.getList()" :key="item.id"
:label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.paramValueType === SysOnlineParamValueType.FORM_PARAM">
<el-form-item label="参数值" prop="paramValue">
<el-select class="input-item" v-model="formData.paramValue" key="FORM_PARAM"
:clearable="true" placeholder="参数值">
<el-option v-for="item in formParamList" :key="item.columnName"
:label="item.columnName" :value="item.columnName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.paramValueType === SysOnlineParamValueType.TABLE_COLUMN">
<el-form-item label="参数值" prop="paramValue">
<el-select class="input-item" v-model="formData.paramValue" key="TABLE_COLUMN"
:clearable="true" placeholder="参数值">
<el-option-group v-for="table in tableFilterColumnList" :key="table.tableId" :label="table.tableName">
<el-option v-for="item in table.columnList" :key="item.columnId"
:label="item.columnName" :value="item.columnId" />
</el-option-group>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.paramValueType === SysOnlineParamValueType.STATIC_DICT">
<el-form-item label="参数值" prop="paramValue">
<el-cascader v-model="formData.paramValue" :options="staticData" :props="staticPops" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.paramValueType === SysOnlineParamValueType.INPUT_VALUE">
<el-form-item label="参数值" prop="paramValue">
<el-input v-model="formData.paramValue" placeholder="请输入参数值" clearable />
</el-form-item>
</el-col>
<el-col :span="24" style="margin-top: 15px;">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findItemFromList } from '@/utils';
import * as StaticDict from '@/staticDict';
export default {
props: {
// 表格数据表
tableList: {
type: Array,
required: true
},
// 已经使用的过滤字段
usedColumnList: {
type: Array,
required: true
},
// 表单参数列表
formParamList: {
type: Array,
required: true
},
// 表单过滤字段列表
tableFilterColumnList: {
type: Array,
required: true
}
},
data () {
return {
formData: {
tableId: undefined,
columnId: undefined,
paramValueType: undefined,
paramValue: undefined
},
staticPops: {
label: 'name',
value: 'id'
},
staticData: [],
rules: {
tableId: [
{ required: true, message: '表格列绑定数据表不能为空', trigger: 'blur' }
],
columnId: [
{ required: true, message: '表格列绑定字段不能为空', trigger: 'blur' }
],
paramValueType: [
{ required: true, message: '请选择参数值类型', trigger: 'blur' }
],
paramValue: [
{ required: true, message: '请选择参数值', trigger: 'blur' }
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess, this.formData);
}
},
onSubmit () {
this.$refs.form.validate(valid => {
if (!valid) return;
this.formData.table = this.getCurrentTable;
if (this.getCurrentTable.relationType == null) {
this.formData.relationId = this.getCurrentTable.id;
} else {
this.formData.relationId = undefined;
}
this.formData.column = findItemFromList(this.getTableColumnList, this.formData.columnId, 'columnId');
this.onCancel(true);
});
},
onTableChange (value) {
this.formData.columnId = undefined;
this.formData.paramValueType = undefined;
this.formData.paramValue = undefined;
},
onColumnChange (value) {
this.formData.paramValueType = undefined;
this.formData.paramValue = undefined;
},
onParamValueTypeChange (value) {
this.formData.dictValue = undefined;
this.$refs.form.clearValidate();
},
loadStaticData () {
this.staticData = Object.keys(StaticDict).map(key => {
if (key === 'DictionaryBase') return undefined;
let dictItem = StaticDict[key];
return {
id: key,
name: dictItem.showName,
children: dictItem.getList()
}
}).filter(item => item != null);
}
},
computed: {
getCurrentTable () {
return findItemFromList(this.tableList, this.formData.tableId, 'tableId');
},
getTableColumnList () {
if (this.getCurrentTable != null) {
return this.getCurrentTable.columnList.filter(item => {
return this.usedColumnList.indexOf(item.columnId) === -1 && item.filterType !== this.SysOnlineColumnFilterType.NONE;
});
} else {
return [];
}
}
},
mounted () {
this.loadStaticData();
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,166 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row>
<el-col :span="24">
<el-form-item label="字段数据表" prop="tableId">
<el-select class="input-item" v-model="formData.tableId"
:clearable="true" placeholder="字段数据表"
@change="onTableChange" >
<el-option v-for="(table, index) in tableList" :key="table.tableId"
:label="table.tableName" :value="table.tableId">
<el-row type="flex" justify="space-between" align="middle">
<span>{{table.tableName}}</span>
<el-tag
:type="table.relationType == null ? 'success' : 'parimary'"
style="margin-left: 30px;" size="mini" effect="dark" >
{{(table.relationType == null || index === 0) ? '主表' : '一对一关联'}}
</el-tag>
</el-row>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="绑定列字段" prop="columnId">
<el-select class="input-item" v-model="formData.columnId"
:clearable="true" placeholder="字段数据表" @change="onColumnChange">
<el-option v-for="column in getTableColumnList" :key="column.columnId"
:label="column.columnName" :value="column.columnId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="表格列名" prop="showName">
<el-input class="input-item" v-model="formData.showName"
:clearable="true" placeholder="表格列名" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="表格列宽" prop="columnId">
<el-input-number class="input-item" v-model="formData.columnWidth"
placeholder="表格列宽" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="支持排序" prop="columnId">
<el-switch class="input-item" v-model="formData.sortable" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="显示顺序" prop="showOrder">
<el-input-number class="input-item" v-model="formData.showOrder"
placeholder="显示顺序" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findItemFromList } from '@/utils';
export default {
props: {
showOrder: {
type: Number
},
rowData: {
type: Object
},
tableList: {
type: Array,
required: true
},
usedColumnList: {
type: Array,
required: true
}
},
data () {
return {
formData: {
columnId: undefined,
tableId: undefined,
showName: undefined,
showOrder: this.showOrder,
sortable: false,
columnWidth: undefined
},
oldColumnId: undefined,
rules: {
showName: [
{ required: true, message: '表格列名不能为空', trigger: 'blur' }
],
tableId: [
{ required: true, message: '表格列绑定数据表不能为空', trigger: 'blur' }
],
columnId: [
{ required: true, message: '表格列绑定字段不能为空', trigger: 'blur' }
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess, this.formData);
}
},
onSubmit () {
this.$refs.form.validate(valid => {
if (!valid) return;
this.formData.table = this.getCurrentTable;
this.formData.relationId = this.getCurrentTable.relationType == null ? undefined : this.getCurrentTable.id;
this.onCancel(true);
});
},
onTableChange (value) {
this.formData.columnId = undefined;
},
onColumnChange (value) {
this.formData.column = findItemFromList(this.getTableColumnList, this.formData.columnId, 'columnId');
this.formData.showName = this.formData.column ? this.formData.column.columnComment : undefined;
}
},
computed: {
getCurrentTable () {
return findItemFromList(this.tableList, this.formData.tableId, 'tableId');
},
getTableColumnList () {
if (this.getCurrentTable != null) {
return this.getCurrentTable.columnList.filter(item => {
return this.usedColumnList.indexOf(item.columnId) === -1 || this.oldColumnId === item.columnId;
});
} else {
return [];
}
}
},
mounted () {
if (this.rowData != null) {
this.formData = {
...this.rowData
}
this.oldColumnId = this.formData.columnId;
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,129 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row>
<el-col :span="24">
<el-form-item label="操作名称" prop="name">
<el-input class="input-item" v-model="formData.name"
:clearable="true" placeholder="操作按钮名称" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="!formData.rowOperation">
<el-form-item label="操作名称" prop="btnType">
<el-select v-model="formData.btnType">
<el-option label="primary" value="primary" />
<el-option label="success" value="success" />
<el-option label="warning" value="warning" />
<el-option label="danger" value="danger" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="!formData.rowOperation">
<el-form-item label="镂空模式" prop="btnType">
<el-switch v-model="formData.plain" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="formData.rowOperation">
<el-form-item label="操作按钮类名">
<el-input class="input-item" v-model="formData.btnClass"
:clearable="true" placeholder="操作按钮类名" />
</el-form-item>
</el-col>
<el-col :span="24"
v-if="formData.type === SysCustomWidgetOperationType.ADD ||
formData.type === SysCustomWidgetOperationType.EDIT ||
formData.type === SysCustomWidgetOperationType.CUSTOM"
>
<el-form-item label="操作表单">
<el-select v-model="formData.formId" placeholder="选择操作按钮触发表单" clearable>
<el-option v-for="form in getFormList" :key="form.formId"
:label="form.formName" :value="form.formId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
export default {
props: {
rowData: {
type: Object
},
formList: {
type: Array,
required: true
}
},
data () {
return {
formData: {
type: this.SysCustomWidgetOperationType.CUSTOM,
name: undefined,
btnType: undefined,
plain: false,
enabled: true,
builtin: false,
rowOperation: true,
btnClass: 'table-btn primary',
formId: undefined
},
rules: {
name: [
{ required: true, message: '操作按钮名称不能为空', trigger: 'blur' }
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess, this.formData);
}
},
onSubmit () {
this.$refs.form.validate(valid => {
if (!valid) return;
this.onCancel(true);
});
}
},
computed: {
getFormList () {
return this.formList.filter(item => {
if (this.formData.type === this.SysCustomWidgetOperationType.CUSTOM) {
return item.formType === this.SysOnlineFormType.QUERY;
} else {
return item.formType === this.SysOnlineFormType.FORM;
}
});
}
},
mounted () {
if (this.rowData != null) {
this.formData = {
...this.rowData
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,150 @@
<template>
<el-col :span="widgetConfig.span" class="editable-widget-item"
:class="{'draggable-item': draggable, 'has-error': widgetConfig.hasError}"
:style="{width: widgetConfig.widgetKind === SysCustomWidgetKind.Filter ? (formConfig().labelWidth + 272 + 'px') : undefined}"
@click.stop.native="onClick">
<i v-if="canDelete" class="el-icon-delete drag-widget-delete" style="color: #F56C6C;" @click.stop="onDeleteClick" />
<template v-if="widgetConfig.widgetKind === SysCustomWidgetKind.Filter">
<CustomFilterWidget class="drag-widget-item" :widgetConfig="{ ...widgetConfig }" :value="widgetConfig.defaultValue" @input="() => {}" />
</template>
<template v-else>
<CustomTable v-if="widgetConfig.widgetType === SysCustomWidgetType.Table"
class="drag-widget-item" :formType="formConfig().formType" :widgetConfig="{ ...widgetConfig, span: null }" :dictList="{}" />
<CustomUpload v-else-if="widgetConfig.widgetType === SysCustomWidgetType.Upload"
class="drag-widget-item" :widgetConfig="{ ...widgetConfig, span: null }"
:value="widgetConfig.defaultValue" @input="() => {}" />
<CustomWidget v-else class="drag-widget-item"
:formConfig="formConfig()"
:widgetConfig="{ ...widgetConfig, span: null }"
:value="widgetConfig.defaultValue" @input="() => {}">
<Draggable draggable=".draggable-item" :list="widgetConfig.childWidgetList" style="min-height: 50px;"
group="componentsGroup" :animation="340"
>
<template v-if="Array.isArray(widgetConfig.childWidgetList) && widgetConfig.childWidgetList.length > 0">
<drag-widget-item v-for="child in widgetConfig.childWidgetList" :key="child.id"
:class="{'active-widget': child === current()}"
@click="onChildClick"
@delete="onChildDeleteClick"
:widgetConfig="child" />
</template>
</Draggable>
</CustomWidget>
</template>
</el-col>
</template>
<script>
import Draggable from 'vuedraggable';
import CustomWidget from './customWidget.vue';
import CustomTable from './customTable.vue';
import CustomUpload from './customUpload.vue';
import CustomFilterWidget from './customFilterWidget.vue';
export default {
components: {
Draggable,
CustomWidget,
CustomTable,
CustomUpload,
CustomFilterWidget
},
inject: ['current', 'isLocked', 'formConfig'],
props: {
widgetConfig: {
type: Object,
required: true
},
canDelete: {
type: Boolean,
default: true
}
},
data () {
return {
value: this.widgetConfig.defaultValue
}
},
methods: {
onClick () {
this.$emit('click', this.widgetConfig);
},
onChildClick (element) {
this.$emit('click', element);
},
onDeleteClick () {
this.$emit('delete', this.widgetConfig);
},
onChildDeleteClick (element) {
this.widgetConfig.childWidgetList = this.widgetConfig.childWidgetList.filter(item => {
return item.id !== element.id;
});
this.$emit('delete', this.widgetConfig, true);
}
},
computed: {
draggable () {
return !this.isLocked() || this.widgetConfig.widgetKind !== this.SysCustomWidgetKind.Container;
}
},
mounted () {
}
}
</script>
<style scoped>
.editable-widget-item {
position: relative;
margin-bottom: 10px;
}
.editable-widget-item.active-widget > .drag-widget-item {
background: #b0d7fd;
border: 1px dashed #77b9fc;
}
.has-error {
background: #fdd5d5!important;
border: 1px dashed #F56C6C!important;
}
.drag-widget-item {
cursor: move;
border: 1px dashed #e2e0e0;
padding: 13px 10px;
}
.drag-widget-item:hover {
background: #f3f9ff;
}
.has-error .drag-widget-item:hover {
background: #fdd5d5!important;
}
.drag-widget-delete {
border-color: #F56C6C;
width: 22px;
height: 22px;
top: -10px;
right: 24px;
line-height: 22px;
text-align: center;
border-radius: 50%;
font-size: 12px;
border: 1px solid;
cursor: pointer;
z-index: 1;
position: absolute;
display: none;
}
.editable-widget-item:hover > .drag-widget-delete {
display: block;
}
</style>
<style>
.editable-widget-item .el-form-item {
margin: 0px !important;
}
</style>

View File

@@ -0,0 +1,239 @@
import { SysCustomWidgetKind, SysCustomWidgetType, SysCustomWidgetOperationType } from '@/staticDict/onlineStaticDict.js';
const defaultWidgetAttributes = {
label: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.Label,
span: 12,
placeholder: '',
defaultValue: '',
readOnly: true
},
input: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.Input,
span: 12,
type: 'text',
placeholder: '',
defaultValue: '',
minRows: 2,
maxRows: 2,
readOnly: false,
disabled: false
},
numberInput: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.NumberInput,
span: 12,
defaultValue: 0,
min: 0,
max: 100,
step: 1,
precision: 0,
controlVisible: 1,
controlPosition: 0,
readOnly: false,
disabled: false
},
numberRange: {
widgetKind: SysCustomWidgetKind.Filter,
widgetType: SysCustomWidgetType.NumberRange,
readOnly: false,
disabled: false
},
switch: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.Switch,
span: 12,
readOnly: false,
disabled: false
},
select: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.Select,
span: 12,
placeholder: ''
},
cascader: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.Cascader,
span: 12,
placeholder: ''
},
date: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.Date,
span: 12,
placeholder: '',
type: 'date',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd',
readOnly: false,
disabled: false
},
dateRange: {
widgetKind: SysCustomWidgetKind.Filter,
widgetType: SysCustomWidgetType.DateRange,
readOnly: false,
disabled: false
},
richEditor: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.RichEditor,
span: 24
},
upload: {
widgetKind: SysCustomWidgetKind.Form,
widgetType: SysCustomWidgetType.Upload,
span: 12,
isImage: true,
maxFileCount: undefined,
fileFieldName: 'uploadFile',
actionUrl: '',
downloadUrl: ''
},
divider: {
widgetKind: SysCustomWidgetKind.Data,
widgetType: SysCustomWidgetType.Divider,
span: 24,
position: 'center'
},
text: {
widgetKind: SysCustomWidgetKind.Data,
widgetType: SysCustomWidgetType.Text,
span: 24,
color: undefined,
backgroundColor: undefined,
fontSize: undefined,
lineHeight: undefined,
indent: undefined,
decoration: 'none',
align: 'left',
padding: 0
},
image: {
widgetKind: SysCustomWidgetKind.Data,
widgetType: SysCustomWidgetType.Image,
span: 24,
src: 'https://www.w3school.com.cn/i/eg_tulip.jpg',
height: undefined,
width: undefined,
fit: 'fill'
},
table: {
widgetKind: SysCustomWidgetKind.Data,
widgetType: SysCustomWidgetType.Table,
span: 24,
supportBottom: 0,
tableInfo: {
height: undefined,
paged: true,
optionColumnWidth: 150
},
titleColor: '#409EFF',
tableColumnList: [],
operationList: [
/**
* 暂时去掉导出操作,等支持后再开启
{
id: 0,
type: SysCustomWidgetOperationType.EXPORT,
name: '导出',
enabled: true,
builtin: true,
rowOperation: false,
btnType: 'primary',
plain: true,
formId: undefined
},
*/
{
id: 1,
type: SysCustomWidgetOperationType.ADD,
name: '新建',
enabled: true,
builtin: true,
rowOperation: false,
btnType: 'primary',
plain: false,
formId: undefined
},
{
id: 2,
type: SysCustomWidgetOperationType.EDIT,
name: '编辑',
enabled: true,
builtin: true,
rowOperation: true,
btnClass: 'table-btn success',
formId: undefined
},
{
id: 3,
type: SysCustomWidgetOperationType.DELETE,
name: '删除',
enabled: true,
builtin: true,
rowOperation: true,
btnClass: 'table-btn delete',
formId: undefined
}
],
queryParamList: []
},
card: {
widgetKind: SysCustomWidgetKind.Container,
widgetType: SysCustomWidgetType.Card,
span: 12,
supportBottom: 0,
padding: 15,
gutter: 15,
height: undefined,
shadow: 'always',
childWidgetList: []
}
}
const defaultFormConfig = {
formType: undefined,
formKind: undefined,
gutter: 20,
labelWidth: 100,
labelPosition: 'right',
tableWidget: undefined,
width: 800,
height: undefined
}
const baseWidgetList = [
{
id: 'orang_base_card',
columnName: 'card',
showName: '基础卡片',
widgetType: SysCustomWidgetType.Card
},
{
id: 'orange_base_divider',
columnName: 'divider',
showName: '分割线',
widgetType: SysCustomWidgetType.Divider
},
{
id: 'orange_base_text',
columnName: 'text',
showName: '文本',
widgetType: SysCustomWidgetType.Text
},
{
id: 'orange_base_image',
columnName: 'image',
showName: '图片',
widgetType: SysCustomWidgetType.Image
}
];
export {
baseWidgetList,
defaultWidgetAttributes,
defaultFormConfig
};

View File

@@ -0,0 +1,89 @@
<template>
<el-popover trigger="click" width="300px" @show="onInit" v-model="isShow">
<el-form ref="dictData" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-form-item label="字典键类型">
<el-radio-group v-model="formData.type">
<el-radio-button label="Integer">整数</el-radio-button>
<el-radio-button label="String">字符串</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-if="formData.type === 'String'" label="字典键数据" prop="id">
<el-input v-model="formData.id" />
</el-form-item>
<el-form-item v-if="formData.type === 'Integer'" label="字典键数据" prop="id">
<el-input-number v-model="formData.id" />
</el-form-item>
<el-form-item label="字典值数据" prop="id">
<el-input v-model="formData.name" />
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button size="mini" type="primary" :plain="true" @click="onCancel">取消</el-button>
<el-button size="mini" type="primary" @click="onSubmit">保存</el-button>
</el-row>
<el-button class="table-btn" :class="{'success': value != null}" slot="reference" size="mini" type="text">{{btnText}}</el-button>
</el-popover>
</template>
<script>
export default {
props: {
width: {
type: String,
default: '200px'
},
btnText: {
type: String,
required: true
},
value: {
type: Object
}
},
data () {
return {
isShow: false,
formData: {
type: 'Integer',
id: undefined,
name: undefined
},
rules: {
id: [
{required: true, message: '字典键数据不能为空', trigger: 'blur'}
],
name: [
{required: true, message: '字典值数据不能为空', trigger: 'blur'}
]
}
}
},
methods: {
onCancel () {
this.isShow = false;
},
onSubmit () {
this.$refs.dictData.validate(valid => {
if (!valid) return;
this.$emit('save', this.formData, this.value);
this.isShow = false;
});
},
onInit () {
this.formData = {
type: 'Integer',
id: undefined,
name: undefined
}
if (this.value != null) {
this.formData = { ...this.value };
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,495 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditOnlineFormDict" :model="formOnlineDict" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="150px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="字典名称" prop="dictName">
<el-input class="input-item" v-model="formOnlineDict.dictName"
:clearable="true" placeholder="字典名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="字典类型" prop="dictType">
<el-select class="input-item" v-model="formOnlineDict.dictType"
:clearable="true" :disabled="isEdit"
placeholder="字典类型" :loading="dictTypeWidget.loading"
@visible-change="dictTypeWidget.onVisibleChange"
@change="onDictTypeChange">
<el-option v-for="item in dictTypeWidget.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<!-- 静态字典选择 -->
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.STATIC">
<el-form-item label="字典选择" prop="staticDictName">
<el-select class="input-item" v-model="formOnlineDict.staticDictName" :clearable="true"
filterable placeholder="字典类型" :loading="staticDictWidget.loading"
@visible-change="staticDictWidget.onVisibleChange"
@change="onStaiicDictChange">
<el-option v-for="item in staticDictWidget.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<!-- 数据表字典选择数据表 -->
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="数据库" prop="dblinkId">
<el-select class="input-item" v-model="formOnlineDict.dblinkId" :clearable="true"
placeholder="数据表所属数据库" :loading="dblinkIdWidget.loading"
@visible-change="dblinkIdWidget.onVisibleChange"
@change="onDblinkChange">
<el-option v-for="item in dblinkIdWidget.dropdownList" :key="item.dblinkId" :value="item.dblinkId" :label="item.dblinkName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="数据表" prop="tableName">
<el-select class="input-item" v-model="formOnlineDict.tableName" :clearable="true"
placeholder="选择字典数据表" :loading="tableNameWidget.loading" filterable
@visible-change="tableNameWidget.onVisibleChange"
@change="onDictTableChange">
<el-option v-for="item in tableNameWidget.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<!-- URL字典输入字典获取url -->
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.URL">
<el-form-item label="字典URL" prop="dictListUrl">
<el-input class="input-item" v-model="formOnlineDict.dictListUrl"
:clearable="true" placeholder="输入字典获取url"
@change="clearDictInfo">
<el-button slot="append" size="mini" @click="onGetDictData(true)">获取数据</el-button>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.URL">
<el-form-item label="指定数据获取URL" prop="dictIdsUrl">
<el-input class="input-item" v-model="formOnlineDict.dictIdsUrl"
:clearable="true" placeholder="根据输入的ids参数获取字典数据"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24" style="height: 47px;"
v-if="formOnlineDict.dictType === SysOnlineDictType.URL || formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="树状字典">
<el-switch v-model="formOnlineDict.treeFlag" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.treeFlag &&
(formOnlineDict.dictType === SysOnlineDictType.URL || formOnlineDict.dictType === SysOnlineDictType.TABLE)">
<el-form-item label="字典父字段">
<el-select v-model="formOnlineDict.parentKeyColumnName" clearable
placeholder="选择字典父字段" filterable allow-create default-first-option>
<el-option v-for="column in dictColumnList" :key="column" :label="column" :value="column" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.URL || formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="字典键字段" prop="keyColumnName">
<el-select v-model="formOnlineDict.keyColumnName" clearable
placeholder="选择字典键字段" filterable allow-create default-first-option>
<el-option v-for="column in dictColumnList" :key="column" :label="column" :value="column" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.URL || formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="字典值字段" prop="valueColumnName">
<el-select v-model="formOnlineDict.valueColumnName" clearable
placeholder="选择字典值字段" filterable allow-create default-first-option>
<el-option v-for="column in dictColumnList" :key="column" :label="column" :value="column" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="逻辑删除字段">
<el-select v-model="formOnlineDict.deletedColumnName" clearable
placeholder="选择逻辑删除字段" filterable allow-create default-first-option>
<el-option v-for="column in dictColumnList" :key="column" :label="column" :value="column" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="用户过滤字段">
<el-select v-model="formOnlineDict.userFilterColumnName" clearable
placeholder="选择用户过滤字段,用于数据权限用户过滤" filterable allow-create default-first-option>
<el-option v-for="column in dictColumnList" :key="column" :label="column" :value="column" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="部门过滤字段">
<el-select v-model="formOnlineDict.deptFilterColumnName" clearable
placeholder="选择部门过滤字段,用于数据权限部门过滤" filterable allow-create default-first-option>
<el-option v-for="column in dictColumnList" :key="column" :label="column" :value="column" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="租户过滤字段">
<el-select v-model="formOnlineDict.tenantFilterColumnName" clearable
placeholder="选择部门过滤字段,用于多租户租户过滤" filterable allow-create default-first-option>
<el-option v-for="column in dictColumnList" :key="column" :label="column" :value="column" />
</el-select>
</el-form-item>
</el-col>
<!-- 字典参数 -->
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.URL || formOnlineDict.dictType === SysOnlineDictType.TABLE">
<el-form-item label="字典参数">
<el-select v-model="dictParamList" placeholder="请添加字典获取参数"
multiple filterable allow-create default-first-option>
<el-option v-for="item in dictColumnList" :key="item" :value="item"
:label="item">
</el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 字典数据 -->
<el-col :span="24" v-if="formOnlineDict.dictType === SysOnlineDictType.STATIC || formOnlineDict.dictType === SysOnlineDictType.CUSTOM">
<el-table :data="dictData" size="mini" header-cell-class-name="table-header-gray" height="300px">
<el-table-column label="字典键数据" prop="id" />
<el-table-column label="字典值数据" prop="name" />
<el-table-column label="操作" width="100px" fixed="right" align="right"
v-if="formOnlineDict.dictType === SysOnlineDictType.CUSTOM">
<template slot="header">
<el-row type="flex" justify="end" align="middle">
<EditDictDataButton width="200px" btnText="新建" @save="onAddDictData" />
</el-row>
</template>
<template slot-scope="scope">
<EditDictDataButton width="200px" :value="scope.row" btnText="编辑" @save="onEditDictData" />
<el-button class="table-btn delete" style="margin-left: 10px;" type="text" @click="onDeleteDictData(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="24" style="margin-top: 15px;">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSaveClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import * as StaticDict from '@/staticDict';
/* eslint-disable-next-line */
import { DropdownWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { OnlineDictController, OnlineDblinkController } from '@/api/onlineController.js';
import EditDictDataButton from './editDictDataButton.vue';
export default {
name: 'formEditOnlineDict',
props: {
dictId: {
default: undefined
}
},
components: {
EditDictDataButton
},
data () {
return {
formOnlineDict: {
dblinkId: undefined,
dictName: undefined,
dictType: this.SysOnlineDictType.TABLE,
dictListUrl: undefined,
dictIdsUrl: undefined,
staticDictName: undefined,
tableName: undefined,
// 字典父字段名称
parentKeyColumnName: undefined,
// 字典键字段名称
keyColumnName: undefined,
// 字典值字段名称
valueColumnName: undefined,
// 逻辑删除字段名称
deletedColumnName: undefined,
// 用户过滤字段名称
userFilterColumnName: undefined,
// 部门过滤字段名称
deptFilterColumnName: undefined,
// 租户过滤字段名称
tenantFilterColumnName: undefined,
// 树状字典
treeFlag: false
},
dictData: [],
// 字典字段列表
dictColumnList: [],
// 数据表所属数据库
dblinkIdWidget: new DropdownWidget(this.loadDblinkWidgetDropdownList),
// 字典数据表
tableNameWidget: new DropdownWidget(this.loadTableNameWidgetDropdownList),
// 字典类型
dictTypeWidget: new DropdownWidget(this.loadDictTypeWidgetDropdownList),
// 静态字典下拉选择
staticDictWidget: new DropdownWidget(this.loadStaticDictWidgetDropdownList),
// 当前选中字典参数
currentParam: undefined,
// 字典参数列表
dictParamList: [],
dictTableProps: {
lazy: true,
lazyLoad: this.loadDictTableData
},
rules: {
'dictName': [
{required: true, message: '请输入字典名称', trigger: 'blur'}
],
'dblinkId': [
{required: true, message: '请选择字典数据表所属数据库', trigger: 'blur'}
],
'tableName': [
{required: true, message: '请选择字典数据表', trigger: 'blur'}
],
'dictListUrl': [
{required: true, message: '请输入字典数据获取URL', trigger: 'blur'}
],
'dictIdsUrl': [
{required: true, message: '请输入字典指定数据获取URL', trigger: 'blur'}
],
'staticDictName': [
{required: true, message: '请选择静态字典', trigger: 'blur'}
],
'keyColumnName': [
{required: true, message: '请输入字典键字段名称', trigger: 'blur'}
],
'valueColumnName': [
{required: true, message: '请输入字典值字段名称', trigger: 'blur'}
]
}
}
},
methods: {
/**
* 字典数据
*/
onAddDictData (dictData) {
if (dictData != null) this.dictData.push(dictData);
},
onEditDictData (newValue, oldValue) {
if (newValue != null && oldValue != null) {
this.dictData = this.dictData.map(item => {
return item.id === oldValue.id ? newValue : item;
});
}
},
onDeleteDictData (row) {
if (row != null) {
this.dictData = this.dictData.filter(item => {
return item.id !== row.id;
});
}
},
loadDblinkWidgetDropdownList () {
return new Promise((resolve, reject) => {
OnlineDblinkController.list(this, {}).then(res => {
return resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
onDblinkChange (value) {
this.clearDictInfo();
this.formOnlineDict.tableName = undefined;
this.tableNameWidget.dirty = true;
},
loadTableNameWidgetDropdownList () {
if (this.formOnlineDict.dblinkId == null || this.formOnlineDict.dblinkId === '') return Promise.reject();
return new Promise((resolve, reject) => {
OnlineDblinkController.listDblinkTables(this, {
dblinkId: this.formOnlineDict.dblinkId
}).then(res => {
resolve(res.data.map(item => {
return {
id: item.tableName,
name: item.tableName
}
}));
}).catch(e => {
reject(e);
});
});
},
/**
* 选择字典数据表
*/
onDictTableChange (value) {
this.formOnlineDict.tableName = value;
if (this.formOnlineDict.tableName != null) {
this.loadTableColumnList();
}
},
/**
* 清空字典信息
*/
clearDictInfo () {
this.formOnlineDict.parentKeyColumnName = undefined;
this.formOnlineDict.keyColumnName = undefined;
this.formOnlineDict.valueColumnName = undefined;
this.dictParamList = [];
this.formOnlineDict.staticDictName = undefined;
this.dictData = [];
},
loadTableColumnList () {
let params = {
dblinkId: this.formOnlineDict.dblinkId,
tableName: this.formOnlineDict.tableName
}
this.dictColumnList = [];
OnlineDblinkController.listDblinkTableColumns(this, params).then(res => {
this.dictColumnList = res.data.map(item => {
return item.columnName;
});
}).catch(e => {});
},
onDictTypeChange () {
this.clearDictInfo();
this.formOnlineDict.dictListUrl = undefined;
this.formOnlineDict.tableName = undefined;
this.formOnlineDict.dblinkId = undefined;
this.dictColumnList = [];
},
onStaiicDictChange () {
let staticDict = StaticDict[this.formOnlineDict.staticDictName];
this.dictData = [];
if (staticDict != null) {
this.dictData = staticDict.getList();
}
},
/**
* 获取字典数据
*/
onGetDictData (showWarning = false) {
let url = this.formOnlineDict.dictListUrl;
if (url == null || url === '') {
this.$message.error('请输入字典数据获取URL');
return;
}
this.dictColumnList = [];
this.doUrl(url, 'get', {}).then(res => {
if (showWarning) {
this.$message.success('获取字典数据成功!');
}
if (Array.isArray(res.data) && res.data.length > 0) {
let dictDataItem = res.data[0];
this.dictColumnList = Object.keys(dictDataItem);
}
}).catch(e => {});
},
/**
* 获取字典类型下拉列表
*/
loadDictTypeWidgetDropdownList () {
return Promise.resolve(this.SysOnlineDictType.getList());
},
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 获取静态字典下拉列表
*/
loadStaticDictWidgetDropdownList () {
return Promise.resolve(Object.keys(StaticDict).map(key => {
// 过滤掉静态字典的基类
if (key === 'DictionaryBase') return undefined;
return {
id: key,
name: StaticDict[key].showName
}
}).filter(item => item != null));
},
/**
* 保存字典信息
*/
onSaveClick () {
this.$refs.formEditOnlineFormDict.validate((valid) => {
if (!valid) return;
let params = {
onlineDictDto: {
...this.formOnlineDict,
dblinkId: this.formOnlineDict.dblinkId,
dictDataJson: JSON.stringify({
staticDictName: this.formOnlineDict.dictType === this.SysOnlineDictType.STATIC ? this.formOnlineDict.staticDictName : undefined,
dictData: this.formOnlineDict.dictType === this.SysOnlineDictType.CUSTOM ? this.dictData : undefined,
paramList: this.dictParamList.map(item => {
return {
dictParamName: item
}
})
})
}
}
let httpCall = this.isEdit ? OnlineDictController.update(this, params) : OnlineDictController.add(this, params);
httpCall.then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
}
},
computed: {
isEdit () {
return this.dictId != null && this.dcitId !== '';
}
},
mounted () {
// 获取字典类型下拉列表数据
this.dictTypeWidget.onVisibleChange(true);
// 编辑状态下获取字典参数列表
if (this.isEdit) {
OnlineDictController.view(this, {
dictId: this.dictId
}).then(res => {
this.formOnlineDict = {
...res.data
};
// 解析字典参数信息
this.formOnlineDict.dictDataJson = undefined;
let dataJson = JSON.parse(res.data.dictDataJson);
if (dataJson && Array.isArray(dataJson.paramList)) {
this.dictParamList = dataJson.paramList.map(item => {
return item.dictParamName;
});
}
// 获取字典字段
if (this.formOnlineDict.dictType === this.SysOnlineDictType.TABLE) {
// 获取下拉数据
this.dblinkIdWidget.onVisibleChange(true);
this.tableNameWidget.onVisibleChange(true);
this.loadTableColumnList();
} else if (this.formOnlineDict.dictType === this.SysOnlineDictType.URL) {
this.onGetDictData();
} else if (this.formOnlineDict.dictType === this.SysOnlineDictType.STATIC) {
this.staticDictWidget.onVisibleChange(true);
if (dataJson) this.formOnlineDict.staticDictName = dataJson.staticDictName;
this.dictData = StaticDict[this.formOnlineDict.staticDictName] ? StaticDict[this.formOnlineDict.staticDictName].getList() : [];
} else if (this.formOnlineDict.dictType === this.SysOnlineDictType.CUSTOM) {
if (dataJson && Array.isArray(dataJson.dictData)) {
this.dictData = dataJson.dictData;
}
}
}).catch(e => {});
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,193 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="字典名称">
<el-input class="filter-item" v-model="formOnlineDict.formFilter.dictName"
:clearable="true" placeholder="字典名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshOnlineDict(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini"
@click="onFormCreateDictClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table ref="class" :data="formOnlineDict.dict.impl.dataList" size="mini" @sort-change="formOnlineDict.dict.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formOnlineDict.dict.impl.getTableIndex" />
<el-table-column label="字典名称" prop="dictName" />
<el-table-column label="字典类型" prop="dictTypeDictMap.name">
<template slot-scope="scope">
<el-tag size="mini" :type="getDictTypeTagType(scope.row.dictType)">
{{scope.row.dictTypeDictMap.name}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="是否树字典">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.treeFlag ? 'success' : 'danger'">
{{scope.row.treeFlag ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="150px">
<template slot-scope="scope">
<el-button class="table-btn success" @click.stop="onFormEditDictClick(scope.row)" type="text" size="mini">
编辑
</el-button>
<el-button class="table-btn delete" @click.stop="onFormDeleteDictClick(scope.row)" type="text" size="mini">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formOnlineDict.dict.impl.totalCount"
:current-page="formOnlineDict.dict.impl.currentPage"
:page-size="formOnlineDict.dict.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formOnlineDict.dict.impl.onCurrentPageChange"
@size-change="formOnlineDict.dict.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
import '@/staticDict/onlineStaticDict.js';
/* eslint-disable-next-line */
import { TableWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { OnlineDictController } from '@/api/onlineController.js';
import EditOnlineDict from './editOnlineDict.vue';
export default {
name: 'formOnlineDict',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formOnlineDict: {
formFilter: {
dictName: undefined
},
formFilterCopy: {
dictName: undefined
},
dict: {
impl: new TableWidget(this.loadDynamicDictData, this.loadDynamicDictVerify, true, false)
},
isInit: false
}
}
},
methods: {
getDictTypeTagType (type) {
switch (type) {
case this.SysOnlineDictType.TABLE: return 'success';
case this.SysOnlineDictType.URL: return 'primary';
case this.SysOnlineDictType.STATIC: return 'warning';
case this.SysOnlineDictType.CUSTOM: return 'danger';
default:
return 'info';
}
},
/**
* 获取动态表单字典列表
*/
loadDynamicDictData (params) {
params = {
...params,
onlineDictDtoFilter: {
dictName: this.formOnlineDict.formFilterCopy.dictName
}
}
return new Promise((resolve, reject) => {
OnlineDictController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
loadDynamicDictVerify () {
this.formOnlineDict.formFilterCopy.dictName = this.formOnlineDict.formFilter.dictName;
return true;
},
refreshOnlineDict (reloadData) {
if (reloadData) {
this.formOnlineDict.dict.impl.refreshTable(true, 1);
} else {
this.formOnlineDict.dict.impl.refreshTable();
}
if (!this.formOnlineDict.isInit) {
// 初始化下拉数据
}
this.formOnlineDict.isInit = true;
},
onFormCreateDictClick () {
this.$dialog.show('新建字典', EditOnlineDict, {
area: '600px',
offset: '100px'
}).then(res => {
this.formOnlineDict.dict.impl.refreshTable();
}).catch(e => {
console.log(e);
});
},
onFormEditDictClick (row) {
this.$dialog.show(row ? '编辑字典' : '新建字典', EditOnlineDict, {
area: '600px',
offset: '100px'
}, {
dictId: row.dictId
}).then(res => {
this.formOnlineDict.dict.impl.refreshTable();
}).catch(e => {
});
},
onFormDeleteDictClick (row) {
this.$confirm('是否删除此字典?').then(res => {
let params = {
dictId: row.dictId
}
return OnlineDictController.delete(this, params);
}).then(res => {
this.$message.success('删除成功!');
this.formOnlineDict.dict.impl.refreshTable();
}).catch(e => {});
},
onResume () {
this.refreshOnlineDict();
},
initFormData () {
},
formInit () {
this.refreshOnlineDict();
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,212 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="表单编码" prop="formCode">
<el-input class="input-item" v-model="formData.formCode"
:clearable="true" placeholder="表单编码" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="表单名称" prop="formName">
<el-input class="input-item" v-model="formData.formName"
:clearable="true" placeholder="表单名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="表单类别" prop="formKind">
<el-select class="input-item" v-model="formData.formKind"
placeholder="表单类别" :disabled="pageType === SysOnlinePageType.FLOW">
<el-option v-for="item in SysOnlineFormKind.getList()" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="表单类型" prop="formType">
<el-select class="input-item" v-model="formData.formType"
placeholder="表单类型" :disabled="isEdit">
<el-option v-for="item in getValidFormType" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="表单数据" prop="masterTableId">
<el-select class="input-item" v-model="formData.masterTableId" :clearable="true"
placeholder="表单数据" :disabled="isEdit">
<el-option v-for="item in getValidTableList" :key="item.tableId" :value="item.tableId" :label="item.tableName">
<el-row type="flex" justify="space-between" align="middle">
<span>{{item.tableName}}</span>
<el-tag size="mini" :type="getDatasourceTableTagType(item.relationType)" effect="dark"
style="margin-left: 30px;"
>
{{getDatasourceTableTagName(item.relationType)}}
</el-tag>
</el-row>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { OnlineFormController } from '@/api/onlineController.js';
import { defaultFormConfig, defaultWidgetAttributes } from '../data/onlineFormOptions.js';
export default {
props: {
pageId: {
type: String,
required: true
},
pageType: {
type: Number,
required: true
},
datasourceTableList: {
type: Array,
required: true
},
datasourceId: {
type: String,
required: true
},
form: {
type: Object
}
},
data () {
return {
formData: {
formId: undefined,
formCode: undefined,
formName: undefined,
formKind: this.SysOnlineFormKind.PAGE,
formType: this.pageType === this.SysOnlinePageType.FLOW ? this.SysOnlineFormType.FLOW : this.SysOnlineFormType.QUERY,
masterTableId: undefined
},
rules: {
formCode: [
{required: true, message: '表单编码不能为空', trigger: true},
{type: 'string', pattern: /^[A-Za-z0-9]+$/, message: '表单编码只允许输入字母和数字', trigger: 'blur'}
],
formName: [
{required: true, message: '表单名称不能为空', trigger: true}
],
masterTableId: [
{required: true, message: '请选择表单数据', trigger: true}
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
let formConfig = {
...defaultFormConfig,
widgetList: [],
paramList: []
}
// 如果是查询页面,则添加默认的主表
if (this.formData.formType === this.SysOnlineFormType.QUERY || this.formData.formType === this.SysOnlineFormType.WORK_ORDER) {
formConfig.tableWidget = {
...defaultWidgetAttributes.table,
tableId: this.formData.masterTableId,
tableColumnList: [],
variableName: this.formData.formCode,
showName: this.formData.formName,
operationList: this.formData.formType === this.SysOnlineFormType.QUERY ? [...defaultWidgetAttributes.table.operationList] : [],
tableInfo: { ...defaultWidgetAttributes.table.tableInfo }
}
}
let params = {
onlineFormDto: {
...this.formData,
pageId: this.pageId,
widgetJson: this.isEdit ? this.formData.widgetJson : JSON.stringify({
formConfig: formConfig,
widgetList: []
}),
paramsJson: this.isEdit ? this.formData.paramsJson : JSON.stringify([]),
datasourceIdList: [this.datasourceId]
}
}
let httpCall = this.isEdit ? OnlineFormController.update(this, params) : OnlineFormController.add(this, params);
httpCall.then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
},
getDatasourceTableTagType (relationType) {
if (relationType == null) return 'success';
switch (relationType) {
case this.SysOnlineRelationType.ONE_TO_ONE: return 'primary';
case this.SysOnlineRelationType.ONE_TO_MANY: return 'warning';
default:
return 'info';
}
},
getDatasourceTableTagName (relationType) {
if (relationType == null) return '数据主表';
return this.SysOnlineRelationType.getValue(relationType) || '未知类型';
}
},
computed: {
isEdit () {
return this.form != null;
},
getValidFormType () {
return this.SysOnlineFormType.getList().filter(item => {
if (item.id === this.SysOnlineFormType.FLOW) {
return this.pageType === this.SysOnlinePageType.FLOW;
} else if (item.id === this.SysOnlineFormType.QUERY) {
return this.pageType !== this.SysOnlinePageType.FLOW;
} else {
return true;
}
});
},
getValidTableList () {
return this.datasourceTableList.filter(item => {
// 主数据源和一对多关联的从表,才可以创建表单
return (
item.relationType == null || item.relationType === this.SysOnlineRelationType.ONE_TO_MANY ||
(this.formData.formType === this.SysOnlineFormType.FLOW && item.relationType === this.SysOnlineRelationType.ONE_TO_ONE)
);
});
}
},
mounted () {
if (this.isEdit) {
this.formData = {
...this.form
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,201 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditOnlinePageDatasource" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="数据源名称" prop="datasourceName">
<el-input class="input-item" v-model="formData.datasourceName"
:clearable="true" placeholder="数据源名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="数据源标识" prop="variableName">
<el-input class="input-item" v-model="formData.variableName"
:clearable="true" placeholder="数据源标识" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="!isEdit">
<el-form-item label="数据源主表" prop="masterTableId">
<el-cascader v-model="masterTablePath"
filterable
:disabled="isEdit"
:props="masterTableProps"
@change="onMasterTableChange"
/>
</el-form-item>
</el-col>
<el-col :span="24" v-else>
<el-form-item label="数据源主表">
<el-input class="input-item" v-model="(masterTableIdDictMap || {}).name" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { OnlineDatasourceController, OnlineDblinkController } from '@/api/onlineController.js';
export default {
name: 'formEditOnlinePageDatasource',
props: {
pageId: {
type: String,
required: true
},
datasourceId: {
type: String,
default: undefined
},
dblinkInfo: {
type: Object
}
},
data () {
return {
masterTableIdDictMap: {},
formData: {
datasourceId: this.datasourceId,
datasourceName: undefined,
variableName: undefined,
dblinkId: undefined,
masterTableId: undefined
},
masterTablePath: [],
rules: {
datasourceName: [
{required: true, message: '数据源名称不能为空!', trigger: 'blur'}
],
variableName: [
{required: true, message: '数据源标识不能为空!', trigger: 'blur'},
{type: 'string', pattern: /^[a-z][a-zA-Z]+$/, message: '数据源标识必须是小驼峰命名', trigger: 'blur'}
],
masterTableId: [
{required: true, message: '数据源主表不能为空!', trigger: 'blur'}
]
},
masterTableProps: {
lazy: true,
lazyLoad: this.loadMasterTableData
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
this.$refs.formEditOnlinePageDatasource.validate((valid) => {
if (!valid) return;
let params = {
pageId: this.pageId,
onlineDatasourceDto: {
datasourceId: this.formData.datasourceId,
datasourceName: this.formData.datasourceName,
variableName: this.formData.variableName,
dblinkId: this.formData.dblinkId,
masterTableName: this.formData.masterTableId,
masterTableId: this.isEdit ? this.formData.masterTableId : undefined
}
}
let httpCall = this.isEdit ? OnlineDatasourceController.update(this, params) : OnlineDatasourceController.add(this, params);
httpCall.then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
onMasterTableChange (values) {
this.formData.dblinkId = values[0];
this.formData.masterTableId = values[1];
},
/**
* 获取字典表级联数据
*/
loadMasterTableData (node, resolve) {
if (node.level === 0) {
// 获取dblink信息
if (this.dblinkInfo == null) {
OnlineDblinkController.list(this, {}).then(res => {
resolve(res.data.dataList.map(item => {
return {
value: item.dblinkId,
label: item.dblinkName,
leaf: false
}
}));
}).catch(e => {
node.loaded = false;
node.loading = false;
});
} else {
resolve(Object.keys(this.dblinkInfo).map(key => {
let dblinkItem = this.dblinkInfo[key];
return {
value: dblinkItem.dblinkId,
label: dblinkItem.dblinkName,
leaf: false
}
}));
}
} else if (node.level === 1) {
OnlineDblinkController.listDblinkTables(this, {
dblinkId: node.data.value
}).then(res => {
resolve(res.data.map(item => {
return {
value: item.tableName,
label: item.tableName,
leaf: true
}
}));
}).catch(e => {
node.loaded = false;
node.loading = false;
});
}
}
},
computed: {
isEdit () {
return this.datasourceId != null && this.datasourceId !== '';
}
},
mounted () {
if (this.datasourceId != null) {
OnlineDatasourceController.view(this, {
datasourceId: this.datasourceId
}).then(res => {
this.formData.datasourceId = res.data.datasourceId;
this.formData.datasourceName = res.data.datasourceName;
this.formData.dblinkId = res.data.dblinkId;
this.formData.masterTableId = res.data.masterTableId;
this.formData.variableName = res.data.variableName;
this.masterTablePath = [this.formData.dblinkId, this.formData.masterTableId];
this.masterTableIdDictMap = res.data.masterTableIdDictMap;
}).catch(e => {});
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,358 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditOnlinePageDatasourceRelation" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="120px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="关联名称" prop="relationName">
<el-input class="input-item" v-model="formData.relationName" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="关联类型">
<el-select class="input-item" v-model="formData.relationType" placeholder="关联类型" :disabled="isEdit">
<el-option v-for="item in SysOnlineRelationType.getList()" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="关联主表">
<el-input :value="dblinkInfo.dblinkName + ' / ' + datasource.masterTableIdDictMap.name" readonly />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="主表关联字段" prop="masterColumnId">
<el-select class="input-item" v-model="formData.masterColumnId" :clearable="true" filterable
placeholder="主表关联字段" :loading="masterColumnIdWidget.loading"
@visible-change="masterColumnIdWidget.onVisibleChange"
@change="onMasterColumnChange">
<el-option v-for="item in masterColumnIdWidget.dropdownList" :key="item.columnId" :value="item.columnId" :label="item.columnName">
<el-row type="flex" justify="space-between">
<span>{{item.columnName}}</span>
<span style="margin-left: 30px;">{{item.columnComment}}</span>
</el-row>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="关联从表" prop="slaveTableId">
<el-select class="input-item" v-model="formData.slaveTableId" :clearable="true" filterable
placeholder="关联从表" :loading="slaveTableIdWidget.loading" :disabled="isEdit"
@visible-change="slaveTableIdWidget.onVisibleChange"
@change="onSlaveTableChange">
<el-option v-for="item in slaveTableIdWidget.dropdownList" :key="item.id" :value="item.id" :label="item.name">
<span>{{item.name}}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="从表关联字段" prop="slaveColumnId">
<el-select class="input-item" v-model="formData.slaveColumnId" :clearable="true" filterable
placeholder="关联从表" :loading="slaveColumnIdWidget.loading"
@visible-change="slaveColumnIdWidget.onVisibleChange">
<el-option v-for="item in slaveColumnIdWidget.dropdownList" :key="item.columnId" :value="item.columnId" :label="item.columnName">
<span>{{item.columnName}}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="是否级联删除">
<el-switch v-model="formData.cascadeDelete" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="是否左连接">
<el-switch v-model="formData.leftJoin" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findItemFromList } from '@/utils';
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
import { DropdownWidget } from '@/utils/widget.js';
import { OnlineDatasourceRelationController, OnlineDblinkController, OnlineColumnController } from '@/api/onlineController.js';
export default {
name: 'formEditOnlinePageDatasourceRelation',
props: {
datasource: {
type: Object,
required: true
},
dblinkInfo: {
type: Object,
required: true
},
relationId: {
type: String,
default: undefined
},
usedTableNameList: {
type: Array
}
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
// 编辑状态下老的关联从表表名
oldSlaveTableName: undefined,
formData: {
relationId: undefined,
relationName: undefined,
relationType: this.SysOnlineRelationType.ONE_TO_ONE,
variableName: undefined,
masterColumnId: undefined,
slaveTableId: undefined,
slaveColumnId: undefined,
cascadeDelete: false,
leftJoin: false
},
// 主表关联字段
masterColumnIdWidget: new DropdownWidget(this.loadMasterColumnDropdownList),
// 关联从表
slaveTableIdWidget: new DropdownWidget(this.loadSlaveTableDropdownList),
// 从表关联字段
slaveColumnIdWidget: new DropdownWidget(this.loadSlaveColumnDropdownList),
rules: {
relationName: [
{required: true, message: '请输入关联名称', trigger: 'blur'}
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
this.$refs.formEditOnlinePageDatasourceRelation.validate((valid) => {
if (!valid) return;
let masterColumn = findItemFromList(this.masterColumnIdWidget.dropdownList, this.formData.masterColumnId, 'columnId');
let slaveTable = findItemFromList(this.slaveTableIdWidget.dropdownList, this.formData.slaveTableId, 'id');
let slaveColumn = findItemFromList(this.slaveColumnIdWidget.dropdownList, this.formData.slaveColumnId, 'columnId');
if (!this.isEdit) this.formData.variableName = masterColumn.columnName + '_' + slaveTable.name + '_' + slaveColumn.columnName + 'Relation';
let params = {
onlineDatasourceRelationDto: {
datasourceId: this.datasource.datasourceId,
relationId: this.formData.relationId,
relationName: this.formData.relationName,
relationType: this.formData.relationType,
variableName: this.formData.variableName,
masterColumnId: this.formData.masterColumnId,
slaveTableId: this.isEdit ? this.formData.slaveTableId : undefined,
slaveTableName: this.isEdit ? undefined : this.formData.slaveTableId,
slaveColumnId: this.isEdit ? this.formData.slaveColumnId : undefined,
slaveColumnName: this.isEdit ? undefined : this.formData.slaveColumnId,
cascadeDelete: this.formData.cascadeDelete,
leftJoin: this.formData.leftJoin
}
}
let httpCall = this.isEdit ? OnlineDatasourceRelationController.update(this, params) : OnlineDatasourceRelationController.add(this, params);
httpCall.then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
/**
* 主表关联字段改变
*/
onMasterColumnChange (value) {
},
/**
* 获取从表下拉表列表
*/
loadSlaveTableDropdownList () {
return Promise.resolve(this.getValidTableList.filter(item => {
// 可选从表为未使用的数据表
return (this.oldSlaveTableName != null && this.oldSlaveTableName === item.name) ||
(
item.name !== this.datasource.masterTableIdDictMap.name &&
(this.usedTableNameList == null || this.usedTableNameList.indexOf(item.name) === -1)
);
}));
},
/**
* 从表改变,清空从表关联字段选中
*/
onSlaveTableChange () {
this.formData.slaveColumnId = null;
this.slaveColumnIdWidget.dirty = true;
this.formData.leftJoin = false;
this.formData.cascadeDelete = false;
},
getColumnTagType (status) {
switch (status) {
case this.SysOnlinePageDatasourceFieldStatus.USED:
case this.SysOnlinePageDatasourceFieldStatus.UNUSED:
return 'success';
case this.SysOnlinePageDatasourceFieldStatus.DELETED:
return 'danger';
}
},
/**
* 合并表字段
*/
mergeTableColumns (onlineTableColumns, dblinkTableColumns) {
if (!Array.isArray(onlineTableColumns)) onlineTableColumns = [];
if (!Array.isArray(dblinkTableColumns)) dblinkTableColumns = [];
let columnNameSet = new Set();
// 合并字段
let finalColumnList = dblinkTableColumns.map(dblinkColumn => {
let onlineColumn = findItemFromList(onlineTableColumns, dblinkColumn.columnName, 'columnName');
columnNameSet.add(dblinkColumn.columnName);
return {
id: onlineColumn ? onlineColumn.columnId : dblinkColumn.columnName,
name: dblinkColumn.columnName,
columnType: dblinkColumn.columnType,
columnComment: dblinkColumn.columnComment,
status: onlineColumn ? this.SysOnlinePageDatasourceFieldStatus.USED : this.SysOnlinePageDatasourceFieldStatus.UNUSED,
tag: onlineColumn || dblinkColumn
}
});
// 添加online table里存在但是dblink table里不存在的字段此字段可能为被删除字段或者字段名被修改
onlineTableColumns.forEach(onlineColumn => {
if (!columnNameSet.has(onlineColumn.columnName)) {
finalColumnList.push({
id: onlineColumn.columnId,
name: onlineColumn.columnName,
columnType: onlineColumn.columnType,
columnComment: onlineColumn.columnComment,
status: this.SysOnlinePageDatasourceFieldStatus.DELETED,
tag: onlineColumn
})
}
});
columnNameSet = null;
return finalColumnList;
},
/**
* 获取主表关联字段列表
*/
loadMasterColumnDropdownList () {
return new Promise((resolve, reject) => {
this.loadOnlineTableColumns(this.datasource.masterTableId).then(res => {
resolve(res);
}).catch(e => {
reject(e);
});
});
},
/**
* 获取从表关联字段列表
*/
loadSlaveColumnDropdownList () {
return new Promise((resolve, reject) => {
// 获取从表信息
let slaveTable = findItemFromList(this.datasource.validTableList, this.formData.slaveTableId, 'id');
if (slaveTable == null) reject();
if (slaveTable.status === this.SysOnlinePageDatasourceFieldStatus.USED) {
// 从导入数据表中获取数据表字段列表
this.loadOnlineTableColumns(slaveTable.id).then(res => {
resolve(res);
}).catch(e => {
reject(e);
});
} else {
// 从数据库中获取数据表字段列表
this.loadDblinkTableColumns(this.datasource.dblinkId, slaveTable.id).then(res => {
res.forEach(item => {
item.columnId = item.columnName;
});
resolve(res);
}).catch(e => {
reject(e);
})
}
});
},
/**
* 获取在线表单导入表字段列表
*/
loadOnlineTableColumns (tableId) {
return new Promise((resolve, reject) => {
if (tableId == null) {
resolve([]);
return;
}
let params = {
onlineColumnDtoFilter: {
tableId: tableId
}
};
OnlineColumnController.list(this, params).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
/**
* 获取数据库表字段列表
*/
loadDblinkTableColumns (dblinkId, tableName) {
return new Promise((resolve, reject) => {
let params = {
dblinkId: dblinkId,
tableName: tableName
};
OnlineDblinkController.listDblinkTableColumns(this, params).then(res => {
resolve(res.data);
}).catch(e => {
reject(e);
});
});
}
},
computed: {
isEdit () {
return this.relationId != null && this.relationId !== '';
},
getValidTableList () {
return this.datasource.validTableList;
}
},
mounted () {
if (this.isEdit) {
OnlineDatasourceRelationController.view(this, {
relationId: this.relationId
}).then(res => {
this.oldSlaveTableName = res.data.slaveTable.tableName;
this.formData = {
...res.data
}
this.masterColumnIdWidget.onVisibleChange(true);
this.slaveTableIdWidget.onVisibleChange(true);
this.slaveColumnIdWidget.onVisibleChange(true);
}).catch(e => {});
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,193 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="数据表" prop="tableId">
<el-select class="input-item" v-model="formData.tableId"
:clearable="true" filterable placeholder="数据表"
>
<el-option v-for="item in tableList" :key="item.tableId" :value="item.tableId" :label="item.tableName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="过滤字段" prop="columnId">
<el-select class="input-item" v-model="formData.columnId"
:clearable="true" filterable placeholder="过滤字段"
>
<el-option v-for="item in columnList" :key="item.columnId" :value="item.columnId" :label="item.columnName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="过滤类型" prop="operatorType">
<el-select class="input-item" v-model="formData.operatorType"
:clearable="true" filterable placeholder="过滤类型"
@change="onOperationTypeChange"
>
<el-option v-for="item in SysOnlineFilterOperationType.getList()" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="过滤参数值" prop="value">
<el-select v-if="dictValueList != null" v-model="formData.value" :disabled="!valueEnabled" placeholder="">
<el-option v-for="item in dictValueList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
<template v-else>
<el-switch v-if="filterColumn != null && filterColumn.objectFieldType === 'Boolean'" :disabled="!valueEnabled" v-model="formData.value" />
<el-input-number v-if="filterColumn != null && ['Integer', 'Long', 'BigDecimal', 'Double'].indexOf(filterColumn.objectFieldType) !== -1"
:disabled="!valueEnabled" v-model="formData.value" :controls="false"
/>
<el-input v-else :disabled="filterColumn == null || !valueEnabled" v-model="formData.value" clearable />
</template>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findItemFromList } from '@/utils';
import { DropdownWidget } from '@/utils/widget.js';
import { OnlineColumnController } from '@/api/onlineController.js';
import { getDictDataList } from '../utils';
export default {
props: {
tableList: {
type: Array,
required: true
},
rowData: {
type: Object
}
},
data () {
return {
formData: {
tableId: undefined,
columnId: undefined,
operatorType: this.SysOnlineFilterOperationType.EQUAL,
value: undefined,
dictValueName: undefined
},
columnList: [],
dictValueList: [],
operatorTypeWidget: new DropdownWidget(this.loadColumnIdDropdownList),
rules: {}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
let temp = findItemFromList(this.dictValueList, this.formData.value, 'id');
this.formData.dictValueName = temp ? temp.name : undefined;
this.observer.cancel(isSuccess, {
...this.formData,
table: this.filterTable,
column: this.filterColumn
});
}
},
onSubmit () {
this.$refs.form.validate(valid => {
if (!valid) return;
this.onCancel(true);
});
},
loadOnlineTableColumnList (tableId) {
if (tableId == null || tableId === '') return;
let params = {
onlineColumnDtoFilter: {
tableId
}
}
OnlineColumnController.list(this, params).then(res => {
this.filterTable.columnList = res.data.dataList;
this.columnList = res.data.dataList;
}).catch(e => {});
},
onOperationTypeChange (value) {
if ([this.SysOnlineFilterOperationType.NOT_NULL || this.SysOnlineFilterOperationType.IS_NULL].indexOf(value) !== -1 || value == null) {
this.formData.value = undefined;
}
},
getDictValue (dictInfo) {
if (dictInfo == null) return;
getDictDataList(this, dictInfo).then(res => {
this.dictValueList = res;
}).catch(e => {});
}
},
computed: {
valueEnabled () {
let temp = [
this.SysOnlineFilterOperationType.NOT_NULL,
this.SysOnlineFilterOperationType.IS_NULL
];
return temp.indexOf(this.formData.operatorType) === -1 && this.formData.operatorType != null;
},
filterTable () {
return findItemFromList(this.tableList, this.formData.tableId, 'tableId');
},
filterColumn () {
return findItemFromList(this.columnList, this.formData.columnId, 'columnId');
}
},
mounted () {
if (this.rowData) {
this.formData = {
...this.rowData
}
}
},
watch: {
filterTable: {
handler (table) {
this.columnList = [];
if (table != null) {
if (Array.isArray(table.columnList)) {
this.columnList = table.columnList;
} else {
this.loadOnlineTableColumnList(table.tableId);
}
}
}
},
filterColumn: {
handler (column) {
this.dictValueList = null;
this.formData.dictValueName = undefined;
if (column != null) {
if (column.dictInfo != null) {
this.getDictValue(column.dictInfo);
}
} else {
this.formData.columnId = undefined;
}
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,203 @@
<template>
<div style="position: relative;">
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="表单类型">
<el-select class="filter-item" v-model="formOnlinePage.formFilter.pageType"
placeholder="表单类型" :clearable="true">
<el-option v-for="item in SysOnlinePageType.getList()"
:key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="表单名称">
<el-input class="filter-item" v-model="formOnlinePage.formFilter.pageName"
:clearable="true" placeholder="表单名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshOnlinePage(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini"
@click="onCreateOnlinePage()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table ref="class" :data="pageListWidget.dataList" size="mini" @sort-change="pageListWidget.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="pageListWidget.getTableIndex" />
<el-table-column label="页面名称" prop="pageName" />
<el-table-column label="页面代码" prop="pageCode" />
<el-table-column label="页面类型">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.pageType === SysOnlinePageType.BIZ ? 'success' : 'primary'">
{{SysOnlinePageType.getValue(scope.row.pageType)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="页面状态" prop="statusDictMap.name">
<template slot-scope="scope">
<el-tag size="mini" :type="getPageStatusTagType(scope.row.status)">
{{SysOnlinePageStatus.getValue(scope.row.status)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="发布状态">
<template slot-scope="scope">
<el-switch v-model="scope.row.published" @change="onUpdatePagePublished(scope.row)" />
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime" />
<el-table-column label="操作" width="150px" fixed="right">
<template slot-scope="scope">
<el-button class="table-btn success" type="text" @click="onEditOnlinePage(scope.row)">编辑</el-button>
<el-button class="table-btn delete" type="text" @click="onDeleteOnlinePage(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<OnlinePageSetting v-if="showPageSetting" :pageId="(currentPage || {}).pageId" @close="onCloseSetting" />
</div>
</template>
<script>
import '@/staticDict/onlineStaticDict.js';
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { TableWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { OnlinePageController } from '@/api/onlineController.js';
import OnlinePageSetting from './onlinePageSetting.vue';
export default {
name: 'formOnlinePage',
props: {
},
components: {
OnlinePageSetting
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
showPageSetting: false,
currentPage: undefined,
formOnlinePage: {
formFilter: {
pageType: undefined,
pageName: undefined
},
formFilterCopy: {
pageType: undefined,
pageName: undefined
},
isInit: false
},
pageListWidget: new TableWidget(this.loadOnlinePageData, this.loadOnlinePageVerify, false, false)
}
},
methods: {
getPageStatusTagType (status) {
switch (status) {
case this.SysOnlinePageStatus.BASIC: return 'warning';
case this.SysOnlinePageStatus.DATASOURCE: return 'primary';
case this.SysOnlinePageStatus.DESIGNING: return 'success';
}
},
/**
* 获取在线页面列表
*/
loadOnlinePageData (params) {
if (params == null) params = {};
params = {
...params,
onlinePageDtoFilter: {
pageType: this.formOnlinePage.formFilterCopy.pageType,
pageName: this.formOnlinePage.formFilterCopy.pageName
}
}
return new Promise((resolve, reject) => {
OnlinePageController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
loadOnlinePageVerify () {
this.formOnlinePage.formFilterCopy.pageType = this.formOnlinePage.formFilter.pageType;
this.formOnlinePage.formFilterCopy.pageName = this.formOnlinePage.formFilter.pageName;
return true;
},
onCreateOnlinePage () {
this.currentPage = null;
this.showPageSetting = true;
},
onEditOnlinePage (row) {
this.currentPage = row;
this.showPageSetting = true;
},
onDeleteOnlinePage (row) {
this.$confirm('是否删除此页面?').then(res => {
let params = {
pageId: row.pageId
}
return OnlinePageController.delete(this, params);
}).then(res => {
this.$message.success('删除成功!');
this.pageListWidget.refreshTable();
}).catch(e => {});
},
onUpdatePagePublished (row) {
let params = {
pageId: row.pageId,
published: row.published
}
OnlinePageController.updatePublished(this, params).catch(e => {
// 恢复发布状态为更改之前
row.published = !row.published;
});
},
onCloseSetting () {
this.currentPage = null;
this.showPageSetting = false;
this.pageListWidget.refreshTable();
},
refreshOnlinePage (reloadData) {
if (reloadData) {
this.pageListWidget.refreshTable(true, 1);
} else {
this.pageListWidget.refreshTable();
}
if (!this.formOnlinePage.isInit) {
// 初始化下拉数据
}
this.formOnlinePage.isInit = true;
},
onResume () {
this.refreshOnlinePage();
},
initFormData () {
},
formInit () {
this.refreshOnlinePage();
}
},
computed: {
...mapGetters(['getClientHeight'])
},
mounted () {
// 初始化页面数据
this.formInit();
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,936 @@
<template>
<div class="edit-online-form">
<el-container>
<el-header>
<el-row>
<el-col class="title header" :span="6" style="">
<i class="el-icon-orange" />
<span>橙单在线表单</span>
</el-col>
<el-col :span="12">
<el-steps :active="activeStep" finish-status="success" simple style="margin-top: 7px;">
<el-step title="基础信息"></el-step>
<el-step title="数据模型"></el-step>
<el-step title="表单设计"></el-step>
</el-steps>
</el-col>
<el-col :span="6">
<el-row type="flex" justify="end" align="middle" style="height: 60px;" v-if="virtualColumnTable == null && currentTable == null && currentForm == null">
<el-button size="small" @click="onPrevClick"
:disabled="activeStep === SysOnlinePageSettingStep.BASIC"
>
上一步
</el-button>
<el-button size="small" @click="onNextClick" :disabled="activeStep === SysOnlinePageSettingStep.FORM_DESIGN">下一步</el-button>
<el-button size="small" type="primary" @click="onClose(false)">退出</el-button>
</el-row>
</el-col>
</el-row>
</el-header>
<el-main style="background: #EBEEF5; padding: 10px;" :style="{height: getClientHeight - 60 + 'px'}">
<el-row type="flex" justify="center" style="height: 100%;">
<!-- 在线表单基础信息设置 -->
<el-col v-if="activeStep === SysOnlinePageSettingStep.BASIC" class="main-box" style="width: 600px;" :span="9">
<el-form ref="pageBasicInfo" class="full-width-input" size="small" :model="formPageData" :rules="formRules"
label-position="right" label-width="100px" @submit.native.prevent>
<el-col :span="24">
<el-form-item label="页面类型">
<el-select v-model="formPageData.pageType" :disabled="isEdit">
<el-option :value="SysOnlinePageType.BIZ" :label="SysOnlinePageType.getValue(SysOnlinePageType.BIZ)" />
<el-option :value="SysOnlinePageType.FLOW" :label="SysOnlinePageType.getValue(SysOnlinePageType.FLOW)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="页面编码" prop="pageCode">
<el-input v-model="formPageData.pageCode" :disabled="isEdit" @change="dirty = true" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="页面名称" prop="pageName">
<el-input v-model="formPageData.pageName" @change="dirty = true" />
</el-form-item>
</el-col>
</el-form>
</el-col>
<!-- 在线表单数据模型配置 -->
<el-col v-if="activeStep === SysOnlinePageSettingStep.DATASOURCE && currentTable == null && virtualColumnTable == null" class="main-box" :span="24" style="min-width: 1100px;">
<el-table :data="getPageDatasourceTableList" 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="tableName" />
<el-table-column label="关联类型" prop="relationType">
<template slot-scope="scope">
<el-tag size="mini" :type="getDatasourceTableTagType(scope.row.relationType)" effect="dark">
{{getDatasourceTableTagName(scope.row.relationType)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="主表关联字段" prop="masterColumnName" />
<el-table-column label="从表关联字段" prop="slaveColumnName" />
<el-table-column label="级联删除" prop="cascadeDelete">
<template slot-scope="scope">
<el-tag v-if="scope.row.relationType != null" size="mini"
:type="scope.row.cascadeDelete ? 'success' : 'danger'" effect="dark">
{{scope.row.cascadeDelete ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="是否左连接" prop="leftJoin">
<template slot-scope="scope">
<el-tag v-if="scope.row.relationType != null" size="mini"
:type="scope.row.leftJoin ? 'success' : 'danger'" effect="dark">
{{scope.row.leftJoin ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="250px" fixed="right">
<template slot-scope="scope">
<!-- 数据源主表只有当没有任何关联的时候才可以编辑 -->
<el-button class="table-btn success" size="mini" type="text"
@click="onEditDatasourceTable(scope.row)"
:disabled="scope.row.relationType == null && Array.isArray(scope.row.relationList) && scope.row.relationList.length > 0"
>
编辑
</el-button>
<el-button size="mini" type="text"
@click="onEditTableColumn(scope.row)">
字段管理
</el-button>
<el-button size="mini" type="text"
:disabled="scope.row.relationType != null"
@click="onEditVirtualColumn(scope.row)">
聚合计算
</el-button>
<el-button class="table-btn delete" size="mini" type="text"
:disabled="scope.row.relationType == null && (!Array.isArray(scope.row.relationList) || scope.row.relationList.length <= 0)"
@click="onDeleteDatasourceTable(scope.row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="btn-add" icon="el-icon-plus" @click="onAddDatasourceClick">新增数据表</el-button>
</el-col>
<!-- 编辑数据表字段验证规则 -->
<el-col v-if="activeStep === SysOnlinePageSettingStep.DATASOURCE && currentTable != null" :span="24">
<OnlinePageTableColumnRule
:isMasterTable="currentTable.relationType == null"
:tableId="currentTable.tableId"
:dblinkId="getPageDatasource.dblinkId"
:tableName="currentTable.tableName"
:dictList="dictList"
:height="getClientHeight - 80"
@close="onRuleClose"
/>
</el-col>
<!-- 数据源虚拟字段设置 -->
<el-col v-if="activeStep === SysOnlinePageSettingStep.DATASOURCE && virtualColumnTable != null" :span="24">
<OnlinePageVirtualColumn
:datasource="virtualColumnTable.tag"
:relationList="virtualColumnTable.tag.relationList"
:height="getClientHeight - 80"
@close="onVirtualColumnClose"
/>
</el-col>
<!-- 在线表单子表单列表 -->
<el-col v-if="activeStep === SysOnlinePageSettingStep.FORM_DESIGN && currentForm == null" class="main-box" :span="16">
<el-table :data="formList" header-cell-class-name="table-header-gray" key="onlineForm">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" />
<el-table-column label="表单标识" prop="formCode" />
<el-table-column label="表单名称" prop="formName" />
<el-table-column label="表单类型" prop="formType">
<template slot-scope="scope">
<el-tag size="mini" effect="dark"
:type="getFormTypeTag(scope.row.formType)"
>
{{SysOnlineFormType.getValue(scope.row.formType)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150px">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="onDesignPageForm(scope.row)">页面布局</el-button>
<el-button class="table-btn success" size="mini" type="text" @click="onEditPageForm(scope.row)">编辑</el-button>
<el-button class="table-btn delete" size="mini" type="text" style="color: #F56C6C;" @click="onDeletePageForm(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="btn-add" icon="el-icon-plus" @click="onEditPageForm()">添加表单</el-button>
</el-col>
<!-- 在线表单子表单设计 -->
<FormGenerator v-if="currentForm != null" style="width: 100%;"
:pageType="formPageData.pageType"
:height="getClientHeight - 80"
:form="currentForm"
:tableList="getTableInfo"
:datasourceTableList="getPageDatasourceTableList"
:formList="formList"
:formDatasourceList="pageDatasourceList"
@tableCreate="onQueryCreateClick"
@close="onCloseFormDesign"
/>
</el-row>
</el-main>
</el-container>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { findItemFromList } from '@/utils';
import OnlinePageTableColumnRule from './onlinePageTableColumnRule.vue';
import OnlinePageVirtualColumn from './onlinePageVirtualColumn.vue';
import FormGenerator from '../components/formGenerator.vue';
import {
OnlinePageController,
OnlineDatasourceController,
OnlineDatasourceRelationController,
OnlineFormController,
OnlineDblinkController,
OnlineColumnController,
OnlineDictController,
OnlineVirtualColumnController
} from '@/api/onlineController.js';
import EditOnlinePageDatasource from './editOnlinePageDatasource.vue';
import EditOnlinePageDatasourceRelation from './editOnlinePageDatasourceRelation.vue';
import EditOnlineForm from './editOnlineForm.vue';
export default {
name: 'onlinePageSetting',
props: {
pageId: {
type: String,
default: undefined
}
},
components: {
FormGenerator,
OnlinePageTableColumnRule,
OnlinePageVirtualColumn
},
data () {
return {
dirty: false,
activeStep: this.SysOnlinePageSettingStep.BASIC,
// 页面基础信息
formPageData: {
pageId: undefined,
pageCode: undefined,
pageName: undefined,
published: false,
pageType: this.SysOnlinePageType.BIZ,
status: this.SysOnlinePageStatus.BASIC
},
dictList: [],
// 页面数据模型列表
pageDatasourceList: [],
// 子表单列表
formList: [],
// 数据库信息
dblinkInfo: {},
// 当前选中表单
currentForm: undefined,
currentTable: undefined,
virtualColumnTable: undefined,
formRules: {
pageCode: [
{required: true, message: '页面编码不能为空!', trigger: 'blur'},
{type: 'string', pattern: /^[A-Za-z0-9]+$/, message: '页面编码只允许输入字母和数字', trigger: 'blur'}
],
pageName: [
{required: true, message: '页面名称不能为空!', trigger: 'blur'}
]
}
}
},
methods: {
onClose () {
this.$emit('close');
},
onCloseFormDesign () {
this.currentForm = null;
this.initPageFormList(this.formPageData.pageId).catch(e => {});
},
onQueryCreateClick () {
},
getFormTypeTag (formType) {
switch (formType) {
case this.SysOnlineFormType.QUERY: return 'success';
case this.SysOnlineFormType.FORM: return 'primary';
case this.SysOnlinePageType.FLOW: return 'warning';
default: return 'info';
}
},
/**
* 点击上一步
*/
onPrevClick () {
switch (this.activeStep) {
case this.SysOnlinePageSettingStep.DATASOURCE:
this.onSavePageDatasourceInfo(true).then(res => {
this.activeStep = this.SysOnlinePageSettingStep.BASIC;
}).catch(e => {});
break;
case this.SysOnlinePageSettingStep.FORM_DESIGN:
this.dirty = false;
this.activeStep = this.SysOnlinePageSettingStep.DATASOURCE;
break;
}
},
/**
* 点击下一步
*/
onNextClick () {
switch (this.activeStep) {
case this.SysOnlinePageSettingStep.BASIC:
this.onSavePageBasicInfo().then(res => {
return this.initPageDatasourceInfo(this.formPageData.pageId);
}).then(res => {
this.activeStep = this.SysOnlinePageSettingStep.DATASOURCE;
}).catch(e => {});
break;
case this.SysOnlinePageSettingStep.DATASOURCE:
this.onSavePageDatasourceInfo(false).then(res => {
// Step 1 获取数据源所有用到的数据表的字段列表
let httpCalls = [];
this.getPageDatasourceTableList.forEach(item => {
httpCalls.push(this.loadOnlineTableColumns(item.tableId))
});
return Promise.all(httpCalls)
}).then(res => {
res.forEach((item, index) => {
this.getPageDatasourceTableList[index].columnList = item;
return this.getPageDatasourceTableList[index];
});
// Step 2 获取表单列表
return this.initPageFormList(this.formPageData.pageId);
}).then(res => {
// Step 3 进入表单设计页面
this.activeStep = this.SysOnlinePageSettingStep.FORM_DESIGN;
}).catch(e => {});
}
},
/**
* 保存页面基础信息
*/
savePageInfo (status) {
let params = {
onlinePageDto: {
...this.formPageData,
status: status,
published: false
}
}
return this.isEdit ? OnlinePageController.update(this, params) : OnlinePageController.add(this, params);
},
/**
* 保存页面基础信息
*/
onSavePageBasicInfo () {
return new Promise((resolve, reject) => {
this.$refs.pageBasicInfo.validate(valid => {
if (!valid || !this.dirty) {
valid ? resolve() : reject();
return;
}
this.savePageInfo(this.SysOnlinePageStatus.DATASOURCE).then(res => {
this.$message.success('保存页面基础信息成功!');
if (!this.isEdit) this.formPageData.pageId = res.data;
this.dirty = false;
resolve();
}).catch(e => {
reject(e);
});
});
});
},
/**
* 保存页面数据模型信息
*/
onSavePageDatasourceInfo (isPrev = false) {
// 如果是上一步,直接返回上一步
if (isPrev) return Promise.resolve();
// 下一步需判断是否添加了数据源
if (this.getPageDatasource == null) {
this.$message.error('请设置页面数据模型!');
if (this.formPageData.status !== this.SysOnlinePageStatus.DATASOURCE) {
this.savePageInfo(this.SysOnlinePageStatus.DATASOURCE).catch(e => {});
}
return Promise.reject();
} else {
if (this.formPageData.status === this.SysOnlinePageStatus.DESIGNING) {
return Promise.resolve();
} else {
return this.savePageInfo(this.SysOnlinePageStatus.DESIGNING);
}
}
},
/**
* 初始化页面基础信息
*/
initPageInfo () {
this.formPageData = {
pageId: undefined,
pageCode: undefined,
pageName: undefined,
pageType: this.SysOnlinePageType.BIZ,
status: this.SysOnlinePageStatus.BASIC
};
this.activeStep = this.SysOnlinePageSettingStep.BASIC;
if (this.pageId != null || this.formPageData.pageId != null) {
let params = {
pageId: this.pageId || this.formPageData.pageId
}
return OnlinePageController.view(this, params);
} else {
return Promise.resolve();
}
},
/**
* 获取数据模型关联信息
*/
loadDatasourceRelation () {
if (this.getPageDatasource == null) return Promise.resolve();
return OnlineDatasourceRelationController.list(this, {
onlineDatasourceRelationDtoFilter: {
datasourceId: this.getPageDatasource.datasourceId
}
});
},
/**
* 初始化页面数据模型信息
*/
initPageDatasourceInfo (pageId) {
return new Promise((resolve, reject) => {
OnlinePageController.listOnlinePageDatasource(this, {
pageId: pageId
}).then(res => {
this.pageDatasourceList = res.data.dataList;
return this.loadDatasourceRelation();
}).then(res => {
this.pageDatasourceList = this.pageDatasourceList.map(item => {
if (item.datasourceId === this.getPageDatasource.datasourceId) {
item.relationList = res.data.dataList || [];
}
return item;
});
resolve();
}).catch(e => {
reject(e);
});
});
},
/**
* 获取页面子表单列表
*/
initPageFormList (pageId) {
return new Promise((resolve, reject) => {
OnlineFormController.list(this, {
onlineFormDtoFilter: {
pageId: pageId
},
orderParam: [
{
fieldName: 'createTime',
asc: true
}
]
}).then(res => {
this.formList = res.data.dataList;
this.formList.forEach(item => {
item.formData = JSON.parse(item.widgetJson);
});
resolve();
}).catch(e => {
reject(e);
});
});
},
/**
* 获取数据库信息
*/
loadDblinkList () {
return new Promise((resolve, reject) => {
this.dblinkInfo = {};
OnlineDblinkController.list(this, {}).then(res => {
res.data.dataList.forEach(item => {
this.dblinkInfo[item.dblinkId] = {
...item,
tableList: undefined
}
});
resolve();
}).catch(e => {
reject(e);
});
});
},
/**
* 获取数据库下数据表列表
*/
loadDblinkTableList (dblinkId) {
return new Promise((resolve, reject) => {
// 如果此数据库下数据表已经获取过,直接返回数据表列表
if (Array.isArray(this.dblinkInfo[dblinkId].tableList) && this.dblinkInfo[dblinkId].tableList.length > 0) {
resolve(this.dblinkInfo[dblinkId].tableList);
return;
}
// 获取数据库下数据表列表
OnlineDblinkController.listDblinkTables(this, {
dblinkId: dblinkId
}).then(res => {
this.dblinkInfo[dblinkId].tableList = res.data.dataList;
resolve(res.data);
}).catch(e => {
reject(e);
});
});
},
/**
* 获取本数据源下所有导入的表
*/
loadDatasourceTableList (datasourceId) {
return new Promise((resolve, reject) => {
let params = {
datasourceId: datasourceId
}
OnlineDatasourceController.view(this, params).then(res => {
this.datasourceTableList = res.data.tableList || [];
resolve(this.datasourceTableList);
}).catch(e => {
reject(e);
});
});
},
loadOnlineDictList () {
return new Promise((resolve, reject) => {
OnlineDictController.list(this, {}).then(res => {
this.dictList = res.data.dataList;
resolve();
}).catch(e => {
reject(e);
});
});
},
/*************************************************************
************************ 数据模型操作 ************************
*************************************************************/
getDatasourceTableTagType (relationType) {
if (relationType == null) return 'success';
switch (relationType) {
case this.SysOnlineRelationType.ONE_TO_ONE: return 'primary';
case this.SysOnlineRelationType.ONE_TO_MANY: return 'warning';
default:
return 'info';
}
},
getDatasourceTableTagName (relationType) {
if (relationType == null) return '数据主表';
return this.SysOnlineRelationType.getValue(relationType) || '未知类型';
},
/**
* 新增数据模型表
*/
onAddDatasourceClick () {
if (this.getPageDatasource == null) {
// 新增数据模型
this.$dialog.show('新建数据源', EditOnlinePageDatasource, {
area: '500px'
}, {
pageId: this.formPageData.pageId,
dblinkInfo: this.dblinkInfo
}).then(res => {
return this.initPageDatasourceInfo(this.formPageData.pageId);
}).catch(e => {});
} else {
// 新增数据模型关联
this.loadDatasourceValidTableList(this.getPageDatasource).then(res => {
this.$dialog.show('添加关联', EditOnlinePageDatasourceRelation, {
area: '600px'
}, {
datasource: this.getPageDatasource,
dblinkInfo: this.dblinkInfo[this.getPageDatasource.dblinkId],
usedTableNameList: this.getPageDatasourceTableList.map(item => item.tableName)
}).then(res => {
return this.initPageDatasourceInfo(this.formPageData.pageId);
}).catch(e => {
console.log(e);
});
}).catch(e => {
console.log(e);
});
}
},
/**
* 编辑数据模型表
*/
onEditDatasourceTable (row) {
this.loadDatasourceValidTableList(this.getPageDatasource).then(res => {
if (row.relationType == null) {
// 编辑数据模型
this.$dialog.show('编辑数据源', EditOnlinePageDatasource, {
area: '500px'
}, {
pageId: this.formPageData.pageId,
dblinkInfo: this.dblinkInfo,
datasourceId: row.tag.datasourceId
}).then(res => {
return this.initPageDatasourceInfo(this.formPageData.pageId);
}).catch(e => {});
} else {
// 编辑关联
this.$dialog.show('编辑关联', EditOnlinePageDatasourceRelation, {
area: '600px'
}, {
relationId: row.id,
datasource: this.getPageDatasource,
dblinkInfo: this.dblinkInfo[this.getPageDatasource.dblinkId],
usedTableNameList: this.getPageDatasourceTableList.map(item => item.tableName)
}).then(res => {
return this.initPageDatasourceInfo(this.formPageData.pageId);
}).catch(e => {
console.log(e);
});
}
}).catch(e => {});
},
/**
* 删除数据模型表
*/
onDeleteDatasourceTable (row) {
if (row.relationType == null) {
// 删除数据模型
let warningMsg = '是否删除此数据模型?'
if (Array.isArray(row.relationList) && row.relationList.length > 0) {
warningMsg = '此数据模型下还存在关联,如果删除关联数据也将同时删除,是否继续?'
}
this.$confirm(warningMsg).then(res => {
let params = {
datasourceId: row.id
}
return OnlineDatasourceController.delete(this, params);
}).then(res => {
return this.initPageDatasourceInfo(this.formPageData.pageId);
}).catch(e => {});
} else {
// 删除关联数据
this.$confirm('是否删除此关联数据?').then(res => {
let params = {
relationId: row.id
}
return OnlineDatasourceRelationController.delete(this, params);
}).then(res => {
return this.initPageDatasourceInfo(this.formPageData.pageId);
}).catch(e => {});
}
},
/**
* 关闭字段规则编辑
*/
onRuleClose () {
this.currentTable = undefined;
},
/**
* 编辑数据模型表字段规则信息
*/
onEditTableColumn (row) {
this.currentTable = row;
},
/**
* 关闭聚合计算管理
*/
onVirtualColumnClose () {
this.virtualColumnTable = undefined;
},
/**
* 编辑数据源虚拟字段
*/
onEditVirtualColumn (row) {
this.virtualColumnTable = row;
},
/**
* 获得数据源所有可用的数据表列表,包含已经导入的数据表和未导入的数据表
*/
loadDatasourceValidTableList (datasource) {
if (datasource == null) return Promise.reject();
if (Array.isArray(datasource.validTableList) && datasource.validTableList.length > 0) {
return Promise.resolve();
}
let httpCalls = [
this.loadDatasourceTableList(datasource.datasourceId),
this.loadDblinkTableList(datasource.dblinkId)
];
return new Promise((resolve, reject) => {
Promise.all(httpCalls).then(res => {
let datasourceTableList = res[0];
let dblinkTableList = res[1];
// 合并两个数据表
let tableNameSet = new Set();
datasource.validTableList = dblinkTableList.map(table => {
tableNameSet.add(table.tableName);
let temp = findItemFromList(datasourceTableList, table.tableName, 'tableName');
tableNameSet.add(table.tableName);
return {
id: temp ? temp.tableId : table.tableName,
name: table.tableName,
desc: temp ? temp.tableComment : table.tableComment,
status: temp ? this.SysOnlinePageDatasourceFieldStatus.USED : this.SysOnlinePageDatasourceFieldStatus.UNUSED,
dblinkTable: temp == null,
tag: temp || table
}
});
// 添加被使用但是已经从数据库中删除的数据表
datasourceTableList.forEach(table => {
if (!tableNameSet.has(table.tableName)) {
datasource.validTableList.push({
id: table.tableId,
name: table.tableName,
desc: table.tableComment,
status: this.SysOnlinePageDatasourceFieldStatus.DELETED,
dblinkTable: false,
tag: table
});
}
});
tableNameSet = null;
resolve();
}).catch(e => {
reject(e);
});
});
},
/*************************************************************
************************ 表单设计操作 ************************
*************************************************************/
/**
* 编辑子表单
*/
onEditPageForm (row) {
this.$dialog.show('编辑表单', EditOnlineForm, {
area: '600px'
}, {
pageId: this.formPageData.pageId,
pageType: this.formPageData.pageType,
datasourceId: this.getPageDatasource.datasourceId,
datasourceTableList: this.getPageDatasourceTableList,
form: row
}).then(res => {
this.initPageFormList(this.formPageData.pageId);
}).catch(e => {});
},
loadOnlineTableColumns (tableId) {
if (tableId == null || tableId === '') return Promise.reject();
return new Promise((resolve, reject) => {
let params = {
onlineColumnDtoFilter: {
tableId
}
}
OnlineColumnController.list(this, params).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
loadOnlineVirtualColumnList () {
return new Promise((resolve, reject) => {
let params = {
onlineVirtualColumnDtoFilter: {
datasourceId: this.getPageDatasource.datasourceId
}
}
OnlineVirtualColumnController.list(this, params).then(res => {
res.data.dataList.forEach(item => {
item.columnId = item.virtualColumnId;
item.columnName = item.objectFieldName;
item.columnComment = item.columnPrompt;
item.isVirtualColumn = true;
});
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
onDesignPageForm (row) {
let masterTable = findItemFromList(this.getPageDatasourceTableList, row.masterTableId, 'tableId');
if (masterTable) {
if (masterTable && masterTable.relationType == null) {
// 主表获取虚拟字段列
this.loadOnlineVirtualColumnList().then(res => {
let virtualColumnList = res;
// 数据源主表的查询以及编辑页面
let httpCalls = [];
// 返回主表和一对一从表,编辑页面同时返回一对多从表
let templateList = this.getPageDatasourceTableList.filter(item => {
return (
item.relationType == null ||
item.relationType === this.SysOnlineRelationType.ONE_TO_ONE ||
(row.formType !== this.SysOnlineFormType.QUERY && item.relationType === this.SysOnlineRelationType.ONE_TO_MANY)
);
});
httpCalls = templateList.map(item => {
return this.loadOnlineTableColumns(item.tableId);
});
Promise.all(httpCalls).then(res => {
let tableList = res.map((item, index) => {
templateList[index].columnList = item;
// 数据源主表,添加虚拟字段
if (templateList[index].tableId === row.masterTableId) {
templateList[index].columnList.push(...virtualColumnList);
}
return templateList[index];
});
row.tableList = tableList;
this.currentForm = row;
}).catch(e => {
console.log(e);
});
}).catch(e => {
console.log(e);
});
} else {
this.loadOnlineTableColumns(masterTable.tableId).then(res => {
masterTable.columnList = res;
row.tableList = [masterTable];
this.currentForm = row;
}).catch(e => {
console.log(e);
});
}
}
// this.currentForm = row;
},
onDeletePageForm (row) {
this.$confirm('是否删除此表单?').then(res => {
let params = {
formId: row.formId
}
return OnlineFormController.delete(this, params);
}).then(res => {
this.$message.success('删除成功!');
this.initPageFormList(this.formPageData.pageId);
}).catch(e => {});
}
},
computed: {
isEdit () {
return this.formPageData.pageId != null && this.formPageData.pageId !== '';
},
getPageDatasource () {
return this.pageDatasourceList[0];
},
getPageDatasourceTableList () {
if (this.getPageDatasource == null) return [];
let tableList = [];
// 添加主表信息
tableList.push({
id: this.getPageDatasource.datasourceId,
tableName: this.getPageDatasource.masterTableIdDictMap.name,
tableId: this.getPageDatasource.masterTableId,
relationType: undefined,
masterColumnName: undefined,
slaveColumnName: undefined,
cascadeDelete: false,
leftJoin: false,
tag: this.getPageDatasource
});
// 添加关联从表信息
if (Array.isArray(this.getPageDatasource.relationList)) {
this.getPageDatasource.relationList.forEach(relation => {
tableList.push({
id: relation.relationId,
tableName: relation.slaveTable.tableName,
tableId: relation.slaveTableId,
relationType: relation.relationType,
masterColumnName: relation.masterColumn.columnName,
slaveColumnName: relation.slaveColumn.columnName,
cascadeDelete: relation.cascadeDelete,
leftJoin: relation.leftJoin,
tag: relation
});
});
}
return tableList;
},
getTableInfo () {
return this.currentForm.tableList;
},
...mapGetters(['getClientHeight'])
},
mounted () {
this.loadOnlineDictList().catch(e => {});
this.loadDblinkList().then(res => {
return this.initPageInfo();
}).then(res => {
this.formPageData = {
pageId: res.data.pageId,
pageCode: res.data.pageCode,
pageName: res.data.pageName,
published: res.data.published,
pageType: res.data.pageType,
status: res.data.status
}
this.activeStep = this.SysOnlinePageSettingStep.BASIC;
}).catch(e => {});
}
}
</script>
<style scoped>
.edit-online-form {
position: fixed;
width: 100vw;
height: 100vh;
background: white;
top: 0px;
left: 0px;
z-index: 100
}
.edit-online-form >>> .el-steps--simple {
background: white!important;
}
.edit-online-form >>> .el-table th,.edit-online-form >>> .el-table td {
padding: 6px 0px;
}
.edit-online-form >>> .el-scrollbar__bar {
display: none;
}
.edit-online-form .header {
height: 60px;
line-height: 60px;
}
.edit-online-form .title {
font-size: 24px
}
.edit-online-form .title > i {
color: #FDA834;
margin-right: 10px;
}
.edit-online-form .main-box {
padding: 20px;
background: white;
height: 100%;
}
.edit-online-form .btn-add {
width: 100%;
margin-top: 10px;
border: 1px dashed #EBEEF5;
}
</style>

View File

@@ -0,0 +1,568 @@
<template>
<el-row type="flex" style="width: 100%;" :style="{height: height + 'px'}">
<!-- 字段列表 -->
<div class="table-column-list">
<div class="title">
<span>{{tableName}}</span>
<el-dropdown trigger="click" @command="onAddNewColumn">
<el-button class="table-btn success" size="mini" type="text"
icon="el-icon-circle-plus-outline" :disabled="getNewColumnList.length <= 0"
>
新增
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="newColumn in getNewColumnList" :key="newColumn.columnName"
:command="newColumn">
{{newColumn.columnName}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<el-scrollbar :style="{height: height - 51 + 'px'}">
<div v-for="column in getAllColumnList" :key="column.columnId"
class="table-column-item" :class="{'active-column': currentColumn === column}"
:title="column.columnComment"
@click.stop="onActiveColumnClick(column)"
>
<div>
<span style="margin-right: 10px;">{{column.columnName}}</span>
<el-tag v-if="column.deletedFlag" size="mini" type="danger">已删除</el-tag>
</div>
<div class="refresh" style="margin-left: 10px;">
<el-button class="table-btn success" size="mini" type="text" v-if="getNewColumnList.length <= 0"
@click.stop="onRefreshOnlineColumn(column, column)"
>
刷新
</el-button>
<el-dropdown v-else trigger="click" @command="onRefreshNewColumn">
<el-button class="table-btn success" size="mini" type="text" @click.stop="() => {}">
刷新
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="newColumn in getNewColumnList" :key="newColumn.columnName"
:command="{column, newColumn}">
{{newColumn.columnName}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button v-if="column.deletedFlag" class="table-btn delete" size="mini" type="text" style="margin-left: 10px;"
@click.stop="onDeleteColumn(column)"
>
删除
</el-button>
</div>
</div>
</el-scrollbar>
</div>
<!-- 字段属性 -->
<div class="column-attributes">
<el-row type="flex" justify="end" align="middle" style="padding-right: 10px; border-bottom: 1px dashed #dcdfe6">
<div class="attribute-title">
<span>字段属性</span>
</div>
<el-button type="text" icon="el-icon-refresh" @click="onSaveColumn">保存</el-button>
<el-button type="text" icon="el-icon-back" style="color: #67C23A;" @click="onBack">返回</el-button>
</el-row>
<el-form ref="columnAttribute" :model="currentColumn" class="full-width-input" style="width: 100%;"
label-width="120px" label-position="right" @submit.native.prevent size="small">
<div v-if="currentColumn != null" style="padding: 20px;" class="attibute-box">
<el-col class="attribute-item">
<el-form-item label="字段名:">
<span :title="currentColumn.columnComment">{{currentColumn.columnName}}</span>
<el-tag size="mini" type="warning" v-if="currentColumn.primaryKey" style="margin-left: 20px;">主键</el-tag>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="字段类型:">
<span>{{currentColumn.fullColumnType}}</span>
<el-tag size="mini" type="success" effect="dark" style="margin-left: 10px;">{{currentColumn.tag.objectFieldType}}</el-tag>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="是否必填:">
<el-switch v-model="currentColumn.required" disabled />
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="过滤支持:">
<el-radio-group v-model="currentColumn.filterType" @change="dirty = true">
<el-radio-button v-for="item in SysOnlineColumnFilterType.getList()"
:key="item.id" :label="item.id">
{{SysOnlineColumnFilterType.getValue(item.id)}}
</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="显示名称:">
<el-input v-model="currentColumn.columnComment" style="width: 278px;" @change="dirty = true" placeholder="字段在表单上的显示名称" />
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="字典数据:">
<el-select v-model="currentColumn.dictId" placeholder="选择字段绑定的字典" style="width: 278px;"
clearable filterable :disabled="currentColumn.tag.objectFieldType === 'Boolean'">
<el-option v-for="item in dictList" :key="item.dictId" :value="item.dictId" :label="item.dictName" />
</el-select>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="数据权限过滤:">
<el-select v-model="dataPermFilterType" placeholder="字段用于数据权限过滤规则"
style="width: 278px;" clearable @change="dirty = true">
<el-option v-for="item in SysOnlineDataPermFilterType.getList()" :key="item.id"
:label="item.name" :value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="字段类别:">
<el-select v-model="currentColumn.fieldKind" clearable placeholder="字段的业务类别" @change="dirty = true" style="width: 278px;">
<el-option v-for="item in getValidColumnKind" :key="item.id"
:label="item.name" :value="item.id" :disabled="columnKindItemDisabled(item)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col class="attribute-item" v-if="currentColumn.fieldKind === SysOnlineFieldKind.UPLOAD || currentColumn.fieldKind === SysOnlineFieldKind.UPLOAD_IMAGE">
<el-form-item label="上传文件数量:">
<el-input-number v-model="currentColumn.maxFileCount" style="width: 278px;" placeholder="不填或者0则代表无限制" @change="dirty = true" />
</el-form-item>
</el-col>
</div>
</el-form>
</div>
<!-- 验证规则 -->
<div class="column-rules">
<el-row type="flex" align="middle" style="border-bottom: 1px dashed #dcdfe6; height: 40px;">
<span style="color: #043254; font-weight: 700;">验证规则</span>
</el-row>
<el-row style="margin-top: 15px;">
<el-col :span="24" style="border-top: 1px solid #EBEEF5;">
<el-table size="mini" :data="columnRuleList" :show-header="false" empty-text="请添加验证规则">
<el-table-column type="index" width="45px" />
<el-table-column label="规则名称" prop="ruleName" width="150px" />
<el-table-column label="校验错误信息" prop="columnRuleInfo.message" />
<el-table-column label="操作" width="110px">
<template slot-scope="scope">
<el-button class="table-btn success" type="text" @click="onEditColumnRule(scope.row)">编辑</el-button>
<el-button class="table-btn delete" type="text" @click="onDeleteColumnRule(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-button style="width: 100%; margin-top: 10px; border: 1px dashed #EBEEF5;"
:disabled="currentColumn == null" icon="el-icon-plus" @click="onSetColumnRule">
添加验证规则
</el-button>
</el-col>
</el-row>
</div>
</el-row>
</template>
<script>
import SetOnlineTableColumnRule from './setOnlineTableColumnRule.vue';
import { OnlineColumnController, OnlineDblinkController } from '@/api/onlineController.js';
export default {
props: {
isMasterTable: {
type: Boolean,
default: false
},
tableId: {
type: String,
required: true
},
dblinkId: {
type: [String, Number],
required: true
},
tableName: {
type: String,
required: true
},
dictList: {
type: Array
},
height: {
type: Number,
required: true
}
},
data () {
return {
dirty: false,
dataPermFilterType: undefined,
columnMap: undefined,
dblinkTableColumnMap: undefined,
columnRuleList: [],
currentColumn: undefined,
storeColumn: undefined
}
},
methods: {
onBack () {
this.$emit('close');
},
/**
* 添加字段
*/
onAddNewColumn (newColumn) {
let params = {
tableId: this.tableId,
dblinkId: this.dblinkId,
tableName: this.tableName,
columnName: newColumn.columnName
}
OnlineColumnController.add(this, params).then(res => {
this.$message.success('添加成功!');
this.dirty = false;
this.loadOnlineTableColumns();
}).catch(e => {});
},
/**
* 刷新字段
*/
onRefreshOnlineColumn (column, newColumn) {
this.$confirm('刷新字段将替换现有字段有所的属性,是否继续?').then(res => {
let params = {
columnId: column.columnId,
dblinkId: this.dblinkId,
tableName: this.tableName,
columnName: newColumn.columnName
}
return OnlineColumnController.refreshColumn(this, params);
}).then(res => {
this.$message.success('刷新成功!');
this.dirty = false;
this.loadOnlineTableColumns();
}).catch(e => {});
},
onDeleteColumn (column) {
this.$confirm('是否删除字段?').then(res => {
let params = {
columnId: column.columnId
}
return OnlineColumnController.delete(this, params);
}).then(res => {
this.$message.success('删除成功!');
this.loadOnlineTableColumns();
}).catch(e => {});
},
onRefreshNewColumn (command) {
this.onRefreshOnlineColumn(command.column, command.newColumn)
},
loadColumnRuleList (columnId) {
this.columnRuleList = [];
OnlineColumnController.listOnlineColumnRule(this, {
columnId: columnId
}).then(res => {
res.data.dataList.forEach(item => {
item.columnRuleInfo = {
...JSON.parse(item.onlineColumnRule.propDataJson)
}
});
this.columnRuleList = res.data.dataList;
}).catch(e => {});
},
onDeleteColumnRule (rule) {
this.$confirm('是否从当前字段中删除此规则?').then(() => {
let params = {
columnId: this.currentColumn.columnId,
ruleId: rule.ruleId
}
return OnlineColumnController.deleteOnlineColumnRule(this, params);
}).then(res => {
this.$message.success('删除成功!');
this.loadColumnRuleList(this.currentColumn.columnId);
}).catch(e => {});
},
onEditColumnRule (rule) {
this.$dialog.show('编辑字段验证规则', SetOnlineTableColumnRule, {
area: '600px'
}, {
column: this.currentColumn,
columnRule: rule
}).then(res => {
this.loadColumnRuleList(this.currentColumn.columnId);
}).catch(e => {});
},
setCurrentColumn (column) {
this.currentColumn = column;
this.dataPermFilterType = undefined;
if (this.currentColumn.tag.userFilter) this.dataPermFilterType = this.SysOnlineDataPermFilterType.USER_FILTER;
if (this.currentColumn.tag.deptFilter) this.dataPermFilterType = this.SysOnlineDataPermFilterType.DEPT_FILTER;
this.storeColumn = { ...column };
this.loadColumnRuleList(this.currentColumn.columnId);
},
onActiveColumnClick (column) {
if (this.dirty) {
this.$confirm('字段信息已修改,是否保存?').then(res => {
this.onSaveColumn().then(res => {
this.setCurrentColumn(column);
}).catch(e => {});
}).catch(e => {
this.dirty = false;
// 恢复字段属性
if (this.storeColumn) {
this.currentColumn.maxFileCount = this.storeColumn.maxFileCount;
this.currentColumn.fieldKind = this.storeColumn.fieldKind;
this.currentColumn.filterType = this.storeColumn.filterType;
}
// 设置当前字段为新字段
this.setCurrentColumn(column);
});
} else {
this.dirty = false;
this.setCurrentColumn(column);
}
},
onSetColumnRule () {
this.$dialog.show('设置字段验证规则', SetOnlineTableColumnRule, {
area: '600px'
}, {
column: this.currentColumn
}).then(res => {
this.loadColumnRuleList(this.currentColumn.columnId);
}).catch(e => {});
},
onSaveColumn () {
if (this.currentColumn == null) return Promise.reject();
return new Promise((resolve, reject) => {
let params = {
onlineColumnDto: {
...this.currentColumn.tag,
dictId: this.currentColumn.tag.objectFieldType === 'Boolean' ? undefined : this.currentColumn.dictId,
fieldKind: this.currentColumn.fieldKind,
filterType: this.currentColumn.filterType,
maxFileCount: this.currentColumn.maxFileCount,
columnComment: this.currentColumn.columnComment,
userFilter: this.dataPermFilterType === this.SysOnlineDataPermFilterType.USER_FILTER,
deptFilter: this.dataPermFilterType === this.SysOnlineDataPermFilterType.DEPT_FILTER
}
}
OnlineColumnController.update(this, params).then(res => {
this.dirty = false;
this.$message.success('保存成功!');
this.loadOnlineTableColumns();
resolve();
}).catch(e => {
reject(e);
});
});
},
/**
* 获取在线表单导入表字段列表
*/
loadOnlineTableColumns () {
let params = {
onlineColumnDtoFilter: {
tableId: this.tableId
}
};
OnlineColumnController.list(this, params).then(res => {
this.columnMap = new Map();
res.data.dataList.forEach(item => {
let temp = {
columnId: item.columnId,
columnName: item.columnName,
columnComment: item.columnComment,
fullColumnType: item.fullColumnType,
primaryKey: item.primaryKey,
required: !item.nullable,
fieldKind: item.fieldKind,
maxFileCount: item.maxFileCount,
filterType: item.filterType,
dictId: item.dictId,
tag: item
}
this.columnMap.set(temp.columnName, temp);
});
if (this.currentColumn != null) {
this.$nextTick(() => {
this.currentColumn = this.columnMap ? this.columnMap.get(this.currentColumn.columnName) : undefined;
});
}
}).catch(e => {});
},
/**
* 获取数据库数据表字段列表
*/
loadDblinkTableColumns () {
let params = {
dblinkId: this.dblinkId,
tableName: this.tableName
}
OnlineDblinkController.listDblinkTableColumns(this, params).then(res => {
this.dblinkTableColumnMap = new Map();
res.data.forEach(item => {
this.dblinkTableColumnMap.set(item.columnName, item);
});
}).catch(e => {});
},
columnKindItemDisabled (columnKind) {
switch (columnKind.id) {
case this.SysOnlineFieldKind.CREATE_TIME:
case this.SysOnlineFieldKind.UPDATE_TIME:
return this.currentColumn.tag.objectFieldType !== 'Date';
case this.SysOnlineFieldKind.UPLOAD:
case this.SysOnlineFieldKind.UPLOAD_IMAGE:
case this.SysOnlineFieldKind.RICH_TEXT:
return this.currentColumn.tag.objectFieldType !== 'String';
case this.SysOnlineFieldKind.LOGIC_DELETE:
case this.SysOnlineFieldKind.FLOW_STATUS:
return this.currentColumn.tag.objectFieldType !== 'Integer';
default:
return false;
}
}
},
computed: {
getValidColumnKind () {
return this.SysOnlineFieldKind.getList().filter(item => {
return this.isMasterTable ? true : item.id !== this.SysOnlineFieldKind.FLOW_STATUS;
});
},
getAllColumnList () {
let columnList = [];
if (this.columnMap != null) {
this.columnMap.forEach((column) => {
if (this.dblinkTableColumnMap != null) {
let dblinkColumn = this.dblinkTableColumnMap.get(column.columnName);
column.deletedFlag = (dblinkColumn == null);
} else {
column.deletedFlag = false;
}
columnList.push(column);
});
}
return columnList;
},
getNewColumnList () {
let columnList = [];
if (this.dblinkTableColumnMap != null && this.columnMap != null) {
this.dblinkTableColumnMap.forEach(column => {
let onlineColumn = this.columnMap.get(column.columnName);
if (onlineColumn == null) {
columnList.push(column);
}
});
}
return columnList;
}
},
mounted () {
this.loadOnlineTableColumns();
this.loadDblinkTableColumns();
}
}
</script>
<style scoped>
.table-column-list {
width: 300px;
height: 100%;
border-radius: 3px;
padding: 0px 10px 10px 10px;
margin-bottom: 10px;
flex-shrink: 0;
background: white;
}
.table-column-list > .title {
font-size: 14px;
color: #043254;
line-height: 30px;
height: 40px;
margin-bottom: 10px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px dashed #dcdfe6;
}
.table-column-list > .title > span {
width: 100%;
}
.table-column-list .table-column-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0px 10px;
margin-bottom: 8px;
font-size: 12px;
color: #043254;
cursor: pointer;
border-radius: 3px;
height: 35px;
line-height: 35px;
width: 100%;
background: #f4f7fa;
border: 1px dashed #f3f9ff;
}
.table-column-list .table-column-item:hover {
background: #ecf4fc;
}
.table-column-list .table-column-item.active-column {
background: #ecf4fc;
border: 1px dashed #b6d8fa;
}
.table-column-list .table-column-item .refresh {
display: none;
}
.table-column-list .table-column-item:hover .refresh {
display: block;
}
.column-attributes {
height: 100%;
width: 100%;
padding: 0px 10px 10px 10px;
background: white;
margin: 0px 10px;
border-radius: 3px;
}
.column-attributes .attribute-title {
width: 100%;
margin-left: 15px;
color: #043254;
font-weight: 700;
}
.column-attributes .attibute-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.column-attributes .attibute-box .attribute-item {
width: 500px;
}
.column-rules {
width: 600px;
height: 100%;
padding: 0px 10px 10px 10px;
background: white;
flex-shrink: 0;
border-radius: 3px;
}
</style>>

View File

@@ -0,0 +1,582 @@
<template>
<el-row type="flex" style="width: 100%;" :style="{height: height + 'px'}">
<!-- 虚拟字段列表 -->
<div class="table-column-list">
<div class="title">
<span>虚拟字段列表</span>
<el-button class="table-btn success" size="mini" type="text"
icon="el-icon-circle-plus-outline"
@click.stop="onAddNewVirtualColumn">
新增
</el-button>
</div>
<el-scrollbar :style="{height: height - 51 + 'px'}">
<div v-for="column in allVirtualColumnList" :key="column.columnId"
class="table-column-item" :class="{'active-column': currentColumn.virtualColumnId === column.virtualColumnId}"
:title="column.columnComment"
@click.stop="onActiveColumnClick(column)"
>
<span style="margin-right: 10px;">{{column.columnPrompt}}</span>
<el-button class="table-btn delete" size="mini" type="text" style="margin-left: 10px;"
@click.stop="onDeleteColumn(column)"
>
删除
</el-button>
</div>
</el-scrollbar>
</div>
<!-- 虚拟字段属性 -->
<div class="column-attributes">
<el-row type="flex" justify="end" align="middle" style="padding-right: 10px; border-bottom: 1px dashed #dcdfe6">
<div class="attribute-title">
<span>字段属性</span>
</div>
<el-button type="text" icon="el-icon-refresh" @click="onSaveColumn">保存</el-button>
<el-button class="table-btn success" type="text" icon="el-icon-back" @click="onBack">返回</el-button>
</el-row>
<el-form class="full-width-input" ref="columnAttribute"
:model="currentColumn" style="width: 100%;"
label-width="120px" label-position="right"
@submit.native.prevent size="small" :rules="rules">
<div v-if="currentColumn != null" style="padding: 20px;" class="attibute-box">
<el-col class="attribute-item">
<el-form-item label="结果字段列名:" prop="objectFieldName">
<el-input v-model="currentColumn.objectFieldName" placeholder="结果字段列名" />
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="结果字段显示名" prop="columnPrompt">
<el-input v-model="currentColumn.columnPrompt" placeholder="结果字段显示名" />
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="聚合关联" prop="relationId">
<el-select v-model="currentColumn.relationId" placeholder="聚合关联选择"
@change="onRelationChange">
<el-option v-for="item in relationList" :key="item.relationId"
:value="item.relationId" :label="item.relationName">
<div style="display: flex; justify-content: space-between; align-items: center">
<span>{{item.relationName}}</span>
<el-tag style="margin-left: 30px;" size="mini"
:type="getDatasourceTableTagType(item.relationType)">
{{SysOnlineRelationType.getValue(item.relationType)}}
</el-tag>
</div>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="聚合计算表" prop="aggregationTableId">
<el-select v-model="currentColumn.aggregationTableId" placeholder="聚合计算表" @change="onAggregationTableIdChange">
<el-option v-for="item in aggregationTableList" :key="item.relationId"
:value="item.tableId" :label="item.tableName">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="聚合计算字段" prop="aggregationColumnId">
<el-select v-model="currentColumn.aggregationColumnId" placeholder="聚合计算表" @change="onAggregationColumnIdChange">
<el-option v-for="item in aggregationColumnList" :key="item.relationId"
:value="item.columnId" :label="item.columnName">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="结果字段类型" prop="objectFieldType">
<el-select v-model="currentColumn.objectFieldType" placeholder="结果字段类型" @change="currentColumn.aggregationType = undefined">
<el-option v-for="item in getVirtualColumnFieldType" :key="item"
:value="item" :label="item"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col class="attribute-item">
<el-form-item label="聚合计算规则" prop="relationId">
<el-select v-model="currentColumn.aggregationType" placeholder="聚合字段计算规则">
<el-option v-for="item in getAggregationTypeList" :key="item.id"
:value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
</el-col>
</div>
</el-form>
</div>
<!-- 过滤条件 -->
<div class="column-filter">
<el-row type="flex" align="middle" style="border-bottom: 1px dashed #dcdfe6; height: 40px;">
<span style="color: #043254; font-weight: 700;">过滤条件</span>
</el-row>
<el-row style="margin-top: 15px;">
<el-col :span="24" style="border-top: 1px solid #EBEEF5;">
<el-table size="mini" :data="virtualColumnFilterList" :show-header="false" empty-text="请添加过滤条件">
<el-table-column label="操作" width="45px">
<template slot-scope="scope">
<el-button class="table-btn delete" type="text" icon="el-icon-remove-outline"
@click="onDeleteColumnFilter(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="参数名称">
<template slot-scope="scope">
<el-button class="table-btn" type="text" style="text-decoration: underline;" @click="onEditColumnFilter(scope.row)">{{(scope.row.column || {}).columnName || '未知字段'}}</el-button>
</template>
</el-table-column>
<el-table-column label="所属表" width="100px">
<template>
<el-tag size="mini" type="success">关联从表</el-tag>
</template>
</el-table-column>
<el-table-column label="过滤类型" width="100px">
<template slot-scope="scope">
<span>{{SysOnlineFilterOperationType.getValue(scope.row.operatorType)}}</span>
</template>
</el-table-column>
<el-table-column label="参数值" prop="value">
<template slot-scope="scope">
<span v-if="(scope.row.column || {}).dictInfo == null">{{scope.row.value}}</span>
<span v-else>{{scope.row.column.dictInfo.dictName + ' / ' + scope.row.dictValueName}}</span>
</template>
</el-table-column>
</el-table>
<el-button style="width: 100%; margin-top: 10px; border: 1px dashed #EBEEF5;"
:disabled="currentColumn == null || aggregationRelation == null" icon="el-icon-plus"
@click="onEditColumnFilter(null)">
添加过滤条件
</el-button>
</el-col>
</el-row>
</div>
</el-row>
</template>
<script>
import { findItemFromList } from '@/utils';
import { getDictDataList } from '../utils';
import { OnlineColumnController, OnlineVirtualColumnController } from '@/api/onlineController.js';
import EditVirtualColumnFilter from './editVirtualColumnFilter.vue';
const defaultVirtualColumnInfo = {
virtualColumnId: undefined,
datasourceId: undefined,
objectFieldName: undefined,
columnPrompt: undefined,
objectFieldType: undefined,
relationId: undefined,
aggregationType: undefined,
aggregationTableId: undefined,
aggregationColumnId: undefined,
virtualType: 0,
whereClauseJson: undefined
}
export default {
props: {
datasource: {
type: Object
},
relationList: {
type: Array
},
height: {
type: Number
}
},
data () {
return {
currentColumn: {
...defaultVirtualColumnInfo
},
allVirtualColumnList: [],
aggregationTableList: [],
aggregationColumnList: [],
virtualColumnFilterList: [],
rules: {
objectFieldName: [
{required: true, message: '结果字段列名不能为空', trigger: 'blur'}
],
objectFieldType: [
{required: true, message: '结果字段类型不能为空', trigger: 'blur'}
],
columnPrompt: [
{required: true, message: '结果字段显示名不能为空', trigger: 'blur'}
],
relationId: [
{required: true, message: '必须选则聚合字段关联', trigger: 'blur'}
],
aggregationType: [
{required: true, message: '必须选则聚合计算规则', trigger: 'blur'}
],
aggregationTableId: [
{required: true, message: '聚合计算表不能为空', trigger: 'blur'}
],
aggregationColumnId: [
{required: true, message: '聚合计算字段不能为空', trigger: 'blur'}
]
}
}
},
methods: {
onBack () {
this.$emit('close');
},
onActiveColumnClick (column) {
this.currentColumn = column;
},
onAddNewVirtualColumn () {
this.currentColumn = {
...defaultVirtualColumnInfo
}
},
onDeleteColumn (column) {
this.$confirm('是否删除此虚拟字段?').then(res => {
let params = {
virtualColumnId: column.virtualColumnId
}
OnlineVirtualColumnController.delete(this, params).then(res => {
if (column.virtualColumnId === this.currentColumn.virtualColumnId) {
this.currentColumn = {
...defaultVirtualColumnInfo
}
}
this.$message.success('删除成功!');
this.loadOnlineVirtualColumnList();
}).catch(e => {});
}).catch(e => {});
},
onSaveColumn () {
let whereClauseJson = this.virtualColumnFilterList.map(item => {
return {
tableId: item.tableId,
columnId: item.columnId,
operatorType: item.operatorType,
value: item.value
}
});
let params = {
onlineVirtualColumnDto: {
...this.currentColumn,
datasourceId: this.datasource.datasourceId,
whereClauseJson: JSON.stringify(whereClauseJson)
}
}
let httpCall = this.currentColumn.virtualColumnId ? OnlineVirtualColumnController.update(this, params) : OnlineVirtualColumnController.add(this, params);
httpCall.then(res => {
if (this.currentColumn.virtualColumnId == null) this.currentColumn.virtualColumnId = res.data;
this.$message.success('保存成功!');
this.loadOnlineVirtualColumnList();
}).catch(e => {});
},
onEditColumnFilter (row) {
this.$dialog.show(row ? '编辑过滤' : '添加过滤', EditVirtualColumnFilter, {
area: '500px'
}, {
rowData: row,
tableList: this.aggregationTableList
}).then(res => {
if (row == null) {
this.virtualColumnFilterList.push(res);
} else {
this.virtualColumnFilterList = this.virtualColumnFilterList.map(item => {
return item === row ? res : item;
});
}
}).catch(e => {});
},
onDeleteColumnFilter (row) {
this.$confirm('是否删除此过滤条件?').then(res => {
this.virtualColumnFilterList = this.virtualColumnFilterList.filter(item => item !== row);
}).catch(e => {});
},
loadOnlineTableColumnList (tableId) {
return new Promise((resolve, reject) => {
if (tableId == null || tableId === '') resolve();
let params = {
onlineColumnDtoFilter: {
tableId
}
}
OnlineColumnController.list(this, params).then(res => {
this.aggregationTable.columnList = res.data.dataList;
this.aggregationColumnList = res.data.dataList;
resolve();
}).catch(e => {
reject();
});
});
},
getDatasourceTableTagType (relationType) {
if (relationType == null) return 'success';
switch (relationType) {
case this.SysOnlineRelationType.ONE_TO_ONE: return 'primary';
case this.SysOnlineRelationType.ONE_TO_MANY: return 'warning';
default:
return 'info';
}
},
onRelationChange (relationId) {
this.aggregationTableList = [];
this.aggregationColumnList = [];
this.currentColumn.aggregationColumnId = undefined;
this.currentColumn.aggregationTableId = undefined;
this.currentColumn.aggregationType = undefined;
this.currentColumn.objectFieldType = undefined;
let relation = findItemFromList(this.relationList, relationId, 'relationId');
if (relation != null) {
this.aggregationTableList = [relation.slaveTable];
}
},
onAggregationTableIdChange (tableId) {
this.aggregationColumnList = [];
this.currentColumn.aggregationColumnId = undefined;
this.currentColumn.aggregationType = undefined;
this.currentColumn.objectFieldType = undefined;
if (this.aggregationTable != null) {
if (Array.isArray(this.aggregationTable.columnList) && this.aggregationTable.columnList.length > 0) {
this.aggregationColumnList = this.aggregationTable.columnList;
} else {
this.loadOnlineTableColumnList(this.aggregationTable.tableId).catch(e => {});
}
}
},
onAggregationColumnIdChange (columnId) {
this.currentColumn.aggregationType = undefined;
this.currentColumn.objectFieldType = undefined;
},
loadOnlineVirtualColumnList () {
let params = {
onlineVirtualColumnDtoFilter: {
datasourceId: this.datasource.datasourceId
}
}
OnlineVirtualColumnController.list(this, params).then(res => {
this.allVirtualColumnList = res.data.dataList;
}).catch(e => {});
},
buildVirtualColumnFilter () {
let filterList = this.currentColumn.whereClauseJson ? JSON.parse(this.currentColumn.whereClauseJson) : [];
filterList = filterList.map(item => {
return {
...item,
table: this.aggregationTable,
column: findItemFromList(this.aggregationTable.columnList, item.columnId, 'columnId')
}
});
// 获取过滤条件种过滤值的字典信息
let allPromise = filterList.map(filterItem => {
return new Promise((resolve) => {
if (filterItem.column == null || filterItem.column.dictInfo == null) {
resolve();
return;
}
let dictInfo = filterItem.column.dictInfo;
getDictDataList(this, dictInfo).then(dictValueList => {
let dictValue = findItemFromList(dictValueList, filterItem.value, 'id');
if (dictValue) {
filterItem.dictValueName = dictValue.name;
} else {
filterItem.value = undefined;
}
resolve();
}).catch(e => {
filterItem.value = undefined;
resolve(e);
});
});
});
Promise.all(allPromise).then(res => {
this.virtualColumnFilterList = filterList;
}).catch(e => {
console.log(e);
});
}
},
computed: {
aggregationRelation () {
if (this.currentColumn.relationId == null) return null;
return findItemFromList(this.relationList, this.currentColumn.relationId, 'relationId');
},
aggregationTable () {
if (this.currentColumn.aggregationTableId == null) return null;
return findItemFromList(this.aggregationTableList, this.currentColumn.aggregationTableId, 'tableId');
},
aggregationColumn () {
if (this.currentColumn.aggregationColumnId == null) return null;
return findItemFromList(this.aggregationColumnList, this.currentColumn.aggregationColumnId, 'columnId');
},
getVirtualColumnFieldType () {
if (this.aggregationColumn == null) return [];
switch (this.aggregationColumn.objectFieldType) {
case 'String':
case 'Boolean':
return ['Integer'];
case 'Integer':
case 'Long':
case 'BigDecimal':
case 'Double':
return ['Integer', 'Long', 'Double'];
case 'Date':
return ['Integer', 'Date'];
default:
return ['Integer', 'Long', 'Double', 'Date'];
}
},
getAggregationTypeList () {
if (this.aggregationColumn == null) return [];
return this.SysOnlineAggregationType.getList().filter(item => {
switch (item.id) {
case this.SysOnlineAggregationType.SUM:
return ['Date', 'Boolean', 'String'].indexOf(this.aggregationColumn.objectFieldType) === -1 && this.currentColumn.objectFieldType !== 'Date';
case this.SysOnlineAggregationType.COUNT:
return true;
case this.SysOnlineAggregationType.AVG:
case this.SysOnlineAggregationType.MIN:
case this.SysOnlineAggregationType.MAX:
if (this.aggregationColumn.objectFieldType === 'Date') {
return this.currentColumn.objectFieldType === 'Date';
} else {
return ['Integer', 'Long', 'BigDecimal', 'Double'].indexOf(this.aggregationColumn.objectFieldType) !== -1;
}
}
});
}
},
mounted () {
this.loadOnlineVirtualColumnList();
},
watch: {
currentColumn: {
handler (newValue) {
if (newValue == null) {
this.currentColumn = {
...defaultVirtualColumnInfo
}
} else {
if (this.aggregationRelation) this.aggregationTableList = [this.aggregationRelation.slaveTable];
if (this.aggregationTable) {
this.loadOnlineTableColumnList(this.aggregationTable.tableId).catch(e => {});
if (Array.isArray(this.aggregationTable.columnList) && this.aggregationTable.columnList.length > 0) {
this.buildVirtualColumnFilter();
} else {
this.loadOnlineTableColumnList(this.aggregationTable.tableId).then(res => {
this.buildVirtualColumnFilter();
}).catch(e => {
console.log(e);
});
}
}
}
},
immediate: true
}
}
}
</script>
<style scoped>
.table-column-list {
width: 300px;
height: 100%;
border-radius: 3px;
padding: 0px 10px 10px 10px;
margin-bottom: 10px;
flex-shrink: 0;
background: white;
}
.table-column-list > .title {
font-size: 14px;
color: #043254;
line-height: 30px;
height: 40px;
margin-bottom: 10px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px dashed #dcdfe6;
}
.table-column-list > .title > span {
width: 100%;
}
.table-column-list .table-column-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0px 10px;
margin-bottom: 8px;
font-size: 12px;
color: #043254;
cursor: pointer;
border-radius: 3px;
height: 35px;
line-height: 35px;
width: 100%;
background: #f4f7fa;
border: 1px dashed #f3f9ff;
}
.table-column-list .table-column-item:hover {
background: #ecf4fc;
}
.table-column-list .table-column-item.active-column {
background: #ecf4fc;
border: 1px dashed #b6d8fa;
}
.table-column-list .table-column-item .delete {
display: none;
}
.table-column-list .table-column-item:hover .delete {
display: block;
}
.column-attributes {
height: 100%;
width: 100%;
padding: 0px 10px 10px 10px;
background: white;
margin: 0px 10px;
border-radius: 3px;
}
.column-attributes .attribute-title {
width: 100%;
margin-left: 15px;
color: #043254;
font-weight: 700;
}
.column-attributes .attibute-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.column-attributes .attibute-box .attribute-item {
width: 500px;
}
.column-filter {
width: 600px;
height: 100%;
padding: 0px 10px 10px 10px;
background: white;
flex-shrink: 0;
border-radius: 3px;
}
</style>

View File

@@ -0,0 +1,285 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<!-- 设置字段验证规则 -->
<el-form v-if="!isCreateRule" class="full-width-input" ref="form" :rules="rules" :model="formData"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="验证规则" prop="ruleId" key="ruleId">
<el-row type="flex" justify="space-between">
<el-select class="input-item" v-model="formData.ruleId" placeholder="选择验证规则" clearable
:disabled="isEdit"
:loading="ruleListWidget.loading"
@visible-change="ruleListWidget.onVisibleChange"
@change="onRuleIdChange">
<el-option v-for="item in ruleListWidget.dropdownList" :key="item.ruleId" :value="item.ruleId" :label="item.ruleName">
<el-row type="flex" justify="end" align="middle" class="rule-item">
<span style="width: 100%;">{{item.ruleName}}</span>
<el-button class="table-btn success" v-if="!item.builtin" type="text" icon="el-icon-edit-outline"
style="margin-left: 30px;" @click.stop="onEditRule(item)"
/>
<el-button class="table-btn delete" v-if="!item.builtin" type="text" icon="el-icon-circle-close"
@click.stop="onDeleteRule(item)"
/>
</el-row>
</el-option>
</el-select>
<el-button v-if="!isEdit" type="warning" style="margin-left: 3px;" @click="onCreateRuleClick">新建规则</el-button>
</el-row>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="错误信息" prop="message" key="message">
<el-input v-model="formData.message" placeholder="输入校验错误信息" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="最小值">
<el-input-number v-model="formData.min" placeholder="输入最小值"
:disabled="!ruleInfo || ruleInfo.ruleType !== SysOnlineRuleType.RANGE" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="最大值">
<el-input-number v-model="formData.max" placeholder="输入最大值"
:disabled="!ruleInfo || ruleInfo.ruleType !== SysOnlineRuleType.RANGE" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<!-- 新建验证规则 -->
<el-form v-if="isCreateRule" class="full-width-input" ref="ruleData" :rules="rules" :model="ruleData"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="规则类型" prop="ruleType">
<el-input :value="SysOnlineRuleType.getValue(ruleData.ruleType)" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="规则名称" prop="ruleName" key="ruleName">
<el-input v-model="ruleData.ruleName" placeholder="规则名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="正则表达式" prop="pattern" key="pattern">
<el-input type="textarea" v-model="ruleData.pattern" placeholder="规则正则表达式" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true" @click="onCancelClick">取消</el-button>
<el-button type="primary" size="mini" @click="onSubmit">保存</el-button>
</el-row>
</div>
</template>
<script>
import { findItemFromList } from '@/utils';
import { DropdownWidget } from '@/utils/widget.js';
import { OnlineRuleController, OnlineColumnController } from '@/api/onlineController.js';
export default {
props: {
column: {
type: Object,
required: true
},
columnRule: {
type: Object
}
},
data () {
return {
isCreateRule: false,
isEditRule: false,
formData: {
ruleId: undefined,
message: undefined,
min: undefined,
max: undefined
},
ruleData: {
ruleName: undefined,
ruleType: this.SysOnlineRuleType.CUSTOM,
pattern: undefined,
builtin: false
},
rules: {
ruleId: [
{required: true, message: '请选择验证规则', trigger: 'blur'}
],
message: [
{required: true, message: '请输入校验错误信息', trigger: 'blur'}
],
ruleName: [
{required: true, message: '规则名称不能为空', trigger: 'blur'}
],
pattern: [
{required: true, message: '正则表达式不能为空', trigger: 'blur'}
]
},
ruleListWidget: new DropdownWidget(this.loadRuleListDropdownList)
}
},
methods: {
removeValidate () {
if (this.$refs.ruleData) this.$refs.ruleData.clearValidate();
if (this.$refs.form) this.$refs.form.clearValidate();
},
onCancelClick () {
if (!this.isCreateRule) {
this.onCancel(false);
}
this.isCreateRule = this.isEditRule = false;
this.removeValidate();
},
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
if (this.isEdit) {
this.onUpdateColumnRule();
} else {
this.isCreateRule ? this.onSaveRule() : this.onSetColumnRule();
}
},
onCreateRuleClick () {
this.isCreateRule = true;
this.isEditRule = false;
this.ruleData = {
ruleName: undefined,
pattern: undefined,
ruleType: this.SysOnlineRuleType.CUSTOM,
builtin: false
}
this.removeValidate();
},
onEditRule (rule) {
this.isCreateRule = true;
this.isEditRule = true;
this.ruleData = {
...rule
}
this.removeValidate();
},
onDeleteRule (rule) {
this.$confirm('是否删除此规则?').then(res => {
let params = {
ruleId: rule.ruleId
}
return OnlineRuleController.delete(this, params);
}).then(res => {
if (this.formData.ruleId === rule.ruleId) {
this.formData.ruleId = undefined;
}
this.ruleListWidget.dirty = true;
this.ruleListWidget.onVisibleChange(true);
}).catch(e => {});
},
onSaveRule () {
this.$refs.ruleData.validate(valid => {
if (!valid) return;
let params = {
onlineRuleDto: {
...this.ruleData
}
}
let httpCall = this.isEditRule ? OnlineRuleController.update(this, params) : OnlineRuleController.add(this, params);
httpCall.then(res => {
if (!this.isEditRule) this.formData.ruleId = res.data;
this.ruleListWidget.dirty = true;
this.ruleListWidget.onVisibleChange(true);
this.isCreateRule = false;
}).catch(e => {});
})
},
onSetColumnRule () {
let params = {
columnId: this.column.columnId,
onlineColumnRuleDtoList: [
{
columnId: this.column.columnId,
ruleId: this.formData.ruleId,
propDataJson: JSON.stringify({
message: this.formData.message,
min: this.formData.min,
max: this.formData.max
})
}
]
}
OnlineColumnController.addOnlineColumnRule(this, params).then(res => {
this.$message.success('添加成功!');
this.onCancel(true);
}).catch(e => {});
},
onUpdateColumnRule () {
let params = {
onlineColumnRuleDto: {
columnId: this.column.columnId,
ruleId: this.formData.ruleId,
propDataJson: JSON.stringify({
message: this.formData.message,
min: this.formData.min,
max: this.formData.max
})
}
}
OnlineColumnController.updateOnlineColumnRule(this, params).then(res => {
this.$message.success('保存成功!');
this.onCancel(true);
}).catch(e => {});
},
loadRuleListDropdownList () {
return new Promise((resolve, reject) => {
let params = {
columnId: this.column.columnId
}
let httpCall = this.isEdit ? OnlineColumnController.listOnlineColumnRule(this, params) : OnlineColumnController.listNotInOnlineColumnRule(this, params);
httpCall.then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
})
});
},
onRuleIdChange (value) {
this.formData.message = undefined;
}
},
computed: {
isEdit () {
return this.columnRule != null;
},
ruleInfo () {
return findItemFromList(this.ruleListWidget.dropdownList, this.formData.ruleId, 'ruleId');
}
},
mounted () {
if (this.columnRule != null) {
this.formData = {
ruleId: this.columnRule.ruleId,
message: this.columnRule.columnRuleInfo.message,
max: this.columnRule.columnRuleInfo.max,
min: this.columnRule.columnRuleInfo.min
}
this.ruleListWidget.onVisibleChange(true);
}
}
}
</script>
<style scoped>
.rule-item .el-button {
display: none;
font-size: 14px;
}
.rule-item:hover .el-button {
display: block;
}
</style>

View File

@@ -0,0 +1,260 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-scrollbar class="custom-scroll" :style="{height: formConfig.height + 'px', 'min-height': '100px'}">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules"
:label-width="formConfig.labelWidth + 'px'" size="mini"
:label-position="formConfig.labelPosition"
@submit.native.prevent>
<el-row :gutter="formConfig.gutter">
<template v-for="widget in formConfig.formWidgetList">
<CustomTable :ref="widget.variableName"
v-if="widget.widgetType === SysCustomWidgetType.Table" :key="widget.id"
:widgetConfig="widget"
:formType="formConfig.formType"
:primaryColumnName="widget.primaryColumnName"
:isNew="isRelationTableAdd(widget)"
:getTableQueryParams="getTableQueryParams"
@operationClick="onTableOperationClick"
/>
<CustomUpload :ref="widget.variableName" :key="widget.id"
v-else-if="widget.widgetType === SysCustomWidgetType.Upload"
:widgetConfig="widget"
:flowData="flowData"
:getDataId="getWidgetPrimaryColumnId"
v-model="formData[getWidgetFieldName(widget)]" />
<CustomWidget
v-else
:ref="widget.variableName"
:key="widget.id"
:widgetConfig="widget"
:formConfig="formConfig"
:getDropdownParams="getDropdownParams"
v-model="formData[getWidgetFieldName(widget)]"
>
<template v-for="subWidget in widget.childWidgetList">
<CustomTable :ref="subWidget.variableName"
v-if="subWidget.widgetType === SysCustomWidgetType.Table" :key="subWidget.id"
:widgetConfig="subWidget"
:formType="formConfig.formType"
:isNew="isRelationTableAdd(subWidget)"
:getTableQueryParams="getTableQueryParams"
@operationClick="onTableOperationClick"
/>
<CustomUpload :ref="subWidget.variableName" :key="subWidget.id"
v-else-if="subWidget.widgetType === SysCustomWidgetType.Upload"
:widgetConfig="subWidget"
:flowData="flowData"
:getDataId="getWidgetPrimaryColumnId"
v-model="formData[getWidgetFieldName(subWidget)]" />
<CustomWidget
v-else
:ref="subWidget.variableName"
:key="subWidget.id"
:widgetConfig="subWidget"
:formConfig="formConfig"
:getDropdownParams="getDropdownParams"
v-model="formData[getWidgetFieldName(subWidget)]"
/>
</template>
</CustomWidget>
</template>
</el-row>
</el-form>
</el-scrollbar>
<el-row v-if="formConfig.formType === SysOnlineFormType.FORM" type="flex" justify="end" style="margin-top: 15px;">
<el-button type="primary" size="mini" :plain="true"
v-if="formConfig.formKind === SysOnlineFormKind.DIALOG"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSave()">
保存
</el-button>
</el-row>
</div>
</template>
<script>
import { OnlineFormMixins } from './onlineFormMixins.js';
import CustomUpload from '@/views/onlineForm/components/customUpload.vue';
import CustomWidget from '@/views/onlineForm/components/customWidget.vue';
import CustomTable from '@/views/onlineForm/components/customTable.vue';
export default {
name: 'onlineEditForm',
inject: ['preview'],
mixins: [OnlineFormMixins],
props: {
operationType: {
type: [Number, String],
required: true
},
saveOnClose: {
type: String,
default: '1'
},
rowData: {
type: Object
},
flowData: {
type: Object
}
},
components: {
CustomWidget,
CustomTable,
CustomUpload
},
methods: {
getWidgetFieldName (widget) {
if (widget && widget.relation == null) {
return (widget.column || {}).columnName;
} else {
return widget.relation.variableName + '__' + (widget.column || {}).columnName
}
},
// 当前表格是否为新建从表数据
isRelationTableAdd (tableWidget) {
let temp = Number.parseInt(this.operationType) === this.SysCustomWidgetOperationType.ADD && tableWidget.relation != null;
return temp;
},
onCancel (isSuccess, data) {
this.$emit('close', isSuccess, data);
},
onSave () {
if (this.preview()) return;
setTimeout(() => {
this.$refs.form.validate(valid => {
if (!valid) return;
let datasourceId = (this.masterTable.datasource || {}).datasourceId;
let relationId = (this.masterTable.relation || {}).relationId;
let params = {
datasourceId,
relationId,
masterData: relationId == null ? this.formData : undefined
}
// 添加调用按钮接口代码
if (this.saveOnClose === '1') {
if (datasourceId != null && datasourceId !== '') {
// 从表数据
let slaveData = {};
if (relationId == null) {
if (Array.isArray(this.tableWidgetList) && this.tableWidgetList.length > 0 && Number.parseInt(this.operationType) === this.SysCustomWidgetOperationType.ADD) {
this.tableWidgetList.forEach(tableWidget => {
let tableData = this.getRelationTableData(tableWidget);
if (tableData != null) {
slaveData[tableWidget.relation.relationId] = tableData;
}
});
}
} else {
slaveData = this.masterTable.columnList.reduce((retObj, column) => {
let fieldName = this.masterTable.relation.variableName + '__' + column.columnName;
retObj[column.columnName] = this.formData[fieldName];
return retObj;
}, {});
slaveData = {
...slaveData,
...this.params
}
}
params.slaveData = slaveData;
// params.slaveData.video_course_id = '1037103328223401584';
let httpCall = null;
if (Number.parseInt(this.operationType) === this.SysCustomWidgetOperationType.ADD) {
if (relationId == null) {
httpCall = this.doUrl('/admin/online/onlineOperation/addDatasource/' + (this.masterTable.datasource || {}).variableName, 'post', params);
} else {
httpCall = this.doUrl('/admin/online/onlineOperation/addOneToManyRelation/' + (this.masterTable.datasource || {}).variableName, 'post', params);
}
} else {
if (relationId == null) {
httpCall = this.doUrl('/admin/online/onlineOperation/updateDatasource/' + (this.masterTable.datasource || {}).variableName, 'post', params);
} else {
httpCall = this.doUrl('/admin/online/onlineOperation/updateOneToManyRelation/' + (this.masterTable.datasource || {}).variableName, 'post', params);
}
}
httpCall.then(res => {
this.onCancel(true, this.formData);
}).catch(e => {});
}
} else {
let masterData = {};
if (this.masterTable && Array.isArray(this.masterTable.columnList)) {
this.masterTable.columnList.forEach(column => {
let keyName = column.columnName;
if (this.masterTable.relation) keyName = this.masterTable.relation.variableName + '__' + keyName;
masterData[keyName] = this.formData[keyName];
});
if (Array.isArray(this.dropdownWidgetList)) {
this.dropdownWidgetList.forEach(dropdwonWidget => {
let keyName = dropdwonWidget.column.columnName;
if (dropdwonWidget.table.relation) keyName = dropdwonWidget.table.relation.variableName + '__' + keyName;
let tempWidget = this.$refs[dropdwonWidget.variableName];
if (Array.isArray(tempWidget)) {
tempWidget.forEach(item => {
masterData[keyName + '__DictMap'] = {
id: this.formData[keyName],
name: item.getDictValue(this.formData[keyName])
}
});
}
});
}
}
this.onCancel(true, masterData);
}
});
}, 30);
},
getTableQueryParams (widget) {
let queryParams = [];
if (Array.isArray(widget.queryParamList)) {
queryParams = widget.queryParamList.map(item => {
let paramValue = this.getParamValue(item.paramValueType, item.paramValue);
if (paramValue == null || paramValue === '' || (Array.isArray(paramValue) && paramValue.length === 0)) return;
let temp = {
tableName: item.table.tableName,
columnName: item.column.columnName,
filterType: item.column.filterType,
columnValue: item.column.filterType !== this.SysOnlineColumnFilterType.RANFGE_FILTER ? paramValue : undefined
}
if (item.column.filterType === this.SysOnlineColumnFilterType.RANFGE_FILTER) {
temp.columnValueStart = paramValue[0];
temp.columnValueEnd = paramValue[1];
}
return temp;
}).filter(item => item != null);
}
return queryParams;
},
getDropdownParams (widget) {
if (Array.isArray(widget.dictParamList)) {
let params = {};
for (let i = 0; i < widget.dictParamList.length; i++) {
let dictParam = widget.dictParamList[i];
if (dictParam.dictValue == null || dictParam.dictValueType == null) continue;
params = this.getParamValueObj(dictParam.dictParamName, dictParam.dictValueType, dictParam.dictValue, params);
if (params == null) return null;
}
return params;
} else {
return {};
}
},
onTableOperationClick (operation, row, widget) {
this.handlerOperation(operation, row, widget);
}
},
mounted () {
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,836 @@
import { mapMutations } from 'vuex';
import * as StaticDict from '@/staticDict';
import rules from '@/utils/validate.js';
import { getOperationPermCode } from '../utils/index.js';
import OnlineForm from '@/views/onlineForm/index.vue';
import {
OnlineFormController
} from '@/api/onlineController.js';
const OnlineFormMixins = {
props: {
formId: {
type: String,
required: true
},
readOnly: {
type: Boolean,
default: false
},
closeVisible: {
type: String,
default: '0'
},
params: {
type: Object
}
},
data () {
return {
isLoading: true,
formData: {},
rules: {},
formConfig: {
formType: undefined,
formKind: undefined,
gutter: 20,
labelPosition: 'right',
labelWidth: 120,
width: undefined,
height: undefined,
formWidgetList: [],
formQueryTable: undefined
},
masterTable: undefined,
errorMessage: [],
tableWidgetList: [],
dropdownWidgetList: [],
richEditWidgetList: [],
datasourceMap: new Map(),
relationMap: new Map(),
tableMap: new Map(),
columnMap: new Map(),
dictMap: new Map(),
linkageMap: new Map()
}
},
methods: {
getFormData () {
return this.formData;
},
getPermCode (widget, operation) {
return getOperationPermCode(widget, operation);
},
loadOnlineFormData () {
return new Promise((resolve, reject) => {
OnlineFormController.render(this, {
formId: this.formId
}).then(res => {
let onlineForm = res.data.onlineForm;
let formConfigData = JSON.parse(onlineForm.widgetJson);
let formConfig = {
formName: onlineForm.formName,
formType: onlineForm.formType,
formKind: onlineForm.formKind,
masterTableId: onlineForm.masterTableId,
labelWidth: formConfigData.formConfig.labelWidth,
labelPosition: formConfigData.formConfig.labelPosition,
gutter: formConfigData.formConfig.gutter,
height: formConfigData.formConfig.height,
width: formConfigData.formConfig.width,
formWidgetList: formConfigData.widgetList,
formQueryTable: formConfigData.formConfig.tableWidget
}
onlineForm = null;
res.data.onlineForm = null;
// 字典
if (Array.isArray(res.data.onlineDictList)) {
res.data.onlineDictList.forEach(dict => {
this.dictMap.set(dict.dictId, dict);
});
}
res.data.onlineDictList = null;
// 数据表
if (Array.isArray(res.data.onlineTableList)) {
res.data.onlineTableList.forEach(table => {
this.tableMap.set(table.tableId, table);
});
}
res.data.onlineTableList = null;
// 字段
if (Array.isArray(res.data.onlineColumnList)) {
res.data.onlineColumnList.forEach(column => {
if (column.dictId != null) {
column.dictInfo = this.dictMap.get(column.dictId);
}
let table = this.tableMap.get(column.tableId);
if (table) {
if (!Array.isArray(table.columnList)) table.columnList = [];
table.columnList.push(column);
}
this.columnMap.set(column.columnId, column);
});
}
res.data.onlineColumnList = null;
// 虚拟字段
if (Array.isArray(res.data.onlineVirtualColumnList)) {
res.data.onlineVirtualColumnList.forEach(column => {
column.columnId = column.virtualColumnId;
column.columnComment = column.columnPrompt;
column.columnName = column.objectFieldName;
column.primaryKey = false;
column.isVirtualColumn = true;
this.columnMap.set(column.columnId, column);
});
}
res.data.onlineVirtualColumnList = null;
// 数据源
if (Array.isArray(res.data.onlineDatasourceList)) {
res.data.onlineDatasourceList.forEach(datasource => {
datasource.masterTable = this.tableMap.get(datasource.masterTableId);
if (datasource.masterTable) datasource.masterTable.datasource = datasource;
this.datasourceMap.set(datasource.datasourceId, datasource);
});
}
res.data.onlineDatasourceList = null;
// 关联
if (Array.isArray(res.data.onlineDatasourceRelationList)) {
res.data.onlineDatasourceRelationList.forEach(relation => {
let datasource = this.datasourceMap.get(relation.datasourceId);
if (datasource) {
if (!Array.isArray(datasource.relationList)) datasource.relationList = [];
datasource.relationList.push(relation);
}
relation.masterColumn = this.columnMap.get(relation.masterColumnId);
relation.slaveTable = this.tableMap.get(relation.slaveTableId);
if (relation.slaveTable) {
relation.slaveTable.relation = relation;
relation.slaveTable.datasource = datasource;
}
relation.slaveColumn = this.columnMap.get(relation.slaveColumnId);
this.relationMap.set(relation.relationId, relation);
});
}
res.data.onlineDatasourceRelationList = null;
// 校验规则
if (Array.isArray(res.data.onlineColumnRuleList)) {
res.data.onlineColumnRuleList.forEach(rule => {
let column = this.columnMap.get(rule.columnId);
if (column) {
if (!Array.isArray(column.ruleList)) column.ruleList = [];
column.ruleList.push(rule);
}
});
}
res.data.onlineColumnRuleList = null;
this.initFormData(formConfig);
this.formConfig = formConfig;
resolve();
}).catch(e => {
reject(e);
});
});
},
initWidget (widget, formConfig) {
if (widget != null) {
if (widget.datasourceId) widget.datasource = this.datasourceMap.get(widget.datasourceId);
if (widget.relationId) {
widget.relation = this.relationMap.get(widget.relationId);
if (widget.datasource == null && widget.relation != null) {
widget.datasource = this.datasourceMap.get(widget.relation.datasourceId);
}
}
if (widget.datasource == null) {
widget.datasource = {
masterTable: {}
}
widget.column = {}
}
if (widget.tableId) widget.table = this.tableMap.get(widget.tableId);
if (widget.columnId) widget.column = this.columnMap.get(widget.columnId);
if (widget.widgetType === this.SysCustomWidgetType.RichEditor) {
this.richEditWidgetList.push(widget);
}
// 初始化组件下拉字典参数
if (Array.isArray(widget.dictParamList)) {
widget.dictParamList.forEach(param => {
if (param.dictValueType === this.SysOnlineParamValueType.STATIC_DICT) {
let errorItem = null;
if (Array.isArray(param.dictValue) && param.dictValue.length === 2) {
let staticDict = StaticDict[param.dictValue[0]];
if (staticDict == null) {
errorItem = {
widget: widget,
message: '组件字典参数' + param.dictParamName + '绑定的静态字典 [' + param.dictValue[0] + '] 并不存在!'
}
} else {
if (staticDict.getValue(param.dictValue[1]) == null) {
errorItem = {
widget: widget,
message: '组件字典参数' + param.dictParamName + '绑定的静态字典值并不属于静态字段 [' + param.dictValue[0] + '] '
}
}
}
} else {
errorItem = {
widget: widget,
message: '组件字典参数' + param.dictParamName + '绑定的静态字典错误!'
}
}
if (errorItem != null) this.errorMessage.push(errorItem);
}
});
}
if (widget.column && widget.column.dictInfo != null) {
this.dropdownWidgetList.push(widget);
}
// 初始化表格列
if (widget.widgetType === this.SysCustomWidgetType.Table) {
// 寻找表格主键
widget.primaryColumnName = undefined;
if (widget.table && Array.isArray(widget.table.columnList)) {
for (let i = 0; i < widget.table.columnList.length; i++) {
if (widget.table.columnList[i].primaryKey) {
widget.primaryColumnName = widget.table.columnList[i].columnName;
break;
}
}
}
if (Array.isArray(widget.tableColumnList)) {
widget.tableColumnList.forEach(tableColumn => {
tableColumn.table = this.tableMap.get(tableColumn.tableId);
tableColumn.column = this.columnMap.get(tableColumn.columnId);
tableColumn.relation = this.relationMap.get(tableColumn.relationId);
if (tableColumn.table == null || tableColumn.column == null) {
this.errorMessage.push({
widget: widget,
message: '表格列 [' + tableColumn.showName + '] 绑定的字段不存在!'
});
}
});
}
if (Array.isArray(widget.queryParamList)) {
widget.queryParamList.forEach(param => {
param.table = this.tableMap.get(param.tableId);
param.column = this.columnMap.get(param.columnId);
param.relation = this.relationMap.get(param.relationId);
if (param.table == null || param.column == null) {
this.errorMessage.push({
widget: widget,
message: '表格查询参数不存在!'
});
}
});
}
this.tableWidgetList.push(widget);
}
while (widget.datasourceId != null || widget.relationId != null) {
if (widget.datasourceId == null && widget.relation == null) {
let errorItem = {
widget: widget,
message: '组件绑定字段所属' + (widget.datasourceId ? '数据源' : '关联') + '不存在!'
}
this.errorMessage.push(errorItem);
break;
}
if (widget.table == null) {
let errorItem = {
widget: widget,
messagre: '组件绑定字段所属数据表不存在!'
}
this.errorMessage.push(errorItem);
break;
}
if (widget.column == null && widget.columnId != null) {
let errorItem = {
widget: widget,
messagre: '组件绑定字段不存在!'
}
this.errorMessage.push(errorItem);
break;
}
if (widget.column) {
let table = this.tableMap.get(widget.tableId);
if (table.tableId !== widget.table.tableId) {
let errorItem = {
widget: widget,
messagre: '组件绑定字段不属于选张的数据表!'
}
this.errorMessage.push(errorItem);
break;
}
}
break;
}
if (Array.isArray(widget.childWidgetList)) {
widget.childWidgetList.forEach(subWidget => {
if (formConfig.formType === this.SysOnlineFormType.FLOW && this.formReadOnly) {
subWidget.readOnly = true;
}
this.initWidget(subWidget, formConfig);
})
}
if (widget.column && widget.column.dictInfo) {
if (Array.isArray(widget.dictParamList)) {
widget.dictParamList.forEach(dictParam => {
if (dictParam.dictValueType === this.SysOnlineParamValueType.TABLE_COLUMN) {
let linkageItem = this.linkageMap.get(dictParam.dictValue);
if (linkageItem == null) {
linkageItem = [];
this.linkageMap.set(dictParam.dictValue, linkageItem);
}
linkageItem.push(widget);
}
});
}
}
}
},
initFormWidgetList (formConfig) {
this.errorMessage = [];
if (Array.isArray(formConfig.formWidgetList)) {
formConfig.formWidgetList.forEach(widget => {
if (formConfig.formType === this.SysOnlineFormType.FLOW && this.formReadOnly) {
widget.readOnly = true;
}
this.initWidget(widget, formConfig);
});
}
if (this.errorMessage.length > 0) {
console.error(this.errorMessage);
}
},
buildRuleItem (widget, rule) {
if (rule.propDataJson) rule.data = JSON.parse(rule.propDataJson);
if (widget != null && rule != null) {
switch (rule.onlineRule.ruleType) {
case this.SysOnlineRuleType.INTEGER_ONLY:
return { type: 'integer', message: rule.data.message, trigger: 'blur', transform: (value) => Number(value) };
case this.SysOnlineRuleType.DIGITAL_ONLY:
return { type: 'number', message: rule.data.message, trigger: 'blur', transform: (value) => Number(value) };
case this.SysOnlineRuleType.LETTER_ONLY:
return { type: 'string', pattern: rules.pattern.english, message: rule.data.message, trigger: 'blur' };
case this.SysOnlineRuleType.EMAIL:
return { type: 'email', message: rule.data.message, trigger: 'blur' };
case this.SysOnlineRuleType.MOBILE:
return { type: 'string', pattern: rules.pattern.mobie, message: rule.data.message, trigger: 'blur' };
case this.SysOnlineRuleType.RANGE:
if (widget.column) {
let isNumber = ['Boolean', 'Date', 'String'].indexOf(widget.column.objectFieldType) === -1;
return { type: isNumber ? 'number' : 'string', min: rule.data.min, max: rule.data.max, message: rule.data.message, trigger: 'blur' };
}
break;
case this.SysOnlineRuleType.CUSTOM:
return { type: 'string', pattern: new RegExp(rule.data.pattern), message: rule.data.message, trigger: 'blur' };
}
}
},
buildWidgetRule (widget, rules) {
if (widget != null && widget.column != null) {
let widgetRuleKey = (widget.relation ? widget.relation.variableName + '__' : '') + widget.column.columnName;
// 必填字段以及设置了验证规则的字段
if (!widget.column.nullable || Array.isArray(widget.column.ruleList)) {
rules[widgetRuleKey] = [];
// 必填验证
if (!widget.column.nullable) {
rules[widgetRuleKey].push(
{ required: true, message: widget.showName + '不能为空!', trigger: 'true' }
)
}
// 其他验证
if (Array.isArray(widget.column.ruleList)) {
widget.column.ruleList.forEach(rule => {
let ruleItem = this.buildRuleItem(widget, rule);
if (ruleItem) rules[widgetRuleKey].push(ruleItem);
});
}
}
}
},
initWidgetRule (formConfig) {
if (Array.isArray(formConfig.formWidgetList)) {
let rules = {};
formConfig.formWidgetList.forEach(widget => {
this.buildWidgetRule(widget, rules);
});
this.$set(this, 'rules', rules);
this.$nextTick(() => {
if (this.$refs.form) this.$refs.form.clearValidate();
});
}
},
initFormDatasourceData (formConfig) {
let that = this;
function addFormDataByColumn (retObj, column, relation) {
let fieldName = (relation ? relation.variableName + '__' : '') + column.columnName;
if (retObj == null) retObj = {};
if (formConfig.formType === that.SysOnlineFormType.QUERY) {
if (retObj.formFilter == null) retObj.formFilter = {};
if (retObj.formFilterCopy == null) retObj.formFilterCopy = {};
retObj.formFilter[fieldName] = column.objectFieldType === 'Boolean' ? false : undefined;
retObj.formFilterCopy[fieldName] = column.objectFieldType === 'Boolean' ? false : undefined;
} else {
retObj[fieldName] = column.objectFieldType === 'Boolean' ? false : undefined;
}
return retObj;
}
// 设置数据源数据
let datasourceFormData = {};
if (this.masterTable) {
// 添加表单主表的数据
this.masterTable.columnList.forEach(column => {
datasourceFormData = addFormDataByColumn(datasourceFormData, column, this.masterTable.relation);
});
// 如果表单主表是数据源主表,添加关联数据
if (this.masterTable.relation == null) {
let datasource = this.masterTable.datasource;
if (datasource != null && Array.isArray(datasource.relationList)) {
datasource.relationList.forEach(relation => {
// 一对一关联从表数据
if (relation.relationType === this.SysOnlineRelationType.ONE_TO_ONE) {
let slaveTable = this.tableMap.get(relation.slaveTableId);
if (slaveTable && Array.isArray(slaveTable.columnList)) {
slaveTable.columnList.forEach(column => {
datasourceFormData = addFormDataByColumn(datasourceFormData, column, relation);
});
}
}
});
}
}
}
this.$set(this, 'formData', datasourceFormData);
},
initWidgetLinkage (formConfig) {
this.linkageMap.forEach((widgetList, key) => {
let column = this.columnMap.get(key);
let watchKey = null;
if (formConfig.formType === this.SysOnlineFormType.QUERY) {
watchKey = 'formData.formFilter.' + column.columnName;
} else {
watchKey = 'formData.' + column.columnName;
}
this.$watch(watchKey, (newValue) => {
if (Array.isArray(widgetList)) {
widgetList.forEach(widget => {
if (Array.isArray(this.$refs[widget.variableName])) {
this.$refs[widget.variableName].forEach(ref => {
ref.reset();
});
} else {
this.$refs[widget.variableName].reset();
}
});
}
});
});
},
initFormData (formConfig) {
this.masterTable = this.tableMap.get(formConfig.masterTableId);
// 初始化表单数据
this.initFormDatasourceData(formConfig);
// 初始化表单组件
this.initWidget(formConfig.formQueryTable, formConfig);
this.initFormWidgetList(formConfig);
// 初始化校验信息
this.initWidgetRule(formConfig);
},
getParamValue (valueType, valueData) {
switch (valueType) {
case this.SysOnlineParamValueType.FORM_PARAM:
return this.params ? this.params[valueData] : undefined;
case this.SysOnlineParamValueType.TABLE_COLUMN:
{
let column = this.columnMap.get(valueData);
let columnValue = null;
if (this.formConfig.formType === this.SysOnlineFormType.QUERY) {
columnValue = this.formData.formFilterCopy[column.columnName];
} else {
columnValue = this.formData[column.columnName];
}
if (column == null || columnValue == null || columnValue === '') {
return null;
} else {
return columnValue;
}
}
case this.SysOnlineParamValueType.STATIC_DICT:
return Array.isArray(valueData) ? valueData[1] : undefined;
case this.SysOnlineParamValueType.INPUT_VALUE:
return valueData;
}
},
getParamValueObj (paramName, valueType, valueData, retObj) {
try {
if (retObj == null) retObj = {};
retObj[paramName] = this.getParamValue(valueType, valueData);
if (retObj[paramName] == null) return null;
return retObj;
} catch (e) {
console.log(e);
}
},
clean () {
this.datasourceMap = null;
this.relationMap = null;
this.tableMap = null;
this.columnMap = null;
this.dictMap = null;
},
loadAllDropdownData () {
if (Array.isArray(this.dropdownWidgetList)) {
this.dropdownWidgetList.forEach(dropdownWidget => {
let dropdownWidgetImpl = this.$refs[dropdownWidget.variableName][0];
if (dropdownWidgetImpl) {
dropdownWidgetImpl.onVisibleChange();
}
});
}
},
reload () {
this.loadOnlineFormData().then(res => {
this.isLoading = false;
if (this.formConfig.formType === this.SysOnlineFormType.FORM) {
if (Number.parseInt(this.operationType) === this.SysCustomWidgetOperationType.EDIT && this.saveOnClose === '1') {
// 编辑操作页面,初始化页面数据
let httpCall = null;
if (this.saveOnClose === '0') {
httpCall = Promise.resolve({
data: this.params
});
} else {
let params = {
datasourceId: (this.masterTable.datasource || {}).datasourceId,
relationId: (this.masterTable.relation || {}).relationId
}
for (let i = 0; i < this.masterTable.columnList.length; i++) {
let column = this.masterTable.columnList[i];
if (column.primaryKey) {
params.dataId = this.params[column.columnName];
break;
}
}
if (params.relationId) {
httpCall = this.doUrl('/admin/online/onlineOperation/viewByOneToManyRelationId/' + (this.masterTable.datasource || {}).variableName, 'get', params);
} else {
httpCall = this.doUrl('/admin/online/onlineOperation/viewByDatasourceId/' + (this.masterTable.datasource || {}).variableName, 'get', params);
}
}
httpCall.then(res => {
this.formData = {
...this.formData,
...res.data
}
this.loadAllDropdownData();
// 初始化组件联动
this.initWidgetLinkage(this.formConfig);
}).catch(e => {});
return;
} else {
if (this.rowData != null) {
this.formData = {
...this.rowData
}
}
}
this.loadAllDropdownData();
}
setTimeout(() => {
if (this.formConfig.formType === this.SysOnlineFormType.FLOW) {
this.loadAllDropdownData();
}
// 初始化组件联动
this.initWidgetLinkage(this.formConfig);
this.onResume();
this.$emit('ready');
}, 30);
}).catch(e => {
console.log(e);
});
},
onResume () {},
getPrimaryKeyColumnParam (table, row) {
if (table && Array.isArray(table.columnList)) {
return table.columnList.reduce((retObj, column) => {
let fieldName = (table.relation ? table.relation.variableName + '__' : '') + column.columnName;
if (column.primaryKey) {
retObj[column.columnName] = row ? row[fieldName] : undefined;
}
return retObj;
}, {});
}
return null;
},
buildSubFormParams (operation, subFormInfo, row) {
let subFormMasterTable = this.tableMap.get(subFormInfo.masterTableId);
if (subFormMasterTable == null) return null;
if (subFormMasterTable.relation == null) {
// 下级表单操作的是主表数据的编辑
if (operation.type === this.SysCustomWidgetOperationType.EDIT) {
return this.getPrimaryKeyColumnParam(this.masterTable, row);
} else {
return null;
}
} else {
// 下级表单操作的是从表
if (subFormInfo.formType === this.SysOnlineFormType.QUERY) {
// 从表的查询页面,参数为主表主键
return this.getPrimaryKeyColumnParam(this.masterTable, row);
} else {
if (operation.type === this.SysCustomWidgetOperationType.EDIT) {
// 从表的编辑页面
if (this.formConfig.formType === this.SysOnlineFormType.FORM &&
Number.parseInt(this.operationType) === this.SysCustomWidgetOperationType.ADD) {
return {
...row
}
} else {
return this.getPrimaryKeyColumnParam(subFormMasterTable, row);
}
} else {
// 从表的添加页面
return {
...this.params
}
}
}
}
},
handlerOperation (operation, row, widget) {
if (this.preview()) return;
if (operation.formId != null) {
OnlineFormController.view(this, {
formId: operation.formId
}).then(res => {
let formInfo = res.data;
if (formInfo != null) {
let params = this.buildSubFormParams(operation, formInfo, row);
if (formInfo.formKind === this.SysOnlineFormKind.DIALOG) {
let formJsonData = JSON.parse(formInfo.widgetJson);
let area = (formInfo.height != null) ? [(formJsonData.formConfig.width || 800) + 'px', formJsonData.formConfig.height + 'px'] : (formJsonData.formConfig.width || 800) + 'px';
this.$dialog.show(operation.name, OnlineForm, {
area: area,
offset: '100px'
}, {
flowData: this.flowData,
formId: formInfo.formId,
formType: formInfo.formType,
operationType: operation.type,
params,
saveOnClose: (
formInfo.formType === this.SysOnlineFormType.FLOW || this.formConfig.formType === this.SysOnlineFormType.FLOW ||
(
formInfo.formType === this.SysOnlineFormType.FORM &&
Number.parseInt(this.operationType) === this.SysCustomWidgetOperationType.ADD
)
) ? '0' : '1',
rowData: row
}).then(res => {
let widgetObj = this.$refs[widget.variableName];
if (Array.isArray(widgetObj)) {
widgetObj.forEach(item => {
item.refresh(res, operation.type);
});
} else {
widgetObj.refresh(res, operation.type);
}
}).catch(e => {
});
} else {
if (this.formConfig.formType === this.SysOnlineFormType.QUERY) {
let tableWidget = this.$refs[this.formConfig.formQueryTable.variableName].getTableWidget();
this.addOnlineFormCache({
key: this.$route.fullPath,
value: {
formFilter: { ...this.formData.formFilter },
formFilterCopy: { ...this.formData.formFilterCopy },
tableImpl: {
totalCount: tableWidget.totalCount,
currentPage: tableWidget.currentPage,
pageSize: tableWidget.pageSize
}
}
});
}
this.$router.push({
name: 'onlineForm',
query: {
flowData: this.flowData,
formId: formInfo.formId,
formType: formInfo.formType,
closeVisible: '1',
operationType: operation.type,
params,
saveOnClose: (
formInfo.formType === this.SysOnlineFormType.FLOW || this.formConfig.formType === this.SysOnlineFormType.FLOW ||
(
formInfo.formType === this.SysOnlineFormType.FORM &&
Number.parseInt(this.operationType) === this.SysCustomWidgetOperationType.ADD
)
) ? '0' : '1',
rowData: row
}
})
}
}
}).catch(e => {});
} else {
if (operation.type === this.SysCustomWidgetOperationType.DELETE) {
this.$confirm('是否删除当前数据?').then(res => {
if (this.formConfig.formType !== this.SysOnlineFormType.FLOW &&
(this.formConfig.formType !== this.SysOnlineFormType.FORM || Number.parseInt(this.operationType) !== this.SysCustomWidgetOperationType.ADD)) {
let params = {
datasourceId: (widget.table.datasource || {}).datasourceId,
relationId: (widget.table.relation || {}).relationId
}
for (let i = 0; i < widget.table.columnList.length; i++) {
let column = widget.table.columnList[i];
if (column.primaryKey) {
let fieldName = (widget.table.relation ? widget.table.relation.variableName + '__' : '') + column.columnName;
params.dataId = row[fieldName];
break;
}
}
let httpCall = null;
if (params.relationId) {
httpCall = this.doUrl('/admin/online/onlineOperation/deleteOneToManyRelation/' + widget.datasource.variableName, 'post', params);
} else {
httpCall = this.doUrl('/admin/online/onlineOperation/deleteDatasource/' + widget.datasource.variableName, 'post', params);
}
httpCall.then(res => {
this.$message.success('删除成功!');
let widgetObj = this.$refs[widget.variableName];
if (Array.isArray(widgetObj)) {
widgetObj.forEach(item => {
item.refresh(res, operation.type);
});
} else {
widgetObj.refresh(res, operation.type);
}
}).catch(e => {
});
} else {
let widgetObj = this.$refs[widget.variableName];
if (Array.isArray(widgetObj)) {
widgetObj.forEach(item => {
item.refresh(row, operation.type);
});
} else {
widgetObj.refresh(row, operation.type);
}
}
}).catch(e => {});
} else if (operation.type === this.SysCustomWidgetOperationType.EXPORT) {
this.$message.warning('导出操作尚未支持!');
}
}
},
getRelationTableData (tableWidget) {
if (tableWidget.widgetType === this.SysCustomWidgetType.Table) {
let table = tableWidget.table;
let temp = this.$refs[tableWidget.variableName];
if (table != null && table.relation != null && Array.isArray(table.columnList) && temp != null) {
let tableWidgetImpl = temp[0] || temp;
return tableWidgetImpl.getTableWidget().dataList.map(data => {
return table.columnList.reduce((retObj, column) => {
let fieldName = (table.relation ? table.relation.variableName + '__' : '') + column.columnName;
retObj[column.columnName] = data[fieldName];
return retObj
}, {});
});
}
}
return null;
},
getWidgetPrimaryColumnId (widget) {
console.log(widget);
let columnList = null;
if (widget.relationId == null) {
columnList = widget.datasource.masterTable.columnList;
} else {
columnList = widget.relation.slaveTable.columnList;
}
if (Array.isArray(columnList)) {
for (let i = 0; i < columnList.length; i++) {
let column = columnList[i];
if (column.primaryKey) {
let columnName = column.columnName;
if (widget.relation != null) columnName = widget.relation.variableName + '__' + columnName;
console.log(this.formData, columnName);
return this.formData[columnName];
}
}
}
},
...mapMutations(['addOnlineFormCache'])
},
created () {
this.reload();
},
destoryed () {
this.clean();
},
watch: {
formId: {
handler (newValue) {
this.reload();
}
}
}
}
export {
OnlineFormMixins
}

View File

@@ -0,0 +1,141 @@
<template>
<div style="position: relative;">
<el-form :label-width="formConfig.labelWidth + 'px'" size="mini" :label-position="formConfig.labelPosition" @submit.native.prevent>
<filter-box :item-width="formConfig.labelWidth + 250" v-if="!isLoading">
<CustomFilterWidget v-for="widget in formConfig.formWidgetList" :key="widget.id"
:ref="widget.variableName"
:widgetConfig="widget" :formConfig="formConfig"
:getDropdownParams="getDropdownParams"
v-model="formData.formFilter[widget.column.columnName]"
/>
<el-button v-if="Array.isArray(formConfig.formWidgetList) && formConfig.formWidgetList.length > 0"
slot="operator" type="primary" :plain="true" size="mini" @click="onSearch">
查询
</el-button>
<el-button v-for="operation in getTableOperation(false)" :key="operation.id"
slot="operator" size="mini"
:plain="operation.plain"
:type="operation.btnType"
:disabled="!checkPermCodeExist(getPermCode(formConfig.formQueryTable, operation))"
@click.stop="onTableOperationClick(operation, null, formConfig.formQueryTable)">
{{operation.name}}
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24" v-if="formConfig.formQueryTable">
<CustomTable :ref="formConfig.formQueryTable.variableName" :widgetConfig="formConfig.formQueryTable" :formType="formConfig.formType"
:getTableQueryParams="getTableQueryParams"
@operationClick="onTableOperationClick" />
</el-col>
</el-row>
</div>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex';
import { OnlineFormMixins } from './onlineFormMixins.js';
import CustomFilterWidget from '@/views/onlineForm/components/customFilterWidget.vue';
import CustomTable from '@/views/onlineForm/components/customTable.vue';
export default {
name: 'onlineQueryForm',
mixins: [OnlineFormMixins],
props: {
formId: {
type: String,
required: true
},
closeVisible: {
type: String,
default: '0'
}
},
components: {
CustomFilterWidget,
CustomTable
},
inject: ['preview'],
methods: {
getTableOperation (rowOperation) {
if (this.formConfig.formQueryTable == null || !Array.isArray(this.formConfig.formQueryTable.operationList)) return [];
return this.formConfig.formQueryTable.operationList.filter(operation => {
return operation.rowOperation === rowOperation && operation.enabled;
});
},
getTableQueryParams (widget) {
let queryParams = [];
if (Array.isArray(widget.queryParamList)) {
queryParams = widget.queryParamList.map(item => {
let paramValue = this.getParamValue(item.paramValueType, item.paramValue);
if (paramValue == null || paramValue === '' || (Array.isArray(paramValue) && paramValue.length === 0)) return;
let temp = {
tableName: item.table.tableName,
columnName: item.column.columnName,
filterType: item.column.filterType,
columnValue: item.column.filterType !== this.SysOnlineColumnFilterType.RANFGE_FILTER ? paramValue : undefined
}
if (item.column.filterType === this.SysOnlineColumnFilterType.RANFGE_FILTER) {
temp.columnValueStart = paramValue[0];
temp.columnValueEnd = paramValue[1];
}
return temp;
}).filter(item => item != null);
}
return queryParams;
},
onSearch () {
this.formData.formFilterCopy = {
...this.formData.formFilter
}
this.$refs[this.formConfig.formQueryTable.variableName].refresh();
},
getDropdownParams (widget) {
if (Array.isArray(widget.dictParamList)) {
let params = {};
for (let i = 0; i < widget.dictParamList.length; i++) {
let dictParam = widget.dictParamList[i];
params = this.getParamValueObj(dictParam.dictParamName, dictParam.dictValueType, dictParam.dictValue, params);
if (params == null) return null;
}
return params;
} else {
return {};
}
},
onTableOperationClick (operation, row, widget) {
this.handlerOperation(operation, row, widget);
},
onResume () {
let key = this.$route.fullPath;
let cacheFormData = this.getOnlineFormCache[key];
if (cacheFormData) {
this.$nextTick(() => {
if (Array.isArray(this.dropdownWidgetList)) {
this.dropdownWidgetList.forEach(dropdownWidget => {
let dropdownWidgetImpl = this.$refs[dropdownWidget.variableName][0];
if (dropdownWidgetImpl) {
dropdownWidgetImpl.onVisibleChange();
}
});
}
this.formData.formFilter = cacheFormData.formFilter;
this.formData.formFilterCopy = cacheFormData.formFilterCopy;
this.$refs[this.formConfig.formQueryTable.variableName].setTableWidget(cacheFormData.tableImpl);
this.removeOnlineFormCache(key);
});
}
},
...mapMutations(['removeOnlineFormCache'])
},
computed: {
...mapGetters(['getOnlineFormCache'])
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,293 @@
<template>
<div style="position: relative;">
<el-form label-width="80px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="330">
<el-form-item label="工单状态">
<el-select class="filter-item" v-model="flowStatus" :clearable="true"
placeholder="工单状态">
<el-option v-for="item in SysFlowWorkOrderStatus.getList()" :key="item.id"
:label="item.name" :value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="创建日期">
<date-range class="filter-item" v-model="createTime" :clearable="true" :allowTypes="['day']" align="left"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini"
:disabled="processDefinitionKey == null"
@click="onSearch()">
查询
</el-button>
<el-button slot="operator" type="primary" size="mini"
:disabled="processDefinitionKey == null"
@click="onStartFlow()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24" v-if="formConfig.formQueryTable">
<CustomTable v-if="processDefinitionKey != null" :ref="formConfig.formQueryTable.variableName"
:widgetConfig="formConfig.formQueryTable" :formType="formConfig.formType"
:getTableQueryParams="getTableQueryParams"
:loadTableDataFunc="listWorkOrder"
@viewWOrkOrder="onView"
@handlerWOrkOrder="onSubmit"
@cancelWOrkOrder="onCancelWorkOrder"
/>
</el-col>
</el-row>
</div>
</template>
<script>
import '@/staticDict/flowStaticDict.js';
import { mapGetters, mapMutations } from 'vuex';
import { OnlineFormMixins } from './onlineFormMixins.js';
import CustomTable from '@/views/onlineForm/components/customTable.vue';
import { FlowOperationController, FlowEntryController } from '@/api/flowController.js';
export default {
name: 'onlineWorkOrder',
props: {
formId: {
type: String,
required: true
},
entryId: {
type: String,
required: true
},
isPreview: {
type: Boolean,
default: false
}
},
mixins: [OnlineFormMixins],
components: {
CustomTable
},
data () {
return {
processDefinitionKey: undefined,
processDefinitionName: undefined,
createTime: [],
flowStatus: undefined
}
},
methods: {
getTableQueryParams (widget) {
let queryParams = [];
if (Array.isArray(widget.queryParamList)) {
queryParams = widget.queryParamList.map(item => {
let paramValue = this.getParamValue(item.paramValueType, item.paramValue);
if (paramValue == null || paramValue === '' || (Array.isArray(paramValue) && paramValue.length === 0)) return;
let temp = {
tableName: item.table.tableName,
columnName: item.column.columnName,
filterType: item.column.filterType,
columnValue: item.column.filterType !== this.SysOnlineColumnFilterType.RANFGE_FILTER ? paramValue : undefined
}
if (item.column.filterType === this.SysOnlineColumnFilterType.RANFGE_FILTER) {
temp.columnValueStart = Array.isArray(paramValue) ? paramValue[0] : undefined;
temp.columnValueEnd = Array.isArray(paramValue) ? paramValue[1] : undefined;
}
return temp;
}).filter(item => item != null);
}
return queryParams;
},
listWorkOrder (params) {
if (this.isPreview || this.processDefinitionKey == null) return Promise.reject();
return new Promise((resolve, reject) => {
params = {
...params,
flowWorkOrderDtoFilter: {
flowStatus: this.flowStatus,
createTimeStart: Array.isArray(this.createTime) ? this.createTime[0] : undefined,
createTimeEnd: Array.isArray(this.createTime) ? this.createTime[1] : undefined
}
}
FlowOperationController.listWorkOrder(this, params, {
processDefinitionKey: this.processDefinitionKey
}).then(res => {
res.data.dataList = res.data.dataList.map(item => {
let initTaskInfo = JSON.parse(item.initTaskInfo);
let runtimeTaskInfo = (Array.isArray(item.runtimeTaskInfoList) && item.runtimeTaskInfoList.length > 0) ? item.runtimeTaskInfoList[0] : {};
return {
...item,
flowStatus: this.SysFlowWorkOrderStatus.getValue(item.flowStatus),
...Object.keys(item.masterData).reduce((retObj, key) => {
retObj['masterTable__' + key] = item.masterData[key];
return retObj;
}, {}),
initTaskInfo,
runtimeTaskInfo,
masterData: undefined
}
});
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
onSearch () {
this.formData.formFilterCopy = {
...this.formData.formFilter
}
this.$refs[this.formConfig.formQueryTable.variableName].refresh();
},
onResume () {
let key = this.$route.fullPath;
let cacheFormData = this.getOnlineFormCache[key];
if (cacheFormData) {
this.$nextTick(() => {
if (Array.isArray(this.dropdownWidgetList)) {
this.dropdownWidgetList.forEach(dropdownWidget => {
let dropdownWidgetImpl = this.$refs[dropdownWidget.variableName][0];
if (dropdownWidgetImpl) {
dropdownWidgetImpl.onVisibleChange();
}
});
}
this.formData.formFilter = cacheFormData.formFilter;
this.formData.formFilterCopy = cacheFormData.formFilterCopy;
this.$refs[this.formConfig.formQueryTable.variableName].setTableWidget(cacheFormData.tableImpl);
this.removeOnlineFormCache(key);
});
}
},
onStartFlow () {
if (this.isPreview || this.processDefinitionKey == null) return;
let params = {
processDefinitionKey: this.processDefinitionKey
}
FlowOperationController.viewInitialTaskInfo(this, params).then(res => {
if (res.data && res.data.taskType === this.SysFlowTaskType.USER_TASK && res.data.assignedMe) {
this.$router.push({
name: res.data.routerName || 'handlerFlowTask',
query: {
processDefinitionKey: this.processDefinitionKey,
formId: res.data.formId,
routerName: res.data.routerName,
readOnly: res.data.readOnly,
taskName: '启动流程',
flowEntryName: this.processDefinitionName,
operationList: (res.data.operationList || []).filter(item => item.type !== this.SysFlowTaskOperationType.CO_SIGN),
variableList: res.data.variableList
}
});
} else {
FlowOperationController.startOnly(this, {
processDefinitionKey: this.processDefinitionKey
}).then(res => {
this.$message.success('启动成功!');
}).catch(e => {});
}
}).catch(e => {});
},
onSubmit (row) {
if (this.isPreview || this.processDefinitionKey == null) return;
let taskId = (Array.isArray(row.runtimeTaskInfoList) && row.runtimeTaskInfoList.length > 0) ? row.runtimeTaskInfoList[0].taskId : undefined;
let params = {
processInstanceId: row.processInstanceId,
processDefinitionId: row.processDefinitionId,
taskId: taskId
}
FlowOperationController.viewRuntimeTaskInfo(this, params).then(res => {
if (res.data) {
this.$router.push({
name: res.data.routerName || 'handlerFlowTask',
query: {
isRuntime: true,
taskId: taskId,
processDefinitionKey: row.processDefinitionKey,
processInstanceId: row.processInstanceId,
processDefinitionId: row.processDefinitionId,
formId: res.data.formId,
routerName: res.data.routerName,
readOnly: res.data.readOnly,
taskName: (row.runtimeInitialTask || {}).taskName,
flowEntryName: row.processDefinitionName,
processInstanceInitiator: row.processInstanceInitiator,
operationList: (res.data.operationList || []).filter(item => item.type !== this.SysFlowTaskOperationType.CO_SIGN),
variableList: res.data.variableList
}
});
}
}).catch(e => {});
},
onView (row) {
if (this.isPreview || this.processDefinitionKey == null) return;
let params = {
processInstanceId: row.processInstanceId
}
FlowOperationController.viewInitialHistoricTaskInfo(this, params).then(res => {
if (res.data) {
this.$router.push({
name: res.data.routerName || 'handlerFlowTask',
query: {
isRuntime: false,
processDefinitionKey: row.processDefinitionKey,
processInstanceId: row.processInstanceId,
processDefinitionId: row.processDefinitionId,
formId: res.data.formId,
routerName: res.data.routerName,
readOnly: true,
flowEntryName: row.processDefinitionName,
processInstanceInitiator: row.processInstanceInitiator
}
});
}
}).catch(e => {});
},
onCancelWorkOrder (row) {
this.$confirm('是否撤销此工单?').then(res => {
let params = {
workOrderId: row.workOrderId,
cancelReason: '主动撤销'
}
FlowOperationController.cancelWorkOrder(this, params).then(res => {
this.$message.success('撤销成功!');
this.onSearch();
}).catch(e => {});
}).catch(e => {});
},
...mapMutations(['removeOnlineFormCache'])
},
provide () {
return {
preview: () => this.isPreview
}
},
computed: {
...mapGetters(['getOnlineFormCache'])
},
mounted () {
FlowEntryController.viewDict(this, {
entryId: this.entryId
}).then(res => {
this.processDefinitionKey = res.data.processDefinitionKey;
this.processDefinitionName = res.data.processDefinitionName;
}).catch(e => {
console.log(e);
});
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,250 @@
<template>
<div class="form-single-fragment">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules"
:label-width="formConfig.labelWidth + 'px'" size="mini"
:label-position="formConfig.labelPosition"
@submit.native.prevent>
<el-row :gutter="formConfig.gutter">
<template v-for="widget in formConfig.formWidgetList">
<CustomTable :ref="widget.variableName"
v-if="widget.widgetType === SysCustomWidgetType.Table" :key="widget.id"
:widgetConfig="widget"
:formType="formConfig.formType"
:primaryColumnName="widget.primaryColumnName"
:flowData="flowData"
:isNew="true"
:getTableQueryParams="getTableQueryParams"
@operationClick="onTableOperationClick"
/>
<CustomUpload :ref="widget.variableName" :key="widget.id"
v-else-if="widget.widgetType === SysCustomWidgetType.Upload"
:widgetConfig="widget"
:flowData="flowData"
:getDataId="getWidgetPrimaryColumnId"
v-model="formData[getWidgetFieldName(widget)]" />
<CustomWidget
v-else
:ref="widget.variableName"
:key="widget.id"
:widgetConfig="widget"
:formConfig="formConfig"
:getDropdownParams="getDropdownParams"
v-model="formData[getWidgetFieldName(widget)]"
>
<template v-for="subWidget in widget.childWidgetList">
<CustomTable :ref="subWidget.variableName"
v-if="subWidget.widgetType === SysCustomWidgetType.Table" :key="subWidget.id"
:widgetConfig="subWidget"
:formType="formConfig.formType"
:isNew="true"
:getTableQueryParams="getTableQueryParams"
@operationClick="onTableOperationClick"
/>
<CustomUpload :ref="subWidget.variableName" :key="subWidget.id"
v-else-if="subWidget.widgetType === SysCustomWidgetType.Upload"
:widgetConfig="subWidget"
:flowData="flowData"
:getDataId="getWidgetPrimaryColumnId"
v-model="formData[getWidgetFieldName(subWidget)]" />
<CustomWidget
v-else
:ref="subWidget.variableName"
:key="subWidget.id"
:widgetConfig="subWidget"
:formConfig="formConfig"
:getDropdownParams="getDropdownParams"
v-model="formData[getWidgetFieldName(subWidget)]"
/>
</template>
</CustomWidget>
</template>
</el-row>
</el-form>
</div>
</template>
<script>
import { OnlineFormMixins } from './onlineFormMixins.js';
import CustomUpload from '@/views/onlineForm/components/customUpload.vue';
import CustomWidget from '@/views/onlineForm/components/customWidget.vue';
import CustomTable from '@/views/onlineForm/components/customTable.vue';
export default {
name: 'workflowForm',
props: {
readOnly: {
type: [String, Boolean]
}
},
inject: ['preview'],
mixins: [OnlineFormMixins],
components: {
CustomWidget,
CustomTable,
CustomUpload
},
data () {
return {
flowData: {}
}
},
methods: {
getWidgetFieldName (widget) {
if (widget && widget.relation == null) {
return (widget.column || {}).columnName;
} else {
return widget.relation.variableName + '__' + (widget.column || {}).columnName
}
},
getDropdownParams (widget) {
if (Array.isArray(widget.dictParamList)) {
let params = {};
for (let i = 0; i < widget.dictParamList.length; i++) {
let dictParam = widget.dictParamList[i];
if (dictParam.dictValue == null || dictParam.dictValueType == null) continue;
params = this.getParamValueObj(dictParam.dictParamName, dictParam.dictValueType, dictParam.dictValue, params);
if (params == null) return null;
}
return params;
} else {
return {};
}
},
getTableQueryParams (widget) {
return {};
},
onTableOperationClick (operation, row, widget) {
this.handlerOperation(operation, row, widget);
},
setFormData (formData, oneToManyData, flowData) {
this.flowData = flowData;
this.formData = {
...this.formData,
...formData
}
this.setOneToManyRelationData(oneToManyData);
},
setOneToManyRelationData (oneToManyRelationList) {
if (oneToManyRelationList != null) {
Object.keys(oneToManyRelationList).forEach(relationVariableName => {
if (Array.isArray(this.tableWidgetList)) {
for (let i = 0; i < this.tableWidgetList.length; i++) {
let tableWidget = this.tableWidgetList[i];
if (tableWidget.relation.variableName === relationVariableName) {
let temp = this.$refs[tableWidget.variableName];
let tableImpl = Array.isArray(temp) ? temp[0] : temp;
if (tableImpl) {
tableImpl.getTableWidget().dataList = oneToManyRelationList[relationVariableName];
}
break;
}
}
}
});
}
},
getVariableData (variableList) {
let variableData;
if (Array.isArray(variableList) && variableList.length > 0) {
variableList.forEach(variable => {
if (!variable.builtin) {
let column = this.columnMap.get(variable.bindColumnId);
let relation = this.relationMap.get(variable.bindRelationId);
if (column != null) {
if (variableData == null) variableData = {};
let key = relation == null ? '' : relation.variableName + '__';
key += column.columnName;
variableData[variable.variableName] = this.formData[key];
}
}
});
}
return variableData;
},
getFormData () {
return new Promise((resolve, reject) => {
this.$refs.form.validate(valid => {
if (!valid) return reject();
let tempObj = {};
let that = this;
function getFlowWidgetData (widget) {
if (widget == null || widget.readOnly || widget.disabled) return;
if (widget.relation == null) {
if (tempObj.masterData == null) tempObj.masterData = {};
tempObj.masterData[widget.column.columnName] = that.formData[that.getWidgetFieldName(widget)];
tempObj.masterData.__maasterTable__ = widget.table;
} else {
if (tempObj.slaveData == null) tempObj.slaveData = {};
if (widget.widgetType === that.SysCustomWidgetType.Table) {
let tableData = that.getRelationTableData(widget);
if (tableData != null) {
tempObj.slaveData[widget.relation.relationId] = tableData;
}
} else {
tempObj.slaveData[widget.relation.relationId][widget.column.columnName] = that.formData[that.getWidgetFieldName(widget)];
if (tempObj.slaveData[widget.relation.relationId]['__slaveWidget__'] == null) tempObj.slaveData[widget.relation.relationId]['__slaveWidget__'] = widget;
}
}
if (Array.isArray(widget.childWidgetList)) {
widget.childWidgetList.forEach(subWidget => {
getFlowWidgetData(subWidget);
});
}
}
if (Array.isArray(this.formConfig.formWidgetList)) {
this.formConfig.formWidgetList.forEach(widget => {
getFlowWidgetData(widget);
});
}
if (tempObj.masterData != null && tempObj.masterData.__maasterTable__ != null) {
let primaryColumn = null;
if (Array.isArray(tempObj.masterData.__maasterTable__.columnList)) {
primaryColumn = tempObj.masterData.__maasterTable__.columnList.filter(column => {
return column.primaryKey;
})[0];
}
if (primaryColumn != null && this.formData[primaryColumn.columnName] != null) {
tempObj.masterData[primaryColumn.columnName] = this.formData[primaryColumn.columnName];
}
delete tempObj.masterData.__maasterTable__;
}
if (tempObj.slaveData != null) {
Object.keys(tempObj.slaveData).map(key => {
let slaveObj = tempObj.slaveData[key];
let primaryColumn = null;
if (slaveObj != null && slaveObj.__slaveWidget__ != null && slaveObj.__slaveWidget__.table != null) {
if (Array.isArray(slaveObj.__slaveWidget__.table.columnList)) {
primaryColumn = slaveObj.__slaveWidget__.table.columnList.filter(column => {
return column.primaryKey;
})[0];
}
let widget = slaveObj.__slaveWidget__;
if (primaryColumn != null && this.formData[widget.relation.variableName + '__' + (widget.column || {}).columnName] != null) {
slaveObj[primaryColumn.columnName] = this.formData[widget.relation.variableName + '__' + (widget.column || {}).columnName]
}
delete slaveObj.__slaveWidget__;
}
});
}
resolve(tempObj);
});
});
}
},
computed: {
formReadOnly () {
return this.readOnly === 'true' || this.readOnly;
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,169 @@
<template>
<div style="position: relative;" :style="getFlowFormStyle">
<OnlineQueryForm ref="form" v-if="Number.parseInt(formType) === SysOnlineFormType.QUERY"
:operationType="operationType"
:formId="formId"
:params="params"
:key="formKey"
@ready="onFormReady"
/>
<OnlineEditForm ref="form" v-if="Number.parseInt(formType) === SysOnlineFormType.FORM"
:saveOnClose="saveOnClose"
:formId="formId"
:key="formKey"
:params="params"
:operationType="operationType"
:rowData="rowData"
:flowData="flowData"
@close="onClose"
@ready="onFormReady"
/>
<WorkflowForm ref="form" v-if="Number.parseInt(formType) === SysOnlineFormType.FLOW"
:formId="formId"
:key="formKey"
:readOnly="readOnly"
@ready="onFormReady"
/>
<WorkOrderForm ref="form" v-if="Number.parseInt(formType) === SysOnlineFormType.WORK_ORDER"
:entryId="entryId"
:formId="formId"
:key="formKey"
:isPreview="isPreview"
:readOnly="readOnly"
@ready="onFormReady"
/>
<label v-if="closeVisible === '1'" class="page-close-box">
<el-button type="text" @click="onClose(true)" icon="el-icon-close" />
</label>
</div>
</template>
<script>
import OnlineQueryForm from '@/views/onlineForm/formRender/onlineQueryForm.vue';
import OnlineEditForm from '@/views/onlineForm/formRender/onlineEditForm.vue';
import WorkflowForm from '@/views/onlineForm/formRender/workflowForm.vue';
import WorkOrderForm from '@/views/onlineForm/formRender/onlineWorkOrder.vue';
import { SysCustomWidgetOperationType } from '@/staticDict/onlineStaticDict.js';
export default {
props: {
formId: {
type: String,
required: true
},
formType: {
type: [Number, String],
required: true
},
closeVisible: {
type: String,
default: '0'
},
saveOnClose: {
type: String,
default: '1'
},
operationType: {
type: [Number, String],
default: SysCustomWidgetOperationType.ADD
},
params: {
type: Object
},
isPreview: {
type: Boolean,
default: false
},
rowData: {
type: Object
},
flowData: {
type: Object
},
readOnly: {
type: [String, Boolean]
},
entryId: {
type: String
}
},
components: {
OnlineQueryForm,
OnlineEditForm,
WorkflowForm,
WorkOrderForm
},
data () {
return {
formKey: 0,
formConfig: {}
}
},
methods: {
onClose (isSuccess, data) {
if (this.observer != null) {
this.observer.cancel(isSuccess, data);
} else {
this.$router.go(-1);
}
},
setFormData (formData, setFormData, flowData) {
if (this.$refs.form && this.$refs.form.setFormData) this.$refs.form.setFormData(formData, setFormData, flowData);
},
getVariableData (variableList) {
let funGetVariableData = null;
if (Array.isArray(this.$refs.form) && this.$refs.form.length > 0) {
funGetVariableData = this.$refs.form[0].getVariableData;
} else {
if (this.$refs.form != null) funGetVariableData = this.$refs.form.getVariableData;
}
if (typeof funGetVariableData === 'function') {
return funGetVariableData(variableList);
}
},
getFormData () {
let funGetFormData = null;
if (Array.isArray(this.$refs.form) && this.$refs.form.length > 0) {
funGetFormData = this.$refs.form[0].getFormData;
} else {
if (this.$refs.form != null) funGetFormData = this.$refs.form.getFormData;
}
if (typeof funGetFormData === 'function') {
return funGetFormData();
}
},
onFormReady () {
this.$emit('ready');
}
},
computed: {
getFlowFormStyle () {
if (Number.parseInt(this.formType) === this.SysOnlineFormType.FLOW && this.formConfig) {
return {
width: (this.formConfig.width != null && this.formConfig.width !== '') ? this.formConfig.width + 'px' : '100%'
}
} else {
return undefined;
}
}
},
provide () {
return {
preview: () => this.isPreview
}
},
watch: {
formId: {
handler (newValue) {
this.formKey++;
}
}
},
created () {
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,105 @@
import * as StaticDict from '@/staticDict';
import { SysOnlineDictType, SysCustomWidgetOperationType } from '@/staticDict/onlineStaticDict.js';
import { OnlineOperation } from '@/api/onlineController.js';
import ajax from '@/core/http/index.js';
function getTableDictData (sender, dictId, dictParams) {
return new Promise((resolve, reject) => {
let filterDtoList = Object.keys(dictParams).map(key => {
return {
columnName: key,
columnValue: dictParams[key]
}
});
let params = {
dictId: dictId,
filterDtoList: filterDtoList
}
OnlineOperation.listDict(sender, params).then(res => {
resolve(res.data);
}).catch(e => {
reject(e);
});
});
}
function getDictDataByUrl (url, params, dictInfo, methods = 'get') {
return new Promise((resolve, reject) => {
ajax.doUrl(url, methods, params).then(res => {
if (Array.isArray(res.data)) {
resolve(res.data.map(item => {
return {
id: item[dictInfo.keyColumnName],
name: item[dictInfo.valueColumnName],
parentId: item[dictInfo.parentKeyColumnName]
}
}));
} else {
reject();
}
}).catch(e => {
reject(e);
});
});
}
function getUrlDictData (dictInfo, dictParams) {
let url = dictInfo.dictListUrl;
if (url != null && url !== '') {
return getDictDataByUrl(url, dictParams, dictInfo, 'get');
} else {
console.error('字典 [' + dictInfo.dictName + '] url为空');
return Promise.reject();
}
}
/**
* 获取字典数据
* @param {*} dictInfo 字典配置对象
* @param {*} params 获取字典时传入的参数仅对于数据表字典和URL字典有效
* @returns 字典数据
*/
function getDictDataList (sender, dictInfo, dictParams) {
let dictData = JSON.parse(dictInfo.dictDataJson);
switch (dictInfo.dictType) {
case SysOnlineDictType.TABLE:
return getTableDictData(sender, dictInfo.dictId, dictParams);
case SysOnlineDictType.URL:
return getUrlDictData(dictInfo, dictParams);
case SysOnlineDictType.CUSTOM:
if (dictData != null && Array.isArray(dictData.dictData)) {
return Promise.resolve(dictData.dictData);
} else {
return Promise.reject(new Error('获取自定义字典数据错误!'));
}
case SysOnlineDictType.STATIC:
if (dictData != null && dictData.staticDictName != null && StaticDict[dictData.staticDictName] != null) {
return Promise.resolve(StaticDict[dictData.staticDictName].getList());
} else {
return Promise.reject(new Error('未知的静态字典!'));
}
default:
return Promise.reject(new Error('未知的字典类型!'));
}
}
function getOperationPermCode (widget, operation) {
let datasourceVariableName = (widget.datasource || {}).variableName;
let temp = 'view';
switch (operation.type) {
case SysCustomWidgetOperationType.ADD:
case SysCustomWidgetOperationType.EDIT:
case SysCustomWidgetOperationType.DELETE:
temp = 'edit';
break;
default:
temp = 'view';
}
return 'online:' + datasourceVariableName + ':' + temp;
}
export {
getDictDataList,
getDictDataByUrl,
getOperationPermCode
}

View File

@@ -0,0 +1,193 @@
<template>
<el-container class="advance-query-form">
<el-aside width="300px">
<el-card class="base-card" shadow="never" :body-style="{ padding: '0px' }" style="border: none;">
<div slot="header" class="base-card-header">
<span>字典列表</span>
</div>
<el-scrollbar :style="{'height': (getMainContextHeight - 51) + 'px'}" class="custom-scroll">
<el-tree :data="dictList" :props="{label: 'name'}" node-key="variableName" :highlight-current="true"
:current-node-key="(dictList[0] || {}).variableName" @node-click="onDictChange">
<div class="module-node-item" slot-scope="{ data }">
<span style="padding-left: 24px;">{{data.name}}</span>
</div>
</el-tree>
</el-scrollbar>
</el-card>
</el-aside>
<el-main style="margin-left: 15px; background-color: white; padding: 20px;">
<el-form label-width="120px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item v-if="dirtyCount > 0" label="失效缓存数量:">
<span style="color: #F56C6C;">{{dirtyCount}}</span>
</el-form-item>
<el-button slot="operator" type="primary" size="mini" :plain="true"
:disabled="!checkPermCodeExist('formSysDict:fragmentSysDict:reloadCache') || currentDict == null"
@click="onRefreshCacheData">
同步缓存
</el-button>
<el-button slot="operator" type="primary" size="mini"
:disabled="!checkPermCodeExist('formSysDict:fragmentSysDict:add') || currentDict == null"
@click="onAddDictData">
添加数据
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="getCurrentDictData" size="mini" header-cell-class-name="table-header-gray"
:row-style="tableRowStyle"
:height="(getMainContextHeight - 90) + 'px'" row-key="id">
<el-table-column label="ID" prop="id" />
<el-table-column label="字典名称" prop="name">
<template slot-scope="scope">
<span>{{scope.row.name}}</span>
<el-tag v-if="scope.row.dirty" size="mini" effect="dark" type="warning"
style="margin-left: 15px;">
缓存失效
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150px">
<template slot-scope="scope">
<el-button type="text" size="mini" :disabled="!checkPermCodeExist('formSysDict:fragmentSysDict:update')" @click="onUpdateDictDataClick(scope.row)">编辑</el-button>
<el-button type="text" size="mini" :disabled="!checkPermCodeExist('formSysDict:fragmentSysDict:delete')" @click="onDeleteDictDataClick(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-main>
</el-container>
</template>
<script>
import { mapGetters } from 'vuex';
import { treeDataTranslate, findItemFromList } from '@/utils';
/* eslint-disable-next-line */
import { DictionaryController } from '@/api';
import editDict from '@/views/upms/formEditDict';
export default {
name: 'formDictManagement',
data () {
return {
dictList: [
],
dirtyCount: 0,
currentDict: undefined,
currentDictDataList: []
}
},
methods: {
tableRowStyle ({row, rowIndex}) {
if (row.dirty) {
return {
background: '#FFE1E1'
}
}
},
updateDictData () {
this.currentDictDataList = [];
this.dirtyCount = 0;
this.currentDict.listApi(this).then(res => {
let cachedMap = new Map();
if (Array.isArray(res.cachedResultList)) {
res.cachedResultList.forEach(item => {
cachedMap.set(item.id, item);
});
}
if (Array.isArray(res.fullResultList)) {
res.fullResultList.forEach(item => {
let cachedItem = cachedMap.get(item.id);
if (cachedItem == null || cachedItem.name !== item.name) {
item.dirty = true;
this.dirtyCount++;
}
});
}
cachedMap = null;
if (this.currentDict.treeFlag) {
this.currentDictDataList = treeDataTranslate(res.fullResultList, 'id', 'parentId');
} else {
this.currentDictDataList = res.fullResultList;
}
}).catch(e => {});
},
onDictChange (data) {
if (this.currentDict === data) return;
this.currentDict = findItemFromList(this.dictList, (data || {}).variableName, 'variableName');
this.currentDictDataList = [];
if (this.currentDict == null) {
this.$message.error('没有找到相关字典');
return;
}
this.updateDictData();
},
onRefreshCacheData () {
this.$confirm('是否同步缓存?').then(res => {
return this.currentDict.reloadCachedDataApi(this);
}).then(res => {
this.$message.success('同步成功');
this.updateDictData();
}).catch(e => {});
},
onAddDictData () {
this.$dialog.show(`新建字典数据 - [${this.currentDict.name}]`, editDict, {
area: '500px'
}, {
dictInfo: this.currentDict,
dictData: this.currentDict.treeFlag ? this.currentDictDataList : []
}).then(res => {
this.updateDictData();
}).catch(e => {});
},
onUpdateDictDataClick (row) {
this.$dialog.show(`编辑字典数据 - [${this.currentDict.name}]`, editDict, {
area: '500px'
}, {
dictInfo: this.currentDict,
currentData: row,
dictData: this.currentDict.treeFlag ? this.currentDictDataList : []
}).then(res => {
this.updateDictData();
}).catch(e => {});
},
onDeleteDictDataClick (row) {
this.$confirm('是否删除此字典数据?').then(res => {
let params = {};
params[this.currentDict.idKey] = row.id;
return this.currentDict.deleteApi(this, params);
}).then(res => {
this.$message.success('删除成功');
this.updateDictData();
}).catch(e => {});
}
},
computed: {
getCurrentDictData () {
return this.currentDictDataList;
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
this.onDictChange(this.dictList[0]);
}
}
</script>
<style scoped>
>>> .el-tree-node__content {
height: 35px;
}
>>> .el-tree-node__content .is-leaf {
display: none;
}
.module-node-item {
width: 100%;
height: 35px;
line-height: 35px;
}
</style>

View File

@@ -0,0 +1,110 @@
<template>
<el-form ref="form" :model="formData" :rules="rules" label-width="80px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-form-item v-if="dictInfo.treeFlag" label="父字典">
<el-cascader style="width: 100%;"
:options="dictData" v-model="parentPath"
:props="{label: 'name', value: 'id'}" placeholder="请选择所属父字典"
:clearable="true" :change-on-select="true"
@change="onParentChange"
/>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="字典名称" clearable />
</el-form-item>
</el-row>
<el-row type="flex" justify="end" class="dialog-btn-layer">
<el-button size="mini" @click="onCancel(false)" >取消</el-button>
<el-button type="primary" size="mini" @click="onSubmit">确定</el-button>
</el-row>
</el-form>
</template>
<script>
import { findTreeNodePath } from '@/utils';
export default {
name: 'DictEdit',
props: {
dictInfo: {
type: Object,
required: true
},
currentData: {
type: Object,
default: undefined
},
dictData: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
parentPath: [],
formData: {
name: undefined,
id: undefined
},
rules: {
name: [{required: true, message: '字典数据名称不能为空', trigger: 'blur'}]
}
}
},
methods: {
onParentChange (values) {
if (Array.isArray(values) && values.length > 0) {
this.formData.parentId = values[values.length - 1];
} else {
this.formData.parentId = undefined;
}
},
onCancel (isSuccess = false) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
this.$refs.form.validate((valid) => {
if (valid) {
let params = {};
params[this.dictInfo.variableName + 'Dto'] = {};
params[this.dictInfo.variableName + 'Dto'][this.dictInfo.nameKey] = this.formData.name;
params[this.dictInfo.variableName + 'Dto'][this.dictInfo.parentKey] = this.formData.parentId;
if (this.formData.id == null) {
this.dictInfo.addApi(this, params).then(res => {
this.$message.success('操作成功');
this.onCancel(true);
}).catch(e => {
});
} else {
params[this.dictInfo.variableName + 'Dto'][this.dictInfo.idKey] = this.formData.id;
this.dictInfo.updateApi(this, params).then(res => {
this.$message.success('操作成功');
this.onCancel(true);
}).catch(e => {
});
}
}
});
}
},
mounted () {
if (this.currentData != null) {
this.formData.id = this.currentData.id;
this.formData.name = this.currentData.name;
if (this.dictInfo.treeFlag && this.currentData.parentId != null && this.currentData.parentId !== '') {
this.formData.parentId = this.currentData.parentId;
this.parentPath = findTreeNodePath(this.dictData, this.formData.parentId, 'id');
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,243 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditSysDataPerm" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="120px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="数据权限名称" prop="SysDataPerm.dataPermName">
<el-input class="input-item" v-model="formData.SysDataPerm.dataPermName"
:clearable="true" placeholder="显示名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="过滤规则" prop="SysDataPerm.ruleType">
<el-select class="input-item" v-model="formData.SysDataPerm.ruleType" :clearable="true"
placeholder="过滤规则" :loading="formEditSysDataPerm.ruleType.impl.loading"
@visible-change="onRuleTypeVisibleChange"
@change="onRuleTypeValueChange">
<el-option v-for="item in formEditSysDataPerm.ruleType.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-card shadow="never">
<div slot="header" class="card-header">
<span>部门列表</span>
<el-input size="mini" v-model="deptNameFilter" placeholder="输入部门名称过滤" style="width: 250px;" clearable suffix-icon="el-icon-search" />
</div>
<el-scrollbar style="height: 250px;" wrap-class="scrollbar_dropdown__wrap">
<el-tree ref="deptTree" :data="deptTree" show-checkbox node-key="id" default-expand-all
:check-strictly="true" :props="{...deptProps, disabled: () => {return (formData.SysDataPerm.ruleType !== SysDataPermType.CUSTOM_DEPT_AND_CHILD && formData.SysDataPerm.ruleType !== SysDataPermType.CUSTOM_DEPT)}}" :filter-node-method="filterDeptNode" />
</el-scrollbar>
</el-card>
</el-col>
</el-row>
<el-col :span="24" style="margin-top: 20px;">
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true" @click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onUpdateClick()"
:disabled="!(checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:add') || checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:update'))">
保存
</el-button>
</el-row>
</el-col>
</el-form>
</div>
</template>
<script>
import { treeDataTranslate } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController, SysDataPermController } from '@/api';
export default {
name: 'formEditSysDataPerm',
props: {
dataPermId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachedPageChildMixin],
data () {
return {
deptTree: [],
deptNameFilter: undefined,
deptProps: {
label: 'name'
},
formData: {
SysDataPerm: {
dataPermId: undefined,
dataPermName: undefined,
ruleType: undefined,
deptIdListString: undefined,
createUserId: undefined,
createUsername: undefined
}
},
rules: {
'SysDataPerm.dataPermName': [
{required: true, message: '请输入数据权限名称', trigger: 'blur'}
],
'SysDataPerm.ruleType': [
{required: true, message: '请选择过滤规则', trigger: 'blur'}
]
},
formEditSysDataPerm: {
formFilter: {
},
formFilterCopy: {
},
ruleType: {
impl: new DropdownWidget(this.loadRuleTypeDropdownList)
},
isInit: false
}
}
},
methods: {
filterDeptNode (value, data) {
if (!value) return true;
return data.deptName ? data.deptName.indexOf(value) !== -1 : true;
},
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 过滤规则下拉数据获取函数
*/
loadRuleTypeDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDataPermType(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 过滤规则下拉框显隐
*/
onRuleTypeVisibleChange (show) {
this.formEditSysDataPerm.ruleType.impl.onVisibleChange(show).catch(e => {});
},
/**
* 过滤规则选中值改变
*/
onRuleTypeValueChange (value) {
},
/**
* 部门列表数据获取函数
*/
loadDeptList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDept(this, params).then(res => {
this.deptTree = treeDataTranslate(res.getList(), 'id');
if (Array.isArray(this.formData.SysDataPerm.dataPermDeptList)) {
this.$refs.deptTree.setCheckedKeys(this.formData.SysDataPerm.dataPermDeptList.map((item) => {
return item.deptId;
}));
}
}).catch(e => {
reject(e);
});
});
},
/**
* 更新编辑数据权限
*/
refreshFormEditSysDataPerm (reloadData = false) {
this.formEditSysDataPerm.ruleType.impl.onVisibleChange(true).catch(e => {});
this.formEditSysDataPerm.isInit = true;
},
/**
* 编辑
*/
onUpdateClick () {
this.$refs.formEditSysDataPerm.validate((valid) => {
if (!valid) return;
let params = {
sysDataPermDto: {
dataPermId: this.dataPermId,
ruleType: this.formData.SysDataPerm.ruleType,
dataPermName: this.formData.SysDataPerm.dataPermName
}
};
if (this.formData.SysDataPerm.ruleType === this.SysDataPermType.CUSTOM_DEPT_AND_CHILD ||
this.formData.SysDataPerm.ruleType === this.SysDataPermType.CUSTOM_DEPT) {
let deptList = this.$refs.deptTree.getCheckedKeys();
if (deptList.length <= 0) {
this.$message.error('请选择数据权限部门');
return;
}
params.deptIdListString = Array.isArray(deptList) ? deptList.join(',') : undefined;
}
if (this.dataPermId == null) {
SysDataPermController.add(this, params).then(res => {
this.$message.success('添加成功');
this.onCancel(true);
}).catch(e => {});
} else {
SysDataPermController.update(this, params).then(res => {
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {});
}
});
},
/**
* 获取数据权限详细信息
*/
loadSysDataPermData () {
return new Promise((resolve, reject) => {
if (this.dataPermId == null) {
resolve();
} else {
let params = {
dataPermId: this.dataPermId
};
SysDataPermController.view(this, params).then(res => {
this.formData.SysDataPerm = {...res.data};
resolve();
}).catch(e => {
reject();
});
}
});
},
initFormData () {
},
formInit () {
let loadAllDatasource = [
this.loadSysDataPermData()
];
Promise.all(loadAllDatasource).then(res => {
this.initFormData();
this.refreshFormEditSysDataPerm();
this.loadDeptList();
}).catch(e => {});
}
},
mounted () {
this.formInit();
},
watch: {
deptNameFilter (val) {
this.$refs.deptTree.filter(val);
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,201 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditSysDept" :model="formData" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="所属部门" prop="SysDept.parentId">
<el-cascader class="input-item" v-model="formEditSysDept.parentId.value" :clearable="true"
placeholder="所属部门" :loading="formEditSysDept.parentId.impl.loading" :props="{value: 'id', label: 'name', checkStrictly: true}"
@visible-change="onParentIdVisibleChange" :options="formEditSysDept.parentId.impl.dropdownList"
@change="onParentIdValueChange">
</el-cascader>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="部门名称" prop="SysDept.deptName">
<el-input class="input-item" v-model="formData.SysDept.deptName"
:clearable="true" placeholder="部门名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="显示顺序" prop="SysDept.showOrder">
<el-input-number class="input-item" v-model="formData.SysDept.showOrder"
:clearable="true" controls-position="right" placeholder="显示顺序" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onUpdateClick()"
:disabled="!(checkPermCodeExist('formSysDept:fragmentSysDept:update') || checkPermCodeExist('formSysDept:fragmentSysDept:add'))">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findTreeNodePath } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDeptController, DictionaryController } from '@/api';
export default {
name: 'formEditSysDept',
props: {
deptId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachedPageChildMixin],
data () {
return {
formData: {
SysDept: {
deptId: undefined,
deptName: undefined,
showOrder: undefined,
parentId: undefined,
deletedFlag: undefined
}
},
rules: {
'SysDept.deptName': [
{required: true, message: '请输入部门名称', trigger: 'blur'}
],
'SysDept.showOrder': [
{required: true, message: '请输入显示顺序', trigger: 'blur'}
]
},
formEditSysDept: {
formFilter: {
},
formFilterCopy: {
},
parentId: {
impl: new DropdownWidget(this.loadParentIdDropdownList, true, 'id'),
value: []
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 所属部门下拉数据获取函数
*/
loadParentIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDept(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属部门下拉框显隐
*/
onParentIdVisibleChange (show) {
this.formEditSysDept.parentId.impl.onVisibleChange(show).catch(e => {});
},
/**
* 所属部门选中值改变
*/
onParentIdValueChange (value) {
},
/**
* 更新编辑用户
*/
refreshFormEditSysDept (reloadData = false) {
this.formEditSysDept.parentId.impl.onVisibleChange(true).then(res => {
if (!this.formEditSysDept.isInit) {
this.formEditSysDept.parentId.value = findTreeNodePath(
this.formEditSysDept.parentId.impl.dropdownList, this.formData.SysDept.parentId, 'id');
}
this.formEditSysDept.isInit = true;
});
},
/**
* 编辑
*/
onUpdateClick () {
this.$refs.formEditSysDept.validate((valid) => {
if (!valid) return;
let params = {
sysDeptDto: {
deptName: this.formData.SysDept.deptName,
showOrder: this.formData.SysDept.showOrder,
parentId: Array.isArray(this.formEditSysDept.parentId.value) ? this.formEditSysDept.parentId.value[this.formEditSysDept.parentId.value.length - 1] : undefined,
deptId: this.deptId
}
};
if (this.isEdit) {
SysDeptController.update(this, params).then(res => {
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {});
} else {
SysDeptController.add(this, params).then(res => {
this.$message.success('新建成功');
this.onCancel(true);
}).catch(e => {});
}
});
},
/**
* 获取部门管理详细信息
*/
loadSysDeptData () {
if (!this.isEdit) return;
let params = {
deptId: this.deptId
};
return new Promise((resolve, reject) => {
SysDeptController.view(this, params).then(res => {
this.formData.SysDept = {...res.data};
resolve();
}).catch(e => {
reject();
});
});
},
initFormData () {
},
formInit () {
let loadAllDatasource = [
this.loadSysDeptData()
];
Promise.all(loadAllDatasource).then(res => {
this.initFormData();
this.refreshFormEditSysDept();
}).catch(e => {});
}
},
computed: {
isEdit () {
return this.deptId != null;
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,108 @@
<template>
<el-form ref="form" :model="formData" :rules="rules" label-width="110px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20" class="full-width-input">
<el-col :span="24" >
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="formData.menuName" placeholder="菜单名称" clearable />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="显示顺序" prop="showOrder">
<el-input-number v-model="formData.showOrder" controls-position="right"
:min="1" :max="99999" placeholder="请输入显示顺序"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<!-- 弹窗按钮 -->
<el-row type="flex" justify="end" class="dialog-btn-layer mt20">
<el-button size="mini" @click="onCancel(false)" >取消</el-button>
<el-button type="primary" size="mini" @click="onSubmit">确定</el-button>
</el-row>
</el-form>
</template>
<script>
import { SystemController } from '@/api';
export default {
props: {
columnId: {
type: String
},
columnName: {
type: String
},
showOrder: {
type: Number
}
},
data () {
return {
// 是否自动用上级菜单的名称过滤权限字列表当这个开关打开后会使用getAutoFilterString返回的字符串当做过滤字符串
autoFilter: false,
permCodeNameFilter: undefined,
allowParentList: [],
formData: {
menuId: this.columnId,
parentId: undefined,
menuName: this.columnName,
showOrder: this.showOrder,
menuType: this.SysMenuType.DIRECTORY,
icon: undefined,
formRouterName: undefined
},
rules: {
menuName: [{required: true, message: '请输入栏目名称', trigger: 'blur'}],
showOrder: [{required: true, message: '请输入栏目显示顺序', trigger: 'blur'}]
}
};
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
return new Promise((resolve, reject) => {
this.$refs['form'].validate((valid) => {
if (valid) {
let params = {};
params.sysMenuDto = {...this.formData};
if (this.isEdit) {
SystemController.updateMenu(this, params).then(res => {
resolve(res);
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {
reject(e);
});
} else {
SystemController.addMenu(this, params).then(res => {
resolve(res);
this.$message.success('添加成功');
this.onCancel(true);
}).catch(e => {
reject(e);
});
}
} else {
reject();
}
});
});
},
initData () {
}
},
computed: {
isEdit () {
return this.formData.menuId != null;
}
},
mounted () {
this.initData();
}
};
</script>

View File

@@ -0,0 +1,400 @@
<template>
<el-form ref="form" :model="formData" :rules="rules" label-width="110px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20" class="full-width-input">
<el-col :span="12">
<el-form-item label="上级菜单">
<el-cascader :options="menuTree" v-model="parentMenuPath" :props="menuProps" placeholder="选择父菜单"
:disabled="!canEditParent || isEdit" :clearable="true" :change-on-select="true" size="mini"
@change="onParentMenuChange" />
</el-form-item>
</el-col>
<el-col :span="12" >
<el-form-item label="菜单名称" prop="menuName">
<el-input v-model="formData.menuName" placeholder="菜单名称" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单类型" prop="menuType">
<el-select v-model="formData.menuType" :disabled="isEdit" placeholder="菜单类型" @change="onMenuTypeChange">
<el-option v-for="item in getValidMenuType" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示顺序" prop="showOrder">
<el-input-number v-model="formData.showOrder" controls-position="right"
:min="1" :max="99999" placeholder="请输入显示顺序"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="绑定类型">
<el-select v-model="formData.bindType" plaaceholder="菜单绑定类型"
:disabled="formData.menuType !== 1 || isEdit"
@change="onBindTypeChange">
<el-option v-for="item in SysMenuBindType.getList()" :key="item.id"
:label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.bindType === SysMenuBindType.ROUTER">
<el-form-item label="菜单路由">
<el-input v-model="formData.formRouterName" placeholder="菜单路由"
:disabled="formData.menuType !== 1" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.bindType === SysMenuBindType.ONLINE_FORM">
<el-form-item label="在线表单" prop="onlineFormId">
<el-cascader v-model="onlineFormPath" :options="formTreeData" filterable
:clearable="true" placeholder="选择菜单绑定的在线表单"
:props="{value: 'id', label: 'name'}"
@change="onOnlineFormChange" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="formData.bindType === SysMenuBindType.WORK_ORDER">
<el-form-item label="工作流" prop="onlineFlowEntryId">
<el-cascader v-model="onlineFlowPath" :options="entryTreeData" filterable
:clearable="true" placeholder="选择菜单绑定的工单"
:props="{value: 'id', label: 'name'}"
@change="onOnlineEntryChange" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单图标" prop="icon">
<icon-select v-model="formData.icon" :height="28" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-card shadow="never">
<div slot="header" class="card-header">
<span>权限字列表</span>
<el-input size="mini" v-model="permCodeNameFilter" placeholder="输入权限字名称过滤" style="width: 250px;" clearable suffix-icon="el-icon-search" />
</div>
<el-scrollbar style="height: 210px;" wrap-class="scrollbar_dropdown__wrap">
<el-tree ref="permCodeTree" :check-strictly="true"
v-show="formData.menuType && formData.bindType !== SysMenuBindType.ONLINE_FORM"
:props="treeProps" node-key="permCodeId" :default-expanded-keys="defaultExpandedKeys"
show-checkbox :data="getPermCodeTree" :filter-node-method="filterPermCodeNode"></el-tree>
</el-scrollbar>
</el-card>
</el-col>
</el-row>
<!-- 弹窗按钮 -->
<el-row type="flex" justify="end" class="dialog-btn-layer mt20">
<el-button size="mini" @click="onCancel(false)" >取消</el-button>
<el-button type="primary" size="mini" @click="onSubmit"
:disabled="!(checkPermCodeExist('formSysMenu:fragmentSysMenu:add') || checkPermCodeExist('formSysMenu:fragmentSysMenu:update'))">
确定
</el-button>
</el-row>
</el-form>
</template>
<script>
// eslint-disable-next-line no-unused-vars
import { treeDataTranslate, findTreeNodePath, findTreeNode, findItemFromList } from '@/utils';
import { SystemController } from '@/api';
import { OnlinePageController } from '@/api/onlineController.js';
import { FlowOperationController } from '@/api/flowController.js';
import IconSelect from '@/components/IconSelect/index.vue';
export default {
props: {
menuId: {
type: String
},
parentId: {
type: String
},
menuList: {
type: Array,
default: undefined
},
rowData: {
type: Object,
default: undefined
}
},
components: {
IconSelect
},
data () {
return {
// 是否自动用上级菜单的名称过滤权限字列表当这个开关打开后会使用getAutoFilterString返回的字符串当做过滤字符串
autoFilter: false,
permCodeNameFilter: undefined,
allowParentList: [],
formData: {
menuId: undefined,
parentId: undefined,
menuName: undefined,
showOrder: undefined,
menuType: undefined,
icon: undefined,
bindType: this.SysMenuBindType.ROUTER,
onlineFormId: undefined,
onlineFlowEntryId: undefined,
formRouterName: undefined
},
onlineFormPath: [],
formTreeData: [],
onlineFlowPath: [],
entryTreeData: [],
menuProps: {
label: 'menuName',
value: 'menuId'
},
parentMenuType: undefined,
parentMenuPath: [],
menuTree: [],
permCodeList: [],
defaultExpandedKeys: [],
rules: {
menuName: [{required: true, message: '请输入菜单名称', trigger: 'blur'}],
showOrder: [{required: true, message: '请输入菜单显示顺序', trigger: 'blur'}],
onlineFormId: [{required: true, message: '请选择菜单绑定的在线表单', trigger: 'blur'}],
onlineFlowEntryId: [{required: true, message: '请选择菜单绑定的工单', trigger: 'blur'}],
formRouterName: [{required: true, message: '请输入菜单路由名称', trigger: 'blur'}]
},
treeProps: {
label: 'showName'
}
};
},
methods: {
getAutoFilterString () {
let node = findTreeNode(this.menuTree, this.parentMenuPath[this.parentMenuPath.length - 1], 'menuId');
return node ? node.menuName : undefined;
},
onMenuTypeChange (value) {
if (this.autoFilter && value === this.SysMenuType.BUTTON && (this.permCodeNameFilter == null || this.permCodeNameFilter === '')) {
this.permCodeNameFilter = this.getAutoFilterString();
}
},
filterPermCodeNode (value, data) {
if (!value) return true;
if (data.showName.indexOf(value) !== -1) {
this.allowParentList.push(data.permCodeId);
return true;
} else {
return this.allowParentList.indexOf(data.parentId) !== -1;
}
},
onParentMenuChange (value, isInit) {
if (!isInit) this.formData.menuType = undefined;
this.parentMenuType = undefined;
if (Array.isArray(value) && value.length > 0) {
let node = findTreeNode(this.menuTree, value[value.length - 1], 'menuId');
if (node) this.parentMenuType = node.menuType;
}
},
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
return new Promise((resolve, reject) => {
this.$refs['form'].validate((valid) => {
if (valid) {
let params = {};
params.sysMenuDto = {...this.formData};
if (this.formData.bindType === this.SysMenuBindType.ROUTER) {
params.sysMenuDto.onlineFormId = undefined;
params.sysMenuDto.onlineFlowEntryId = undefined;
}
if (this.parentMenuPath.length > 0) {
params.sysMenuDto.parentId = this.parentMenuPath[this.parentMenuPath.length - 1];
}
if ([this.SysMenuType.MENU, this.SysMenuType.BUTTON, this.SysMenuType.FRAGMENT].indexOf(params.sysMenuDto.menuType) !== -1) {
let tempList = this.$refs.permCodeTree.getHalfCheckedKeys();
tempList = tempList.concat(this.$refs.permCodeTree.getCheckedKeys());
params.permCodeIdListString = tempList.join(',');
}
if (this.isEdit) {
SystemController.updateMenu(this, params).then(res => {
resolve(res);
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {
reject(e);
});
} else {
SystemController.addMenu(this, params).then(res => {
resolve(res);
this.$message.success('添加成功');
this.onCancel(true);
}).catch(e => {
reject(e);
});
}
} else {
reject();
}
});
});
},
formatMenuTree () {
this.menuTree = [];
if (Array.isArray(this.menuList)) {
this.menuTree = this.menuList.filter((item) => {
return item.menuType !== this.SysMenuType.BUTTON && item.menuId !== this.formData.menuId;
});
}
this.menuTree = treeDataTranslate(this.menuTree, 'menuId', 'parentId');
},
onBindTypeChange (value) {
this.formData.onlineFormId = undefined;
this.formData.formRouterName = undefined;
this.formData.onlineFlowEntryId = undefined;
},
onOnlineFormChange (values) {
this.formData.onlineFormId = values[1];
},
onOnlineEntryChange (values) {
this.formData.onlineFlowEntryId = values[0];
this.formData.onlineFormId = values[1];
},
loadPageAndForms () {
OnlinePageController.listAllPageAndForm(this, {}).then(res => {
let formList = res.data.formList;
let pageList = res.data.pageList;
if (!Array.isArray(formList) || !Array.isArray(pageList)) {
this.formTreeData = [];
return;
}
this.formTreeData = pageList.map(page => {
let children = formList.filter(form => {
return form.pageId === page.pageId && form.formKind === this.SysOnlineFormKind.PAGE && form.formType === this.SysOnlineFormType.QUERY;
}).map(form => {
return {
id: form.formId,
name: form.formName
}
});
return {
id: page.pageId,
name: page.pageName,
disabled: !page.published,
children
}
});
if (this.formData.onlineFormId) {
this.onlineFormPath = findTreeNodePath(this.formTreeData, this.formData.onlineFormId, 'id');
}
}).catch(e => {});
},
loadFlowEntryForms () {
FlowOperationController.listFlowEntryForm(this, {}).then(res => {
if (Array.isArray(res.data)) {
this.entryTreeData = res.data.map(entry => {
let formList = [];
if (Array.isArray(entry.formList)) {
formList = entry.formList.filter(form => form.formType === this.SysOnlineFormType.WORK_ORDER).map(form => {
return {
id: form.formId,
name: form.formName
}
});
}
if (formList.length > 0) {
return {
id: entry.entryId,
name: entry.processDefinitionName,
children: formList
}
}
return null;
}).filter(entry => entry != null);
}
if (this.formData.onlineFlowEntryId) {
this.onlineFlowPath = [this.formData.onlineFlowEntryId, this.formData.onlineFormId];
}
}).catch(e => {});
},
initData () {
this.defaultExpandedKeys = [];
this.formatMenuTree();
this.parentMenuPath = findTreeNodePath(this.menuTree, this.formData.parentId, 'menuId');
this.onParentMenuChange(this.parentMenuPath, true);
this.onMenuTypeChange(this.formData.menuType);
SystemController.getPermCodeList(this, {}).then(res => {
this.permCodeList = res.data;
if (Array.isArray(this.formData.permCodeIdList) && this.formData.permCodeIdList.length > 0) {
let tempList = [];
this.permCodeList.forEach((item) => {
if (findItemFromList(this.formData.permCodeIdList, item.permCodeId) != null) {
tempList.push(item.permCodeId);
}
});
this.defaultExpandedKeys = tempList;
this.$refs.permCodeTree.setCheckedKeys(tempList);
this.$nextTick(() => {
this.allowParentList = [];
if (this.permCodeNameFilter != null && this.permCodeNameFilter !== '') this.$refs.permCodeTree.filter(this.permCodeNameFilter);
});
}
}).catch(e => {});
this.loadPageAndForms();
this.loadFlowEntryForms();
}
},
computed: {
getValidMenuType () {
let allList = this.SysMenuType.getList();
if (this.parentMenuType == null) {
return allList.filter((item) => {
return [this.SysMenuType.MENU, this.SysMenuType.DIRECTORY].indexOf(item.id) !== -1;
});
} else {
return allList.filter((item) => {
switch (Number.parseInt(this.parentMenuType)) {
case this.SysMenuType.DIRECTORY: return [this.SysMenuType.MENU, this.SysMenuType.DIRECTORY].indexOf(item.id) !== -1;
case this.SysMenuType.MENU: return [this.SysMenuType.FRAGMENT, this.SysMenuType.BUTTON].indexOf(item.id) !== -1;
case this.SysMenuType.FRAGMENT: return item.id === this.SysMenuType.BUTTON;
default: return false;
}
});
}
},
isEdit () {
return this.formData.menuId != null;
},
// 判断是否新建一个目录
isNew () {
return this.formData.parentId == null && this.formData.menuId == null;
},
canEditParent () {
return this.parentId == null;
},
getPermCodeTree () {
if (this.permCodeList != null) {
return treeDataTranslate(this.permCodeList, 'permCodeId', 'parentId');
} else {
return [];
}
}
},
mounted () {
if (this.rowData != null) {
this.formData = {...this.formData, ...this.rowData};
if (this.formData.onlineFlowEntryId != null) {
this.formData.bindType = this.SysMenuBindType.WORK_ORDER;
} else {
this.formData.bindType = this.formData.onlineFormId == null ? this.SysMenuBindType.ROUTER : this.SysMenuBindType.ONLINE_FORM;
}
if (Array.isArray(this.formData.sysMenuPermCodeList)) {
this.formData.permCodeIdList = this.formData.sysMenuPermCodeList.map(item => item.permCodeId);
}
}
if (this.parentId != null) this.formData.parentId = this.parentId;
this.initData();
},
watch: {
permCodeNameFilter (val) {
this.allowParentList = [];
this.$refs.permCodeTree.filter(val);
}
}
};
</script>

View File

@@ -0,0 +1,168 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formCreatePerm" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="权限名称" prop="SysPerm.permName">
<el-input class="input-item" v-model="formData.SysPerm.permName"
:clearable="true" placeholder="权限名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="所属模块" prop="SysPerm.moduleId">
<el-cascader class="input-item" :options="permModuleList" v-model="formData.SysPerm.moduleId"
placeholder="选择所属模块" :clearable="true" size="mini" :props="{value: 'moduleId', label: 'moduleName'}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="关联的url" prop="SysPerm.url">
<el-input class="input-item" v-model="formData.SysPerm.url"
:clearable="true" placeholder="关联的url" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="显示顺序" prop="SysPerm.showOrder">
<el-input-number class="input-item" v-model="formData.SysPerm.showOrder"
:clearable="true" controls-position="right" placeholder="权限在当前模块下的顺序" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onAddClick()"
:disabled="!(checkPermCodeExist('formSysPerm:fragmentSysPerm:updatePerm') || checkPermCodeExist('formSysPerm:fragmentSysPerm:addPerm'))">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findTreeNodePath } from '@/utils';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController } from '@/api';
export default {
name: 'formEditSysPerm',
props: {
permId: {
default: undefined
},
moduleId: {
default: undefined
},
rowData: {
type: Object
},
currentPermGroupId: String,
permModuleList: {
type: Array,
default: () => {
return [];
}
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachedPageChildMixin],
data () {
return {
formData: {
SysPerm: {
permId: undefined,
moduleId: this.currentPermGroupId,
permName: undefined,
url: undefined,
showOrder: undefined,
deletedFlag: undefined
}
},
rules: {
'SysPerm.permName': [
{required: true, message: '请输入权限名称', trigger: 'blur'}
],
'SysPerm.url': [
{required: true, message: '请输入关联的url', trigger: 'blur'}
],
'SysPerm.showOrder': [
{required: true, message: '请输入显示顺序', trigger: 'blur'}
]
},
formCreatePerm: {
formFilter: {
},
formFilterCopy: {
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 更新新建权限
*/
refreshFormCreatePerm (reloadData = false) {
if (!this.formCreatePerm.isInit) {
this.formData.SysPerm.moduleId = findTreeNodePath(this.permModuleList, this.formData.SysPerm.moduleId, 'moduleId');
}
this.formCreatePerm.isInit = true;
},
/**
* 新增
*/
onAddClick () {
this.$refs.formCreatePerm.validate((valid) => {
if (!valid) return;
let params = {
sysPermDto: {
permId: this.permId,
showOrder: this.formData.SysPerm.showOrder,
moduleId: Array.isArray(this.formData.SysPerm.moduleId) ? this.formData.SysPerm.moduleId[this.formData.SysPerm.moduleId.length - 1] : undefined,
url: this.formData.SysPerm.url,
permName: this.formData.SysPerm.permName
}
};
if (this.isEdit) {
SystemController.updatePerm(this, params).then(res => {
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {});
} else {
SystemController.addPerm(this, params).then(res => {
this.$message.success('新增成功');
this.onCancel(true);
}).catch(e => {});
}
});
},
initFormData () {
if (this.rowData != null) this.formData.SysPerm = {...this.formData.SysPerm, ...this.rowData};
},
formInit () {
this.initFormData();
this.refreshFormCreatePerm();
}
},
computed: {
isEdit () {
return this.permId != null;
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,221 @@
<template>
<el-form ref="form" :model="formData" :rules="rules" label-width="110px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20" class="full-width-input">
<el-col :span="24">
<el-form-item label="所属权限字">
<el-cascader :options="permCodeTree" v-model="parentPermCodePath" :props="permCodeProps" filterable
:disabled="formData.permCodeId != null || formData.parenId == null" placeholder="选择父权限字" :clearable="true" :change-on-select="true" size="mini" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="权限字名称" prop="showName">
<el-input v-model="formData.showName" placeholder="权限字名称" clearable ></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="权限字标识" prop="permCode">
<el-input v-model="formData.permCode" placeholder="权限字标识" clearable ></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="权限字类型" prop="permCode">
<el-select v-model="formData.permCodeType" placeholder="权限字类型" :disabled="true">
<el-option v-for="item in SysPermCodeType.getList()" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示顺序" prop="showOrder">
<el-input-number v-model="formData.showOrder" controls-position="right"
:min="1" :max="99999" placeholder="请输入显示顺序"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="24">
<el-card shadow="never">
<div slot="header" class="card-header">
<span>权限列表</span>
<el-input size="mini" v-model="permNameFilter" placeholder="输入权限名称过滤" style="width: 250px;" clearable suffix-icon="el-icon-search" />
</div>
<el-scrollbar style="height: 215px;" wrap-class="scrollbar_dropdown__wrap">
<el-tree ref="permTree" :data="formData.permCodeType === SysPermCodeType.FORM ? [] : getPermTree" :props="treeProps" show-checkbox
node-key="id" empty-text="暂无权限资源" :filter-node-method="filterPermNode"
:default-expanded-keys="defaultExpandedKeys">
<div slot-scope="{ data }" style="display: flex; justify-content: space-between; width: 100%">
<span>{{ data.name }}</span>
<span style="margin-right: 10px;">{{ data.url }}</span>
</div>
</el-tree>
</el-scrollbar>
</el-card>
</el-col>
</el-row>
<!-- 弹窗按钮 -->
<el-row type="flex" justify="end" class="dialog-btn-layer mt20">
<el-button size="mini" @click="onCancel(false)" >取消</el-button>
<el-button type="primary" size="mini" @click="onSubmit"
:disabled="!(checkPermCodeExist('formSysPermCode:fragmentSysPermCode:add') || checkPermCodeExist('formSysPermCode:fragmentSysPermCode:update'))">
确定
</el-button>
</el-row>
</el-form>
</template>
<script>
import { treeDataTranslate, findTreeNodePath } from '@/utils'
import { SystemController } from '@/api'
export default {
props: {
permCodeTree: {
type: Array,
default: function () {
return [];
}
},
permCodeType: {
type: Number,
default: undefined
},
rowData: {
type: Object
}
},
data () {
return {
permNameFilter: undefined,
allowParentList: [],
formData: {
permCodeId: undefined,
parentId: undefined,
permCode: undefined,
permCodeType: this.permCodeType || this.SysPermCodeType.FORM,
showName: undefined,
showOrder: undefined
},
parentPermCodePath: [],
permList: [],
defaultExpandedKeys: [],
treeProps: {
label: 'name',
isLeaf: function (data, node) {
return data.isPerm;
}
},
permCodeProps: {
label: 'showName',
value: 'permCodeId'
},
rules: {
showName: [{required: true, message: '权限字名称不能为空', trigger: 'blur'}],
permCode: [{required: true, message: '权限字标识不能为空', trigger: 'blur'}],
showOrder: [{required: true, message: '请输入权限字显示顺序', trigger: 'blur'}],
permCodeType: [{required: true, message: '请选择权限字类型', trigger: 'blur'}]
}
}
},
methods: {
filterPermNode (value, data) {
if (!value) return true;
if (data.name.indexOf(value) !== -1) {
this.allowParentList.push(data.id);
return true;
} else {
return this.allowParentList.indexOf(data.parentId) !== -1;
}
},
getTreeLeafKeys () {
let selectPermNodeList = this.$refs.permTree.getCheckedNodes();
let tempList = [];
selectPermNodeList.forEach((item) => {
if (item.isPerm) {
tempList.push(item.id);
}
});
return tempList;
},
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
return new Promise((resolve, reject) => {
this.$refs['form'].validate((valid) => {
if (valid) {
let selectedPermList = this.getTreeLeafKeys();
let params = {};
params.sysPermCodeDto = {...this.formData};
delete params.sysPermCodeDto.children;
params.sysPermCodeDto.permCodeType = (this.permCodeType == null) ? this.SysPermCodeType.FORM : this.permCodeType;
if (this.parentPermCodePath.length > 0) {
params.sysPermCodeDto.parentId = this.parentPermCodePath[this.parentPermCodePath.length - 1];
}
params.permIdListString = selectedPermList.join(',');
if (params.sysPermCodeDto.permCodeId != null) {
SystemController.updatePermCode(this, params).then(res => {
resolve(res);
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {
reject(e);
});
} else {
SystemController.addPermCode(this, params).then(res => {
resolve(res);
this.$message.success('添加成功');
this.onCancel(true);
}).catch(e => {
reject(e);
});
}
} else {
reject();
}
});
});
},
initData () {
SystemController.getAllPermList(this, {}).then(res => {
res.data.forEach((item) => {
item.id = item.id + '';
item.parentId = item.parentId + '';
});
this.permList = res.data;
this.defaultExpandedKeys = this.formData.permIdList;
if (Array.isArray(this.formData.permIdList)) {
this.$refs.permTree.setCheckedKeys(this.formData.permIdList, true);
}
}).catch(e => {});
}
},
computed: {
getPermTree () {
return treeDataTranslate(this.permList.map((item) => {
return {...item};
}), 'id', 'parentId');
}
},
mounted () {
if (this.rowData != null) {
this.formData = {...this.formData, ...this.rowData};
if (Array.isArray(this.formData.sysPermCodePermList)) {
this.formData.permIdList = this.formData.sysPermCodePermList.map(item => item.permId);
}
if (this.formData.parentId != null && this.permCodeTree != null && Array.isArray(this.permCodeTree)) {
this.parentPermCodePath = findTreeNodePath(this.permCodeTree, this.formData.parentId, 'permCodeId');
} else {
this.parentPermCodePath = [];
}
}
this.initData();
},
watch: {
permNameFilter (val) {
this.allowParentList = [];
this.$refs.permTree.filter(val);
}
}
}
</script>

View File

@@ -0,0 +1,184 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formCreatePermModule" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="120px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="模块名称" prop="SysPermModule.moduleName">
<el-input class="input-item" v-model="formData.SysPermModule.moduleName"
:clearable="true" placeholder="权限模块名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="模块类型">
<el-select class="input-item" v-model="formData.SysPermModule.moduleType"
placeholder="模块类型" :clearable="true" size="mini" :disabled="isEdit">
<el-option v-for="item in SysPermModuleType.getList()" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="所属模块">
<el-cascader class="input-item" :options="getPermGroupTree" v-model="formData.SysPermModule.parentId"
placeholder="选择所属模块" :clearable="true" size="mini"
:props="{value: 'moduleId', label: 'moduleName', checkStrictly: true}" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="显示顺序" prop="SysPermModule.showOrder">
<el-input-number class="input-item" v-model="formData.SysPermModule.showOrder"
:clearable="true" controls-position="right" placeholder="权限模块在当前层级下的顺序" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true" @click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onAddClick()"
:disabled="!(checkPermCodeExist('formSysPerm:fragmentSysPerm:addPermModule') || checkPermCodeExist('formSysPerm:fragmentSysPerm:updatePermModule'))">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { treeDataTranslate, findTreeNodePath } from '@/utils';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { DictionaryController, SystemController } from '@/api';
export default {
name: 'formEditSysPermModule',
props: {
parentId: {
default: undefined
},
moduleType: {
default: undefined
},
moduleId: {
default: undefined
},
rowData: {
type: Object,
default: undefined
},
moduleList: {
type: Array,
default: () => {
return []
}
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachedPageChildMixin],
data () {
return {
formData: {
SysPermModule: {
moduleId: undefined,
parentId: undefined,
moduleName: undefined,
moduleType: undefined,
level: undefined,
showOrder: undefined
}
},
rules: {
'SysPermModule.moduleName': [
{required: true, message: '请输入模块名称', trigger: 'blur'}
],
'SysPermModule.showOrder': [
{required: true, message: '请输入显示顺序', trigger: 'blur'}
]
},
formCreatePermModule: {
formFilter: {
},
formFilterCopy: {
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 更新新建权限模块
*/
refreshFormCreatePermModule (reloadData = false) {
if (!this.formCreatePermModule.isInit) {
this.formData.SysPermModule.parentId = findTreeNodePath(this.getPermGroupTree, this.formData.SysPermModule.parentId, 'moduleId')
}
this.formCreatePermModule.isInit = true;
},
/**
* 新增
*/
onAddClick () {
this.$refs.formCreatePermModule.validate((valid) => {
if (!valid) return;
let params = {
sysPermModuleDto: {
moduleId: this.moduleId,
moduleName: this.formData.SysPermModule.moduleName,
showOrder: this.formData.SysPermModule.showOrder,
moduleType: this.formData.SysPermModule.moduleType,
parentId: Array.isArray(this.formData.SysPermModule.parentId) ? this.formData.SysPermModule.parentId[this.formData.SysPermModule.parentId.length - 1] : undefined
}
};
if (this.isEdit) {
SystemController.updatePermGroup(this, params).then(res => {
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {});
} else {
SystemController.addPermGroup(this, params).then(res => {
this.$message.success('新增成功');
this.onCancel(true);
}).catch(e => {});
}
});
},
initFormData () {
if (this.rowData != null) {
this.formData.SysPermModule = {...this.formData.SysPermModule, ...this.rowData};
}
if (this.parentId != null) this.formData.SysPermModule.parentId = this.parentId;
if (this.moduleType != null) this.formData.SysPermModule.moduleType = this.moduleType;
},
formInit () {
this.initFormData();
this.refreshFormCreatePermModule();
}
},
computed: {
isEdit () {
return this.moduleId != null;
},
getPermGroupTree () {
let tempList = this.moduleList.map((item) => {
if (item.moduleType === this.SysPermModuleType.GROUP) {
return {...item, children: undefined};
}
}).filter((item) => {
return item != null;
});
return treeDataTranslate(tempList, 'moduleId');
}
},
mounted () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,198 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="fragmentEditPost" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="岗位名称" prop="SysPost.postName">
<el-input class="input-item" v-model="formData.SysPost.postName"
:clearable="true" placeholder="岗位名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="岗位层级" prop="SysPost.level">
<el-input-number class="input-item" v-model="formData.SysPost.level"
:clearable="true" controls-position="right" placeholder="岗位层级" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="领导岗位">
<el-switch class="input-item" v-model="formData.SysPost.leaderPost" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
:disabled="!(checkPermCodeExist('formSysPost:fragmentSysPost:add') || checkPermCodeExist('formSysPost:fragmentSysPost:update'))"
@click="onSaveClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysPostController, DictionaryController } from '@/api';
export default {
name: 'formEditSysPost',
props: {
postId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
SysPost: {
postId: undefined,
postName: undefined,
level: undefined,
leaderPost: false,
isDatasourceInit: false
}
},
rules: {
'SysPost.postName': [
{required: true, message: '请输入岗位名称', trigger: 'blur'}
],
'SysPost.level': [
{required: true, message: '请输入岗位层级', trigger: 'blur'}
]
},
fragmentEditPost: {
formFilter: {
},
formFilterCopy: {
},
menuBlock: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 更新编辑岗位
*/
refreshFragmentEditPost (reloadData = false) {
this.loadSysPostData().then(res => {
if (!this.fragmentEditPost.isInit) {
// 初始化下拉数据
}
this.fragmentEditPost.isInit = true;
}).catch(e => {});
},
/**
* 保存
*/
onSaveClick () {
this.$refs.fragmentEditPost.validate((valid) => {
if (!valid) return;
if (
this.formData.SysPost.postName == null ||
this.formData.SysPost.level == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
sysPostDto: {
postId: this.postId,
postName: this.formData.SysPost.postName,
level: this.formData.SysPost.level,
leaderPost: this.formData.SysPost.leaderPost
}
};
let httpCall = this.isEdit ? SysPostController.update(this, params) : SysPostController.add(this, params);
httpCall.then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
/**
* 获取岗位管理详细信息
*/
loadSysPostData () {
return new Promise((resolve, reject) => {
if (!this.formData.SysPost.isDatasourceInit && this.isEdit) {
if (
this.postId == null
) {
this.resetFormData();
reject();
return;
}
let params = {
postId: this.postId
};
SysPostController.view(this, params).then(res => {
this.formData.SysPost = {...res.data, isDatasourceInit: true};
resolve();
}).catch(e => {
reject();
});
} else {
resolve();
}
});
},
initFormData () {
},
/**
* 重置表单数据
*/
resetFormData () {
this.formData = {
SysPost: {
postId: undefined,
postName: undefined,
level: undefined,
leaderPost: undefined,
createUserId: undefined,
createTime: undefined,
updateUserId: undefined,
updateTime: undefined,
deletedFlag: undefined,
isDatasourceInit: false
}
}
},
formInit () {
this.refreshFragmentEditPost();
}
},
computed: {
isEdit () {
return this.postId != null;
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,158 @@
<template>
<el-form ref="form" :model="formData" :rules="rules" label-width="80px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="角色名称" prop="roleName">
<el-input v-model="formData.roleName" placeholder="角色名称" clearable />
</el-form-item>
<el-form-item v-if="false" label="角色类型" :required="true">
<el-radio-group v-model="formData.adminRole">
<el-radio :label="1">管理员</el-radio>
<el-radio :label="0">其他</el-radio>
</el-radio-group>
</el-form-item>
<el-card shadow="never">
<div slot="header" class="card-header">
<span>菜单权限</span>
<el-input size="mini" v-model="menuNameFilter" placeholder="输入菜单名称过滤" style="width: 250px;" clearable suffix-icon="el-icon-search" />
</div>
<el-scrollbar style="height: 230px;" wrap-class="scrollbar_dropdown__wrap">
<el-tree ref="authTree" :data="authData" :props="treeProps" :check-strictly="false"
show-checkbox node-key="menuId" :filter-node-method="filterMneuNode">
</el-tree>
</el-scrollbar>
</el-card>
</el-col>
</el-row>
<!-- 弹窗下发按钮栏必须设置class为dialog-btn-layer -->
<el-row type="flex" justify="end" class="dialog-btn-layer" style="margin-top: 20px;">
<el-button size="mini" @click="onCancel(false)" >取消</el-button>
<el-button type="primary" size="mini" @click="onSubmit"
:disabled="!(checkPermCodeExist('formSysRole:fragmentSysRole:update') || checkPermCodeExist('formSysRole:fragmentSysRole:add'))">
确定
</el-button>
</el-row>
</el-form>
</template>
<script>
import { treeDataTranslate, findItemFromList } from '@/utils'
import { SystemController } from '@/api'
export default {
props: {
rowData: {
type: Object
}
},
data () {
return {
menuNameFilter: undefined,
formData: {
roleId: undefined,
roleName: undefined,
adminRole: false,
menuIdListString: undefined
/*
permsJsonData: {
checked: [],
halfChecked: [],
},
*/
},
rules: {
roleName: [{required: true, message: '角色名称不能为空', trigger: 'blur'}]
},
treeProps: {
label: 'menuName'
},
authData: [],
allowParentList: []
}
},
methods: {
filterMneuNode (value, data) {
if (!value) return true;
if (data.menuName.indexOf(value) !== -1) {
this.allowParentList.push(data.menuId);
return true;
} else {
return this.allowParentList.indexOf(data.parentId) !== -1;
}
},
onCancel (isSuccess = false) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
this.$refs.form.validate((valid) => {
if (valid) {
let selectMenu = [];
selectMenu = this.$refs.authTree.getHalfCheckedKeys();
selectMenu = selectMenu.concat(this.$refs.authTree.getCheckedKeys());
if (selectMenu.length <= 0) {
this.$message.error({message: '请选择角色的菜单权限', showClose: true});
return;
}
let params = {
sysRoleDto: {...this.formData}
}
params.menuIdListString = selectMenu.join(',');
if (this.isEdit) {
SystemController.updateRole(this, params).then(res => {
this.$message.success('编辑成功');
this.onCancel(true);
}).catch(e => {});
} else {
SystemController.addRole(this, params).then(res => {
this.$message.success('添加成功');
this.onCancel(true);
}).catch(e => {});
}
}
});
},
loadAuthData () {
SystemController.getMenuPermList(this, {}).then(res => {
this.authData = treeDataTranslate(res.data, 'menuId', 'parentId');
if (Array.isArray(this.formData.menuIdList)) {
let tempList = [];
this.formData.menuIdList.forEach((item) => {
let tempMenu = findItemFromList(res.data, item, 'menuId');
// 判断是否为叶子节点
if (tempMenu != null && (!Array.isArray(tempMenu.children) || tempMenu.children.length <= 0)) {
tempList.push(item);
}
});
this.$refs.authTree.setCheckedKeys(tempList);
}
}).catch(e => {});
}
},
computed: {
isEdit () {
return this.formData.roleId != null;
}
},
mounted () {
if (this.rowData) {
this.formData = {...this.formData, ...this.rowData};
if (Array.isArray(this.formData.sysRoleMenuList)) {
this.formData.menuIdList = this.formData.sysRoleMenuList.map(item => item.menuId);
}
}
this.loadAuthData();
},
watch: {
menuNameFilter (val) {
this.allowParentList = [];
this.$refs.authTree.filter(val);
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,257 @@
<template>
<el-form ref="form" :model="formData" :rules="rules" label-width="110px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20" class="full-width-input">
<el-col :span="24">
<el-form-item label="登录名称" prop="loginName">
<el-input v-model="formData.loginName" placeholder="用户登录名称" clearable :disabled="isEdit" />
</el-form-item>
<el-form-item label="登录密码" v-if="!isEdit" prop="password">
<el-input v-model="formData.password" type="password" placeholder="用户登录密码" clearable />
</el-form-item>
<el-form-item label="再次输入密码" v-if="!isEdit" prop="passwordRepeat">
<el-input v-model="formData.passwordRepeat" type="password" placeholder="再次输入用户密码" clearable />
</el-form-item>
<el-form-item label="用户昵称" prop="showName">
<el-input v-model="formData.showName" placeholder="用户昵称" clearable />
</el-form-item>
<el-form-item label="账号类型" prop="userType">
<el-select v-model="formData.userType">
<el-option v-for="item in SysUserType.getList()" :key="item.id"
:label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="用户状态" prop="userStatus" v-if="isEdit">
<el-radio-group v-model="formData.userStatus">
<el-radio v-for="item in SysUserStatus.getList()" :key="item.id" :label="item.id">
{{item.name}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="所属部门" prop="deptId">
<el-cascader class="input-item" v-model="deptId.value" :clearable="true"
placeholder="所属部门" :loading="deptId.impl.loading" :props="{value: 'deptId', label: 'deptName', checkStrictly: true}"
@visible-change="onDeptIdVisibleChange" :options="deptId.impl.dropdownList"
@change="onDeptIdValueChange">
</el-cascader>
</el-form-item>
<el-form-item label="用户岗位" prop="deptPostIdList">
<el-select v-model="formData.deptPostIdList" multiple placeholder="用户岗位">
<el-option v-for="deptPost in deptPostList" :key="deptPost.deptPostId"
:label="deptPost.postShowName" :value="deptPost.deptPostId" />
</el-select>
</el-form-item>
<el-form-item label="用户角色" prop="roleIdList">
<el-select v-model="formData.roleIdList" multiple placeholder="用户角色">
<el-option v-for="role in roleList" :key="role.roleId"
:label="role.roleName" :value="role.roleId" />
</el-select>
</el-form-item>
<el-form-item label="数据权限" prop="dataPermIdList">
<el-select v-model="formData.dataPermIdList" multiple placeholder="数据权限">
<el-option v-for="dataPerm in dataPermList" :key="dataPerm.dataPermId"
:label="dataPerm.dataPermName" :value="dataPerm.dataPermId" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 弹窗下发按钮栏必须设置class为dialog-btn-layer -->
<el-row type="flex" justify="end" class="dialog-btn-layer">
<el-button size="mini" type="primary" :plain="true" @click="onCancel(false)" >取消</el-button>
<el-button type="primary" size="mini" @click="onSubmit"
:disabled="!(checkPermCodeExist('formSysUser:fragmentSysUser:update') || checkPermCodeExist('formSysUser:fragmentSysUser:add'))">
确定
</el-button>
</el-row>
</el-form>
</template>
<script>
/* eslint-disable-next-line */
import { findTreeNodePath } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
import { SystemController, SysDeptController, SysDataPermController, DictionaryController } from '@/api';
import { uploadMixin } from '@/core/mixins';
export default {
props: {
rowData: Object
},
mixins: [uploadMixin],
data () {
return {
formData: {
userId: undefined,
loginName: undefined,
password: undefined,
showName: undefined,
userType: 2,
userStatus: 0,
dataPermIdList: [],
deptPostIdList: [],
roleIdList: []
},
params: {
userId: undefined,
loginName: undefined,
password: undefined,
showName: undefined,
deptId: '',
userType: 2,
userStatus: 0,
dataPermIdListString: undefined,
deptPostIdListString: undefined,
roleIdListString: undefined
},
deptId: {
impl: new DropdownWidget(this.loadDeptmentDropdownList, true, 'deptId'),
value: []
},
rules: {
loginName: [{required: true, message: '用户名称不能为空', trigger: 'blur'}],
password: [{required: true, message: '用户密码不能为空', trigger: 'blur'}],
passwordRepeat: [{required: true, message: '重输密码不能为空', trigger: 'blur'}],
showName: [{required: true, message: '用户昵称不能为空', trigger: 'blur'}],
dataPermIdList: [{required: true, message: '数据权限不能为空', trigger: 'change'}],
deptPostIdList: [{required: true, message: '用户岗位不能为空', trigger: 'change'}],
roleIdList: [{required: true, message: '用户角色不能为空', trigger: 'change'}]
},
showHeaderSelect: false,
dataPermList: [],
deptPostList: [],
roleList: []
}
},
methods: {
/**
* 所属部门下拉数据获取函数
*/
loadDeptmentDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
SysDeptController.list(this, params).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
/**
* 所属部门下拉框显隐
*/
onDeptIdVisibleChange (show) {
this.deptId.impl.onVisibleChange(show).catch(e => {});
},
/**
* 所属部门选中值改变
*/
onDeptIdValueChange (value) {
this.formData.deptId = Array.isArray(value) ? value[value.length - 1] : undefined;
this.formData.deptPostIdList = undefined;
this.loadDeptPost();
},
/**
* 获取部门岗位列表
*/
loadDeptPost () {
if (this.formData.deptId == null || this.formData.deptId === '') {
this.deptPostList = [];
return;
}
DictionaryController.dictDeptPost(this, {
deptId: this.formData.deptId
}).then(res => {
this.deptPostList = res;
}).catch(e => {});
},
onCancel (isSuccess = false) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.formData.userId == null && (this.formData.password !== this.formData.passwordRepeat)) {
this.$message.error({message: '两次密码输入不一致,请重新输入', showClose: true});
return;
}
let params = {
sysUserDto: {
userId: this.formData.userId,
loginName: this.formData.loginName,
password: this.formData.password,
showName: this.formData.showName,
userType: this.formData.userType,
deptId: this.formData.deptId,
userStatus: this.formData.userStatus
},
dataPermIdListString: Array.isArray(this.formData.dataPermIdList) ? this.formData.dataPermIdList.join(',') : undefined,
deptPostIdListString: Array.isArray(this.formData.deptPostIdList) ? this.formData.deptPostIdList.join(',') : undefined,
roleIdListString: Array.isArray(this.formData.roleIdList) ? this.formData.roleIdList.join(',') : undefined
}
let operation = null;
if (this.formData.userId != null) {
operation = SystemController.updateUser(this, params);
} else {
operation = SystemController.addUser(this, params);
}
operation.then(res => {
this.$message.success(this.formData.userId != null ? '编辑成功' : '添加成功');
this.onCancel(true);
}).catch(e => {
//
})
}
});
},
loadRole () {
SystemController.getRoleList(this, {}).then(res => {
this.roleList = res.data.dataList;
}).catch(e => {});
},
loadDataPerm () {
SysDataPermController.list(this, {}).then(res => {
this.dataPermList = res.data.dataList;
}).catch(e => {});
},
loadRowData (id) {
var params = {
userId: id
}
return SystemController.getUser(this, params);
}
},
computed: {
isEdit () {
return (this.formData.userId != null);
}
},
mounted () {
if (this.rowData != null) {
this.formData = {...this.rowData, dataPermIdList: [], deptPostIdList: [], roleIdList: []};
if (Array.isArray(this.formData.sysDataPermUserList)) {
this.formData.dataPermIdList = this.formData.sysDataPermUserList.map(item => item.dataPermId);
}
if (Array.isArray(this.formData.sysUserPostList)) {
this.formData.deptPostIdList = this.formData.sysUserPostList.map(item => item.deptPostId);
}
if (Array.isArray(this.formData.sysUserRoleList)) {
this.formData.roleIdList = this.formData.sysUserRoleList.map(item => item.roleId);
}
}
this.deptId.impl.onVisibleChange(true).then(res => {
this.deptId.value = findTreeNodePath(this.deptId.impl.dropdownList, this.formData.deptId, 'deptId');
});
this.loadRole();
this.loadDataPerm();
this.loadDeptPost();
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,150 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="关联URL">
<el-input class="filter-item" v-model="formMenuPerm.formFilter.url"
:clearable="true" placeholder="权限字名称" />
</el-form-item>
<el-button slot="operator" type="primary" size="mini" :plain="true" @click="refreshFormMenuPerm(true)">
查询
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="getPermList" size="mini" height="459px"
@sort-change="formMenuPerm.SysPerm.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px" :index="formMenuPerm.SysPerm.impl.getTableIndex" />
<el-table-column label="权限字名称" prop="showName" width="150px">
</el-table-column>
<el-table-column label="权限字类型" width="100px">
<template slot-scope="scope">
<el-tag size="mini" :type="getPermCodeType(scope.row.permCodeType)">
{{SysPermCodeType.getValue(scope.row.permCodeType)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="权限字标识" prop="permCode" width="300px" />
<el-table-column label="权限名称" prop="permName" width="150px" />
<el-table-column label="关联URL" prop="url" min-width="300px">
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController } from '@/api';
export default {
name: 'formMenuPerm',
props: {
menuId: {
type: String,
required: true
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formMenuPerm: {
formFilter: {
menuId: this.menuId,
url: undefined
},
formFilterCopy: {
menuId: this.menuId,
url: undefined
},
SysPerm: {
impl: new TableWidget(this.loadSysPermData, this.loadSysPermVerify, false)
},
isInit: false
}
}
},
methods: {
getPermCodeType (permCodeType) {
switch (permCodeType) {
case this.SysPermCodeType.FORM: return 'primary';
case this.SysPermCodeType.FRAGMENT: return 'warning';
case this.SysPermCodeType.OPERATION: return 'success';
default: return 'info';
}
},
/**
* 权限数据获取函数返回Primise
*/
loadSysPermData (params) {
params = {
...params,
menuId: this.formMenuPerm.formFilterCopy.menuId
}
return new Promise((resolve, reject) => {
SystemController.listMenuPerm(this, params).then(res => {
resolve({
dataList: res.data
});
}).catch(e => {
reject(e);
});
});
},
/**
* 权限数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysPermVerify () {
this.formMenuPerm.formFilterCopy.url = this.formMenuPerm.formFilter.url;
this.formMenuPerm.formFilterCopy.menuId = this.formMenuPerm.formFilter.menuId;
if (this.formMenuPerm.formFilterCopy.menuId == null || this.formMenuPerm.formFilterCopy.menuId === '') {
this.$message.error('所属菜单不能为空!');
return false;
}
return true;
},
/**
* 更新权限管理
*/
refreshFormMenuPerm (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formMenuPerm.SysPerm.impl.refreshTable(true, 1);
} else {
this.formMenuPerm.SysPerm.impl.refreshTable();
}
this.formMenuPerm.isInit = true;
},
onResume () {
this.refreshFormMenuPerm();
},
initFormData () {
},
formInit () {
this.initFormData();
this.refreshFormMenuPerm();
}
},
computed: {
getPermList () {
return this.formMenuPerm.SysPerm.impl.dataList.filter((item) => {
return (this.formMenuPerm.formFilterCopy.url == null || this.formMenuPerm.formFilterCopy.url === '') ||
(item.url.indexOf(this.formMenuPerm.formFilterCopy.url) !== -1);
});
}
},
created () {
this.formInit();
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,211 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="325">
<el-form-item label="用户状态">
<el-select class="filter-item" v-model="formSysUser.formFilter.sysUserStatus" :clearable="true"
placeholder="用户状态" :loading="formSysUser.sysUserStatus.impl.loading"
@visible-change="onSysUserStatusVisibleChange">
<el-option v-for="item in formSysUser.sysUserStatus.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="用户名">
<el-input class="filter-item" v-model="formSysUser.formFilter.sysUserLoginName"
:clearable="true" placeholder="用户名" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysUser(true)">查询</el-button>
<el-button slot="operator" size="mini" type="primary" :plain="false" @click="onSetUser"
:disabled="selectUsers == null || selectUsers.length <= 0">授权人员</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSysUser.SysUser.impl.dataList" size="mini" row-key="userId" ref="userTable"
header-cell-class-name="table-header-gray" height="395px" @selection-change="onTableSelectionChange">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px" :index="formSysUser.SysUser.impl.getTableIndex" />
<el-table-column header-align="center" align="center" type="selection" width="50px" :reserve-selection="true" />
<el-table-column label="用户名" prop="loginName">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型">
<template slot-scope="scope">
<span>{{SysUserType.getValue(scope.row.userType)}}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysUser.SysUser.impl.totalCount"
:current-page="formSysUser.SysUser.impl.currentPage"
:page-size="formSysUser.SysUser.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysUser.SysUser.impl.onCurrentPageChange"
@size-change="formSysUser.SysUser.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController } from '@/api';
export default {
props: {
roleId: {
type: [String, Number],
required: true
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysUser: {
formFilter: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
formFilterCopy: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
sysUserStatus: {
impl: new DropdownWidget(this.loadSysUserStatusDropdownList)
},
SysUser: {
impl: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, true, false)
},
isInit: false
},
selectUsers: []
}
},
methods: {
/**
* 用户状态下拉数据获取函数
*/
loadSysUserStatusDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysUserStatus(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 用户状态下拉框显隐
*/
onSysUserStatusVisibleChange (show) {
this.formSysUser.sysUserStatus.impl.onVisibleChange(show).catch(e => {});
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
onTableSelectionChange (values) {
this.selectUsers = values;
},
onSetUser () {
let params = {
roleId: this.roleId,
userIdListString: this.selectUsers.map((item) => {
return item.userId
}).join(',')
}
SystemController.addRoleUser(this, params).then(res => {
this.$message.success('授权成功');
this.refreshFormSysUser(true);
this.$refs.userTable.clearSelection();
this.selectUsers = [];
}).catch(e => {});
},
onCancel () {
this.$router.go(-1);
},
loadSysUserData (params) {
params.roleId = this.roleId;
params.sysUserDtoFilter = {
loginName: this.formSysUser.formFilterCopy.sysUserLoginName,
userStatus: this.formSysUser.formFilterCopy.sysUserStatus
}
this.$refs.userTable.clearSelection();
return new Promise((resolve, reject) => {
SystemController.listNotInUserRole(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
this.formSysUser.formFilterCopy.sysUserLoginName = this.formSysUser.formFilter.sysUserLoginName;
this.formSysUser.formFilterCopy.sysUserStatus = this.formSysUser.formFilter.sysUserStatus;
return true;
},
refreshFormSysUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysUser.SysUser.impl.refreshTable(true, 1);
} else {
this.formSysUser.SysUser.impl.refreshTable();
}
this.formSysUser.sysUserStatus.impl.onVisibleChange(true).catch(e => {});
this.formSysUser.isInit = true;
},
initData () {
this.refreshFormSysUser();
}
},
mounted () {
this.initData();
},
computed: {
getContextHeightStyle () {
return [
{'height': (this.getClientHeight - 142) + 'px'}
]
},
...mapGetters(['getClientHeight'])
},
watch: {
currentPage: function (value, oldValue) {
this.loadDatasource(false).catch(e => {
this.currentPage = oldValue;
})
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,211 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="325">
<el-form-item label="用户状态">
<el-select class="filter-item" v-model="formSysUser.formFilter.sysUserStatus" :clearable="true"
placeholder="用户状态" :loading="formSysUser.sysUserStatus.impl.loading"
@visible-change="onSysUserStatusVisibleChange">
<el-option v-for="item in formSysUser.sysUserStatus.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="用户名">
<el-input class="filter-item" v-model="formSysUser.formFilter.sysUserLoginName"
:clearable="true" placeholder="用户名" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysUser(true)">查询</el-button>
<el-button slot="operator" size="mini" type="primary" :plain="false" @click="onSetUser"
:disabled="selectUsers == null || selectUsers.length <= 0">授权人员</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSysUser.SysUser.impl.dataList" size="mini" row-key="userId" ref="userTable"
header-cell-class-name="table-header-gray" height="395px" @selection-change="onTableSelectionChange">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px" :index="formSysUser.SysUser.impl.getTableIndex" />
<el-table-column header-align="center" align="center" type="selection" width="50px" :reserve-selection="true" />
<el-table-column label="用户名" prop="loginName">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型">
<template slot-scope="scope">
<span>{{SysUserType.getValue(scope.row.userType)}}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysUser.SysUser.impl.totalCount"
:current-page="formSysUser.SysUser.impl.currentPage"
:page-size="formSysUser.SysUser.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysUser.SysUser.impl.onCurrentPageChange"
@size-change="formSysUser.SysUser.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDataPermController, DictionaryController } from '@/api';
export default {
props: {
dataPermId: {
type: [String, Number],
required: true
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysUser: {
formFilter: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
formFilterCopy: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
sysUserStatus: {
impl: new DropdownWidget(this.loadSysUserStatusDropdownList)
},
SysUser: {
impl: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, true, false)
},
isInit: false
},
selectUsers: []
}
},
methods: {
/**
* 用户状态下拉数据获取函数
*/
loadSysUserStatusDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysUserStatus(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 用户状态下拉框显隐
*/
onSysUserStatusVisibleChange (show) {
this.formSysUser.sysUserStatus.impl.onVisibleChange(show).catch(e => {});
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
onTableSelectionChange (values) {
this.selectUsers = values;
},
onSetUser () {
let params = {
dataPermId: this.dataPermId,
userIdListString: this.selectUsers.map((item) => {
return item.userId
}).join(',')
}
SysDataPermController.addDataPermUser(this, params).then(res => {
this.$message.success('授权成功');
this.refreshFormSysUser(true);
this.$refs.userTable.clearSelection();
this.selectUsers = [];
}).catch(e => {});
},
onCancel () {
this.$router.go(-1);
},
loadSysUserData (params) {
params.dataPermId = this.dataPermId;
params.sysUserDtoFilter = {
loginName: this.formSysUser.formFilterCopy.sysUserLoginName,
userStatus: this.formSysUser.formFilterCopy.sysUserStatus
}
this.$refs.userTable.clearSelection();
return new Promise((resolve, reject) => {
SysDataPermController.listNotInDataPermUser(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
this.formSysUser.formFilterCopy.sysUserLoginName = this.formSysUser.formFilter.sysUserLoginName;
this.formSysUser.formFilterCopy.sysUserStatus = this.formSysUser.formFilter.sysUserStatus;
return true;
},
refreshFormSysUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysUser.SysUser.impl.refreshTable(true, 1);
} else {
this.formSysUser.SysUser.impl.refreshTable();
}
this.formSysUser.sysUserStatus.impl.onVisibleChange(true).catch(e => {});
this.formSysUser.isInit = true;
},
initData () {
this.refreshFormSysUser();
}
},
mounted () {
this.initData();
},
computed: {
getContextHeightStyle () {
return [
{'height': (this.getClientHeight - 142) + 'px'}
]
},
...mapGetters(['getClientHeight'])
},
watch: {
currentPage: function (value, oldValue) {
this.loadDatasource(false).catch(e => {
this.currentPage = oldValue;
})
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,479 @@
<template>
<div class="tab-dialog-box" style="position: relative;">
<el-tabs v-model="activeFragmentId" :before-leave="onFragmentChange">
<el-tab-pane label="数据权限管理" name="fragmentSysDataPerm" style="width: 100%;"
v-if="checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm')">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="过滤规则">
<el-select class="filter-item" v-model="fragmentSysDataPerm.formFilter.sysDatapermType" :clearable="true"
placeholder="过滤规则" :loading="fragmentSysDataPerm.sysDatapermType.impl.loading"
@visible-change="onSysDatapermTypeVisibleChange"
@change="onSysDatapermTypeValueChange">
<el-option v-for="item in fragmentSysDataPerm.sysDatapermType.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="数据权限名称">
<el-input class="filter-item" v-model="fragmentSysDataPerm.formFilter.sysDataPermName"
:clearable="true" placeholder="数据权限名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysDataPerm(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:add')"
@click="onAddDataPermClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysDataPerm.SysDataPerm.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysDataPerm.SysDataPerm.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysDataPerm.SysDataPerm.impl.getTableIndex" />
<el-table-column label="权限名称" prop="dataPermName">
</el-table-column>
<el-table-column label="过滤规则">
<template slot-scope="scope">
<span>{{SysDataPermType.getValue(scope.row.ruleType)}}</span>
</template>
</el-table-column>
<el-table-column label="创建人" prop="createUsername">
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button @click="onEditDataPermClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:update')">
编辑
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPerm:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="fragmentSysDataPerm.SysDataPerm.impl.totalCount"
:current-page="fragmentSysDataPerm.SysDataPerm.impl.currentPage"
:page-size="fragmentSysDataPerm.SysDataPerm.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="fragmentSysDataPerm.SysDataPerm.impl.onCurrentPageChange"
@size-change="fragmentSysDataPerm.SysDataPerm.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="用户授权" name="fragmentSysDataPermUser" style="width: 100%;"
v-if="checkPermCodeExist('formSysDataPerm:fragmentSysDataPermUser')">
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="数据权限">
<el-select class="filter-item" v-model="fragmentSysDataPermUser.formFilter.dataPermId" clearable
placeholder="数据权限" :loading="fragmentSysDataPermUser.dataPermId.impl.loading"
@visible-change="fragmentSysDataPermUser.dataPermId.impl.onVisibleChange"
@change="onDataPermChange">
<el-option v-for="item in fragmentSysDataPermUser.dataPermId.impl.dropdownList" :key="item.dataPermId"
:value="item.dataPermId" :label="item.dataPermName" />
</el-select>
</el-form-item>
<el-form-item label="用户名">
<el-input class="filter-item" v-model="fragmentSysDataPermUser.formFilter.searchString"
:clearable="true" placeholder="输入用户名 / 昵称查询" @change="refreshFragmentSysDataPermUser(true)" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysDataPermUser(true)">
查询
</el-button>
<el-button slot="operator" type="primary" size="mini" @click="onAddDataPermUserClick()"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPermUser:addDataPermUser') ||
fragmentSysDataPermUser.formFilter.dataPermId == null || fragmentSysDataPermUser.formFilter.dataPermId === ''">
添加用户
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysDataPermUser.SysDataPermUserList.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysDataPermUser.SysDataPermUserList.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysDataPermUser.SysDataPermUserList.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型">
<template slot-scope="scope">
<span>{{SysUserType.getValue(scope.row.userType)}}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="80px">
<template slot-scope="scope">
<el-button class="btn-table-delete" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDataPerm:fragmentSysDataPermUser:deleteDataPermUser')"
@click="onDeleteRow(scope.row)">移除</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="fragmentSysDataPermUser.SysDataPermUserList.impl.totalCount"
:current-page="fragmentSysDataPermUser.SysDataPermUserList.impl.currentPage"
:page-size="fragmentSysDataPermUser.SysDataPermUserList.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="fragmentSysDataPermUser.SysDataPermUserList.impl.onCurrentPageChange"
@size-change="fragmentSysDataPermUser.SysDataPermUserList.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDataPermController, DictionaryController } from '@/api';
import formEditSysDataPerm from '@/views/upms/formEditSysDataPerm';
import formSetSysDataPermUser from '@/views/upms/formSetSysDataPermUser';
export default {
name: 'formSysDataPerm',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
activeFragmentId: undefined,
fragmentSysDataPerm: {
formFilter: {
sysDatapermType: undefined,
sysDataPermName: undefined
},
formFilterCopy: {
sysDatapermType: undefined,
sysDataPermName: undefined
},
sysDatapermType: {
impl: new DropdownWidget(this.loadSysDatapermTypeDropdownList)
},
SysDataPerm: {
impl: new TableWidget(this.loadSysDataPermData, this.loadSysDataPermVerify, true, false)
},
isInit: false
},
fragmentSysDataPermUser: {
formFilter: {
dataPermId: undefined,
searchString: undefined
},
dataPermId: {
impl: new DropdownWidget(this.loadDataPermDropdownList)
},
SysDataPermUserList: {
impl: new TableWidget(this.loadSysDataPermUserListData, this.loadSysDataPermUserListVerify, true, false)
},
isInit: false
}
}
},
methods: {
/**
* 数据权限数据获取函数返回Primise
*/
loadSysDataPermData (params) {
params.sysDataPermDtoFilter = {
searchString: this.fragmentSysDataPerm.formFilterCopy.sysDataPermName,
ruleType: this.fragmentSysDataPerm.formFilterCopy.sysDatapermType
};
return new Promise((resolve, reject) => {
SysDataPermController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 数据权限数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysDataPermVerify () {
this.fragmentSysDataPerm.formFilterCopy.sysDataPermName = this.fragmentSysDataPerm.formFilter.sysDataPermName;
this.fragmentSysDataPerm.formFilterCopy.sysDatapermType = this.fragmentSysDataPerm.formFilter.sysDatapermType;
return true;
},
/**
* 过滤规则下拉数据获取函数
*/
loadSysDatapermTypeDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysDataPermType(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 过滤规则下拉框显隐
*/
onSysDatapermTypeVisibleChange (show) {
this.fragmentSysDataPerm.sysDatapermType.impl.onVisibleChange(show).catch(e => {});
},
/**
* 过滤规则选中值改变
*/
onSysDatapermTypeValueChange (value) {
},
/**
* 更新数据权限管理
*/
refreshFragmentSysDataPerm (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable(true, 1);
} else {
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable();
}
this.fragmentSysDataPerm.sysDatapermType.impl.onVisibleChange(true).catch(e => {});
this.fragmentSysDataPerm.isInit = true;
},
/**
* 新建
*/
onAddDataPermClick () {
let params = {};
this.$dialog.show('新建数据权限', formEditSysDataPerm, {
area: ['800px', '520px']
}, params).then(res => {
this.fragmentSysDataPermUser.dataPermId.impl.dirty = true;
this.refreshFragmentSysDataPerm();
}).catch(e => {});
},
/**
* 编辑
*/
onEditDataPermClick (row) {
let params = {
dataPermId: row.dataPermId
};
this.$dialog.show('编辑数据权限', formEditSysDataPerm, {
area: ['800px', '520px']
}, params).then(res => {
if (row.dataPermId === this.fragmentSysDataPermUser.formFilter.dataPermId) {
this.fragmentSysDataPermUser.formFilter.dataPermId = undefined;
this.fragmentSysDataPermUser.SysDataPermUserList.impl.clearTable();
}
this.fragmentSysDataPermUser.dataPermId.impl.dirty = true;
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
dataPermId: row.dataPermId
};
this.$confirm('是否删除此数据权限?').then(res => {
SysDataPermController.delete(this, params).then(res => {
this.$message.success('删除成功');
if (row.dataPermId === this.fragmentSysDataPermUser.formFilter.dataPermId) {
this.fragmentSysDataPermUser.formFilter.dataPermId = undefined;
this.fragmentSysDataPermUser.SysDataPermUserList.impl.clearTable();
}
this.fragmentSysDataPermUser.dataPermId.impl.dirty = true;
this.fragmentSysDataPerm.SysDataPerm.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onDataPermChange (value) {
this.refreshFragmentSysDataPermUser(true);
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
loadDataPermDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
SysDataPermController.list(this, params).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
/**
* 用户列表数据获取函数返回Primise
*/
loadSysDataPermUserListData (params) {
return new Promise((resolve, reject) => {
if (this.fragmentSysDataPermUser.formFilter.dataPermId == null || this.fragmentSysDataPermUser.formFilter.dataPermId === '') {
this.$message.error('请选择数据权限');
resolve({
dataList: [],
totalCount: 0
});
return;
}
params.dataPermId = this.fragmentSysDataPermUser.formFilter.dataPermId;
params.searchString = this.fragmentSysDataPermUser.formFilter.searchString;
SysDataPermController.listDataPermUser(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户列表数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysDataPermUserListVerify () {
return true;
},
onDeleteRow (row) {
this.$confirm('是否移除此用户?').then(res => {
let params = {
dataPermId: this.fragmentSysDataPermUser.formFilter.dataPermId,
userId: row.userId
}
SysDataPermController.deleteDataPermUser(this, params).then(res => {
this.refreshFragmentSysDataPermUser(true);
this.$message.success('移除成功');
}).catch(e => {});
}).catch(e => {});
},
/**
* 更新数据权限授权
*/
refreshFragmentSysDataPermUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysDataPermUser.SysDataPermUserList.impl.refreshTable(true, 1);
} else {
this.fragmentSysDataPermUser.SysDataPermUserList.impl.refreshTable();
}
this.fragmentSysDataPermUser.isInit = true;
},
/**
* 授权用户
*/
onAddDataPermUserClick () {
let params = {
dataPermId: this.fragmentSysDataPermUser.formFilter.dataPermId
};
this.$dialog.show('授权用户', formSetSysDataPermUser, {
area: ['1100px', '580px']
}, params).then(res => {
this.refreshFragmentSysDataPermUser(true);
}).catch(e => {
this.refreshFragmentSysDataPermUser(true);
});
},
buildFragmentPermCodeMap () {
this.permCodeList = [
{
key: 'fragmentSysDataPerm',
permCode: 'formSysDataPerm:fragmentSysDataPerm',
refresh: this.refreshFragmentSysDataPerm
},
{
key: 'fragmentSysDataPermUser',
permCode: 'formSysDataPerm:fragmentSysDataPermUser',
refresh: this.refreshFragmentSysDataPermUser
}
];
},
onFragmentChange (fragmentId) {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.permCodeList[i].key === fragmentId) {
this.activeFragmentId = fragmentId;
// if (this.permCodeList[i].refresh) this.permCodeList[i].refresh();
return true;
}
}
return false;
},
getActiveFragment () {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.permCodeList[i].key === this.activeFragmentId) {
return this.permCodeList[i];
}
}
},
/**
* 根据权限获取默认显示的fragment
*/
getDefaultFragment () {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.checkPermCodeExist(this.permCodeList[i].permCode)) {
this.activeFragmentId = this.permCodeList[i].key;
return this.permCodeList[i];
}
}
return undefined;
},
onResume () {
this.refreshFragmentSysDataPerm();
},
initFormData () {
},
formInit () {
this.buildFragmentPermCodeMap();
let defaultFragment = this.getDefaultFragment();
if (defaultFragment == null) {
this.$message.error('您没有访问这个页面的权限,请与系统管理员联系!');
} else {
if (defaultFragment.refresh) defaultFragment.refresh();
}
}
},
computed: {
getTableHeight () {
return (this.getMainContextHeight - 192);
},
...mapGetters(['getMainContextHeight'])
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,193 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="部门名称">
<el-input class="filter-item" v-model="formSysDept.formFilter.deptName"
:clearable="true" placeholder="部门名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysDept(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:add')"
@click="onCreateSysDeptClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSysDept.SysDeptList.impl.dataList" size="mini" row-key="deptId"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px">
</el-table-column>
<el-table-column label="部门名称" prop="deptName">
</el-table-column>
<el-table-column label="操作" fixed="right" width="150px">
<template slot-scope="scope">
<el-button @click="onEditSysDeptClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:update')">
编辑
</el-button>
<el-button @click="onEditSysDeptPostClick(scope.row)" type="text" size="mini"
:disabled="!(checkPermCodeExist('formSysDept:fragmentSysDept:editPost') || checkPermCodeExist('formSysDept:fragmentSysDept:viewPost'))">
岗位
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { treeDataTranslate } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDeptController, DictionaryController } from '@/api';
import formEditSysDept from '../formEditSysDept';
export default {
name: 'formSysDept',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysDept: {
formFilter: {
deptName: undefined
},
formFilterCopy: {
deptName: undefined
},
SysDeptList: {
impl: new TableWidget(this.loadSysDeptListData, this.loadSysDeptListVerify, false)
},
isInit: false
}
}
},
methods: {
/**
* 部门列表数据获取函数返回Primise
*/
loadSysDeptListData (params) {
params.sysDeptDtoFilter = {
deptName: this.formSysDept.formFilterCopy.deptName
};
return new Promise((resolve, reject) => {
SysDeptController.list(this, params).then(res => {
resolve({
dataList: treeDataTranslate(res.data.dataList, 'deptId', 'parentId'),
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 部门列表数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysDeptListVerify () {
this.formSysDept.formFilterCopy.deptName = this.formSysDept.formFilter.deptName;
return true;
},
/**
* 部门列表当前页变化函数
*/
onSysDeptListCurrentPageChange (newPage) {
this.formSysDept.SysDeptList.impl.onCurrentPageChange(newPage);
},
/**
* 部门列表每页显示数量变化函数(跳转回第一页)
*/
onSysDeptListPageSizeChange (newPage) {
this.formSysDept.SysDeptList.impl.onPageSizeChange(newPage);
},
/**
* 更新部门管理
*/
refreshFormSysDept (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysDept.SysDeptList.impl.refreshTable(true, 1);
} else {
this.formSysDept.SysDeptList.impl.refreshTable();
}
this.formSysDept.isInit = true;
},
/**
* 新建
*/
onCreateSysDeptClick () {
let params = {};
this.$dialog.show('新建部门', formEditSysDept, {
area: ['500px']
}, params).then(res => {
this.refreshFormSysDept();
}).catch(e => {});
},
/**
* 编辑部门
*/
onEditSysDeptClick (row) {
let params = {
deptId: row.deptId
};
this.$dialog.show('编辑部门', formEditSysDept, {
area: ['500px']
}, params).then(res => {
this.formSysDept.SysDeptList.impl.refreshTable();
}).catch(e => {});
},
/**
* 岗位
*/
onEditSysDeptPostClick (row) {
let params = {
deptId: row.deptId
};
params.closeVisible = 1;
this.$router.push({name: 'formSysDeptPost', query: params});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
deptId: row.deptId
};
this.$confirm('是否删除部门?').then(res => {
SysDeptController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.formSysDept.SysDeptList.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormSysDept();
},
initFormData () {
},
formInit () {
this.initFormData();
this.refreshFormSysDept();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,185 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="岗位名称">
<el-input class="filter-item" v-model="formSetDeptPost.formFilter.postName"
:clearable="true" placeholder="岗位名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSetDeptPost(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini"
:disabled="tableSelectRowList.length <= 0 || !checkPermCodeExist('formSysDept:fragmentSysDept:editPost')"
@click="onAddSysDeptPostClick()">
添加岗位
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSetDeptPost.SysPost.impl.dataList" size="mini" @sort-change="formSetDeptPost.SysPost.impl.onSortChange"
@selection-change="onSysPostSelectionChange" header-cell-class-name="table-header-gray">
<el-table-column label="序号" type="index" header-align="center" align="center" width="55px" :index="formSetDeptPost.SysPost.impl.getTableIndex" />
<el-table-column type="selection" header-align="center" align="center" width="55px" />
<el-table-column label="岗位名称" prop="postName">
</el-table-column>
<el-table-column label="岗位层级" prop="level" sortable="custom">
</el-table-column>
<el-table-column label="领导岗位" prop="leaderPost" sortable="custom">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.leaderPost ? 'success' : 'danger'">
{{scope.row.leaderPost ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSetDeptPost.SysPost.impl.totalCount"
:current-page="formSetDeptPost.SysPost.impl.currentPage"
:page-size="formSetDeptPost.SysPost.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSetDeptPost.SysPost.impl.onCurrentPageChange"
@size-change="formSetDeptPost.SysPost.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDeptController, DictionaryController } from '@/api';
export default {
name: 'formSetDeptPost',
props: {
deptId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
tableSelectRowList: [],
formSetDeptPost: {
formFilter: {
postName: undefined
},
formFilterCopy: {
postName: undefined
},
SysPost: {
impl: new TableWidget(this.loadSysPostWidgetData, this.loadSysPostVerify, true, false, 'level', 1)
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSysPostSelectionChange (values) {
this.tableSelectRowList = values;
},
/**
* 部门岗位数据获取函数返回Promise
*/
loadSysPostWidgetData (params) {
if (
this.deptId == null
) {
this.formSetDeptPost.SysPost.impl.clearTable();
return Promise.reject();
}
if (params == null) params = {};
params = {
...params,
deptId: this.deptId,
sysPostDtoFilter: {
postName: this.formSetDeptPost.formFilterCopy.postName
}
}
return new Promise((resolve, reject) => {
SysDeptController.listNotInSysDeptPost(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 部门岗位数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysPostVerify () {
this.formSetDeptPost.formFilterCopy.postName = this.formSetDeptPost.formFilter.postName;
return true;
},
/**
* 更新设置部门岗位
*/
refreshFormSetDeptPost (reloadData = false) {
if (reloadData) {
this.formSetDeptPost.SysPost.impl.refreshTable(true, 1);
} else {
this.formSetDeptPost.SysPost.impl.refreshTable();
}
if (!this.formSetDeptPost.isInit) {
// 初始化下拉数据
}
this.formSetDeptPost.isInit = true;
},
/**
* 添加岗位
*/
onAddSysDeptPostClick () {
if (
this.deptId == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
deptId: this.deptId,
sysDeptPostDtoList: this.tableSelectRowList.map((item) => {
return {
postId: item.postId,
postShowName: item.postName
};
})
};
SysDeptController.addSysDeptPost(this, params).then(res => {
this.$message.success('添加岗位成功');
this.onCancel(true);
}).catch(e => {});
},
initFormData () {
},
formInit () {
this.refreshFormSetDeptPost();
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,255 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="岗位名称">
<el-input class="filter-item" v-model="formSysDeptPost.formFilter.postName"
:clearable="true" placeholder="岗位名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysDeptPost(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:editPost')"
@click="onFormSetDeptPostClick()">
岗位设置
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table ref="sysPost" :data="formSysDeptPost.SysPost.impl.dataList" size="mini" @sort-change="formSysDeptPost.SysPost.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formSysDeptPost.SysPost.impl.getTableIndex" />
<el-table-column label="岗位名称" prop="postName">
</el-table-column>
<el-table-column label="岗位别名" prop="sysDeptPost.postShowName">
<template slot-scope="scope">
<span v-if="formSysDeptPost.SysPost.currentRow == null || formSysDeptPost.SysPost.currentRow.postId !== scope.row.postId">{{(scope.row.sysDeptPost || {}).postShowName}}</span>
<el-input v-else size="mini" v-model="formSysDeptPost.SysPost.currentRow.sysDeptPost.postShowName" />
</template>
</el-table-column>
<el-table-column label="岗位层级" prop="level" sortable="custom">
</el-table-column>
<el-table-column label="领导岗位" prop="leaderPost" sortable="custom">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.leaderPost ? 'success' : 'danger'">
{{scope.row.leaderPost ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button v-if="formSysDeptPost.SysPost.currentRow == null"
@click.stop="onEditPostName(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:editPost')">
修改别名
</el-button>
<el-button class="table-btn delete" v-if="formSysDeptPost.SysPost.currentRow == null"
@click.stop="onDeleteSysDeptPostClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysDept:fragmentSysDept:editPost')">
移除
</el-button>
<el-button v-if="formSysDeptPost.SysPost.currentRow != null && formSysDeptPost.SysPost.currentRow.postId === scope.row.postId"
@click.stop="onSavePostName(scope.row)" type="text" size="mini">
保存
</el-button>
<el-button v-if="formSysDeptPost.SysPost.currentRow != null && formSysDeptPost.SysPost.currentRow.postId === scope.row.postId"
@click.stop="onCancelSavePostName(scope.row)" type="text" size="mini">
取消
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysDeptPost.SysPost.impl.totalCount"
:current-page="formSysDeptPost.SysPost.impl.currentPage"
:page-size="formSysDeptPost.SysPost.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysDeptPost.SysPost.impl.onCurrentPageChange"
@size-change="formSysDeptPost.SysPost.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
<label v-if="closeVisible == '1'" class="page-close-box">
<el-button type="text" @click="onCancel(true)" icon="el-icon-close" />
</label>
</div>
</template>
<script>
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysDeptController, DictionaryController } from '@/api';
import formSetDeptPost from './formSetDeptPost.vue';
export default {
name: 'formSysDeptPost',
props: {
deptId: {
default: undefined
},
closeVisible: {
type: [Number, String],
default: 0
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin],
data () {
return {
formSysDeptPost: {
formFilter: {
postName: undefined
},
formFilterCopy: {
postName: undefined
},
SysPost: {
currentRow: undefined,
impl: new TableWidget(this.loadSysPostWidgetData, this.loadSysPostVerify, true, false, 'level', 1)
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
this.removeCachePage(this.$options.name);
this.refreshParentCachedPage = isSuccess;
this.$router.go(-1);
},
/**
* 部门岗位数据获取函数返回Promise
*/
loadSysPostWidgetData (params) {
if (
this.deptId == null
) {
this.formSysDeptPost.SysPost.impl.clearTable();
return Promise.reject();
}
if (params == null) params = {};
params = {
...params,
deptId: this.deptId,
sysPostDtoFilter: {
postName: this.formSysDeptPost.formFilterCopy.postName
}
}
return new Promise((resolve, reject) => {
SysDeptController.listSysDeptPost(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 部门岗位数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysPostVerify () {
this.formSysDeptPost.formFilterCopy.postName = this.formSysDeptPost.formFilter.postName;
return true;
},
/**
* 更新部门岗位
*/
refreshFormSysDeptPost (reloadData = false) {
if (reloadData) {
this.formSysDeptPost.SysPost.impl.refreshTable(true, 1);
} else {
this.formSysDeptPost.SysPost.impl.refreshTable();
}
if (!this.formSysDeptPost.isInit) {
// 初始化下拉数据
}
this.formSysDeptPost.isInit = true;
this.formSysDeptPost.SysPost.currentRow = null;
},
/**
* 修改别名
*/
onEditPostName (row) {
this.formSysDeptPost.SysPost.currentRow = row;
},
/**
* 保存别名
*/
onSavePostName (row) {
SysDeptController.updateSysDeptPost(this, {
sysDeptPostDto: {
deptPostId: row.sysDeptPost.deptPostId,
deptId: row.sysDeptPost.deptId,
postId: row.postId,
postShowName: this.formSysDeptPost.SysPost.currentRow.sysDeptPost.postShowName
}
}).then(res => {
this.refreshFormSysDeptPost();
}).catch(e => {});
},
onCancelSavePostName (row) {
this.refreshFormSysDeptPost();
},
/**
* 移除
*/
onDeleteSysDeptPostClick (row) {
if (
this.deptId == null ||
row.postId == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
deptId: this.deptId,
postId: row.postId
};
this.$confirm('是否从部门中移除此岗位?').then(res => {
SysDeptController.deleteSysDeptPost(this, params).then(res => {
this.$message.success('移除成功');
this.formSysDeptPost.SysPost.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
/**
* 添加岗位
*/
onFormSetDeptPostClick () {
let params = {
deptId: this.deptId
};
this.$dialog.show('岗位设置', formSetDeptPost, {
area: ['1200px', '600px']
}, params).then(res => {
this.refreshFormSysDeptPost();
}).catch(e => {});
},
onResume () {
this.refreshFormSysDeptPost();
},
initFormData () {
},
formInit () {
this.refreshFormSysDeptPost();
}
},
mounted () {
// 初始化页面数据
this.formInit();
console.log(this.closeVisible);
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,146 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="登录名称">
<el-input class="filter-item" v-model="formSysLoginUser.formFilter.loginName" :clearable="true" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormOperationType(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table ref="teacher" :data="formSysLoginUser.loginUser.impl.dataList" size="mini" @sort-change="formSysLoginUser.loginUser.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formSysLoginUser.loginUser.impl.getTableIndex" />
<el-table-column label="登录名称" prop="loginName" />
<el-table-column label="用户昵称" prop="showName" />
<el-table-column label="登录 IP" prop="loginIp" />
<el-table-column label="登录时间" prop="loginTime" />
<el-table-column label="操作" fixed="right" width="150px" >
<template slot-scope="scope">
<el-button @click.stop="onDeleteLoginUserClick(scope.row)" type="text" size="mini">
强退
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysLoginUser.loginUser.impl.totalCount"
:current-page="formSysLoginUser.loginUser.impl.currentPage"
:page-size="formSysLoginUser.loginUser.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysLoginUser.loginUser.impl.onCurrentPageChange"
@size-change="formSysLoginUser.loginUser.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { TableWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController } from '@/api';
export default {
name: 'formSysLoginUser',
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysLoginUser: {
formFilter: {
loginName: undefined
},
formFilterCopy: {
loginName: undefined
},
loginUser: {
impl: new TableWidget(this.loadLoginUserWidgetData, this.loadLoginUserVerify, true, false)
},
isInit: false
}
}
},
methods: {
/**
* 登录用户数据数据获取函数返回Promise
*/
loadLoginUserWidgetData (params) {
if (params == null) params = {};
params = {
...params,
loginName: this.formSysLoginUser.formFilterCopy.loginName
}
return new Promise((resolve, reject) => {
SystemController.listSysLoginUser(this, params).then(res => {
console.log(res);
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 登录用户数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadLoginUserVerify () {
this.formSysLoginUser.formFilterCopy = { ...this.formSysLoginUser.formFilter };
return true;
},
/**
* 强制踢出登录用户
*/
onDeleteLoginUserClick (row) {
this.$confirm('是否删除此用户?').then(res => {
SystemController.deleteSysLoginUser(this, {
sessionId: row.sessionId
}).then(res => {
this.$message.success('删除成功');
this.formSysLoginUser.loginUser.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
/**
* 更新操作日志
*/
refreshFormOperationType (reloadData = false) {
if (reloadData) {
this.formSysLoginUser.loginUser.impl.refreshTable(true, 1);
} else {
this.formSysLoginUser.loginUser.impl.refreshTable();
}
if (!this.formSysLoginUser.isInit) {
// 初始化下拉数据
}
this.formSysLoginUser.isInit = true;
},
onResume () {
this.refreshFormOperationType();
},
initFormData () {
},
formInit () {
this.refreshFormOperationType();
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,307 @@
<template>
<div class="tab-dialog-box" style="position: relative;">
<el-tabs v-model="activeFragment">
<el-tab-pane label="栏目管理" name="fragmentSysColumn" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row type="flex" justify="end" style="margin-bottom: 18px;">
<el-button type="primary" size="mini" :plain="true"
@click="initFormData()">
刷新
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:add')"
@click="onCreateSysColumnClick()">
新建
</el-button>
</el-row>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="columnList" size="mini" :height="getTabPaneHeight + 'px'"
header-cell-class-name="table-header-gray" row-key="menuId">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" />
<el-table-column label="栏目名称" prop="columnName" />
<el-table-column label="显示顺序" prop="showOrder" />
<el-table-column label="操作" width="200px">
<template slot-scope="scope">
<el-button @click="onEditSysColumnClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:update')">
编辑
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="菜单管理" name="fragmentSysMenu" style="width: 100%;">
<el-form label-width="80px" size="mini" label-position="right" @submit.native.prevent>
<el-row>
<el-col :span="12">
<el-form-item label="所属栏目" style="flex-grow: 1">
<el-select class="filter-item" v-model="currentColumnId" filterable
placeholder="所属栏目">
<el-option v-for="item in columnList" :key="item.columnId" :value="item.columnId" :label="item.columnName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="initFormData(true)">
刷新
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:add')"
@click="onCreateSysMenuClick()">
新建
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="currentMenuTree" size="mini" :height="getTabPaneHeight + 'px'"
header-cell-class-name="table-header-gray" row-key="menuId">
<el-table-column label="菜单名称" prop="menuName" width="300px">
</el-table-column>
<el-table-column label="菜单图标" prop="icon" width="100px">
<template slot-scope="scope">
<i :class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column label="菜单顺序" prop="showOrder" width="100px">
</el-table-column>
<el-table-column label="菜单类型" prop="menuType" width="100px">
<template slot-scope="scope">
<el-tag size="mini" :type="getMenuType(scope.row)">{{SysMenuType.getValue(scope.row.menuType)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="菜单路由" prop="formRouterName" min-width="250px">
</el-table-column>
<el-table-column label="操作" width="200px">
<template slot-scope="scope">
<el-button @click="onEditSysMenuClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:update')">
编辑
</el-button>
<el-button @click="onAddChildSysMenuClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:add') || scope.row.menuType === SysMenuType.BUTTON">
添加
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:delete')">
删除
</el-button>
<el-button @click="onShowPermList(scope.row)" type="text" size="mini"
v-if="checkPermCodeExist('formSysMenu:fragmentSysMenu:listSysMenuPermDetail')"
:disabled="scope.row.menuType === SysMenuType.DIRECTORY">
权限详情
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { treeDataTranslate } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { DictionaryController, SystemController } from '@/api';
import formEditSysMenu from '@/views/upms/formEditSysMenu';
import formMenuPerm from './formSysMenuPerm';
import formEditColumn from '@/views/upms/formEditSysMenu/editColumn.vue';
export default {
name: 'formSysMenu',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
activeFragment: 'fragmentSysColumn',
allMenuList: [],
menuTree: [],
currentColumnId: undefined,
formSysMenu: {
currentColumnId: {
impl: new DropdownWidget(this.loadCurrentColumnDropdownList, false, 'columnId', 'columnName'),
value: []
},
isInit: false
}
}
},
methods: {
getMenuType (row) {
if (row.menuType === 0) {
return 'primary'
} else if (row.menuType === 1) {
return 'success';
} else if (row.menuType === 2) {
return 'danger';
} else if (row.menuType === 3) {
return 'warning';
}
},
/**
* 新建栏目
*/
onCreateSysColumnClick () {
this.$dialog.show('新建', formEditColumn, {
area: ['500px']
}, {}).then(res => {
this.initFormData();
}).catch(e => {});
},
/**
* 编辑栏目
*/
onEditSysColumnClick (row) {
this.$dialog.show('编辑', formEditColumn, {
area: ['500px']
}, {
...row
}).then(res => {
this.initFormData();
}).catch(e => {});
},
/**
* 新建菜单
*/
onCreateSysMenuClick () {
let params = {
parentId: this.currentColumnId,
menuList: this.allMenuList
};
this.$dialog.show('新建', formEditSysMenu, {
area: ['800px']
}, params).then(res => {
this.initFormData();
}).catch(e => {});
},
/**
* 编辑菜单
*/
onEditSysMenuClick (row) {
SystemController.viewMenu(this, {menuId: row.menuId}).then(res => {
let params = {
rowData: res.data,
menuId: row.menuId,
menuList: this.allMenuList
};
this.$dialog.show('编辑', formEditSysMenu, {
area: ['800px']
}, params).then(res => {
this.formSysMenu.SysMenu.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
/**
* 添加子菜单
*/
onAddChildSysMenuClick (row) {
let params = {
parentId: row.menuId,
menuList: this.allMenuList
};
this.$dialog.show('添加子菜单', formEditSysMenu, {
area: ['800px']
}, params).then(res => {
this.formSysMenu.SysMenu.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
menuId: row.menuId
};
this.$confirm('是否删除此菜单项?').then(res => {
SystemController.deleteMenu(this, params).then(res => {
this.$message.success('删除成功');
this.formSysMenu.SysMenu.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
/**
* 权限详情
*/
onShowPermList (row) {
let params = {
menuId: row.menuId
};
this.$dialog.show('权限详情 - ' + row.menuName, formMenuPerm, {
area: '1200px',
offset: '30px'
}, params).catch(e => {
});
},
onResume () {
this.initFormData();
},
initFormData () {
SystemController.getMenuPermList(this, {}).then(res => {
this.allMenuList = res.data.map((item) => {
return {...item};
});
this.menuTree = treeDataTranslate(res.data, 'menuId');
// 获取默认的栏目
this.currentColumnId = undefined;
for (let i = 0; i < this.menuTree.length; i++) {
if (this.menuTree[i].menuType === this.SysMenuType.DIRECTORY) {
this.currentColumnId = this.menuTree[i].menuId;
break;
}
}
}).catch(e => {});
},
formInit () {
this.initFormData();
}
},
created () {
this.formInit();
},
computed: {
getTabPaneHeight () {
return (this.getMainContextHeight - 150);
},
currentMenuTree () {
if (this.currentColumnId == null || this.currentColumnId === '') return [];
for (let i = 0; i < this.menuTree.length; i++) {
if (this.menuTree[i].menuId === this.currentColumnId) return this.menuTree[i].children;
}
return [];
},
columnList () {
return this.menuTree.map((item) => {
return {
menuId: item.menuId,
columnId: item.menuId,
columnName: item.menuName,
showOrder: item.showOrder
};
});
},
...mapGetters(['getMainContextHeight'])
}
}
</script>

View File

@@ -0,0 +1,203 @@
<template>
<div class="tab-dialog-box" style="position: relative; margin-top: -15px;">
<el-tabs v-model="activeFragmentId">
<el-tab-pane label="权限资源" name="fragmentSysMenuPerm" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="URL">
<el-input class="filter-item" v-model="fragmentSysMenuPerm.formFilter.url" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshfragmentSysMenuPerm(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysMenuPerm.SysMenuPerm.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysMenuPerm.SysMenuPerm.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysMenuPerm.SysMenuPerm.impl.getTableIndex" />
<el-table-column label="权限字名称" prop="showName" width="150px">
</el-table-column>
<el-table-column label="权限字类型" width="100px">
<template slot-scope="scope">
<el-tag size="mini" :type="getPermCodeType(scope.row.permCodeType)">
{{SysPermCodeType.getValue(scope.row.permCodeType)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="权限字标识" prop="permCode" width="300px" />
<el-table-column label="权限名称" prop="permName" width="150px" />
<el-table-column label="关联URL" prop="url" min-width="300px">
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="用户查询" name="fragmentSysMenuUser" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="用户名">
<el-input class="filter-item" v-model="fragmentSysMenuUser.formFilter.loginName" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysMenuUser(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysMenuUser.SysMenuUser.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysMenuUser.SysMenuUser.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysMenuUser.SysMenuUser.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName" />
<el-table-column label="用户昵称" prop="showName" />
<el-table-column label="用户角色" prop="roleName" />
</el-table>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
import { SystemController } from '@/api';
export default {
name: 'SysMenuPerm',
props: {
menuId: {
type: String,
required: true
}
},
data () {
return {
activeFragmentId: 'fragmentSysMenuPerm',
fragmentSysMenuPerm: {
formFilter: {
url: undefined
},
formFilterCopy: {
url: undefined
},
SysMenuPerm: {
impl: new TableWidget(this.loadSysMenuPermData, this.loadSysMenuPermVerify, false, false)
}
},
fragmentSysMenuUser: {
formFilter: {
loginName: undefined
},
formFilterCopy: {
loginName: undefined
},
SysMenuUser: {
impl: new TableWidget(this.loadSysMenuUserData, this.loadSysMenuUserVerify, false, false)
}
}
}
},
methods: {
/**
* 获取菜单权限资源函数返回Promise
*/
loadSysMenuPermData (params) {
params.menuId = this.menuId;
params.url = this.fragmentSysMenuPerm.formFilterCopy.url;
return new Promise((resolve, reject) => {
SystemController.listSysPermByMenuIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 菜单权限资源获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysMenuPermVerify () {
this.fragmentSysMenuPerm.formFilterCopy.url = this.fragmentSysMenuPerm.formFilter.url;
return true;
},
getPermCodeType (permCodeType) {
switch (permCodeType) {
case this.SysPermCodeType.FORM: return 'primary';
case this.SysPermCodeType.FRAGMENT: return 'warning';
case this.SysPermCodeType.OPERATION: return 'success';
default: return 'info';
}
},
/**
* 更新菜单权限资源
*/
refreshfragmentSysMenuPerm (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysMenuPerm.SysMenuPerm.impl.refreshTable(true, 1);
} else {
this.fragmentSysMenuPerm.SysMenuPerm.impl.refreshTable();
}
},
/**
* 获取菜单用户函数返回Promise
*/
loadSysMenuUserData (params) {
params.menuId = this.menuId;
params.loginName = this.fragmentSysMenuUser.formFilterCopy.loginName;
return new Promise((resolve, reject) => {
SystemController.listSysUserByMenuIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 菜单用户获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysMenuUserVerify () {
if (this.fragmentSysMenuUser.formFilter.loginName == null || this.fragmentSysMenuUser.formFilter.loginName === '') {
this.$message.error('请输入用户名!');
return false;
}
this.fragmentSysMenuUser.formFilterCopy.loginName = this.fragmentSysMenuUser.formFilter.loginName;
return true;
},
/**
* 更新菜单用户
*/
refreshFragmentSysMenuUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysMenuUser.SysMenuUser.impl.refreshTable(true, 1);
} else {
this.fragmentSysMenuUser.SysMenuUser.impl.refreshTable();
}
}
},
computed: {
getTableHeight () {
return (this.getMainContextHeight - 150);
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,241 @@
<template>
<div>
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-button slot="operator" type="primary" size="mini" :plain="true"
@click="refreshFormSysMenu(true)">
刷新
</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:add')"
@click="onCreateSysMenuClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSysMenu.SysMenu.impl.dataList" size="mini"
header-cell-class-name="table-header-gray" row-key="menuId">
<el-table-column label="菜单名称" prop="menuName" width="300px">
</el-table-column>
<el-table-column label="菜单图标" prop="icon" width="100px">
<template slot-scope="scope">
<i :class="scope.row.icon" />
</template>
</el-table-column>
<el-table-column label="菜单顺序" prop="showOrder" width="100px">
</el-table-column>
<el-table-column label="菜单类型" prop="menuType" width="100px">
<template slot-scope="scope">
<el-tag size="mini" :type="getMenuType(scope.row)">{{SysMenuType.getValue(scope.row.menuType)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="菜单路由" prop="formRouterName" min-width="250px">
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="scope">
<el-button @click="onEditSysMenuClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:update') || (scope.row.onlineFormId != null && scope.row.menuType === SysMenuType.BUTTON)">
编辑
</el-button>
<el-button @click="onAddChildSysMenuClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:add') || scope.row.menuType === SysMenuType.BUTTON">
添加
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysMenu:fragmentSysMenu:delete') || (scope.row.onlineFormId != null && scope.row.menuType === SysMenuType.BUTTON)">
删除
</el-button>
<el-button @click="onShowPermList(scope.row)" type="text" size="mini"
v-if="checkPermCodeExist('formSysMenu:fragmentSysMenu:listSysMenuPermDetail')"
:disabled="scope.row.menuType === SysMenuType.DIRECTORY">
权限详情
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { treeDataTranslate } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { DictionaryController, SystemController } from '@/api';
import formEditSysMenu from '@/views/upms/formEditSysMenu';
import formMenuPerm from './formSysMenuPerm';
export default {
name: 'formSysMenu',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysMenu: {
formFilter: {
},
formFilterCopy: {
},
SysMenu: {
impl: new TableWidget(this.loadSysMenuData, this.loadSysMenuVerify, false)
},
isInit: false
}
}
},
methods: {
getMenuType (row) {
if (row.menuType === this.SysMenuType.DIRECTORY) {
return 'primary'
} else if (row.menuType === this.SysMenuType.MENU) {
return 'success';
} else if (row.menuType === this.SysMenuType.FRAGMENT) {
return 'danger';
} else if (row.menuType === this.SysMenuType.BUTTON) {
return 'warning';
}
},
/**
* 菜单数据数据获取函数返回Primise
*/
loadSysMenuData (params) {
return new Promise((resolve, reject) => {
SystemController.getMenuPermList(this, params).then(res => {
this.allMenuList = res.data.map((item) => {
return {...item};
});
resolve({
dataList: treeDataTranslate(res.data, 'menuId'),
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 菜单数据数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysMenuVerify () {
return true;
},
/**
* 菜单数据当前页变化函数
*/
onSysMenuCurrentPageChange (newPage) {
this.formSysMenu.SysMenu.impl.onCurrentPageChange(newPage);
},
/**
* 菜单数据每页显示数量变化函数(跳转回第一页)
*/
onSysMenuPageSizeChange (newPage) {
this.formSysMenu.SysMenu.impl.onPageSizeChange(newPage);
},
/**
* 更新菜单管理
*/
refreshFormSysMenu (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysMenu.SysMenu.impl.refreshTable(true, 1);
} else {
this.formSysMenu.SysMenu.impl.refreshTable();
}
this.formSysMenu.isInit = true;
},
/**
* 新建
*/
onCreateSysMenuClick () {
let params = {
menuList: this.allMenuList
};
this.$dialog.show('新建', formEditSysMenu, {
area: ['800px']
}, params).then(res => {
this.refreshFormSysMenu();
}).catch(e => {});
},
/**
* 编辑
*/
onEditSysMenuClick (row) {
SystemController.viewMenu(this, {menuId: row.menuId}).then(res => {
let params = {
rowData: res.data,
menuId: row.menuId,
menuList: this.allMenuList
};
this.$dialog.show('编辑', formEditSysMenu, {
area: ['800px']
}, params).then(res => {
this.formSysMenu.SysMenu.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
/**
* 添加子菜单
*/
onAddChildSysMenuClick (row) {
let params = {
parentId: row.menuId,
menuList: this.allMenuList
};
this.$dialog.show('添加子菜单', formEditSysMenu, {
area: ['800px']
}, params).then(res => {
this.formSysMenu.SysMenu.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
menuId: row.menuId
};
this.$confirm('是否删除此菜单项?').then(res => {
SystemController.deleteMenu(this, params).then(res => {
this.$message.success('删除成功');
this.formSysMenu.SysMenu.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
/**
* 权限详情
*/
onShowPermList (row) {
let params = {
menuId: row.menuId
};
this.$dialog.show('权限详情 - ' + row.menuName, formMenuPerm, {
area: '1200px',
offset: '30px'
}, params).catch(e => {
});
},
onResume () {
this.refreshFormSysMenu();
},
initFormData () {
},
formInit () {
this.initFormData();
this.refreshFormSysMenu();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,323 @@
<template>
<div class="tab-dialog-box" style="position: relative; margin-top: -15px;">
<el-tabs v-model="activeFragmentId">
<el-tab-pane label="用户查询" name="fragmentSysPermUser" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="用户名">
<el-input class="filter-item" v-model="fragmentSysPermUser.formFilter.loginName" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysPermUser(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysPermUser.SysUser.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysPermUser.SysUser.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysPermUser.SysUser.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName" />
<el-table-column label="用户昵称" prop="showName" />
<el-table-column label="用户角色" prop="roleName" />
<el-table-column label="权限字" prop="permCode" />
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="角色查询" name="fragmentSysPermRole" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="角色名称">
<el-input class="filter-item" v-model="fragmentSysPermRole.formFilter.roleName" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysPermRole(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysPermRole.SysRole.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysPermRole.SysRole.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysPermRole.SysRole.impl.getTableIndex" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="菜单类型" prop="permCodeType">
<template slot-scope="scope">
<el-tag size="mini" :type="getMenuType(scope.row)">{{SysMenuType.getValue(scope.row.menuType)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="角色名称" prop="roleName" />
<el-table-column label="权限字" prop="permCode" />
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="菜单查询" name="fragmentSysPermMenu" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="菜单名称">
<el-input class="filter-item" v-model="fragmentSysPermMenu.formFilter.menuName" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysPermMenu(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysPermMenu.SysMenu.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysPermMenu.SysMenu.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysPermMenu.SysMenu.impl.getTableIndex" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="菜单类型" prop="menuType">
<template slot-scope="scope">
<el-tag size="mini" :type="getMenuType(scope.row)">{{SysMenuType.getValue(scope.row.menuType)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="权限字" prop="permCode" />
</el-table>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
import { SystemController } from '@/api';
export default {
name: 'SysMenuPerm',
props: {
permId: {
type: String,
required: true
}
},
data () {
return {
activeFragmentId: 'fragmentSysPermUser',
menuMap: new Map(),
fragmentSysPermUser: {
formFilter: {
loginName: undefined
},
formFilterCopy: {
loginName: undefined
},
SysUser: {
impl: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, false, false)
}
},
fragmentSysPermRole: {
formFilter: {
roleName: undefined
},
formFilterCopy: {
roleName: undefined
},
SysRole: {
impl: new TableWidget(this.loadSysRoleData, this.loadSysRoleVerify, false, false)
}
},
fragmentSysPermMenu: {
formFilter: {
menuName: undefined
},
formFilterCopy: {
menuName: undefined
},
SysMenu: {
impl: new TableWidget(this.loadPermSysMenuData, this.loadPermSysMenuVerify, false, false)
}
}
}
},
methods: {
getMenuType (row) {
if (row.menuType === 0) {
return 'primary'
} else if (row.menuType === 1) {
return 'success';
} else if (row.menuType === 2) {
return 'danger';
} else if (row.menuType === 3) {
return 'warning';
}
},
/**
* 获取所有菜单项
*/
loadSysMenuData () {
return new Promise((resolve, reject) => {
SystemController.getMenuPermList(this, {}).then(res => {
res.data.forEach(item => {
this.menuMap.set(item.menuId, item);
});
resolve();
}).catch(e => {
reject(e);
});
});
},
getMenuPathById (menuId) {
if (menuId == null || menuId === '') return null;
let menuPath = [];
do {
let menuItem = this.menuMap.get(menuId);
if (menuItem != null) {
menuPath.unshift(menuItem);
menuId = menuItem.parentId;
} else {
menuId = null;
}
} while (menuId != null);
return menuPath;
},
getMenuPathString (menuPath) {
if (Array.isArray(menuPath) && menuPath.length > 0) {
return menuPath.map(item => item.menuName).join(' / ');
} else {
return null;
}
},
/**
* 获取用户函数返回Promise
*/
loadSysUserData (params) {
params.permId = this.permId;
params.loginName = this.fragmentSysPermUser.formFilterCopy.loginName;
return new Promise((resolve, reject) => {
SystemController.listSysUserByPermIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
if (this.fragmentSysPermUser.formFilter.loginName == null || this.fragmentSysPermUser.formFilter.loginName === '') {
this.$message.error('请输入用户名!');
return false;
}
this.fragmentSysPermUser.formFilterCopy.loginName = this.fragmentSysPermUser.formFilter.loginName;
return true;
},
/**
* 更新用户
*/
refreshFragmentSysPermUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysPermUser.SysUser.impl.refreshTable(true, 1);
} else {
this.fragmentSysPermUser.SysUser.impl.refreshTable();
}
},
/**
* 获取角色函数返回Promise
*/
loadSysRoleData (params) {
params.permId = this.permId;
params.roleName = this.fragmentSysPermRole.formFilterCopy.roleName;
return new Promise((resolve, reject) => {
SystemController.listSysRoleByPermIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 角色获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysRoleVerify () {
this.fragmentSysPermRole.formFilterCopy.roleName = this.fragmentSysPermRole.formFilter.roleName;
return true;
},
/**
* 更新角色
*/
refreshFragmentSysPermRole (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysPermRole.SysRole.impl.refreshTable(true, 1);
} else {
this.fragmentSysPermRole.SysRole.impl.refreshTable();
}
},
/**
* 获取菜单函数返回Promise
*/
loadPermSysMenuData (params) {
params.permId = this.permId;
params.menuName = this.fragmentSysPermMenu.formFilterCopy.menuName;
return new Promise((resolve, reject) => {
SystemController.listSysMenuByPermIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 角色获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadPermSysMenuVerify () {
this.fragmentSysPermMenu.formFilterCopy.menuName = this.fragmentSysPermMenu.formFilter.menuName;
return true;
},
/**
* 更新角色
*/
refreshFragmentSysPermMenu (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysPermMenu.SysMenu.impl.refreshTable(true, 1);
} else {
this.fragmentSysPermMenu.SysMenu.impl.refreshTable();
}
}
},
computed: {
getTableHeight () {
return (this.getMainContextHeight - 150);
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
this.loadSysMenuData().catch(e => {});
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,407 @@
<template>
<el-container class="advance-query-form">
<el-aside width="300px">
<el-card class="base-card" shadow="never" :body-style="{ padding: '0px' }" style="border: none;">
<div slot="header" class="base-card-header">
<span style="font-size: 16px; font-weight: 500; color: #282828;">权限模块</span>
<div class="base-card-operation">
<el-button type="text"
:disabled="!checkPermCodeExist('formSysPerm:fragmentSysPerm:addPermModule')"
icon="el-icon-circle-plus-outline" @click="onCreatePermModuleClick()" />
</div>
</div>
<el-scrollbar :style="{height: (getMainContextHeight - 56) + 'px'}" class="custom-scroll">
<el-tree ref="moduleTree" :data="getModuleTreeData" :props="{label: 'moduleName'}"
node-key="moduleId" @node-click="onModuleNodeClick" :default-expanded-keys="formPerm.expandedModule"
:highlight-current="true" @node-expand="onModuleNodeExpand" @node-collapse="onModuleNodeCollapse">
<div class="module-node-item" slot-scope="{ data }">
<div class="module-node-menu" :class="{group: data.moduleType === SysPermModuleType.GROUP}" v-if="!data.isAll">
<el-button type="text" size="mini" @click.stop="onEditpermModuleClick(data)" icon="el-icon-edit-outline"
:disabled="!checkPermCodeExist('formSysPerm:fragmentSysPerm:updatePermModule')"></el-button>
<el-button type="text" size="mini" v-show="data.moduleType === SysPermModuleType.GROUP"
:disabled="!checkPermCodeExist('formSysPerm:fragmentSysPerm:addPermModule')" icon="el-icon-circle-plus-outline"
@click.stop="onAddChildPermModuleClick(data)"></el-button>
<el-button type="text" size="mini" @click.stop="onDeleteModuleClick(data)" icon="el-icon-delete"
:disabled="!checkPermCodeExist('formSysPerm:fragmentSysPerm:deletePermModule')"></el-button>
</div>
<div class="module-node-text" :class="{group: data.moduleType === SysPermModuleType.GROUP}">
<div class="text">{{ data.moduleName }}</div>
</div>
</div>
</el-tree>
</el-scrollbar>
</el-card>
</el-aside>
<el-main style="margin-left: 15px; background-color: white; padding: 20px;">
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="关联URL">
<el-input class="filter-item" placeholder="URL模糊搜索" v-model="formPerm.formFilter.url"
size="mini" clearable />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormPerm(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysPerm:fragmentSysPerm:addPerm')"
@click="onCreatePermClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formPerm.SysPerm.impl.dataList" size="mini" @sort-change="formPerm.SysPerm.impl.onSortChange"
header-cell-class-name="table-header-gray" :height="(getMainContextHeight - 132) + 'px'">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px" :index="formPerm.SysPerm.impl.getTableIndex" />
<el-table-column label="权限名称" prop="permName" width="150px">
</el-table-column>
<el-table-column label="权限模块" prop="moduleIdDictMap.name" width="100px">
</el-table-column>
<el-table-column label="关联URL" prop="url" min-width="250px">
</el-table-column>
<el-table-column label="操作" fixed="right" width="150px">
<template slot-scope="scope">
<el-button @click="onEditPermModuleClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysPerm:fragmentSysPerm:updatePerm')">
编辑
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysPerm:fragmentSysPerm:deletePerm')">
删除
</el-button>
<el-button class="btn-table-primary" type="text" size="mini"
v-if="checkPermCodeExist('formSysPerm:fragmentSysPerm:listSysPermPermDetail')"
@click="onSysPermDetailClick(scope.row)">
权限详情
</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formPerm.SysPerm.impl.totalCount"
:current-page="formPerm.SysPerm.impl.currentPage"
:page-size="formPerm.SysPerm.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formPerm.SysPerm.impl.onCurrentPageChange"
@size-change="formPerm.SysPerm.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</el-main>
</el-container>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController } from '@/api';
import formEditSysPerm from '../formEditSysPerm';
import formEditSysPermModule from '../formEditSysPermModule';
import FormSysPermDetail from './formSysPermDetail.vue';
export default {
name: 'formSysPerm',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formPerm: {
formFilter: {
permModuleId: undefined,
url: undefined
},
formFilterCopy: {
permModuleId: undefined,
url: undefined
},
permModuleId: {
impl: new DropdownWidget(this.loadPermModuleIdDropdownList, true, 'moduleId', 'parentId')
},
SysPerm: {
impl: new TableWidget(this.loadSysPermData, this.loadSysPermVerify, true)
},
permModuleList: [],
expandedModule: [],
isInit: false
}
}
},
methods: {
/**
* 权限数据获取函数返回Primise
*/
loadSysPermData (params) {
params.sysPermDtoFilter = {
url: this.formPerm.formFilterCopy.url === '' ? undefined : this.formPerm.formFilterCopy.url,
moduleId: this.formPerm.formFilterCopy.permModuleId === '' ? undefined : this.formPerm.formFilterCopy.permModuleId
}
return new Promise((resolve, reject) => {
SystemController.getPermList(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 权限数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysPermVerify () {
this.formPerm.formFilterCopy.url = this.formPerm.formFilter.url;
this.formPerm.formFilterCopy.permModuleId = this.formPerm.formFilter.permModuleId;
return true;
},
/**
* 所属权限模块下拉数据获取函数
*/
loadPermModuleIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
SystemController.getPermGroupList(this, params).then(res => {
this.formPerm.permModuleList = res.data;
resolve(res.data);
}).catch(e => {
reject();
});
});
},
/**
* 所属权限模块下拉框显隐
*/
onPermModuleIdVisibleChange (show) {
this.formPerm.permModuleId.impl.onVisibleChange(show).catch(e => {});
},
/**
* 所属权限模块选中值改变
*/
onPermModuleIdValueChange (value) {
},
onSysPermDetailClick (row) {
this.$dialog.show('权限详情', FormSysPermDetail, {
area: '1200px',
offset: '30px'
}, {
permId: row.permId
}).then(res => {}).catch(e => {});
},
/**
* 更新权限管理
*/
refreshFormPerm (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formPerm.SysPerm.impl.refreshTable(true, 1);
} else {
this.formPerm.SysPerm.impl.refreshTable();
}
this.formPerm.permModuleId.impl.onVisibleChange(true).catch(e => {});
this.formPerm.isInit = true;
},
/**
* 新建
*/
onCreatePermClick () {
let params = {
currentPermGroupId: this.formPerm.formFilterCopy.permModuleId,
permModuleList: this.formPerm.permModuleId.impl.dropdownList
};
this.$dialog.show('新建', formEditSysPerm, {
area: ['600px']
}, params).then(res => {
this.refreshFormPerm();
}).catch(e => {});
},
/**
* 编辑
*/
onEditPermModuleClick (row) {
let params = {
moduleId: row.moduleId,
permId: row.permId,
rowData: row,
permModuleList: this.formPerm.permModuleId.impl.dropdownList
};
this.$dialog.show('编辑', formEditSysPerm, {
area: ['600px']
}, params).then(res => {
this.formPerm.SysPerm.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
permId: row.permId
};
this.$confirm('是否删除此权限?').then(res => {
SystemController.deletePerm(this, params).then(res => {
this.$message.success('删除成功');
this.formPerm.SysPerm.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormPerm();
},
initFormData () {
},
formInit () {
this.initFormData();
this.refreshFormPerm();
},
onModuleNodeClick (data) {
if (data.moduleType === this.SysPermModuleType.CONTROLLER) {
this.formPerm.formFilter.permModuleId = data.moduleId;
this.refreshFormPerm(true);
}
},
/**
* 新建模块
*/
onCreatePermModuleClick () {
let params = {
moduleType: this.SysPermModuleType.GROUP,
moduleList: this.formPerm.permModuleList
};
this.$dialog.show('新建模块', formEditSysPermModule, {
area: ['600px']
}, params).then(res => {
this.formPerm.permModuleId.impl.reloadDropdownData().catch(e => {});
}).catch(e => {});
},
/**
* 编辑模块
*/
onEditpermModuleClick (row) {
let params = {
moduleId: row.moduleId,
moduleType: row.moduleType,
rowData: row,
moduleList: this.formPerm.permModuleList
};
this.$dialog.show('编辑模块', formEditSysPermModule, {
area: ['600px']
}, params).then(res => {
this.formPerm.permModuleId.impl.reloadDropdownData().catch(e => {});
}).catch(e => {});
},
/**
* 删除
*/
onDeleteModuleClick (row) {
let params = {
moduleId: row.moduleId
};
this.$confirm('是否删除此模块?').then(res => {
SystemController.deletePermGroup(this, params).then(res => {
this.$message.success('删除成功');
this.formPerm.permModuleId.impl.reloadDropdownData(true).catch(e => {});
}).catch(e => {});
}).catch(e => {});
},
onAddChildPermModuleClick (row) {
let params = {
parentId: row.moduleId,
moduleType: this.SysPermModuleType.CONTROLLER,
moduleList: this.formPerm.permModuleList
};
this.$dialog.show('添加子模块', formEditSysPermModule, {
area: ['600px']
}, params).then(res => {
this.formPerm.permModuleId.impl.reloadDropdownData(true).catch(e => {});
}).catch(e => {});
},
onModuleNodeCollapse (data, node) {
let pos = this.formPerm.expandedModule.indexOf(data.moduleId);
if (pos !== -1) {
this.formPerm.expandedModule.splice(pos, 1);
}
},
onModuleNodeExpand (data, node) {
let pos = this.formPerm.expandedModule.indexOf(data.moduleId);
if (pos === -1) {
this.formPerm.expandedModule.push(data.moduleId);
}
}
},
computed: {
getModuleTreeData () {
let tempList = [{
moduleId: undefined,
moduleName: '全部',
moduleType: this.SysPermModuleType.CONTROLLER,
isAll: true
}];
return tempList.concat(this.formPerm.permModuleId.impl.dropdownList);
},
...mapGetters(['getMainContextHeight'])
},
created () {
this.formInit();
}
}
</script>
<style scoped>
>>> .el-tree-node__content {
height: 35px;
}
>>> .el-tree-node__content .is-leaf {
display: none;
}
.module-node-item {
width: 100%;
height: 35px;
line-height: 35px;
}
.module-node-menu {
float: right;
width: 56px;
}
.module-node-menu.group {
width: 84px;
}
.module-node-text {
width: 100%;
margin-right: 56px;
}
.module-node-text.group {
margin-right: 84px;
}
.el-tree-node__content .is-leaf + .module-node-item .module-node-text {
padding-left: 24px;
}
.module-node-text .text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

View File

@@ -0,0 +1,253 @@
<template>
<div class="tab-dialog-box" style="position: relative; margin-top: -15px;">
<el-tabs v-model="activeFragmentId">
<el-tab-pane label="用户查询" name="fragmentSysPermCodeUser" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="用户名">
<el-input class="filter-item" v-model="fragmentSysPermCodeUser.formFilter.loginName" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysPermCodeUser(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysPermCodeUser.SysUser.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysPermCodeUser.SysUser.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysPermCodeUser.SysUser.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName" />
<el-table-column label="用户昵称" prop="showName" />
<el-table-column label="用户角色" prop="roleName" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="菜单类型" prop="permCodeType">
<template slot-scope="scope">
<el-tag size="mini" :type="getMenuType(scope.row)">{{SysMenuType.getValue(scope.row.menuType)}}</el-tag>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="角色查询" name="fragmentSysPermCodeRole" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="角色名称">
<el-input class="filter-item" v-model="fragmentSysPermCodeRole.formFilter.roleName" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysPermCodeRole(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysPermCodeRole.SysRole.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysPermCodeRole.SysRole.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysPermCodeRole.SysRole.impl.getTableIndex" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="菜单类型" prop="permCodeType">
<template slot-scope="scope">
<el-tag size="mini" :type="getMenuType(scope.row)">{{SysMenuType.getValue(scope.row.menuType)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="角色名称" prop="roleName" />
</el-table>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
import { SystemController } from '@/api';
export default {
name: 'SysMenuPerm',
props: {
permCodeId: {
type: String,
required: true
}
},
data () {
return {
activeFragmentId: 'fragmentSysPermCodeUser',
menuMap: new Map(),
fragmentSysPermCodeUser: {
formFilter: {
loginName: undefined
},
formFilterCopy: {
loginName: undefined
},
SysUser: {
impl: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, false, false)
}
},
fragmentSysPermCodeRole: {
formFilter: {
roleName: undefined
},
formFilterCopy: {
roleName: undefined
},
SysRole: {
impl: new TableWidget(this.loadSysRoleData, this.loadSysRoleVerify, false, false)
}
}
}
},
methods: {
getMenuType (row) {
if (row.menuType === 0) {
return 'primary'
} else if (row.menuType === 1) {
return 'success';
} else if (row.menuType === 2) {
return 'danger';
} else if (row.menuType === 3) {
return 'warning';
}
},
/**
* 获取所有菜单项
*/
loadSysMenuData () {
return new Promise((resolve, reject) => {
SystemController.getMenuPermList(this, {}).then(res => {
res.data.forEach(item => {
this.menuMap.set(item.menuId, item);
});
resolve();
}).catch(e => {
reject(e);
});
});
},
getMenuPathById (menuId) {
if (menuId == null || menuId === '') return null;
let menuPath = [];
do {
let menuItem = this.menuMap.get(menuId);
if (menuItem != null) {
menuPath.unshift(menuItem);
menuId = menuItem.parentId;
} else {
menuId = null;
}
} while (menuId != null);
return menuPath;
},
getMenuPathString (menuPath) {
if (Array.isArray(menuPath) && menuPath.length > 0) {
return menuPath.map(item => item.menuName).join(' / ');
} else {
return null;
}
},
/**
* 获取用户函数返回Promise
*/
loadSysUserData (params) {
params.permCodeId = this.permCodeId;
params.loginName = this.fragmentSysPermCodeUser.formFilterCopy.loginName;
return new Promise((resolve, reject) => {
SystemController.listSysUserByPermCodeIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
if (this.fragmentSysPermCodeUser.formFilter.loginName == null || this.fragmentSysPermCodeUser.formFilter.loginName === '') {
this.$message.error('请输入用户名!');
return false;
}
this.fragmentSysPermCodeUser.formFilterCopy.loginName = this.fragmentSysPermCodeUser.formFilter.loginName;
return true;
},
/**
* 更新用户
*/
refreshFragmentSysPermCodeUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysPermCodeUser.SysUser.impl.refreshTable(true, 1);
} else {
this.fragmentSysPermCodeUser.SysUser.impl.refreshTable();
}
},
/**
* 获取角色函数返回Promise
*/
loadSysRoleData (params) {
params.permCodeId = this.permCodeId;
params.roleName = this.fragmentSysPermCodeRole.formFilterCopy.roleName;
return new Promise((resolve, reject) => {
SystemController.listSysRoleByPermCodeIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 角色获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysRoleVerify () {
this.fragmentSysPermCodeRole.formFilterCopy.roleName = this.fragmentSysPermCodeRole.formFilter.roleName;
return true;
},
/**
* 更新角色
*/
refreshFragmentSysPermCodeRole (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysPermCodeRole.SysRole.impl.refreshTable(true, 1);
} else {
this.fragmentSysPermCodeRole.SysRole.impl.refreshTable();
}
}
},
computed: {
getTableHeight () {
return (this.getMainContextHeight - 150);
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
this.loadSysMenuData().catch(e => {});
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,270 @@
<template>
<div>
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="权限字名称">
<el-input class="filter-item" v-model="formPermCode.formFilter.showName"
:clearable="true" placeholder="权限字名称" />
</el-form-item>
<el-button slot="operator" type="primary" size="mini" :plain="true" @click="refreshFormPermCode(true)">
查询
</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysPermCode:fragmentSysPermCode:add')"
@click="onCreatePermCodeClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="getPermCodeList" size="mini" @sort-change="formPermCode.SysPermCode.impl.onSortChange"
row-key="permCodeId" header-cell-class-name="table-header-gray">
<el-table-column label="权限字名称" prop="showName" width="250px">
</el-table-column>
<el-table-column label="权限字类型" prop="permCodeType" width="150px">
<template slot-scope="scope">
<el-tag size="mini" :type="getPermCodeType(scope.row.permCodeType)">{{SysPermCodeType.getValue(scope.row.permCodeType)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="显示顺序" prop="showOrder" width="100px">
</el-table-column>
<el-table-column label="权限字标识" prop="permCode" min-width="200px">
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="scope">
<el-button @click="onEditPermCodeClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysPermCode:fragmentSysPermCode:update')">
编辑
</el-button>
<el-button @click="onAddChildPermCodeClick(scope.row)" type="text" size="mini"
:disabled="scope.row.permCodeType === 2 || !checkPermCodeExist('formSysPermCode:fragmentSysPermCode:add')">
添加
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysPermCode:fragmentSysPermCode:delete')">
删除
</el-button>
<el-button class="btn-table-primary" type="text" size="mini"
v-if="checkPermCodeExist('formSysPermCode:fragmentSysPermCode:listSysPermCodePermDetail')"
@click="onSysPermCodeDetailClick(scope.row)">
权限详情
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { treeDataTranslate } from '@/utils';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController } from '@/api';
import formEditSysPermCode from '@/views/upms/formEditSysPermCode';
import FormSysPermCodeDetail from '@/views/upms/formSysPermCode/formSysPermCodeDetail.vue';
export default {
name: 'formSysPermCode',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formPermCode: {
formFilter: {
showName: undefined
},
formFilterCopy: {
showName: undefined
},
SysPermCode: {
impl: new TableWidget(this.loadSysPermCodeData, this.loadSysPermCodeVerify, false, false, 'showOrder', 1),
totalCount: 0,
sortInfo: {
orderField: 'showOrder',
asc: 1
}
},
isInit: false
}
}
},
methods: {
getPermCodeType (permCodeType) {
switch (permCodeType) {
case this.SysPermCodeType.FORM: return 'primary';
case this.SysPermCodeType.FRAGMENT: return 'warning';
case this.SysPermCodeType.OPERATION: return 'success';
default: return 'info';
}
},
/**
* 权限资源数据获取函数返回Primise
*/
loadSysPermCodeData (params) {
return new Promise((resolve, reject) => {
SystemController.getPermCodeList(this, params).then(res => {
resolve({
dataList: treeDataTranslate(res.data, 'permCodeId'),
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 权限资源数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysPermCodeVerify () {
this.formPermCode.formFilterCopy.showName = this.formPermCode.formFilter.showName;
return true;
},
/**
* 权限资源当前页变化函数
*/
onSysPermCodeCurrentPageChange (newPage) {
this.formPermCode.SysPermCode.impl.onCurrentPageChange(newPage);
},
/**
* 权限资源每页显示数量变化函数(跳转回第一页)
*/
onSysPermCodePageSizeChange (newPage) {
this.formPermCode.SysPermCode.impl.onPageSizeChange(newPage);
},
/**
* 权限资源列排序变化函数
*/
onSysPermCodeSortChange ({ column, prop, order }) {
this.formPermCode.SysPermCode.sortInfo.orderField = prop;
this.formPermCode.SysPermCode.sortInfo.asc = (order === 'ascending');
this.formPermCode.SysPermCode.impl.refreshTable();
},
onSysPermCodeDetailClick (row) {
this.$dialog.show('权限详情', FormSysPermCodeDetail, {
area: '1200px',
offset: '30px'
}, {
permCodeId: row.permCodeId
}).then(res => {}).catch(e => {});
},
/**
* 更新权限资源管理
*/
refreshFormPermCode (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formPermCode.SysPermCode.impl.refreshTable(true, 1);
} else {
this.formPermCode.SysPermCode.impl.refreshTable();
}
this.formPermCode.isInit = true;
},
/**
* 添加
*/
onCreatePermCodeClick () {
let params = {
permCodeTree: this.formPermCode.SysPermCode.impl.dataList
};
this.$dialog.show('添加', formEditSysPermCode, {
area: ['800px', '583px']
}, params).then(res => {
this.refreshFormPermCode();
}).catch(e => {});
},
/**
* 编辑
*/
onEditPermCodeClick (row) {
SystemController.viewPermCode(this, {
permCodeId: row.permCodeId
}).then(res => {
let params = {
permCodeTree: this.formPermCode.SysPermCode.impl.dataList,
permCodeType: row.permCodeType,
rowData: res.data
};
return this.$dialog.show('编辑', formEditSysPermCode, {
area: ['800px', '583px']
}, params).then(res => {
this.formPermCode.SysPermCode.impl.refreshTable();
}).catch(e => {});
}).then(res => {
this.loadPermCodeData().catch(e => {});
}).catch(e => {
//
});
},
/**
* 添加权限字
*/
onAddChildPermCodeClick (row) {
let params = {
permCodeTree: this.formPermCode.SysPermCode.impl.dataList,
permCodeType: row.permCodeType + 1,
rowData: {
parentId: row.permCodeId
}
};
this.$dialog.show('添加权限字', formEditSysPermCode, {
area: ['800px', '583px']
}, params).then(res => {
this.formPermCode.SysPermCode.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
permCodeId: row.permCodeId
};
this.$confirm('是否删除此权限字?').then(res => {
SystemController.deletePermCode(this, params).then(res => {
this.$message.success('删除成功');
this.formPermCode.SysPermCode.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormPermCode();
},
initFormData () {
},
formInit () {
this.initFormData();
this.refreshFormPermCode();
}
},
computed: {
getPermCodeList () {
try {
if (Array.isArray(this.formPermCode.SysPermCode.impl.dataList)) {
let temp = this.formPermCode.SysPermCode.impl.dataList.filter((item) => {
if (this.formPermCode.formFilterCopy.showName == null || this.formPermCode.formFilterCopy.showName === '') return true;
return (item.showName.indexOf(this.formPermCode.formFilterCopy.showName) !== -1);
});
return temp;
}
} catch (e) {
console.log(e);
}
return [];
},
...mapGetters(['getMainContextHeight'])
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,200 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="岗位名称">
<el-input class="filter-item" v-model="formSysPost.formFilter.postName"
:clearable="true" placeholder="岗位名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysPost(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysPost:fragmentSysPost:add')"
@click="onFormAddPostClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table ref="sysPost" :data="formSysPost.sysPost.impl.dataList" size="mini" @sort-change="formSysPost.sysPost.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formSysPost.sysPost.impl.getTableIndex" />
<el-table-column label="岗位名称" prop="postName">
</el-table-column>
<el-table-column label="岗位层级" prop="level" sortable="custom">
</el-table-column>
<el-table-column label="领导岗位" prop="leaderPost" sortable="custom">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.leaderPost ? 'success' : 'danger'">
{{scope.row.leaderPost ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button @click.stop="onFormEditPostClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysPost:fragmentSysPost:update')">
编辑
</el-button>
<el-button class="table-btn delete" @click.stop="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysPost:fragmentSysPost:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysPost.sysPost.impl.totalCount"
:current-page="formSysPost.sysPost.impl.currentPage"
:page-size="formSysPost.sysPost.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysPost.sysPost.impl.onCurrentPageChange"
@size-change="formSysPost.sysPost.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SysPostController, DictionaryController } from '@/api';
import formEditPost from '@/views/upms/formEditSysPost/index.vue';
export default {
name: 'formSysPost',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysPost: {
formFilter: {
postName: undefined
},
formFilterCopy: {
postName: undefined
},
sysPost: {
impl: new TableWidget(this.loadSysPostWidgetData, this.loadSysPostVerify, true, false, 'level', 1)
},
isInit: false
}
}
},
methods: {
/**
* 岗位管理数据获取函数返回Promise
*/
loadSysPostWidgetData (params) {
if (params == null) params = {};
params = {
...params,
sysPostDtoFilter: {
postName: this.formSysPost.formFilterCopy.postName
}
}
return new Promise((resolve, reject) => {
SysPostController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 岗位管理数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysPostVerify () {
this.formSysPost.formFilterCopy.postName = this.formSysPost.formFilter.postName;
return true;
},
/**
* 更新岗位管理
*/
refreshFormSysPost (reloadData = false) {
if (reloadData) {
this.formSysPost.sysPost.impl.refreshTable(true, 1);
} else {
this.formSysPost.sysPost.impl.refreshTable();
}
if (!this.formSysPost.isInit) {
// 初始化下拉数据
}
this.formSysPost.isInit = true;
},
/**
* 新建
*/
onFormAddPostClick () {
let params = {};
this.$dialog.show('新建', formEditPost, {
area: '600px'
}, params).then(res => {
this.refreshFormSysPost();
}).catch(e => {});
},
/**
* 编辑
*/
onFormEditPostClick (row) {
let params = {
postId: row.postId
};
this.$dialog.show('编辑', formEditPost, {
area: '600px'
}, params).then(res => {
this.formSysPost.sysPost.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
if (
row.postId == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
postId: row.postId
};
this.$confirm('是否删除此岗位?').then(res => {
SysPostController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.formSysPost.sysPost.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormSysPost();
},
initFormData () {
},
formInit () {
this.refreshFormSysPost();
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,254 @@
<template>
<div class="tab-dialog-box" style="position: relative; margin-top: -15px;">
<el-tabs v-model="activeFragmentId">
<el-tab-pane label="权限资源" name="fragmentSysRolePerm" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="URL">
<el-input class="filter-item" v-model="fragmentSysRolePerm.formFilter.url" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshfragmentSysRolePerm(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysRolePerm.SysRolePerm.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysRolePerm.SysRolePerm.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysRolePerm.SysRolePerm.impl.getTableIndex" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="所属权限字" prop="permCode" />
<el-table-column label="URL" prop="url" />
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="权限字" name="fragmentSysRolePermCode" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="权限字">
<el-input class="filter-item" v-model="fragmentSysRolePermCode.formFilter.permCode" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshfragmentSysRolePermCode(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysRolePermCode.SysRolePermCode.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysRolePermCode.SysRolePermCode.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysRolePermCode.SysRolePermCode.impl.getTableIndex" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="权限字" prop="permCode" />
<el-table-column label="权限字类型" prop="permCodeType">
<template slot-scope="scope">
<el-tag size="mini" :type="getPermCodeType(scope.row.permCodeType)">{{SysPermCodeType.getValue(scope.row.permCodeType)}}</el-tag>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
import { SystemController } from '@/api';
export default {
name: 'SysRolePerm',
props: {
roleId: {
type: String,
required: true
}
},
data () {
return {
activeFragmentId: 'fragmentSysRolePerm',
menuMap: new Map(),
fragmentSysRolePerm: {
formFilter: {
url: undefined
},
formFilterCopy: {
url: undefined
},
SysRolePerm: {
impl: new TableWidget(this.loadSysRolePermData, this.loadSysRolePermVerify, false, false)
},
isInit: false
},
fragmentSysRolePermCode: {
formFilter: {
permCode: undefined
},
formFilterCopy: {
permCode: undefined
},
SysRolePermCode: {
impl: new TableWidget(this.loadSysRolePermCodeData, this.loadSysRolePermCodeVerify, false, false)
}
}
}
},
methods: {
getMenuType (row) {
if (row.menuType === 0) {
return 'primary'
} else if (row.menuType === 1) {
return 'success';
} else if (row.menuType === 2) {
return 'danger';
} else if (row.menuType === 3) {
return 'warning';
}
},
/**
* 获取所有菜单项
*/
loadSysMenuData () {
return new Promise((resolve, reject) => {
SystemController.getMenuPermList(this, {}).then(res => {
res.data.forEach(item => {
this.menuMap.set(item.menuId, item);
});
resolve();
}).catch(e => {
reject(e);
});
});
},
getMenuPathById (menuId) {
if (menuId == null || menuId === '') return null;
let menuPath = [];
do {
let menuItem = this.menuMap.get(menuId);
if (menuItem != null) {
menuPath.unshift(menuItem);
menuId = menuItem.parentId;
} else {
menuId = null;
}
} while (menuId != null);
return menuPath;
},
getMenuPathString (menuPath) {
if (Array.isArray(menuPath) && menuPath.length > 0) {
return menuPath.map(item => item.menuName).join(' / ');
} else {
return null;
}
},
/**
* 获取角色权限资源列表函数返回Promise
*/
loadSysRolePermData (params) {
params.roleId = this.roleId;
params.url = this.fragmentSysRolePerm.formFilterCopy.url;
return new Promise((resolve, reject) => {
SystemController.listSysPermByRoleIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 角色权限资源获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysRolePermVerify () {
this.fragmentSysRolePerm.formFilterCopy.url = this.fragmentSysRolePerm.formFilter.url;
return true;
},
/**
* 更新角色权限资源
*/
refreshfragmentSysRolePerm (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysRolePerm.SysRolePerm.impl.refreshTable(true, 1);
} else {
this.fragmentSysRolePerm.SysRolePerm.impl.refreshTable();
}
this.fragmentSysRolePerm.isInit = true;
},
/**
* 获取角色权限字列表函数返回Promise
*/
loadSysRolePermCodeData (params) {
params.roleId = this.roleId;
params.permCode = this.fragmentSysRolePermCode.formFilterCopy.permCode;
return new Promise((resolve, reject) => {
SystemController.listSysPermCodeByRoleIdWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 角色权限资源获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysRolePermCodeVerify () {
this.fragmentSysRolePermCode.formFilterCopy.permCode = this.fragmentSysRolePermCode.formFilter.permCode;
return true;
},
getPermCodeType (permCodeType) {
switch (permCodeType) {
case this.SysPermCodeType.FORM: return 'primary';
case this.SysPermCodeType.FRAGMENT: return 'warning';
case this.SysPermCodeType.OPERATION: return 'success';
default: return 'info';
}
},
/**
* 更新角色权限资源
*/
refreshfragmentSysRolePermCode (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysRolePermCode.SysRolePermCode.impl.refreshTable(true, 1);
} else {
this.fragmentSysRolePermCode.SysRolePermCode.impl.refreshTable();
}
this.fragmentSysRolePermCode.isInit = true;
}
},
computed: {
getTableHeight () {
return (this.getMainContextHeight - 150);
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
this.loadSysMenuData().catch(e => {});
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,473 @@
<template>
<div class="tab-dialog-box" style="position: relative;">
<el-tabs v-model="activeFragmentId" :before-leave="onFragmentChange">
<el-tab-pane label="角色管理" name="fragmentSysRole" style="width: 100%;"
v-if="checkPermCodeExist('formSysRole:fragmentSysRole')">
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="角色名称">
<el-input class="filter-item" v-model="fragmentSysRole.formFilter.sysRoleName"
:clearable="true" placeholder="角色名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysRole(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysRole:fragmentSysRole:add')"
@click="onAddSysRoleClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysRole.SysRole.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysRole.SysRole.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px"
:index="fragmentSysRole.SysRole.impl.getTableIndex" />
<el-table-column label="角色名称" prop="roleName">
</el-table-column>
<el-table-column label="操作" fixed="right" width="150px">
<template slot-scope="scope">
<el-button @click="onEditSysRoleClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysRole:fragmentSysRole:update')">
编辑
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysRole:fragmentSysRole:delete')">
删除
</el-button>
<el-button class="btn-table-primary" type="text" size="mini"
v-if="checkPermCodeExist('formSysRole:fragmentSysRole:listSysRolePermDetail')"
@click="onSysRolePermClick(scope.row)">
权限详情
</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="fragmentSysRole.SysRole.impl.totalCount"
:current-page="fragmentSysRole.SysRole.impl.currentPage"
:page-size="fragmentSysRole.SysRole.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="fragmentSysRole.SysRole.impl.onCurrentPageChange"
@size-change="fragmentSysRole.SysRole.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="用户授权" name="fragmentSysRoleUser" style="width: 100%;"
v-if="checkPermCodeExist('formSysRole:fragmentSysRoleUser')">
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="用户角色">
<el-select class="filter-item" v-model="fragmentSysRoleUser.formFilter.sysRoleId" clearable
placeholder="用户角色" :loading="fragmentSysRoleUser.sysRole.impl.loading"
@visible-change="fragmentSysRoleUser.sysRole.impl.onVisibleChange"
@change="onRoleChange">
<el-option v-for="item in fragmentSysRoleUser.sysRole.impl.dropdownList" :key="item.roleId" :value="item.roleId" :label="item.roleName" />
</el-select>
</el-form-item>
<el-form-item label="用户名">
<el-input class="filter-item" v-model="fragmentSysRoleUser.formFilter.sysUserLoginName"
:clearable="true" placeholder="输入用户名 / 昵称查询" @change="refreshFragmentSysRoleUser(true)" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysRoleUser(true)">
查询
</el-button>
<el-button slot="operator" type="primary" size="mini" @click="onAddRow()"
:disabled="!checkPermCodeExist('formSysRole:fragmentSysRoleUser:addUserRole') ||
fragmentSysRoleUser.formFilter.sysRoleId == null || fragmentSysRoleUser.formFilter.sysRoleId === ''">
添加用户
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysRoleUser.SysUser.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysRoleUser.SysUser.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px" :index="fragmentSysRoleUser.SysUser.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型">
<template slot-scope="scope">
<span>{{SysUserType.getValue(scope.row.userType)}}</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="80px">
<template slot-scope="scope">
<el-button class="btn-table-delete" type="text" size="mini"
:disabled="!checkPermCodeExist('formSysRole:fragmentSysRoleUser:deleteUserRole')"
@click="onDeleteRow(scope.row)">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="fragmentSysRoleUser.SysUser.impl.totalCount"
:current-page="fragmentSysRoleUser.SysUser.impl.currentPage"
:page-size="fragmentSysRoleUser.SysUser.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="fragmentSysRoleUser.SysUser.impl.onCurrentPageChange"
@size-change="fragmentSysRoleUser.SysUser.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController } from '@/api';
import formEditSysRole from '../formEditSysRole';
import formSetRoleUsers from '@/views/upms/formSetRoleUsers';
import FormSysRolePerm from './formSysRolePerm.vue';
export default {
name: 'formSysRole',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
activeFragmentId: undefined,
fragmentSysRole: {
formFilter: {
sysRoleName: undefined
},
formFilterCopy: {
sysRoleName: undefined
},
SysRole: {
impl: new TableWidget(this.loadSysRoleData, this.loadSysRoleVerify, true, false)
},
isInit: false
},
fragmentSysRoleUser: {
formFilter: {
sysRoleId: undefined,
sysUserLoginName: undefined
},
sysRole: {
impl: new DropdownWidget(this.loadSysRoleDropdownList)
},
SysUser: {
impl: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, true, false)
},
isInit: false
}
}
},
methods: {
/**
* 用户角色数据获取函数返回Primise
*/
loadSysRoleData (params) {
params.sysRoleDtoFilter = {
roleName: this.fragmentSysRole.formFilterCopy.sysRoleName
}
return new Promise((resolve, reject) => {
SystemController.getRoleList(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户角色数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysRoleVerify () {
this.fragmentSysRole.formFilterCopy.sysRoleName = this.fragmentSysRole.formFilter.sysRoleName;
return true;
},
/**
* 更新角色列表
*/
refreshFragmentSysRole (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysRole.SysRole.impl.refreshTable(true, 1);
} else {
this.fragmentSysRole.SysRole.impl.refreshTable();
}
this.fragmentSysRole.isInit = true;
},
/**
* 新建
*/
onAddSysRoleClick () {
let params = {};
this.$dialog.show('新建', formEditSysRole, {
area: ['800px', '500px'],
offset: '100px'
}, params).then(res => {
this.fragmentSysRoleUser.sysRole.impl.dirty = true;
this.refreshFragmentSysRole();
}).catch(e => {});
},
/**
* 编辑
*/
onEditSysRoleClick (row) {
this.loadRowData(row).then(rowData => {
return this.$dialog.show('编辑角色', formEditSysRole, {
area: ['600px', '500px']
}, {
rowData
});
}).then(res => {
if (row.roleId === this.fragmentSysRoleUser.formFilter.sysRoleId) {
this.fragmentSysRoleUser.formFilter.sysRoleId = undefined;
this.fragmentSysRoleUser.SysUser.impl.clearTable();
}
this.fragmentSysRoleUser.sysRole.impl.dirty = true;
this.fragmentSysRole.SysRole.impl.refreshTable();
}).catch((e) => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
roleId: row.roleId
};
this.$confirm('是否删除此角色?').then(res => {
SystemController.deleteRole(this, params).then(res => {
this.$message.success('删除成功');
if (row.roleId === this.fragmentSysRoleUser.formFilter.sysRoleId) {
this.fragmentSysRoleUser.formFilter.sysRoleId = undefined;
this.fragmentSysRoleUser.SysUser.impl.clearTable();
}
this.fragmentSysRoleUser.sysRole.impl.dirty = true;
this.fragmentSysRole.SysRole.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
loadRowData (row) {
return new Promise((resolve, reject) => {
var params = {
roleId: row.roleId
}
SystemController.getRole(this, params).then(res => {
if (typeof res.data.permsJsonData === 'string') {
res.data.permsJsonData = JSON.parse(res.data.permsJsonData);
}
resolve(res.data);
}).catch(e => {
reject(e);
});
});
},
buildFragmentPermCodeMap () {
this.permCodeList = [
{
key: 'fragmentSysRole',
permCode: 'formSysRole:fragmentSysRole',
refresh: this.refreshFragmentSysRole
},
{
key: 'fragmentSysRoleUser',
permCode: 'formSysRole:fragmentSysRoleUser',
refresh: this.refreshFragmentSysRoleUser
}
];
},
onFragmentChange (fragmentId) {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.permCodeList[i].key === fragmentId) {
this.activeFragmentId = fragmentId;
// if (this.permCodeList[i].refresh) this.permCodeList[i].refresh();
return true;
}
}
return false;
},
getActiveFragment () {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.permCodeList[i].key === this.activeFragmentId) {
return this.permCodeList[i];
}
}
},
/**
* 根据权限获取默认显示的fragment
*/
getDefaultFragment () {
for (let i = 0; i < this.permCodeList.length; i++) {
if (this.checkPermCodeExist(this.permCodeList[i].permCode)) {
this.activeFragmentId = this.permCodeList[i].key;
return this.permCodeList[i];
}
}
return undefined;
},
onRoleChange (value) {
this.refreshFragmentSysRoleUser(true);
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
onAddRow () {
if (this.fragmentSysRoleUser.formFilter.sysRoleId == null || this.fragmentSysRoleUser.formFilter.sysRoleId === '') {
this.$message.error('请选择角色');
return false;
}
this.$dialog.show('角色用户授权', formSetRoleUsers, {
area: ['1100px', '600px']
}, {
roleId: this.fragmentSysRoleUser.formFilter.sysRoleId
}).catch(e => {
this.refreshFragmentSysRoleUser(true);
});
},
onDeleteRow (row) {
this.$confirm('是否移除此用户?').then(res => {
let params = {
roleId: this.fragmentSysRoleUser.formFilter.sysRoleId,
userId: row.userId
}
return SystemController.deleteRoleUser(this, params);
}).then(res => {
this.$message.success('移除成功');
this.refreshFragmentSysRoleUser(true);
}).catch(e => {});
},
/**
* 用户管理数据获取函数返回Primise
*/
loadSysUserData (params) {
return new Promise((resolve, reject) => {
if (this.fragmentSysRoleUser.formFilter.sysRoleId == null || this.fragmentSysRoleUser.formFilter.sysRoleId === '') {
this.$message.error('请选择角色');
resolve({
dataList: [],
totalCount: 0
});
return;
}
params.roleId = this.fragmentSysRoleUser.formFilter.sysRoleId;
params.sysUserDtoFilter = {
loginName: this.fragmentSysRoleUser.formFilter.sysUserLoginName
}
SystemController.listRoleUser(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户管理数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
if (this.fragmentSysRoleUser.formFilter.sysRoleId == null || this.fragmentSysRoleUser.formFilter.sysRoleId === '') {
this.$message.error('请选择角色');
return false;
}
return true;
},
/**
* 角色下拉数据获取函数
*/
loadSysRoleDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
SystemController.getRoleList(this, params).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
onRuleChange (value) {
this.refreshFragmentSysRoleUser(true);
},
/**
* 权限详情
*/
onSysRolePermClick (row) {
this.$dialog.show('权限详情', FormSysRolePerm, {
area: '1200px',
offset: '30px'
}, {
roleId: row.roleId
}).then(res => {}).catch(e => {});
},
/**
* 更新用户管理
*/
refreshFragmentSysRoleUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysRoleUser.SysUser.impl.refreshTable(true, 1);
} else {
this.fragmentSysRoleUser.SysUser.impl.refreshTable();
}
this.fragmentSysRoleUser.sysRole.impl.onVisibleChange(true).catch(e => {});
this.fragmentSysRoleUser.isInit = true;
},
onResume () {
this.refreshFragmentSysRole();
},
initFormData () {
},
formInit () {
this.buildFragmentPermCodeMap();
let defaultFragment = this.getDefaultFragment();
if (defaultFragment == null) {
this.$message.error('您没有访问这个页面的权限,请与系统管理员联系!');
} else {
if (defaultFragment.refresh) defaultFragment.refresh();
}
}
},
computed: {
getTableHeight () {
return (this.getMainContextHeight - 192);
},
...mapGetters(['getMainContextHeight'])
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,335 @@
<template>
<div class="tab-dialog-box" style="position: relative; margin-top: -15px;">
<el-tabs v-model="activeFragmentId">
<el-tab-pane label="权限资源" name="fragmentSysUserPerm" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="URL">
<el-input class="filter-item" v-model="fragmentSysUserPerm.formFilter.url" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysUserPerm(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysUserPerm.SysUserPerm.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysUserPerm.SysUserPerm.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysUserPerm.SysUserPerm.impl.getTableIndex" />
<el-table-column label="所属角色" prop="roleName" width="150px" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="所属权限字" prop="permCode" />
<el-table-column label="URL" prop="url" />
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="权限字" name="fragmentSysUserPermCode" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="权限字">
<el-input class="filter-item" v-model="fragmentSysUserPermCode.formFilter.permCode" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysUserPermCode(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysUserPermCode.SysUserPermCode.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysUserPermCode.SysUserPermCode.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysUserPermCode.SysUserPermCode.impl.getTableIndex" />
<el-table-column label="所属角色" prop="roleName" width="150px" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="权限字" prop="permCode" />
<el-table-column label="权限字类型" prop="permCodeType">
<template slot-scope="scope">
<el-tag size="mini" :type="getPermCodeType(scope.row.permCodeType)">{{SysPermCodeType.getValue(scope.row.permCodeType)}}</el-tag>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="菜单权限" name="fragmentSysUserMenu" style="width: 100%;">
<el-form label-width="100px" size="mini" label-position="left" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="菜单名称">
<el-input class="filter-item" v-model="fragmentSysUserMenu.formFilter.menuName" clearable
placeholder="" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFragmentSysUserMenu(true)">查询</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="fragmentSysUserMenu.SysUserMenu.impl.dataList" size="mini" :height="getTableHeight + 'px'"
@sort-change="fragmentSysUserMenu.SysUserMenu.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px"
:index="fragmentSysUserPermCode.SysUserPermCode.impl.getTableIndex" />
<el-table-column label="所属角色" prop="roleName" width="150px" />
<el-table-column label="菜单">
<template slot-scope="scope">
<span>{{getMenuPathString(getMenuPathById(scope.row.menuId)) || scope.row.menuName}}</span>
</template>
</el-table-column>
<el-table-column label="菜单类型" prop="menuType">
<template slot-scope="scope">
<el-tag size="mini" :type="getMenuType(scope.row)">{{SysMenuType.getValue(scope.row.menuType)}}</el-tag>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
import { SystemController } from '@/api';
export default {
name: 'SysUserPerm',
props: {
userId: {
type: String,
required: true
}
},
data () {
return {
activeFragmentId: 'fragmentSysUserPerm',
menuMap: new Map(),
fragmentSysUserPerm: {
formFilter: {
url: undefined
},
formFilterCopy: {
url: undefined
},
SysUserPerm: {
impl: new TableWidget(this.loadSysUserPermData, this.loadSysUserPermVerify, false, false)
},
isInit: false
},
fragmentSysUserPermCode: {
formFilter: {
permCode: undefined
},
formFilterCopy: {
permCode: undefined
},
SysUserPermCode: {
impl: new TableWidget(this.loadSysUserPermCodeData, this.loadSysUserPermCodeVerify, false, false)
}
},
fragmentSysUserMenu: {
formFilter: {
menuName: undefined
},
formFilterCopy: {
menuName: undefined
},
SysUserMenu: {
impl: new TableWidget(this.loadSysUserMenuData, this.loadSysUserMenuVerify, false, false)
}
}
}
},
methods: {
getMenuType (row) {
if (row.menuType === 0) {
return 'primary'
} else if (row.menuType === 1) {
return 'success';
} else if (row.menuType === 2) {
return 'danger';
} else if (row.menuType === 3) {
return 'warning';
}
},
/**
* 获取所有菜单项
*/
loadSysMenuData () {
return new Promise((resolve, reject) => {
SystemController.getMenuPermList(this, {}).then(res => {
res.data.forEach(item => {
this.menuMap.set(item.menuId, item);
});
resolve();
}).catch(e => {
reject(e);
});
});
},
getMenuPathById (menuId) {
if (menuId == null || menuId === '') return null;
let menuPath = [];
do {
let menuItem = this.menuMap.get(menuId);
if (menuItem != null) {
menuPath.unshift(menuItem);
menuId = menuItem.parentId;
} else {
menuId = null;
}
} while (menuId != null);
return menuPath;
},
getMenuPathString (menuPath) {
if (Array.isArray(menuPath) && menuPath.length > 0) {
return menuPath.map(item => item.menuName).join(' / ');
} else {
return null;
}
},
/**
* 获取用户权限资源列表函数返回Promise
*/
loadSysUserPermData (params) {
params.userId = this.userId;
params.url = this.fragmentSysUserPerm.formFilterCopy.url;
return new Promise((resolve, reject) => {
SystemController.listSysPermWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户权限资源获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserPermVerify () {
this.fragmentSysUserPerm.formFilterCopy.url = this.fragmentSysUserPerm.formFilter.url;
return true;
},
/**
* 更新用户权限资源
*/
refreshFragmentSysUserPerm (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysUserPerm.SysUserPerm.impl.refreshTable(true, 1);
} else {
this.fragmentSysUserPerm.SysUserPerm.impl.refreshTable();
}
this.fragmentSysUserPerm.isInit = true;
},
/**
* 获取用户权限字列表函数返回Promise
*/
loadSysUserPermCodeData (params) {
params.userId = this.userId;
params.permCode = this.fragmentSysUserPermCode.formFilterCopy.permCode;
return new Promise((resolve, reject) => {
SystemController.listSysPermCodeWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户权限资源获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserPermCodeVerify () {
this.fragmentSysUserPermCode.formFilterCopy.permCode = this.fragmentSysUserPermCode.formFilter.permCode;
return true;
},
getPermCodeType (permCodeType) {
switch (permCodeType) {
case this.SysPermCodeType.FORM: return 'primary';
case this.SysPermCodeType.FRAGMENT: return 'warning';
case this.SysPermCodeType.OPERATION: return 'success';
default: return 'info';
}
},
/**
* 更新用户权限资源
*/
refreshFragmentSysUserPermCode (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysUserPermCode.SysUserPermCode.impl.refreshTable(true, 1);
} else {
this.fragmentSysUserPermCode.SysUserPermCode.impl.refreshTable();
}
this.fragmentSysUserPermCode.isInit = true;
},
/**
* 获取用户权限资源列表函数返回Promise
*/
loadSysUserMenuData (params) {
params.userId = this.userId;
params.menuName = this.fragmentSysUserMenu.formFilterCopy.menuName;
return new Promise((resolve, reject) => {
SystemController.listSysMenuWithDetail(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: res.data.length
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户权限资源获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserMenuVerify () {
this.fragmentSysUserMenu.formFilterCopy.menuName = this.fragmentSysUserMenu.formFilter.menuName;
return true;
},
/**
* 更新用户权限资源
*/
refreshFragmentSysUserMenu (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.fragmentSysUserMenu.SysUserMenu.impl.refreshTable(true, 1);
} else {
this.fragmentSysUserMenu.SysUserMenu.impl.refreshTable();
}
this.fragmentSysUserMenu.isInit = true;
}
},
computed: {
getTableHeight () {
return (this.getMainContextHeight - 150);
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
this.loadSysMenuData().catch(e => {});
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,282 @@
<template>
<div>
<el-form label-width="75px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="用户状态">
<el-select class="filter-item" v-model="formSysUser.formFilter.sysUserStatus" :clearable="true"
placeholder="用户状态" :loading="formSysUser.sysUserStatus.impl.loading"
@visible-change="formSysUser.sysUserStatus.impl.onVisibleChange"
@change="onSysUserStatusValueChange">
<el-option v-for="item in formSysUser.sysUserStatus.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="登录名称">
<el-input class="filter-item" v-model="formSysUser.formFilter.sysUserLoginName"
:clearable="true" placeholder="登录名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormSysUser(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formSysUser:fragmentSysUser:add')"
@click="onAddRow()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formSysUser.SysUser.impl.dataList" size="mini" @sort-change="formSysUser.SysUser.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="50px" :index="formSysUser.SysUser.impl.getTableIndex" />
<el-table-column label="用户名" prop="loginName" sortable="custom">
</el-table-column>
<el-table-column label="昵称" prop="showName">
</el-table-column>
<el-table-column label="账号类型" prop="userTypeDictMap.name" />
<el-table-column label="状态">
<template slot-scope="scope">
<el-tag :type="getUserStatusType(scope.row.userStatus)" size="mini">{{SysUserStatus.getValue(scope.row.userStatus)}}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="220px">
<template slot-scope="scope">
<el-button class="btn-table-edit" type="text" size="mini" @click="onEditRow(scope.row)"
:disabled="isAdmin(scope.row) || !checkPermCodeExist('formSysUser:fragmentSysUser:update')"
>
编辑
</el-button>
<el-button class="btn-table-delete" type="text" size="mini" @click="onDeleteRow(scope.row)"
:disabled="isAdmin(scope.row) || !checkPermCodeExist('formSysUser:fragmentSysUser:delete')"
>
删除
</el-button>
<el-button class="btn-table-delete" type="text" size="mini" @click="onResetPassword(scope.row)"
:disabled="!checkPermCodeExist('formSysUser:fragmentSysUser:resetPassword')"
>
重置密码
</el-button>
<el-button class="btn-table-primary" type="text" size="mini"
v-if="checkPermCodeExist('formSysUser:fragmentSysUser:listSysUserPermDetail')"
@click="onSysUserPermClick(scope.row)">
权限详情
</el-button>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysUser.SysUser.impl.totalCount"
:current-page="formSysUser.SysUser.impl.currentPage"
:page-size="formSysUser.SysUser.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysUser.SysUser.impl.onCurrentPageChange"
@size-change="formSysUser.SysUser.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SystemController, DictionaryController } from '@/api';
import editUser from '@/views/upms/formEditSysUser';
import FormSysUserPerm from './formSysUserPerm.vue';
export default {
name: 'formSysUser',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formSysUser: {
formFilter: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
formFilterCopy: {
sysUserStatus: undefined,
sysUserLoginName: undefined
},
sysUserStatus: {
impl: new DropdownWidget(this.loadSysUserStatusDropdownList)
},
SysUser: {
impl: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, true, false, 'createTime', 1)
},
isInit: false
}
}
},
methods: {
isAdmin (row) {
return (row.userType === this.SysUserType.ADMIN);
},
getUserStatusType (status) {
if (status === this.SysUserStatus.NORMAL) {
return 'success';
} else if (status === this.SysUserStatus.LOCKED) {
return 'danger';
} else {
return 'info';
}
},
onAddRow () {
this.$dialog.show('新建用户', editUser, {
area: '600px'
}).then((res) => {
this.refreshFormSysUser();
}).catch(() => {
});
},
onEditRow (row) {
this.loadRowData(row).then(rowData => {
this.$dialog.show('编辑用户', editUser, {
area: '600px'
}, {
rowData: rowData
}).then((res) => {
this.refreshFormSysUser();
}).catch(e => {
});
}).catch(e => {
//
});
},
onDeleteRow (row) {
let params = {
userId: row.userId
}
this.$confirm('是否删除用户?').then(res => {
return SystemController.deleteUser(this, params);
}).then(res => {
this.$message.success('删除成功');
this.refreshFormSysUser(true);
}).catch(e => {
//
});
},
onResetPassword (row) {
this.$confirm('是否重置用户密码?').then(res => {
return SystemController.resetUserPassword(this, {userId: row.userId});
}).then(res => {
this.$message.success('重置密码成功');
}).catch(e => {
//
});
},
/**
* 用户管理数据获取函数返回Primise
*/
loadSysUserData (params) {
params.sysUserDtoFilter = {
loginName: this.formSysUser.formFilterCopy.sysUserLoginName,
userStatus: this.formSysUser.formFilterCopy.sysUserStatus
}
return new Promise((resolve, reject) => {
SystemController.getUserList(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户管理数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
this.formSysUser.formFilterCopy.sysUserLoginName = this.formSysUser.formFilter.sysUserLoginName;
this.formSysUser.formFilterCopy.sysUserStatus = this.formSysUser.formFilter.sysUserStatus;
return true;
},
/**
* 用户状态下拉数据获取函数
*/
loadSysUserStatusDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSysUserStatus(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 用户状态下拉框显隐
*/
onSysUserStatusVisibleChange (show) {
this.formSysUser.sysUserStatus.impl.onVisibleChange(show).catch(e => {});
},
/**
* 用户状态选中值改变
*/
onSysUserStatusValueChange (value) {
},
/**
* 权限详情
*/
onSysUserPermClick (row) {
this.$dialog.show('权限详情', FormSysUserPerm, {
area: '1200px',
offset: '30px'
}, {
userId: row.userId
}).then(res => {}).catch(e => {});
},
/**
* 更新用户管理
*/
refreshFormSysUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysUser.SysUser.impl.refreshTable(true, 1);
} else {
this.formSysUser.SysUser.impl.refreshTable();
}
this.formSysUser.sysUserStatus.impl.onVisibleChange(true).catch(e => {});
this.formSysUser.isInit = true;
},
loadRowData (row) {
return new Promise((resolve, reject) => {
var params = {
userId: row.userId
}
SystemController.getUser(this, params).then(res => {
resolve(res.data);
}).catch(e => {
reject(e);
});
});
},
onResume () {
this.refreshFormSysUser();
},
initFormData () {
},
formInit () {
this.initFormData();
this.refreshFormSysUser();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,156 @@
<template>
<div>
<div class="title">
<p>浏览完每个功能过后自然会发现些与众不同然而这一切都是<span> 橙单 </span>生成的</p>
</div>
<el-row type="flex">
<div style="width: 100%;">
<el-card class="box-card" shadow="never" :body-style="{padding: '0px 20px'}">
<el-collapse v-model="currentItem">
<el-collapse-item title="选择我们的 5 个理由" name="1">
<ul class="item-list">
<li>是真正的生成器而非脚手架</li>
<li>技术选型包名作者署名都由您钦定</li>
<li>手把手教的操作指南和教学视频</li>
<li>详尽完善免费护眼的开发文档</li>
<li>全网超合理超低价商业授权就是撸顿串的价格</li>
</ul>
</el-collapse-item>
<el-collapse-item title="我们的技术选型" name="2">
<ul class="item-list">
<li>Element (Vue) / Ant Design (React) / ECharts / AntV / Axios / Webpack</li>
<li>Spring Boot / Spring Cloud / Spring Cloud Alibaba + Mybatis + Jwt</li>
<li>Hutool + Guava + Caffeine + Lombok + MapStruct + 通用 Mapper</li>
<li>Redis + Zookeeper + Nacos + Consul + Apollo + XXL-Job + Kafka + Seata</li>
<li>ELK + PinPoint / SkyWalking + Grafana + Prometheus</li>
</ul>
</el-collapse-item>
<el-collapse-item title="可快速上手的高质量代码" name="3">
<ul class="item-list">
<li>无任何二次封装只生成您最懂的代码</li>
<li>遵循阿里巴巴标准的代码规范</li>
<li>主流技术栈恣意组合对面试大有裨益</li>
<li>产品级代码强度层次清晰滴水不漏</li>
<li>15年架构师优化的每一处细节</li>
</ul>
</el-collapse-item>
<el-collapse-item title="设计理念和未来目标" name="4">
<ul class="item-list">
<li>全面实用的日志跟踪和服务监控体系</li>
<li>前沿的单表组合式设计使系统拆分SO EASY</li>
<li>先代码后SQL的原则让服务扩充更具弹性</li>
<li>统一的数据组装接口更高效的满足微服务的拆分与再合并</li>
<li>拥抱云原生架构更多可落地的实用功能正在开发之中</li>
</ul>
</el-collapse-item>
</el-collapse>
</el-card>
</div>
<el-card class="box-card" style="min-width: 450px; margin-left: 20px;" shadow="never" :body-style="{padding: '0px 20px'}">
<div class="item">
<span style="width: 120px;">产品名称</span>
<el-tag effect="dark">橙单代码生成器</el-tag>
</div>
<el-divider></el-divider>
<div class="item">
<span style="width: 120px;">网站首页</span>
<a href="http://www.orangeforms.com/" target="_blank">http://www.orangeforms.com/</a>
</div>
<el-divider></el-divider>
<div class="item">
<span style="width: 120px;">教学视频</span>
<a href="https://www.bilibili.com/video/BV1Wg4y1i7vP" target="_blank">https://www.bilibili.com/video/BV1Wg4y1i7vP</a>
</div>
<el-divider></el-divider>
<div class="item">
<span style="width: 120px;">操作指南</span>
<a href="http://www.orangeforms.com/orange-doc/" target="_blank">http://www.orangeforms.com/orange-doc/</a>
</div>
<el-divider></el-divider>
<div class="item">
<span style="width: 120px;">开发文档</span>
<a href="http://www.orangeforms.com/development-doc/" target="_blank">http://www.orangeforms.com/development-doc/</a>
</div>
<el-divider></el-divider>
<div class="item">
<span style="width: 120px;">开源代码</span>
<a href="https://gitee.com/orangeform/orange-admin" target="_blank">https://gitee.com/orangeform/orange-admin</a>
</div>
<el-divider></el-divider>
<div class="item">
<span style="width: 120px;">联系方式</span>
<span>
QQ群
<a target="_blank" style="margin-left: 5px;"
href="//shang.qq.com/wpa/qunwpa?idkey=590857a1b4c587e2be3d66b9a7e2015109772e777c6451c897dee393489b1661">
788581363
</a>
</span>
</div>
<el-divider></el-divider>
<div style="width: 100%; text-align: center; padding: 10px;">
<img src="../../assets/img/orange-group1.png" />
</div>
</el-card>
</el-row>
</div>
</template>
<script>
export default {
data () {
return {
currentItem: ['1', '2', '3', '4']
}
}
}
</script>
<style scoped>
>>> .el-collapse {
border: none;
}
>>> .el-divider--horizontal {
margin: 0px;
}
>>> .el-tag {
padding: 0px 30px;
}
</style>
<style lang="scss" scoped>
@import '@/assets/style/element-variables.scss';
.title {
border: 1px solid #EDEDED;
border-left-width: 5px;
border-left-color: $--color-primary;
margin-bottom: 20px;
}
.title p {
height: 40px;
line-height: 40px;
font-size: 16px;
margin: 0px;
padding-left: 20px;
}
.title p span {
font-size: 20px;
color: $--color-primary;
}
.item-list {
margin: 0px;
}
.item-list li {
margin: 10px 0px;
}
.item {
height: 48px;
display: flex;
align-items: center;
}
</style>

View File

@@ -0,0 +1,244 @@
<template>
<div class="flow-task" style="position: relative;">
<div class="task-title">
<div>
<span class="text">{{flowInfo.flowEntryName}}</span>
<el-tag v-if="flowInfo.taskName" effect="dark" size="mini" type="success">{{'当前节点' + flowInfo.taskName}}</el-tag>
<el-tag v-if="flowInfo.processInstanceInitiator" effect="dark" size="mini" type="info">{{'发起人' + flowInfo.processInstanceInitiator}}</el-tag>
</div>
</div>
<el-row type="flex" justify="space-between" style="margin-bottom: 15px;">
<el-radio-group size="small" v-model="currentPage" v-if="processInstanceId != null" style="min-width: 300px;">
<el-radio-button label="formInfo">表单信息</el-radio-button>
<el-radio-button v-if="processInstanceId != null" label="flowProcess">流程图</el-radio-button>
<el-radio-button v-if="processInstanceId != null" label="approveInfo">审批记录</el-radio-button>
</el-radio-group>
<el-row class="task-operation" type="flex" justify="end" style="width: 100%;">
<template v-if="$slots.operations">
<slot name="operations" />
</template>
<template v-else>
<el-button v-for="(operation, index) in operationList" :key="index"
size="small" :type="getButtonType(operation.type) || 'primary'" :plain="operation.plain || false"
@click="handlerOperation(operation)">
{{operation.label}}
</el-button>
</template>
</el-row>
</el-row>
<el-scrollbar class="custom-scroll" :style="{height: (getMainContextHeight - 140) + 'px'}">
<el-form ref="form" class="full-width-input" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<!-- 表单信息 -->
<el-row v-show="currentPage === 'formInfo'" type="flex" :key="formKey">
<slot />
</el-row>
<!-- 审批记录 -->
<el-row v-if="currentPage === 'approveInfo'" :gutter="20">
<el-col :span="24">
<el-table :data="flowTaskCommentList" size="mini" border header-cell-class-name="table-header-gray" :height="(getMainContextHeight - 150) + 'px'">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" />
<el-table-column label="流程环节" prop="taskName" width="200px" />
<el-table-column label="执行人" prop="createUsername" width="200px" />
<el-table-column label="操作" width="150px">
<template slot-scope="scope">
<el-tag size="mini" :type="getOperationTagType(scope.row.approvalType)" effect="dark">{{SysFlowTaskOperationType.getValue(scope.row.approvalType)}}</el-tag>
<el-tag v-if="scope.row.delegateAssginee != null" size="mini" type="success" effect="plain" style="margin-left: 10px;">{{scope.row.delegateAssginee}}</el-tag>
</template>
</el-table-column>
<el-table-column label="审批意见">
<template slot-scope="scope">
<span>{{scope.row.comment ? scope.row.comment : ''}}</span>
</template>
</el-table-column>
<el-table-column label="处理时间" prop="createTime" width="200px" />
</el-table>
</el-col>
</el-row>
<!-- 流程图 -->
<el-row v-show="currentPage === 'flowProcess'">
<ProcessViewer :style="{height: (getMainContextHeight - 148) + 'px'}"
:xml="processXml"
:finishedInfo="finishedInfo"
:allCommentList="flowTaskCommentList"
/>
</el-row>
</el-form>
</el-scrollbar>
<label class="page-close-box">
<el-button type="text" @click="onClose(true)" icon="el-icon-close" />
</label>
</div>
</template>
<script>
import '../package/theme/index.scss';
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import { cachedPageChildMixin } from '@/core/mixins';
import { FlowOperationController } from '@/api/flowController.js';
import ProcessViewer from '@/views/workflow/components/ProcessViewer.vue';
export default {
name: 'handlerFowTask',
props: {
// 流程实例id
processInstanceId: {
type: String
},
// 流程定义id
processDefinitionId: {
type: String
},
// 流程名称
flowEntryName: {
type: String
},
// 发起人
processInstanceInitiator: {
type: String
},
// 当前任务节点名称
taskName: {
type: String
},
// 当前任务节点操作列表
operationList: {
type: Array
}
},
components: {
ProcessViewer
},
mixins: [cachedPageChildMixin],
data () {
return {
formKey: new Date().getTime(),
currentPage: 'formInfo',
processXml: undefined,
finishedInfo: undefined,
flowInfo: {
taskName: this.taskName,
flowEntryName: this.flowEntryName,
processInstanceInitiator: this.processInstanceInitiator
},
flowTaskCommentList: []
}
},
methods: {
onClose () {
this.$emit('close');
},
getButtonType (type) {
switch (type) {
case this.SysFlowTaskOperationType.AGREE:
case this.SysFlowTaskOperationType.TRANSFER:
case this.SysFlowTaskOperationType.CO_SIGN:
case this.SysFlowTaskOperationType.MULTI_AGREE:
case this.SysFlowTaskOperationType.MULTI_SIGN:
return 'primary';
case this.SysFlowTaskOperationType.SAVE:
return 'success';
case this.SysFlowTaskOperationType.REFUSE:
case this.SysFlowTaskOperationType.PARALLEL_REFUSE:
case this.SysFlowTaskOperationType.MULTI_REFUSE:
return 'default';
default: return 'default';
}
},
getOperationTagType (type) {
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';
}
},
onStartFlow (operation) {
this.$emit('start', operation);
},
handlerOperation (operation) {
if (this.processInstanceId == null) {
this.onStartFlow(operation);
} else {
this.$emit('submit', operation);
}
},
getTaskHighlightData () {
if (this.processInstanceId == null || this.processInstanceId === '') {
return;
}
let params = {
processInstanceId: this.processInstanceId
}
FlowOperationController.viewHighlightFlowData(this, params).then(res => {
// 已完成节点
this.finishedInfo = res.data;
}).catch(e => {});
},
getTaskProcessXml () {
if (this.processDefinitionId == null || this.processDefinitionId === '') {
return;
}
let params = {
processDefinitionId: this.processDefinitionId
}
FlowOperationController.viewProcessBpmn(this, params).then(res => {
// 当前流程实例xml
this.processXml = res.data;
}).catch(e => {});
},
loadProcessCommentList () {
this.flowTaskCommentList = [];
if (this.processInstanceId == null || this.processInstanceId === '') {
return;
}
FlowOperationController.listFlowTaskComment(this, {
processInstanceId: this.processInstanceId
}).then(res => {
this.flowTaskCommentList = res.data;
}).catch(e => {});
}
},
computed: {
isReadOnly () {
return typeof this.readOnly === 'string' ? this.readOnly === 'true' : this.readOnly;
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
this.getTaskHighlightData();
this.getTaskProcessXml();
this.loadProcessCommentList();
}
}
</script>
<style scoped>
.task-title {
display: flex;
justify-content: space-between;
padding-bottom: 5px;
margin-bottom: 10px;
border-bottom: 3px solid #409EFF;
}
.task-title .text {
height: 28px;
line-height: 28px;
font-weight: 600;
font-size: 16px;
color: #383838;
}
.task-title .el-tag {
margin-left: 10px;
}
</style>

View File

@@ -0,0 +1,86 @@
<template>
<div class="process-design" style="display: flex; height: 100%;">
<MyProcessDesigner
:key="`designer-${reloadIndex}`"
v-model="xmlString"
v-bind="controlForm"
keyboard
ref="processDesigner"
:processId="flowEntryInfo.processDefinitionKey"
:processName="flowEntryInfo.processDefinitionName"
:events="[
'element.click',
'connection.added',
'connection.removed',
'connection.changed'
]"
@element-click="elementClick"
@init-finished="initModeler"
@event="handlerEvent"
@save="onSaveProcess"
/>
<MyProcessPenal :key="`penal-${reloadIndex}`" :bpmn-modeler="modeler" :prefix="controlForm.prefix" :width="600" class="process-panel" />
</div>
</template>
<script>
import Vue from 'vue';
import '../package/theme/index.scss';
import { MyProcessDesigner, MyProcessPenal } from '../package/index.js';
// 自定义元素选中时的弹出菜单(修改 默认任务 为 用户任务)
import CustomContentPadProvider from '../package/process-designer/plugins/content-pad';
// 自定义左侧菜单(修改 默认任务 为 用户任务)
import CustomPaletteProvider from '../package/process-designer/plugins/palette';
import { vuePlugin } from '../package/highlight';
import 'highlight.js/styles/atom-one-dark-reasonable.css';
Vue.use(vuePlugin);
export default {
name: 'ProcessDesigner',
props: {
flowEntryInfo: {
type: Object,
required: true
}
},
components: {
MyProcessDesigner,
MyProcessPenal
},
data () {
return {
reloadIndex: 0,
xmlString: this.flowEntryInfo.bpmnXml,
modeler: null,
controlForm: {
processId: '',
processName: '',
simulation: false,
labelEditing: false,
labelVisible: false,
prefix: 'flowable',
headerButtonSize: 'small',
additionalModel: [CustomContentPadProvider, CustomPaletteProvider]
}
}
},
methods: {
elementClick (element) {
this.element = element;
},
initModeler (modeler) {
setTimeout(() => {
this.modeler = modeler;
}, 10);
},
handlerEvent (eventName, element) {
},
onSaveProcess (saveData) {
this.$emit('save', saveData);
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,232 @@
<template>
<div class="process-viewer">
<div class="process-canvas" style="height: 100%;" ref="processCanvas" v-show="!isLoading" />
<!-- 自定义箭头样式用于已完成状态下流程连线箭头 -->
<defs ref="customDefs">
<marker id="sequenceflow-end-white-success" viewBox="0 0 20 20" refX="11" refY="10" markerWidth="10" markerHeight="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;"></path>
</marker>
<marker id="conditional-flow-marker-white-success" viewBox="0 0 20 20" refX="-1" refY="10" markerWidth="10" markerHeight="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;"></path>
</marker>
</defs>
<!-- 已完成节点悬浮弹窗 -->
<el-dialog class="comment-dialog" :title="dlgTitle || '审批记录'" :visible.sync="dialogVisible">
<el-row>
<el-table :data="taskCommentList" size="mini" border header-cell-class-name="table-header-gray" height="500px">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" />
<el-table-column label="执行人" prop="createUsername" width="150px" />
<el-table-column label="操作" width="150px">
<template slot-scope="scope">
<el-tag size="mini" :type="getOperationTagType(scope.row.approvalType)" effect="dark">{{SysFlowTaskOperationType.getValue(scope.row.approvalType)}}</el-tag>
<el-tag v-if="scope.row.delegateAssginee != null" size="mini" type="success" effect="plain" style="margin-left: 10px;">{{scope.row.delegateAssginee}}</el-tag>
</template>
</el-table-column>
<el-table-column label="审批意见">
<template slot-scope="scope">
<span>{{scope.row.comment ? scope.row.comment : ''}}</span>
</template>
</el-table-column>
<el-table-column label="处理时间" prop="createTime" width="160px" />
</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 '../package/theme/index.scss';
// import BpmnViewer from 'bpmn-js/lib/Viewer';
import BpmnModeler from 'bpmn-js/lib/Modeler';
export default {
props: {
xml: {
type: String
},
finishedInfo: {
type: Object
},
// 所有节点审批记录
allCommentList: {
type: Array
}
},
data () {
return {
dialogVisible: false,
dlgTitle: undefined,
defaultZoom: 1,
// 是否正在加载流程图
isLoading: true,
bpmnViewer: undefined,
// 已完成流程元素
processNodeInfo: undefined,
// 当前任务id
selectTaskId: undefined,
// 任务节点审批记录
taskCommentList: [],
// 已完成任务悬浮延迟Timer
hoverTimer: null
}
},
methods: {
processReZoom () {
this.defaultZoom = 1;
this.bpmnViewer.get('canvas').zoom('fit-viewport', 'auto');
},
processZoomIn (zoomStep = 0.1) {
let 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) {
let 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) {
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 () {
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 customDefs = this.$refs.customDefs;
svg.appendChild(customDefs);
},
// 任务悬浮弹窗
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.taskKey === this.selectTaskId;
});
this.dialogVisible = true;
},
// 显示流程图
async importXML (xml) {
this.clearViewer();
if (xml != null && xml !== '') {
try {
this.bpmnViewer = new BpmnModeler({
container: this.$refs.processCanvas
});
// 任务节点悬浮事件
this.bpmnViewer.on('element.click', ({ element }) => {
this.onSelectElement(element);
});
this.isLoading = true;
await this.bpmnViewer.importXML(xml);
this.addCustomDefs();
} catch (e) {
console.error(e);
this.clearViewer();
} finally {
this.isLoading = false;
this.setProcessStatus(this.processNodeInfo);
}
}
},
// 设置流程图元素状态
setProcessStatus (processNodeInfo) {
this.processNodeInfo = processNodeInfo;
if (this.isLoading || this.processNodeInfo == null || this.bpmnViewer == null) return;
let { finishedSequenceFlowSet, finishedTaskSet, unfinishedTaskSet } = 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');
let 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, 'current');
});
}
}
},
destroyed () {
this.clearViewer();
},
watch: {
xml: {
handler (newXml) {
this.importXML(newXml);
},
immediate: true
},
finishedInfo: {
handler (newInfo) {
this.setProcessStatus(newInfo);
},
immediate: true
}
}
}
</script>
<style scoped>
.comment-dialog >>> .el-dialog__body {
padding: 0px;
}
</style>

View File

@@ -0,0 +1,75 @@
<template>
<div class="tag-select">
<div class="tag-box">
<el-tag v-for="item in selectValues" :key="item.id" effect="dark"
style="margin-right: 5px;" type="primary" size="mini" closable
@close="onDeleteTag(item)"
>
{{item.name}}
</el-tag>
</div>
<slot name="append" />
</div>
</template>
<script>
export default {
name: 'TagSelect',
props: {
value: {
type: [String, Array]
}
},
data () {
return {
selectValues: []
}
},
methods: {
onDeleteTag (tag) {
let temp = this.selectValues.filter(item => {
return item !== tag;
});
if (Array.isArray(this.value)) {
this.$emit('input', temp);
} else {
this.$emit('input', temp.map(item => item.id).join(','));
}
}
},
watch: {
value: {
handler (newValue) {
if (newValue == null || newValue === '') {
this.selectValues = [];
} else {
if (Array.isArray(newValue)) {
this.selectValues = [...newValue];
} else {
this.selectValues = newValue.split(',').map(item => {
return {
id: item,
/* eslint-disable-next-line */
name: item === '${startUserName}' ? '流程发起人' : item
}
});
}
}
},
immediate: true
}
}
}
</script>
<style scoped>
.tag-select {
border: 1px solid #DCDFE6;
border-radius: 4px;
display: flex;
}
.tag-box {
flex-grow: 1;
padding: 0px 5px;
}
</style>

View File

@@ -0,0 +1,107 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formTaskCommit" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24" v-if="operation.type !== SysFlowTaskOperationType.CO_SIGN && operation.type !== SysFlowTaskOperationType.MULTI_SIGN">
<el-form-item label="审批意见:" prop="message">
<el-input v-model="formData.message" clearable placeholder="请输入审批意见" />
</el-form-item>
</el-col>
<el-col :span="24" v-if="showAssignSelect">
<el-form-item label="指派用户:" prop="assignee">
<TagSelect v-model="formData.assignee">
<el-button slot="append" class="append-add" type="default" icon="el-icon-plus" @click="onSelectAssignee" />
</TagSelect>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onSubmitClick()">
提交
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import TagSelect from '@/views/workflow/components/TagSelect.vue';
import TaskUserSelect from '@/views/workflow/components/TaskUserSelect.vue';
export default {
name: 'formTaskCommit',
props: {
operation: {
type: Object,
required: true
}
},
components: {
TagSelect
},
data () {
return {
formData: {
message: undefined,
assignee: undefined
},
rules: {
message: [{required: true, message: '审批意见不能为空', trigger: 'blur'}],
assignee: [{required: true, message: '指派用户不能为空', trigger: 'blur'}]
}
}
},
methods: {
onCancel (isSuccess, data) {
if (this.observer != null) {
this.observer.cancel(isSuccess, data);
}
},
onSubmitClick () {
this.$refs.formTaskCommit.validate(valid => {
if (!valid) return;
this.onCancel(true, this.formData);
});
},
onSelectAssignee () {
this.$dialog.show('选择用户', TaskUserSelect, {
area: ['1000px', '600px']
}, {
multiple: this.multiSelect
}).then(res => {
let assignee = null;
if (Array.isArray(res)) {
assignee = res.map(item => item.loginName).join(',');
} else {
assignee = (res || {}).loginName;
}
this.formData.assignee = assignee;
}).catch(e => {});
}
},
computed: {
showAssignSelect () {
return [this.SysFlowTaskOperationType.TRANSFER, this.SysFlowTaskOperationType.CO_SIGN, this.SysFlowTaskOperationType.MULTI_SIGN].indexOf(this.operation.type) !== -1;
},
multiSelect () {
return this.operation.type === this.SysFlowTaskOperationType.CO_SIGN || this.operation.type === this.SysFlowTaskOperationType.MULTI_SIGN;
}
}
}
</script>
<style scoped>
.append-add {
border: none;
border-left: 1px solid #DCDFE6;
border-radius: 0px;
background: #F5F7FA;
}
</style>

View File

@@ -0,0 +1,106 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row type="flex" justify="end">
<el-button type="primary" size="mini" @click="onSubmit" :disabled="!canCommit">
添加分组
</el-button>
</el-row>
</el-form>
<el-row style="margin-top: 18px;">
<el-col :span="24">
<el-table :data="allGroupList" size="mini" height="452px"
header-cell-class-name="table-header-gray"
row-key="id" :default-expand-all="true"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50px"
header-align="center" align="center"
:selectable="canSelect"
/>
<el-table-column label="部门名称" prop="name" />
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { TableWidget } from '@/utils/widget.js';
import { DictionaryController } from '@/api';
export default {
name: 'taskGroupSelect',
props: {
allGroupList: {
type: Array,
required: true
},
// 已经被使用的分组列表
usedIdList: {
type: Array
}
},
data () {
return {
multiSelectGroup: [],
taskGroupListWidget: new TableWidget(this.loadSysDeptData, this.loadSysDeptVerify, false, false, 'createTime', 1)
}
},
methods: {
onCancel (isSuccess, data) {
if (this.observer != null) {
this.observer.cancel(isSuccess, data);
}
},
canSelect (row) {
if (Array.isArray(this.usedIdList) && this.usedIdList.length > 0) {
return this.usedIdList.indexOf(row.id) === -1;
} else {
return true;
}
},
onSubmit () {
this.onCancel(true, this.multiSelectGroup);
},
handleSelectionChange (values) {
this.multiSelectGroup = values;
},
loadSysDeptData (params) {
return new Promise((resolve, reject) => {
DictionaryController.dictSysDeptByParentId(this, {}).then(res => {
resolve({
dataList: res.getList(),
totalCount: res.getList().length
});
}).catch(e => {
reject(e);
});
});
},
loadSysDeptVerify () {
return true;
},
refresh (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.taskGroupListWidget.refreshTable(true, 1);
} else {
this.taskGroupListWidget.refreshTable();
}
}
},
computed: {
canCommit () {
return this.multiSelectGroup.length > 0;
}
},
mounted () {
this.refresh();
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,148 @@
<template>
<el-container class="advance-query-form">
<el-aside width="300px">
<el-card class="base-card" shadow="never" :body-style="{ padding: '0px' }" style="border: none;">
<div slot="header" class="base-card-header">
<span style="font-size: 16px; font-weight: 500; color: #282828;">所属部门</span>
</div>
<el-scrollbar :style="{height: '500px'}" class="custom-scroll">
<el-tree class="dept-tree" ref="deptTree" :data="getDeptTreeData" :props="{label: 'name'}"
node-key="id" :default-expand-all="true" :expand-on-click-node="false"
@node-click="onDeptNodeClick"
:highlight-current="true">
<div slot-scope="{ data }" style="height: 35px; line-height: 35px;">
{{data.name}}
</div>
</el-tree>
</el-scrollbar>
</el-card>
</el-aside>
<el-main style="margin-left: 15px; background-color: white;">
<el-card class="base-card" shadow="never" :body-style="{ padding: '0px' }" style="border: none;">
<div slot="header" class="base-card-header">
<span style="font-size: 16px; font-weight: 500; color: #282828;">岗位列表</span>
<div class="base-card-operation">
<el-button type="primary" size="mini"
:disabled="selectPost.length <= 0"
@click="onAddPostClick()"
>
添加岗位
</el-button>
</div>
</div>
<el-table :data="getValidDeptPostList" size="mini" height="500px"
header-cell-class-name="table-header-gray"
row-key="deptPostId"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50px" :selectable="canSelect" />
<el-table-column label="岗位名称" prop="postShowName" />
<el-table-column label="领导岗位">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.leaderPost ? 'success' : 'danger'">
{{scope.row.leaderPost ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="岗位级别" prop="level" />
</el-table>
</el-card>
</el-main>
</el-container>
</template>
<script>
import { DictionaryController } from '@/api/index.js';
export default {
name: 'taskPostSelect',
props: {
deptList: {
type: Array
},
deptPostList: {
type: Array
},
usedIdList: {
type: Array
}
},
data () {
return {
currentDept: undefined,
// deptList: [],
selectPost: []
}
},
methods: {
onCancel (isSuccess, data) {
if (this.observer != null) {
this.observer.cancel(isSuccess, data);
}
},
canSelect (row) {
if (Array.isArray(this.usedIdList) && this.usedIdList.length > 0) {
return this.usedIdList.indexOf(row.deptPostId) === -1;
} else {
return true;
}
},
loadSysDeptData () {
DictionaryController.dictSysDept(this, {}).then(res => {
this.deptList = res.getList();
this.currentDept = this.deptList[0];
if (this.currentDept) {
this.$nextTick(() => {
this.$refs.deptTree.setCurrentKey(this.currentDept.id);
});
}
}).catch(e => {});
},
onDeptNodeClick (data) {
this.selectPost = [];
this.currentDept = data;
},
handleSelectionChange (values) {
this.selectPost = values;
},
onAddPostClick () {
this.onCancel(true, this.selectPost);
}
},
computed: {
getDeptTreeData () {
return this.deptList;
},
getValidDeptPostList () {
if (Array.isArray(this.deptPostList)) {
if (this.currentDept == null) {
return this.deptPostList;
} else {
return this.deptPostList.filter(item => {
return item.deptId === this.currentDept.id;
});
}
} else {
return [];
}
}
},
mounted () {
// this.loadSysDeptData();
if (Array.isArray(this.deptList)) {
this.currentDept = this.deptList[0];
if (this.currentDept) {
this.$nextTick(() => {
this.$refs.deptTree.setCurrentKey(this.currentDept.id);
});
}
}
}
}
</script>
<style scoped>
.dept-tree >>> .el-tree-node__content {
height: 35px;
}
</style>

View File

@@ -0,0 +1,201 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row type="flex" justify="space-between">
<el-form-item label="登录名称">
<el-input class="filter-item" v-model="formSysUser.formFilter.sysUserLoginName"
@change="refreshFormSysUser(true)"
:clearable="true" placeholder="登录名称" />
</el-form-item>
<div>
<el-input v-if="!multiple" size="mini" v-model="assignee" placeholder="自定义用户" style="width: 200px; margin: 0px 10px;">
</el-input>
<el-button type="primary" size="mini" @click="setStartUser">
流程发起人
</el-button>
<el-button type="primary" size="mini" @click="onSubmit" :disabled="!canCommit">
添加用户
</el-button>
</div>
</el-row>
</el-form>
<el-row>
<el-col :span="24">
<el-radio-group class="radio-table" v-model="selectUserId" style="width: 100%;">
<el-table :data="formSysUser.sysUserWidget.dataList" size="mini" height="410px"
header-cell-class-name="table-header-gray"
row-key="userId"
@sort-change="formSysUser.sysUserWidget.onSortChange"
@selection-change="handleSelectionChange"
>
<el-table-column v-if="this.multiple" header-align="center"
:reserve-selection="multiple"
align="center" type="selection" width="50px"
:selectable="canSelect"
/>
<el-table-column v-else label="" header-align="center" align="center" width="50px">
<template slot-scope="scope">
<el-radio :label="scope.row.userId"> </el-radio>
</template>
</el-table-column>
<el-table-column label="用户名" prop="loginName" />
<el-table-column label="昵称" prop="showName" />
<el-table-column label="所属部门" prop="deptIdDictMap.name" />
<el-table-column label="账号类型" prop="userTypeDictMap.name" />
<el-table-column label="创建时间">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
</el-table>
<el-col :span="24">
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formSysUser.sysUserWidget.totalCount"
:current-page="formSysUser.sysUserWidget.currentPage"
:page-size="formSysUser.sysUserWidget.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formSysUser.sysUserWidget.onCurrentPageChange"
@size-change="formSysUser.sysUserWidget.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-radio-group>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { findItemFromList } from '@/utils';
import { statsDateRangeMixin } from '@/core/mixins';
import { TableWidget } from '@/utils/widget.js';
import { SystemController } from '@/api';
export default {
name: 'TaskUserSelect',
props: {
// 是否多选
multiple: {
type: Boolean,
default: false
},
// 已经被使用的用户列表
usedUserIdList: {
type: Array
}
},
mixins: [statsDateRangeMixin],
data () {
return {
assignee: undefined,
// 单选下选中的用户
selectUserId: undefined,
// 多选下选中的用户列表
multiSelectUser: [],
formSysUser: {
formFilter: {
sysUserLoginName: undefined
},
formFilterCopy: {
sysUserLoginName: undefined
},
sysUserWidget: new TableWidget(this.loadSysUserData, this.loadSysUserVerify, true, false, 'createTime', 1),
isInit: false
}
}
},
methods: {
onCancel (isSuccess, data) {
if (this.observer != null) {
this.observer.cancel(isSuccess, data);
}
},
onClear () {
this.onCancel(true);
},
setStartUser () {
this.onCancel(true, {
/* eslint-disable-next-line */
loginName: '${startUserName}'
});
},
canSelect (row) {
if (Array.isArray(this.usedUserIdList) && this.usedUserIdList.length > 0) {
return this.usedUserIdList.indexOf(row.loginName) === -1;
} else {
return true;
}
},
onSubmit () {
let selectUser = this.multiSelectUser;
if (!this.multiple) {
if (this.assignee != null && this.assignee !== '') {
this.onCancel(true, {
loginName: this.assignee
});
return;
}
selectUser = findItemFromList(this.formSysUser.sysUserWidget.dataList, this.selectUserId, 'userId');
}
this.onCancel(true, selectUser);
},
handleSelectionChange (values) {
this.multiSelectUser = values;
},
/**
* 用户管理数据获取函数返回Primise
*/
loadSysUserData (params) {
params.sysUserDtoFilter = {
loginName: this.formSysUser.formFilterCopy.sysUserLoginName
}
return new Promise((resolve, reject) => {
SystemController.getUserList(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 用户管理数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadSysUserVerify () {
this.formSysUser.formFilterCopy.sysUserLoginName = this.formSysUser.formFilter.sysUserLoginName;
return true;
},
/**
* 更新用户管理
*/
refreshFormSysUser (reloadData = false) {
// 重新获取数据组件的数据
if (reloadData) {
this.formSysUser.sysUserWidget.refreshTable(true, 1);
} else {
this.formSysUser.sysUserWidget.refreshTable();
}
this.formSysUser.isInit = true;
}
},
computed: {
canCommit () {
return this.multiple ? this.multiSelectUser.length > 0 : ((this.selectUserId != null && this.selectUserId !== '') || this.assignee != null);
}
},
mounted () {
this.refreshFormSysUser();
}
}
</script>
<style scoped>
.radio-table >>> .el-radio__label {
display: none;
}
</style>

View File

@@ -0,0 +1,207 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formEditFlowCategory" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="分类名称" prop="FlowCategory.name">
<el-input class="input-item" v-model="formData.FlowCategory.name"
:clearable="true" placeholder="流程分类名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="分类编码" prop="FlowCategory.code">
<el-input class="input-item" v-model="formData.FlowCategory.code"
:disabled="isEdit" :clearable="true" placeholder="分类编码" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="显示顺序" prop="FlowCategory.showOrder">
<el-input-number class="input-item" v-model="formData.FlowCategory.showOrder"
:clearable="true" controls-position="right" placeholder="显示顺序" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" @click="onSubmitClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { FlowCategoryController } from '@/api/flowController.js';
export default {
name: 'formEditFlowCategory',
props: {
categoryId: {
default: undefined
}
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
FlowCategory: {
categoryId: undefined,
name: undefined,
code: undefined,
showOrder: undefined,
isDatasourceInit: false
}
},
rules: {
'FlowCategory.code': [
{required: true, message: '请输入分类编码', trigger: 'blur'},
{type: 'string', pattern: /^[A-Za-z0-9]+$/, message: '分类编码只能输入英文字母和数字', trigger: 'blur'}
],
'FlowCategory.showOrder': [
{required: true, message: '请输入显示顺序', trigger: 'blur'},
{type: 'integer', message: '显示顺序只允许输入整数', trigger: 'blur', transform: (value) => Number(value)},
{type: 'number', min: 0, message: '显示顺序必须大于0', trigger: 'blur', transform: (value) => Number(value)}
],
'FlowCategory.name': [
{required: true, message: '请输入流程分类名称', trigger: 'blur'}
]
},
formEditFlowCategory: {
formFilter: {
},
formFilterCopy: {
},
menuBlock: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 更新编辑流程分类
*/
refreshFormEditFlowCategory (reloadData = false) {
this.loadFlowCategoryData().then(res => {
if (!this.formEditFlowCategory.isInit) {
// 初始化下拉数据
}
this.formEditFlowCategory.isInit = true;
}).catch(e => {});
},
/**
* 保存
*/
onSubmitClick () {
this.$refs.formEditFlowCategory.validate((valid) => {
if (!valid) return;
if (
this.formData.FlowCategory.name == null ||
this.formData.FlowCategory.code == null ||
this.formData.FlowCategory.showOrder == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
flowCategoryDto: {
categoryId: this.isEdit ? this.categoryId : undefined,
name: this.formData.FlowCategory.name,
code: this.formData.FlowCategory.code,
showOrder: this.formData.FlowCategory.showOrder
}
};
let httpCall = this.isEdit ? FlowCategoryController.update(this, params) : FlowCategoryController.add(this, params);
httpCall.then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
/**
* 获取FlowCategory详细信息
*/
loadFlowCategoryData () {
return new Promise((resolve, reject) => {
if (!this.formData.FlowCategory.isDatasourceInit && this.isEdit) {
if (
this.categoryId == null
) {
this.resetFormData();
reject();
return;
}
let params = {
categoryId: this.categoryId
};
FlowCategoryController.view(this, params).then(res => {
this.formData.FlowCategory = {...res.data, isDatasourceInit: true};
resolve();
}).catch(e => {
reject();
});
} else {
resolve();
}
});
},
initFormData () {
},
/**
* 重置表单数据
*/
resetFormData () {
this.$refs.formEditFlowCategory.resetFields();
/*
this.formData = {
FlowCategory: {
categoryId: undefined,
parentId: undefined,
name: undefined,
code: undefined,
showOrder: undefined,
updateTime: undefined,
updateUserId: undefined,
createTime: undefined,
createUserId: undefined,
isDatasourceInit: false
}
}
*/
},
formInit () {
this.refreshFormEditFlowCategory();
}
},
computed: {
isEdit () {
return this.categoryId != null && this.categoryId !== '';
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,206 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="分类名称">
<el-input class="filter-item" v-model="formFlowCategory.formFilter.name"
:clearable="true" placeholder="流程分类名称" />
</el-form-item>
<el-form-item label="分类编码">
<el-input class="filter-item" v-model="formFlowCategory.formFilter.code"
:clearable="true" placeholder="分类编码" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormFlowCategory(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formFlowCategory:formFlowCategory:add')"
@click="onAddFlowCategoryClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table ref="flowCategory" :data="flowCategoryWidget.dataList" size="mini" @sort-change="flowCategoryWidget.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="flowCategoryWidget.getTableIndex" />
<el-table-column label="流程分类名称" prop="name">
</el-table-column>
<el-table-column label="分类编码" prop="code">
</el-table-column>
<el-table-column label="显示顺序" prop="showOrder" sortable="custom">
</el-table-column>
<el-table-column label="创建时间" prop="createTime" sortable="custom">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button class="table-btn success" @click.stop="onEditFlowCategoryClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formFlowCategory:formFlowCategory:update')">
编辑
</el-button>
<el-button class="table-btn delete" @click.stop="onDeleteFlowCategoryClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formFlowCategory:formFlowCategory:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="flowCategoryWidget.totalCount"
:current-page="flowCategoryWidget.currentPage"
:page-size="flowCategoryWidget.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="flowCategoryWidget.onCurrentPageChange"
@size-change="flowCategoryWidget.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { FlowCategoryController } from '@/api/flowController.js';
import formEditFlowCategory from '@/views/workflow/flowCategory/formEditFlowCategory.vue';
export default {
name: 'formFlowCategory',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formFlowCategory: {
formFilter: {
name: undefined,
code: undefined
},
formFilterCopy: {
name: undefined,
code: undefined
},
isInit: false
},
flowCategoryWidget: new TableWidget(this.loadFlowCategoryWidgetData, this.loadFlowCategoryVerify, true, false, 'showOrder', 1)
}
},
methods: {
/**
* FlowCategory数据获取函数返回Promise
*/
loadFlowCategoryWidgetData (params) {
if (params == null) params = {};
params = {
...params,
flowCategoryDtoFilter: {
name: this.formFlowCategory.formFilterCopy.name,
code: this.formFlowCategory.formFilterCopy.code
}
}
return new Promise((resolve, reject) => {
FlowCategoryController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* FlowCategory数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadFlowCategoryVerify () {
this.formFlowCategory.formFilterCopy.name = this.formFlowCategory.formFilter.name;
this.formFlowCategory.formFilterCopy.code = this.formFlowCategory.formFilter.code;
return true;
},
/**
* 更新流程分类管理
*/
refreshFormFlowCategory (reloadData = false) {
if (reloadData) {
this.flowCategoryWidget.refreshTable(true, 1);
} else {
this.flowCategoryWidget.refreshTable();
}
if (!this.formFlowCategory.isInit) {
// 初始化下拉数据
}
this.formFlowCategory.isInit = true;
},
/**
* 新建
*/
onAddFlowCategoryClick () {
let params = {};
this.$dialog.show('新建', formEditFlowCategory, {
area: '500px'
}, params).then(res => {
this.refreshFormFlowCategory();
}).catch(e => {});
},
/**
* 编辑
*/
onEditFlowCategoryClick (row) {
let params = {
categoryId: row.categoryId
};
this.$dialog.show('编辑', formEditFlowCategory, {
area: '500px'
}, params).then(res => {
this.flowCategoryWidget.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteFlowCategoryClick (row) {
if (
row.categoryId == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
categoryId: row.categoryId
};
this.$confirm('是否删除此流程分类?').then(res => {
FlowCategoryController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.flowCategoryWidget.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormFlowCategory();
},
initFormData () {
},
formInit () {
this.refreshFormFlowCategory();
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,574 @@
<template>
<div class="edit-online-form">
<el-container>
<el-header>
<el-row type="flex" justify="space-between">
<el-col class="title header" :span="8">
<i class="el-icon-orange" />
<span>橙单流程设计</span>
</el-col>
<el-col :span="8">
<el-steps :active="activeStep" finish-status="success" simple style="margin-top: 7px;">
<el-step title="基础信息" style="max-width: 250px"></el-step>
<el-step title="流程变量" style="max-width: 250px"></el-step>
<el-step title="流程设计" style="max-width: 250px"></el-step>
</el-steps>
</el-col>
<el-col :span="8">
<el-row type="flex" justify="end" align="middle" style="height: 60px;">
<el-button size="small" @click="onPrevClick"
:disabled="activeStep === SysFlowEntryStep.BASIC"
>
上一步
</el-button>
<el-button size="small" @click="onNextClick" :disabled="activeStep === SysFlowEntryStep.PROCESS_DESIGN">下一步</el-button>
<el-button size="small" type="primary" @click="onClose(false)">退出</el-button>
</el-row>
</el-col>
</el-row>
</el-header>
<el-main style="background: #EBEEF5; padding: 10px;" :style="{height: getClientHeight - 60 + 'px'}">
<el-row type="flex" justify="center" style="height: 100%;">
<!-- 流程基础信息设置 -->
<el-col v-if="activeStep === SysFlowEntryStep.BASIC" class="main-box" style="width: 600px;" :span="9">
<el-form ref="entryBasicInfo" class="full-width-input" size="small" :model="formFlowEntryData" :rules="formRules"
label-position="right" label-width="120px" @submit.native.prevent>
<el-col :span="24">
<el-form-item label="表单类型" prop="bindFormType">
<el-select v-model="formFlowEntryData.bindFormType" placeholder="" @change="onBindFormTypeChange" :disabled="isEdit">
<el-option :label="SysFlowEntryBindFormType.getValue(SysFlowEntryBindFormType.ROUTER_FORM)" :value="SysFlowEntryBindFormType.ROUTER_FORM" />
<el-option :label="SysFlowEntryBindFormType.getValue(SysFlowEntryBindFormType.ONLINE_FORM)" :value="SysFlowEntryBindFormType.ONLINE_FORM" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="流程名称" prop="processDefinitionName">
<el-input v-model="formFlowEntryData.processDefinitionName" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="流程标识" prop="processDefinitionKey">
<el-input v-model="formFlowEntryData.processDefinitionKey" :disabled="isEdit" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="流程分类" prop="categoryId">
<el-select v-model="formFlowEntryData.categoryId"
placeholder="" :loading="categoryIdWidget.loading"
@visible-change="categoryIdWidget.onVisibleChange">
<el-option v-for="item in categoryIdWidget.dropdownList"
:key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formFlowEntryData.bindFormType === SysFlowEntryBindFormType.ONLINE_FORM">
<el-form-item label="流程页面" prop="pageId">
<el-select v-model="formFlowEntryData.pageId"
:disabled="isEdit"
placeholder="" :loading="pageIdWidget.loading"
@visible-change="pageIdWidget.onVisibleChange"
@change="onEntryPageChange"
>
<el-option v-for="item in pageIdWidget.dropdownList"
:key="item.pageId" :value="item.pageId" :label="item.pageName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formFlowEntryData.bindFormType === SysFlowEntryBindFormType.ONLINE_FORM">
<el-form-item label="默认在线表单" prop="defaultFormId">
<el-select v-model="formFlowEntryData.defaultFormId"
placeholder="" :loading="defaultFormIdWidget.loading"
@visible-change="defaultFormIdWidget.onVisibleChange"
>
<el-option v-for="item in defaultFormIdWidget.dropdownList"
:key="item.formId" :value="item.formId" :label="item.formName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formFlowEntryData.bindFormType === SysFlowEntryBindFormType.ROUTER_FORM">
<el-form-item label="默认路由表单" prop="defaultRouterName">
<el-input v-model="formFlowEntryData.defaultRouterName" clearable />
</el-form-item>
</el-col>
</el-form>
</el-col>
<!-- 流程变量设置 -->
<el-col v-if="activeStep === SysFlowEntryStep.PROCESS_VARIABLE" class="main-box" :span="16">
<el-table :data="processVariableList" header-cell-class-name="table-header-gray" key="processVariableList">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" />
<el-table-column label="变量名称" prop="showName" />
<el-table-column label="变量标识" prop="variableName" />
<el-table-column label="变量类型">
<template slot-scope="scope">
<el-tag size="mini" effect="dark"
:type="scope.row.variableType === SysFlowVariableType.TASK ? 'primary' : 'success'">
{{SysFlowVariableType.getValue(scope.row.variableType)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="内置变量">
<template slot-scope="scope">
<el-tag size="mini" effect="dark" :type="scope.row.builtIn ? 'success' : 'danger'">
{{scope.row.builtIn ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100px">
<template slot-scope="scope">
<el-button class="table-btn success" size="mini" type="text" :disabled="scope.row.builtin" @click="editEntryVariable(scope.row)">编辑</el-button>
<el-button class="table-btn delete" size="mini" type="text" :disabled="scope.row.builtin" @click="deleteEntryVariable(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="btn-add" icon="el-icon-plus" @click="addEntryVariable">添加变量</el-button>
</el-col>
<!-- 流程设计 -->
<el-col v-if="activeStep === SysFlowEntryStep.PROCESS_DESIGN" class="main-box" :span="24" style="min-width: 1100px; padding: 0px">
<ProcessDesigner :flowEntryInfo="formFlowEntryData" @save="onSaveFlowEntry" />
</el-col>
</el-row>
</el-main>
</el-container>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { DropdownWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
import ProcessDesigner from '../components/ProcessDesigner.vue';
/* eslint-disable-next-line */
import { FlowEntryController, FlowEntryVariableController, FlowDictionaryController } from '@/api/flowController.js';
import {
OnlinePageController,
OnlineFormController,
OnlineColumnController,
OnlineDatasourceRelationController,
OnlineVirtualColumnController
} from '@/api/onlineController.js';
import EditFlowEntryVariable from './formEditFlowEntryVariable.vue';
export default {
name: 'formEditFlowEntry',
props: {
flowEntry: {
type: Object
}
},
components: {
ProcessDesigner
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
provide () {
return {
flowEntry: () => this.formFlowEntryData,
formList: () => this.defaultFormIdWidget ? this.defaultFormIdWidget.dropdownList : [],
allVariableList: () => this.processVariableList
}
},
data () {
return {
entryDatasource: undefined,
activeStep: this.SysFlowEntryStep.BASIC,
formFlowEntryData: {
entryId: undefined,
processDefinitionName: undefined,
processDefinitionKey: undefined,
categoryId: undefined,
bindFormType: this.SysFlowEntryBindFormType.ROUTER_FORM,
pageId: undefined,
defaultFormId: undefined,
defaultRouterName: undefined,
bpmnXml: undefined
},
categoryIdWidget: new DropdownWidget(this.loadCategoryIdDropdownList),
pageIdWidget: new DropdownWidget(this.loadPageIdDropdownList),
defaultFormIdWidget: new DropdownWidget(this.loadDefaultFormIdDropdownList),
processVariableList: [],
formRules: {
processDefinitionKey: [
{required: true, message: '流程标识不能为空!', trigger: 'blur'},
{type: 'string', pattern: /^[A-Za-z0-9]+$/, message: '流程标识只允许输入字母和数字', trigger: 'blur'},
{type: 'string', pattern: /^[A-Za-z][A-Za-z0-9]+$/, message: '流程标识不能以数字开头', trigger: 'blur'}
],
processDefinitionName: [
{required: true, message: '流程名称不能为空!', trigger: 'blur'}
],
categoryId: [
{required: true, message: '流程分类不能为空!', trigger: 'blur'}
],
pageId: [
{required: true, message: '流程页面不能为空!', trigger: 'blur'}
],
defaultFormId: [
{required: true, message: '默认在线表单不能为空!', trigger: 'blur'}
],
defaultRouterName: [
{required: true, message: '默认路由表单不能为空!', trigger: 'blur'}
]
}
}
},
methods: {
onClose () {
this.$emit('close');
},
// 流程绑定表单类型改变
onBindFormTypeChange () {
this.formFlowEntryData.pageId = undefined;
this.formFlowEntryData.defaultFormId = undefined;
this.formFlowEntryData.defaultRouterName = undefined;
this.entryDatasource = undefined;
},
// 流程绑定表单页面改变
onEntryPageChange () {
this.formFlowEntryData.defaultFormId = undefined;
this.defaultFormIdWidget.dirty = true;
this.entryDatasource = null;
},
// 获取流程分类
loadCategoryIdDropdownList () {
return new Promise((resolve, reject) => {
FlowDictionaryController.dictFlowCategory(this, {}).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
// 获取在线表单列表
loadPageIdDropdownList () {
return new Promise((resolve, reject) => {
OnlinePageController.list(this, {
onlinePageDtoFilter: {
pageType: this.SysOnlinePageType.FLOW
}
}).then(res => {
resolve(res.data.dataList.filter(item => item.published));
}).catch(e => {
reject(e);
});
});
},
// 获取默认表单页面列表
loadDefaultFormIdDropdownList () {
return new Promise((resolve, reject) => {
if (this.formFlowEntryData.pageId == null || this.formFlowEntryData.pageId === '') {
resolve([]);
return;
}
OnlineFormController.list(this, {
onlineFormDtoFilter: {
pageId: this.formFlowEntryData.pageId
},
orderParam: [
{
fieldName: 'createTime',
asc: true
}
]
}).then(res => {
resolve(res.data.dataList);
}).catch(e => {
reject(e);
});
});
},
onPrevClick () {
switch (this.activeStep) {
case this.SysFlowEntryStep.PROCESS_VARIABLE:
this.activeStep = this.SysFlowEntryStep.BASIC;
break;
case this.SysFlowEntryStep.PROCESS_DESIGN:
this.activeStep = this.SysFlowEntryStep.PROCESS_VARIABLE;
break;
}
},
onNextClick () {
switch (this.activeStep) {
case this.SysFlowEntryStep.BASIC:
this.$refs.entryBasicInfo.validate(valid => {
if (!valid) return;
// 保存流程基本信息
this.onSaveFlowEntryBasicInfo().then(res => {
if (!this.isEdit) this.formFlowEntryData.entryId = res.data;
this.$message.success('保存成功');
// 获取流程页面数据源信息
this.initFlowDatasourceInfo().then(res => {
// 获取流程变量
return this.loadEntryVariableList();
}).then(res => {
this.activeStep = this.SysFlowEntryStep.PROCESS_VARIABLE;
}).catch(e => {
console.log(e);
});
}).catch(e => {
console.log(e);
});
});
break;
case this.SysFlowEntryStep.PROCESS_VARIABLE:
this.activeStep = this.SysFlowEntryStep.PROCESS_DESIGN;
break;
}
},
// 初始化流程基础信息
initFlowEntryInfo () {
this.formFlowEntryData = {
processDefinitionName: undefined,
processDefinitionKey: undefined,
categoryId: undefined,
bindFormType: this.SysFlowEntryBindFormType.ONLINE_FORM,
pageId: undefined,
defaultFormId: undefined,
defaultRouterName: undefined,
bpmnXml: undefined
}
this.activeStep = this.SysFlowEntryStep.BASIC;
FlowEntryController.view(this, {
entryId: this.flowEntry.entryId
}).then(res => {
this.formFlowEntryData = {
...this.formFlowEntryData,
...res.data
}
if (this.formFlowEntryData.bindFormType === this.SysFlowEntryBindFormType.ONLINE_FORM) {
this.defaultFormIdWidget.onVisibleChange(true);
}
}).catch(e => {});
},
// 保存流程基础信息
saveFlowEntryInfo (step) {
let params = {
flowEntryDto: {
...this.formFlowEntryData,
step
}
}
return this.isEdit ? FlowEntryController.update(this, params) : FlowEntryController.add(this, params);
},
onSaveFlowEntry (xml) {
this.formFlowEntryData.bpmnXml = xml;
this.onSaveFlowEntryBasicInfo().then(res => {
this.$message.success('保存成功');
}).catch(e => {});
},
onSaveFlowEntryBasicInfo () {
return this.saveFlowEntryInfo(this.SysFlowEntryStep.DATASOURCE);
},
// 获取流程绑定页面数据源信息
initFlowEntryDatasourceInfo (entryId) {
return FlowEntryController.viewDatasource(this, {
entryId
});
},
/**
* 获取数据模型关联信息
*/
loadDatasourceRelation () {
if (this.entryDatasource == null) return Promise.resolve();
return OnlineDatasourceRelationController.list(this, {
onlineDatasourceRelationDtoFilter: {
datasourceId: this.entryDatasource.datasourceId
}
});
},
// 获取在线表单数据表字段列表
loadOnlineTableColumns (tableId, owner) {
if (tableId == null || tableId === '') return Promise.reject();
return new Promise((resolve, reject) => {
let params = {
onlineColumnDtoFilter: {
tableId
}
}
OnlineColumnController.list(this, params).then(res => {
owner.columnList = res.data.dataList;
resolve();
}).catch(e => {
reject(e);
});
});
},
/**
* 获取数据源下所有表字段
*/
loadDatasourceAllColumnList () {
if (this.entryDatasource == null) return Promise.resolve();
let allHttpCalls = [
this.loadOnlineTableColumns(this.entryDatasource.masterTableId, this.entryDatasource)
];
this.entryDatasource.relationList.forEach(relation => {
if (relation.relationType === this.SysOnlineRelationType.ONE_TO_ONE) {
allHttpCalls.push(this.loadOnlineTableColumns(relation.slaveTableId, relation));
}
});
return Promise.all(allHttpCalls);
},
// 获取流程绑定页面数据源信息
initFlowDatasourceInfo () {
return new Promise((resolve, reject) => {
if (this.entryDatasource != null) return resolve();
if (this.formFlowEntryData.bindFormType === this.SysFlowEntryBindFormType.ONLINE_FORM) {
OnlinePageController.listOnlinePageDatasource(this, {
pageId: this.formFlowEntryData.pageId
}).then(res => {
this.entryDatasource = res.data.dataList[0];
return this.loadDatasourceRelation();
}).then(res => {
this.entryDatasource.relationList = res.data.dataList || [];
return this.loadDatasourceAllColumnList();
}).then(res => {
return OnlineVirtualColumnController.list(this, {
onlineVirtualColumnDtoFilter: {
datasourceId: this.entryDatasource.datasourceId
}
});
}).then(res => {
let virtualColumnList = res.data.dataList;
if (Array.isArray(virtualColumnList)) {
if (!Array.isArray(this.entryDatasource.columnList)) this.entryDatasource.columnList = [];
this.entryDatasource.columnList.push(...virtualColumnList.map(item => {
return {
...item,
columnId: item.virtualColumnId,
columnName: item.objectFieldName,
columnComment: item.columnPrompt
}
}));
}
resolve();
}).catch(e => {
reject(e);
});
} else {
this.entryDatasource = null;
resolve();
}
});
},
// 获取流程变量列表
loadEntryVariableList () {
return new Promise((resolve, reject) => {
let params = {
flowEntryVariableDtoFilter: {
entryId: this.formFlowEntryData.entryId || this.flowEntry.entryId
}
}
FlowEntryVariableController.list(this, params).then(res => {
this.processVariableList = res.data.dataList;
resolve();
}).catch(e => {
reject(e);
});
});
},
addEntryVariable () {
this.$dialog.show('添加变量', EditFlowEntryVariable, {
area: '500px'
}, {
entryId: this.formFlowEntryData.entryId || this.flowEntry.entryId,
datasource: this.entryDatasource
}).then(res => {
this.loadEntryVariableList();
}).catch(e => {});
},
editEntryVariable (row) {
this.$dialog.show('编辑变量', EditFlowEntryVariable, {
area: '500px'
}, {
entryId: this.formFlowEntryData.entryId || this.flowEntry.entryId,
datasource: this.entryDatasource,
rowData: row
}).then(res => {
this.loadEntryVariableList();
}).catch(e => {});
},
deleteEntryVariable (row) {
this.$confirm('是否删除此流程变量?').then(res => {
let params = {
variableId: row.variableId
}
return FlowEntryVariableController.delete(this, params);
}).then(res => {
this.$message.success('删除成功!');
this.loadEntryVariableList();
}).catch(e => {});
}
},
computed: {
isEdit () {
return this.flowEntry != null || this.formFlowEntryData.entryId != null;
},
...mapGetters(['getClientHeight'])
},
mounted () {
// 初始化页面数据
this.categoryIdWidget.onVisibleChange(true);
this.pageIdWidget.onVisibleChange(true);
if (this.isEdit) {
this.initFlowEntryInfo();
}
},
watch: {
}
}
</script>
<style scoped>
.edit-online-form {
position: fixed;
width: 100vw;
height: 100vh;
background: white;
top: 0px;
left: 0px;
z-index: 100
}
.edit-online-form >>> .el-steps--simple {
background: white!important;
padding: 13px 0px;
width: 800px;
}
.edit-online-form >>> .el-table th,.edit-online-form >>> .el-table td {
padding: 6px 0px;
}
.edit-online-form >>> .el-scrollbar__bar {
display: none;
}
.edit-online-form .header {
height: 60px;
line-height: 60px;
}
.edit-online-form .title {
font-size: 24px
}
.edit-online-form .title > i {
color: #FDA834;
margin-right: 10px;
}
.edit-online-form .main-box {
padding: 20px;
background: white;
height: 100%;
}
.edit-online-form .btn-add {
width: 100%;
margin-top: 10px;
border: 1px dashed #EBEEF5;
}
</style>

View File

@@ -0,0 +1,189 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="form" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24" v-if="datasource != null">
<el-form-item label="绑定字段">
<el-cascader class="input-item"
v-model="bindColumnPath" filterable
placeholder="变量绑定的数据源字段"
:options="entryDatasourceData"
:disabled="datasource == null"
@change="onBindColumnChange"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="变量名称" prop="showName">
<el-input class="input-item" v-model="formData.showName"
:clearable="true" placeholder="变量名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="变量标识" prop="variableName">
<el-input class="input-item" v-model="formData.variableName"
:clearable="true" placeholder="变量标识" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini"
@click="onSubmit()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import { findTreeNode } from '@/utils';
import { FlowEntryVariableController } from '@/api/flowController.js';
export default {
name: 'formEditFlowEntryVariable',
props: {
entryId: {
type: String,
required: true
},
datasource: {
type: Object
},
rowData: {
type: Object
}
},
data () {
return {
bindColumnPath: [],
formData: {
showName: undefined,
variableName: undefined,
variableType: this.SysFlowVariableType.TASK,
bindDatasourceId: undefined,
bindRelationId: undefined,
bindColumnId: undefined,
builtIn: false
},
rules: {
showName: [
{required: true, message: '变量名称不能为空!', trigger: 'blur'}
],
variableName: [
{required: true, message: '变量标识不能为空!', trigger: 'blur'},
{type: 'string', pattern: /^[a-z][a-zA-Z]+$/, message: '变量标识必须是小驼峰命名', trigger: 'blur'}
]
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
onSubmit () {
this.$refs.form.validate(valid => {
if (valid) {
let params = {
flowEntryVariableDto: {
...this.formData,
entryId: this.entryId
}
}
let httpCall = this.rowData == null ? FlowEntryVariableController.add(this, params) : FlowEntryVariableController.update(this, params);
httpCall.then(res => {
this.$message.success('保存成功!');
this.onCancel(true);
}).catch(e => {});
}
});
},
onBindColumnChange (values) {
let columnId = null;
if (Array.isArray(values) && values.length > 0) {
columnId = values[values.length - 1];
}
this.formData.bindDatasourceId = this.datasource.datasourceId;
this.formData.bindRelationId = undefined;
this.formData.bindColumnId = undefined;
if (columnId != null) {
if (values[0] !== this.formData.bindDatasourceId) this.formData.bindRelationId = values[0];
let column = findTreeNode(this.entryDatasourceData, columnId, 'value');
if (column != null && column.tag != null) {
this.formData.showName = column.tag.columnComment;
this.formData.variableName = column.tag.objectFieldName;
this.formData.bindColumnId = column.value;
}
}
}
},
computed: {
entryDatasourceData () {
if (this.datasource == null) {
return [];
} else {
let temp = [
{
label: this.datasource.datasourceName,
value: this.datasource.datasourceId,
tableId: this.datasource.masterTableId,
children: this.datasource.columnList.map(column => {
return {
label: column.objectFieldName,
value: column.columnId,
tag: column
}
}),
tag: this.datasource
}
];
if (Array.isArray(this.datasource.relationList)) {
this.datasource.relationList.forEach(relation => {
if (relation.relationType === this.SysOnlineRelationType.ONE_TO_ONE) {
temp.push({
label: relation.relationName,
value: relation.variableName,
tableId: relation.slaveTableId,
children: relation.columnList.map(column => {
return {
label: column.objectFieldName,
value: column.columnId,
tag: column
}
}),
tag: relation
});
}
});
}
return temp;
}
}
},
mounted () {
if (this.rowData != null) {
this.formData = {
...this.formData,
...this.rowData
}
if (this.formData.bindColumnId != null && this.datasource != null) {
this.bindColumnPath = [this.formData.bindRelationId || this.formData.bindDatasourceId, this.formData.bindColumnId];
}
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,341 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="流程分类">
<el-select class="filter-item" v-model="formFlowEntry.formFilter.categoryId"
:clearable="true" filterable placeholder="流程分类"
:loading="formFlowEntry.categoryIdWidget.loading"
@visible-change="formFlowEntry.categoryIdWidget.onVisibleChange"
>
<el-option v-for="item in formFlowEntry.categoryIdWidget.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="流程名称">
<el-input class="filter-item" v-model="formFlowEntry.formFilter.processDefinitionName"
:clearable="true" placeholder="流程名称" />
</el-form-item>
<el-form-item label="流程标识">
<el-input class="filter-item" v-model="formFlowEntry.formFilter.processDefinitionKey"
:clearable="true" placeholder="流程标识" />
</el-form-item>
<el-form-item label="发布状态">
<el-select class="filter-item" v-model="formFlowEntry.formFilter.status" :clearable="true" filterable
placeholder="发布状态">
<el-option v-for="item in SysFlowEntryPublishedStatus.getList()" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormFlowEntry(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formFlowEntry:formFlowEntry:update')"
@click="onAddFlowEntryClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table ref="flowEntry" :data="formFlowEntry.flowEntryWidget.dataList" size="mini" @sort-change="formFlowEntry.flowEntryWidget.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formFlowEntry.flowEntryWidget.getTableIndex" />
<el-table-column label="流程名称" prop="processDefinitionName">
</el-table-column>
<el-table-column label="流程标识" prop="processDefinitionKey">
</el-table-column>
<el-table-column label="流程分类" prop="flowCategory.name">
</el-table-column>
<el-table-column label="发布状态" prop="status">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.status === SysFlowEntryPublishedStatus.PUBLISHED ? 'success' : 'warning'">
{{SysFlowEntryPublishedStatus.getValue(scope.row.status)}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="流程主版本" prop="mainFlowEntryPublish" header-align="center" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.mainFlowEntryPublish" size="mini" type="primary" effect="dark">
{{'V:' + scope.row.mainFlowEntryPublish.publishVersion}}
</el-tag>
<el-tag v-if="scope.row.mainFlowEntryPublish" size="mini" effect="dark" style="margin-left: 10px"
:type="scope.row.mainFlowEntryPublish.activeStatus ? 'success' : 'danger'"
>
{{scope.row.mainFlowEntryPublish.activeStatus ? '激活' : '挂起'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="最近发布时间" prop="lastestPublishTime" sortable="custom" />
<el-table-column label="创建时间" prop="createTime" sortable="custom" />
<el-table-column label="操作" fixed="right" width="250px">
<template slot-scope="scope">
<el-button class="table-btn success" @click.stop="onStartFlowEntryClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formFlowEntry:formFlowEntry:start') ||
!(scope.row.mainFlowEntryPublish && scope.row.mainFlowEntryPublish.activeStatus)">
启动
</el-button>
<el-button class="table-btn success" @click.stop="onEditFlowEntryClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formFlowEntry:formFlowEntry:update')">
编辑
</el-button>
<el-button @click.stop="onPublishedClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formFlowEntry:formFlowEntry:update')">
发布
</el-button>
<el-button @click.stop="onPublishedEntryListClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formFlowEntry:formFlowEntry:update')">
版本管理
</el-button>
<el-button class="table-btn delete" @click.stop="onDeleteFlowEntryClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formFlowEntry:formFlowEntry:update')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formFlowEntry.flowEntryWidget.totalCount"
:current-page="formFlowEntry.flowEntryWidget.currentPage"
:page-size="formFlowEntry.flowEntryWidget.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formFlowEntry.flowEntryWidget.onCurrentPageChange"
@size-change="formFlowEntry.flowEntryWidget.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
<FormEditFlowEntry v-if="showFlowEntryDesign" :flowEntry="currentFlowEntry" @close="onEditFlowEntryClose" />
</div>
</template>
<script>
import '@/staticDict/flowStaticDict.js';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { FlowEntryController, FlowDictionaryController, FlowOperationController } from '@/api/flowController.js';
import FormPublishedFlowEntry from './formPublishedFlowEntry.vue';
import FormEditFlowEntry from './formEditFlowEntry.vue';
export default {
name: 'formFlowEntry',
components: {
FormEditFlowEntry
},
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
showFlowEntryDesign: false,
currentFlowEntry: undefined,
formFlowEntry: {
formFilter: {
status: undefined,
categoryId: undefined,
processDefinitionName: undefined,
processDefinitionKey: undefined
},
formFilterCopy: {
status: undefined,
categoryId: undefined,
processDefinitionName: undefined,
processDefinitionKey: undefined
},
categoryIdWidget: new DropdownWidget(this.loadCategoryIdDropdownList),
flowEntryWidget: new TableWidget(this.loadFlowEntryWidgetData, this.loadFlowEntryVerify, true, false, 'entryId', 1),
isInit: false
}
}
},
methods: {
onEditFlowEntryClose () {
this.showFlowEntryDesign = false;
this.currentFlowEntry = null;
this.refreshFormFlowEntry();
},
/**
* FlowEntry数据获取函数返回Promise
*/
loadFlowEntryWidgetData (params) {
if (params == null) params = {};
params = {
...params,
flowEntryDtoFilter: {
categoryId: this.formFlowEntry.formFilterCopy.categoryId,
processDefinitionName: this.formFlowEntry.formFilterCopy.processDefinitionName,
processDefinitionKey: this.formFlowEntry.formFilterCopy.processDefinitionKey,
status: this.formFlowEntry.formFilterCopy.status
}
}
return new Promise((resolve, reject) => {
FlowEntryController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* FlowEntry数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadFlowEntryVerify () {
this.formFlowEntry.formFilterCopy.categoryId = this.formFlowEntry.formFilter.categoryId;
this.formFlowEntry.formFilterCopy.processDefinitionName = this.formFlowEntry.formFilter.processDefinitionName;
this.formFlowEntry.formFilterCopy.processDefinitionKey = this.formFlowEntry.formFilter.processDefinitionKey;
this.formFlowEntry.formFilterCopy.status = this.formFlowEntry.formFilter.status;
return true;
},
/**
* 流程分类下拉数据获取函数
*/
loadCategoryIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
FlowDictionaryController.dictFlowCategory(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 流程分类选中值改变
*/
onCategoryIdValueChange (value) {
},
/**
* 更新流程设计
*/
refreshFormFlowEntry (reloadData = false) {
if (reloadData) {
this.formFlowEntry.flowEntryWidget.refreshTable(true, 1);
} else {
this.formFlowEntry.flowEntryWidget.refreshTable();
}
if (!this.formFlowEntry.isInit) {
// 初始化下拉数据
}
this.formFlowEntry.isInit = true;
},
/**
* 启动
*/
onStartFlowEntryClick (row) {
let params = {
processDefinitionKey: row.processDefinitionKey
}
FlowOperationController.viewInitialTaskInfo(this, params).then(res => {
if (res.data && res.data.taskType === this.SysFlowTaskType.USER_TASK && res.data.assignedMe) {
this.$router.push({
name: res.data.routerName || 'handlerFlowTask',
query: {
processDefinitionKey: row.processDefinitionKey,
formId: res.data.formId,
routerName: res.data.routerName,
readOnly: res.data.readOnly,
taskName: '启动流程',
flowEntryName: row.processDefinitionName,
operationList: (res.data.operationList || []).filter(item => item.type !== this.SysFlowTaskOperationType.CO_SIGN),
variableList: res.data.variableList
}
});
} else {
FlowOperationController.startOnly(this, {
processDefinitionKey: row.processDefinitionKey
}).then(res => {
this.$message.success('启动成功!');
}).catch(e => {});
}
}).catch(e => {});
},
/**
* 新建
*/
onAddFlowEntryClick () {
this.showFlowEntryDesign = true;
},
/**
* 编辑
*/
onEditFlowEntryClick (row) {
this.currentFlowEntry = row;
this.showFlowEntryDesign = true;
},
/**
* 发布
*/
onPublishedClick (row) {
this.$confirm('是否发布当前工作流设计?').then(res => {
if (
row.entryId == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
entryId: row.entryId
};
FlowEntryController.publish(this, params).then(res => {
this.$message.success('发布成功');
this.refreshFormFlowEntry();
}).catch(e => {});
}).catch(e => {});
},
/**
* 版本管理
*/
onPublishedEntryListClick (row) {
this.$dialog.show('版本管理', FormPublishedFlowEntry, {
area: ['1200px', '750px']
}, {
flowEntry: row
}).then(res => {
this.refreshFormFlowEntry();
}).catch(e => {
this.refreshFormFlowEntry();
});
},
/**
* 删除
*/
onDeleteFlowEntryClick (row) {
if (
row.entryId == null
) {
this.$message.error('请求失败,发现必填参数为空!');
return;
}
let params = {
entryId: row.entryId
};
this.$confirm('是否删除此流程?').then(res => {
FlowEntryController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.formFlowEntry.flowEntryWidget.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormFlowEntry();
},
initFormData () {
},
formInit () {
this.refreshFormFlowEntry();
}
},
mounted () {
// 初始化页面数据
this.formInit();
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,175 @@
<template>
<!-- 流程版本管理 -->
<div class="form-single-fragment" style="position: relative;">
<el-row>
<el-col :span="24" v-if="entryXml == null">
<el-table ref="flowEntry" :data="publishedFlowEntryWidget.dataList" size="mini" height="655px"
@sort-change="publishedFlowEntryWidget.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="publishedFlowEntryWidget.getTableIndex" />
<el-table-column label="流程名称" prop="processDefinitionName">
<template>
<span>{{flowEntry.processDefinitionName}}</span>
</template>
</el-table-column>
<el-table-column label="流程分类">
<template>
<span>{{flowEntry.flowCategory.name}}</span>
</template>
</el-table-column>
<el-table-column label="流程版本" prop="publishVersion">
<template slot-scope="scope">
<el-tag size="mini" type="primary" effect="dark">{{'V:' + scope.row.publishVersion}}</el-tag>
</template>
</el-table-column>
<el-table-column label="激活状态" prop="activeStatus">
<template slot-scope="scope">
<el-tag size="mini" effect="dark" :type="scope.row.activeStatus ? 'success' : 'danger'">
{{scope.row.activeStatus ? '激活' : '挂起'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="主版本" prop="mainVersion">
<template slot-scope="scope">
<el-tag size="mini" effect="dark" :type="scope.row.mainVersion ? 'success' : 'danger'">
{{scope.row.mainVersion ? '是' : '否'}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="发布时间" prop="publishTime" min-width="150px" />
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="scope">
<el-button class="table-btn" :class="scope.row.activeStatus ? 'delete' : 'success'"
@click.stop="onSetActiveStatus(scope.row)" type="text" size="mini">
{{scope.row.activeStatus ? '挂起' : '激活'}}
</el-button>
<el-button class="table-btn primary" type="text" size="mini" @click="getTaskProcessXml(scope.row)">
流程图
</el-button>
<el-button class="table-btn primary" :disabled="scope.row.mainVersion"
@click.stop="onSetMainVersion(scope.row)" type="text" size="mini">
设置为主版本
</el-button>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="24" v-show="entryXml != null">
<ProcessViewer :xml="entryXml" style="height: 653px">
<el-button type="default" size="medium" icon="el-icon-circle-close" @click.stop="entryXml = undefined" />
</ProcessViewer>
</el-col>
</el-row>
</div>
</template>
<script>
import { TableWidget } from '@/utils/widget.js';
import { FlowEntryController, FlowOperationController } from '@/api/flowController.js';
import ProcessViewer from '@/views/workflow/components/ProcessViewer.vue';
export default {
name: 'formPublishedFlowEntry',
props: {
flowEntry: {
type: Object,
required: true
}
},
components: {
ProcessViewer
},
data () {
return {
entryXml: undefined,
publishedFlowEntryWidget: new TableWidget(this.loadFlowEntryWidgetData, this.loadFlowEntryVerify, false, false)
}
},
methods: {
/**
* 工作流发布版本数据获取函数返回Promise
*/
loadFlowEntryWidgetData (params) {
if (params == null) params = {};
params = {
...params,
entryId: this.flowEntry.entryId
}
return new Promise((resolve, reject) => {
FlowEntryController.listFlowEntryPublish(this, params).then(res => {
resolve({
dataList: res.data,
totalCount: Array.isArray(res.data) ? res.data.length : 0
});
}).catch(e => {
reject(e);
});
});
},
/**
* 工作流发布版本数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadFlowEntryVerify () {
return true;
},
/**
* 设置主版本
*/
onSetMainVersion (row) {
this.$confirm('是否将当前版本设置为主版本?').then(res => {
let params = {
entryId: this.flowEntry.entryId,
newEntryPublishId: row.entryPublishId
}
return FlowEntryController.updateMainVersion(this, params);
}).then(res => {
this.refreshFormFlowEntry();
}).catch(e => {});
},
/**
* 激活 / 挂起
*/
onSetActiveStatus (row) {
let params = {
entryPublishId: row.entryPublishId
}
let httpCall = row.activeStatus ? FlowEntryController.suspendFlowEntryPublish(this, params) : FlowEntryController.activateFlowEntryPublish(this, params);
httpCall.then(res => {
this.$message.success(`${row.activeStatus ? '挂起成功!' : '激活成功!'}`);
this.refreshFormFlowEntry();
}).catch(e => {});
},
refreshFormFlowEntry (reloadData = false) {
if (reloadData) {
this.publishedFlowEntryWidget.refreshTable(true, 1);
} else {
this.publishedFlowEntryWidget.refreshTable();
}
},
/**
* 获取流程图xml
*/
getTaskProcessXml (row) {
if (row.processDefinitionId == null || row.processDefinitionId === '') {
this.entryXml = undefined;
return;
}
let params = {
processDefinitionId: row.processDefinitionId
}
FlowOperationController.viewProcessBpmn(this, params).then(res => {
// 当前流程实例xml
this.entryXml = res.data;
}).catch(e => {});
}
},
mounted () {
// 初始化页面数据
this.refreshFormFlowEntry();
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,316 @@
<template>
<HandlerFlowTask
:processInstanceId="processInstanceId"
:processDefinitionId="processDefinitionId"
:flowEntryName="flowEntryName"
:processInstanceInitiator="processInstanceInitiator"
:taskName="taskName"
:operationList="operationList"
@close="handlerClose(false)"
@start="handlerStart"
@submit="handlerOperation"
>
<!-- 在线表单页面 -->
<WorkflowForm v-if="formId != null" ref="workflowForm"
:formId="formId"
:readOnly="isReadOnly"
:formType="SysOnlineFormType.FLOW"
@ready="onFormReady"
/>
<!-- 路由页面 -->
<router-view ref="routerFlowForm" style="width: 100%;"
:isRuntimeTask="isRuntime"
:readOnly="readOnly"
:processInstanceId="processInstanceId"
:taskId="taskId"
:taskVariableList="variableList"
/>
</HandlerFlowTask>
</template>
<script>
import { mapGetters } from 'vuex';
import flowMixins from '../mixins/flowMixins.js';
import { FlowOperationController } from '@/api/flowController.js';
import WorkflowForm from '@/views/onlineForm/index.vue';
import HandlerFlowTask from '@/views/workflow/components/HandlerFlowTask';
export default {
name: 'handlerFowTask',
props: {
isRuntime: {
type: [Boolean, String],
default: false
},
// 流程标识
processDefinitionKey: {
type: String
},
// 在线表单formId
formId: {
type: String
},
// 路由名称
routerName: {
type: String
},
// 只读页面
readOnly: {
type: [String, Boolean],
default: true
},
// 流程实例id
processInstanceId: {
type: String
},
// 流程定义id
processDefinitionId: {
type: String
},
// 当前任务节点id
taskId: {
type: String
},
// 流程名称
flowEntryName: {
type: String
},
// 发起人
processInstanceInitiator: {
type: String
},
// 当前任务节点名称
taskName: {
type: String
},
// 当前任务节点操作列表
operationList: {
type: Array
},
// 当前任务节点变量列表
variableList: {
type: Array
}
},
components: {
WorkflowForm,
HandlerFlowTask
},
mixins: [flowMixins],
data () {
return {
isStart: false,
// 在线表单是否渲染完毕
isFormReady: false,
// 在线表单页面数据
formData: undefined,
// 在线表单页面一对多数据
oneToManyRelationData: undefined
}
},
methods: {
// 在线表单渲染完毕
onFormReady () {
this.isFormReady = true;
let flowData = {
processDefinitionKey: this.processDefinitionKey,
processInstanceId: this.processInstanceId,
taskId: this.taskId
}
this.$refs.workflowForm.setFormData(this.formData, this.oneToManyRelationData, flowData);
},
/**
* 获得路由组件下的函数
* @param {string} functionName 函数名称
* @returns {function}
*/
getRouterCompomentFunction (functionName) {
return typeof this.$refs.routerFlowForm[functionName] === 'function' ? this.$refs.routerFlowForm[functionName] : undefined;
},
/**
* 获取表单数据
*/
getMasterData (operationType, assignee) {
return new Promise((resolve, reject) => {
if (this.isOnlineForm) {
this.$refs.workflowForm.getFormData().then(formData => {
formData.taskVariableData = this.$refs.workflowForm.getVariableData(this.variableList);
// 会签操作设置多实例处理人集合
if (operationType === this.SysFlowTaskOperationType.MULTI_SIGN) {
if (formData.taskVariableData == null) formData.taskVariableData = {};
formData.taskVariableData.assigneeList = assignee.split(',');
}
resolve(formData);
}).catch(e => {
reject(e);
});
} else {
// 获得静态表单页面的getMasterData函数
let funGetMasterData = this.getRouterCompomentFunction('getMasterData');
return funGetMasterData ? funGetMasterData(this.variableList) : reject();
}
});
},
/**
* 启动流程
*/
handlerStart (operation) {
if (!this.isOnlineForm) {
let funHandlerStart = this.getRouterCompomentFunction('handlerStart');
if (funHandlerStart != null) {
funHandlerStart(operation).then(res => {
this.handlerClose();
}).catch(e => {});
} else {
this.$message.error('当前流程并未实现启动功能,请联系管理员!');
}
} else {
this.preHandlerOperation(operation, true).then(res => {
this.getMasterData(operation.type, (res || {}).assignee).then(formData => {
FlowOperationController.startAndTakeUserTask(this, {
processDefinitionKey: this.processDefinitionKey,
masterData: formData.masterData,
slaveData: formData.slaveData,
taskVariableData: formData.taskVariableData,
flowTaskCommentDto: {
approvalType: operation.type
}
}, {
processDefinitionKey: this.processDefinitionKey
}).then(res => {
this.handlerClose();
this.$message.success('启动成功!');
}).catch(e => {});
});
}).catch(e => {});
}
},
/**
* 流程操作
* @param {Object} operation 流程操作
*/
handlerOperation (operation) {
if (this.isOnlineForm) {
this.preHandlerOperation(operation, this.isStart).then(res => {
// 加签操作
if (operation.type === this.SysFlowTaskOperationType.CO_SIGN) {
this.submitConsign((res || {}).assignee).then(res => {
this.handlerClose();
}).catch(e => {});
return;
}
this.getMasterData(operation.type, (res || {}).assignee).then(formData => {
let params = {
taskId: this.taskId,
processInstanceId: this.processInstanceId,
masterData: formData.masterData,
slaveData: formData.slaveData,
flowTaskCommentDto: {
comment: (res || {}).message,
approvalType: operation.type,
delegateAssginee: operation.type === this.SysFlowTaskOperationType.TRANSFER ? (res || {}).assignee : undefined
},
taskVariableData: formData.taskVariableData
}
FlowOperationController.submitUserTask(this, params).then(res => {
this.handlerClose();
this.$message.success('提交成功!');
}).catch(e => {});
});
}).catch(e => {});
} else {
let funHandlerOperation = this.getRouterCompomentFunction('handlerOperation');
if (funHandlerOperation) {
funHandlerOperation(operation).then(res => {
this.handlerClose();
}).catch(e => {});
} else {
this.$message.error('当前流程并未实现处理功能,请联系管理员!');
}
}
},
/**
* 初始化流程表单数据
*/
initFormData () {
if (this.processInstanceId == null || this.processInstanceId === '' || this.formId == null) {
return;
}
if (this.isOnlineForm) {
let params = {
processInstanceId: this.processInstanceId,
taskId: this.taskId
}
// 判断是展示历史流程的数据还是待办流程的数据
let httpCall = (this.taskId != null && this.isRuntime) ? FlowOperationController.viewUserTask(this, params) : FlowOperationController.viewHistoricProcessInstance(this, params);
httpCall.then(res => {
this.isStart = (res.data == null);
// 一对多数据
this.oneToManyRelationData = (res.data || {}).oneToMany;
// 主表数据以及一对一关联数据
if ((res.data || {}).masterAndOneToOne != null) {
this.formData = {
...res.data.masterAndOneToOne
};
}
}).catch(e => {
});
} else {
let funInitFormData = this.getRouterCompomentFunction('initFormData');
funInitFormData ? funInitFormData() : this.$message.error('当前流程并未实现页面初始化功能,请联系管理员!');
}
}
},
computed: {
isReadOnly () {
return typeof this.readOnly === 'string' ? this.readOnly === 'true' : this.readOnly;
},
isOnlineForm () {
return this.formId != null;
},
...mapGetters(['getMainContextHeight'])
},
mounted () {
this.initFormData();
},
watch: {
formData: {
handler (newValue) {
if (this.isFormReady && newValue) {
let flowData = {
processDefinitionKey: this.processDefinitionKey,
processInstanceId: this.processInstanceId,
taskId: this.taskId
}
this.$refs.workflowForm.setFormData(newValue, this.oneToManyRelationData, flowData);
}
}
}
}
}
</script>
<style scoped>
.task-title {
display: flex;
justify-content: space-between;
padding-bottom: 5px;
margin-bottom: 10px;
border-bottom: 3px solid #409EFF;
}
.task-title .text {
height: 28px;
line-height: 28px;
font-weight: 600;
font-size: 16px;
color: #383838;
}
.task-title .el-tag {
margin-left: 10px;
}
</style>

View File

@@ -0,0 +1,79 @@
import { cachedPageChildMixin } from '@/core/mixins';
import TaskCommit from '@/views/workflow/components/TaskCommit.vue';
import { FlowOperationController } from '@/api/flowController.js';
export default {
mixins: [cachedPageChildMixin],
methods: {
// 加签
submitConsign (assignee) {
return new Promise((resolve, reject) => {
let params = {
taskId: this.taskId,
processInstanceId: this.processInstanceId,
newAssignees: assignee.split(',')
}
FlowOperationController.submitConsign(this, params).then(res => {
this.$message.success('加签成功!');
resolve();
}).catch(e => {
reject();
});
});
},
// 关闭流程处理
handlerClose (isDialog = false) {
if (isDialog) {
if (this.observer != null) {
this.observer.cancel(true);
}
} else {
this.refreshParentCachedPage = true;
this.$router.go(-1);
}
},
// 获取表单数据
async getMasterData () {
return Promise.resolve();
},
// 初始化表单数据
initFormData () {
return new Promise((resolve, reject) => {
this.$message.error('初始化流程表单数据接口并未实现,请联系管理员!');
});
},
// 预处理工作流操作
preHandlerOperation (operation, isStart) {
return new Promise((resolve, reject) => {
if (operation == null) {
isStart ? resolve() : reject();
return;
}
// 会签或者审批操作
if (!isStart || operation.type === this.SysFlowTaskOperationType.MULTI_SIGN) {
let title = isStart ? '提交' : (operation.type === this.SysFlowTaskOperationType.CO_SIGN ? '加签' : '审批');
this.$dialog.show(title, TaskCommit, {
area: '500px'
}, {
operation
}).then(res => {
resolve(res);
}).catch(e => {
reject(e);
});
} else {
resolve();
}
});
},
// 启动流程
handlerStart (operation) {
this.$message.error('当前流程并未实现启动功能,请联系管理员!');
},
// 流程处理操作
handlerOperation (operation) {
this.$message.error('当前流程并未实现处理功能,请联系管理员!');
}
}
}

View File

@@ -0,0 +1,5 @@
const hljs = require("highlight.js/lib/core");
hljs.registerLanguage("xml", require("highlight.js/lib/languages/xml"));
hljs.registerLanguage("json", require("highlight.js/lib/languages/json"));
module.exports = hljs;

View File

@@ -0,0 +1,7 @@
import MyProcessDesigner from "./process-designer";
import MyProcessPenal from "./refactor";
export {
MyProcessDesigner,
MyProcessPenal
}

View File

@@ -0,0 +1,460 @@
<template>
<div class="my-process-designer">
<div class="my-process-designer__header">
<slot name="control-header"></slot>
<template v-if="!$slots['control-header']">
<el-button-group key="file-control">
<el-button :size="headerButtonSize" :type="headerButtonType" icon="el-icon-edit-outline" @click="onSave">保存流程</el-button>
<el-button :size="headerButtonSize" :type="headerButtonType" icon="el-icon-folder-opened" @click="$refs.refFile.click()">打开文件</el-button>
<el-tooltip effect="light">
<div slot="content">
<el-button :size="headerButtonSize" type="text" @click="downloadProcessAsXml()">下载为XML文件</el-button>
<br />
<el-button :size="headerButtonSize" type="text" @click="downloadProcessAsSvg()">下载为SVG文件</el-button>
<br />
<el-button :size="headerButtonSize" type="text" @click="downloadProcessAsBpmn()">下载为BPMN文件</el-button>
</div>
<el-button :size="headerButtonSize" :type="headerButtonType" icon="el-icon-download">下载文件</el-button>
</el-tooltip>
<el-tooltip effect="light">
<div slot="content">
<el-button :size="headerButtonSize" type="text" @click="previewProcessXML">预览XML</el-button>
<br />
<el-button :size="headerButtonSize" type="text" @click="previewProcessJson">预览JSON</el-button>
</div>
<el-button :size="headerButtonSize" :type="headerButtonType" icon="el-icon-view">预览</el-button>
</el-tooltip>
<el-tooltip v-if="simulation" effect="light" :content="this.simulationStatus ? '退出模拟' : '开启模拟'">
<el-button :size="headerButtonSize" :type="headerButtonType" icon="el-icon-cpu" @click="processSimulation">
模拟
</el-button>
</el-tooltip>
</el-button-group>
<el-button-group key="align-control">
<el-tooltip effect="light" content="向左对齐">
<el-button :size="headerButtonSize" class="align align-left" icon="el-icon-s-data" @click="elementsAlign('left')" />
</el-tooltip>
<el-tooltip effect="light" content="向右对齐">
<el-button :size="headerButtonSize" class="align align-right" icon="el-icon-s-data" @click="elementsAlign('right')" />
</el-tooltip>
<el-tooltip effect="light" content="向上对齐">
<el-button :size="headerButtonSize" class="align align-top" icon="el-icon-s-data" @click="elementsAlign('top')" />
</el-tooltip>
<el-tooltip effect="light" content="向下对齐">
<el-button :size="headerButtonSize" class="align align-bottom" icon="el-icon-s-data" @click="elementsAlign('bottom')" />
</el-tooltip>
<el-tooltip effect="light" content="水平居中">
<el-button :size="headerButtonSize" class="align align-center" icon="el-icon-s-data" @click="elementsAlign('center')" />
</el-tooltip>
<el-tooltip effect="light" content="垂直居中">
<el-button :size="headerButtonSize" class="align align-middle" icon="el-icon-s-data" @click="elementsAlign('middle')" />
</el-tooltip>
</el-button-group>
<el-button-group key="scale-control">
<el-tooltip effect="light" content="缩小视图">
<el-button :size="headerButtonSize" :disabled="defaultZoom <= 0.3" icon="el-icon-zoom-out" @click="processZoomOut()" />
</el-tooltip>
<el-button :size="headerButtonSize">{{ Math.floor(this.defaultZoom * 10 * 10) + "%" }}</el-button>
<el-tooltip effect="light" content="放大视图">
<el-button :size="headerButtonSize" :disabled="defaultZoom >= 3.9" icon="el-icon-zoom-in" @click="processZoomIn()" />
</el-tooltip>
<el-tooltip effect="light" content="重置视图并居中">
<el-button :size="headerButtonSize" icon="el-icon-c-scale-to-original" @click="processReZoom()" />
</el-tooltip>
</el-button-group>
<el-button-group key="stack-control">
<el-tooltip effect="light" content="撤销">
<el-button :size="headerButtonSize" :disabled="!revocable" icon="el-icon-refresh-left" @click="processUndo()" />
</el-tooltip>
<el-tooltip effect="light" content="恢复">
<el-button :size="headerButtonSize" :disabled="!recoverable" icon="el-icon-refresh-right" @click="processRedo()" />
</el-tooltip>
<el-tooltip effect="light" content="重新绘制">
<el-button :size="headerButtonSize" icon="el-icon-refresh" @click="processRestart" />
</el-tooltip>
</el-button-group>
</template>
<!-- 用于打开本地文件-->
<input type="file" id="files" ref="refFile" style="display: none" accept=".xml, .bpmn" @change="importLocalFile" />
</div>
<div class="my-process-designer__container">
<div class="my-process-designer__canvas" ref="bpmn-canvas"></div>
</div>
<el-dialog title="预览" width="60%" :visible.sync="previewModelVisible" append-to-body destroy-on-close>
<highlightjs :language="previewType" :code="previewResult" style="height: 60vh" />
</el-dialog>
</div>
</template>
<script>
// 生产环境时优化
// const BpmnModeler = window.BpmnJS;
import BpmnModeler from "bpmn-js/lib/Modeler";
import DefaultEmptyXML from "./plugins/defaultEmpty";
// 翻译方法
import customTranslate from "./plugins/translate/customTranslate";
import translationsCN from "./plugins/translate/zh";
// 模拟流转流程
import tokenSimulation from "bpmn-js-token-simulation";
// 标签解析构建器
// import bpmnPropertiesProvider from "bpmn-js-properties-panel/lib/provider/bpmn";
// 标签解析 Moddle
import camundaModdleDescriptor from "./plugins/descriptor/camundaDescriptor.json";
import activitiModdleDescriptor from "./plugins/descriptor/activitiDescriptor.json";
import flowableModdleDescriptor from "./plugins/descriptor/flowableDescriptor.json";
// 标签解析 Extension
import camundaModdleExtension from "./plugins/extension-moddle/camunda";
import activitiModdleExtension from "./plugins/extension-moddle/activiti";
import flowableModdleExtension from "./plugins/extension-moddle/flowable";
// 引入json转换与高亮
import convert from "xml-js";
export default {
name: "MyProcessDesigner",
componentName: "MyProcessDesigner",
props: {
value: String, // xml 字符串
processId: String,
processName: String,
translations: Object, // 自定义的翻译文件
additionalModel: [Object, Array], // 自定义model
moddleExtension: Object, // 自定义moddle
onlyCustomizeAddi: {
type: Boolean,
default: false
},
onlyCustomizeModdle: {
type: Boolean,
default: false
},
simulation: {
type: Boolean,
default: true
},
keyboard: {
type: Boolean,
default: true
},
prefix: {
type: String,
default: "flowable"
},
events: {
type: Array,
default: () => ["element.click"]
},
headerButtonSize: {
type: String,
default: "small",
validator: value => ["default", "medium", "small", "mini"].indexOf(value) !== -1
},
headerButtonType: {
type: String,
default: "primary",
validator: value => ["default", "primary", "success", "warning", "danger", "info"].indexOf(value) !== -1
}
},
data() {
return {
defaultZoom: 1,
previewModelVisible: false,
simulationStatus: false,
previewResult: "",
previewType: "xml",
recoverable: false,
revocable: false
};
},
computed: {
additionalModules() {
const Modules = [];
// 仅保留用户自定义扩展模块
if (this.onlyCustomizeAddi) {
if (Object.prototype.toString.call(this.additionalModel) === "[object Array]") {
return this.additionalModel || [];
}
return [this.additionalModel];
}
// 插入用户自定义扩展模块
if (Object.prototype.toString.call(this.additionalModel) === "[object Array]") {
Modules.push(...this.additionalModel);
} else {
this.additionalModel && Modules.push(this.additionalModel);
}
// 翻译模块
const TranslateModule = {
translate: ["value", customTranslate(this.translations || translationsCN)]
};
Modules.push(TranslateModule);
// 模拟流转模块
if (this.simulation) {
Modules.push(tokenSimulation);
}
// 根据需要的流程类型设置扩展元素构建模块
// if (this.prefix === "bpmn") {
// Modules.push(bpmnModdleExtension);
// }
if (this.prefix === "camunda") {
Modules.push(camundaModdleExtension);
}
if (this.prefix === "flowable") {
Modules.push(flowableModdleExtension);
}
if (this.prefix === "activiti") {
Modules.push(activitiModdleExtension);
}
return Modules;
},
moddleExtensions() {
const Extensions = {};
// 仅使用用户自定义模块
if (this.onlyCustomizeModdle) {
return this.moddleExtension || null;
}
// 插入用户自定义模块
if (this.moddleExtension) {
for (let key in this.moddleExtension) {
Extensions[key] = this.moddleExtension[key];
}
}
// 根据需要的 "流程类型" 设置 对应的解析文件
if (this.prefix === "activiti") {
Extensions.activiti = activitiModdleDescriptor;
}
if (this.prefix === "flowable") {
Extensions.flowable = flowableModdleDescriptor;
}
if (this.prefix === "camunda") {
Extensions.camunda = camundaModdleDescriptor;
}
return Extensions;
}
},
mounted() {
this.initBpmnModeler();
this.createNewDiagram(this.value);
this.$once("hook:beforeDestroy", () => {
if (this.bpmnModeler) this.bpmnModeler.destroy();
this.$emit("destroy", this.bpmnModeler);
this.bpmnModeler = null;
});
},
methods: {
onSave () {
if (this.bpmnModeler == null) return;
this.bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
this.$emit('save', xml);
});
},
initBpmnModeler() {
if (this.bpmnModeler) return;
this.bpmnModeler = new BpmnModeler({
container: this.$refs["bpmn-canvas"],
keyboard: this.keyboard ? { bindTo: document } : null,
additionalModules: this.additionalModules,
moddleExtensions: this.moddleExtensions
});
this.$emit("init-finished", this.bpmnModeler);
this.initModelListeners();
},
initModelListeners() {
const EventBus = this.bpmnModeler.get("eventBus");
const that = this;
// 注册需要的监听事件, 将. 替换为 - , 避免解析异常
this.events.forEach(event => {
EventBus.on(event, function(eventObj) {
let eventName = event.replace(/\./g, "-");
let element = eventObj ? eventObj.element : null;
that.$emit(eventName, element, eventObj);
that.$emit('event', eventName, element, eventObj);
});
});
// 监听图形改变返回xml
EventBus.on("commandStack.changed", async event => {
try {
this.recoverable = this.bpmnModeler.get("commandStack").canRedo();
this.revocable = this.bpmnModeler.get("commandStack").canUndo();
let { xml } = await this.bpmnModeler.saveXML({ format: true });
this.$emit("commandStack-changed", event);
this.$emit("input", xml);
this.$emit("change", xml);
} catch (e) {
console.error(`[Process Designer Warn]: ${e.message || e}`);
}
});
// 监听视图缩放变化
this.bpmnModeler.on("canvas.viewbox.changed", ({ viewbox }) => {
this.$emit("canvas-viewbox-changed", { viewbox });
const { scale } = viewbox;
this.defaultZoom = Math.floor(scale * 100) / 100;
});
},
/* 创建新的流程图 */
async createNewDiagram(xml) {
// 将字符串转换成图显示出来
let newId = this.processId || `Process_${new Date().getTime()}`;
let newName = this.processName || `业务流程_${new Date().getTime()}`;
let xmlString = xml || DefaultEmptyXML(newId, newName, this.prefix);
try {
let { warnings } = await this.bpmnModeler.importXML(xmlString);
if (warnings && warnings.length) {
warnings.forEach(warn => console.warn(warn));
}
} catch (e) {
console.error(`[Process Designer Warn]: ${e.message || e}`);
}
},
// 下载流程图到本地
async downloadProcess(type, name) {
try {
const _this = this;
// 按需要类型创建文件并下载
if (type === "xml" || type === "bpmn") {
const { err, xml } = await this.bpmnModeler.saveXML();
// 读取异常时抛出异常
if (err) {
console.error(`[Process Designer Warn ]: ${err.message || err}`);
}
let { href, filename } = _this.setEncoded(type.toUpperCase(), name, xml);
downloadFunc(href, filename);
} else {
const { err, svg } = await this.bpmnModeler.saveSVG();
// 读取异常时抛出异常
if (err) {
return console.error(err);
}
let { href, filename } = _this.setEncoded("SVG", name, svg);
downloadFunc(href, filename);
}
} catch (e) {
console.error(`[Process Designer Warn ]: ${e.message || e}`);
}
// 文件下载方法
function downloadFunc(href, filename) {
if (href && filename) {
let a = document.createElement("a");
a.download = filename; //指定下载的文件名
a.href = href; // URL对象
a.click(); // 模拟点击
URL.revokeObjectURL(a.href); // 释放URL 对象
}
}
},
// 根据所需类型进行转码并返回下载地址
setEncoded(type, filename = "diagram", data) {
const encodedData = encodeURIComponent(data);
return {
filename: `${filename}.${type}`,
href: `data:application/${type === "svg" ? "text/xml" : "bpmn20-xml"};charset=UTF-8,${encodedData}`,
data: data
};
},
// 加载本地文件
importLocalFile() {
const that = this;
const file = this.$refs.refFile.files[0];
const reader = new FileReader();
reader.readAsText(file);
reader.onload = function() {
let xmlStr = this.result;
that.createNewDiagram(xmlStr);
};
},
/* ------------------------------------------------ refs methods ------------------------------------------------------ */
downloadProcessAsXml() {
this.downloadProcess("xml");
},
downloadProcessAsBpmn() {
this.downloadProcess("bpmn");
},
downloadProcessAsSvg() {
this.downloadProcess("svg");
},
processSimulation() {
this.simulationStatus = !this.simulationStatus;
this.simulation && this.bpmnModeler.get("toggleMode").toggleMode();
},
processRedo() {
this.bpmnModeler.get("commandStack").redo();
},
processUndo() {
this.bpmnModeler.get("commandStack").undo();
},
processZoomIn(zoomStep = 0.1) {
let 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.bpmnModeler.get("canvas").zoom(this.defaultZoom);
},
processZoomOut(zoomStep = 0.1) {
let 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.bpmnModeler.get("canvas").zoom(this.defaultZoom);
},
processZoomTo(newZoom = 1) {
if (newZoom < 0.2) {
throw new Error("[Process Designer Warn ]: The zoom ratio cannot be less than 0.2");
}
if (newZoom > 4) {
throw new Error("[Process Designer Warn ]: The zoom ratio cannot be greater than 4");
}
this.defaultZoom = newZoom;
this.bpmnModeler.get("canvas").zoom(newZoom);
},
processReZoom() {
this.defaultZoom = 1;
this.bpmnModeler.get("canvas").zoom("fit-viewport", "auto");
},
processRestart() {
this.recoverable = false;
this.revocable = false;
this.createNewDiagram(null).then(() => this.bpmnModeler.get("canvas").zoom(1, "auto"));
},
elementsAlign(align) {
const Align = this.bpmnModeler.get("alignElements");
const Selection = this.bpmnModeler.get("selection");
const SelectedElements = Selection.get();
if (!SelectedElements || SelectedElements.length <= 1) {
this.$message.warning("请按住 Ctrl 键选择多个元素对齐");
return;
}
this.$confirm("自动对齐可能造成图形变形,是否继续?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => Align.trigger(SelectedElements, align));
},
/*----------------------------- 方法结束 ---------------------------------*/
previewProcessXML() {
this.bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
this.previewResult = xml;
this.previewType = "xml";
this.previewModelVisible = true;
});
},
previewProcessJson() {
this.bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
this.previewResult = convert.xml2json(xml, { spaces: 2 });
this.previewType = "json";
this.previewModelVisible = true;
});
}
}
};
</script>

View File

@@ -0,0 +1,7 @@
import MyProcessDesigner from "./ProcessDesigner.vue";
MyProcessDesigner.install = function(Vue) {
Vue.component(MyProcessDesigner.name, MyProcessDesigner);
};
export default MyProcessDesigner;

View File

@@ -0,0 +1,390 @@
import { assign, forEach, isArray } from "min-dash";
import { is } from "bpmn-js/lib/util/ModelUtil";
import { isExpanded, isEventSubProcess } from "bpmn-js/lib/util/DiUtil";
import { isAny } from "bpmn-js/lib/features/modeling/util/ModelingUtil";
import { getChildLanes } from "bpmn-js/lib/features/modeling/util/LaneUtil";
import { hasPrimaryModifier } from "diagram-js/lib/util/Mouse";
/**
* A provider for BPMN 2.0 elements context pad
*/
export default function ContextPadProvider(
config,
injector,
eventBus,
contextPad,
modeling,
elementFactory,
connect,
create,
popupMenu,
canvas,
rules,
translate,
elementRegistry
) {
config = config || {};
contextPad.registerProvider(this);
this._contextPad = contextPad;
this._modeling = modeling;
this._elementFactory = elementFactory;
this._connect = connect;
this._create = create;
this._popupMenu = popupMenu;
this._canvas = canvas;
this._rules = rules;
this._translate = translate;
if (config.autoPlace !== false) {
this._autoPlace = injector.get("autoPlace", false);
}
eventBus.on("create.end", 250, function(event) {
var context = event.context,
shape = context.shape;
if (!hasPrimaryModifier(event) || !contextPad.isOpen(shape)) {
return;
}
var entries = contextPad.getEntries(shape);
if (entries.replace) {
entries.replace.action.click(event, shape);
}
});
}
ContextPadProvider.$inject = [
"config.contextPad",
"injector",
"eventBus",
"contextPad",
"modeling",
"elementFactory",
"connect",
"create",
"popupMenu",
"canvas",
"rules",
"translate",
"elementRegistry"
];
ContextPadProvider.prototype.getContextPadEntries = function(element) {
var contextPad = this._contextPad,
modeling = this._modeling,
elementFactory = this._elementFactory,
connect = this._connect,
create = this._create,
popupMenu = this._popupMenu,
canvas = this._canvas,
rules = this._rules,
autoPlace = this._autoPlace,
translate = this._translate;
var actions = {};
if (element.type === "label") {
return actions;
}
var businessObject = element.businessObject;
function startConnect(event, element) {
connect.start(event, element);
}
function removeElement() {
modeling.removeElements([element]);
}
function getReplaceMenuPosition(element) {
var Y_OFFSET = 5;
var diagramContainer = canvas.getContainer(),
pad = contextPad.getPad(element).html;
var diagramRect = diagramContainer.getBoundingClientRect(),
padRect = pad.getBoundingClientRect();
var top = padRect.top - diagramRect.top;
var left = padRect.left - diagramRect.left;
var pos = {
x: left,
y: top + padRect.height + Y_OFFSET
};
return pos;
}
/**
* Create an append action
*
* @param {string} type
* @param {string} className
* @param {string} [title]
* @param {Object} [options]
*
* @return {Object} descriptor
*/
function appendAction(type, className, title, options) {
if (typeof title !== "string") {
options = title;
title = translate("Append {type}", { type: type.replace(/^bpmn:/, "") });
}
function appendStart(event, element) {
var shape = elementFactory.createShape(assign({ type: type }, options));
create.start(event, shape, {
source: element
});
}
var append = autoPlace
? function(event, element) {
var shape = elementFactory.createShape(assign({ type: type }, options));
autoPlace.append(element, shape);
}
: appendStart;
return {
group: "model",
className: className,
title: title,
action: {
dragstart: appendStart,
click: append
}
};
}
function splitLaneHandler(count) {
return function(event, element) {
// actual split
modeling.splitLane(element, count);
// refresh context pad after split to
// get rid of split icons
contextPad.open(element, true);
};
}
if (isAny(businessObject, ["bpmn:Lane", "bpmn:Participant"]) && isExpanded(businessObject)) {
var childLanes = getChildLanes(element);
assign(actions, {
"lane-insert-above": {
group: "lane-insert-above",
className: "bpmn-icon-lane-insert-above",
title: translate("Add Lane above"),
action: {
click: function(event, element) {
modeling.addLane(element, "top");
}
}
}
});
if (childLanes.length < 2) {
if (element.height >= 120) {
assign(actions, {
"lane-divide-two": {
group: "lane-divide",
className: "bpmn-icon-lane-divide-two",
title: translate("Divide into two Lanes"),
action: {
click: splitLaneHandler(2)
}
}
});
}
if (element.height >= 180) {
assign(actions, {
"lane-divide-three": {
group: "lane-divide",
className: "bpmn-icon-lane-divide-three",
title: translate("Divide into three Lanes"),
action: {
click: splitLaneHandler(3)
}
}
});
}
}
assign(actions, {
"lane-insert-below": {
group: "lane-insert-below",
className: "bpmn-icon-lane-insert-below",
title: translate("Add Lane below"),
action: {
click: function(event, element) {
modeling.addLane(element, "bottom");
}
}
}
});
}
if (is(businessObject, "bpmn:FlowNode")) {
if (is(businessObject, "bpmn:EventBasedGateway")) {
assign(actions, {
"append.receive-task": appendAction("bpmn:ReceiveTask", "bpmn-icon-receive-task", translate("Append ReceiveTask")),
"append.message-intermediate-event": appendAction(
"bpmn:IntermediateCatchEvent",
"bpmn-icon-intermediate-event-catch-message",
translate("Append MessageIntermediateCatchEvent"),
{ eventDefinitionType: "bpmn:MessageEventDefinition" }
),
"append.timer-intermediate-event": appendAction(
"bpmn:IntermediateCatchEvent",
"bpmn-icon-intermediate-event-catch-timer",
translate("Append TimerIntermediateCatchEvent"),
{ eventDefinitionType: "bpmn:TimerEventDefinition" }
),
"append.condition-intermediate-event": appendAction(
"bpmn:IntermediateCatchEvent",
"bpmn-icon-intermediate-event-catch-condition",
translate("Append ConditionIntermediateCatchEvent"),
{ eventDefinitionType: "bpmn:ConditionalEventDefinition" }
),
"append.signal-intermediate-event": appendAction(
"bpmn:IntermediateCatchEvent",
"bpmn-icon-intermediate-event-catch-signal",
translate("Append SignalIntermediateCatchEvent"),
{ eventDefinitionType: "bpmn:SignalEventDefinition" }
)
});
} else if (isEventType(businessObject, "bpmn:BoundaryEvent", "bpmn:CompensateEventDefinition")) {
assign(actions, {
"append.compensation-activity": appendAction("bpmn:Task", "bpmn-icon-task", translate("Append compensation activity"), {
isForCompensation: true
})
});
} else if (
!is(businessObject, "bpmn:EndEvent") &&
!businessObject.isForCompensation &&
!isEventType(businessObject, "bpmn:IntermediateThrowEvent", "bpmn:LinkEventDefinition") &&
!isEventSubProcess(businessObject)
) {
assign(actions, {
"append.end-event": appendAction("bpmn:EndEvent", "bpmn-icon-end-event-none", translate("Append EndEvent")),
"append.gateway": appendAction("bpmn:ExclusiveGateway", "bpmn-icon-gateway-none", translate("Append Gateway")),
"append.append-task": appendAction("bpmn:UserTask", "bpmn-icon-user-task", translate("Append Task")),
"append.intermediate-event": appendAction(
"bpmn:IntermediateThrowEvent",
"bpmn-icon-intermediate-event-none",
translate("Append Intermediate/Boundary Event")
)
});
}
}
if (!popupMenu.isEmpty(element, "bpmn-replace")) {
// Replace menu entry
assign(actions, {
replace: {
group: "edit",
className: "bpmn-icon-screw-wrench",
title: translate("Change type"),
action: {
click: function(event, element) {
var position = assign(getReplaceMenuPosition(element), {
cursor: { x: event.x, y: event.y }
});
popupMenu.open(element, "bpmn-replace", position);
}
}
}
});
}
if (isAny(businessObject, ["bpmn:FlowNode", "bpmn:InteractionNode", "bpmn:DataObjectReference", "bpmn:DataStoreReference"])) {
assign(actions, {
"append.text-annotation": appendAction("bpmn:TextAnnotation", "bpmn-icon-text-annotation"),
connect: {
group: "connect",
className: "bpmn-icon-connection-multi",
title: translate("Connect using " + (businessObject.isForCompensation ? "" : "Sequence/MessageFlow or ") + "Association"),
action: {
click: startConnect,
dragstart: startConnect
}
}
});
}
if (isAny(businessObject, ["bpmn:DataObjectReference", "bpmn:DataStoreReference"])) {
assign(actions, {
connect: {
group: "connect",
className: "bpmn-icon-connection-multi",
title: translate("Connect using DataInputAssociation"),
action: {
click: startConnect,
dragstart: startConnect
}
}
});
}
if (is(businessObject, "bpmn:Group")) {
assign(actions, {
"append.text-annotation": appendAction("bpmn:TextAnnotation", "bpmn-icon-text-annotation")
});
}
// delete element entry, only show if allowed by rules
var deleteAllowed = rules.allowed("elements.delete", { elements: [element] });
if (isArray(deleteAllowed)) {
// was the element returned as a deletion candidate?
deleteAllowed = deleteAllowed[0] === element;
}
if (deleteAllowed) {
assign(actions, {
delete: {
group: "edit",
className: "bpmn-icon-trash",
title: translate("Remove"),
action: {
click: removeElement
}
}
});
}
return actions;
};
// helpers /////////
function isEventType(eventBo, type, definition) {
var isType = eventBo.$instanceOf(type);
var isDefinition = false;
var definitions = eventBo.eventDefinitions || [];
forEach(definitions, function(def) {
if (def.$type === definition) {
isDefinition = true;
}
});
return isType && isDefinition;
}

View File

@@ -0,0 +1,6 @@
import CustomContextPadProvider from "./contentPadProvider";
export default {
__init__: ["contextPadProvider"],
contextPadProvider: ["type", CustomContextPadProvider]
};

View File

@@ -0,0 +1,27 @@
export default (key, name, type) => {
if (!type) type = "camunda";
const TYPE_TARGET = {
activiti: "http://activiti.org/bpmn",
camunda: "http://bpmn.io/schema/bpmn",
flowable: "http://flowable.org/bpmn"
};
return `
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
id="diagram_${key}"
targetNamespace="${TYPE_TARGET[type]}">
<bpmn2:process id="${key}" name="${name}" isExecutable="true">
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="${key}">
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
`;
};

Some files were not shown because too many files have changed in this diff Show More