jiuyiUniapp/jiuyi2/components/news/book.vue

527 lines
9.2 KiB
Vue
Raw Normal View History

2024-12-18 15:46:27 +08:00
<script setup>
2025-02-20 15:12:53 +08:00
/**
* 通讯录
*/
import {
useStore,
} from 'vuex'
import {
ref,
computed,
reactive,
onMounted,
onUnmounted,
inject,
getCurrentInstance,
} from 'vue'
// 工具库
import util from '@/common/js/util.js'
// 腾讯云聊天
import TencentCloudChat from '@tencentcloud/chat';
// api
import api from '@/api/index.js'
import pinyin from 'js-pinyin'
import {
forEach
} from 'lodash';
const {
proxy
} = getCurrentInstance();
const store = useStore()
const userinfo = computed(() => {
let result = store.state.userinfo
return result
})
const msgType = {}
// 用户列表
const userList = reactive({
data: [],
pageNum: 1,
pageSize: 10,
total: 0,
})
// 当前操作的用户
let user = reactive({})
// 列表下标
const listKey = ref('')
// 字母列表
const letterList = [{
key: 'other',
name: '#',
},
{
key: 'a',
name: 'A',
},
{
key: 'b',
name: 'B',
},
{
key: 'c',
name: 'C',
},
{
key: 'd',
name: 'D',
},
{
key: 'e',
name: 'E',
},
{
key: 'f',
name: 'F',
},
{
key: 'g',
name: 'G',
},
{
key: 'h',
name: 'H',
},
{
key: 'i',
name: 'I',
},
{
key: 'j',
name: 'J',
},
{
key: 'k',
name: 'K',
},
{
key: 'l',
name: 'L',
},
{
key: 'm',
name: 'M',
},
{
key: 'n',
name: 'N',
},
{
key: 'o',
name: 'O',
},
{
key: 'p',
name: 'P',
},
{
key: 'q',
name: 'Q',
},
{
key: 'r',
name: 'R',
},
{
key: 's',
name: 'S',
},
{
key: 't',
name: 'T',
},
{
key: 'u',
name: 'U',
},
{
key: 'v',
name: 'V',
},
{
key: 'w',
name: 'W',
},
{
key: 'x',
name: 'X',
},
{
key: 'y',
name: 'Y',
},
{
key: 'z',
name: 'Z',
},
]
// 是否移动
const touchmove = ref(false)
// 字母列表dom属性
const letterDom = reactive({
itemHeight: 0,
minHeight: 0,
maxHeight: 0,
height: 0,
})
// 右滑菜单
const rightOption = [{
text: '删除',
style: {
backgroundColor: '#F85050'
},
fn: (user) => delFriend(user),
},
// {
// text: '修改备注',
// style: {
// backgroundColor: '#10C100'
// },
// fn: (user) => setFriendNote(user),
// },
]
onMounted(() => {
// 获取朋友列表
getFriendList()
// 获取字母属性
getLetterProperty()
// 添加监听
addlistener()
2024-12-18 15:46:27 +08:00
2025-02-20 15:12:53 +08:00
// proxy.$refs.note.open()
})
2024-12-18 15:46:27 +08:00
2025-02-20 15:12:53 +08:00
onUnmounted(() => {
removelistener()
})
2024-12-18 15:46:27 +08:00
2025-02-20 15:12:53 +08:00
const viewData = ref([])
2024-12-18 15:46:27 +08:00
2025-02-20 15:12:53 +08:00
// 添加加好友监听
function addlistener() {
let onFriendListUpdated = (event) => {
console.log('onFriendListUpdated', event.data);
getFriendList()
2024-12-18 15:46:27 +08:00
}
2025-02-20 15:12:53 +08:00
// #ifdef APP
uni.$chat.on(TencentCloudChat.EVENT.FRIEND_LIST_UPDATED, onFriendListUpdated);
// #endif
}
// 移除加好友监听
function removelistener() {
// #ifdef APP
uni.$chat.off(TencentCloudChat.EVENT.FRIEND_LIST_UPDATED, () => { });
// #endif
}
// 获取朋友列表
function getFriendList() {
//
api.news.getFriendList().then(rs => {
if (rs.code == 200) {
const result = rs.data
userList.data.length = 0
userList.data = handleUserList(result)
2024-12-18 15:46:27 +08:00
return
}
2025-02-20 15:12:53 +08:00
util.alert({
content: rs.msg,
showCancel: false,
})
})
}
/**
* 用户列表排序
* @param {Object} userList
*/
function handleUserList(userList) {
// 筛选后的用户列表
const userArr = []
// 遍历用户列表
for (let i = 0; i < userList.length; i++) {
const user = userList[i]
// 取拼音
let char = pinyin.getCamelChars(user.remark || user.userNickname);
// 假设姓名的第一个字符为姓氏
const letter = char.charAt(0)
// 下标
let find_index = userArr.findIndex(item => {
return item.key === letter
2024-12-18 15:46:27 +08:00
})
2025-02-20 15:12:53 +08:00
// 未找到追加整过数组 找到追加到子数组
if (find_index == -1) {
userArr.push({
letter: letter,
key: letter,
child: [user]
2025-02-11 09:34:58 +08:00
})
2025-02-20 15:12:53 +08:00
} else {
userArr[find_index].child.push(user)
2025-02-11 09:34:58 +08:00
}
2024-12-18 15:46:27 +08:00
}
2025-02-20 15:12:53 +08:00
// 按照姓氏的字典序对二维数组进行排序
// userArr.sort((a, b) => {
// const surnameA = a.key;
// const surnameB = b.key;
// return surnameA.localeCompare(surnameB);
// });
return userArr;
}
// 获取
function getLetterProperty() {
const query = uni.createSelectorQuery().in(proxy);
query.select(".letterBox").boundingClientRect((data) => {
letterDom.minHeight = data.top
letterDom.height = data.height
letterDom.maxHeight = data.bottom
letterDom.itemHeight = data.height / letterList.length
}).exec();
}
// 手指触摸开始
function handleTouchStart(ev) {
touchmove.value = true
}
// 手指触摸移动
function handleTouchMove(ev) {
if (!touchmove.value) return
// 判断临界值
let result = ev.touches[0].pageY
result = Math.max(result, letterDom.minHeight)
result = Math.min(result, letterDom.maxHeight)
// 计算当前在那个下标
let index = Math.floor(result - letterDom.minHeight) / letterDom.itemHeight
index = parseInt(index)
// 修改下标
listKey.value = letterList[index].key
}
// 手指触摸结束
function handleTouchEnd(ev) {
touchmove.value = false
}
/**
* 点击字母
* @param {Object} item 点击的当前项
*/
function handleLetter(item) {
listKey.value = item.key
}
/**
* 右滑菜单
* @param {Object} ev 默认事件
* @param {Object} user 用户信息
*/
function handleSwipeAction(ev, user) {
ev.content.fn(user)
proxy.$refs.swipeAction.closeAll()
}
/**
* 删除好友
* @param {Object} user 需要删除的好友信息
*/
function delFriend(user) {
new Promise((resolve, reject) => {
util.alert({
content: `确认删除好友${user.remark || user.userNickname}`
}).then(res => {
if (!res.confirm) return
return resolve()
2024-12-18 15:46:27 +08:00
})
2025-02-20 15:12:53 +08:00
}).then(rs => {
api.news.deleteFriend({
2024-12-18 15:46:27 +08:00
query: {
2025-02-20 15:12:53 +08:00
toUserIds: user.userId,
},
2024-12-18 15:46:27 +08:00
}).then(rs => {
if (rs.code === 200) {
2025-02-20 15:12:53 +08:00
// 获取朋友列表
getFriendList()
2024-12-18 15:46:27 +08:00
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
2025-02-20 15:12:53 +08:00
})
}
/**
* 设置好友备注
* @param {Object} ev 需要操作的好友信息
*/
function setFriendNote(ev) {
// 合并用户信息
Object.assign(user, ev)
// 打开设置用户备注弹窗
setTimeout(() => {
proxy.$refs.note.open()
}, 50)
}
// 设置好友备注
function handleSaveNote() {
api.news.setNotes({
query: {
name: user.note || '',
friendId: user.userId,
}
}).then(rs => {
if (rs.code === 200) {
proxy.$refs.note.close()
//
refreshFriendList()
return
}
2025-01-07 21:09:52 +08:00
2025-02-20 15:12:53 +08:00
util.alert({
content: rs.msg,
showCancel: false,
2025-01-07 21:09:52 +08:00
})
2025-02-20 15:12:53 +08:00
})
}
/**
* 点击用户
* @param {Object} user 当前用户信息
*/
function handleUser(user) {
util.toChat({
name: user.remark || user.userNickname,
msgId: user.userId,
type: 'C2C',
})
}
/**
* 跳转
* @param {Object} url
*/
function link(url) {
uni.navigateTo({
url,
})
}
2024-12-18 15:46:27 +08:00
</script>
<template>
<view class="firendBox pr">
<scroll-view scroll-y="true" class="scroll" :scroll-into-view="listKey">
2025-01-07 21:09:52 +08:00
<!-- 菜单 -->
<view class="menu oh c333 f34">
<view class="rows ptb20 plr30 bfff" @click="link('/pages/news/newFriend')">
2025-01-08 21:01:16 +08:00
<view class="">新朋友</view>
2025-01-07 21:09:52 +08:00
<uni-icons type="right" color="#999" size="30rpx" />
</view>
2025-03-10 08:52:36 +08:00
<view class="rows ptb20 plr30 bfff" @click="link('/pages/news/group/chatList')">
2025-01-07 21:09:52 +08:00
<view class="">群聊列表</view>
<uni-icons type="right" color="#999" size="30rpx" />
</view>
</view>
2024-12-18 15:46:27 +08:00
<uni-swipe-action ref="swipeAction">
<view class="list pb30">
<view class="li" v-for="(item, index) in userList.data" :key="item.key" :id="item.key">
<view class="letter ptb10 plr30 c666 f20">{{ item.letter }}</view>
<view class="child pl30 pr50">
2025-01-06 09:45:10 +08:00
<uni-swipe-action-item :right-options="rightOption" v-for="(user, secIndex) in item.child"
2025-02-20 15:12:53 +08:00
:key="secIndex" @click="handleSwipeAction($event, user)">
2024-12-18 15:46:27 +08:00
<view class="item rows ptb20" @click="handleUser(user)">
2025-01-07 21:09:52 +08:00
<image class="wh80 avatar cir" :src="user.avatar" mode="aspectFill" />
2025-02-20 15:12:53 +08:00
<view class="name thd f1 ml20 c333 f32">{{ user.remark || user.userNickname }}</view>
2024-12-18 15:46:27 +08:00
</view>
</uni-swipe-action-item>
</view>
</view>
<view class="mtb20 nomore">到底啦~</view>
</view>
</uni-swipe-action>
</scroll-view>
<!-- 字母列表 -->
2025-01-06 09:45:10 +08:00
<view class="letterBox c666 f22" @touchstart="handleTouchStart" @touchmove.stop.prevent="handleTouchMove"
@touchend="handleTouchEnd">
<view class="item fmid ptb5 plr20" v-for="(item, index) in letterList" :key="item"
@click="handleLetter(item)">{{ item.name }}</view>
2024-12-18 15:46:27 +08:00
</view>
</view>
<!-- 好友备注 -->
<uni-popup ref="note" type="bottom" mask-background-color="rgba(0,0,0,0)">
<view class="noteAlt popBot plr25 bfff">
<view class="header rows ptb20">
2025-02-20 15:12:53 +08:00
<view class="title c333 f34">设置好友({{ user.remark }})备注</view>
2024-12-18 15:46:27 +08:00
<uni-icons type="closeempty" size="40rpx" @click="$refs.note.close()" />
</view>
<view class="content mt30 plr30">
<input class="input" v-model="user.note" placeholder="请输入好友备注" />
</view>
<view class="btn lg black mtb30" @click="handleSaveNote">保存</view>
</view>
</uni-popup>
</template>
<style lang="scss" scoped>
2025-02-20 15:12:53 +08:00
// 朋友列表
.firendBox {
height: 100%;
2024-12-18 15:46:27 +08:00
2025-02-20 15:12:53 +08:00
.scroll {
height: 100%;
}
2024-12-18 15:46:27 +08:00
2025-02-20 15:12:53 +08:00
// 列表项
.li {
.letter {
background-color: #eee;
2024-12-18 15:46:27 +08:00
}
}
2025-02-20 15:12:53 +08:00
// 子集
.child {
.item+.item {
border-top: 2rpx solid #eee;
}
2024-12-18 15:46:27 +08:00
}
2025-02-20 15:12:53 +08:00
}
// 字母列表
.letterBox {
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
}
// 设置好友备注
.noteAlt {
box-shadow: 0 0 20rpx #0003;
.content {
.input {
padding: 20rpx 20rpx;
background-color: #eaeaea;
border-radius: 20rpx;
2024-12-18 15:46:27 +08:00
}
}
2025-02-20 15:12:53 +08:00
}
2024-12-18 15:46:27 +08:00
</style>