完成通讯录功能的员工通讯录tab,接入对应的接口、交互组件等

This commit is contained in:
wangyifeng 2025-05-12 17:00:56 +08:00
parent a82875da05
commit 8c9f634d0b
4 changed files with 162 additions and 18 deletions

View File

@ -16,7 +16,7 @@
</div> </div>
</template> </template>
<slot name="content"></slot> <slot name="content"></slot>
<template #footer> <template #footer v-if="actionBtns.cancelBtn || actionBtns.confirmBtn">
<div class="custom-modal-btns"> <div class="custom-modal-btns">
<customBtn <customBtn
color="#C7C7C9" color="#C7C7C9"

View File

@ -2,14 +2,14 @@
<div class="row items-center"> <div class="row items-center">
<div v-if="state.treeData.edit"> <div v-if="state.treeData.edit">
<n-input v-model:value="state.editTitle" <n-input v-model:value="state.editTitle"
style="width:120px" /> style="max-width:200px" />
</div> </div>
<n-popover trigger="hover" <n-popover trigger="hover"
v-else> v-else>
<template #trigger> <template #trigger>
<div style="width:120px" <div style="max-width:200px"
class="fl-px-sm sf-text-ellipsis">{{ state.treeData.title }}</div> class="fl-px-sm sf-text-ellipsis">{{ state.treeData.title + '' + state.treeData.staffNum + '' }}</div>
</template> </template>
<div>{{ state.treeData.title }}</div> <div>{{ state.treeData.title }}</div>
</n-popover> </n-popover>

View File

@ -12,6 +12,7 @@ import {
} from "vue"; } from "vue";
import Sortable from "sortablejs"; import Sortable from "sortablejs";
import { debounce } from "lodash-es"; import { debounce } from "lodash-es";
import { NDataTable } from "naive-ui";
// Props // Props
const props = defineProps({ const props = defineProps({

View File

@ -1,8 +1,27 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref, onMounted, watch, reactive, onBeforeMount, getCurrentInstance } from 'vue' import {
computed,
ref,
onMounted,
watch,
reactive,
onBeforeMount,
getCurrentInstance,
h
} from 'vue'
import { onBeforeRouteUpdate } from 'vue-router' import { onBeforeRouteUpdate } from 'vue-router'
import { useDialogueStore, useTalkStore } from '@/store' import { useDialogueStore, useTalkStore } from '@/store'
import { NDropdown, NIcon, NInput, NPopover, NTabs, NTab, NCard } from 'naive-ui' import {
NDropdown,
NIcon,
NInput,
NPopover,
NTabs,
NTab,
NCard,
NButton,
NPagination
} from 'naive-ui'
import { Search, Plus } from '@icon-park/vue-next' import { Search, Plus } from '@icon-park/vue-next'
import TalkItem from './TalkItem.vue' import TalkItem from './TalkItem.vue'
import Skeleton from './Skeleton.vue' import Skeleton from './Skeleton.vue'
@ -13,11 +32,12 @@ import { ISession } from '@/types/chat'
import { useSessionMenu } from '@/hooks' import { useSessionMenu } from '@/hooks'
import customModal from '@/components/common/customModal.vue' import customModal from '@/components/common/customModal.vue'
import xSearchForm from '@/components/x-naive-ui/x-search-form/index.vue' import xSearchForm from '@/components/x-naive-ui/x-search-form/index.vue'
import xNDataTable from '@/components/x-naive-ui/x-n-data-table/index.vue'
import flTree from '@/components/flnlayout/tree/flnindex.vue' import flTree from '@/components/flnlayout/tree/flnindex.vue'
import { processError, processSuccess } from '@/utils/helper/message.js' import { processError, processSuccess } from '@/utils/helper/message.js'
const currentInstance = getCurrentInstance() const currentInstance = getCurrentInstance()
const { $request } = currentInstance?.appContext.config.globalProperties const $request = currentInstance?.appContext.config.globalProperties?.$request
const { const {
dropdown, dropdown,
@ -52,9 +72,54 @@ const state = reactive({
treeData: [], treeData: [],
expandedKeys: [], expandedKeys: [],
clickKey: '', clickKey: 3,
treeRefreshCount: 0, treeRefreshCount: 0,
treeSelectData: {} treeSelectData: {},
addressBookColumns: [
{
title: '姓名',
field: 'name',
width: 200,
render(row, index) {
return row.nickName
}
},
{
title: '岗位名称',
field: 'positionName',
width: 400,
ellipsis: true,
render(row, index) {
let positionName = row.nowPositions.map((item) => item.name).join(' , ')
return positionName
}
},
{
title: '操作',
field: 'action',
width: 200,
align: 'center',
fixed: 'right',
render(row, index) {
return h(
NButton,
{
size: 'small',
text: true,
color: '#46299d',
onClick: () => handleEnterChat(row)
},
{ default: () => '进入聊天' }
)
}
}
], //
addressBookData: [], //
addressBookTableHeight: 524, //
addressBookTableWidth: 800, //
addressBookPage: 1, //
addressBookPageSize: 10, //
addressBookTotal: 0 //
}) })
const items = computed((): ISession[] => { const items = computed((): ISession[] => {
@ -68,13 +133,16 @@ const items = computed((): ISession[] => {
return keyword.toLowerCase().indexOf(searchKeyword.value.toLowerCase()) != -1 return keyword.toLowerCase().indexOf(searchKeyword.value.toLowerCase()) != -1
}) })
}) })
setTimeout(()=>{ setTimeout(() => {
console.log('items.value',items.value) console.log('items.value', items.value)
},1000) }, 1000)
watch(() => talkStore, (newValue, oldValue) => { watch(
console.log(newValue); () => talkStore,
(newValue, oldValue) => {
},{deep:true,immediate:true}) console.log(newValue)
},
{ deep: true, immediate: true }
)
// //
const loadStatus = computed(() => talkStore.loadStatus) const loadStatus = computed(() => talkStore.loadStatus)
@ -145,8 +213,10 @@ const showAddressBookModal = () => {
state.isShowAddressBookModal = true state.isShowAddressBookModal = true
} }
const handleTreeClick = ({ selectedKey, tree }) => { const handleTreeClick = ({ selectedKey, tree }) => {
console.log(tree)
state.clickKey = tree.key state.clickKey = tree.key
state.treeSelectData = tree state.treeSelectData = tree
getDepPoisUser()
} }
const calcTreeData = (data) => { const calcTreeData = (data) => {
for (let item of data) { for (let item of data) {
@ -194,6 +264,7 @@ const getTreeData = () => {
// } // }
// } // }
state.treeRefreshCount++ state.treeRefreshCount++
getDepPoisUser()
// state.tableConfig.refreshCount++; // state.tableConfig.refreshCount++;
} else { } else {
processError(res.msg || '获取失败!') processError(res.msg || '获取失败!')
@ -207,6 +278,38 @@ const getTreeData = () => {
} }
) )
} }
//
const getDepPoisUser = () => {
let url = '/user/v2/list'
let params = {
departmentId: state.clickKey,
page: state.addressBookPage,
pageSize: state.addressBookPageSize,
status: 'notactive'
}
$request.HTTP.components.postDataByParams(url, params).then((res) => {
console.log(res)
if (res.status === 0 && Array.isArray(res.data.data)) {
state.addressBookData = res.data.data || []
state.addressBookTotal = res.data.count
}
})
}
//
const handleEnterChat = (row) => {
console.log(row)
}
//
const handleAddressBookPagination = (page) => {
state.addressBookPage = page
getDepPoisUser()
}
//
const handleAddressBookPaginationSize = (pageSize) => {
state.addressBookPageSize = pageSize
state.addressBookPage = 1
getDepPoisUser()
}
</script> </script>
<template> <template>
@ -290,7 +393,6 @@ const getTreeData = () => {
<main id="talk-session-list" class="el-main me-scrollbar me-scrollbar-thumb"> <main id="talk-session-list" class="el-main me-scrollbar me-scrollbar-thumb">
<template v-if="loadStatus == 2"><Skeleton /></template> <template v-if="loadStatus == 2"><Skeleton /></template>
<template v-else> <template v-else>
<TalkItem <TalkItem
v-for="item in items" v-for="item in items"
:key="item.index_name" :key="item.index_name"
@ -317,7 +419,7 @@ const getTreeData = () => {
> >
<template #content> <template #content>
<div class="custom-modal-content"> <div class="custom-modal-content">
<n-card> <n-card style="padding: 0 12px;">
<n-tabs type="line"> <n-tabs type="line">
<n-tab name="employeeAddressBook">员工通讯录</n-tab> <n-tab name="employeeAddressBook">员工通讯录</n-tab>
<n-tab name="groupChatList">群聊列表</n-tab> <n-tab name="groupChatList">群聊列表</n-tab>
@ -333,6 +435,31 @@ const getTreeData = () => {
@triggerTreeClick="handleTreeClick" @triggerTreeClick="handleTreeClick"
></fl-tree> ></fl-tree>
</div> </div>
<div class="addressBook-table">
<xNDataTable
:columns="state.addressBookColumns"
:data="state.addressBookData"
:style="{
height: `${state.addressBookTableHeight}px`,
width: `${state.addressBookTableWidth}px`
}"
flex-height
></xNDataTable>
<div class="addressBook-pagination">
<n-pagination
v-model:page="state.addressBookPage"
v-model:page-size="state.addressBookPageSize"
:item-count="state.addressBookTotal"
show-quick-jumper
show-size-picker
:page-sizes="[10, 20, 50]"
:on-update:page="handleAddressBookPagination"
:on-update:page-size="handleAddressBookPaginationSize"
>
<template #prefix="{ itemCount }"> {{ itemCount }} 条记录 </template>
</n-pagination>
</div>
</div>
</div> </div>
</n-card> </n-card>
</div> </div>
@ -447,6 +574,9 @@ html[theme-mode='dark'] {
width: 100%; width: 100%;
padding: 0 12px; padding: 0 12px;
.addressBook-content { .addressBook-content {
display: flex;
flex-direction: row;
gap: 20px;
.addressBook-tree { .addressBook-tree {
width: 328px; width: 328px;
height: 524px; height: 524px;
@ -456,6 +586,19 @@ html[theme-mode='dark'] {
padding: 12px 20px; padding: 12px 20px;
box-sizing: border-box; box-sizing: border-box;
} }
.addressBook-table {
:deep(.n-data-table-th) {
background-color: #46299d;
color: #fff;
}
.addressBook-pagination {
display: flex;
justify-content: flex-end;
align-items: center;
padding: 22px 0 0;
box-sizing: border-box;
}
}
} }
} }
</style> </style>