89 lines
1.7 KiB
Vue
89 lines
1.7 KiB
Vue
<template>
|
|
<view class="assignee-tree">
|
|
<template v-for="row in flatRows" :key="row.key">
|
|
<view
|
|
v-if="row.type === 'dept'"
|
|
class="dept-node"
|
|
:style="{ paddingLeft: `${row.level * 24 + 20}rpx` }"
|
|
>
|
|
<text class="dept-name">{{ row.deptName }}</text>
|
|
</view>
|
|
<view
|
|
v-else
|
|
class="user-item"
|
|
:class="{ active: String(selectedIdentityId) === String(resolveAssigneeIdentityId(row.user)) }"
|
|
:style="{ paddingLeft: `${row.level * 24 + 20}rpx` }"
|
|
@click="handleSelect(row.user)"
|
|
>
|
|
<text class="user-item-text">{{ formatAssigneeDisplayName(row.user) }}</text>
|
|
<text
|
|
v-if="String(selectedIdentityId) === String(resolveAssigneeIdentityId(row.user))"
|
|
class="cuIcon-check text-blue"
|
|
></text>
|
|
</view>
|
|
</template>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue';
|
|
import {
|
|
flattenApproverDeptTree,
|
|
formatAssigneeDisplayName,
|
|
resolveAssigneeIdentityId
|
|
} from './flowAssigneeUtils.js';
|
|
|
|
const props = defineProps({
|
|
depts: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
selectedIdentityId: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
});
|
|
|
|
const emit = defineEmits(['select']);
|
|
|
|
const flatRows = computed(() => flattenApproverDeptTree(props.depts));
|
|
|
|
const handleSelect = (user) => {
|
|
emit('select', user);
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.dept-node {
|
|
padding: 20rpx 20rpx 12rpx;
|
|
font-size: 26rpx;
|
|
color: #909399;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.dept-name {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.user-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 24rpx 20rpx;
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
|
|
&.active {
|
|
.user-item-text {
|
|
color: #2667E9;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
.user-item-text {
|
|
flex: 1;
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
}
|
|
}
|
|
</style>
|