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
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>
|