优化代码
This commit is contained in:
@@ -118,3 +118,7 @@ export function signIn(data) {
|
|||||||
export function editEmail(data) {
|
export function editEmail(data) {
|
||||||
return postAxios({ url: 'user/updateUserMail', data })
|
return postAxios({ url: 'user/updateUserMail', data })
|
||||||
}
|
}
|
||||||
|
//获取OTP
|
||||||
|
export function getOtp() {
|
||||||
|
return getAxios({ url: 'otp/getotp' })
|
||||||
|
}
|
||||||
88
src/components/chatMessage/PictureMessage.vue
Normal file
88
src/components/chatMessage/PictureMessage.vue
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<div class="picture-message" @click="dialogVisibleClick">
|
||||||
|
<img class="picture-message-img" :src="item.payload.url" alt="">
|
||||||
|
</div>
|
||||||
|
<el-dialog v-model="dialogVisible" fullscreen>
|
||||||
|
<div class="dialog-content">
|
||||||
|
<img class="dialog-img" :src="item.payload.url" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="dialogVisible = false">关闭</el-button>
|
||||||
|
<el-button type="primary" @click="saveToDesktop">保存到本地</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 保存到桌面
|
||||||
|
function saveToDesktop() {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = props.item.payload.url;
|
||||||
|
link.download = props.item.payload.filename;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 弹窗相关
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
function dialogVisibleClick() {
|
||||||
|
dialogVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const refname = ref('');
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.picture-message{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
/* display: inline-block; */
|
||||||
|
max-width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.picture-message-img{
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.dialog-content{
|
||||||
|
width: 98vw;
|
||||||
|
height: 95vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.dialog-img{
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -11,8 +11,8 @@ import GoEasy from 'goeasy'
|
|||||||
|
|
||||||
const goeasy = GoEasy.getInstance({
|
const goeasy = GoEasy.getInstance({
|
||||||
host:"hangzhou.goeasy.io", //若是新加坡区域:singapore.goeasy.io
|
host:"hangzhou.goeasy.io", //若是新加坡区域:singapore.goeasy.io
|
||||||
appkey:"您的common key",
|
appkey:"PC-a88037e060ed4753bb316ac7239e62d9",
|
||||||
modules:['pubsub']//根据需要,传入‘pubsub’或'im’,或数组方式同时传入
|
modules:['im']//根据需要,传入‘pubsub’或'im’,或数组方式同时传入
|
||||||
});
|
});
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|||||||
@@ -32,4 +32,18 @@ export const tokenStore = defineStore('token', {
|
|||||||
this.user = user
|
this.user = user
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
export const IMloginStore = defineStore('IMlogin', {
|
||||||
|
state: () => {
|
||||||
|
return { IMstate: false }
|
||||||
|
},
|
||||||
|
// 也可以这样定义
|
||||||
|
// state: () => ({ count: 0 })
|
||||||
|
actions: {
|
||||||
|
setIMstate(state){
|
||||||
|
this.IMstate = state
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
import { goeasy } from '../main'
|
import { goeasy } from '../main'
|
||||||
|
import { IMloginStore } from '@/stores/notice.js';
|
||||||
|
import GoEasy from 'goeasy'
|
||||||
|
|
||||||
|
//链接IM(登录IM)
|
||||||
export function goEasyLink(data) {
|
export function goEasyLink(data) {
|
||||||
|
const counter = IMloginStore()
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
goeasy.connect({
|
goeasy.connect({
|
||||||
id:data.id, //im必填,最大长度60字符
|
id:data.id, //im必填,最大长度60字符
|
||||||
@@ -8,14 +12,49 @@ export function goEasyLink(data) {
|
|||||||
otp:data.key,
|
otp:data.key,
|
||||||
onSuccess: function () { //连接成功
|
onSuccess: function () { //连接成功
|
||||||
console.log("连接成功");
|
console.log("连接成功");
|
||||||
|
counter.setIMstate(true); //登录IM成功
|
||||||
resolve(true);
|
resolve(true);
|
||||||
},
|
},
|
||||||
onFailed: function (error) { //连接失败
|
onFailed: function (error) { //连接失败
|
||||||
console.log("连接失败,错误码:" + error.code + ",错误信息:" + error.content);
|
console.log("连接失败,错误码:" + error.code + ",错误信息:" + error.content);
|
||||||
},
|
},
|
||||||
onProgress:function(attempts) { //连接或自动重连中
|
onProgress:function(attempts) { //连接或自动重连中
|
||||||
console.log("正在重连中..." + attempts);
|
console.log("正在重连中...");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取会话列表
|
||||||
|
export function goEasyGetConversations() {
|
||||||
|
var im = goeasy.im;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
im.latestConversations({
|
||||||
|
onSuccess: function (result) {
|
||||||
|
resolve(result);
|
||||||
|
},
|
||||||
|
onFailed: function (error) {
|
||||||
|
console.log("获取会话列表失败,错误码:" + error.code + " content:" + error.content);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取指定会话的消息列表
|
||||||
|
export function goEasyGetMessages(data) {
|
||||||
|
var im = goeasy.im;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
im.history({
|
||||||
|
id: data.id,//用户id或者群id
|
||||||
|
type: GoEasy.IM_SCENE.PRIVATE, //群聊:GoEasy.IM_SCENE.GROUP, 客服:GoEasy.IM_SCENE.CS,
|
||||||
|
lastTimestamp: data.timestamp, //上次查询结果里最后一条消息的时间戳,首次查询传入null即可
|
||||||
|
limit: 30, //可选项,返回的消息条数,默认为10条,最多30条
|
||||||
|
onSuccess: function (result) {
|
||||||
|
resolve(result.content);
|
||||||
|
},
|
||||||
|
onFailed: function (error) {
|
||||||
|
console.log("获取消息列表失败,错误码:" + error.code + " content:" + error.content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@@ -59,12 +59,13 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onMounted, onUnmounted } from "vue";
|
import { ref, watch, onMounted, onUnmounted } from "vue";
|
||||||
import { getVxQrcode, getScanResult, login } from "@/api/account"; // 导入登录接口
|
import { getVxQrcode, getScanResult, login, getOtp} from "@/api/account"; // 导入登录接口
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { tokenStore, UserStore } from '@/stores/notice'
|
import { tokenStore, UserStore } from '@/stores/notice'
|
||||||
import { setStorage , getStorage } from '@/utils/storage.js';
|
import { setStorage , getStorage } from '@/utils/storage.js';
|
||||||
import { goEasyLink } from '@/utils/goeasy.js';
|
import { goEasyLink } from '@/utils/goeasy.js';
|
||||||
|
import { ElLoading } from "element-plus";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const refname = ref("");
|
const refname = ref("");
|
||||||
const refEmail = ref(""); // 邮箱
|
const refEmail = ref(""); // 邮箱
|
||||||
@@ -73,6 +74,7 @@ const refSwitch = ref(false); // 登录切换/true:微信登录/false:邮箱登
|
|||||||
const Qrcode = ref(""); // 二维码
|
const Qrcode = ref(""); // 二维码
|
||||||
const token = tokenStore()
|
const token = tokenStore()
|
||||||
const user = UserStore()
|
const user = UserStore()
|
||||||
|
const info = ref({})
|
||||||
// 登录
|
// 登录
|
||||||
function EmailLogin() {
|
function EmailLogin() {
|
||||||
// // 邮箱验证
|
// // 邮箱验证
|
||||||
@@ -98,19 +100,32 @@ function EmailLogin() {
|
|||||||
// email: refEmail.value,
|
// email: refEmail.value,
|
||||||
password: refpassword.value,
|
password: refpassword.value,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
console.log(res);
|
|
||||||
token.setToken(res.token);
|
token.setToken(res.token);
|
||||||
setStorage("token", res.token);
|
setStorage("token", res.token);
|
||||||
setStorage("email", refEmail.value);
|
setStorage("email", refEmail.value);
|
||||||
setStorage("password", refpassword.value);
|
setStorage("password", refpassword.value);
|
||||||
user.setUser(res);
|
user.setUser(res);
|
||||||
setStorage("user", res);
|
setStorage("user", res);
|
||||||
// otp/getopt 调用
|
info.value = res
|
||||||
goEasyLink().then(() => {
|
getOtp().then((res) => {
|
||||||
|
const data = {
|
||||||
|
id: String(info.value.id),
|
||||||
|
avatar: info.value.headerIcon,
|
||||||
|
nickname: info.value.nickName,
|
||||||
|
key: res,
|
||||||
|
}
|
||||||
|
goEasyLink(data).then(() => {
|
||||||
loading.close();
|
loading.close();
|
||||||
router.push("/nav");
|
router.push("/nav");
|
||||||
|
}).catch((err) => {
|
||||||
|
ElMessage.error("登录失败:"+err.content);
|
||||||
|
loading.close();
|
||||||
});
|
});
|
||||||
|
}).catch((err) => {
|
||||||
|
loading.close();
|
||||||
|
});
|
||||||
|
}).catch((err) => {
|
||||||
|
loading.close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 登录切换
|
// 登录切换
|
||||||
@@ -132,7 +147,6 @@ function register() {
|
|||||||
function fetchQrcode() {
|
function fetchQrcode() {
|
||||||
getVxQrcode().then((res) => {
|
getVxQrcode().then((res) => {
|
||||||
Qrcode.value = res;
|
Qrcode.value = res;
|
||||||
console.log(res);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//查询微信扫码是否成功
|
//查询微信扫码是否成功
|
||||||
|
|||||||
@@ -6,20 +6,31 @@
|
|||||||
<el-splitter-panel size="17%" min="17%" max="25%">
|
<el-splitter-panel size="17%" min="17%" max="25%">
|
||||||
<!-- 会话列表 -->
|
<!-- 会话列表 -->
|
||||||
<div class="demo-panel">
|
<div class="demo-panel">
|
||||||
<div
|
<div class="chatList" style="overflow: auto">
|
||||||
v-infinite-scroll="load"
|
<div
|
||||||
infinite-scroll-distance="100px"
|
class="chatItem"
|
||||||
class="chatList"
|
v-for="(item, index) in chatList"
|
||||||
style="overflow: auto"
|
:key="index"
|
||||||
>
|
@click="handleClick(item)"
|
||||||
<div class="chatItem" v-for="(item, index) in chatList" :key="index">
|
:style="{ background: handleClickdata == item ? '#f5f5f5' : '' }"
|
||||||
<div class="Avatar"></div>
|
>
|
||||||
|
<el-badge
|
||||||
|
:value="item.unread > 0 ? item.unread : ''"
|
||||||
|
:max="999"
|
||||||
|
class="item"
|
||||||
|
>
|
||||||
|
<div class="Avatar">
|
||||||
|
<img class="Avatar-img" :src="item.data.avatar" alt="" />
|
||||||
|
</div>
|
||||||
|
</el-badge>
|
||||||
<div class="chatContent">
|
<div class="chatContent">
|
||||||
<div class="PersonalInfo">
|
<div class="PersonalInfo">
|
||||||
<div class="name">名称</div>
|
<div class="name">{{ item.data.nickname }}</div>
|
||||||
<div class="time">07-29 14:00</div>
|
<div class="time">
|
||||||
|
{{ TimestamptolocalTime(item.lastMessage.timestamp) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chatText">最后一条消息</div>
|
<div class="chatText">{{ item.lastMessage.payload.text }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -29,19 +40,87 @@
|
|||||||
<el-splitter layout="vertical">
|
<el-splitter layout="vertical">
|
||||||
<el-splitter-panel>
|
<el-splitter-panel>
|
||||||
<!-- 消息列表 -->
|
<!-- 消息列表 -->
|
||||||
<div class="demo-panel"></div>
|
<div class="demo-panel">
|
||||||
|
<div class="chatlist" v-if="handleClickdata != null" style="overflow: auto" ref="chatlistContainer">
|
||||||
|
<div
|
||||||
|
class="chatmessages"
|
||||||
|
v-for="(item, index) in messageslist"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<!-- 对方消息 -->
|
||||||
|
<div
|
||||||
|
class="messageOtherSide"
|
||||||
|
v-if="item.senderId == handleClickdata.userId"
|
||||||
|
>
|
||||||
|
<!-- 头像 -->
|
||||||
|
<div class="messageAvatar">
|
||||||
|
<img
|
||||||
|
class="Avatar-img"
|
||||||
|
:src="handleClickdata.data.avatar"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 三角 -->
|
||||||
|
<div class="OtherTriangle" v-if="item.type == 'text'" />
|
||||||
|
<!-- 消息内容 -->
|
||||||
|
<div class="messageContent" :style="{padding:item.type == 'text'?' 10px 20px 10px 20px':'0'}">
|
||||||
|
<!-- 文本消息 -->
|
||||||
|
<div v-if="item.type == 'text'">
|
||||||
|
{{ item.payload.text }}
|
||||||
|
</div>
|
||||||
|
<!-- 图片消息 -->
|
||||||
|
<PictureMessage :item="item" v-if="item.type == 'image'"></PictureMessage>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 自己消息 -->
|
||||||
|
<div class="messageMySide" v-if="item.senderId == user.id">
|
||||||
|
<!-- 消息内容 -->
|
||||||
|
<div class="messageMyContent" :style="{padding:item.type == 'text'?' 10px 20px 10px 20px':''}">
|
||||||
|
<!-- 文本消息 -->
|
||||||
|
<div v-if="item.type == 'text'">
|
||||||
|
{{ item.payload.text }}
|
||||||
|
</div>
|
||||||
|
<!-- 图片消息 -->
|
||||||
|
<PictureMessage :item="item" v-if="item.type == 'image'"></PictureMessage>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="MyTriangle" v-if="item.type == 'text'" />
|
||||||
|
<div class="messageAvatar">
|
||||||
|
<img class="Avatar-img" :src="headerIcon" alt="" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-splitter-panel>
|
</el-splitter-panel>
|
||||||
<el-splitter-panel size="20%" min="20%" max="40%">
|
<el-splitter-panel size="20%" min="20%" max="40%">
|
||||||
<!-- 输入框 -->
|
<!-- 输入框 -->
|
||||||
<div class="demo-panel">
|
<div class="demo-panel">
|
||||||
<div class="inputBox">
|
<div class="inputBox">
|
||||||
<div class="Console">
|
<div class="Console">
|
||||||
<div class="Console-content">
|
<!-- 控制面板 -->
|
||||||
|
<div class="Console-content">
|
||||||
</div>
|
<!-- 其他的消息 -->
|
||||||
|
<div class="chat-input-other">
|
||||||
|
<!-- 图片消息 -->
|
||||||
|
<div class="chat-input-img">
|
||||||
|
<img class="chat-input-img-img" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Album.png" alt="">
|
||||||
|
</div>
|
||||||
|
<!-- 邀请消息 -->
|
||||||
|
<div class="chat-input-img">
|
||||||
|
<img class="chat-input-img-img" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/chat_invite.png" alt="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 发送按钮 -->
|
||||||
|
<div class="chat-input-Send">发送</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<textarea
|
<textarea
|
||||||
v-model="textarea"
|
v-model="textarea"
|
||||||
class="textarea"
|
class="textarea"
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
@@ -64,53 +143,118 @@ import {
|
|||||||
onMounted, // 组件挂载完成后执行
|
onMounted, // 组件挂载完成后执行
|
||||||
onUpdated, // 组件更新后执行
|
onUpdated, // 组件更新后执行
|
||||||
onUnmounted, // 组件销毁前执行
|
onUnmounted, // 组件销毁前执行
|
||||||
|
nextTick, // 确保DOM更新完成
|
||||||
} from "vue";
|
} from "vue";
|
||||||
const refname = ref("");
|
import { goEasyGetConversations, goEasyGetMessages } from "@/utils/goeasy.js";
|
||||||
|
import { TimestamptolocalTime } from "@/utils/timeConversion.js";
|
||||||
|
import { IMloginStore } from "@/stores/notice.js";
|
||||||
|
import { goeasy } from "../../main";
|
||||||
|
import GoEasy from "goeasy";
|
||||||
|
import { getPromiseStorage } from "@/utils/storage.js";
|
||||||
|
import PictureMessage from "@/components/chatMessage/PictureMessage";
|
||||||
|
|
||||||
|
var im = goeasy.im;
|
||||||
|
const counter = IMloginStore();
|
||||||
const textarea = ref(""); // 输入框内容
|
const textarea = ref(""); // 输入框内容
|
||||||
const chatList = ref([
|
const chatList = ref([]); // 会话列表
|
||||||
{},
|
const handleClickdata = ref(null); // 选中会话
|
||||||
{},
|
const messageslist = ref([]); //消息列表
|
||||||
{},
|
const user = ref(null); // 用户信息
|
||||||
{},
|
const headerIcon = ref(null); // 用户头像
|
||||||
{},
|
const chatlistContainer = ref(null); // 聊天列表容器引用
|
||||||
{},
|
const isLoading = ref(false); // 防止重复加载
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
]);
|
|
||||||
|
|
||||||
function load() {
|
// 加载更多消息
|
||||||
console.log("加载更多",textarea.value);
|
function loadMore() {
|
||||||
|
if (isLoading.value) return;
|
||||||
} // 加载更多
|
isLoading.value = true;
|
||||||
|
// 这里添加加载更多消息逻辑/加载完后才改为false
|
||||||
|
getMoreMessages();
|
||||||
|
}
|
||||||
|
|
||||||
watch(refname, async (newQuestion, oldQuestion) => {
|
// 滚动事件处理
|
||||||
// 变化后执行
|
function scrollHandler() {
|
||||||
});
|
const container = chatlistContainer.value;
|
||||||
|
if (container && container.scrollTop <= 0) {
|
||||||
|
loadMore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//选中会话
|
||||||
|
function handleClick(item) {
|
||||||
|
handleClickdata.value = item;
|
||||||
|
console.log(item);
|
||||||
|
goEasyGetMessages({
|
||||||
|
id: item.userId,
|
||||||
|
timestamp: null,
|
||||||
|
}).then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
messageslist.value = res;
|
||||||
|
nextTick(() => {
|
||||||
|
if (chatlistContainer.value) {
|
||||||
|
chatlistContainer.value.scrollTop = chatlistContainer.value.scrollHeight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
chatlistContainer.value.addEventListener('scroll', scrollHandler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取更多消息
|
||||||
|
function getMoreMessages() {
|
||||||
|
goEasyGetMessages({
|
||||||
|
id: handleClickdata.value.userId,
|
||||||
|
timestamp: messageslist.value[0].timestamp,
|
||||||
|
}).then((res) => {
|
||||||
|
isLoading.value = false;
|
||||||
|
messageslist.value.unshift(...res);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新后的最新会话列表
|
||||||
|
function onConversationsUpdated(conversations) {
|
||||||
|
chatList.value = conversations;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取会话列表
|
||||||
|
function getChatList() {
|
||||||
|
goEasyGetConversations().then((res) => {
|
||||||
|
chatList.value = res.content.conversations;
|
||||||
|
console.log(chatList.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
watch(counter, (newQuestion, oldQuestion) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
getChatList();
|
||||||
|
}, 300);
|
||||||
|
}),
|
||||||
|
{ deep: true };
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 组件挂载完成后执行
|
getPromiseStorage("user")
|
||||||
|
.then((res) => {
|
||||||
|
user.value = res;
|
||||||
|
headerIcon.value = user.value.headerIcon;
|
||||||
|
console.log(user.value);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (counter.IMstate == true) {
|
||||||
|
getChatList();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
im.on(GoEasy.IM_EVENT.CONVERSATIONS_UPDATED, onConversationsUpdated);
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
onUpdated(() => {
|
onUpdated(() => {
|
||||||
// 组件更新后执行
|
// 组件更新后执行
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// 组件销毁前执行
|
// 移除滚动事件监听
|
||||||
|
if (chatlistContainer.value) {
|
||||||
|
chatlistContainer.value.removeEventListener('scroll', scrollHandler);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -151,13 +295,18 @@ onUnmounted(() => {
|
|||||||
.Avatar {
|
.Avatar {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
border-radius: 50%;
|
border-radius: 10px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
.Avatar-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
.chatContent {
|
.chatContent {
|
||||||
margin-left: 10px;
|
margin-left: 30px;
|
||||||
width: calc(100% - 80px);
|
width: calc(100% - 100px);
|
||||||
height: 60%;
|
height: 60%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -189,6 +338,76 @@ onUnmounted(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis; /* 显示省略号 */
|
text-overflow: ellipsis; /* 显示省略号 */
|
||||||
}
|
}
|
||||||
|
.chatlist {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.chatmessages {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.messageOtherSide {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: self-start;
|
||||||
|
}
|
||||||
|
.messageMySide {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: self-start;
|
||||||
|
}
|
||||||
|
.messageAvatar {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.OtherTriangle {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 10px solid transparent;
|
||||||
|
border-right: 10px solid #f5f5f5;
|
||||||
|
border-bottom: 10px solid transparent;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.MyTriangle {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 10px solid transparent;
|
||||||
|
border-left: 10px solid #7bbd0093;
|
||||||
|
border-bottom: 10px solid transparent;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
.messageContent {
|
||||||
|
max-width: 30%;
|
||||||
|
height: auto;
|
||||||
|
min-height: 20px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
word-break: break-all; /* 强制换行(适合中文) */
|
||||||
|
overflow-wrap: break-word; /* 长单词换行(适合英文) */
|
||||||
|
white-space: normal; /* 允许自动换行 */
|
||||||
|
}
|
||||||
|
.messageMyContent {
|
||||||
|
max-width: 30%;
|
||||||
|
height: auto;
|
||||||
|
min-height: 20px;
|
||||||
|
background-color: #7bbd0093;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
word-break: break-all; /* 强制换行(适合中文) */
|
||||||
|
overflow-wrap: break-word; /* 长单词换行(适合英文) */
|
||||||
|
white-space: normal; /* 允许自动换行 */
|
||||||
|
}
|
||||||
.inputBox {
|
.inputBox {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -203,21 +422,66 @@ onUnmounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.Console-content{
|
.Console-content {
|
||||||
width: 98%;
|
width: 98%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.chat-input-other{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.chat-input-img{
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
margin-left: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
}
|
||||||
|
.chat-input-img:hover{
|
||||||
|
background-color: #d4d4d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input-img-img{
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.chat-input-Send {
|
||||||
|
width: 10%;
|
||||||
|
height: 80%;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #03aba8;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-right: 6px;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
}
|
||||||
|
.chat-input-Send:hover {
|
||||||
|
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3);
|
||||||
|
background-color: #03aba82d;
|
||||||
|
// color: #ffffff;
|
||||||
|
}
|
||||||
|
.chat-input-Send:active{
|
||||||
|
transition: all 0.1s ease;
|
||||||
|
transform: scale(0.95) !important;
|
||||||
}
|
}
|
||||||
.input {
|
.input {
|
||||||
width: 98%;
|
width: 98%;
|
||||||
height: calc(100% - 70px);
|
height: calc(100% - 70px);
|
||||||
}
|
}
|
||||||
.textarea{
|
.textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color:#ffffff00;
|
background-color: #ffffff00;
|
||||||
resize:none;
|
resize: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -843,6 +843,10 @@ onUnmounted(() => {
|
|||||||
background-color: #03aba82d;
|
background-color: #03aba82d;
|
||||||
// color: #ffffff;
|
// color: #ffffff;
|
||||||
}
|
}
|
||||||
|
.chat-input-Send:active{
|
||||||
|
transition: all 0.1s ease;
|
||||||
|
transform: scale(0.95) !important;
|
||||||
|
}
|
||||||
.chat-input-Textarea {
|
.chat-input-Textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="common-layout">
|
<div class="common-layout">
|
||||||
<el-container>
|
<el-container>
|
||||||
<!-- 左侧导航栏 -->
|
<!-- 左侧导航栏 -->
|
||||||
<el-aside class="nav-aside">
|
<el-aside class="nav-aside">
|
||||||
<Appaside></Appaside>
|
<Appaside></Appaside>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
@@ -15,8 +15,49 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Appaside from "/src/components/Appaside.vue";
|
import Appaside from "/src/components/Appaside.vue";
|
||||||
|
import { ref, watch, onMounted, onUnmounted } from "vue";
|
||||||
|
import { getOtp } from "@/api/account";
|
||||||
|
const user = ref(null); // 用户信息
|
||||||
|
import { goEasyLink } from "@/utils/goeasy.js";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import {getPromiseStorage } from "@/utils/storage.js";
|
||||||
|
const router = useRouter();
|
||||||
|
//自动链接IM
|
||||||
|
function autoLinkIM() {
|
||||||
|
getOtp()
|
||||||
|
.then((res) => {
|
||||||
|
const data = {
|
||||||
|
id: String(user.value.id),
|
||||||
|
avatar: user.value.headerIcon,
|
||||||
|
nickname: user.value.nickName,
|
||||||
|
key: res,
|
||||||
|
};
|
||||||
|
goEasyLink(data)
|
||||||
|
.then(() => {
|
||||||
|
console.log("IM链接成功");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
ElMessage.error("聊天系统链接失败");
|
||||||
|
router.push("/");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
ElMessage.error("聊天系统获取失败");
|
||||||
|
router.push("/");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getPromiseStorage("user")
|
||||||
|
.then((res) => {
|
||||||
|
user.value = res;
|
||||||
|
autoLinkIM() //自动链接IM
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@@ -43,4 +84,4 @@ html {
|
|||||||
// background-image: linear-gradient(0deg, @bg-Sidebar-color-top, @bg-color);
|
// background-image: linear-gradient(0deg, @bg-Sidebar-color-top, @bg-color);
|
||||||
// border: 2px solid @border-color;
|
// border: 2px solid @border-color;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user