Files
laws_chery_client/src/components/PersonnelInfo.vue
T

324 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="person-comp-box">
<a-steps direction="vertical">
<!-- 没有currentNode说明流程已经结束了图标和线都显示已经走过的样式 -->
<a-step v-for="(step, index) in stepsData" :key="step.id" :status="step.nodeName === currentNode ? 'process' : 'wait'"
:class="{'red-tail': currentNode ? index < currentNodeIndex : true}">
<template #icon>
<div class="step-cus-icon"
:class="{'step-cus-icon-done': currentNode ? index < currentNodeIndex : true, 'step-cus-icon-now': index === currentNodeIndex}">
<i class="iconfont icon-user" />
</div>
</template>
<!-- 流程节点标题-->
<!--<template #title>-->
<!-- <a-tooltip>-->
<!-- <template #title>{{ step.nodeName }}</template>-->
<!-- <div class="step-title">{{ step.nodeName }}</div>-->
<!-- </a-tooltip>-->
<!--</template>-->
<!-- 流程节点选人内容-->
<template #description>
<div class="personnel-container">
<div class="personnel-container-title" :class="{'personnel-container-select-title': index === 0}">
<a-tooltip>
<template #title>{{ step.nodeName }}</template>
<div class="personnel-container-title-text">{{ step.nodeName }}</div>
</a-tooltip>
</div>
<div class="personnel-container-content">
<div class="personnel-container-content-text">
<template v-if="step.canChoose && index >= currentNodeIndex">
<user-select-by-work-group v-if="step.chooseSource === 'workGroup'"
v-model="step.linkUserIds"
:type="step.chooseType"
:name-str="step.linkUserIds_dictText"
:filedName="step.variableName"
@nameChange="nameChange"
input-type="textarea" />
<user-select-by-contact v-else-if="step.chooseSource === 'contactManage'"
v-model="step.linkUserIds"
:type="step.chooseType"
:name-str="step.linkUserIds_dictText"
:filedName="step.variableName"
@nameChange="nameChange"
input-type="textarea" />
<user-selection v-else-if="step.chooseSource === 'user'"
:type="step.chooseType"
v-model="step.linkUserIds"
:name-str="step.linkUserIds_dictText"
:filedName="step.variableName"
@nameChange="nameChange"
input-type="textarea" />
</template>
<div class="personnel-container-content-echo-text" v-else>{{ step.userList }}</div>
</div>
<a-icon type="clock-circle" theme="filled" v-if="index === currentNodeIndex" class="personnel-container-content-icon" />
<a-icon type="check"
v-if="index < currentNodeIndex"
class="personnel-container-content-icon personnel-container-content-icon-now" />
</div>
</div>
</template>
</a-step>
</a-steps>
</div>
</template>
<script>
import '@assets/less/common.less'
import UserSelection from './selection/UserSelection.vue'
import UserSelectByWorkGroup from './selection/UserSelectByWorkGroup'
import UserSelectByContact from './selection/UserSelectByContact'
export default {
name: 'PersonnelInfo',
components: { UserSelectByContact, UserSelectByWorkGroup, UserSelection },
props: {
// 数据
data: {
type: Array,
required: true,
default: () => {
return []
}
},
// 当前节点
currentNode: {
type: String,
required: false,
default: null
},
// 特殊流程需要用indexOf判断的前缀
specialProcessNodePrefix: {
type: String,
required: false,
default: null
},
// 不需要做必填校验的字段,用于应对第一个节点选没选人决定节点跳不跳过的问题
notPermissField: {
type: Array,
required: false,
default: () => {
return []
}
}
},
data () {
return {
stepsData: []
}
},
computed: {
// 当前节点的位置
currentNodeIndex () {
if (this.specialProcessNodePrefix) {
return this.stepsData.findIndex(tt => tt.xmlNodeId.indexOf(this.specialProcessNodePrefix) === 0)
}
return this.stepsData.findIndex(tt => tt.xmlNodeId === this.currentNode)
}
},
watch: {
data: {
handler () {
this.stepsData = JSON.parse(JSON.stringify(this.data))
},
deep: true,
immediate: true
}
},
methods: {
// 获取人员对象,无校验
getDataObj () {
const personnelObj = {}
// for (let i = 0; i < this.stepsData.length; i++) {
// // 该属性还没有人就给他赋值
// if ((this.stepsData[i].canChoose || i === 0) && !personnelObj[this.stepsData[i].variableName]) {
// personnelObj[this.stepsData[i].variableName] = this.stepsData[i].linkUserIds
// personnelObj[this.stepsData[i].variableName + '_dictText'] = this.stepsData[i].linkUserIds_dictText || this.stepsData[i].userList
// }
// }
for (const item of this.stepsData) {
console.log(item)
// 该属性还没有人就给他赋值
if (!personnelObj[item.variableName]) {
personnelObj[item.variableName] = item.linkUserIds
personnelObj[item.variableName + '_dictText'] = item.linkUserIds_dictText || item.userList
}
// if ((item.canChoose || item.sort === 1) && !personnelObj[item.variableName]) {
// personnelObj[item.variableName] = item.linkUserIds
// personnelObj[item.variableName + '_dictText'] = item.linkUserIds_dictText || item.userList
// }
}
return personnelObj
},
// 有校验的获取人员对象
getDataObjVerify () {
let personnelObj = {}
console.log(this.stepsData)
for (let i = 0; i < this.stepsData.length; i++) {
// 该属性还没有人就给他赋值,并且如果minLength有值的话,需要判断选的人数过了这个限制
if ((this.stepsData[i].canChoose || i === 0) && !personnelObj[this.stepsData[i].variableName]) {
if (this.stepsData[i].minLength) {
// 有设置至少选几人
if (this.stepsData[i].linkUserIds && this.stepsData[i].linkUserIds.split(',').length >= this.stepsData[i].minLength) {
// 说明人数通过了限制
personnelObj[this.stepsData[i].variableName] = this.stepsData[i].linkUserIds
personnelObj[this.stepsData[i].variableName + '_dictText'] = this.stepsData[i].linkUserIds_dictText || this.stepsData[i].userList
} else {
// 提示XX节点至少选择XX人
this.$message.warning(this.stepsData[i].nodeName + this.$t('node') + this.$t('atLeastSelect') + this.stepsData[i].minLength + this.$t('personnal'))
personnelObj[this.stepsData[i].variableName] = ''
return
}
} else {
personnelObj[this.stepsData[i].variableName] = this.stepsData[i].linkUserIds
personnelObj[this.stepsData[i].variableName + '_dictText'] = this.stepsData[i].linkUserIds_dictText || this.stepsData[i].userList
}
}
}
console.log(personnelObj)
for (const item in personnelObj) {
if (!this.notPermissField.includes(item) && !personnelObj[item]) {
// 不在不需要做必填校验的字段里,说明是必填并且没有数据
this.$message.warning(this.$t('pleaseEnterPersonnelInfo'))
personnelObj = false
break
}
}
return personnelObj
},
nameChange (value, fieldName) {
this.stepsData.find(item => item.variableName === fieldName).linkUserIds_dictText = value
this.stepsData.find(item => item.variableName === fieldName).userList = value
}
}
}
</script>
<style scoped lang="less">
.person-comp-box {
height: 100%;
}
/deep/ .ant-steps-vertical .ant-steps-item-icon {
margin-right: 0;
}
/deep/ .ant-steps-item-title {
max-width: 100%;
}
/deep/ .ant-steps-item-content {
padding: 0 12px 30px 12px;
}
.step-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16px;
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
color: #1D2129;
font-weight: 550;
}
.personnel-container {
&-title {
height: 36px;
background: #6A7484;
border-radius: 8px 8px 0 0;
padding: 0 16px;
&-text {
font-size: 16px;
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
color: #FFFFFF;
line-height: 36px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
&-select-title {
background: #9F5258;
}
&-content {
background: #FFFFFF;
border-radius: 0 0 8px 8px;
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1);
padding: 16px;
min-height: 52px;
display: flex;
align-items: center;
&-text {
flex: 1;
width: 0;
}
&-icon {
margin-left: 16px;
color: @primary-color;
font-size: 20px;
}
&-icon-now {
font-size: 10px;
width: 20px;
height: 20px;
background: #FAE6E5;
border-radius: 10px 10px 10px 10px;
opacity: 1;
line-height: 20px;
text-align: center;
}
&-echo-text {
font-size: 14px;
font-family: PingFang SC-Regular, PingFang SC, sans-serif;
font-weight: 400;
color: #4E5969;
line-height: 22px;
word-break: break-all;
}
}
}
/deep/ .user-organ-wrap .button-box {
height: 32px;
}
/deep/ .ant-steps-vertical > .ant-steps-item > .ant-steps-item-container > .ant-steps-item-tail {
left: 14px;
padding: 31px 0 4px;
}
.step-cus-icon {
width: 28px;
height: 28px;
background: #F2F3F5;
border-radius: 32px 32px 32px 32px;
display: flex;
align-items: center;
justify-content: center;
&-done {
background: rgba(0, 100, 250, 0.08);
color: @primary-color;
}
&-now {
color: white;
background: @primary-color;
}
}
/deep/ .red-tail > .ant-steps-item-container > .ant-steps-item-tail::after {
background-color: @primary-color;
}
</style>