123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- <template>
- <layout title="流程">
- <div class="custom-flow-path-container">
- <!-- 审批人 -->
- <div class="rows">
- <div class="left">
- <div class="left__title">
- 审批人
- </div>
- <div class="left__desc">
- {{ approveTxt }}
- </div>
- </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="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 !== 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">
- <van-icon :size="20" color="#979797" name="plus" />
- </div> -->
- </div>
- <div class="rows-line"></div>
- </div>
- <!-- 抄送人 -->
- <div class="rows" v-if="copySelList.length || isAllowCopy == '1'">
- <div class="left">
- <div class="left__title">
- 抄送人
- </div>
- <div class="left__desc">
- {{ sendTxt }}
- </div>
- </div>
- <div class="right flex flex-row">
- <div class="procesbox flex flex-row flex-row-aic">
- <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">
- <van-icon name="friends-o" :size="24" />
- </span>
- </div>
- <div class="personal__name">查看全部</div>
- </div>
- <van-icon class="arrow" :size="14" name="plus" color="rgb(151, 151, 151)" />
- </div>
- <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 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>
- <style lang="less" scoped>
- @import url("@/styles/variables.less");
- .custom-flow-path {
- &-container {
- padding: 10px 12px;
- background-color: @white;
- .rows {
- position: relative;
- display: flex;
- flex-direction: row;
- // align-items: center;
- justify-content: space-between;
- margin-bottom: 16px;
- .rows-line {
- position: absolute;
- left: -10px;
- top: 17px;
- width: 1px;
- height: 100%;
- background-color: #D8D8D8;
- }
- .left {
- &__title {
- position: relative;
- font-size: @font-size-common;
- font-weight: 400;
- color: #191A1E;
- line-height: 18px;
- &::after {
- position: absolute;
- content: "";
- left: -12px;
- top: 50%;
- width: 8px;
- height: 8px;
- border-radius: 8px;
- background: #D8D8D8;
- transform: translateY(-50%);
- }
- }
- &__desc {
- font-size: @font-size-third;
- font-weight: 400;
- color: #9A9A9A;
- line-height: 18px;
- }
- }
- .empty-box {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- width: 31px;
- height: 31px;
- background: #FFFFFF;
- border-radius: 5px;
- border: 1px solid #EEEEEF;
- }
- // .right {}
- &:last-child {
- .rows-line {
- width: 0;
- }
- }
- }
- }
- }
- .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 {
- 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>
- <script>
- import Layout from './Layout.vue';
- import { dingtalkComplexPicker } from '@/utils/dingtalk'
- export default {
- name: 'CFlowPath',
- components: {
- Layout
- },
- computed: {
- approveTxt() {
- let list = this.approveSelList
- return list.length ? `${list.length}人依次审批` : '请选择审批人'
- },
- 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: {
- type: Array
- },
- copy: {
- type: Array
- },
- isAllowCopy: { // 是否允许抄送人存在变更 (0:否, 1:是)
- // validator: val => (['0', '1'].includes(val)),
- type: [String, Number],
- default: 1
- }
- },
- data() {
- return {
- showMoreCopy: false,
- approveSelList: [],
- copySelList: []
- }
- },
- methods: {
- // 打开钉钉联系人控件。完成选审批/抄送人操作
- async handleOpenContacts() {
- const result = await dingtalkComplexPicker({})
- console.log(result);
- },
- 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) {
- if (arrs.length) this.approveSelList = [...arrs]
- },
- deep: true,
- },
- copy: {
- handler(arrs) {
- if (arrs.length) this.copySelList = [...arrs]
- },
- deep: true
- }
- }
- }
- </script>
|