Merge branch 'main' of http://103.44.237.87:3000/commiu/question_uniapp
This commit is contained in:
commit
265dcb2bf1
@ -546,6 +546,13 @@
|
||||
{
|
||||
"navigationBarTitleText": "select"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/im/member",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
},{
|
||||
"path" : "pages/about/helpdetail",
|
||||
"style" :
|
||||
|
@ -10,7 +10,7 @@
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
|
||||
<view class="box-1">
|
||||
<view class="box-1" @click="emoji_show=addons_show=false">
|
||||
<scroll-view scroll-y refresher-background="transparent" style="height: 100%;"
|
||||
@refresherrefresh="refresherrefresh" :refresher-enabled="hasMoreMessages" :scroll-with-animation="false"
|
||||
:refresher-triggered="scrollView.refresherTriggered" :scroll-into-view="scrollView.intoView"
|
||||
@ -30,13 +30,11 @@
|
||||
@tap="showUserInfo(item.from_user)">
|
||||
</image>
|
||||
<view class="body">
|
||||
<view class="nickname">{{ item.from_user.nickname || item.from_user.username ||
|
||||
'Unknown'}}
|
||||
</view>
|
||||
<view class="nickname">{{ item.from_user.nickname || item.from_user.username || 'Unknown'}}</view>
|
||||
<view class="content" :class="{ 'image-content': item.type === 'image' }">
|
||||
<template v-if="item.type === 'image'">
|
||||
<image :src="getImageUrl(item.content)" mode="widthFix"
|
||||
style="max-width: 400rpx;" @tap="previewImage(item.content)"
|
||||
<image :src="item.message.thumbnail" mode="widthFix"
|
||||
style="max-width: 400rpx;" @tap="previewImage(item)"
|
||||
@load="onImageLoad(item.id)"></image>
|
||||
</template>
|
||||
<template v-else>
|
||||
@ -69,10 +67,10 @@
|
||||
@blur="onInputBlur"></uni-easyinput>
|
||||
</view>
|
||||
<view class="action-buttons">
|
||||
<button @tap="showemoji">
|
||||
<uni-icons type="checkbox-filled" size="24" color="#666"></uni-icons>
|
||||
<button @tap="showemoji" style="display: flex;align-items: center;">
|
||||
<img src="@/static/im/emoji.png" style="height:48rpx" mode="widthFix" />
|
||||
</button>
|
||||
<button @tap="showaddons">
|
||||
<button @tap="showaddons" style="display: flex;align-items: center;">
|
||||
<uni-icons type="plus" size="24" color="#666"></uni-icons>
|
||||
</button>
|
||||
</view>
|
||||
@ -165,7 +163,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
init: {
|
||||
cdnurl: 'http://q.sjqqzc.top'
|
||||
cdnurl: 'http://api.dxmt.io'
|
||||
},
|
||||
channel:{},
|
||||
// 滚动容器
|
||||
@ -197,6 +195,11 @@ export default {
|
||||
emojiList:emojiList,
|
||||
emoji_show:false,
|
||||
addons_show:false,
|
||||
// 图片加载队列
|
||||
imageLoadQueue: [],
|
||||
isProcessingQueue: false,
|
||||
// 占位图
|
||||
placeholderImage: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -254,7 +257,21 @@ export default {
|
||||
async initChannel(options) {
|
||||
let channel = await mattermost.getChannelById(options.target_id);
|
||||
if(channel.type=='O'){
|
||||
channel.name = channel.display_name || channel.name
|
||||
channel.name = channel.display_name || channel.name;
|
||||
//一次性获取全部用户的昵称
|
||||
// const members = await mattermost.getChannelMembers(channel.id);
|
||||
// console.log('获取到的频道成员:', members);
|
||||
// const users_ids = [];
|
||||
// for (const member of members) {
|
||||
// if (member.user_id && member.user_id !== mattermost.getCurrentUserId()) {
|
||||
// users_ids.push(member.user_id);
|
||||
// }
|
||||
// }
|
||||
// const users = await mattermost.getUsersByIds(users_ids);
|
||||
// console.log('获取到的频道成员:', users);
|
||||
// for (const user of users.data) {
|
||||
// mattermost.kown_users[user.id] = user;
|
||||
// }
|
||||
}
|
||||
if(channel.type=='D'){
|
||||
var target_user_id = channel.name.replace(mattermost.getCurrentUserId(),'').replace('__','')
|
||||
@ -297,30 +314,95 @@ export default {
|
||||
|
||||
|
||||
// 处理消息数据
|
||||
processMessageData(post, senderName = '') {
|
||||
async processMessageData(post, senderName = '') {
|
||||
console.log('处理消息数据:', post);
|
||||
// 构建用户信息
|
||||
const fromUser = mattermost.kown_users[post.user_id];
|
||||
const fromUser = await mattermost.getUserById(post.user_id);
|
||||
|
||||
// 处理消息类型
|
||||
let messageType = 'text';
|
||||
let messageContent = post.message;
|
||||
let imageUrl = '';
|
||||
|
||||
if (post.props && post.props.attachments) {
|
||||
const attachment = post.props.attachments[0];
|
||||
if (attachment.type === 'image') {
|
||||
let imageInfo = null;
|
||||
// 检查是否是图片消息
|
||||
if (post.file_ids && post.file_ids.length > 0) {
|
||||
messageType = 'image';
|
||||
imageUrl = attachment.image_url;
|
||||
// 从 metadata.files 中获取图片信息
|
||||
if (post.metadata && post.metadata.files && post.metadata.files.length > 0) {
|
||||
const file = post.metadata.files[0];
|
||||
if (file.mime_type && file.mime_type.startsWith('image/')) {
|
||||
// 构建图片信息对象
|
||||
imageInfo = {
|
||||
id: file.id,
|
||||
width: file.width,
|
||||
height: file.height,
|
||||
mimeType: file.mime_type
|
||||
};
|
||||
console.log(file)
|
||||
|
||||
messageContent = {
|
||||
id: file.id,
|
||||
//thumbnail: this.placeholderImage, // 先使用占位图
|
||||
thumbnail: `${mattermost.adminBaseUrl}/api/v4/files/${file.id}/thumbnail`,
|
||||
preview: null,
|
||||
original: `${mattermost.adminBaseUrl}/api/v4/files/${file.id}/preview`
|
||||
};
|
||||
|
||||
// 将图片添加到加载队列
|
||||
//this.addToImageLoadQueue(post.id, file.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...post,
|
||||
id: post.id,
|
||||
user_id: post.user_id,
|
||||
message: messageContent,
|
||||
type: messageType,
|
||||
create_time: post.create_at,
|
||||
status: 'success',
|
||||
from_user: fromUser
|
||||
from_user: fromUser,
|
||||
imageInfo: imageInfo
|
||||
};
|
||||
},
|
||||
|
||||
// 添加图片到加载队列
|
||||
addToImageLoadQueue(messageId, fileId) {
|
||||
this.imageLoadQueue.push({ messageId, fileId });
|
||||
if (!this.isProcessingQueue) {
|
||||
this.processImageLoadQueue();
|
||||
}
|
||||
},
|
||||
|
||||
// 处理图片加载队列
|
||||
async processImageLoadQueue() {
|
||||
if (this.isProcessingQueue || this.imageLoadQueue.length === 0) return;
|
||||
|
||||
this.isProcessingQueue = true;
|
||||
const { messageId, fileId } = this.imageLoadQueue.shift();
|
||||
|
||||
try {
|
||||
// 获取缩略图
|
||||
const thumbnailData = await mattermost.getThumbnail(fileId);
|
||||
|
||||
// 更新消息中的图片
|
||||
const messageIndex = this.talkList.findIndex(msg => msg.id === messageId);
|
||||
if (messageIndex !== -1) {
|
||||
this.$set(this.talkList[messageIndex].message, 'thumbnail', thumbnailData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载缩略图失败:', error);
|
||||
} finally {
|
||||
this.isProcessingQueue = false;
|
||||
// 继续处理队列中的下一个图片
|
||||
if (this.imageLoadQueue.length > 0) {
|
||||
setTimeout(() => this.processImageLoadQueue(), 100);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 加载消息
|
||||
async loadMessages() {
|
||||
if (this.ajax.flag || this.ajax.loading) return;
|
||||
@ -355,7 +437,8 @@ export default {
|
||||
});
|
||||
}
|
||||
for (var k in posts) {
|
||||
posts[k]['from_user'] = mattermost.kown_users[posts[k]['user_id']];//users[posts[k]['user_id']];
|
||||
posts[k] = await this.processMessageData(posts[k]);
|
||||
//posts[k]['from_user'] = await mattermost.getUserById(posts[k]['user_id']);//users[posts[k]['user_id']];
|
||||
}
|
||||
// 更新消息列表
|
||||
if (this.ajax.page === 0) {
|
||||
@ -405,15 +488,14 @@ export default {
|
||||
//console.log('发送消息:', this.content);
|
||||
// 发送消息
|
||||
const result = await mattermost.sendTextMessage(this.channel.id, this.content);
|
||||
|
||||
//console.log('发送消息:', this.content);
|
||||
if (result && result.id) {
|
||||
this.content = '';
|
||||
result['from_user'] = await mattermost.getUserById(result.user_id);
|
||||
this.talkList.push(result);
|
||||
console.log('发送成功:', result,this.talkList);
|
||||
// 更新消息状态
|
||||
//result.from_user = this.im_user;
|
||||
//this.talkList[result.id] = result;
|
||||
//result['from_user'] = await mattermost.getUserById(result.user_id);
|
||||
if(this.channel.type !='O'){
|
||||
this.handleNewMessage({post:result});
|
||||
}
|
||||
//console.log('发送成功:', result,this.talkList);
|
||||
} else {
|
||||
throw new Error('发送失败');
|
||||
}
|
||||
@ -435,8 +517,9 @@ export default {
|
||||
if (!result || !result.id) {
|
||||
throw new Error('发送失败');
|
||||
}
|
||||
result['from_user'] = await mattermost.getUserById(result.user_id);
|
||||
this.talkList.push(result);
|
||||
if(this.channel.type !='O'){
|
||||
this.handleNewMessage({post:result});
|
||||
}
|
||||
//this.content = '';
|
||||
|
||||
//console.log('发送图片消息成功:', result);
|
||||
@ -448,10 +531,8 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 处理新消息
|
||||
handleNewMessage(message) {
|
||||
async handleNewMessage(message) {
|
||||
console.log('收到新消息:', message);
|
||||
|
||||
// 检查消息格式
|
||||
@ -485,8 +566,7 @@ export default {
|
||||
console.log('消息已存在,忽略:', post.id);
|
||||
return;
|
||||
}
|
||||
|
||||
const newMessage = this.processMessageData(post, message.sender_name);
|
||||
const newMessage = await this.processMessageData(post, message.sender_name);
|
||||
|
||||
console.log('添加新消息到列表:', newMessage);
|
||||
this.talkList.push(newMessage);
|
||||
@ -642,13 +722,27 @@ export default {
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(url) {
|
||||
previewImage(message) {
|
||||
console
|
||||
.warn('previewImage', message);
|
||||
if (!message.message || !message.message.id) return;
|
||||
const file_id = message.imageInfo.id;
|
||||
// 获取所有图片消息的原图URL
|
||||
const images = this.talkList
|
||||
.filter(msg => msg.type === 'image')
|
||||
.map(msg => this.getImageUrl(msg.content));
|
||||
.filter(msg => msg.type === 'image' && msg.imageInfo && msg.imageInfo.id)
|
||||
.map(msg => {
|
||||
return `${mattermost.adminBaseUrl}/api/v4/files/${msg.imageInfo.id}`;
|
||||
});
|
||||
|
||||
uni.previewImage({
|
||||
urls: images,
|
||||
current: this.getImageUrl(url)
|
||||
current: `${mattermost.adminBaseUrl}/api/v4/files/${message.imageInfo.id}`,
|
||||
success: () => {
|
||||
console.log('预览图片成功');
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('预览图片失败:', err);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@ -762,7 +856,6 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
height: 100vh;
|
||||
|
390
pages/im/member.vue
Normal file
390
pages/im/member.vue
Normal file
@ -0,0 +1,390 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<uni-nav-bar
|
||||
:title="$t('MT Team')"
|
||||
left-icon="left"
|
||||
@clickLeft="goto('/pages/im/index',2)"
|
||||
:border="false"
|
||||
backgroundColor="F5f5f5">
|
||||
</uni-nav-bar>
|
||||
<view class="box-1">
|
||||
<scroll-view
|
||||
scroll-y
|
||||
refresher-background="transparent"
|
||||
style="height: 100%;"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
:refresher-enabled="ajax.last_page > ajax.page"
|
||||
:scroll-with-animation="false"
|
||||
:refresher-triggered="scrollView.refresherTriggered"
|
||||
>
|
||||
<uni-list>
|
||||
<template v-for="item in friend_list" >
|
||||
<uni-list-chat
|
||||
v-if="item.id"
|
||||
:key="`${item.id}`"
|
||||
:avatar-circle="true"
|
||||
:title="item.display_name || item.name || item.nickname || item.email"
|
||||
:avatar="getAvatarUrl(item)"
|
||||
:note="item.last_msg ? (item.last_msg_type === 'image' ? '[图片]' : item.last_msg) : '暂无消息'"
|
||||
:time="item.last_post_at ? date(item.last_post_at) : ''"
|
||||
:badge-text="item.unread_count > 0 ? (item.unread_count > 99 ? '99+' : item.unread_count) : ''"
|
||||
clickable
|
||||
@click="handleContactClick(item)"
|
||||
></uni-list-chat>
|
||||
</template>
|
||||
<!--这里显示最近联系人-->
|
||||
</uni-list>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapMutations
|
||||
} from 'vuex';
|
||||
import mattermost from '@/static/im/mattermost.js';
|
||||
import base from '@/config/baseUrl'; // 导入base变量
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 初始化数据
|
||||
config: {
|
||||
cdnurl: '',
|
||||
// 其他初始化数据
|
||||
},
|
||||
friend_list: {},
|
||||
// 聊天列表数据
|
||||
ajax: {
|
||||
limit: 20, // 每页数量
|
||||
last_page: 1, // 总页数
|
||||
page: 0, // 当前页码
|
||||
flag: false, // 请求开关
|
||||
loading: false // 加载状态
|
||||
},
|
||||
scrollView: {
|
||||
refresherTriggered: false // 下拉刷新状态
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['userInfo']),
|
||||
// 添加计算属性来安全访问 ajax 数据
|
||||
hasMoreData() {
|
||||
return this.ajax && this.ajax.last_page > this.ajax.page;
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.init();
|
||||
},
|
||||
onLoad() {
|
||||
this.init();
|
||||
},
|
||||
onUnload() {
|
||||
// 移除消息事件监听
|
||||
mattermost.off('posted', this.handleNewMessage);
|
||||
mattermost.off('post_deleted', this.handleMessageDeleted);
|
||||
mattermost.off('post_edited', this.handleMessageEdited);
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.loadContactList().finally(() => {
|
||||
uni.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setUserInfo']),
|
||||
async init(){
|
||||
try {
|
||||
if(!this.userInfo.token || !this.userInfo.im_token){
|
||||
return ;
|
||||
}
|
||||
// 获取用户信息
|
||||
//const userinfo = await this.$http.get('/api/user/profile');
|
||||
//this.setUserInfo(userinfo.data);
|
||||
//console.log('用户信息:', this.userInfo);
|
||||
|
||||
// 获取初始化数据
|
||||
const initRes = await this.$http.get('/api/common/init?lang=' + this.$i18n.locale);
|
||||
if (initRes.code === 0) {
|
||||
this.config = initRes.data;
|
||||
this.config.cdnurl = initRes.data.cdnurl || "http://www.dxmt.io";
|
||||
}
|
||||
|
||||
// 检查 Mattermost 连接状态
|
||||
await mattermost.init();
|
||||
// 加载联系人列表
|
||||
this.loadContactList();
|
||||
// 注册消息事件监听
|
||||
mattermost.on('posted', this.handleNewMessage);
|
||||
mattermost.on('post_deleted', this.handleMessageDeleted);
|
||||
mattermost.on('post_edited', this.handleMessageEdited);
|
||||
} catch (error) {
|
||||
console.error('页面加载失败:', error);
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 加载联系人列表
|
||||
async loadContactList() {
|
||||
if (this.ajax.flag || this.ajax.loading) return;
|
||||
this.ajax.flag = true;
|
||||
this.ajax.loading = true;
|
||||
|
||||
try {
|
||||
// 获取固定联系人列表
|
||||
const fixedContactsRes = await this.$http.get('/api/chat/get_team_member_list');
|
||||
let fixedContacts = [];
|
||||
|
||||
if (fixedContactsRes.code === 0 && Array.isArray(fixedContactsRes.data)) {
|
||||
fixedContacts = fixedContactsRes.data;
|
||||
}
|
||||
|
||||
// 获取私聊列表
|
||||
const recent_contacts = await mattermost.getRecentContacts();
|
||||
|
||||
const sortedContacts = {};
|
||||
for (const key in fixedContacts) {
|
||||
if (Object.prototype.hasOwnProperty.call(fixedContacts, key)) {
|
||||
sortedContacts[fixedContacts[key].id] = fixedContacts[key];
|
||||
}
|
||||
}
|
||||
for (const key in sortedContacts) {
|
||||
if (Object.prototype.hasOwnProperty.call(sortedContacts, key)) {
|
||||
sortedContacts[key].unread_count = sortedContacts[key].unread_count || 0;
|
||||
this.friend_list[key] = sortedContacts[key];
|
||||
}
|
||||
}
|
||||
console.log('联系人列表:',this.friend_list);
|
||||
// 更新列表
|
||||
if (this.ajax.page === 0) {
|
||||
//this.friend_list = sortedContacts;
|
||||
} else {
|
||||
//this.friend_list = [...this.friend_list, ...sortedContacts];
|
||||
}
|
||||
|
||||
// 更新分页信息
|
||||
this.ajax.page++;
|
||||
this.ajax.last_page = Math.ceil(sortedContacts.length / this.ajax.limit);
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载联系人列表失败:', error);
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.ajax.flag = false;
|
||||
this.ajax.loading = false;
|
||||
this.scrollView.refresherTriggered = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 处理联系人点击
|
||||
async handleContactClick(item) {
|
||||
try {
|
||||
// 如果是私聊类型,需要先查询直接消息频道ID
|
||||
var url = await mattermost.talk_to_user(item); // 跳转到聊天页面
|
||||
uni.navigateTo({
|
||||
url: url
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('处理联系人点击失败:', error);
|
||||
uni.showToast({
|
||||
title: '操作失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 处理新消息
|
||||
async handleNewMessage(message) {
|
||||
// 更新联系人列表中的消息
|
||||
const updateContact = async(list) => {
|
||||
let is_exist = false;
|
||||
let post = JSON.parse(message.post);
|
||||
for(var k in list){
|
||||
const contact = list[k];
|
||||
if(message.channel_type == 'D'){
|
||||
//私聊消息
|
||||
if(contact.id === post.user_id) {
|
||||
is_exist = true;
|
||||
list[k]= contact;
|
||||
list[k]['last_msg']=post.message;
|
||||
list[k]['last_msg_type']= post.type || 'text';
|
||||
list[k]['last_msg_time']= post.create_at;
|
||||
list[k]['unread_count']= contact.unread_count+=1;
|
||||
}
|
||||
}
|
||||
if(message.channel_type == 'O'){
|
||||
if(contact.id === post.channel_id) {
|
||||
is_exist = true;
|
||||
list[k]= contact;
|
||||
list[k]['last_msg']=post.message;
|
||||
list[k]['last_msg_type']= post.type || 'text';
|
||||
list[k]['last_msg_time']= post.create_at;
|
||||
list[k]['unread_count']= contact.unread_count+=1;
|
||||
}
|
||||
//群组消息
|
||||
}
|
||||
}
|
||||
if(message.channel_type == 'D' && !is_exist){
|
||||
console.log('新消息:', message,'不存在');
|
||||
let send_user = await mattermost.getUserInfo(post.user_id);
|
||||
//console.log('send_user',send_user);
|
||||
let contact = send_user.data;
|
||||
contact['last_msg']=post.message;
|
||||
contact['last_msg_type']= post.type || 'text';
|
||||
contact['last_msg_time']= post.create_at;
|
||||
contact['unread_count']= 1;
|
||||
list[k]= contact;
|
||||
}
|
||||
let _keys = Object.keys(list).sort((a, b) => {
|
||||
const timeA = a.last_msg_time ? new Date(a.last_msg_time).getTime() : 0;
|
||||
const timeB = b.last_msg_time ? new Date(b.last_msg_time).getTime() : 0;
|
||||
return timeB - timeA;
|
||||
});
|
||||
|
||||
let _list = {};
|
||||
for (let index = 0; index < _keys.length; index++) {
|
||||
_list[_keys[index]] = list[_keys[index]];
|
||||
}
|
||||
return _list;
|
||||
};
|
||||
|
||||
this.friend_list = await updateContact(this.friend_list);
|
||||
},
|
||||
|
||||
// 处理消息删除
|
||||
handleMessageDeleted(message) {
|
||||
const updateContact = (list) => {
|
||||
return list.map(contact => {
|
||||
if(contact.id === message.channel_id) {
|
||||
return {
|
||||
...contact,
|
||||
last_msg: '此消息已删除',
|
||||
last_msg_type: 'text',
|
||||
last_msg_time: message.create_at
|
||||
};
|
||||
}
|
||||
return contact;
|
||||
});
|
||||
};
|
||||
|
||||
this.friend_list = updateContact(this.friend_list);
|
||||
},
|
||||
|
||||
// 处理消息编辑
|
||||
handleMessageEdited(message) {
|
||||
const updateContact = (list) => {
|
||||
return list.map(contact => {
|
||||
if(contact.id === message.channel_id) {
|
||||
return {
|
||||
...contact,
|
||||
last_msg: message.message,
|
||||
last_msg_time: message.update_at
|
||||
};
|
||||
}
|
||||
return contact;
|
||||
});
|
||||
};
|
||||
|
||||
this.friend_list = updateContact(this.friend_list);
|
||||
},
|
||||
|
||||
refresherrefresh() {
|
||||
this.scrollView.refresherTriggered = true;
|
||||
this.ajax.page = 0;
|
||||
this.loadContactList();
|
||||
},
|
||||
goto(url,type){
|
||||
if(type==2){
|
||||
return uni.switchTab({url:url})
|
||||
}
|
||||
if(type==1){
|
||||
return uni.navigateBack({delta:url});
|
||||
}
|
||||
uni.navigateTo({
|
||||
url:url
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* JavaScript 仿 PHP date() 函数
|
||||
* @param {string} format - 格式字符串
|
||||
* @param {number|Date} [timestamp] - 可选的时间戳或Date对象,默认为当前时间
|
||||
* @return {string} 格式化后的日期时间字符串
|
||||
*/
|
||||
date(format, timestamp) {
|
||||
// 处理时间参数
|
||||
if(!timestamp){
|
||||
return '';
|
||||
}
|
||||
let date = timestamp;
|
||||
if(!(timestamp instanceof Date)){
|
||||
date = Date(timestamp * 1000);
|
||||
if(timestamp > 1749000000){
|
||||
date = Date(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
// 定义替换规则
|
||||
const replacements = {
|
||||
// 日
|
||||
'd': () => String(date.getDate()).padStart(2, '0'),
|
||||
'j': () => date.getDate(),
|
||||
// 月
|
||||
'm': () => String(date.getMonth() + 1).padStart(2, '0'),
|
||||
'n': () => date.getMonth() + 1,
|
||||
// 年
|
||||
'Y': () => date.getFullYear(),
|
||||
'y': () => String(date.getFullYear()).slice(-2),
|
||||
// 时间
|
||||
'H': () => String(date.getHours()).padStart(2, '0'),
|
||||
'i': () => String(date.getMinutes()).padStart(2, '0'),
|
||||
's': () => String(date.getSeconds()).padStart(2, '0'),
|
||||
// 其他
|
||||
'w': () => date.getDay(), // 星期几 (0-6)
|
||||
'A': () => date.getHours() >= 12 ? 'PM' : 'AM',
|
||||
'a': () => date.getHours() >= 12 ? 'pm' : 'am',
|
||||
};
|
||||
|
||||
// 执行替换
|
||||
let result = '';
|
||||
for (let i = 0; i < format.length; i++) {
|
||||
const char = format[i];
|
||||
if (char in replacements) {
|
||||
result += replacements[char]();
|
||||
} else {
|
||||
result += char;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
getAvatarUrl(item) {
|
||||
if(!item.avatar){
|
||||
return this.config.cdnurl+'/static/img/avatar.png';
|
||||
}
|
||||
return (item.avatar.startsWith('http') ? '' : this.config.cdnurl) + item.avatar;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
height: 100vh;
|
||||
background-color: #F5F5F5;
|
||||
font-family: "poppins";
|
||||
.box-1 {
|
||||
flex: 1;
|
||||
height: calc(100vh - var(--window-top) - 44px);
|
||||
}
|
||||
}
|
||||
</style>
|
BIN
static/im/emoji.png
Normal file
BIN
static/im/emoji.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
@ -73,7 +73,7 @@ class MattermostClient {
|
||||
const protocol = process.env.NODE_ENV === 'development' ? 'ws' : 'wss';
|
||||
// 构建 WebSocket URL,使用用户 API 域名
|
||||
const connectionId = Date.now().toString(36) + Math.random().toString(36).substr(2);
|
||||
this.wsUrl = this.userBaseUrl.replace('https',protocol) + `/api/v4/websocket?connection_id=${connectionId}&sequence_number=0`;
|
||||
this.wsUrl = this.userBaseUrl.replace('https',protocol)+`/api/v4/websocket?connection_id=${connectionId}&sequence_number=0`;
|
||||
// 重置状态
|
||||
this.sequence = 1;
|
||||
this.reconnectAttempts = 0;
|
||||
@ -591,7 +591,11 @@ class MattermostClient {
|
||||
|
||||
// 文件上传封装
|
||||
async uploadFile(options) {
|
||||
const { url, filePath, name = 'files', headers = {} } = options;
|
||||
const { channelId, filePath, name = 'files', headers = {} } = options;
|
||||
|
||||
if (!channelId) {
|
||||
throw new Error('channelId 是必需的');
|
||||
}
|
||||
|
||||
// 添加认证头
|
||||
const requestHeaders = {
|
||||
@ -599,24 +603,28 @@ class MattermostClient {
|
||||
...headers
|
||||
};
|
||||
|
||||
const [error, response] = await uni.uploadFile({
|
||||
url,
|
||||
// 直接上传文件
|
||||
const [uploadError, uploadResponse] = await uni.uploadFile({
|
||||
url: `${this.userBaseUrl}/api/v4/files`,
|
||||
filePath,
|
||||
name,
|
||||
header: requestHeaders
|
||||
header: requestHeaders,
|
||||
formData: {
|
||||
channel_id: channelId
|
||||
}
|
||||
}).catch(err => [err, null]);
|
||||
|
||||
if (error) {
|
||||
console.error(`文件上传失败 [${url}]:`, error);
|
||||
throw error;
|
||||
if (uploadError) {
|
||||
console.error('文件上传失败:', uploadError);
|
||||
throw uploadError;
|
||||
}
|
||||
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
return response.data;
|
||||
if (uploadResponse.statusCode >= 200 && uploadResponse.statusCode < 300) {
|
||||
return JSON.parse(uploadResponse.data);
|
||||
}
|
||||
|
||||
console.error(`文件上传失败 [${url}]:`, response);
|
||||
throw new Error(`文件上传失败: ${response.statusCode}`);
|
||||
console.error('文件上传失败:', uploadResponse);
|
||||
throw new Error(`文件上传失败: ${uploadResponse.statusCode}`);
|
||||
}
|
||||
|
||||
// 获取频道消息
|
||||
@ -664,16 +672,15 @@ class MattermostClient {
|
||||
try {
|
||||
// 1. 上传文件
|
||||
const fileData = await this.uploadFile({
|
||||
url: `${this.userBaseUrl}/api/v4/files`,
|
||||
channelId,
|
||||
filePath
|
||||
});
|
||||
|
||||
const fileInfo = JSON.parse(fileData);
|
||||
const fileId = fileInfo.file_infos[0].id;
|
||||
const fileId = fileData.file_infos[0].id;
|
||||
|
||||
// 2. 发送带图片的消息
|
||||
return this.request({
|
||||
url: `${this.userBaseUrl}/api/v4/posts`,
|
||||
url: `/api/v4/posts`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
channel_id: channelId,
|
||||
@ -687,6 +694,40 @@ class MattermostClient {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async getThumbnail(file_id, width = 200, height = 200) {
|
||||
return this.adminBaseUrl+'/api/v4/files/${file_id}/thumbnail?width=${width}&height=${height}';
|
||||
try {
|
||||
const response = await this.request({
|
||||
url: `/api/v4/files/${file_id}/thumbnail`,
|
||||
method: 'GET',
|
||||
data: {
|
||||
width,
|
||||
height
|
||||
}
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('获取缩略图失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getPreview(file_id, width = 800, height = 800) {
|
||||
try {
|
||||
const response = await this.request({
|
||||
url: `/api/v4/files/${file_id}/preview`,
|
||||
method: 'GET',
|
||||
data: {
|
||||
width,
|
||||
height
|
||||
}
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('获取预览图失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 标记消息为已读
|
||||
async markChannelAsViewed(channelId) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user