|
- <template>
- <view class="tree-item">
- <!-- 全局根元素时隐藏 -->
- <view v-if="root.id !== '0'" @click="selfClick" class="tree-item-self">
- <!-- 已确认子列表为空则显示横杠图标;加载中则显示 loading 图标;否则显示展开/收起图标 -->
- <l-icon v-if="isEmpty" type="move" class="tree-item-icon" />
- <l-icon
- v-else-if="root.type !== 'user' && !isLoading"
- :type="isOpen ? 'unfold' : 'right'"
- class="tree-item-icon"
- />
- <view v-else-if="root.type !== 'user' && isLoading" class="loading-fix cu-load loading tree-item-icon"></view>
-
- <!-- 是职员,则显示头像 -->
- <image
- v-else
- class="tree-item-avatar"
- :src="avatar"
- :style="{ borderRadius: roundAvatar ? '50%' : '3px' }"
- mode="aspectFill"
- ></image>
-
- <!-- 名称 -->
- <!-- <text class="tree-item-title">{{ name }}</text> -->
- <text class="tree-item-title">{{ name + (mobile ? '(' +mobile + ')' : "") }}</text>
-
- <!-- 非用户,显示后置标题 -->
- <l-tag v-if="root.type !== 'user' || staffTag" :line="tagColor" size="sm" class="margin-left-sm">
- {{ tagName }}
- </l-tag>
-
- <uni-view v-if="root.type === 'user' && mobile" class="margin-left-sm sm line-gray cu-tag" style="z-index: 1;" @tap="copy(mobile)">复制</uni-view>
-
- <!-- 开启按钮显示且级别对应,则显示按钮 -->
- <view v-if="button && root.type === level" class="tree-item-action">
- <l-button v-if="!selectIds.includes(root.id)" @click="itemClick(root)" line="green" size="sm">选择</l-button>
- <l-button v-else @click="itemClick(root)" line="blue" size="sm">取消选择</l-button>
- </view>
- </view>
-
- <!-- 子节点列表;非用户节点且已加载完毕时显示 -->
- <view
- v-if="root.type !== 'user' && isLoadOk"
- v-show="isOpen"
- :style="{ paddingLeft: root.id === '0' ? '0' : '25rpx' }"
- class="tree-item-children"
- >
- <l-organize-tree
- v-for="child of children"
- @userClick="$emit('userClick', $event)"
- @buttonClick="$emit('buttonClick', $event)"
- :key="child.id"
- :open="root.id === '0'"
- :root="child"
- :button="button"
- :level="level"
- :value="value"
- />
- </view>
- </view>
- </template>
-
- <script>
- import uniCopy from "@/common/js/uni-copy.js"
- export default {
- name: 'l-organize-tree',
-
- props: {
- root: { default: () => ({ type: 'company', id: '0' }) },
- level: { default: 'user' },
- button: {},
- open: { default: true },
- value:{},
- },
-
- data() {
- return {
- isOpen: this.open,
- isLoading: false,
- isLoadOk: false,
- isEmpty: false,
- children: [],
- selectIds:[]
- }
- },
-
- async created() {
- await this.init()
- },
-
- methods: {
- // 组件被创建
- async init() {
- if(this.value){
- this.selectIds = this.value.split(",")
- }
- // 如果自己是根节点,则创建时直接加载子节点
- if (this.open) {
- await this.loadChildren()
- }
- },
-
- // 自身被点击,如果不是用户节点则收起/展开 (如果没有加载子节点则还需加载),否则触发点击用户的事件
- selfClick() {
- if (this.isLoading) {
- return
- }
-
- if (this.root.type === 'user') {
- this.$emit('userClick', this.root)
- return
- }
-
- if (this.isLoadOk) {
- this.isOpen = !this.isOpen
- return
- }
-
- this.loadChildren()
- },
-
- itemClick(root){
- if(this.selectIds.indexOf(root.id) !== -1){
- this.selectIds.splice(this.selectIds.indexOf(root.id),1)
- }else{
- this.selectIds.push(root.id)
- }
- this.$emit('buttonClick', root)
- },
-
- // 加载子节点
- async loadChildren() {
- this.isLoading = true
-
- let children = []
- // 只有公司/根节点能加载子公司
- if (this.root.type === 'company') {
- children = children.concat(
- Object.entries(this.GET_GLOBAL('company'))
- .filter(([id, item]) => item.parentId === this.root.id)
- .map(([id, item]) => ({ ...item, id, type: 'company' }))
- )
- }
-
- // 加载子部门
- if (this.level === 'department' || this.level === 'user') {
- console.log(this.level,'level')
- if(this.root.type == 'company'){
- children = children.concat(
- Object.entries(this.GET_GLOBAL('department'))
- .filter(([id, item]) => item.companyId === this.root.id && (Number(item.parentId) == -1||Number(item.parentId) == 0))
- .map(([id, item]) => ({ ...item, id, type: 'department' }))
- )
- }
- else{
- children = children.concat(
- Object.entries(this.GET_GLOBAL('department'))
- .filter(([id, item]) => item.companyId === this.root.companyId && (item.parentId == this.root.id ))
- .map(([id, item]) => ({ ...item, id, type: 'department' }))
- )
- }
- }
-
- // 加载子职员
- if (this.level === 'user') {
- children = children.concat(
- Object.entries(this.GET_GLOBAL('user'))
- .filter(
- ([id, item]) =>
- this.root.id ===
- (item.departmentId && Number(item.departmentId) !== 0 ? item.departmentId : item.companyId)
- )
- .map(([id, item]) => ({ ...item, id, type: 'user' }))
- )
- }
-
- this.children = children
-
- this.isLoadOk = true
- this.isOpen = true
- this.isLoading = false
- },
-
- copy(mobile){
- uniCopy({
- content:mobile,
- success:(res)=>{
- uni.showToast({
- title: "复制手机号成功~",
- icon: 'none',
- duration:3000,
- })
- },
- error:(e)=>{
- uni.showToast({
- title: e,
- icon: 'none',
- duration:3000,
- })
- }
- })
- }
- },
-
- computed: {
- // 获取用户头像
- avatar() {
- if (!Number.isNaN(this.root.img)) {
- return Number(this.root.img) === 1 ? '/static/img-avatar/chat-boy.jpg' : '/static/img-avatar/chat-girl.jpg'
- }
-
- return this.root.img
- },
-
- // 是否在职员一级显示标签
- staffTag() {
- return this.CONFIG('pageConfig.contact.staffTag')
- },
-
- // 获取树形列表每一项后面 tag 的显示
- tagName() {
- return { user: '职员', department: '部门', company: '公司' }[this.root.type]
- },
-
- // 获取 tag 的颜色
- tagColor() {
- return { company: 'red', department: 'blue', user: 'green' }[this.root.type]
- },
-
- // 节点名称
- name() {
- if (this.root.name) {
- return this.root.name
- }
-
- const rootItem = this.GET_GLOBAL(this.root.type)[this.root.id]
- return rootItem ? rootItem.name : '(根节点)'
- },
- mobile() {
- if (this.root.mobile) {
- return this.root.mobile
- }
-
- const rootItem = this.GET_GLOBAL(this.root.type)[this.root.id]
- return rootItem ? rootItem.mobile: '(根节点)'
- },
-
- // 头像圆形/方形显示参数
- roundAvatar() {
- return this.CONFIG('pageConfig.roundAvatar')
- }
- }
- }
- </script>
-
- <style lang="less" scoped>
- :host {
- display: block;
- }
-
- .tree-item {
- background-color: #fff;
-
- .tree-item-self {
- display: flex;
- min-height: 65rpx;
- align-items: center;
-
- .tree-item-icon {
- margin: 0 30rpx;
- line-height: 1em;
- }
-
- .tree-item-avatar {
- width: 60rpx;
- height: 60rpx;
- margin-top: 8rpx;
- margin-bottom: 8rpx;
- margin-left: 30rpx;
- margin-right: 16rpx;
- }
-
- .tree-item-action {
- position: absolute;
- right: 30rpx;
- }
- }
- }
- </style>
|