|
@@ -1,7 +1,5 @@
|
|
|
<template>
|
|
|
- <layout
|
|
|
- title="流程"
|
|
|
- >
|
|
|
+ <layout title="流程">
|
|
|
<div class="custom-flow-path-container">
|
|
|
<!-- 审批人 -->
|
|
|
<div class="rows">
|
|
@@ -15,25 +13,26 @@
|
|
|
</div>
|
|
|
<div class="right flex flex-row">
|
|
|
<div v-if="approveSelList.length" class="procesbox flex flex-row flex-row-aic">
|
|
|
- <div
|
|
|
- class="flex flex-row"
|
|
|
- v-for="(personal, idx) in approveSelList"
|
|
|
- :key="idx"
|
|
|
- >
|
|
|
- <div class="personal flex flex-col"
|
|
|
- >
|
|
|
+ <div class="flex flex-row" v-for="(personal, idx) in approveSelList" :key="idx">
|
|
|
+ <div class="personal flex flex-col">
|
|
|
<div class="avatar avatar--name">
|
|
|
- <span class="avatar__name">{{ personal.name | changeName }}</span>
|
|
|
+ <template v-if="personal.avatar">
|
|
|
+ <img class="avatar-heade" :src="personal.avatar" />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <span class="avatar__name">{{ personal.name | changeName }}</span>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
<div class="personal__name">{{ personal.name }}</div>
|
|
|
</div>
|
|
|
|
|
|
- <van-icon class="arrow" v-if="idx !== approveSelList.length - 1" :size="14" name="arrow" />
|
|
|
+ <van-icon class="arrow" v-if="idx !== approveSelList.length - 1" :size="14" name="arrow"
|
|
|
+ color="rgb(151, 151, 151)" />
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div v-if="approveSelList.length < 3" class="empty-box" @click="handleOpenContacts">
|
|
|
+ <!-- <div v-if="approveSelList.length < 3" class="empty-box" @click="handleOpenContacts">
|
|
|
<van-icon :size="20" color="#979797" name="plus" />
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
</div>
|
|
|
<div class="rows-line"></div>
|
|
|
</div>
|
|
@@ -50,30 +49,72 @@
|
|
|
</div>
|
|
|
<div class="right flex flex-row">
|
|
|
<div v-if="copySelList.length" class="procesbox flex flex-row flex-row-aic">
|
|
|
- <div
|
|
|
- class="flex flex-row"
|
|
|
- v-for="(personal, idx) in copySelList"
|
|
|
- :key="idx"
|
|
|
- >
|
|
|
- <div class="personal flex flex-col"
|
|
|
- >
|
|
|
+ <div class="flex flex-row" v-if="copySelList.length > 3" @click="showMoreCopy = true">
|
|
|
+ <div class="personal flex flex-col">
|
|
|
<div class="avatar avatar--name">
|
|
|
- <span class="avatar__name">{{ personal.name | changeName }}</span>
|
|
|
+ <span class="avatar__name">
|
|
|
+ <van-icon name="friends-o" :size="24" />
|
|
|
+ </span>
|
|
|
</div>
|
|
|
- <div class="personal__name">{{ personal.name }}</div>
|
|
|
+ <div class="personal__name">查看全部</div>
|
|
|
</div>
|
|
|
+ <van-icon class="arrow" :size="14" name="plus" color="rgb(151, 151, 151)" />
|
|
|
+ </div>
|
|
|
|
|
|
- <van-icon class="arrow" v-if="idx !== 2" :size="14" name="arrow" />
|
|
|
-
|
|
|
+ <div class="flex flex-row" v-for="(personal, idx) in copySelListCompu" :key="idx">
|
|
|
+ <div class="personal flex flex-col">
|
|
|
+ <div class="avatar avatar--name">
|
|
|
+ <template v-if="personal.avatar">
|
|
|
+ <img class="avatar-heade" :src="personal.avatar" />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <span class="avatar__name">{{ personal.name | changeName }}</span>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div class="personal__name">{{ personal.name }}</div>
|
|
|
+ </div>
|
|
|
+ <van-icon v-if="idx !== copySelListCompu.length - 1" class="arrow" :size="14" name="plus"
|
|
|
+ color="rgb(151, 151, 151)" />
|
|
|
+ <van-icon v-else-if="isAllowCopy == '1'" class="arrow" :size="14" name="plus"
|
|
|
+ color="rgb(151, 151, 151)" />
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div v-if="copySelList.length < 3" class="empty-box" @click="handleOpenContactsCopy">
|
|
|
+ <div class="empty-box" v-if="isAllowCopy == '1'" @click="handleOpenContactsCopy">
|
|
|
<van-icon :size="20" color="#979797" name="plus" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- NOTE: 当抄送人过多时 展示优化 -->
|
|
|
+ <van-popup v-model="showMoreCopy" position="bottom" :style="{ height: '60%' }" closeable
|
|
|
+ close-icon-position="top-right">
|
|
|
+ <div class="show-more-copy-container flex flex-col">
|
|
|
+ <div class="header">抄送{{ copySelList.length }}人</div>
|
|
|
+ <div class="main">
|
|
|
+ <div class="procesbox flex flex-row flex-row-aic">
|
|
|
+ <div class="flex flex-row" v-for="(personal, idx) in copySelList" :key="idx">
|
|
|
+ <div class="personal flex flex-col">
|
|
|
+ <div class="closebox" @click="handleRemoveSignal(personal, idx)"><van-icon name="cross"
|
|
|
+ :size="14" color="#fff" /></div>
|
|
|
+ <div class="avatar avatar--name">
|
|
|
+ <template v-if="personal.avatar">
|
|
|
+ <img class="avatar-heade" :src="personal.avatar" />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <span class="avatar__name">{{ personal.name | changeName }}</span>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div class="personal__name">{{ personal.name }}</div>
|
|
|
+ </div>
|
|
|
+ <van-icon class="arrow" v-if="idx !== copySelList.length - 1" :size="14" name="plus"
|
|
|
+ color="rgb(151, 151, 151)" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </van-popup>
|
|
|
</layout>
|
|
|
</template>
|
|
|
|
|
@@ -84,6 +125,7 @@
|
|
|
&-container {
|
|
|
padding: 10px 12px;
|
|
|
background-color: @white;
|
|
|
+
|
|
|
.rows {
|
|
|
position: relative;
|
|
|
display: flex;
|
|
@@ -91,7 +133,7 @@
|
|
|
// align-items: center;
|
|
|
justify-content: space-between;
|
|
|
margin-bottom: 16px;
|
|
|
-
|
|
|
+
|
|
|
.rows-line {
|
|
|
position: absolute;
|
|
|
left: -10px;
|
|
@@ -108,6 +150,7 @@
|
|
|
font-weight: 400;
|
|
|
color: #191A1E;
|
|
|
line-height: 18px;
|
|
|
+
|
|
|
&::after {
|
|
|
position: absolute;
|
|
|
content: "";
|
|
@@ -121,6 +164,7 @@
|
|
|
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
&__desc {
|
|
|
font-size: @font-size-third;
|
|
|
font-weight: 400;
|
|
@@ -140,6 +184,7 @@
|
|
|
border-radius: 5px;
|
|
|
border: 1px solid #EEEEEF;
|
|
|
}
|
|
|
+
|
|
|
// .right {}
|
|
|
&:last-child {
|
|
|
.rows-line {
|
|
@@ -147,54 +192,89 @@
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- .avatar {
|
|
|
- position: relative;
|
|
|
- width: 31px;
|
|
|
- height: 31px;
|
|
|
- background: #3290C4;
|
|
|
+.procesbox {
|
|
|
+ flex-wrap: wrap;
|
|
|
+
|
|
|
+ .avatar {
|
|
|
+ position: relative;
|
|
|
+ width: 31px;
|
|
|
+ height: 31px;
|
|
|
+ background: #3290C4;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: @font-size-third;
|
|
|
+
|
|
|
+ &--name {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-heade {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ vertical-align: middle;
|
|
|
border-radius: 4px;
|
|
|
- &--name {
|
|
|
- display: flex;
|
|
|
- flex-direction: row;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- }
|
|
|
- &__name {
|
|
|
- font-size: @font-size-third;
|
|
|
- font-family: PingFangSC-Regular, PingFang SC;
|
|
|
- font-weight: 400;
|
|
|
- color: #FFFFFF;
|
|
|
- line-height: 9px;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- .procesbox {
|
|
|
- flex-wrap: wrap;
|
|
|
- .avatar {
|
|
|
- font-size: @font-size-third;
|
|
|
- &__name {
|
|
|
- white-space: nowrap;
|
|
|
- }
|
|
|
- }
|
|
|
- .personal {
|
|
|
- align-items: center;
|
|
|
- &__name {
|
|
|
- font-size: @font-size-third;
|
|
|
- font-family: PingFangSC-Regular, PingFang SC;
|
|
|
- font-weight: 400;
|
|
|
- color: #9A9A9A;
|
|
|
- text-align: center;
|
|
|
- line-height: 20px;
|
|
|
- }
|
|
|
- }
|
|
|
- .arrow {
|
|
|
- height: 31px;
|
|
|
- line-height: 31px;
|
|
|
- padding: 0 5px;
|
|
|
- }
|
|
|
+ &__name {
|
|
|
+ font-size: @font-size-third;
|
|
|
+ font-family: PingFangSC-Regular, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: 9px;
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
-
|
|
|
+ }
|
|
|
+
|
|
|
+ .personal {
|
|
|
+ position: relative;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ &__name {
|
|
|
+ font-size: @font-size-third;
|
|
|
+ font-family: PingFangSC-Regular, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #9A9A9A;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .closebox {
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ z-index: 9;
|
|
|
+ font-size: 0;
|
|
|
+ transform: translate(30%, -30%);
|
|
|
+ background-color: #b7b5b5;
|
|
|
+ border-radius: 1000px;
|
|
|
+ padding: 1px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .arrow {
|
|
|
+ height: 31px;
|
|
|
+ line-height: 31px;
|
|
|
+ padding: 0 5px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.show-more-copy-container {
|
|
|
+ .header {
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 50px;
|
|
|
+ padding: 0 20px;
|
|
|
+ color: #828282;
|
|
|
+ }
|
|
|
+
|
|
|
+ .main {
|
|
|
+ height: 0;
|
|
|
+ flex: 1;
|
|
|
+ padding: 6px 10px;
|
|
|
}
|
|
|
}
|
|
|
</style>
|
|
@@ -210,14 +290,19 @@ export default {
|
|
|
Layout
|
|
|
},
|
|
|
computed: {
|
|
|
- approveTxt () {
|
|
|
- let list = this.approvePersonal
|
|
|
+ approveTxt() {
|
|
|
+ let list = this.approveSelList
|
|
|
return list.length ? `${list.length}人依次审批` : '请选择审批人'
|
|
|
},
|
|
|
- sendTxt () {
|
|
|
- let list = this.sendTo
|
|
|
+ sendTxt() {
|
|
|
+ let list = this.copySelList
|
|
|
return list.length ? `抄送${list.length}人` : '请选择抄送人'
|
|
|
},
|
|
|
+ copySelListCompu() {
|
|
|
+ let arrs = [...this.copySelList]
|
|
|
+ if (arrs.length > 2) return arrs.slice(-2)
|
|
|
+ else return arrs
|
|
|
+ },
|
|
|
},
|
|
|
props: {
|
|
|
approve: {
|
|
@@ -227,47 +312,49 @@ export default {
|
|
|
type: Array
|
|
|
},
|
|
|
isAllowCopy: { // 是否允许抄送人存在变更 (0:否, 1:是)
|
|
|
- validator: val => (['0', '1'].includes(val))
|
|
|
+ // validator: val => (['0', '1'].includes(val)),
|
|
|
+ type: [String, Number],
|
|
|
+ default: 1
|
|
|
}
|
|
|
},
|
|
|
- data () {
|
|
|
+ data() {
|
|
|
return {
|
|
|
+ showMoreCopy: false,
|
|
|
approveSelList: [],
|
|
|
- copySelList: [],
|
|
|
-
|
|
|
- personalList: [],
|
|
|
- personalList2: [],
|
|
|
-
|
|
|
- approvePersonal: [],
|
|
|
- sendTo: []
|
|
|
+ copySelList: []
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
|
|
|
// 打开钉钉联系人控件。完成选审批/抄送人操作
|
|
|
- async handleOpenContacts () {
|
|
|
+ async handleOpenContacts() {
|
|
|
|
|
|
const result = await dingtalkComplexPicker({})
|
|
|
-
|
|
|
+
|
|
|
console.log(result);
|
|
|
},
|
|
|
- async handleOpenContactsCopy () {
|
|
|
+ async handleOpenContactsCopy() {
|
|
|
if (this.isAllowCopy != 1) return
|
|
|
-
|
|
|
+
|
|
|
const result = await dingtalkComplexPicker({})
|
|
|
-
|
|
|
+
|
|
|
console.log(result);
|
|
|
},
|
|
|
+ handleRemoveSignal(person, idx) {
|
|
|
+ this.copySelList.splice(idx, 1)
|
|
|
+
|
|
|
+ // TODO: Update copy data.
|
|
|
+ }
|
|
|
},
|
|
|
watch: {
|
|
|
approve: {
|
|
|
- handler (arrs) {
|
|
|
+ handler(arrs) {
|
|
|
if (arrs.length) this.approveSelList = [...arrs]
|
|
|
},
|
|
|
deep: true,
|
|
|
},
|
|
|
copy: {
|
|
|
- handler (arrs) {
|
|
|
+ handler(arrs) {
|
|
|
if (arrs.length) this.copySelList = [...arrs]
|
|
|
},
|
|
|
deep: true
|