You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

435 lines
11 KiB

<template>
<view>
<cu-custom :bgColor="PageCur=='mine'?'bg-mine':'bg-white'">
<template #backText>
<view v-if="PageCur=='message' || PageCur=='contacts'" class="f-20 ml-10 mr-10" @tap="search()">
<text class="cuIcon-search" style="margin-left: -10px;"></text>
</view>
</template>
<template #content>{{PageName}}</template>
<template #right>
<view v-if="PageCur=='message'" class="f-20 ml-10 mr-10" @tap="modelName='add'">
<text class="cuIcon-add f-28" id="add"></text>
</view>
</template>
</cu-custom>
<view>
<message v-show="PageCur=='message'"></message>
<contacts v-show="PageCur=='contacts'" :TabCur="TabCur"></contacts>
<compass v-show="PageCur=='compass'"></compass>
<mine v-show="PageCur=='mine'"></mine>
</view>
<view class="cu-bar tabbar bg-white shadow foot">
<view class="action" @click="NavChange(item)" v-for="(item,index) in navList" :key="index" data-cur="message">
<view class='cuIcon-cu-image' style="position: relative;">
<image :src="'/static/image/tabbar/' + [item.name] + [PageCur==item.name?'-active':''] + '.svg'"></image>
<view class="cu-tag badge" v-if="item.notice>0">{{item.notice}}</view>
<view style="position: absolute;top: 0px;right: 2px;" v-if="item.bol>0">
<view class="notice-back"></view>
</view>
</view>
<view :class="PageCur==item.name?'text-green':'text-black'">{{item.title}}</view>
</view>
</view>
<view class="add-modal" :class="modelName=='add' ? 'show' : 'none'" @tap="modelName=''" >
<view class="add-dialog" :style="{top:top+20+'px'}">
<view class="add-item" @tap="initContacts();">
<view class="content padding-tb-sm">
<text class="cuIcon-refresh"></text>
<text class="text">更新消息</text>
</view>
</view>
<view class="add-item" @tap="addFriend()" v-if='globalConfig.sysInfo.runMode==2'>
<view class="content padding-tb-sm">
<text class="cuIcon-friendadd"></text>
<text class="text">添加朋友</text>
</view>
</view>
<view class="add-item" @tap="addGroup()">
<view class="content padding-tb-sm">
<text class=" cuIcon-friend"></text>
<text class="text">创建群聊</text>
</view>
</view>
<view class="add-item" @tap="scan()">
<view class="content padding-tb-sm" style="text-align: left;">
<text class=" cuIcon-scan mr-5"></text>
<text class="text">扫 一 扫</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import message from '@/pages/message';
import contacts from '@/pages/contacts';
import compass from '@/pages/compass';
import mine from '@/pages/mine';
import { storeToRefs } from 'pinia';
import { useMsgStore } from '@/store/message';
import { useloginStore } from '@/store/login';
import pinia from '@/store/index'
import scan from '@/common/scan.js'
import homeData from '../../service/homeData';
const msgStore = useMsgStore(pinia)
const loginStore = useloginStore(pinia)
const { unread,sysUnread,NoticeCount } = storeToRefs(msgStore);
export default {
components: {
message,
contacts,
compass,
mine
},
data() {
let navList=[
{
name:'message',
title:'消息',
notice:unread
},
{
name:'contacts',
title:'通讯录',
notice:sysUnread
}
]
let compass={
name:'compass',
title:'探索',
notice:0,
bol:NoticeCount
};
if(loginStore.globalConfig && loginStore.globalConfig.compass){
if(loginStore.globalConfig.compass.status==1){
navList.push(compass);
}
}
let mine={
name:'mine',
title:'我的',
notice:0
}
navList.push(mine);
return {
globalConfig:loginStore.globalConfig,
PageCur: 'message',
PageName: '消息',
TabCur:0,
modelName:false,
navList:navList,
top:10,
indexs:0,
IntervalChat:null
}
},
onBackPress(options) {
if (getCurrentPages().length > 1) {
return false;
}
try {
const main = plus.android.runtimeMainActivity();
main.moveTaskToBack(false); // 将任务移动到后台
return true; // 拦截返回按键,防止退出应用
} catch (e) {
return false; // 出现错误时允许默认返回行为
}
},
mounted(){
// #ifndef MP
uni.hideTabBar();
// #endif
// 监听ws状态,如果重新连接了,要更新联系人
uni.$on('socketStatus',(e)=>{
if(e){
console.log('触发了一次');
this.initContacts();
}
})
uni.$off('initContacts');
uni.$on('initContacts',(e)=>{
this.initContacts();
})
let query = this.$util.getQuery(this).select("#add").boundingClientRect();
query.exec((res)=> {
let top = res[0].top;
let height = res[0].height;
this.top = top+height
});
},
onShow(){
const _this = this
const tabid = uni.getStorageSync('tabid')
if(tabid){
uni.removeStorageSync('tabid')
}
uni.getNetworkType({
success (res) {
if(res.networkType == 'none'){
_this.getGroupData()
}else{
_this.initContacts(0);
// _this.startPolling()
// _this.getGroupData()
}
// console.log(res.networkType,'1111');
}
});
},
onHide() {
// 组件销毁时清除定时器
this.stopPolling()
},
methods: {
startPolling(){
this.IntervalChat = setInterval(()=>{
this.initContacts();
},5000)
},
stopPolling(){
clearInterval(this.IntervalChat)
this.IntervalChat = null
},
closeModel(){
this.modelName=false;
},
scan(){
scan.scanQr();
},
NavChange: function(item) {
this.PageCur = item.name
this.PageName = item.title
},
showContacts(){
this.TabCur==1 ? this.TabCur=0 :this.TabCur=1
},
initContacts(num){
if(num){
this.indexs = num
}
this.modelName='';
this.$api.msgApi.initContacts().then(res => {
this.indexs++
// 设置消息未读数和系统消息未读数
msgStore.sysUnread=res.count;
msgStore.initContacts(res.data);
// if(this.indexs === 1&&num===0){
// 新增持久化存储检查
res.data.forEach((val)=>{
if(val.id==-2){
val.lastContent = val.lastContent.replace(/'/g, "''");
}
})
this.syncGroupData(res.data)
const userInfo = uni.getStorageSync('userInfo')
const list = [...res.data]
list.push({avatar:userInfo.avatar})
list.forEach(res => {
// #ifdef APP-PLUS
uni.downloadFile({ url: res.avatar,success: (downloadResult) => {
this.saveToPermanentStorage(downloadResult.tempFilePath);
}})
// #endif
})
// }
// this.getGroupData()
})
},
// App端持久化存储实现
saveToPermanentStorage(tempPath) {
return new Promise((resolve, reject) => {
// 获取应用文档目录(持久化存储)
plus.io.resolveLocalFileSystemURL(
'_doc',
(docDir) => {
// 创建目标路径
docDir.getDirectory(
'img',
{ create: true, exclusive: false },
(entry) => {
// 从临时路径获取文件名
const fileName = this.getFileName(tempPath);
const fileName1 = this.getFileName(docDir.fullPath + 'img/' +fileName);
// 新增:检查文件是否存在
entry.getFile(fileName1,{ create: false }, // 不创建新文件
(fileEntry) => {
// console.log('文件已存在,拒绝操作');
// 文件已存在,拒绝操作
reject(new Error('File already exists: ' + fileName));
},
(error) => {
// console.log(error);
// 文件不存在(或发生其他错误),继续复制操作
if (error.code === 14) { // 1表示文件不存在(不同平台错误码可能不同)
this.copyFile(tempPath, entry, fileName, resolve, reject);
} else {
reject(error);
}
}
);
},
(error) => {
reject(error);
}
);
},
(error) => {
reject(error);
}
);
});
},
// 提取复制逻辑为独立方法
copyFile(tempPath, targetDir, fileName, resolve, reject) {
plus.io.resolveLocalFileSystemURL(
tempPath,
(tempEntry) => {
tempEntry.copyTo(
targetDir,
fileName,
(newEntry) => {
resolve(newEntry.toLocalURL());
},
(error) => {
reject(error);
}
);
},
(error) => {
reject(error);
}
);
},
// 获取文件名工具方法
getFileName(path) {
const index = path.lastIndexOf('/');
let fileName = path.substr(index + 1);
fileName = fileName.replace(/\(\d+\)(?=\.[^./]+$)/, '');
return fileName;
},
async syncGroupData(data) {
// #ifdef APP-PLUS
// 1. 获取接口数据(示例)
let apiResponse = data;
// 3. 执行批量插入
await homeData.deleteallList()
await homeData.batchInsertOrUpdate(apiResponse);
// #endif
},
async getGroupData(){
// #ifdef APP-PLUS
const groups = await homeData.getList();
msgStore.initContacts(groups)
// console.log('处理后的数据:', groups)
// #endif
},
addGroup(){
uni.navigateTo({
url: '/pages/index/userSelection?type=1'
})
},
addFriend(){
uni.navigateTo({
url: '/pages/contacts/search'
})
},
search(){
const type = this.PageCur=="message" ? 1 : 2;
uni.navigateTo({
url: '/pages/index/search?type='+type
})
}
}
}
</script>
<style scoped lang="scss">
.add-modal{
position: fixed;
top: 0;
right: 0;
z-index: -99999;
.add-dialog{
display: flex;
flex-direction: column;
background-color: #4f4f4f;
color: #fff;
border-radius: 10rpx;
justify-content: space-around;
align-items: center;
position: fixed;
right: 10rpx;
width: 240rpx;
padding:20rpx;
.add-item{
.text{
margin-left: 10rpx;
}
}
}
.add-dialog::after {
content: "";
top: -10rpx;
transform: rotate(45deg);
position: absolute;
display: inline-block;
overflow: hidden;
width: 30rpx;
height: 30rpx;
right: 20rpx;
left: initial;
background: #4f4f4f;
}
}
.show{
position: fixed;
top: 0;
z-index: 9999;
height: 100vh;
width: 100vw;
opacity:1
}
.none{
position: fixed;
top: 0;
right: 0;
z-index: -99999;
opacity: 0;
}
.notice-back{
width: 6px;
height: 6px;
position: relative;
border-radius: 50%;
background-color: red;
vertical-align: middle;
}
.notice-back::after{
content: "";
width: 100%;
height: 100%;
top: 0px;
right: 0px;
position: absolute;
border-radius: 50%;
background: inherit;
animation: notiback 1.2s ease-in-out infinite;
}
@keyframes notiback{
0% {transform: scale(0.5);opacity: 1;}
30%{opacity: 0.7;}
100%{ transform: scale(2.5);opacity: 0;}
}
</style>