Commit a40e2553 by pangchong

feat: 联系人列表

parent 3a140a03
export const CallState = {
callIn: 'callIn',
callOut: 'callout',
calling: 'calling',
idle: 'idle'
}
export const videoGroup = {
0: '专家',
1: '维修人'
......
import { defineStore } from 'pinia'
import { ContactsState, UserItemDto } from './types'
const CallState = {
callIn: 'callIn',
callOut: 'callout',
calling: 'calling',
idle: 'idle'
}
import { userStates } from 'AnyR/states/wsStates'
const useContactsStore = defineStore('contacts', {
state: (): ContactsState => {
return {
......@@ -16,7 +11,32 @@ const useContactsStore = defineStore('contacts', {
},
getters: {
//获取通话用户
//获取合并ws后的所有用户列表
getAllOnlineContacts(state) {
const userList = [] as UserItemDto[]
state.userList.forEach((item1) => {
userStates.value.onlineContacts.forEach((item2: any) => {
if (item1.id == item2.fromID) {
Object.assign(item1, item2)
}
})
userList.push(item1)
})
return userList
},
//获取ws的用户列表
getOnlineContacts(state) {
const userList = [] as UserItemDto[]
userStates.value.onlineContacts.forEach((item1: any) => {
state.userList.forEach((item2) => {
if (item1.fromID == item2.id) {
Object.assign(item1, item2)
}
})
userList.push(item1)
})
return userList
}
},
actions: {
......
......@@ -4,6 +4,7 @@ export interface UserItemDto {
remark: string
videoGroup: 0 | 1
choose?: boolean
[propName: string]: any
}
export interface ContactsState {
showWait: boolean
......
......@@ -2,12 +2,12 @@
<a-spin class="g-block" :loading="loading" tip="加载中...">
<div class="flex justify-between items-center h-10 px-4">
<span class="text-base">联系人</span>
<a-checkbox value="1">只显示在线人员</a-checkbox>
<a-checkbox v-model="searchParams.isOnline">只显示在线人员</a-checkbox>
</div>
<a-tabs class="h-full">
<a-tab-pane title="默认列表">
<div class="px-4">
<a-input-search placeholder="搜索" v-model="searchParams.groupName"></a-input-search>
<a-input-search placeholder="搜索" v-model="searchParams.userName"></a-input-search>
<a-button class="rounded-full my-4" type="primary" long @click="multiCall">
<template #icon>
<global-icon icon="plus-circle" :size="14" color="var(--color-bg-white)" />
......@@ -37,6 +37,7 @@ import type { UserItemDto } from '@/store/contacts/types'
import useContactsStore from '@/store/contacts/index'
import { useRequest } from 'alova'
import { videoGroup } from '@/constants/common/user'
import { storeToRefs } from 'pinia'
interface Props {
showGroup?: boolean
......@@ -48,11 +49,7 @@ const ps = withDefaults(defineProps<Props>(), {
const getShowGroup = computed(() => {
return ps.showGroup ? 'block' : 'none'
})
const {
loading,
data: userList,
onSuccess
} = useRequest(
const { loading, data, onSuccess } = useRequest(
() =>
alova.Post(
'/admin/getUserListVideo',
......@@ -69,24 +66,34 @@ const {
}
)
const { setUserList } = useContactsStore()
const { getAllOnlineContacts, getOnlineContacts } = storeToRefs(useContactsStore())
onSuccess(({ data }) => {
setUserList(data)
})
const searchParams = reactive({
groupName: ''
userName: '',
isOnline: false
})
//获取联系人分组
const getUserListGroup = computed(() => {
return userList.value
return getAllOnlineContacts.value
?.sort((a, b) => a.videoGroup - b.videoGroup)
?.reduce((result: any, item) => {
const groupName = videoGroup[item.videoGroup]
if (!result[groupName]) {
result[groupName] = []
}
if (item.nickname.indexOf(searchParams.groupName) != -1) {
// 名字搜索
if (item.nickname.indexOf(searchParams.userName) != -1) {
if (searchParams.isOnline) {
//在线人员
if (getOnlineContacts.value.find((_item) => _item.id == item.id)) {
result[groupName].push(item)
}
} else {
result[groupName].push(item)
}
}
return result
}, {})
})
......
......@@ -8,7 +8,9 @@
<global-icon icon="mic" :size="14"></global-icon>
</div>
<div class="flex-auto text-right">
<a-button type="primary" shape="circle" @click.stop="changeWait(true)"><global-icon icon="phone" :size="14" color="var(--color-bg-white)"></global-icon></a-button>
<a-button type="primary" shape="circle" @click.stop="changeWait(true)" :disabled="!(item.callState == 'callState' && item.hasCamera == 1 && item.hasMike == 1)">
<global-icon icon="phone" :size="14" color="var(--color-bg-white)"></global-icon>
</a-button>
</div>
</div>
</template>
......
......@@ -21,7 +21,7 @@ interface Props {
const ps = withDefaults(defineProps<Props>(), {
data: () => []
})
const checkbox = defineModel()
const checkbox = defineModel<string[]>()
</script>
<style lang="less" scoped>
.item.active,
......
......@@ -7,7 +7,7 @@
</div>
<!-- table展示 -->
<div class="flex-auto overflow-y-auto px-4">
<a-table :columns="columns" :data="tableData" :bordered="false" :loading="loading">
<a-table :columns="columns" :data="tableData" :bordered="false" :loading="loading" :pagination="false">
<template #initiator="{ record }">
<div class="flex items-center">
<global-avatar :avatar-size="24" :icon-size="12"></global-avatar>
......@@ -19,6 +19,9 @@
</template>
</a-table>
</div>
<div class="px-4">
<a-pagination class="justify-end" show-total show-page-size :total="total!" v-model:current="page" v-model:page-size="pageSize" />
</div>
</div>
</template>
......@@ -84,7 +87,7 @@ const {
initialPageSize: 10, // 初始每页数据条数,默认为10
debounce: [800],
abortLast: true,
total: (res) => res.data.total,
total: (res) => parseInt(res.data.total),
data: (res) => res.data.list,
sendable: () => {
return chooseUser?.value?.id ? true : false
......
......@@ -3,12 +3,12 @@
<div class="h-80 overflow-y-auto">
<a-collapse :bordered="false">
<a-collapse-item :header="key + '列表'" :key="index" v-for="(value, key, index) in getUserListGroup">
<contacts-list-choose :data="value" v-model="chooseUsers"></contacts-list-choose>
<contacts-list-choose :data="value" v-model="chooseUserIds"></contacts-list-choose>
</a-collapse-item>
</a-collapse>
</div>
<template #footer>
<a-button size="large" type="primary" @click="showModel = false" :disabled="chooseUsers.length == 0">呼叫{{ chooseUsers.length }}</a-button>
<a-button size="large" type="primary" @click="showModel = false" :disabled="chooseUserIds.length == 0">呼叫{{ chooseUserIds.length }}</a-button>
<a-button size="large" @click="showModel = false">取消</a-button>
</template>
</global-model>
......@@ -17,30 +17,32 @@
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import useContactsStore from '@/store/contacts/index'
import { UserItemDto } from '@/store/contacts/types'
import contactsListChoose from './contactsListChoose.vue'
import { cloneDeep } from 'lodash'
import { videoGroup } from '@/constants/common/user'
//选中的联系人数组id
const chooseUsers = ref([])
const chooseUserIds = ref([])
const showModel = ref(false)
const open = () => {
showModel.value = true
chooseUsers.value = []
chooseUserIds.value = []
}
//当前联系人
const { userList } = storeToRefs(useContactsStore())
//所有联系人
const { getAllOnlineContacts, getOnlineContacts } = storeToRefs(useContactsStore())
//获取联系人分组
const getUserListGroup = computed(() => {
return cloneDeep(userList.value)
return cloneDeep(getAllOnlineContacts.value)
?.sort((a, b) => a.videoGroup - b.videoGroup)
?.reduce((result: any, item) => {
const groupName = videoGroup[item.videoGroup]
if (!result[groupName]) {
result[groupName] = []
}
//在线人员
if (getOnlineContacts.value.find((_item) => _item.id == item.id)) {
result[groupName].push(item)
}
return result
}, {})
})
......
......@@ -16,22 +16,29 @@
import VideoItem from './videoItem.vue'
import { IconLeft, IconRight } from '@arco-design/web-vue/es/icon'
const slidePosition = ref(0)
const sliderWidth = ref(150) //滑块宽度
const slidePosition = ref(0) //初始位置
const slideDistance = 150 // 滑动距离
const animationDuration = 500 // 动画持续时间(毫秒)
//动画效果
const sliderStyles = computed(() => {
return {
transform: `translateX(${slidePosition.value}px)`,
transition: `transform ${animationDuration}ms`
}
})
//点击左滑
const slideLeft = () => {
slidePosition.value += slideDistance
}
//点击右滑
const slideRight = () => {
slidePosition.value -= slideDistance
}
//获取宽度
const getSliderWidth = computed(() => {
return sliderWidth.value + 'px'
})
</script>
<style lang="less" scoped>
.slider-container {
......@@ -41,7 +48,7 @@ const slideRight = () => {
white-space: nowrap;
position: relative;
.slider-item {
width: 150px;
width: v-bind('getSliderWidth');
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment