| | |
| | | <div class="voiceCallContainer" :style="{ paddingTop: topMargin + 'px' }"> |
| | | <!-- 顶部搜索栏 --> |
| | | <div class="searchBar"> |
| | | <up-search placeholder="请输入关键字搜索" :animation="true" :show-action="false"></up-search> |
| | | <up-search placeholder="请输入关键字搜索" v-model="defaultParam.friendNickName" :animation="true" :show-action="false" @confirm="onSearch" @search="onSearch" @clear="handleClear"></up-search> |
| | | </div> |
| | | |
| | | <!-- 联系人列表 --> |
| | | <div class="contactList"> |
| | | <div |
| | | class="contactItem" |
| | | v-for="(contact, index) in filteredContacts" |
| | | :key="index" |
| | | > |
| | | <div class="itemBox"> |
| | | <!-- 头像 --> |
| | | <div class="contactAvatar"> |
| | | <image :src="contact.avatar" mode="aspectFill" /> |
| | | </div> |
| | | <div class="contactList" @scrolltolower="onScrollToLower"> |
| | | <div |
| | | class="contactItem" |
| | | v-for="(contact, index) in contacts" |
| | | :key="index" |
| | | > |
| | | <div class="itemBox"> |
| | | <!-- 头像 --> |
| | | <div class="contactAvatar"> |
| | | <image :src="contact.avatar || defaultAvatar" /> |
| | | </div> |
| | | |
| | | <!-- 联系人信息 --> |
| | | <div class="contactInfo"> |
| | | <div class="contactName">{{ contact.name }}</div> |
| | | <div class="contactDept">{{ contact.dept }}</div> |
| | | </div> |
| | | <!-- 联系人信息 --> |
| | | <div class="contactInfo"> |
| | | <div class="contactName">{{ contact.friendNickName || '未知联系人' }}</div> |
| | | <div class="contactDept">{{ contact.deptName || '未知部门' }}</div> |
| | | </div> |
| | | |
| | | <!-- 电话按钮 --> |
| | | <div class="callButton" @click="makeCall(contact)"> |
| | | <image src="@/static/images/voiceVal/phoneVal.svg" mode="aspectFit" /> |
| | | </div> |
| | | </div> |
| | | <!-- 电话按钮 --> |
| | | <div class="callButton" @click="makeCall(contact)"> |
| | | <image src="@/static/images/voiceVal/phoneVal.svg" /> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 加载提示 --> |
| | | <div class="loadingMore"> |
| | | <text v-if="loading">加载中...</text> |
| | | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getStatusBarHeight } from '@/utils/common'; |
| | | |
| | | const topMargin = getStatusBarHeight() |
| | | |
| | | // 搜索关键字 |
| | | const searchKeyword = ref('') |
| | | |
| | | import { getPhoneBookListApi } from '@/api/voiceCall/index.js' |
| | | import { onShow } from '@dcloudio/uni-app' |
| | | import defaultAvatar from '/static/images/defaultAvatar.svg' |
| | | // 联系人数据 |
| | | const contacts = ref([ |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | { name: '张晓晓', dept: '吉州区应急部门', avatar: '/static/images/tabbar/icon_me.png' }, |
| | | ]) |
| | | |
| | | // 过滤后的联系人列表 |
| | | const filteredContacts = computed(() => { |
| | | if (!searchKeyword.value) { |
| | | return contacts.value |
| | | } |
| | | return contacts.value.filter(contact => { |
| | | return contact.name.includes(searchKeyword.value) || |
| | | contact.dept.includes(searchKeyword.value) |
| | | }) |
| | | const contacts = ref([]) |
| | | const defaultParam = ref({ |
| | | current: 1, |
| | | size: 10, |
| | | friendNickName: '' |
| | | }) |
| | | |
| | | // 加载状态 |
| | | const loading = ref(false) |
| | | const hasMore = ref(true) |
| | | |
| | | // 获取通讯录 |
| | | const getPhoneBookList = () => { |
| | | if (loading.value || !hasMore.value) return |
| | | loading.value = true |
| | | // 添加分页参数 |
| | | const params = { |
| | | current: defaultParam.value.current, |
| | | size: defaultParam.value.size, |
| | | friendNickName: defaultParam.value.friendNickName |
| | | } |
| | | |
| | | getPhoneBookListApi(params).then(res => { |
| | | const response = res.data.data |
| | | if (defaultParam.value.current === 1) { |
| | | contacts.value = response.records |
| | | } else { |
| | | contacts.value = [...contacts.value, ...response.records] |
| | | } |
| | | |
| | | // 判断是否还有更多数据 |
| | | if (response.records.length < defaultParam.value.size || response.current >= response.pages) { |
| | | hasMore.value = false |
| | | } else { |
| | | hasMore.value = true |
| | | } |
| | | |
| | | }).catch(err => { |
| | | console.error('获取通讯录失败:', err) |
| | | const errorMsg = err.msg || err.message || '获取通讯录失败' |
| | | uni.showToast({ |
| | | title: errorMsg, |
| | | icon: 'none', |
| | | duration: 3000 |
| | | }) |
| | | }).finally(() => { |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | // 加载更多 |
| | | const loadMore = () => { |
| | | if (loading.value || !hasMore.value) return |
| | | |
| | | defaultParam.value.current++ |
| | | getPhoneBookList() |
| | | } |
| | | const onSearch = () => { |
| | | defaultParam.value.current = 1 |
| | | hasMore.value = true |
| | | getPhoneBookList() |
| | | |
| | | } |
| | | const handleClear = () => { |
| | | defaultParam.value.friendNickName = '' |
| | | defaultParam.value.current = 1 |
| | | hasMore.value = true |
| | | getPhoneBookList() |
| | | } |
| | | // 拨打电话方法 |
| | | const makeCall = (contact) => { |
| | | console.log('拨打电话给', contact.name) |
| | | // 这里可以添加实际的拨打电话逻辑 |
| | | uni.showToast({ |
| | | title: `正在拨打${contact.name}的电话`, |
| | | icon: 'none' |
| | | console.log('拨打电话', contact) |
| | | // 将contact对象转换为JSON字符串并URL编码 |
| | | const contactStr = encodeURIComponent(JSON.stringify(contact)) |
| | | uni.navigateTo({ |
| | | url: `/subPackages/voiceCallDetail/index?contact=${contactStr}`, |
| | | }) |
| | | } |
| | | |
| | | onShow(() => { |
| | | // 重置分页参数 |
| | | defaultParam.value.current = 1 |
| | | hasMore.value = true |
| | | getPhoneBookList() |
| | | }); |
| | | |
| | | // 监听滚动到底部 |
| | | const onScrollToLower = () => { |
| | | loadMore() |
| | | } |
| | | </script> |
| | | |
| | |
| | | } |
| | | |
| | | .searchBar { |
| | | padding: 20rpx; |
| | | padding: 20rpx 20rpx 0 20rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | height: 108rpx; |
| | | :deep(){ |
| | | .u-search__content{ |
| | | background: #fff !important; |
| | | } |
| | | .u-search__content__input{ |
| | | background: #fff !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .contactList { |
| | | margin: 0 24rpx; |
| | | margin: 0 20rpx 20rpx 20rpx; |
| | | background: #fff; |
| | | border-radius: 12rpx ; |
| | | border-radius: 12rpx; |
| | | overflow-y: auto; |
| | | height: 0; |
| | | flex-grow: 1; |
| | |
| | | .contactItem { |
| | | display: flex; |
| | | align-items: center; |
| | | padding:0 24rpx; |
| | | padding: 0 20rpx; |
| | | |
| | | } |
| | | |
| | | .itemBox { |
| | | display: flex; |
| | | align-items: center; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | width:100%; |
| | | width: 100%; |
| | | height: 98rpx; |
| | | border-bottom: 1rpx solid #EBEBEB; |
| | | } |
| | | |
| | | .contactAvatar { |
| | | width: 80rpx; |
| | | height: 80rpx; |
| | |
| | | height: 60rpx; |
| | | |
| | | } |
| | | |
| | | .loadingMore { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 80rpx; |
| | | font-size: 28rpx; |
| | | color: #999; |
| | | } |
| | | </style> |