285 lines
7.5 KiB
Vue
285 lines
7.5 KiB
Vue
<template>
|
|
<div>
|
|
<van-overlay :show="loading" :z-index="99999">
|
|
<van-loading />
|
|
</van-overlay>
|
|
<div class="header-switch">
|
|
<!--基础信息-->
|
|
<div class="header-switch-item header-switch-left"
|
|
:class="{'header-switch-active': activeTab === 'basic'}"
|
|
@click="handleActiveTab('basic')">
|
|
{{ $t('basicInfo') }}
|
|
</div>
|
|
<!--人员信息-->
|
|
<div class="header-switch-item header-switch-right"
|
|
:class="{'header-switch-active': activeTab === 'person'}"
|
|
@click="handleActiveTab('person')">
|
|
{{ $t('personalInfo') }}
|
|
</div>
|
|
</div>
|
|
<!--流程信息部分-->
|
|
<div class="process-container" v-show="activeTab === 'basic'">
|
|
<slot name="process"></slot>
|
|
</div>
|
|
<!--人员信息-->
|
|
<div class="process-container" v-show="activeTab === 'person'">
|
|
<van-steps direction="vertical">
|
|
<van-step v-for="item in personnelInfoData" :key="item.id">
|
|
<template #active-icon>
|
|
<van-icon class="iconfont" class-prefix="icon" name="circle" />
|
|
</template>
|
|
<template #inactive-icon>
|
|
<van-icon class="iconfont" class-prefix="icon" name="circle" />
|
|
</template>
|
|
<h3>{{ item.nodeName }}</h3>
|
|
<p v-if="!item.canChoose">{{ item.linkUserIds_dictText }}</p>
|
|
<div v-else>
|
|
<select-user-field v-if="item.chooseSource === 'user'"
|
|
class="no-label"
|
|
v-model="item.linkUserIds"
|
|
:type="item.chooseType"
|
|
:checkedNames="item.linkUserIds_dictText"
|
|
:fieldName="item.variableName"
|
|
@selectNameChange="nameChange"
|
|
input-type="textarea" />
|
|
</div>
|
|
</van-step>
|
|
</van-steps>
|
|
</div>
|
|
|
|
<!--底部操作按钮-->
|
|
<div class="operate-box">
|
|
<slot name="operation"></slot>
|
|
</div>
|
|
|
|
<slot></slot>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { getPersonInfoList } from '@/api/api'
|
|
import SelectUserField from '@/components/SelectUserField'
|
|
|
|
export default {
|
|
name: 'ProcessCommonLayout',
|
|
components: { SelectUserField },
|
|
props: {
|
|
// 加载效果
|
|
loading: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false
|
|
},
|
|
// 流程key
|
|
processKey: {
|
|
type: String,
|
|
required: false,
|
|
default: ''
|
|
},
|
|
// 人员信息可以修改的字段
|
|
canChooseFields: {
|
|
type: Array,
|
|
required: false,
|
|
default: () => {
|
|
return []
|
|
}
|
|
}
|
|
},
|
|
data () {
|
|
return {
|
|
activeTab: 'basic',
|
|
personnelInfoData: [] // 人员信息列表
|
|
}
|
|
},
|
|
mounted () {
|
|
this.getPersonInfoStructure()
|
|
},
|
|
methods: {
|
|
/**
|
|
* 切换标签页
|
|
* @param key
|
|
*/
|
|
handleActiveTab (key) {
|
|
this.activeTab = key
|
|
},
|
|
/**
|
|
* 获取人员信息列表数据
|
|
* @param key
|
|
*/
|
|
getPersonInfoStructure () {
|
|
const param = {}
|
|
param.processDefinitionKey = this.processKey
|
|
if (this.$route.query.processInstanceId) {
|
|
param.processInstanceId = this.$route.query.processInstanceId
|
|
}
|
|
getPersonInfoList(param).then(res => {
|
|
if (res.success) {
|
|
console.log('-------------获取人员信息完成', res.result)
|
|
// 处理人员信息数据,判断每个节点是否能选人
|
|
this.personnelInfoData = res.result.map(item => {
|
|
return {
|
|
...item,
|
|
canChoose: this.canChooseFields.includes(item.variableName),
|
|
chooseType: item.variableType === 'string' ? 'radio' : 'checkbox'
|
|
}
|
|
})
|
|
}
|
|
})
|
|
},
|
|
// 从草稿进来填过的人员需要回显
|
|
draftInitPersonInfo (personInfoObj) {
|
|
console.log('--------------draftInitPersonInfo 草稿进来回显')
|
|
this.personnelInfoData = this.personnelInfoData.map(item => {
|
|
return {
|
|
...item,
|
|
linkUserIds: personInfoObj[item.variableName] || item.linkUserIds,
|
|
linkUserIds_dictText: personInfoObj[item.variableName + '_dictText'],
|
|
userList: personInfoObj[item.variableName + '_dictText']
|
|
}
|
|
})
|
|
},
|
|
// 获取人员对象,无校验
|
|
getDataObj () {
|
|
const personnelObj = {}
|
|
for (const item of this.personnelInfoData) {
|
|
// 该属性还没有人就给他赋值
|
|
if (!personnelObj[item.variableName]) {
|
|
personnelObj[item.variableName] = item.linkUserIds
|
|
personnelObj[item.variableName + '_dictText'] = item.linkUserIds_dictText || item.userList
|
|
}
|
|
}
|
|
console.log(personnelObj)
|
|
return personnelObj
|
|
},
|
|
// 有校验的获取人员对象
|
|
getDataObjVerify () {
|
|
let personnelObj = {}
|
|
for (const item of this.personnelInfoData) {
|
|
// 该属性还没有人就给他赋值
|
|
if (item.canChoose && !personnelObj[item.variableName]) {
|
|
personnelObj[item.variableName] = item.linkUserIds
|
|
}
|
|
}
|
|
if (!Object.values(personnelObj).every(v => !!v)) {
|
|
this.$message(this.$t('pleaseEnterPersonnelInfo'))
|
|
personnelObj = false
|
|
}
|
|
return personnelObj
|
|
},
|
|
nameChange (value, fieldName) {
|
|
console.log(value, fieldName)
|
|
this.personnelInfoData.find(item => item.variableName === fieldName).linkUserIds_dictText = value
|
|
this.personnelInfoData.find(item => item.variableName === fieldName).userList = value
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
@import '~@assets/less/common.less';
|
|
|
|
.header-switch {
|
|
height: 1.11rem;
|
|
background: #FFFFFF;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.header-switch-item {
|
|
width: 2.09rem;
|
|
height: 0.68rem;
|
|
font-size: 0.28rem;
|
|
line-height: 0.68rem;
|
|
text-align: center;
|
|
color: @font-color;
|
|
border: 1px solid @primary-color;
|
|
}
|
|
|
|
.header-switch-left {
|
|
border-radius: 0.34rem 0 0 0.34rem;
|
|
}
|
|
|
|
.header-switch-right {
|
|
border-radius: 0 0.34rem 0.34rem 0;
|
|
}
|
|
|
|
.header-switch-active {
|
|
background-color: @primary-color;
|
|
color: #FFFFFF;
|
|
}
|
|
|
|
.process-container {
|
|
height: calc(100% - 1.11rem - 1.28rem);
|
|
overflow: auto;
|
|
padding-top: 0.16rem;
|
|
background: #F8F9FB;
|
|
}
|
|
|
|
.operate-box {
|
|
height: 1.28rem;
|
|
background-color: #FFFFFF;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.van-overlay {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
/deep/ .van-steps {
|
|
padding: 0 0.32rem 0 0.88rem;
|
|
.van-step__title {
|
|
h3 {
|
|
font-size: 0.28rem;
|
|
color: rgba(29, 33, 41, 0.9);
|
|
line-height: 0.33rem;
|
|
margin: 0 0 0.16rem 0;
|
|
font-weight: 400;
|
|
}
|
|
p {
|
|
background: #F2F3F5;
|
|
border-radius: 0.04rem 0.04rem 0.04rem 0.04rem;
|
|
margin: 0;
|
|
padding: 0.26rem 0.21rem;
|
|
color: #1D2129;
|
|
font-size: 0.32rem;
|
|
font-weight: 600;
|
|
line-height: 0.38rem;
|
|
}
|
|
}
|
|
.van-step__circle-container {
|
|
left: -0.44rem;
|
|
color: @primary-color;
|
|
}
|
|
.van-step__line {
|
|
width: 0.03rem;
|
|
height: calc(100% - 0.24rem);
|
|
left: -0.46rem !important;
|
|
top: 0.47rem;
|
|
background: linear-gradient(to top,transparent 0%,transparent 50%,#ccc 50%,#ccc 100%);
|
|
background-size: 0.03rem 0.2rem;
|
|
background-repeat: repeat-y;
|
|
//border: 1px dashed #BABABA;
|
|
}
|
|
.van-step:last-child {
|
|
.van-step__line {
|
|
display: none;
|
|
}
|
|
}
|
|
.van-step--vertical:not(:last-child)::after {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.no-label {
|
|
/deep/ .van-cell__title {
|
|
display: none;
|
|
}
|
|
}
|
|
</style>
|