Compare commits
39 Commits
4bc906d350
...
dfeddfb341
| Author | SHA1 | Date |
|---|---|---|
|
|
dfeddfb341 | |
|
|
27b4cd4971 | |
|
|
e1150abbb0 | |
|
|
0f3da398ee | |
|
|
08fe77cf2f | |
|
|
2c8b9978e8 | |
|
|
92e66c2f45 | |
|
|
a84bbbeedb | |
|
|
9285814edc | |
|
|
cde76e13cb | |
|
|
f98ca9efbb | |
|
|
87b1d9d2c0 | |
|
|
fc288926d5 | |
|
|
74fbae3095 | |
|
|
b271979372 | |
|
|
dabdc0551e | |
|
|
8df27644fb | |
|
|
2392ad5e0a | |
|
|
49c295a5bc | |
|
|
fcfbafa62a | |
|
|
17a00c86d4 | |
|
|
4be0068978 | |
|
|
5be2a2ecd4 | |
|
|
73219c5c04 | |
|
|
318e54f53f | |
|
|
219d33b07e | |
|
|
a59157a525 | |
|
|
16c2d773b9 | |
|
|
e93c22da9f | |
|
|
d6d3832475 | |
|
|
6dc15b6ae0 | |
|
|
14b9e638e3 | |
|
|
6bfd88fc73 | |
|
|
348de04db7 | |
|
|
e78241c710 | |
|
|
e6b901cbbe | |
|
|
ae13cebe3c | |
|
|
424d86ba66 | |
|
|
a1a76b3efa |
File diff suppressed because it is too large
Load Diff
|
|
@ -21,6 +21,7 @@
|
|||
"signature_pad": "^3.0.0-beta.4",
|
||||
"trim-canvas": "^0.1.2",
|
||||
"vue": "^2.6.11",
|
||||
"vue-esign": "^1.1.4",
|
||||
"vue-router": "^3.4.3",
|
||||
"vuedraggable": "^2.24.1",
|
||||
"vuex": "^3.5.1"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
<script>
|
||||
//import layout from './components/layout'
|
||||
import {getToken} from "./main";
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
|
|
@ -16,7 +15,6 @@
|
|||
return {}
|
||||
},
|
||||
created() {
|
||||
getToken()
|
||||
},
|
||||
mounted() {
|
||||
let beforeUrl = sessionStorage.getItem('router-path')
|
||||
|
|
|
|||
|
|
@ -34,6 +34,14 @@ export function getDepartmentTree() {
|
|||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
getOrgTree, getUserByName, getRole,getDepartmentTree
|
||||
//根据角色或者部门获取到对应的数据
|
||||
export function getUserTree(type,chooseId){
|
||||
return request({
|
||||
url:`/admin/user/choose/${type}/${chooseId}`,
|
||||
method:'get'
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
getOrgTree, getUserByName, getRole,getDepartmentTree,getUserTree
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,13 @@ export function startProcessInstance(param) {
|
|||
})
|
||||
}
|
||||
|
||||
export function getAboutInstanceList() {
|
||||
return request({
|
||||
url: "/flowable/process/instance/about",
|
||||
method: "get",
|
||||
})
|
||||
}
|
||||
|
||||
export function getInitiatedInstanceList() {
|
||||
return request({
|
||||
url: "/flowable/process/instance/self",
|
||||
|
|
@ -22,7 +29,7 @@ export function getInitiatedInstanceList() {
|
|||
|
||||
export function getInitiatedInstanceInfo(processInstanceId) {
|
||||
return request({
|
||||
url: "/flowable/process/instance/self/info/"+processInstanceId,
|
||||
url: "/flowable/process/instance/info/"+processInstanceId,
|
||||
method: "get",
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
import request from '@/api/request.js'
|
||||
|
||||
|
||||
// 查询万能查询列表
|
||||
export function listQuery(query) {
|
||||
return request({
|
||||
url: '/custom-query/uni/query',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询万能查询详细
|
||||
export function getQuery(id) {
|
||||
return request({
|
||||
url: '/custom-query/uni/query/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增万能查询
|
||||
export function addQuery(data) {
|
||||
return request({
|
||||
url: '/custom-query/uni/query',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改万能查询
|
||||
export function updateQuery(data) {
|
||||
return request({
|
||||
url: '/custom-query/uni/query',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除万能查询
|
||||
export function delQuery(id) {
|
||||
return request({
|
||||
url: '/custom-query/uni/query/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出万能查询
|
||||
export function exportQuery(query) {
|
||||
return request({
|
||||
url: '/custom-query/uni/query/export',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获取条件
|
||||
export function getQueryInfo(id) {
|
||||
return request({
|
||||
url: '/query/'+id,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
// 修改条件
|
||||
export function editQueryInfo(data) {
|
||||
return request({
|
||||
url: '/query',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
|
@ -5,13 +5,13 @@ import { Notification, MessageBox, Message } from "element-ui";
|
|||
|
||||
// 第三方插件
|
||||
import "element-ui/lib/theme-chalk/index.css";
|
||||
import {getToken} from "../main";
|
||||
|
||||
Vue.prototype.$axios = axios;
|
||||
// 字体图标
|
||||
|
||||
export function getBaseUrl(){
|
||||
return "http://gateway.mytwins.top"
|
||||
// return "http://192.168.101.7:8000"
|
||||
// return "http://localhost:8000"
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ service.interceptors.response.use(
|
|||
rsp => {
|
||||
let data = rsp.data
|
||||
if (data.code === 401){
|
||||
getToken()
|
||||
localStorage.clear()
|
||||
}
|
||||
if (data.code === 1000){
|
||||
return data
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
<template>
|
||||
<div :class="{'hidden':hidden}" class="pagination-container">
|
||||
<el-pagination
|
||||
:background="background"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
:layout="layout"
|
||||
:page-sizes="pageSizes"
|
||||
:total="total"
|
||||
v-bind="$attrs"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Pagination',
|
||||
props: {
|
||||
total: {
|
||||
required: true,
|
||||
type: Number
|
||||
},
|
||||
page: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [10, 20, 30, 50]
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'total, sizes, prev, pager, next, jumper'
|
||||
},
|
||||
background: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoScroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
hidden: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentPage: {
|
||||
get() {
|
||||
return this.page
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:page', val)
|
||||
}
|
||||
},
|
||||
pageSize: {
|
||||
get() {
|
||||
return this.limit
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:limit', val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
this.$emit('pagination', { page: this.currentPage, limit: val })
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.$emit('pagination', { page: val, limit: this.pageSize })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pagination-container {
|
||||
background: #fff;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
.pagination-container.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<!-- @author Shiyn/ huangmx 20200807优化-->
|
||||
<template>
|
||||
<div class="top-right-btn">
|
||||
<el-row>
|
||||
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top">
|
||||
<el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
|
||||
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "RightToolbar",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
props: {
|
||||
showSearch: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
//搜索
|
||||
toggleSearch() {
|
||||
this.$emit("update:showSearch", !this.showSearch);
|
||||
},
|
||||
//刷新
|
||||
refresh() {
|
||||
this.$emit("queryTable");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<template>
|
||||
<div :class="{'line': row === 1, 'lines': row > 1}"
|
||||
:title="hoverTip ? content: null"
|
||||
:style="{'--row':row}">
|
||||
<slot name="pre"></slot>
|
||||
<div style="display: flex;flex-wrap: wrap;">
|
||||
<div v-for="(user,index) in userInfo" :key="index" class="avatar_name">
|
||||
<el-avatar size="large"
|
||||
:src="user.avatar"></el-avatar>
|
||||
<div v-if="user.icon"
|
||||
class="el-timeline-item__node" :style="{
|
||||
backgroundColor: user.color
|
||||
}">
|
||||
<i v-if="user.icon"
|
||||
class="el-timeline-item__icon"
|
||||
:class="user.icon"
|
||||
></i>
|
||||
</div>
|
||||
<el-tooltip class="item" effect="dark" :content="user.name" placement="bottom-start">
|
||||
<span class="item_name">{{ user.name }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<!-- <el-button type="primary" icon="el-icon-plus" circle @click="$refs.userPicker.showUserPicker()"/>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AvatarEllipsis",
|
||||
install(Vue) {
|
||||
Vue.component('avatarEllipsis', this)
|
||||
},
|
||||
components: {},
|
||||
props: {
|
||||
row: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
hoverTip: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
userInfo: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
for (let user of this.userInfo) {
|
||||
this.initUser(user)
|
||||
}
|
||||
},
|
||||
initUser(user) {
|
||||
let state = user.state
|
||||
//创建节点
|
||||
if (state === 'CREATE') {
|
||||
this.$set(user, "icon", "el-icon-check")
|
||||
this.$set(user, "color", "#0bbd87")
|
||||
}
|
||||
//审批通过
|
||||
if (state === 'AGREE' || state === 'AUTO_PASS') {
|
||||
this.$set(user, "icon", "el-icon-check")
|
||||
this.$set(user, "color", "#0bbd87")
|
||||
}
|
||||
//审批处理中
|
||||
if (state === 'RUNNING') {
|
||||
this.$set(user, "icon", "el-icon-loading")
|
||||
this.$set(user, "color", "#f78f5f")
|
||||
}
|
||||
//拒绝后评论
|
||||
if (state === 'REFUSE' || state === 'AUTO_REFUSE') {
|
||||
this.$set(user, "icon", "el-icon-close")
|
||||
this.$set(user, "color", "#f56c6c")
|
||||
}
|
||||
if (state === 'PASS') {
|
||||
this.$set(user, "icon", "el-icon-more")
|
||||
this.$set(user, "color", "#c0c4cc")
|
||||
}
|
||||
return user;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.avatar_name {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-right: 1px;
|
||||
/*width: 45px;*/
|
||||
position: relative;
|
||||
}
|
||||
.el-timeline-item__node {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 1px;
|
||||
}
|
||||
.item_name{
|
||||
width: 45px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
padding-top: 3px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
<!--显示退回节点弹出框-->
|
||||
<div v-if="type === 4" style="margin-bottom: 10px">
|
||||
<span>回退节点:</span>
|
||||
<el-select v-if="userTaskOption.length >0 " v-model="backNode" slot="prepend" placeholder="选择要回退到的节点">
|
||||
<el-select v-if="userTaskOption.length >0 " v-model="rollBackId" slot="prepend" placeholder="选择要回退到的节点">
|
||||
<el-option v-for="(option,index) in userTaskOption" :key="index"
|
||||
:label="option.label" :value="option.value"/>
|
||||
</el-select>
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
</div>
|
||||
<div slot="tip" class="el-upload__tip">添加图片 {{ sizeTip }}</div>
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogVisible" center append-to-body>
|
||||
<el-dialog :visible.sync="dialogVisible" center append-to-body>
|
||||
<div>
|
||||
<img width="100%" :src="dialogImageUrl" alt="" style="z-index: 3435">
|
||||
</div>
|
||||
|
|
@ -140,7 +140,7 @@ export default {
|
|||
authorization: localStorage.getItem("token")
|
||||
},
|
||||
context: null,
|
||||
backNode: null,
|
||||
rollBackId: null,
|
||||
dialogImageUrl: '',
|
||||
dialogVisible: false
|
||||
};
|
||||
|
|
@ -196,7 +196,7 @@ export default {
|
|||
deleteFile(file.id).then(res => {
|
||||
if (res.code === 1000) {
|
||||
this.$message.success("删除成功")
|
||||
this.fileList.splice( this.fileList.findIndex((item)=>item.id===file.id),1)
|
||||
this.fileList.splice(this.fileList.findIndex((item) => item.id === file.id), 1)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
@ -222,7 +222,8 @@ export default {
|
|||
})
|
||||
let data = {
|
||||
context: this.context,
|
||||
attachments: fileList
|
||||
attachments: fileList,
|
||||
rollBackId: this.rollBackId,
|
||||
}
|
||||
this.$emit("ok", data, this.type)
|
||||
this.visible = false;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ export default {
|
|||
//获取角色信息
|
||||
getRole() {
|
||||
getRole().then(res => {
|
||||
console.log('系统角色',res.data);
|
||||
this.roleList= res.data.map(function (val){
|
||||
return {roleId:val.value,roleName:val.label}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,16 +6,34 @@
|
|||
<div style="padding: 5px 8px;">
|
||||
<el-input v-model="filterText" style="width: 100%;" size="small"
|
||||
clearable placeholder="输入关键字进行过滤" prefix-icon="el-icon-search"/>
|
||||
<div style="margin-top: 5px">
|
||||
<el-radio-group v-model="radio" size="mini" @input="radioChange">
|
||||
<el-radio-button :label="0">角色</el-radio-button>
|
||||
<el-radio-button :label="1">部门</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 部门 -->
|
||||
<el-empty :image-size="100" description="似乎没有数据" v-show="deptList.length === 0"/>
|
||||
<el-scrollbar style="height:350px">
|
||||
<el-tree :data="deptList" ref="tree" :props="deptProps" empty-text="" node-key="deptId" default-expand-all
|
||||
:show-checkbox="showCheckbox" check-strictly highlight-current
|
||||
@check-change="handleCheckChange" @node-click="(node,check)=>handle(node,check)"
|
||||
:filter-node-method="filterNode">
|
||||
<div class="custom-tree-node" slot-scope="{ node }" style="width: 100%">
|
||||
<i class="el-icon-folder-opened" style="margin-right: 5px"></i>{{ node.label }}
|
||||
<!-- 人员选择 -->
|
||||
<el-empty :image-size="100" description="似乎没有数据" v-show="dataList.length === 0"/>
|
||||
<el-scrollbar style="height:317px">
|
||||
<el-tree :data="dataList" ref="tree" :props="defaultProps" empty-text="" node-key="value"
|
||||
:default-expanded-keys="expandedKeys"
|
||||
@node-click="handleChange"
|
||||
:filter-node-method="filterNode"
|
||||
>
|
||||
<div class="tree-node" slot-scope="{ node,data }">
|
||||
<div v-if="data.type === 0" style="display: flex;align-items: center">
|
||||
<el-avatar :src="data.avatar"></el-avatar>
|
||||
{{ node.label }}
|
||||
</div>
|
||||
<div v-else-if="data.type === 1">
|
||||
<el-icon class="el-icon-user-solid"/>
|
||||
{{ node.label }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-icon class="el-icon-folder-opened"/>
|
||||
{{ node.label }}
|
||||
</div>
|
||||
</div>
|
||||
</el-tree>
|
||||
</el-scrollbar>
|
||||
|
|
@ -29,9 +47,9 @@
|
|||
<div class="org-items" style="height: 350px;">
|
||||
<el-empty :image-size="100" description="请点击左侧列表选择数据" v-show="selectList.length === 0"/>
|
||||
<div v-for="(selectItem, selectIndex) in selectList" :key="selectIndex" class="org-item">
|
||||
<i class="el-icon-folder-opened"></i>
|
||||
<span>{{ selectItem.label }}</span>
|
||||
<i class="el-icon-close" @click="noSelected(selectItem)" v-if="showCheckbox===false"></i>
|
||||
<el-avatar :src="selectItem.avatar" style="margin-right: 5px;"></el-avatar>
|
||||
{{ selectItem.name }}
|
||||
<i class="el-icon-close" @click="noSelected(selectItem)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -41,10 +59,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {getDepartmentTree} from "@/api/org";
|
||||
import {getUserTree} from "@/api/org";
|
||||
|
||||
export default {
|
||||
name: "departmentPicker",
|
||||
name: "Test",
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
|
@ -63,16 +81,24 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
radio: 0,
|
||||
chooseId: 0,
|
||||
selectItem: {
|
||||
type: -1,
|
||||
value: '0',
|
||||
},
|
||||
activeNames: ['1'],
|
||||
visible: false,
|
||||
loading: false,
|
||||
title: "请选择",
|
||||
selectList: [],
|
||||
filterText: "",
|
||||
deptList: [],
|
||||
deptProps: {
|
||||
dataList: [],
|
||||
expandedKeys: [],
|
||||
defaultProps: {
|
||||
value: 'value',
|
||||
label: 'label',
|
||||
children: 'children'
|
||||
label: 'name',
|
||||
children: 'children',
|
||||
}
|
||||
};
|
||||
},
|
||||
|
|
@ -81,9 +107,6 @@ export default {
|
|||
this.$refs.tree.filter(val);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDepartmentTree();
|
||||
},
|
||||
computed: {
|
||||
_value: {
|
||||
get() {
|
||||
|
|
@ -95,106 +118,77 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
//获取部门信息
|
||||
getDepartmentTree() {
|
||||
getDepartmentTree().then(res => {
|
||||
// const jsona = JSON.stringify(res.data) // 把接口返回的res.data数据转成字符串
|
||||
// const jsonb = jsona.replace(/"value"/g, '"deptId"') // 修改成你要的字段
|
||||
// const jsonc = jsonb.replace(/"label"/g, '"deptName"')
|
||||
this.deptList = res.data
|
||||
console.log("获取部门信息===========", this.deptList);
|
||||
radioChange(e) {
|
||||
this.selectItem.type = -2
|
||||
this.chooseId = 0
|
||||
this.radio = e
|
||||
this.expandedKeys = []
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
getUserTree(this.radio, this.chooseId).then(res => {
|
||||
if (res.data) {
|
||||
if (this.selectItem.type === -1 || this.selectItem.type === -2) {
|
||||
this.dataList = this.setData(res.data)
|
||||
} else if (this.selectItem.type === 1) {
|
||||
this.selectItem.children = res.data
|
||||
} else if (this.selectItem.type === 2) {
|
||||
this.selectItem.children = this.setData(res.data)
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
setData(source) {
|
||||
for (let item of source) {
|
||||
this.$set(item, "value", this.selectItem.value + "-" + item.id)
|
||||
this.$set(item, "children", [])
|
||||
}
|
||||
return source;
|
||||
},
|
||||
//通过关键字过滤树节点
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.deptName.indexOf(value) !== -1;
|
||||
return data.name.indexOf(value) !== -1;
|
||||
},
|
||||
//用于弹开部门选择
|
||||
showDeptPicker() {
|
||||
//用于用户选择
|
||||
showUserPicker() {
|
||||
this.getList();
|
||||
this.visible = true;
|
||||
},
|
||||
/**
|
||||
* 选中部门
|
||||
* @param data 选择的每个节点item
|
||||
* @param checked 是否选中
|
||||
*/
|
||||
handleCheckChange(data, checked) {
|
||||
// 左侧有选择框
|
||||
if (this.showCheckbox) {
|
||||
// 左侧有选择框 + 多选
|
||||
//渲染子节点用户或部门及用户数据
|
||||
handleChange(item, check) {
|
||||
this.selectItem = item
|
||||
this.expandedKeys.push(item.value)
|
||||
if (item.type !== 0) {
|
||||
this.chooseId = item.id
|
||||
this.getList()
|
||||
}
|
||||
if (!item.children) {
|
||||
if (this.multiple) {
|
||||
//不添加重复的数据到右边
|
||||
for (let i = 0; i < this.selectList.length; i++) {
|
||||
if (this.selectList[i].value === data.value) {
|
||||
if (this.selectList[i].id === item.id) {
|
||||
this.selectList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checked) {
|
||||
this.selectList.push(data);
|
||||
} else if (data === '1') {
|
||||
this.$refs.tree.setCheckedKeys([]);
|
||||
this.selectList = [];
|
||||
}
|
||||
} else {// 左侧有选择框 + 单选
|
||||
//不添加重复的数据到右边
|
||||
for (let i = 0; i < this.selectList.length; i++) {
|
||||
if (this.selectList[i].value === data.value) {
|
||||
this.selectList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checked) {
|
||||
this.$refs.tree.setCheckedNodes([data]);
|
||||
this.selectList = [data];
|
||||
} else if (data === '1') {
|
||||
this.$refs.tree.setCheckedKeys([]);
|
||||
this.selectList = [];
|
||||
}
|
||||
this.selectList.push(item);
|
||||
console.log('多选this.selectList', this.selectList);
|
||||
} else {
|
||||
this.selectList = [item];
|
||||
}
|
||||
}
|
||||
this._value = this.selectList
|
||||
},
|
||||
|
||||
//左侧没有选择框时,点击tree-item
|
||||
/**
|
||||
* 可以点击树节点deptName,进行选择
|
||||
* @param node 选择的每个节点item
|
||||
* @param check checked(checkbox选择框)是否选中
|
||||
*/
|
||||
handle(node, check) {
|
||||
if (this.multiple) {
|
||||
//不添加重复的数据到右边
|
||||
for (let i = 0; i < this.selectList.length; i++) {
|
||||
if (this.selectList[i].value === node.value) {
|
||||
this.selectList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
check.checked = true
|
||||
this.selectList.push(node);
|
||||
} else {
|
||||
check.checked = true
|
||||
this.selectList = [node];
|
||||
}
|
||||
this._value = this.selectList
|
||||
},
|
||||
//左侧无选择框时,右侧显示×
|
||||
//右侧的×
|
||||
noSelected(selectItem) {
|
||||
for (let i = 0; i < this.selectList.length; i++) {
|
||||
if (this.selectList[i].value === selectItem.value) {
|
||||
this.selectList.splice(i, 1);
|
||||
this.$refs.tree.setCheckedKeys(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.showCheckbox) {
|
||||
// 左侧有选择框 + 单选
|
||||
if (this.multiple === false) {
|
||||
this.$refs.tree.setCheckedKeys([]);
|
||||
}
|
||||
}
|
||||
selectItem.selected = false;
|
||||
},
|
||||
//清空
|
||||
clearSelected() {
|
||||
|
|
@ -203,10 +197,7 @@ export default {
|
|||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.handleCheckChange("1");
|
||||
if (!this.showCheckbox) {
|
||||
this.selectList = []
|
||||
}
|
||||
this.selectList = []
|
||||
});
|
||||
},
|
||||
//确定按钮
|
||||
|
|
@ -220,6 +211,23 @@ export default {
|
|||
|
||||
<style lang="less" scoped>
|
||||
@containWidth: 278px;
|
||||
/deep/ .el-tree-node {
|
||||
.el-tree-node__children {
|
||||
.el-tree-node__content {
|
||||
height: 42px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tree-node {
|
||||
div {
|
||||
.el-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node {
|
||||
.is-leaf + .el-checkbox .el-checkbox__inner {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,353 @@
|
|||
<template>
|
||||
<w-dialog :border="false" closeFree width="600px" @ok="selectConfirm" :title="title" v-model="visible">
|
||||
<div>
|
||||
<div class="picker">
|
||||
<div class="candidate" v-loading="loading">
|
||||
<div style="padding: 5px 8px;">
|
||||
<el-input v-model="filterText" style="width: 100%;" size="small"
|
||||
clearable placeholder="输入关键字进行过滤" prefix-icon="el-icon-search"/>
|
||||
<div style="margin-top: 5px">
|
||||
<el-radio-group v-model="radio" size="mini" @input="radioChange">
|
||||
<el-radio-button :label="0">角色</el-radio-button>
|
||||
<el-radio-button :label="1">部门</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 人员选择 -->
|
||||
<el-empty :image-size="100" description="似乎没有数据" v-show="dataList.length === 0"/>
|
||||
<el-scrollbar style="height:317px">
|
||||
<el-tree :data="dataList" ref="tree" :props="defaultProps" empty-text="" node-key="value"
|
||||
:default-expanded-keys="expandedKeys" lazy accordion
|
||||
@node-click="handleChange"
|
||||
>
|
||||
<div class="tree-node" slot-scope="{ node,data }" >
|
||||
<div v-if="data.type === 0" style="display: flex;align-items: center;">
|
||||
<el-avatar :src="data.avatar"></el-avatar>
|
||||
{{ node.label }}
|
||||
</div>
|
||||
<div v-else-if="data.type === 1" >
|
||||
<el-icon class="el-icon-user-solid"/>
|
||||
{{ node.label }}
|
||||
</div>
|
||||
<div v-else >
|
||||
<el-icon class="el-icon-folder-opened"/>
|
||||
{{ node.label }}
|
||||
</div>
|
||||
</div>
|
||||
</el-tree>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
|
||||
<div class="selected">
|
||||
<div class="count">
|
||||
<span>已选 {{ selectList.length }} 项</span>
|
||||
<span @click="clearSelected">清空</span>
|
||||
</div>
|
||||
<div class="org-items" style="height: 350px;">
|
||||
<el-empty :image-size="100" description="请点击左侧列表选择数据" v-show="selectList.length === 0"/>
|
||||
<div v-for="(selectItem, selectIndex) in selectList" :key="selectIndex" class="org-item">
|
||||
<el-avatar :src="selectItem.avatar" style="margin-right: 5px;"></el-avatar>
|
||||
{{ selectItem.name }}
|
||||
<i class="el-icon-close" @click="noSelected(selectItem)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</w-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getUserTree} from "@/api/org";
|
||||
|
||||
export default {
|
||||
name: "UserPicker",
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
multiple: { //是否多选
|
||||
default: true,
|
||||
type: Boolean
|
||||
},
|
||||
showCheckbox: { //是否显示左侧选择框
|
||||
default: true,
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
radio: 0,
|
||||
chooseId: 0,
|
||||
selectItem: {
|
||||
type: -1,
|
||||
value: '0',
|
||||
},
|
||||
activeNames: ['1'],
|
||||
visible: false,
|
||||
loading: false,
|
||||
title: "请选择",
|
||||
selectList: [],
|
||||
filterText: "",
|
||||
dataList: [],
|
||||
expandedKeys: [],
|
||||
defaultProps: {
|
||||
value: 'value',
|
||||
label: 'name',
|
||||
children: 'children',
|
||||
isLeaf: function (data, node) {
|
||||
return data.type === 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
_value: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit("input", val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
radioChange(e) {
|
||||
this.selectItem.type = -2
|
||||
this.chooseId = 0
|
||||
this.radio = e
|
||||
this.expandedKeys = []
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
getUserTree(this.radio, this.chooseId).then(res => {
|
||||
// if (res.data) {
|
||||
if (this.selectItem.type === -1 || this.selectItem.type === -2) {
|
||||
this.dataList = res.data
|
||||
} else if (this.selectItem.type === 1) {
|
||||
this.selectItem.children = res.data
|
||||
} else if (this.selectItem.type === 2) {
|
||||
this.selectItem.children = res.data
|
||||
}
|
||||
// }
|
||||
});
|
||||
},
|
||||
setData(source) {
|
||||
// for (let item of source) {
|
||||
// this.$set(item, "value", this.selectItem.value + "-" + item.id)
|
||||
// }
|
||||
return source;
|
||||
},
|
||||
//通过关键字过滤树节点
|
||||
// filterNode(value, data) {
|
||||
// if (!value) return true;
|
||||
// return data.name.indexOf(value) !== -1;
|
||||
// },
|
||||
//用于用户选择
|
||||
showUserPicker() {
|
||||
this.selectItem = {
|
||||
type: -1,
|
||||
value: '0',
|
||||
}
|
||||
this.dataList = []
|
||||
// this.selectList = []
|
||||
this.chooseId = 0
|
||||
this.radio = 0
|
||||
this.visible = true;
|
||||
this.getList();
|
||||
|
||||
},
|
||||
//渲染子节点用户或部门及用户数据
|
||||
handleChange(item, data, node) {
|
||||
this.selectItem = item
|
||||
this.expandedKeys.push(item.value)
|
||||
//不重复发送请求getList()
|
||||
if (node.expanded === false) {
|
||||
if (item.type !== 0) {
|
||||
this.chooseId = item.id
|
||||
this.getList()
|
||||
return
|
||||
}
|
||||
}
|
||||
//仅选择用户
|
||||
if (item.avatar !== null) {
|
||||
if (this.multiple) {
|
||||
//不添加重复的数据到右边
|
||||
for (let i = 0; i < this.selectList.length; i++) {
|
||||
if (this.selectList[i].id === item.id) {
|
||||
this.selectList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.selectList.push(item);
|
||||
} else {
|
||||
this.selectList = [item];
|
||||
}
|
||||
}
|
||||
// this._value = this.selectList
|
||||
},
|
||||
//右侧的×
|
||||
noSelected(selectItem) {
|
||||
for (let i = 0; i < this.selectList.length; i++) {
|
||||
if (this.selectList[i].value === selectItem.value) {
|
||||
this.selectList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
selectItem.selected = false;
|
||||
},
|
||||
//清空
|
||||
clearSelected() {
|
||||
this.$confirm("您确定要清空已选中的项?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.selectList = []
|
||||
});
|
||||
},
|
||||
//确定按钮
|
||||
selectConfirm() {
|
||||
this.$emit("ok", this.selectList);
|
||||
// this.dataList = []
|
||||
this.visible = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@containWidth: 278px;
|
||||
/deep/ .el-tree-node {
|
||||
.el-tree-node__children {
|
||||
.el-tree-node {
|
||||
.el-tree-node__content {
|
||||
height: auto;
|
||||
.tree-node{
|
||||
.el-avatar{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tree-node {
|
||||
div {
|
||||
.el-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node {
|
||||
.is-leaf + .el-checkbox .el-checkbox__inner {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.el-checkbox .el-checkbox__inner {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.picker {
|
||||
height: 402px;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
|
||||
.candidate {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.candidate, .selected {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
width: @containWidth;
|
||||
height: 400px;
|
||||
border: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.selected {
|
||||
border-left: none;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
.count {
|
||||
width: calc(@containWidth - 20px);
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
margin-bottom: 5px;
|
||||
|
||||
& > span:nth-child(2) {
|
||||
float: right;
|
||||
color: #c75450;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.org-items {
|
||||
overflow-y: auto;
|
||||
height: 350px;
|
||||
|
||||
.el-icon-close {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
cursor: pointer;
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
.org-item {
|
||||
margin: 0 5px;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
padding: 7px 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
> span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-scrollbar .el-scrollbar__wrap {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
float: right;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 16px;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -12,13 +12,13 @@ import "@/assets/theme.less";
|
|||
import "@/assets/global.css";
|
||||
import "@/assets/iconfont/iconfont.css"
|
||||
|
||||
import AvatarEllipsis from '@/components/common/AvatarEllipsis'
|
||||
import Ellipsis from '@/components/common/Ellipsis'
|
||||
import WDialog from '@/components/common/WDialog'
|
||||
import Tip from '@/components/common/Tip'
|
||||
import axios from "axios";
|
||||
import {getBaseUrl} from "./api/request";
|
||||
|
||||
Vue.use(ElementUI);
|
||||
Vue.use(AvatarEllipsis);
|
||||
Vue.use(Ellipsis);
|
||||
Vue.use(WDialog);
|
||||
Vue.use(Tip);
|
||||
|
|
@ -48,27 +48,13 @@ Vue.prototype.$deepCopy = function (obj) {
|
|||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
export function getToken() {
|
||||
// let item = localStorage.getItem("token");
|
||||
// if (item != null) {
|
||||
// return
|
||||
// }
|
||||
axios.post(
|
||||
// "http://security-react.mytwins.top/auth/login",
|
||||
// getBaseUrl()+"/auth/login",
|
||||
"http://gateway.mytwins.top/auth/login",
|
||||
// "http://localhost:8000/auth/login",
|
||||
{
|
||||
code: "string",
|
||||
password: "926425",
|
||||
username: "admin",
|
||||
uuid: "string"
|
||||
}
|
||||
).then(res => {
|
||||
console.log(res)
|
||||
localStorage.setItem("token", res.data.data)
|
||||
})
|
||||
}
|
||||
import Pagination from "@/components/Pagination";
|
||||
//自定义表格工具扩展
|
||||
import RightToolbar from "@/components/RightToolbar"
|
||||
// 全局组件挂载
|
||||
Vue.component('Pagination', Pagination)
|
||||
Vue.component('RightToolbar', RightToolbar)
|
||||
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@ const router = new Router({
|
|||
component: () => import("@/views/admin/FormsPanel.vue"),
|
||||
meta: {title: '表单列表', viewport: viewport}
|
||||
},
|
||||
{
|
||||
path: "/query",
|
||||
name: "query",
|
||||
component: () => import("@/views/query/index.vue"),
|
||||
meta: {title: '自定义查询', viewport: viewport}
|
||||
},
|
||||
{
|
||||
path: "/admin/design",
|
||||
name: "design",
|
||||
|
|
|
|||
|
|
@ -8,12 +8,15 @@ export default new Vuex.Store({
|
|||
state: {
|
||||
nodeMap: new Map(),
|
||||
parentMap: new Map(),
|
||||
selectUserMap: new Map(),
|
||||
isEdit: null,
|
||||
selectedNode: {},
|
||||
selectFormItem: null,
|
||||
runningList: [],
|
||||
endList: [],
|
||||
noTakeList: [],
|
||||
refuseList: [],
|
||||
passList: [],
|
||||
design:{},
|
||||
},
|
||||
mutations: {
|
||||
|
|
@ -27,7 +30,11 @@ export default new Vuex.Store({
|
|||
state.isEdit = val
|
||||
}
|
||||
},
|
||||
getters: {},
|
||||
getters: {
|
||||
selectedNode(){
|
||||
return state.selectedNode
|
||||
}
|
||||
},
|
||||
actions: {},
|
||||
modules: {}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
<template>
|
||||
<div style="text-align: center">
|
||||
<!-- <h4>先选择本次登录人员的身份,再进入相应的系统 😅</h4>-->
|
||||
<!-- <h4>先选择本次登录人员的身份,再进入相应的系统 😅</h4>-->
|
||||
<h4>欢迎进入Spring Security 配套 Workflow工作流模块</h4>
|
||||
<div v-if="!token">
|
||||
<el-input v-model="username"/>
|
||||
<el-button @click="getToken">登录</el-button>
|
||||
</div>
|
||||
<div class="work-panel">
|
||||
<!-- <div class="user">-->
|
||||
<!-- <el-button type="primary" round size="small" @click="showRolePicker()" icon="el-icon-user">选择本次登录者</el-button>-->
|
||||
<!-- <div v-if="loginUser !== '' && loginUser !== null">-->
|
||||
<!-- <span>{{ loginUser.name }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="user">-->
|
||||
<!-- <el-button type="primary" round size="small" @click="showRolePicker()" icon="el-icon-user">选择本次登录者</el-button>-->
|
||||
<!-- <div v-if="loginUser !== '' && loginUser !== null">-->
|
||||
<!-- <span>{{ loginUser.name }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<div class="panel">
|
||||
<div class="panel-item" @click="to('/workSpace')">
|
||||
<div>
|
||||
|
|
@ -32,8 +36,8 @@
|
|||
</div>
|
||||
|
||||
|
||||
<!-- <test type="user" ref="orgPicker" :v-model="select" :value="select" @dengjie="dengjie"-->
|
||||
<!-- @ok="selected"></test>-->
|
||||
<!-- <test type="user" ref="orgPicker" :v-model="select" :value="select" @dengjie="dengjie"-->
|
||||
<!-- @ok="selected"></test>-->
|
||||
|
||||
|
||||
</div>
|
||||
|
|
@ -41,12 +45,15 @@
|
|||
|
||||
<script>
|
||||
import Test from "@/components/common/Test";
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "Index",
|
||||
components: {Test},
|
||||
data() {
|
||||
return {
|
||||
token: localStorage.getItem("token"),
|
||||
username: null,
|
||||
select: [],
|
||||
roleData: [
|
||||
{
|
||||
|
|
@ -78,9 +85,30 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
dengjie() {
|
||||
console.log("==================================")
|
||||
console.log(this.select)
|
||||
|
||||
|
||||
getToken() {
|
||||
// let item = localStorage.getItem("token");
|
||||
// if (item != null) {
|
||||
// return
|
||||
// }
|
||||
axios.post(
|
||||
// "http://security-react.mytwins.top/auth/login",
|
||||
// getBaseUrl()+"/auth/login",
|
||||
"http://gateway.mytwins.top/auth/login",
|
||||
// "http://localhost:8000/auth/login",
|
||||
{
|
||||
code: "string",
|
||||
password: "926425",
|
||||
// username: "admin",
|
||||
username: this.username,
|
||||
uuid: "string"
|
||||
}
|
||||
).then(res => {
|
||||
console.log(res)
|
||||
this.token = res.data.data
|
||||
localStorage.setItem("token", this.token)
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -91,8 +91,7 @@
|
|||
<el-radio-button label="E">编辑</el-radio-button>
|
||||
<el-radio-button label="R">查看</el-radio-button>
|
||||
</el-radio-group>
|
||||
<!--todo 表单渲染-->
|
||||
<form-render-view v-if="viewFormVisibleRender" ref="form" :form-items="forms" v-model="formData" :is-preview="true" :model="formPreviewModel"/>
|
||||
<form-render-view v-if="viewFormVisibleRender" ref="form" :form-items="forms" v-model="formValue" :is-preview="true" :model="formPreviewModel"/>
|
||||
</w-dialog>
|
||||
</el-container>
|
||||
</template>
|
||||
|
|
@ -109,7 +108,7 @@ export default {
|
|||
components: {draggable, FormComponentConfig, FormDesignRender, FormRenderView},
|
||||
data() {
|
||||
return {
|
||||
formData: {},
|
||||
// formData: {},
|
||||
libSelect: 0,
|
||||
viewFormVisible: false,
|
||||
viewFormVisibleRender: true,
|
||||
|
|
@ -205,8 +204,8 @@ export default {
|
|||
this.formValue=this.$refs.form.value
|
||||
})
|
||||
for (const key in this.formValue) {
|
||||
if(this.formValue[key]!=undefined){
|
||||
this.formValue[key]=[]
|
||||
if(this.formValue[key]!==undefined){
|
||||
this.formValue[key]=undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
<script>
|
||||
import ProcessTree from './process/ProcessTree.vue'
|
||||
// import ProcessTree from './process/ProcessTreeBack.vue'
|
||||
import NodeConfig from '../../common/process/config/NodeConfig'
|
||||
//流程设计器
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</div>
|
||||
<el-main>
|
||||
<div class="design" :style="'transform: scale('+ scale / 100 +');'">
|
||||
<process-tree ref="process-tree-view"/>
|
||||
<process-tree ref="process-tree"/>
|
||||
</div>
|
||||
</el-main>
|
||||
</div>
|
||||
|
|
@ -34,6 +34,21 @@ export default {
|
|||
},
|
||||
beforeDestroy() {
|
||||
this.$store.state.diagramMode = "design";
|
||||
},
|
||||
methods:{
|
||||
//校验数据配置的合法性
|
||||
validate() {
|
||||
return this.$refs["process-tree"].validateProcess()
|
||||
},
|
||||
validate_ASSIGN_USER(err) {
|
||||
if (this.config.props.assignedUser.length > 0) {
|
||||
return true;
|
||||
} else {
|
||||
this.errorInfo = '请指定审批人员'
|
||||
err.push(`${this.config.name} 未指定审批人员`)
|
||||
return false
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<!--todo 预览时渲染的component-->
|
||||
<component ref="form" :is="config.name" :mode="mode" :perm="perm" v-model="_value" v-bind="config.props"/>
|
||||
<component ref="form" :is="config.name" :config="config" :mode="mode" :perm="perm" v-model="_value" v-bind="config.props"/>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
|
|
|
|||
|
|
@ -30,23 +30,28 @@ export default {
|
|||
return this.$store.state.parentMap;
|
||||
},
|
||||
dom() {
|
||||
console.log(this.$store.state.design)
|
||||
return this.$store.state.design.process;
|
||||
},
|
||||
viewer(){
|
||||
viewer() {
|
||||
return this.$store.state.diagramMode === 'viewer'
|
||||
},
|
||||
preview(){
|
||||
preview() {
|
||||
return this.$store.state.preview;
|
||||
},
|
||||
runningList(){
|
||||
return this.$store.state.runningList
|
||||
runningList() {
|
||||
return this.$store.state.runningList
|
||||
},
|
||||
endList(){
|
||||
return this.$store.state.endList
|
||||
endList() {
|
||||
return this.$store.state.endList
|
||||
},
|
||||
noTakeList(){
|
||||
return this.$store.state.noTakeList
|
||||
noTakeList() {
|
||||
return this.$store.state.noTakeList
|
||||
},
|
||||
refuseList() {
|
||||
return this.$store.state.refuseList
|
||||
},
|
||||
passList() {
|
||||
return this.$store.state.passList
|
||||
},
|
||||
},
|
||||
render(h, ctx) {
|
||||
|
|
@ -64,17 +69,19 @@ export default {
|
|||
return []
|
||||
}
|
||||
if (node.props && this.viewer && !this.preview) {
|
||||
let headerBgc = '#ff943e'
|
||||
if (this.runningList.includes(node.id)) {
|
||||
headerBgc = '#1e90ff'
|
||||
}
|
||||
else if (this.endList.includes(node.id)) {
|
||||
headerBgc = '#20b2aa'
|
||||
}
|
||||
else if (this.noTakeList.includes(node.id)) {
|
||||
headerBgc = '#909399'
|
||||
}
|
||||
node.props.headerBgc = headerBgc
|
||||
let headerBgc = '#ff943e'
|
||||
if (this.runningList.includes(node.id)) {
|
||||
headerBgc = '#1e90ff'
|
||||
} else if (this.endList.includes(node.id)) {
|
||||
headerBgc = '#20b2aa'
|
||||
} else if (this.noTakeList.includes(node.id)) {
|
||||
headerBgc = '#909399'
|
||||
} else if (this.refuseList.includes(node.id)) {
|
||||
headerBgc = '#f56c6c'
|
||||
} else if (this.passList.includes(node.id)) {
|
||||
headerBgc = '#ff943e'
|
||||
}
|
||||
node.props.headerBgc = headerBgc
|
||||
}
|
||||
if (this.isPrimaryNode(node)) {
|
||||
//普通业务节点
|
||||
|
|
@ -98,7 +105,7 @@ export default {
|
|||
//插入添加分支/条件的按钮
|
||||
branchItems.unshift(h('div', {'class': {'add-branch-btn': true}}, [
|
||||
h('el-button', {
|
||||
'class': {'add-branch-btn-el': !this.viewer},
|
||||
'class': {'add-branch-btn-el': !this.viewer},
|
||||
props: {size: 'small', round: true},
|
||||
on: {click: () => this.addBranchNode(node)},
|
||||
domProps: {
|
||||
|
|
@ -161,7 +168,7 @@ export default {
|
|||
this.nodeMap.set(nodeItem.id, nodeItem)
|
||||
this.parentMap.set(nodeItem.parentId, nodeItem)
|
||||
})
|
||||
}catch (e){
|
||||
} catch (e) {
|
||||
}
|
||||
},
|
||||
//id映射到map,用来向上遍历
|
||||
|
|
@ -254,6 +261,7 @@ export default {
|
|||
},
|
||||
//选中一个节点
|
||||
selectNode(node) {
|
||||
console.log(node)
|
||||
this.$store.commit('selectedNode', node)
|
||||
console.log(node, "node")
|
||||
if (!this.isConcurrentNode(node)) {
|
||||
|
|
|
|||
|
|
@ -14,16 +14,17 @@ let Location = () => import('./components/Location.vue')
|
|||
let MoneyInput = () => import('./components/MoneyInput.vue')
|
||||
let DeptPicker = () => import('./components/DeptPicker.vue')
|
||||
let UserPicker = () => import('./components/UserPicker.vue')
|
||||
let SignPanel = () => import('./components/SignPannel.vue')
|
||||
let RatePicker = () => import('./components/RatePicker.vue')
|
||||
|
||||
let SpanLayout = () => import('./components/SpanLayout.vue')
|
||||
let TableList = () => import('./components/TableList.vue')
|
||||
let SignPanel = () => import('./components/SignPanel.vue')
|
||||
|
||||
export default {
|
||||
//基础组件
|
||||
TextInput, NumberInput, AmountInput, TextareaInput, SelectInput, MultipleSelect,
|
||||
DateTime, DateTimeRange, UserPicker, DeptPicker,
|
||||
DateTime, DateTimeRange, UserPicker, DeptPicker,RatePicker,
|
||||
//高级组件
|
||||
Description, FileUpload, ImageUpload, MoneyInput, Location, SignPanel,
|
||||
SpanLayout, TableList
|
||||
SpanLayout, TableList,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export const ValueType = {
|
|||
date: 'Date',
|
||||
user: 'User',
|
||||
dept: 'Dept',
|
||||
star: 'star',
|
||||
dateRange: 'DateRange'
|
||||
}
|
||||
|
||||
|
|
@ -179,6 +180,22 @@ export const baseComponents = [
|
|||
multiple: false
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '评分',
|
||||
name: 'RatePicker',
|
||||
icon: 'el-icon-star-off',
|
||||
value: '',
|
||||
valueType: ValueType.star,
|
||||
props: {
|
||||
color: '#f0a732',
|
||||
max: 5,
|
||||
required: false,
|
||||
enablePrint: true,
|
||||
showScore: true,
|
||||
enableHalf: true,
|
||||
placeholder: undefined,
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '说明文字',
|
||||
name: 'Description',
|
||||
|
|
@ -210,7 +227,20 @@ export const baseComponents = [
|
|||
maxSize: 0, //最大条数,为0则不限制
|
||||
columns:[] //列设置
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '签名',
|
||||
name: 'SignPanel',
|
||||
icon: 'el-icon-edit',
|
||||
value: [],
|
||||
valueType: ValueType.string,
|
||||
props: {
|
||||
required: false,
|
||||
enablePrint: true,
|
||||
isCrop: true,
|
||||
lineColor: '#ff0000',
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form label-width="90px" v-if="form.name !== 'SpanLayout'">
|
||||
<el-form-item label="表单ID">
|
||||
<el-input size="small" clearable v-model="form.id" disabled/>
|
||||
</el-form-item>
|
||||
<el-form-item label="表单名称">
|
||||
<el-input size="small" clearable v-model="form.title"/>
|
||||
</el-form-item>
|
||||
|
|
@ -14,7 +17,6 @@
|
|||
</el-form>
|
||||
<el-empty v-else description="当前组件不支持配置"></el-empty>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -33,6 +35,8 @@ import MoneyInput from './config/MoneyInputConfig.vue'
|
|||
import DeptPicker from './config/OrgPickerConfig.vue'
|
||||
import UserPicker from './config/OrgPickerConfig.vue'
|
||||
import TableList from './config/TableListConfig.vue'
|
||||
import SignPanel from './config/SignPanelConfig.vue'
|
||||
import RatePicker from './config/RatePickerConfig.vue'
|
||||
|
||||
export default {
|
||||
name: "FormComponentConfig",
|
||||
|
|
@ -51,7 +55,9 @@ export default {
|
|||
MoneyInput,
|
||||
DeptPicker,
|
||||
UserPicker,
|
||||
TableList
|
||||
TableList,
|
||||
SignPanel,
|
||||
RatePicker
|
||||
},
|
||||
props:{},
|
||||
computed:{
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export default {
|
|||
rules: {},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
created() {
|
||||
this.loadFormConfig(this.formItems)
|
||||
},
|
||||
computed: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-form ref="form" class="process-form" label-position="top" :rules="rules" :model="_value">
|
||||
<el-form ref="formView" class="process-form" label-position="top" :rules="rules" :model="_value">
|
||||
<div v-for="(item, index) in formItems" :key="item.name + index">
|
||||
<el-form-item v-if="item.name !== 'SpanLayout' && item.name !== 'Description'"
|
||||
:prop="item.id" :label="item.title">
|
||||
|
|
@ -30,15 +30,15 @@ export default {
|
|||
return {}
|
||||
}
|
||||
},
|
||||
model:{
|
||||
model: {
|
||||
type: String,
|
||||
default:() => {
|
||||
default: () => {
|
||||
return "R"
|
||||
}
|
||||
},
|
||||
isPreview:{
|
||||
isPreview: {
|
||||
type: Boolean,
|
||||
default:() => {
|
||||
default: () => {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -58,25 +58,52 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
created() {
|
||||
this.loadFormConfig(this.formItems)
|
||||
},
|
||||
methods: {
|
||||
validate(call) {
|
||||
console.log("我被执行了")
|
||||
|
||||
let success = true
|
||||
this.$refs.formView.validate(valid => {
|
||||
success = valid
|
||||
if(valid){
|
||||
//校验成功再校验内部
|
||||
for (let i = 0; i < this.formItems.length; i++) {
|
||||
if (this.formItems[i].name === 'TableList'){
|
||||
let formRef = this.$refs[`sub-item_${this.formItems[i].id}`]
|
||||
if (formRef && Array.isArray(formRef) && formRef.length > 0){
|
||||
formRef[0].validate(subValid => {
|
||||
success = subValid
|
||||
})
|
||||
if (!success){
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
call(success)
|
||||
});
|
||||
},
|
||||
loadFormConfig(formItems) {
|
||||
formItems.forEach(item => {
|
||||
if (item.name === 'SpanLayout') {
|
||||
this.loadFormConfig(item.props.items)
|
||||
} else {
|
||||
this.$set(this._value, item.id, this.value[item.id])
|
||||
if (this.isPreview){
|
||||
if (this.isPreview) {
|
||||
this.$set(item, 'perm', this.model)
|
||||
}
|
||||
if (item.props.required && this.model === "E") {
|
||||
this.$set(this.rules, item.id, [{
|
||||
type: item.valueType === 'Array' ? 'array' : undefined,
|
||||
required: true,
|
||||
message: `请填写${item.title}`, trigger: 'blur'
|
||||
}])
|
||||
if (item.perm === 'E') {
|
||||
if (item.props.required) {
|
||||
this.$set(this.rules, item.id, [{
|
||||
type: item.valueType === 'Array' ? 'array' : undefined,
|
||||
required: true,
|
||||
message: `请填写${item.title}`, trigger: 'blur'
|
||||
}])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -90,6 +117,7 @@ export default {
|
|||
margin: 15px 0;
|
||||
padding: 10px 10px 1px 10px;
|
||||
background: #fff;
|
||||
|
||||
/deep/ .el-form-item__label {
|
||||
padding: 0 0;
|
||||
}
|
||||
|
|
@ -98,6 +126,7 @@ export default {
|
|||
padding-left: 5px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
/deep/ .el-form-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<div>
|
||||
<template v-if="mode === 'DESIGN'">
|
||||
<el-rate
|
||||
disabled
|
||||
:show-score="showScore"
|
||||
:allow-half="enableHalf"
|
||||
:text-color="color"
|
||||
text-color="#ff9900"
|
||||
score-template="{value}">
|
||||
</el-rate>
|
||||
<p>{{ placeholder }}</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="perm === 'E'">
|
||||
<el-rate
|
||||
v-model="_value"
|
||||
:show-score="showScore"
|
||||
:allow-half="enableHalf"
|
||||
:text-color="color"
|
||||
score-template="{value}">
|
||||
</el-rate>
|
||||
<p>{{ placeholder }}</p>
|
||||
</template>
|
||||
<template v-else-if="perm === 'R'">
|
||||
<el-rate
|
||||
v-model="_value"
|
||||
disabled
|
||||
:show-score="showScore"
|
||||
:allow-half="enableHalf"
|
||||
:text-color="color"
|
||||
score-template="{value}">
|
||||
</el-rate>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import componentMinxins from '../ComponentMinxins'
|
||||
|
||||
export default {
|
||||
mixins: [componentMinxins],
|
||||
name: "RatePicker",
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
perm: {
|
||||
type: String,
|
||||
default: 'E'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#f0a732'
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请打分!'
|
||||
},
|
||||
enableHalf: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showScore: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
p{
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
<template>
|
||||
<div>
|
||||
<template v-if="mode === 'DESIGN'">
|
||||
<el-icon class="el-icon-location-information"/>
|
||||
请签名
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="perm === 'E'">
|
||||
<div v-if="!_value">
|
||||
<el-button icon="el-icon-edit" @click="doSign">请签字</el-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
<el-image fit="contain" class="sign-border-preview" style="width: 200px; height: 100px" @click="doSign"
|
||||
:src="_value"/>
|
||||
</div>
|
||||
<div>
|
||||
点击签名重签
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="perm === 'R'">
|
||||
<div v-if="_value">
|
||||
<el-image fit="contain" style="width: 200px; height: 100px" :src="_value"/>
|
||||
</div>
|
||||
<div>
|
||||
请签名
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<el-dialog title="请使用鼠标签字" width="800px" :visible.sync="sign.open" @close="signClose" append-to-body>
|
||||
<div class="sign-border">
|
||||
<vue-esign v-if="sign.open" ref="sign" :width="800" :height="300" :isCrop="isCrop"
|
||||
:lineWidth="sign.lineWidth" :lineColor="sign.lineColor"
|
||||
:bgColor.sync="sign.bgColor"/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<el-button size="mini" @click="signClose">取消</el-button>
|
||||
<el-button size="mini" type="primary" @click="handleGenerate">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import vueEsign from 'vue-esign'
|
||||
|
||||
|
||||
import componentMinxins from '../ComponentMinxins'
|
||||
|
||||
export default {
|
||||
mixins: [componentMinxins],
|
||||
name: "SignPanel",
|
||||
components: {vueEsign},
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
perm: {
|
||||
type: String,
|
||||
default: 'E'
|
||||
},
|
||||
isCrop: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
lineColor: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sign: {
|
||||
open: false,
|
||||
lineWidth: 6,
|
||||
bgColor: '',
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
signClose() {
|
||||
this.sign.open = false
|
||||
this.$refs.sign.reset()
|
||||
},
|
||||
doSign() {
|
||||
this.sign.open = true
|
||||
},
|
||||
handleGenerate() {
|
||||
this.$refs.sign.generate().then(res => {
|
||||
this._value = res
|
||||
this.sign.open = false
|
||||
}).catch(err => {
|
||||
alert(err) // 画布没有签字时会执行这里 'Not Signned'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sign-border {
|
||||
border: 1px dashed #2b2b2b;
|
||||
}
|
||||
|
||||
.sign-border-preview {
|
||||
border: 1px solid #ffffff;
|
||||
}
|
||||
|
||||
.sign-border-preview:hover {
|
||||
border: 1px dashed #1989fa;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SignPannel",
|
||||
components: {},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -2,37 +2,50 @@
|
|||
<div style="max-width: 350px">
|
||||
<template v-if="mode === 'DESIGN'">
|
||||
<el-button disabled icon="el-icon-user" type="primary" size="mini" round>选择人员</el-button>
|
||||
<span class="placeholder"> {{placeholder}}</span>
|
||||
<span class="placeholder"> {{ placeholder }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="perm === 'E'">
|
||||
<el-button icon="el-icon-user" type="primary" size="mini" round @click="$refs.orgPicker.show()">选择人员</el-button>
|
||||
<org-picker type="user" :multiple="multiple" ref="orgPicker" :selected="_value" @ok="selected"/>
|
||||
<span class="placeholder"> {{placeholder}}</span>
|
||||
<div style="margin-top: 5px">
|
||||
<el-tag size="mini" style="margin: 5px" closable v-for="(dept, i) in _value" :key="i" @close="delDept(i)">{{dept.name}}</el-tag>
|
||||
<el-button icon="el-icon-user" type="primary" size="mini" round @click="$refs.userPicker.showUserPicker()">
|
||||
选择人员
|
||||
</el-button>
|
||||
<user-select :multiple="multiple" ref="userPicker" title="请选择系统用户" :v-mode="_value" @ok="selected"/>
|
||||
<span class="placeholder"> {{ placeholder }}</span>
|
||||
<div style="display: flex;">
|
||||
<div class="userStyle" v-for="(user, i) in _value" :key="i">
|
||||
<span @click="delDept(i)">×</span>
|
||||
<el-avatar :src="user.avatar"/>
|
||||
<el-tooltip class="item" effect="dark" :content="user.name" placement="bottom-start">
|
||||
<span>{{ user.name }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="perm === 'R'">
|
||||
{{ _value }}
|
||||
<div style="display: flex;">
|
||||
<div v-for="(user, i) in _value" :key="i" class="view_user">
|
||||
<el-avatar :src="user.avatar"/>
|
||||
<el-tooltip effect="dark" :content="user.name" placement="bottom-start">
|
||||
<span>{{ user.name }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentMinxins from '../ComponentMinxins'
|
||||
import OrgPicker from "@/components/common/Test";
|
||||
import UserSelect from "@/components/common/UserPicker";
|
||||
|
||||
export default {
|
||||
mixins: [componentMinxins],
|
||||
name: "DeptPicker",
|
||||
components: {OrgPicker},
|
||||
name: "UserPicker",
|
||||
components: {UserSelect},
|
||||
props: {
|
||||
value:{
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
|
|
@ -46,32 +59,75 @@ export default {
|
|||
type: String,
|
||||
default: '请选择人员'
|
||||
},
|
||||
multiple:{
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showOrgSelect: false
|
||||
showPickerSelect: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selected(values){
|
||||
this.showOrgSelect = false
|
||||
selected(values) {
|
||||
this.showPickerSelect = false
|
||||
this._value = values
|
||||
},
|
||||
delDept(i){
|
||||
delDept(i) {
|
||||
this._value.splice(i, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.placeholder{
|
||||
<style scoped lang="less">
|
||||
.placeholder {
|
||||
margin-left: 10px;
|
||||
color: #adabab;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.userStyle {
|
||||
width: 45px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
|
||||
span:first-child {
|
||||
position: absolute;
|
||||
right: -3px;
|
||||
top: -11px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span:last-child {
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden
|
||||
}
|
||||
}
|
||||
|
||||
.view_user {
|
||||
width: 45px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 10px;
|
||||
|
||||
span {
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form-item label="提示文字">
|
||||
<el-input size="small" v-model="value.placeholder" placeholder="请设置提示语"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大分值">
|
||||
<el-input-number size="small" :min="1" v-model="value.max" />
|
||||
</el-form-item>
|
||||
<el-form-item label="允许半分">
|
||||
<el-switch v-model="value.enableHalf"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示分值">
|
||||
<el-switch v-model="value.showScore"></el-switch>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "RatePickerConfig",
|
||||
components: {},
|
||||
props:{
|
||||
value:{
|
||||
type: Object,
|
||||
default: ()=>{
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form-item label="是否裁剪">
|
||||
<el-switch v-model="value.isCrop"></el-switch>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SignPanelConfig",
|
||||
components: {},
|
||||
props:{
|
||||
value:{
|
||||
type: Object,
|
||||
default: ()=>{
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
<template>
|
||||
<div style="margin: 10px">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="(operation,index) in operationList"
|
||||
:key="index" :timestamp="operation.startTime"
|
||||
:icon="operation.icon"
|
||||
:color="operation.color"
|
||||
size="large"
|
||||
placement="top">
|
||||
<el-card>
|
||||
<div style="display: flex;">
|
||||
<div v-for="(user,index) in operation.userInfo" :key="index" class="avatar_name">
|
||||
<el-avatar size="large" :src="user.avatar"></el-avatar>
|
||||
<!--v-if="!$slots.dot && operation.userInfo.length > 1" -->
|
||||
<div v-if="user.icon"
|
||||
class="el-timeline-item__node" :style="{
|
||||
backgroundColor: user.color
|
||||
}">
|
||||
<i v-if="user.icon"
|
||||
class="el-timeline-item__icon"
|
||||
:class="user.icon"
|
||||
></i>
|
||||
</div>
|
||||
<el-tooltip effect="dark" :content="user.name" placement="bottom-start">
|
||||
<span class="username">{{ user.name }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div style="margin-left: 10px;">
|
||||
<div style="color: #c0bebe">{{ operation.operationName }}</div>
|
||||
<div style="font-size: 14px; font-weight: bold;">{{ operation.remark }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="operation.comment">
|
||||
<div style="margin-top: 10px;background:#f5f5f5;padding: 10px;">
|
||||
<div>
|
||||
{{ operation.comment.context }}
|
||||
</div>
|
||||
<div style="margin-top: 10px;" v-if="operation.comment.attachments && operation.comment.attachments.length > 0">
|
||||
<template v-for="(item) in getAttachmentList(operation.comment.attachments,true)">
|
||||
<el-image
|
||||
style="width: 100px; height: 100px"
|
||||
:src="item.url"
|
||||
:preview-src-list="[item.url]">
|
||||
</el-image>
|
||||
</template>
|
||||
<div v-for="(file) in getAttachmentList(operation.comment.attachments,false)">
|
||||
<el-link style="color: #2a99ff" :href="file.url" icon="el-icon-document">{{ file.name }}</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
<el-timeline-item :color="timeline.color" :icon="timeline.icon" size="large">
|
||||
<el-card style="font-size: 16px;font-weight: bold;">
|
||||
{{ timeline.context }}
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "OperationRender",
|
||||
props: {
|
||||
operationList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
},
|
||||
state: {
|
||||
type: String,
|
||||
default: () => {
|
||||
return '1'
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timeline: {},
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
switch (this.state) {
|
||||
case '1':
|
||||
this.timeline = {
|
||||
color: '#f78f5f',
|
||||
icon: 'el-icon-more',
|
||||
context: '审批进行中'
|
||||
}
|
||||
break
|
||||
case '2':
|
||||
this.timeline = {
|
||||
color: '#0bbd87',
|
||||
icon: 'el-icon-check',
|
||||
context: '审批通过'
|
||||
}
|
||||
break
|
||||
case '3':
|
||||
this.timeline = {
|
||||
color: '#f56c6c',
|
||||
icon: 'el-icon-close',
|
||||
context: '审核已驳回'
|
||||
}
|
||||
break
|
||||
case '4':
|
||||
this.timeline = {
|
||||
color: '#0bbd87',
|
||||
icon: 'el-icon-check',
|
||||
context: '审批通过'
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
// let operationListNew = []
|
||||
for (let i = 0;i<this.operationList.length;i++) {
|
||||
let operationNew = this.initOperationFun(this.operationList[i])
|
||||
let userList = []
|
||||
if (operationNew.userInfo){
|
||||
for (let user of operationNew.userInfo) {
|
||||
let userNew = this.initUser(user)
|
||||
userList.push(userNew)
|
||||
}
|
||||
operationNew.userInfo = userList
|
||||
}
|
||||
// operationListNew.push(operationNew)
|
||||
// this.operationList.push(operationNew)
|
||||
this.operationList[i] = operationNew
|
||||
}
|
||||
},
|
||||
//获取到对应附件的地址
|
||||
getAttachmentList(attachments, image) {
|
||||
let result = [];
|
||||
console.log(attachments)
|
||||
if (attachments){
|
||||
for (let attachment of attachments) {
|
||||
if (attachment.isImage === image) {
|
||||
result.push(attachment)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
initUser(user) {
|
||||
let state = user.state
|
||||
//创建节点
|
||||
if (state === 'CREATE') {
|
||||
this.$set(user, "icon", "el-icon-check")
|
||||
this.$set(user, "color", "#0bbd87")
|
||||
}
|
||||
//审批通过
|
||||
if (state === 'AGREE' || state === 'AUTO_PASS') {
|
||||
this.$set(user, "icon", "el-icon-check")
|
||||
this.$set(user, "color", "#0bbd87")
|
||||
}
|
||||
//审批处理中
|
||||
if (state === 'RUNNING') {
|
||||
this.$set(user, "icon", "el-icon-loading")
|
||||
this.$set(user, "color", "#f78f5f")
|
||||
}
|
||||
//拒绝后评论
|
||||
if (state === 'REFUSE') {
|
||||
this.$set(user, "icon", "el-icon-close")
|
||||
this.$set(user, "color", "#f56c6c")
|
||||
}
|
||||
if (state === 'PASS'){
|
||||
this.$set(user, "icon", "el-icon-more")
|
||||
this.$set(user, "color", "#c0c4cc")
|
||||
}
|
||||
return user;
|
||||
},
|
||||
initOperationFun(operation) {
|
||||
let state = operation.state
|
||||
let type = operation.operation
|
||||
//创建节点
|
||||
if (state === 'CREATE') {
|
||||
this.$set(operation, "icon", "el-icon-check")
|
||||
this.$set(operation, "color", "#0bbd87")
|
||||
}
|
||||
//审批通过
|
||||
if (state === 'AGREE' || state === 'AUTO_PASS') {
|
||||
this.$set(operation, "icon", "el-icon-check")
|
||||
this.$set(operation, "color", "#0bbd87")
|
||||
this.$set(operation, "remark", ' (已同意)')
|
||||
}
|
||||
if (state === 'PASS'){
|
||||
this.$set(operation, "icon", "el-icon-more")
|
||||
this.$set(operation, "color", "#c0c4cc")
|
||||
}
|
||||
//审批处理中
|
||||
if (state === 'RUNNING') {
|
||||
this.$set(operation, "icon", "el-icon-loading")
|
||||
this.$set(operation, "color", "#f78f5f")
|
||||
this.$set(operation, "remark",' (处理中)')
|
||||
}
|
||||
//回退
|
||||
if (state === 'ROLLBACK') {
|
||||
this.$set(operation, "icon", "el-icon-refresh")
|
||||
this.$set(operation, "color", "#f78f5f")
|
||||
this.$set(operation, "remark", ' (回退成功)')
|
||||
}
|
||||
//抄送
|
||||
if (type === 'CC') {
|
||||
this.$set(operation, "icon", "el-icon-s-promotion")
|
||||
this.$set(operation, "color", "#3395f8")
|
||||
this.$set(operation, "remark", ' (抄送成功)')
|
||||
}
|
||||
//评论
|
||||
if (state === 'COMMENT') {
|
||||
this.$set(operation, "icon", "el-icon-chat-dot-round")
|
||||
this.$set(operation, "color", "#0bbd87")
|
||||
this.$set(operation, "remark", ' (添加了评论)')
|
||||
}
|
||||
//拒绝后评论
|
||||
if (state === 'REFUSE' && type === 'COMMENT') {
|
||||
this.$set(operation, "icon", "el-icon-chat-dot-round")
|
||||
this.$set(operation, "color", "#f56c6c")
|
||||
this.$set(operation, "remark", ' (填写拒绝理由)')
|
||||
}
|
||||
//拒绝操作
|
||||
if ((state === 'REFUSE' || state === 'AUTO_REFUSE')&& type === 'OPINION') {
|
||||
this.$set(operation, "icon", "el-icon-close")
|
||||
this.$set(operation, "color", "#f56c6c")
|
||||
this.$set(operation, "remark", ' (拒绝)')
|
||||
}
|
||||
return operation;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
/deep/ .el-card__body, .el-main {
|
||||
padding: 10px;
|
||||
}
|
||||
.avatar_name{
|
||||
width: 45px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.el-timeline-item__node{
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 1px;
|
||||
}
|
||||
.username{
|
||||
width: 45px;
|
||||
padding-top: 2px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden
|
||||
}
|
||||
</style>
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
</el-radio-group>
|
||||
<div v-if="nodeProps.assignedType === 'ASSIGN_USER'">
|
||||
<el-button size="mini" icon="el-icon-plus" type="primary" @click="selectUser" round>选择人员</el-button>
|
||||
<org-items v-model="nodeProps.assignedUser"/>
|
||||
<avatar-ellipsis :row="3" :user-info="nodeProps.assignedUser"/>
|
||||
</div>
|
||||
<div v-else-if="nodeProps.assignedType === 'SELF_SELECT'">
|
||||
<el-radio-group size="mini" v-model="nodeProps.selfSelect.multiple">
|
||||
|
|
@ -118,8 +118,8 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="🙅 如果审批被驳回 👇">
|
||||
<el-radio-group v-model="nodeProps.refuse.type">
|
||||
<el-radio label="TO_END">直接结束流程</el-radio>
|
||||
<!-- <el-radio label="TO_BEFORE">驳回到上级审批节点</el-radio>-->
|
||||
<el-radio label="TO_INITIAL">直接结束流程</el-radio>
|
||||
<el-radio label="TO_BEFORE">驳回到上级审批节点</el-radio>
|
||||
<!-- <el-radio label="TO_NODE">驳回到指定节点</el-radio>-->
|
||||
</el-radio-group>
|
||||
<div v-if="nodeProps.refuse.type === 'TO_NODE'">
|
||||
|
|
@ -133,19 +133,22 @@
|
|||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<role-picker :title="pickerTitle" multiple ref="rolePicker" :v-model="select" @ok="selectedRole"/>
|
||||
<role-picker title="请选择人员" multiple ref="rolePicker" :v-model="roleList" @ok="selectedRole"/>
|
||||
<user-picker title="请选择系统角色" multiple ref="userPicker" :v-model="assignedUser" @ok="selectedUser"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RolePicker from "@/components/common/RolePicker";
|
||||
import UserPicker from "@/components/common/UserPicker";
|
||||
import RoleItems from "../RoleItems";
|
||||
import OrgItems from "../OrgItems";
|
||||
|
||||
|
||||
export default {
|
||||
name: "ApprovalNodeConfig",
|
||||
components: {RoleItems, OrgItems, RolePicker},
|
||||
components: {RoleItems, OrgItems, RolePicker, UserPicker},
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
|
|
@ -158,7 +161,6 @@ export default {
|
|||
return {
|
||||
showOrgSelect: false,
|
||||
orgPickerSelected: [],
|
||||
orgPickerType: "user",
|
||||
approvalTypes: [
|
||||
{name: "指定人员", type: "ASSIGN_USER"},
|
||||
{name: "发起人自选", type: "SELF_SELECT"},
|
||||
|
|
@ -174,27 +176,27 @@ export default {
|
|||
nodeProps() {
|
||||
return this.$store.state.selectedNode.props;
|
||||
},
|
||||
select() {
|
||||
return this.config.assignedUser || [];
|
||||
assignedUser: {
|
||||
get() {
|
||||
return this.config.assignedUser || [];
|
||||
},
|
||||
set(val) {
|
||||
this.config.assignedUser = val
|
||||
}
|
||||
},
|
||||
roleList() {
|
||||
return this.config.roleList || [];
|
||||
roleList:{
|
||||
get() {
|
||||
return this.config.roleList || [];
|
||||
},
|
||||
set(val) {
|
||||
this.config.roleList = val
|
||||
}
|
||||
},
|
||||
forms() {
|
||||
return this.$store.state.design.formItems.filter(f => {
|
||||
return f.name === "UserPicker";
|
||||
});
|
||||
},
|
||||
pickerTitle() {
|
||||
switch (this.orgPickerType) {
|
||||
case "user":
|
||||
return "请选择人员";
|
||||
case "role":
|
||||
return "请选择系统角色";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
nodeOptions() {
|
||||
let values = [];
|
||||
const excType = ["ROOT", "EMPTY", "CONDITION", "CONDITIONS", "CONCURRENT", "CONCURRENTS"];
|
||||
|
|
@ -224,34 +226,30 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
selectUser() {
|
||||
this.orgPickerSelected = this.select;
|
||||
this.orgPickerType = "user";
|
||||
this.$refs.orgPicker.show();
|
||||
this.$refs.userPicker.showUserPicker()
|
||||
},
|
||||
selectNoSetUser() {
|
||||
this.orgPickerSelected = this.config.nobody.assignedUser;
|
||||
this.orgPickerType = "user";
|
||||
this.$refs.orgPicker.show();
|
||||
|
||||
},
|
||||
//弹出角色选择器,选择系统角色
|
||||
selectRole() {
|
||||
this.orgPickerType = "role";
|
||||
this.$refs.rolePicker.showRolePicker();
|
||||
},
|
||||
selectedRole(select) {
|
||||
select.forEach(val => {
|
||||
for (let i = 0; i < this.roleList.length; i++) {
|
||||
if (this.roleList[i].roleId === val.roleId) {
|
||||
this.roleList.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.roleList.push(val);
|
||||
});
|
||||
this.roleList = select
|
||||
},
|
||||
selectedUser(select) {
|
||||
let userInfoList = []
|
||||
for (let val of select) {
|
||||
let userInfo = {
|
||||
id: val.id,
|
||||
name: val.name,
|
||||
avatar: val.avatar,
|
||||
}
|
||||
userInfoList.push(userInfo)
|
||||
}
|
||||
this.assignedUser = userInfoList
|
||||
},
|
||||
removeOrgItem(index) {
|
||||
this.select.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-button size="mini" icon="el-icon-plus" type="primary" @click="selectOrg" round>选择抄送人</el-button>
|
||||
<el-button size="mini" icon="el-icon-plus" type="primary" @click="selectUser" round>选择抄送人</el-button>
|
||||
<div class="option">
|
||||
<el-checkbox label="允许发起人添加抄送人" v-model="config.shouldAdd"></el-checkbox>
|
||||
<el-checkbox label="允许发起人添加抄送人" v-model="shouldAdd"></el-checkbox>
|
||||
</div>
|
||||
<org-items v-model="select"/>
|
||||
<org-picker multiple ref="orgPicker" :selected="select" @ok="selected"/>
|
||||
<!-- <org-items v-model="select"/>-->
|
||||
<avatar-ellipsis :row="3" :user-info="assignedUser"/>
|
||||
<user-picker title="请选择系统角色" multiple ref="userPicker" :v-model="assignedUser" @ok="selectedUser"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OrgPicker from "@/components/common/Test";
|
||||
import OrgItems from "../OrgItems";
|
||||
import UserPicker from "@/components/common/UserPicker";
|
||||
|
||||
export default {
|
||||
name: "CcNodeConfig.vue",
|
||||
components: {OrgPicker, OrgItems},
|
||||
components: {UserPicker},
|
||||
props:{
|
||||
config:{
|
||||
type: Object,
|
||||
|
|
@ -25,7 +25,16 @@ export default {
|
|||
}
|
||||
},
|
||||
computed:{
|
||||
select: {
|
||||
shouldAdd:{
|
||||
get(){
|
||||
return this.config.shouldAdd || false
|
||||
},
|
||||
set(val){
|
||||
console.log("asdjhajdhasjdhasdhasjdad")
|
||||
this.config.shouldAdd = val
|
||||
}
|
||||
},
|
||||
assignedUser: {
|
||||
get(){
|
||||
return this.config.assignedUser || []
|
||||
},
|
||||
|
|
@ -38,16 +47,21 @@ export default {
|
|||
return {}
|
||||
},
|
||||
methods: {
|
||||
selectOrg() {
|
||||
this.$refs.orgPicker.show()
|
||||
selectUser() {
|
||||
this.$refs.userPicker.showUserPicker()
|
||||
},
|
||||
selected(select) {
|
||||
console.log(select)
|
||||
this.select = Object.assign([], select)
|
||||
selectedUser(select) {
|
||||
let userInfoList = []
|
||||
for (let val of select) {
|
||||
let userInfo = {
|
||||
id: val.id,
|
||||
name: val.name,
|
||||
avatar: val.avatar,
|
||||
}
|
||||
userInfoList.push(userInfo)
|
||||
}
|
||||
this.assignedUser = userInfoList
|
||||
},
|
||||
removeOrgItem(index){
|
||||
this.select.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo"
|
||||
<node :title="config.name" :show-error="showError" :content="content"
|
||||
:show-avatar="config.props.assignedType === 'ASSIGN_USER'" :user-info="assignedUser"
|
||||
:error-info="errorInfo"
|
||||
:select-user="selectUser"
|
||||
@selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="请设置审批人" :header-bgc="headerBgc" header-icon="el-icon-s-check"/>
|
||||
</template>
|
||||
|
|
@ -9,8 +12,8 @@ import Node from './Node'
|
|||
|
||||
export default {
|
||||
name: "ApprovalNode",
|
||||
props:{
|
||||
config:{
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
|
|
@ -24,120 +27,136 @@ export default {
|
|||
errorInfo: '',
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
viewer(){
|
||||
computed: {
|
||||
selectUser() {
|
||||
return {
|
||||
show: this.config.props.assignedType === 'SELF_SELECT',
|
||||
multiple: this.config.props.selfSelect.multiple
|
||||
};
|
||||
},
|
||||
assignedUser() {
|
||||
if (this.config.props.assignedType === 'SELF_SELECT') {
|
||||
this.config.props.assignedUser = []
|
||||
}
|
||||
return this.config.props.assignedUser;
|
||||
},
|
||||
viewer() {
|
||||
return this.$store.state.diagramMode === 'viewer'
|
||||
},
|
||||
preview(){
|
||||
preview() {
|
||||
return this.$store.state.preview;
|
||||
},
|
||||
headerBgc() {
|
||||
if (this.preview || !this.viewer){
|
||||
if (this.preview || !this.viewer) {
|
||||
return '#ff943e'
|
||||
}else {
|
||||
} else {
|
||||
return this.config.props.headerBgc
|
||||
}
|
||||
},
|
||||
content(){
|
||||
content() {
|
||||
const config = this.config.props
|
||||
switch (config.assignedType){
|
||||
switch (config.assignedType) {
|
||||
case "ASSIGN_USER":
|
||||
if (config.assignedUser.length > 0){
|
||||
if (config.assignedUser.length > 0) {
|
||||
let texts = []
|
||||
config.assignedUser.forEach(org => texts.push(org.name))
|
||||
return String(texts).replaceAll(',', '、')
|
||||
}else {
|
||||
} else {
|
||||
return '请指定审批人'
|
||||
}
|
||||
case "SELF":
|
||||
return '发起人自己'
|
||||
case "SELF_SELECT":
|
||||
return config.selfSelect.multiple ? '发起人自选多人':'发起人自选一人'
|
||||
return config.selfSelect.multiple ? '发起人自选多人' : '发起人自选一人'
|
||||
case "LEADER_TOP":
|
||||
return '多级主管依次审批'
|
||||
case "LEADER":
|
||||
return config.leader.level > 1 ? '发起人的第 ' + config.leader.level + ' 级主管' : '发起人的直接主管'
|
||||
case "FORM_USER":
|
||||
if (!config.formUser || config.formUser === ''){
|
||||
if (!config.formUser || config.formUser === '') {
|
||||
return '表单内联系人(未选择)'
|
||||
}else {
|
||||
} else {
|
||||
let text = this.getFormItemById(config.formUser)
|
||||
if (text && text.title){
|
||||
if (text && text.title) {
|
||||
return `表单(${text.title})内的人员`
|
||||
}else {
|
||||
} else {
|
||||
return '该表单已被移除😥'
|
||||
}
|
||||
}
|
||||
case "ROLE":
|
||||
if (config.roleList.length > 0){
|
||||
return config.roleList.map(role=>{
|
||||
if (config.roleList.length > 0) {
|
||||
return config.roleList.map(role => {
|
||||
return role.roleName;
|
||||
}).join("、")
|
||||
}else {
|
||||
} else {
|
||||
return '指定角色(未设置)'
|
||||
}
|
||||
default: return '未知设置项😥'
|
||||
default:
|
||||
return '未知设置项😥'
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
getFormItemById(id){
|
||||
getFormItemById(id) {
|
||||
return this.$store.state.design.formItems.find(item => item.id === id)
|
||||
},
|
||||
//校验数据配置的合法性
|
||||
validate(err){
|
||||
validate(err) {
|
||||
try {
|
||||
this.showError = !this[`validate_${this.config.props.assignedType}`](err)
|
||||
|
||||
if (this.config.props.nobody.handler === 'TO_USER' && this.config.props.nobody.assignedUser.length === 0) {
|
||||
this.errorInfo = '审批人为空时, 转交给指定人员:【请指定一个具体的人】'
|
||||
err.push('审批人为空时, 转交给指定人员:【请指定一个具体的人】')
|
||||
this.showError = true
|
||||
} else if (this.viewer) {
|
||||
this.showError = !this.validate_ASSIGN_USER(err)
|
||||
console.log(this.showError)
|
||||
}
|
||||
|
||||
return this.showError
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return true;
|
||||
}
|
||||
},
|
||||
validate_ASSIGN_USER(err){
|
||||
if(this.config.props.assignedUser.length > 0){
|
||||
validate_ASSIGN_USER(err) {
|
||||
if (this.config.props.assignedUser.length > 0) {
|
||||
return true;
|
||||
}else {
|
||||
} else {
|
||||
this.errorInfo = '请指定审批人员'
|
||||
err.push(`${this.config.name} 未指定审批人员`)
|
||||
return false
|
||||
}
|
||||
},
|
||||
validate_SELF_SELECT(err){
|
||||
validate_SELF_SELECT(err) {
|
||||
return true;
|
||||
},
|
||||
validate_LEADER_TOP(err){
|
||||
validate_LEADER_TOP(err) {
|
||||
return true;
|
||||
},
|
||||
validate_LEADER(err){
|
||||
validate_LEADER(err) {
|
||||
return true;
|
||||
},
|
||||
validate_ROLE(err){
|
||||
if (this.config.props.roleList.length <= 0){
|
||||
validate_ROLE(err) {
|
||||
if (this.config.props.roleList.length <= 0) {
|
||||
this.errorInfo = '请指定负责审批的系统角色'
|
||||
err.push(`${this.config.name} 未指定审批角色`)
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
},
|
||||
validate_SELF(err){
|
||||
validate_SELF(err) {
|
||||
return true;
|
||||
},
|
||||
validate_FORM_USER(err){
|
||||
if (this.config.props.formUser === ''){
|
||||
validate_FORM_USER(err) {
|
||||
if (this.config.props.formUser === '') {
|
||||
this.errorInfo = '请指定表单中的人员组件'
|
||||
err.push(`${this.config.name} 审批人为表单中人员,但未指定`)
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
},
|
||||
validate_REFUSE(err){
|
||||
validate_REFUSE(err) {
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<node :title="config.name" :show-error="showError" :content="content" :error-info="errorInfo"
|
||||
<node :title="config.name" :show-error="showError" :select-user="selectUser" :content="content"
|
||||
:error-info="errorInfo" :show-avatar="true" :user-info="config.props.assignedUser"
|
||||
@selected="$emit('selected')" @delNode="$emit('delNode')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="请设置抄送人" :header-bgc="headerBgc" header-icon="el-icon-s-promotion"/>
|
||||
</template>
|
||||
|
|
@ -9,8 +10,8 @@ import Node from './Node'
|
|||
|
||||
export default {
|
||||
name: "CcNode",
|
||||
props:{
|
||||
config:{
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
|
|
@ -24,24 +25,30 @@ export default {
|
|||
errorInfo: '',
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
viewer(){
|
||||
computed: {
|
||||
selectUser() {
|
||||
return {
|
||||
show: this.config.props.assignedType !== 'ASSIGN_USER',
|
||||
multiple: true
|
||||
};
|
||||
},
|
||||
viewer() {
|
||||
return this.$store.state.diagramMode === 'viewer'
|
||||
},
|
||||
preview(){
|
||||
preview() {
|
||||
return this.$store.state.preview;
|
||||
},
|
||||
headerBgc() {
|
||||
if (this.preview || !this.viewer){
|
||||
if (this.preview || !this.viewer) {
|
||||
return '#3296fa'
|
||||
}else {
|
||||
} else {
|
||||
return this.config.props.headerBgc
|
||||
}
|
||||
},
|
||||
content() {
|
||||
if (this.config.props.shouldAdd){
|
||||
if (this.config.props.shouldAdd) {
|
||||
return '由发起人指定'
|
||||
}else if (this.config.props.assignedUser.length > 0) {
|
||||
} else if (this.config.props.assignedUser.length > 0) {
|
||||
let texts = []
|
||||
this.config.props.assignedUser.forEach(org => texts.push(org.name))
|
||||
return String(texts).replaceAll(',', '、')
|
||||
|
|
@ -52,15 +59,15 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
//校验数据配置的合法性
|
||||
validate(err){
|
||||
validate(err) {
|
||||
this.showError = false
|
||||
if(this.config.props.shouldAdd){
|
||||
if (this.config.props.shouldAdd) {
|
||||
this.showError = false
|
||||
}else if(this.config.props.assignedUser.length === 0){
|
||||
} else if (this.config.props.assignedUser.length === 0) {
|
||||
this.showError = true
|
||||
this.errorInfo = '请选择需要抄送的人员'
|
||||
}
|
||||
if (this.showError){
|
||||
if (this.showError) {
|
||||
err.push(`抄送节点 ${this.config.name} 未设置抄送人`)
|
||||
}
|
||||
return !this.showError
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="node">
|
||||
<div class="node">
|
||||
<!-- 并行分支选择后右侧出现操作面板,占时不需要 <div class="node-body" @click="$emit('selected')">-->
|
||||
<div class="node-body" @click="$emit('selected')">
|
||||
<div v-if="designStart()" class="node-body" @click="$emit('selected')">
|
||||
<div class="node-body-left" @click.stop="$emit('leftMove')" v-if="level > 1 && designStart() ">
|
||||
<i class="el-icon-arrow-left"></i>
|
||||
</div>
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="node-footer">
|
||||
<div class="btn">
|
||||
<div class="btn" :style="(designStart() ? '' : 'height:0px')">
|
||||
<insert-button v-if="designStart()" @insertNode="type => $emit('insertNode', type)"></insert-button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,29 @@
|
|||
<template>
|
||||
<div :class="{'node': true, 'root': isRoot || !show, 'node-error-state': showError}">
|
||||
<div v-if="show" @click="$emit('selected')" :class="{'node-body': true, 'error': showError}" >
|
||||
<div v-if="show" @click="$emit('selected')" :class="{'node-body': true, 'error': showError}">
|
||||
<div>
|
||||
<div class="node-body-header" :style="{'background-color': headerBgc}">
|
||||
<i :class="headerIcon" style="margin-right: 5px" v-if="(headerIcon || '') !== ''"></i>
|
||||
<ellipsis class="name" hover-tip :content="title"/>
|
||||
<i class="el-icon-close" v-if="!isRoot && $store.state.diagramMode !== 'viewer'" style="float:right;" @click="$emit('delNode')"></i>
|
||||
<i class="el-icon-close" v-if="!isRoot && $store.state.diagramMode !== 'viewer'" style="float:right;"
|
||||
@click="$emit('delNode')"></i>
|
||||
</div>
|
||||
<div class="node-body-content">
|
||||
<i :class="leftIcon" v-if="leftIcon"></i>
|
||||
<span class="placeholder" v-if="(content || '').trim() === ''">{{placeholder}}</span>
|
||||
<ellipsis :row="3" :content="content" v-else/>
|
||||
<i class="el-icon-arrow-right" v-if="$store.state.diagramMode !== 'viewer'" ></i>
|
||||
<template v-if="viewer && selectUser.show">
|
||||
<div class="avatar_button">
|
||||
<avatar-ellipsis :row="3" v-if="userInfo.length > 0" :user-info="userInfo"/>
|
||||
<el-button type="primary" icon="el-icon-plus" circle @click="$refs.userPicker.showUserPicker()"/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="showAvatar">
|
||||
<span class="placeholder" v-if="userInfo.length === 0">{{ placeholder }}</span>
|
||||
<avatar-ellipsis :row="3" :user-info="userInfo" v-else/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="placeholder" v-if="(content || '').trim() === ''">{{ placeholder }}</span>
|
||||
<ellipsis :row="3" :content="content" v-else/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="node-error" v-if="showError">
|
||||
<el-tooltip effect="dark" :content="errorInfo" placement="top-start">
|
||||
|
|
@ -21,21 +33,28 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="node-footer">
|
||||
<div v-if="merge" class="branch-merge"><img data-v-1e7b1da5="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABXlJREFUeF7tmm2IVGUUx3/nLkQUqxmkpAVhSPUllZX8EEGhvVgZQWCU6wcpsqi2mXtnoaBwoqLCufeO9oJYUJQiFZWlZPQCfYiIXkylstTyS1oWWeYWCe6cuLsz7t3r3Ll3du6907oz35bnPM9z/r895zznmWeECf6RCa6fDoBOBExwAp0UmOAB0CmCnRTopECbCZi2nivK1CMD7FpXlH+ydqctKZBz9QyjwkqFG4HzfKK/0gpvl/ulmBWIzAHkVmlRDFY2EihwwLFkRhYQxgzAtHW2CpcBc4CpOsg26eK7yVPYVFwu/9ZzPufq2VLhQBxhAk85lvSF2Y5l/3prjQlAvqR3IjwJTKqz6DeGssQuyLfBsbyjz6PcFgeAZyOwzLFk/QnrjHH/RACYtj6ncHuUCDWYXs7Lz367XEn3inB+1NzauMLGsiW3+u1b2b9lAH22LuiCD2IJED5yTbmiZpt3dAbKT7Hmjhjtdi25oPZnK/uH7dtUCpi2vqVwQ1wRWuHhWkW3StpTEb6IO3fIThhwTemuzWll/0QA5G39FTgrtghhs2vKELA7inra6d38HXvusOEnriWXHo+iFvZvGUDfap3VdYzdzQgIHmd5W7cBc2Ovoax1C3KXZ5/E/i3VgCQciNMD+J1Ug55yXjxo7QfgOdFKCvjyeL/C9MgoEBa5przrt0ti/+C+mRVB/8amrWsU7m2Ql/c5lqwJjre9CDZ1DMFnriXzw0SatvZW4FqBW6o2vwGvCGxyLPmw3rym9g8cwy0XQV8Ix2qEgH0C1ziWNCyceVu1uvZrriVLGqVGsainHO7mRyDynlCvEWupCI7Kxcat6BFg+OwW9ohyfSMIcQF44v/sZovAlRH1I7QVTwyAt1Cjy8hfh9hYvepGQogDoI74HYbSXzHwusTYl7FEAURVcdPWN+NAiAJQTzzCda4p+6N8iDPe1CkQZ8FAtY+E0AhA2uKHszTlT1QkhAHIQnwmAKr1IjQS6gHISnxmABpBCALIUnymAMIgKHxf6wMmH6E3cNTtSLLgZXoKNOgAR6UDyqyq7esKk3znfOriM48AXzc5AmGE1EFgWvXPTMS3DcAJ6TA6XDIT31YAoRCEc5JqcuKc8Kn3AVFO+E4BryvJVHzbI8BzwAdgi2vJ4ihgSY//nyIg8jqctPi2RYBp61wV5qsyR2BFVdhBhBe0wtdisNU15VAagoNrZh4BOVsfFcVCODVUoLBn6E2hIBvShpApgLyt3nvhRXFFCWxwLOmNaz8Wu8wA5G31ntQWNOukwD2OJc80Oy+ufSYAciVdJsJLcZ0K2nV1MbuUk51jnd9oXuoACmW9eHCQj49/T+j3RtiJslPgFxXmoVxe11nhPdeUq8clANPWPoXVQef9D6e1saEHVINHUBYF7Q1lnl2QL5OGkHoE5G19GRhVyBQ+L1tyST0xoa/Iygq3IOvGI4BdwIWjHBeecE15IExM3tYfgJmBOetcU2o9Q2IcsoiAw8Gf0qhyU7kgb4QCcPRTlNGvSspmtzD81J7kJ30AJX0fYeHo2seLjiXLG0TA78CZ/nGFB8uWPJakeG+t9AE4+jjK/XGLWtgTusBix5It4w5ArqRLRTjhl14IW40KD/kre66ki0R4p57IrgozS/2yb9wByDvqhbKX07Xv/oIavMfOP6pFb0pdgcqrbkFuTlp8JingbRIaBfEUHUOYltbtMPUaUNNo2rpeYWk8zSNWqvSmeSvMDIAnybT1boWnY0I4aigL7YJ4bXRqn0wBeCqG7gYVVqFcFapKWXt0gP5nizKQmvLqwpkDqAkaanmhB4MelOkI27XCDjHY7pqyN23htfXbBiArgVH7dABEETrZxzsRcLL/h6P0/Qc1qphfvB2K3wAAAABJRU5ErkJggg==" alt=""></div>
|
||||
<div v-if="merge" class="branch-merge">
|
||||
<img data-v-1e7b1da5=""
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABXlJREFUeF7tmm2IVGUUx3/nLkQUqxmkpAVhSPUllZX8EEGhvVgZQWCU6wcpsqi2mXtnoaBwoqLCufeO9oJYUJQiFZWlZPQCfYiIXkylstTyS1oWWeYWCe6cuLsz7t3r3Ll3du6907oz35bnPM9z/r895zznmWeECf6RCa6fDoBOBExwAp0UmOAB0CmCnRTopECbCZi2nivK1CMD7FpXlH+ydqctKZBz9QyjwkqFG4HzfKK/0gpvl/ulmBWIzAHkVmlRDFY2EihwwLFkRhYQxgzAtHW2CpcBc4CpOsg26eK7yVPYVFwu/9ZzPufq2VLhQBxhAk85lvSF2Y5l/3prjQlAvqR3IjwJTKqz6DeGssQuyLfBsbyjz6PcFgeAZyOwzLFk/QnrjHH/RACYtj6ncHuUCDWYXs7Lz367XEn3inB+1NzauMLGsiW3+u1b2b9lAH22LuiCD2IJED5yTbmiZpt3dAbKT7Hmjhjtdi25oPZnK/uH7dtUCpi2vqVwQ1wRWuHhWkW3StpTEb6IO3fIThhwTemuzWll/0QA5G39FTgrtghhs2vKELA7inra6d38HXvusOEnriWXHo+iFvZvGUDfap3VdYzdzQgIHmd5W7cBc2Ovoax1C3KXZ5/E/i3VgCQciNMD+J1Ug55yXjxo7QfgOdFKCvjyeL/C9MgoEBa5przrt0ti/+C+mRVB/8amrWsU7m2Ql/c5lqwJjre9CDZ1DMFnriXzw0SatvZW4FqBW6o2vwGvCGxyLPmw3rym9g8cwy0XQV8Ix2qEgH0C1ziWNCyceVu1uvZrriVLGqVGsainHO7mRyDynlCvEWupCI7Kxcat6BFg+OwW9ohyfSMIcQF44v/sZovAlRH1I7QVTwyAt1Cjy8hfh9hYvepGQogDoI74HYbSXzHwusTYl7FEAURVcdPWN+NAiAJQTzzCda4p+6N8iDPe1CkQZ8FAtY+E0AhA2uKHszTlT1QkhAHIQnwmAKr1IjQS6gHISnxmABpBCALIUnymAMIgKHxf6wMmH6E3cNTtSLLgZXoKNOgAR6UDyqyq7esKk3znfOriM48AXzc5AmGE1EFgWvXPTMS3DcAJ6TA6XDIT31YAoRCEc5JqcuKc8Kn3AVFO+E4BryvJVHzbI8BzwAdgi2vJ4ihgSY//nyIg8jqctPi2RYBp61wV5qsyR2BFVdhBhBe0wtdisNU15VAagoNrZh4BOVsfFcVCODVUoLBn6E2hIBvShpApgLyt3nvhRXFFCWxwLOmNaz8Wu8wA5G31ntQWNOukwD2OJc80Oy+ufSYAciVdJsJLcZ0K2nV1MbuUk51jnd9oXuoACmW9eHCQj49/T+j3RtiJslPgFxXmoVxe11nhPdeUq8clANPWPoXVQef9D6e1saEHVINHUBYF7Q1lnl2QL5OGkHoE5G19GRhVyBQ+L1tyST0xoa/Iygq3IOvGI4BdwIWjHBeecE15IExM3tYfgJmBOetcU2o9Q2IcsoiAw8Gf0qhyU7kgb4QCcPRTlNGvSspmtzD81J7kJ30AJX0fYeHo2seLjiXLG0TA78CZ/nGFB8uWPJakeG+t9AE4+jjK/XGLWtgTusBix5It4w5ArqRLRTjhl14IW40KD/kre66ki0R4p57IrgozS/2yb9wByDvqhbKX07Xv/oIavMfOP6pFb0pdgcqrbkFuTlp8JingbRIaBfEUHUOYltbtMPUaUNNo2rpeYWk8zSNWqvSmeSvMDIAnybT1boWnY0I4aigL7YJ4bXRqn0wBeCqG7gYVVqFcFapKWXt0gP5nizKQmvLqwpkDqAkaanmhB4MelOkI27XCDjHY7pqyN23htfXbBiArgVH7dABEETrZxzsRcLL/h6P0/Qc1qphfvB2K3wAAAABJRU5ErkJggg=="
|
||||
alt=""></div>
|
||||
<div class="btn">
|
||||
<insert-button v-show="$store.state.diagramMode !== 'viewer'" @insertNode="type => $emit('insertNode', type)"></insert-button>
|
||||
<insert-button v-show="$store.state.diagramMode !== 'viewer'"
|
||||
@insertNode="type => $emit('insertNode', type)"></insert-button>
|
||||
</div>
|
||||
</div>
|
||||
<user-picker v-if="selectUser.show" title="请选择系统用户" :multiple="selectUser.multiple" ref="userPicker"
|
||||
@ok="selectedUser"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserPicker from "@/components/common/UserPicker";
|
||||
import InsertButton from '@/views/common/InsertButton.vue'
|
||||
|
||||
export default {
|
||||
name: "Node",
|
||||
components: {InsertButton},
|
||||
props:{
|
||||
components: {InsertButton, UserPicker},
|
||||
props: {
|
||||
//是否为根节点
|
||||
isRoot: {
|
||||
type: Boolean,
|
||||
|
|
@ -56,11 +75,25 @@ export default {
|
|||
type: String,
|
||||
default: ""
|
||||
},
|
||||
title:{
|
||||
//节点内容区域文字
|
||||
showAvatar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
selectUser: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
show: false,
|
||||
multiple: false,
|
||||
}
|
||||
}
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: "标题"
|
||||
},
|
||||
placeholder:{
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "请设置"
|
||||
},
|
||||
|
|
@ -70,49 +103,73 @@ export default {
|
|||
default: undefined
|
||||
},
|
||||
//头部图标
|
||||
headerIcon:{
|
||||
headerIcon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
//头部背景色
|
||||
headerBgc:{
|
||||
headerBgc: {
|
||||
type: String,
|
||||
default: '#576a95'
|
||||
},
|
||||
//是否显示错误状态
|
||||
showError:{
|
||||
showError: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
errorInfo:{
|
||||
errorInfo: {
|
||||
type: String,
|
||||
default: '无信息'
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
return {
|
||||
userInfo:[]
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
computed: {
|
||||
viewer() {
|
||||
return this.$store.state.diagramMode === 'viewer'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectedUser(select) {
|
||||
let userInfoList = []
|
||||
for (let val of select) {
|
||||
let userInfo = {
|
||||
id: val.id,
|
||||
name: val.name,
|
||||
avatar: val.avatar,
|
||||
}
|
||||
userInfoList.push(userInfo)
|
||||
}
|
||||
this.userInfo = userInfoList
|
||||
this.$store.state.selectUserMap.set(this.$store.state.selectedNode.id, userInfoList)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.root{
|
||||
&:before{
|
||||
.root {
|
||||
&:before {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
.node-error-state{
|
||||
.node-body{
|
||||
|
||||
.node-error-state {
|
||||
.node-body {
|
||||
box-shadow: 0px 0px 5px 0px #F56C6C !important;
|
||||
}
|
||||
}
|
||||
.node{
|
||||
|
||||
.node {
|
||||
padding: 0 50px;
|
||||
width: 220px;
|
||||
position: relative;
|
||||
&:before{
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
|
|
@ -125,15 +182,18 @@ export default {
|
|||
border-color: #CACACA transparent transparent;
|
||||
background: #F5F5F7;
|
||||
}
|
||||
.node-body{
|
||||
|
||||
.node-body {
|
||||
cursor: pointer;
|
||||
max-height: 120px;
|
||||
min-height: 63px;
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
background-color: white;
|
||||
box-shadow: 0px 0px 5px 0px #d8d8d8;
|
||||
&:hover{
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 3px 0px @theme-primary;
|
||||
|
||||
.node-body-header {
|
||||
.el-icon-close {
|
||||
display: inline;
|
||||
|
|
@ -141,36 +201,56 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
.node-body-header{
|
||||
|
||||
.node-body-header {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
padding: 5px 15px;
|
||||
color: white;
|
||||
font-size: xx-small;
|
||||
.el-icon-close{
|
||||
|
||||
.el-icon-close {
|
||||
display: none;
|
||||
}
|
||||
.name{
|
||||
|
||||
.name {
|
||||
height: 14px;
|
||||
width: 150px;
|
||||
display: inline-block
|
||||
}
|
||||
}
|
||||
.node-body-content{
|
||||
|
||||
.node-body-content {
|
||||
padding: 18px;
|
||||
color: #656363;
|
||||
font-size: 14px;
|
||||
i{
|
||||
|
||||
.avatar_button {
|
||||
//float: left;
|
||||
display: flex;
|
||||
//flex: 1;
|
||||
flex-wrap: wrap;
|
||||
button {
|
||||
margin-top: 3px;
|
||||
height: 40px;
|
||||
//flex-shrink: 0;
|
||||
//flex-grow: 0;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 55%;
|
||||
right: 5px;
|
||||
font-size: medium;
|
||||
}
|
||||
.placeholder{
|
||||
|
||||
.placeholder {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
}
|
||||
.node-error{
|
||||
|
||||
.node-error {
|
||||
position: absolute;
|
||||
right: -40px;
|
||||
top: 20px;
|
||||
|
|
@ -179,9 +259,10 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.node-footer{
|
||||
.node-footer {
|
||||
position: relative;
|
||||
.branch-merge{
|
||||
|
||||
.branch-merge {
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
width: 38px;
|
||||
|
|
@ -194,17 +275,20 @@ export default {
|
|||
flex-direction: column;
|
||||
box-shadow: 0 0 5px 0 #d8d8d8;
|
||||
}
|
||||
.btn{
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 20px 0 32px;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
}
|
||||
/deep/ .el-button{
|
||||
|
||||
/deep/ .el-button {
|
||||
height: 32px;
|
||||
}
|
||||
&::before{
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<node title="发起人" :is-root="true" :content="content"
|
||||
<node title="发起人" :is-root="true" :content="content" show-avatar :user-info="config.props.assignedUser"
|
||||
@selected="$emit('selected')" @insertNode="type => $emit('insertNode', type)"
|
||||
placeholder="所有人" :header-bgc="config.props.headerBgc" header-icon="el-icon-user-solid"/>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,352 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="名称" prop="uqName">
|
||||
<el-input
|
||||
v-model="queryParams.uqName"
|
||||
placeholder="请输入名称"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="uqDescribe">
|
||||
<el-input
|
||||
v-model="queryParams.uqDescribe"
|
||||
placeholder="请输入描述"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="daterangeCreateTime"
|
||||
size="small"
|
||||
style="width: 240px"
|
||||
value-format="yyyy-MM-dd"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
>新增
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="el-icon-edit"
|
||||
size="mini"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-download"
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
>导出
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="queryList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center"/>
|
||||
<el-table-column type="index" width="50"></el-table-column>
|
||||
<el-table-column label="名称" align="center" prop="uqName"/>
|
||||
<el-table-column label="描述" align="center" prop="uqDescribe"/>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.createTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新时间" align="center" prop="updateTime">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.updateTime }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.isRelease===2">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
icon="el-icon-edit-outline"
|
||||
@click="handleEditTable(scope.row)"
|
||||
>设计</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
>删除</el-button>
|
||||
</span>
|
||||
<span v-if="scope.row.isRelease===1">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handRelease(scope.row.id)"
|
||||
>撤销</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改万能查询对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="名称" prop="uqName">
|
||||
<el-input v-model="form.uqName" placeholder="请输入名称"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="uqDescribe">
|
||||
<el-input v-model="form.uqDescribe" placeholder="请输入描述"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {listQuery, getQuery, delQuery, addQuery, updateQuery, exportQuery, Release} from "@/api/query";
|
||||
import {Message} from "element-ui";
|
||||
|
||||
export default {
|
||||
name: "Query",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 万能查询表格数据
|
||||
queryList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 创建时间时间范围
|
||||
daterangeCreateTime: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
uqName: null,
|
||||
uqDescribe: null,
|
||||
type: 1
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
uqName: [
|
||||
{required: true, message: "名称不能为空}", trigger: "blur"},
|
||||
],
|
||||
uqDescribe: [
|
||||
{required: true, message: "描述不能为空}", trigger: "blur"},
|
||||
],
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询万能查询列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listQuery(this.queryParams).then(response => {
|
||||
let data = response.data
|
||||
this.queryList = data.rows;
|
||||
this.total = data.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
id: null,
|
||||
uqName: null,
|
||||
uqDescribe: null,
|
||||
};
|
||||
// this.$refs['form'].resetFields()
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
handleEditTable(row) {
|
||||
this.$router.push("/query/edit/" + row.id);
|
||||
},
|
||||
/** 发布与撤销 */
|
||||
handRelease(id) {
|
||||
let that = this
|
||||
this.$confirm('是否确认撤销该查询?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(function () {
|
||||
let data = {
|
||||
id: id,
|
||||
isRelease: 2
|
||||
}
|
||||
Release(data).then(res => {
|
||||
Message({
|
||||
message: res.msg,
|
||||
type: 'success'
|
||||
})
|
||||
that.getList()
|
||||
})
|
||||
})
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.daterangeCreateTime = [];
|
||||
this.$refs.queryForm.resetFields()
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.id)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加自定义查询";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const id = row.id || this.ids
|
||||
getQuery(id).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改自定义查询";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
this.form.type = 1
|
||||
if (valid) {
|
||||
if (this.form.id != null) {
|
||||
updateQuery(this.form).then(response => {
|
||||
Message({
|
||||
message: "修改成功",
|
||||
type: 'success'
|
||||
})
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addQuery(this.form).then(response => {
|
||||
Message({
|
||||
message: "新增成功",
|
||||
type: 'success'
|
||||
})
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const ids = row.id || this.ids;
|
||||
this.$confirm('是否确认删除自定义查询编号为"' + ids + '"的数据项?', "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function () {
|
||||
return delQuery(ids);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.msgSuccess("删除成功");
|
||||
})
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
const queryParams = this.queryParams;
|
||||
this.$confirm('是否确认导出所有自定义查询数据项?', "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function () {
|
||||
return exportQuery(queryParams);
|
||||
}).then(response => {
|
||||
this.download(response.msg);
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-table :data="tableData"
|
||||
@row-click="clickRow"
|
||||
style="width: 100%">
|
||||
<el-table-column
|
||||
prop="deploymentName"
|
||||
label="审批类型"
|
||||
width="180"/>
|
||||
<el-table-column
|
||||
prop="approveName"
|
||||
label="发起人"
|
||||
width="180"/>
|
||||
<el-table-column
|
||||
prop="submitTime"
|
||||
label="提交时间"/>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
label="结束时间"/>
|
||||
<el-table-column
|
||||
prop="taskName"
|
||||
label="当前节点"/>
|
||||
<el-table-column
|
||||
label="处理耗时">
|
||||
<template slot-scope="scope">
|
||||
{{ getTimeConsuming(scope.row) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="state"
|
||||
label="状态">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.state === '1'">进行中</el-tag>
|
||||
<el-tag v-if="scope.row.state === '4'" type="success">审批通过</el-tag>
|
||||
<el-tag v-if="scope.row.state === '3'" type="danger">审批驳回</el-tag>
|
||||
<el-tag v-if="scope.row.state === '2'" type="info">已撤销</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="min" type="text" icon="el-icon-thumb">再次提交</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-drawer
|
||||
title="审批详情"
|
||||
size="500px"
|
||||
:visible.sync="approveOpen"
|
||||
direction="rtl">
|
||||
<div v-loading="loading">
|
||||
<div class="top">
|
||||
<div class="top_left">
|
||||
<el-avatar size="large" :src="processInstanceData.userInfo.avatar"></el-avatar>
|
||||
<span style="text-align: center;color: #19191a;font-size: 14px;">{{ processInstanceData.userInfo.name }}</span>
|
||||
</div>
|
||||
<div class="top_right">
|
||||
<div style="margin-bottom: 12px">
|
||||
<span style="font-size: 15px;">{{ selectProcessInstance.deploymentName }}</span>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '1'" size="mini" >进行中</el-tag>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '4'" size="mini" type="success">审批通过</el-tag>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '3'" size="mini" type="danger">审批驳回</el-tag>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '2'" size="mini" type="info">已撤销</el-tag>
|
||||
<el-tooltip class="item" effect="dark" content="查看详细流程" placement="top-start">
|
||||
<el-icon class="el-icon-view" style="float: right;font-size: 20px;cursor: pointer" @click.native="processDiagramViewer = true"></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div>
|
||||
<span style="color: rgb(108, 108, 108);">编号: {{ selectProcessInstance.processInstanceId }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
<form-render-view v-if="!loading" ref="taskViewForm" :form-items="processInstanceData.formItems"
|
||||
v-model="processInstanceData.formData"/>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
<operation-render v-if="!loading"
|
||||
:operation-list="processInstanceData.operationList"
|
||||
:state="selectProcessInstance.state"/>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog title="流程详情" :visible.sync="processDiagramViewer" :close-on-click-modal="true">
|
||||
<process-diagram-viewer v-if="processDiagramViewer"/>
|
||||
<div style="height: 70px;"></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormRenderView from '@/views/common/form/FormRenderView'
|
||||
import ProcessDiagramViewer from "../admin/layout/ProcessDiagramViewer";
|
||||
import {getAboutInstanceList, getInitiatedInstanceInfo} from "@/api/processInstance";
|
||||
import {timeLength} from '@/utils/date'
|
||||
import OperationRender from "../common/operation/OperationRender";
|
||||
export default {
|
||||
name: "AboutInstance",
|
||||
components: {OperationRender, FormRenderView, ProcessDiagramViewer},
|
||||
data() {
|
||||
return {
|
||||
approveOpen: false,
|
||||
processDiagramViewer: false,
|
||||
selectProcessInstance: {},
|
||||
tableData: [],
|
||||
loading: false,
|
||||
processInstanceData: {
|
||||
userInfo: {},
|
||||
formData: {},
|
||||
formItems: [],
|
||||
processList: [],
|
||||
operationList: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
clickRow(row) {
|
||||
this.approveOpen = true;
|
||||
this.loadProcessInstance(row.processInstanceId)
|
||||
this.selectProcessInstance = row
|
||||
},
|
||||
|
||||
loadProcessInstance(processInstanceId) {
|
||||
let that = this;
|
||||
this.init();
|
||||
getInitiatedInstanceInfo(processInstanceId).then(res => {
|
||||
let data = res.data
|
||||
that.processInstanceData = data
|
||||
that.$store.state.design = data;
|
||||
that.$store.state.runningList = data.runningList;
|
||||
that.$store.state.endList = data.endList;
|
||||
that.$store.state.noTakeList = data.noTakeList;
|
||||
that.$store.state.refuseList = data.refuseList;
|
||||
that.$store.state.passList = data.passList;
|
||||
this.loading = false;
|
||||
console.log(data, "获取到的结果数据")
|
||||
})
|
||||
},
|
||||
|
||||
init() {
|
||||
this.processInstanceData = {
|
||||
userInfo: {},
|
||||
formData: {},
|
||||
formItems: [],
|
||||
processList: [],
|
||||
};
|
||||
|
||||
this.loading = true;
|
||||
this.$store.state.design = this.taskData;
|
||||
this.$store.state.runningList = [];
|
||||
this.$store.state.endList = [];
|
||||
this.$store.state.noTakeList = [];
|
||||
this.$store.state.refuseList = [];
|
||||
this.$store.state.passList = [];
|
||||
this.$store.state.diagramMode = "viewer";
|
||||
this.$store.state.preview = false;
|
||||
},
|
||||
|
||||
getList() {
|
||||
getAboutInstanceList().then(res => {
|
||||
let data = res.data
|
||||
this.tableData = data.rows
|
||||
})
|
||||
},
|
||||
getTimeConsuming(instance) {
|
||||
if (instance.state != 1) {
|
||||
//dateFormat(开始时间,结束时间)
|
||||
return timeLength(instance.submitTime,instance.endTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.top {
|
||||
padding: 0 10px 10px 10px;
|
||||
display: flex;
|
||||
|
||||
.top_left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top_right {
|
||||
width: 85%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
//justify-content: space-between;
|
||||
font-size: 13px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.state_tag{
|
||||
font-size: 12px;
|
||||
//margin-right: 15px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -29,10 +29,10 @@
|
|||
prop="state"
|
||||
label="状态">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.state == 1">待处理</el-tag>
|
||||
<el-tag v-if="scope.row.state == 4" type="success">已同意</el-tag>
|
||||
<el-tag v-if="scope.row.state == 3" type="danger">已拒绝</el-tag>
|
||||
<el-tag v-if="scope.row.state == 2" type="warning">已退回</el-tag>
|
||||
<el-tag v-if="scope.row.state === '1'">待处理</el-tag>
|
||||
<el-tag v-if="scope.row.state === '4'" type="success">已同意</el-tag>
|
||||
<el-tag v-if="scope.row.state === '3'" type="danger">已拒绝</el-tag>
|
||||
<el-tag v-if="scope.row.state === '2'" type="warning">已退回</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -44,13 +44,18 @@
|
|||
<div v-loading="loading">
|
||||
<div class="top">
|
||||
<div class="top_left">
|
||||
<el-avatar size="large" :src="avatar"></el-avatar>
|
||||
<span style="text-align: center;color: #19191a;font-size: 14px;">{{ selectTask.initiatorName }}</span>
|
||||
<el-avatar size="large" :src="taskData.userInfo.avatar"></el-avatar>
|
||||
<span style="text-align: center;color: #19191a;font-size: 14px;">{{ taskData.userInfo.name }}</span>
|
||||
</div>
|
||||
<div class="top_right">
|
||||
<div style="margin-bottom: 12px">
|
||||
<span style="font-size: 15px;margin-right: 15px">{{ selectTask.processName }}</span>
|
||||
<el-tag style="font-size: 12px" size="mini">进行中</el-tag>
|
||||
|
||||
<el-tag class="state_tag" size="mini" v-if="selectTask.state === '1'">进行中</el-tag>
|
||||
<el-tag class="state_tag" size="mini" v-if="selectTask.state === '4'" type="success">审批通过</el-tag>
|
||||
<el-tag class="state_tag" size="mini" v-if="selectTask.state === '3'" type="danger">审批驳回</el-tag>
|
||||
<el-tag class="state_tag" size="mini" v-if="selectTask.state === '2'" type="info">已撤销</el-tag>
|
||||
<!-- <el-tag style="font-size: 12px" size="mini">进行中</el-tag>-->
|
||||
</div>
|
||||
<div>
|
||||
<span style="color: rgb(108, 108, 108);">编号: {{ selectTask.taskId }}</span>
|
||||
|
|
@ -58,15 +63,21 @@
|
|||
</div>
|
||||
</div>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
<form-render v-if="!loading" ref="taskViewForm" :form-items="taskData.formItems"
|
||||
v-model="taskData.formData"/>
|
||||
<div>
|
||||
<form-render-view v-if="!loading" ref="taskViewForm" :form-items="taskData.formItems"
|
||||
v-model="taskData.formData"/>
|
||||
</div>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
<operation-render v-if="!loading"
|
||||
:operation-list="taskData.operationList"
|
||||
:state="selectTask.state"/>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
<el-footer class="footer">
|
||||
<div class="footer_comment" @click="showCommentBox">
|
||||
<i class="el-icon-chat-line-round" style="font-size: 18px;"></i>
|
||||
<span style="font-size: 12px;">评论</span>
|
||||
</div>
|
||||
<!-- <process-diagram-viewer/>-->
|
||||
<!-- <process-diagram-viewer/>-->
|
||||
<div style="margin-right: 20px;">
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link" style="color: #2a99ff;cursor: pointer">
|
||||
|
|
@ -76,7 +87,7 @@
|
|||
<el-dropdown-item icon="el-icon-s-custom" @click.native="showTransferBox()">转交</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-s-release" @click.native="showBackNodeBox()">退回</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-s-check" @click.native="showAddApprovalBox()">加签</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-refresh-left" @click.native="showRevocationBox()">撤销</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-refresh-left" @click.native="showRevocationBox()">撤销</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button type="danger" size="mini" plain round style="margin-left: 20px"
|
||||
|
|
@ -97,13 +108,14 @@
|
|||
|
||||
<script>
|
||||
import Comment from "../../components/common/Comment";
|
||||
import FormRender from "@/views/common/form/FormRender";
|
||||
import ProcessDiagramViewer from "../admin/layout/ProcessDiagramViewer";
|
||||
import {addComment, completeTask, getTaskInfo, getTaskList, refuseTask,rollBackTask} from "@/api/task";
|
||||
import {addComment, completeTask, getTaskInfo, getTaskList, refuseTask, rollBackTask} from "@/api/task";
|
||||
import OperationRender from "@/views/common/operation/OperationRender";
|
||||
import FormRenderView from "../common/form/FormRenderView";
|
||||
|
||||
export default {
|
||||
name: "DisposalTask",
|
||||
components: { Comment, FormRender, ProcessDiagramViewer},
|
||||
components: {FormRenderView, OperationRender, Comment, ProcessDiagramViewer},
|
||||
data() {
|
||||
return {
|
||||
approveOpen: false,
|
||||
|
|
@ -115,9 +127,11 @@ export default {
|
|||
},
|
||||
loading: false,
|
||||
taskData: {
|
||||
userInfo: {},
|
||||
formData: {},
|
||||
formItems: [],
|
||||
processList: []
|
||||
processList: [],
|
||||
operationList: []
|
||||
},
|
||||
avatar: require("@/assets/image/avatar.png")
|
||||
};
|
||||
|
|
@ -140,9 +154,11 @@ export default {
|
|||
},
|
||||
init() {
|
||||
this.taskData = {
|
||||
userInfo: {},
|
||||
formData: {},
|
||||
formItems: [],
|
||||
processList: []
|
||||
processList: [],
|
||||
operationList: []
|
||||
};
|
||||
this.loading = true;
|
||||
this.$store.state.design = this.taskData;
|
||||
|
|
@ -153,29 +169,28 @@ export default {
|
|||
let that = this;
|
||||
this.init();
|
||||
getTaskInfo(taskId).then(res => {
|
||||
let data=res.data
|
||||
data.formItems.map(item=>{
|
||||
if(item.props.required){
|
||||
item.props.required=!item.props.required
|
||||
}
|
||||
return item
|
||||
})
|
||||
that.taskData = res.data;
|
||||
that.$store.state.design = that.taskData;
|
||||
that.$store.state.userTaskOption = that.taskData.userTaskOption;
|
||||
|
||||
console.log(that.taskData.userTaskOption,"that.taskData.userTaskOption")
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
submitTask() {
|
||||
let params = {
|
||||
taskId: this.selectTask.taskId,
|
||||
formData: JSON.stringify(this.taskData.formData)
|
||||
};
|
||||
completeTask(params).then(res => {
|
||||
this.approveOpen = false;
|
||||
this.getList();
|
||||
this.$message.success(res.msg);
|
||||
});
|
||||
this.$refs.taskViewForm.validate(valid =>{
|
||||
if (valid){
|
||||
let params = {
|
||||
taskId: this.selectTask.taskId,
|
||||
formData: JSON.stringify(this.taskData.formData)
|
||||
};
|
||||
completeTask(params).then(res => {
|
||||
this.approveOpen = false;
|
||||
this.getList();
|
||||
this.$message.success(res.msg);
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
showCommentBox() {
|
||||
this.commentInfo = {
|
||||
|
|
@ -223,7 +238,28 @@ export default {
|
|||
this.$refs.comment.show()
|
||||
},
|
||||
/**
|
||||
* 拒绝提交
|
||||
* 评论回调
|
||||
* @param data
|
||||
* @param type
|
||||
*/
|
||||
commentConfirm(data, type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
this.submitComment(data);
|
||||
break;
|
||||
case 2:
|
||||
this.submitRefuse(data);
|
||||
break;
|
||||
case 4:
|
||||
this.submitRollBack(data);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 拒绝任务
|
||||
* @param data
|
||||
*/
|
||||
submitRefuse(data) {
|
||||
|
|
@ -238,32 +274,17 @@ export default {
|
|||
})
|
||||
},
|
||||
/**
|
||||
* 评论回调
|
||||
* @param data
|
||||
* @param type
|
||||
* 回退
|
||||
*/
|
||||
commentConfirm(data, type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
this.submitComment(data);
|
||||
break;
|
||||
case 2:
|
||||
this.submitRollBack(data);
|
||||
break;
|
||||
case 3:
|
||||
this.submitRefuse(data);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
},
|
||||
submitRollBack(data){
|
||||
submitRollBack(data) {
|
||||
let params = {
|
||||
taskId: this.selectTask.taskId,
|
||||
rollBackId: data.rollBackId,
|
||||
comment: data,
|
||||
};
|
||||
rollBackTask(params).then(res=>{
|
||||
rollBackTask(params).then(res => {
|
||||
this.approveOpen = false;
|
||||
this.getList();
|
||||
this.$message.success(res.msg);
|
||||
})
|
||||
},
|
||||
|
|
@ -274,6 +295,7 @@ export default {
|
|||
submitComment(data) {
|
||||
this.$set(data, "taskId", this.selectTask.taskId);
|
||||
addComment(data).then(res => {
|
||||
this.approveOpen = false;
|
||||
this.$message.success(res.msg);
|
||||
});
|
||||
}
|
||||
|
|
@ -282,6 +304,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
.top {
|
||||
padding: 0 10px 10px 10px;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
<div v-loading="loading" class="initiate_process">
|
||||
<div v-if="!loading" style="min-width: 338px;">
|
||||
<!--渲染表单-->
|
||||
<form-render class="process-form" ref="form" :form-items="processDefinition.formItems" v-model="formData"/>
|
||||
<form-render class="process-form" ref="initiateForm" :form-items="processDefinition.formItems" v-model="formData"/>
|
||||
</div>
|
||||
<div style="display: flex;justify-content: center;flex-direction: column;min-width: 1036px;">
|
||||
<span style="font-size: 18px;text-align: center;padding-top: 20px;">审批流程</span>
|
||||
<process-diagram-viewer/>
|
||||
<process-diagram-viewer ref="processDiagramViewer"/>
|
||||
<!--渲染流程执行过程-->
|
||||
<el-timeline :reverse="false">
|
||||
<!-- <el-timeline-item v-for="(activity, index) in activities" :key="index">-->
|
||||
|
|
@ -64,7 +64,6 @@ export default {
|
|||
methods: {
|
||||
loadProcessDefinitionInfo(processDefinitionKey) {
|
||||
getInitiateInfo(processDefinitionKey).then(res => {
|
||||
console.log(res);
|
||||
let processDefinition = res.data;
|
||||
this.processDefinition = processDefinition;
|
||||
//构建表单及校验规则
|
||||
|
|
@ -75,7 +74,8 @@ export default {
|
|||
});
|
||||
},
|
||||
validate(call) {
|
||||
this.$refs.form.validate(call);
|
||||
this.$refs.initiateForm.validate(call);
|
||||
this.$refs.processDiagramViewer.validate(call);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@
|
|||
prop="state"
|
||||
label="状态">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.state == 1">进行中</el-tag>
|
||||
<el-tag v-if="scope.row.state == 4" type="success">审批通过</el-tag>
|
||||
<el-tag v-if="scope.row.state == 3" type="danger">审批驳回</el-tag>
|
||||
<el-tag v-if="scope.row.state == 2" type="info">已撤销</el-tag>
|
||||
<el-tag v-if="scope.row.state === '1'">进行中</el-tag>
|
||||
<el-tag v-if="scope.row.state === '4'" type="success">审批通过</el-tag>
|
||||
<el-tag v-if="scope.row.state === '3'" type="danger">审批驳回</el-tag>
|
||||
<el-tag v-if="scope.row.state === '2'" type="info">已撤销</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
|
|
@ -51,27 +51,32 @@
|
|||
<div v-loading="loading">
|
||||
<div class="top">
|
||||
<div class="top_left">
|
||||
<el-avatar size="large" :src="avatar"></el-avatar>
|
||||
<span style="text-align: center;color: #19191a;font-size: 14px;">{{ selectProcessInstance.approveName }}</span>
|
||||
<el-avatar size="large" :src="processInstanceData.userInfo.avatar"></el-avatar>
|
||||
<span style="text-align: center;color: #19191a;font-size: 14px;">{{ processInstanceData.userInfo.name }}</span>
|
||||
</div>
|
||||
<div class="top_right">
|
||||
<div style="margin-bottom: 12px">
|
||||
<span style="font-size: 15px;">{{ selectProcessInstance.deploymentName }}</span>
|
||||
<el-tag style="font-size: 12px;margin:0 15px;" size="mini" type="success" v-if="selectProcessInstance.state==4">审批通过</el-tag>
|
||||
<el-tag style="font-size: 12px;margin:0 15px;" size="mini" v-else >进行中</el-tag>
|
||||
<span style="font-size: 15px;margin-right: 15px">{{ selectProcessInstance.deploymentName }}</span>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '1'" size="mini" >进行中</el-tag>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '4'" size="mini" type="success">审批通过</el-tag>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '3'" size="mini" type="danger">审批驳回</el-tag>
|
||||
<el-tag class="state_tag" v-if="selectProcessInstance.state === '2'" size="mini" type="info">已撤销</el-tag>
|
||||
<el-tooltip class="item" effect="dark" content="查看详细流程" placement="top-start">
|
||||
<el-icon class="el-icon-view" style="float: right;font-size: 20px;cursor: pointer" @click.native="processDiagramViewer = true"></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div>
|
||||
<span style="color: rgb(108, 108, 108);">编号: {{ selectProcessInstance.taskId }}</span>
|
||||
<span style="color: rgb(108, 108, 108);">编号: {{ selectProcessInstance.processInstanceId }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
<form-render-view ref="taskViewForm" :form-items="processInstanceData.formItems"
|
||||
<form-render-view v-if="!loading" ref="taskViewForm" :form-items="processInstanceData.formItems"
|
||||
v-model="processInstanceData.formData"/>
|
||||
<!-- <process-diagram-viewer v-if="!loading"/>-->
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
<operation-render v-if="!loading"
|
||||
:operation-list="processInstanceData.operationList"
|
||||
:state="selectProcessInstance.state"/>
|
||||
<div style="height: 15px;background:#f5f5f5;"></div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
|
@ -84,14 +89,14 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Comment from "@/components/common/Comment";
|
||||
import FormRenderView from '@/views/common/form/FormRender'
|
||||
import FormRenderView from '@/views/common/form/FormRenderView'
|
||||
import ProcessDiagramViewer from "../admin/layout/ProcessDiagramViewer";
|
||||
import {getInitiatedInstanceList, getInitiatedInstanceInfo} from "@/api/processInstance";
|
||||
import {timeLength} from '@/utils/date'
|
||||
import OperationRender from "../common/operation/OperationRender";
|
||||
export default {
|
||||
name: "InitiatedInstance",
|
||||
components: {Comment, FormRenderView, ProcessDiagramViewer},
|
||||
components: {OperationRender, FormRenderView, ProcessDiagramViewer},
|
||||
data() {
|
||||
return {
|
||||
approveOpen: false,
|
||||
|
|
@ -100,11 +105,12 @@ export default {
|
|||
tableData: [],
|
||||
loading: false,
|
||||
processInstanceData: {
|
||||
userInfo: {},
|
||||
formData: {},
|
||||
formItems: [],
|
||||
processList: [],
|
||||
operationList: [],
|
||||
},
|
||||
avatar: require("@/assets/image/avatar.png")
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -126,23 +132,27 @@ export default {
|
|||
that.$store.state.runningList = data.runningList;
|
||||
that.$store.state.endList = data.endList;
|
||||
that.$store.state.noTakeList = data.noTakeList;
|
||||
that.$store.state.refuseList = data.refuseList;
|
||||
that.$store.state.passList = data.passList;
|
||||
this.loading = false;
|
||||
console.log(data, "获取到的结果数据")
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
init() {
|
||||
this.processInstanceData = {
|
||||
userInfo: {},
|
||||
formData: {},
|
||||
formItems: [],
|
||||
processList: []
|
||||
processList: [],
|
||||
};
|
||||
this.loading = true;
|
||||
this.$store.state.design = this.taskData;
|
||||
this.$store.state.runningList = [];
|
||||
this.$store.state.endList = [];
|
||||
this.$store.state.noTakeList = [];
|
||||
this.$store.state.refuseList = [];
|
||||
this.$store.state.passList = [];
|
||||
this.$store.state.diagramMode = "viewer";
|
||||
this.$store.state.preview = false;
|
||||
},
|
||||
|
|
@ -185,4 +195,9 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.state_tag{
|
||||
font-size: 12px;
|
||||
//margin-right: 15px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -51,9 +51,7 @@ export default {
|
|||
taskId: this.taskId,
|
||||
formData : JSON.stringify(that.taskData.formData)
|
||||
}
|
||||
console.log(params,"需要提交的数据")
|
||||
completeTask(params).then(res =>{
|
||||
console.log(res)
|
||||
that.$parent.approveOpen = false
|
||||
that.$parent.getList()
|
||||
that.$message.success(res.msg)
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@
|
|||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="待我处理(3)" name="disposalTask">
|
||||
<disposal-task v-if="active == 'disposalTask'" ref="disposalTask"/>
|
||||
<disposal-task v-if="active === 'disposalTask'" ref="disposalTask"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="我发起的" name="initiated">
|
||||
<initiated-instance v-if="active == 'initiated'" ref="InitiatedInstance"/>
|
||||
<initiated-instance v-if="active === 'initiated'" ref="InitiatedInstance"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="关于我的" name="aboutMe">
|
||||
<div class="no-data">暂无数据 😀</div>
|
||||
<about-instance v-if="active === 'aboutMe'" ref="AboutInstance"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
|
|
@ -67,10 +67,11 @@ import InitiatedInstance from "./InitiatedInstance";
|
|||
import DisposalTask from "./DisposalTask";
|
||||
import {getProcessDefinitionList} from "@/api/processDefinition";
|
||||
import {startProcessInstance} from "@/api/processInstance";
|
||||
import AboutInstance from "./AboutInstance";
|
||||
|
||||
export default {
|
||||
name: "workSpace",
|
||||
components: {InitiateProcess,DisposalTask,InitiatedInstance},
|
||||
components: {AboutInstance, InitiateProcess,DisposalTask,InitiatedInstance},
|
||||
data() {
|
||||
return {
|
||||
active: 'disposalTask',
|
||||
|
|
@ -119,9 +120,12 @@ export default {
|
|||
// todo 提交流程测试
|
||||
submitForm(){
|
||||
let processInstance = this.$refs.processInstance;
|
||||
let selectUserMap = {}
|
||||
this.$store.state.selectUserMap.forEach(((value, key) => {selectUserMap[key]=value}))
|
||||
let paramsData = {
|
||||
processDefinitionId: this.selectForm.processDefinitionId,
|
||||
formData: JSON.stringify(processInstance.formData)
|
||||
formData: JSON.stringify(processInstance.formData),
|
||||
optionalUser: selectUserMap
|
||||
}
|
||||
processInstance.validate(valid => {
|
||||
if (valid) {
|
||||
|
|
@ -129,7 +133,6 @@ export default {
|
|||
this.openItemDl = false
|
||||
this.$message.success(res.msg)
|
||||
this.$refs.disposalTask.getList()
|
||||
|
||||
})
|
||||
} else {
|
||||
this.$message.warning("请完善表单😥")
|
||||
|
|
|
|||
Loading…
Reference in New Issue