Commit 2b02de5c by panjiangyi

成员名字

parent 803da04e
<template>
<div
class="message-con d-flex"
:class="
isMyMessage
? 'my-message align-items-start flex-row-reverse'
: 'align-items-start'
"
>
<span class="no-selection">
<avatar :size="40" class="msg-avatar" :shape="shape" :src="avatar" />
</span>
<div class="msg-content">
<div class="msg-name no-selection">{{ username }}</div>
<!-- Image -->
<div
class="msg-detail image-message"
:class="{ 'image-404': fileFailed2Load }"
v-if="messageType === 'image'"
@dblclick="openFile"
>
<img
v-if="messageRealUrl"
:src="messageRealUrl"
:title="messageBody.msg.name"
:alt="messageBody.msg.name"
/>
<file-icon v-else-if="fileFailed2Load" :value="image404"></file-icon>
</div>
<!-- File -->
<div
class="msg-detail file-message d-flex"
v-else-if="messageType === 'file'"
@dblclick="openFile"
>
<div class="file-message-info">
<div
class="text-nowrap text-truncate file-message-name"
:title="messageBody.msg.name"
>
{{ messageBody.msg.name }}
</div>
<div class="text-hint">
{{ messageBody.msg.size | formatSize }}
</div>
</div>
<file-icon :value="fileIcon"></file-icon>
</div>
<!-- Audio -->
<div
class="msg-detail voice-message d-flex align-items-center"
:class="{ playing: playing, 'can-play': messageRealUrl }"
v-else-if="messageType === 'voice'"
@click.stop="play"
:style="{ width: getVoiceMessageWidth + 'px' }"
>
<div class="d-flex align-items-center" v-if="messageRealUrl">
<voice-icon :loading="playing"></voice-icon>
<audio ref="audio" @play="onPlay" @pause="onPause">
<source type="audio/aac" :src="messageRealUrl" />
</audio>
<span v-if="duration" class="duration text-nowrap text-hint"
>{{ durationInSecond }}s</span
>
</div>
<i
class="el-icon-warning-outline"
v-else-if="fileFailed2Load"
title="[语音加载失败]"
></i>
</div>
<!-- Video -->
<div
class="
<div
class="message-con d-flex align-items-center"
:class="isMyMessage ? 'my-message flex-row-reverse' : ''"
>
<div class="msg-content">
<div class="msg-name no-selection">{{ senderName }}</div>
<!-- Image -->
<div
class="msg-detail image-message"
:class="{ 'image-404': fileFailed2Load }"
v-if="messageType === 'image'"
@dblclick="openFile"
>
<img
v-if="messageRealUrl"
:src="messageRealUrl"
:title="messageBody.msg.name"
:alt="messageBody.msg.name"
/>
<file-icon
v-else-if="fileFailed2Load"
:value="image404"
></file-icon>
</div>
<!-- File -->
<div
class="msg-detail file-message d-flex"
v-else-if="messageType === 'file'"
@dblclick="openFile"
>
<div class="file-message-info">
<div
class="text-nowrap text-truncate file-message-name"
:title="messageBody.msg.name"
>
{{ messageBody.msg.name }}
</div>
<div class="text-hint">
{{ messageBody.msg.size | formatSize }}
</div>
</div>
<file-icon :value="fileIcon"></file-icon>
</div>
<!-- Audio -->
<div
class="msg-detail voice-message d-flex align-items-center"
:class="{ playing: playing, 'can-play': messageRealUrl }"
v-else-if="messageType === 'voice'"
@click.stop="play"
:style="{ width: getVoiceMessageWidth + 'px' }"
>
<div class="d-flex align-items-center" v-if="messageRealUrl">
<voice-icon :loading="playing"></voice-icon>
<audio ref="audio" @play="onPlay" @pause="onPause">
<source type="audio/aac" :src="messageRealUrl" />
</audio>
<span v-if="duration" class="duration text-nowrap text-hint"
>{{ durationInSecond }}s</span
>
</div>
<i
class="el-icon-warning-outline"
v-else-if="fileFailed2Load"
title="[语音加载失败]"
></i>
</div>
<!-- Video -->
<div
class="
msg-detail
video-message
d-flex
align-items-center
justify-content-center
"
v-else-if="messageType === 'video'"
>
<video-player-icon @click.native="openFile"></video-player-icon>
</div>
<!-- Text -->
<div
class="msg-detail inline-text"
v-else
v-html="format2Link(messageBody.msg.text || emptyText)"
></div>
</div>
v-else-if="messageType === 'video'"
>
<video-player-icon @click.native="openFile"></video-player-icon>
</div>
<!-- Text -->
<div
class="msg-detail inline-text"
v-else
v-html="format2Link(messageBody.msg.text || emptyText)"
></div>
</div>
<a
v-if="!isSendingMessage && messageType === 'file'"
class="
<a
v-if="!isSendingMessage && messageType === 'file'"
class="
d-flex
align-items-center
justify-content-center
download-icon
"
:href="messageRealUrl | downloadUrl(getAttachment)"
:download="getAttachment"
title="下载文件"
>
<img src="~@/customer-service/imgs/download.png" alt="Download" />
</a>
<i class="el-icon-warning text-danger" v-if="failed" title="发送失败"></i>
<i class="el-icon-loading" v-else-if="isSendingMessage"></i>
<template v-if="showReadSummary">
<div v-if="isMyMessage" class="msg-read pos-rel">
<span @click="readListVisibility = true" class="pointer">
<template v-if="isAllRead">全部已读</template>
<template v-else-if="data.read_count > 0"
>{{ data.read_count }}人已读</template
>
<template v-else>未读</template>
</span>
<who-read-list
v-if="readListVisibility"
@blur="readListVisibility = false"
:msgId="data.id"
/>
</div>
</template>
</div>
:href="messageRealUrl | downloadUrl(getAttachment)"
:download="getAttachment"
title="下载文件"
>
<img src="~@/customer-service/imgs/download.png" alt="Download" />
</a>
<i
class="el-icon-warning text-danger"
v-if="failed"
title="发送失败"
></i>
<i class="el-icon-loading" v-else-if="isSendingMessage"></i>
<template v-if="showReadSummary">
<div v-if="isMyMessage" class="msg-read pos-rel">
<span @click="readListVisibility = true" class="pointer">
<template v-if="isAllRead">全部已读</template>
<template v-else-if="data.read_count > 0"
>{{ data.read_count }}人已读</template
>
<template v-else>未读</template>
</span>
<who-read-list
v-if="readListVisibility"
@blur="readListVisibility = false"
:msgId="data.id"
/>
</div>
</template>
</div>
</template>
<script lang="ts">
import { Component, Inject, Mixins, Prop, Ref } from "vue-property-decorator";
import { Filters } from '../mixin/filter';
import { Filters } from "../mixin/filter";
import * as dto from "../model";
import { isAccessibleUrl } from "../service/tools";
import { replaceText2Link } from "../utils";
import { getUserInfo } from "../utils/user-info";
import chat from "./../xim";
import {
FileType,
getFileType,
isAudio,
isImage,
isVideo,
MAX_FILE_SIZE,
MAX_IMAGE_SIZE,
FileType,
getFileType,
isAudio,
isImage,
isVideo,
MAX_FILE_SIZE,
MAX_IMAGE_SIZE,
} from "./file-controller";
import FileIcon from "./file-icon.vue";
import VideoPlayerIcon from "./video-player-icon.vue";
......@@ -156,460 +156,459 @@ import avatar from "@/customer-service/components/avatar.vue";
import { chatStore, ChatStore } from "@/customer-service/store/model";
@Component({
components: { FileIcon, VoiceIcon, WhoReadList, VideoPlayerIcon, avatar },
components: { FileIcon, VoiceIcon, WhoReadList, VideoPlayerIcon, avatar },
})
export default class Message extends Mixins(Filters) {
@chatStore.State(ChatStore.STATE_CHAT_MY_ID)
private readonly chatMyId!: ChatStore.STATE_CHAT_MY_ID;
@chatStore.State(ChatStore.STATE_CHAT_MY_ID)
private readonly chatMyId!: ChatStore.STATE_CHAT_MY_ID;
@chatStore.Getter(ChatStore.GETTER_CURRENT_CHAT_PRESENT_MEMBERS)
private readonly chatMembers!: ChatStore.GETTER_CURRENT_CHAT_PRESENT_MEMBERS;
@chatStore.Getter(ChatStore.GETTER_CURRENT_CHAT_PRESENT_MEMBERS)
private readonly chatMembers!: ChatStore.GETTER_CURRENT_CHAT_PRESENT_MEMBERS;
@chatStore.State(ChatStore.STATE_CHAT_SOURCE)
private readonly chatSource!: ChatStore.STATE_CHAT_SOURCE;
@chatStore.State(ChatStore.STATE_CHAT_SOURCE)
private readonly chatSource!: ChatStore.STATE_CHAT_SOURCE;
@chatStore.State(ChatStore.STATE_CHAT_CURRENT_CHAT_ID)
private readonly chatId!: ChatStore.STATE_CHAT_CURRENT_CHAT_ID;
@chatStore.State(ChatStore.STATE_CHAT_CURRENT_CHAT_ID)
private readonly chatId!: ChatStore.STATE_CHAT_CURRENT_CHAT_ID;
/**
* tbd: 文件消息所在的域名的url,逻辑需要补充
*/
private messageRealUrl = "";
private fileFailed2Load = false;
private image404 = FileType.Image_404;
private loadingRealUrl = false;
/**
* tbd: 文件消息所在的域名的url,逻辑需要补充
*/
private messageRealUrl = "";
private fileFailed2Load = false;
private image404 = FileType.Image_404;
private loadingRealUrl = false;
private senderName = "";
@Prop({ type: Object, default: () => Object.create(null) })
private data!: dto.Message;
@Prop({ type: Object, default: () => Object.create(null) })
private data!: dto.Message;
@Prop()
private isSendingMessage!: boolean;
@Prop()
private isSendingMessage!: boolean;
@Prop()
private failed!: boolean;
@Prop()
private failed!: boolean;
@Prop({ default: "circle" })
private shape!: string;
@Prop({ default: "circle" })
private shape!: string;
@Ref("audio")
private readonly audioRef!: HTMLAudioElement;
@Ref("audio")
private readonly audioRef!: HTMLAudioElement;
private playing = false;
private playing = false;
@Inject({ default: false }) readonly showReadSummary!: boolean;
@Inject({ default: false }) readonly showReadSummary!: boolean;
private emptyText = " ";
private emptyText = " ";
private readListVisibility = false;
private readListVisibility = false;
private org = "";
private org = "";
private get isAllRead() {
return this.data.read_count >= this.data.total_read_count;
}
private get messageBody(): { eid?: string; oid?: string; msg: any } {
if (this.data) {
try {
return { ...this.data, msg: JSON.parse(this.data.msg) };
} catch {
return {
...this.data,
msg: JSON.parse(this.data.msg.replace(/\n/g, "\\n")),
};
}
private get isAllRead() {
return this.data.read_count >= this.data.total_read_count;
}
return { msg: { text: "" } };
}
private get messageBody(): { eid?: string; oid?: string; msg: any } {
if (this.data) {
try {
return { ...this.data, msg: JSON.parse(this.data.msg) };
} catch {
return {
...this.data,
msg: JSON.parse(this.data.msg.replace(/\n/g, "\\n")),
};
}
}
private get getAttachment() {
if (this.messageBody) {
return this.messageBody.msg.name;
return { msg: { text: "" } };
}
return "文件下载";
}
private get isMyMessage() {
if (this.isSendingMessage) {
return true;
private get getAttachment() {
if (this.messageBody) {
return this.messageBody.msg.name;
}
return "文件下载";
}
const senderEid = this.messageBody.eid;
if (this.messageBody) {
const msg = this.messageBody;
if (this.chatSource) {
const source = msg.msg.source;
if (source) {
return (
source === this.chatSource && senderEid === this.chatMyId
);
private get isMyMessage() {
if (this.isSendingMessage) {
return true;
}
if (this.org && this.messageBody.oid) {
return (
this.messageBody.oid === this.org &&
senderEid === this.chatMyId
);
const senderEid = this.messageBody.eid;
if (this.messageBody) {
const msg = this.messageBody;
if (this.chatSource) {
const source = msg.msg.source;
if (source) {
return (
source === this.chatSource &&
senderEid === this.chatMyId
);
}
if (this.org && this.messageBody.oid) {
return (
this.messageBody.oid === this.org &&
senderEid === this.chatMyId
);
}
return false;
}
return senderEid === this.chatMyId;
}
return false;
}
}
return senderEid === this.chatMyId;
public created() {
this.getUserName(this.data.eid);
}
return false;
}
private get username() {
const avatar: any = chat.getUserMapping();
if (this.data == null) return "";
if (avatar == null) return this.data.id;
const value = avatar[this.data.eid];
if (value == null) return "";
if (value.name == null) return "";
return value.name;
}
private get avatar() {
const avatar = chat.getUserMapping();
if (this.isSendingMessage) {
if (avatar && this.chatMyId) {
const user = avatar[this.chatMyId];
if (user && user.avatar) {
return user.avatar;
}
}
private async getUserName(eid: string) {
const data = await getUserInfo(eid);
this.senderName = data.name;
}
if (avatar && this.data) {
const value = avatar[this.data.eid];
if (value && value.avatar) {
return value.avatar;
}
private get avatar() {
const avatar = chat.getUserMapping();
if (this.isSendingMessage) {
if (avatar && this.chatMyId) {
const user = avatar[this.chatMyId];
if (user && user.avatar) {
return user.avatar;
}
}
}
if (avatar && this.data) {
const value = avatar[this.data.eid];
if (value && value.avatar) {
return value.avatar;
}
}
return "";
}
return "";
}
private get fileIcon() {
if (this.data) {
return getFileType(this.messageBody.msg.name);
}
private get fileIcon() {
if (this.data) {
return getFileType(this.messageBody.msg.name);
return FileType.Others;
}
return FileType.Others;
}
private get messageType() {
const type = this.data?.type;
if (type === "file") {
const name = this.messageBody?.msg.name;
if (name) {
const size = this.messageBody?.msg.size;
if (size) {
const outImageSize = size > MAX_IMAGE_SIZE;
if (!outImageSize && isImage(name)) {
return "image";
}
const outSize = size > MAX_FILE_SIZE;
if (!outSize) {
if (isAudio(name)) {
return "voice";
}
if (isVideo(name)) {
return "video";
private get messageType() {
const type = this.data?.type;
if (type === "file") {
const name = this.messageBody?.msg.name;
if (name) {
const size = this.messageBody?.msg.size;
if (size) {
const outImageSize = size > MAX_IMAGE_SIZE;
if (!outImageSize && isImage(name)) {
return "image";
}
const outSize = size > MAX_FILE_SIZE;
if (!outSize) {
if (isAudio(name)) {
return "voice";
}
if (isVideo(name)) {
return "video";
}
}
}
}
}
}
}
}
return this.data?.type;
}
// 图片的样式设置,通过js偶尔会有高度计算不准确, 直接通过css的处理目前看可以达到对应效果
// private get imageStyle() {
// if (this.messageBody == null) return {};
// if (this.messageBody.msg.w == null) return {};
// if (this.messageBody.msg.h == null) return {};
// const w = this.messageBody.msg.w;
// const h = this.messageBody.msg.h;
// const maxWidth = 300;
// const maxHeight = maxWidth * (h / w);
// return { width: `${w}px`, height: `${h}px`, maxHeight: `${maxHeight}px` };
// }
private get duration() {
const v = this.messageBody.msg.duration as number;
return v || 0;
}
private get durationInSecond() {
return Math.round(this.duration / 1000);
}
private get getVoiceMessageWidth() {
if (this.fileFailed2Load) {
return 35;
return this.data?.type;
}
const d = this.duration / 1000;
if (d <= 3) {
return 60;
// 图片的样式设置,通过js偶尔会有高度计算不准确, 直接通过css的处理目前看可以达到对应效果
// private get imageStyle() {
// if (this.messageBody == null) return {};
// if (this.messageBody.msg.w == null) return {};
// if (this.messageBody.msg.h == null) return {};
// const w = this.messageBody.msg.w;
// const h = this.messageBody.msg.h;
// const maxWidth = 300;
// const maxHeight = maxWidth * (h / w);
// return { width: `${w}px`, height: `${h}px`, maxHeight: `${maxHeight}px` };
// }
private get duration() {
const v = this.messageBody.msg.duration as number;
return v || 0;
}
if (d >= 60) {
return 200;
private get durationInSecond() {
return Math.round(this.duration / 1000);
}
return 60 + d;
}
private get getVoiceMessageWidth() {
if (this.fileFailed2Load) {
return 35;
}
const d = this.duration / 1000;
if (d <= 3) {
return 60;
}
private isCustomer() {
return !this.showReadSummary;
}
if (d >= 60) {
return 200;
}
private buildMessageUrl() {
if (this.messageRealUrl || this.loadingRealUrl) {
return;
}
const url = this.messageBody.msg.url as string;
if (url) {
// const service = XimService.getInstance()
if (isAccessibleUrl(url)) {
return (this.messageRealUrl = url);
}
this.loadingRealUrl = true;
// service
// .getFileUrlById(url, this.chatId || 0, this.isCustomer())
// .then((data) => {
// if (data && data.itemList) {
// this.messageRealUrl = data.itemList[0].url
// } else {
// this.fileFailed2Load = true
// }
// })
// .catch(() => (this.fileFailed2Load = true))
// .finally(() => (this.loadingRealUrl = false))
} else {
this.fileFailed2Load = true;
return 60 + d;
}
}
private openFile() {
if (this.isSendingMessage) {
return;
private isCustomer() {
return !this.showReadSummary;
}
if (this.failed || this.fileFailed2Load) {
return;
private buildMessageUrl() {
if (this.messageRealUrl || this.loadingRealUrl) {
return;
}
const url = this.messageBody.msg.url as string;
if (url) {
// const service = XimService.getInstance()
if (isAccessibleUrl(url)) {
return (this.messageRealUrl = url);
}
this.loadingRealUrl = true;
// service
// .getFileUrlById(url, this.chatId || 0, this.isCustomer())
// .then((data) => {
// if (data && data.itemList) {
// this.messageRealUrl = data.itemList[0].url
// } else {
// this.fileFailed2Load = true
// }
// })
// .catch(() => (this.fileFailed2Load = true))
// .finally(() => (this.loadingRealUrl = false))
} else {
this.fileFailed2Load = true;
}
}
const copy = { ...this.messageBody.msg };
if (this.messageRealUrl) {
copy.url = this.messageRealUrl;
private openFile() {
if (this.isSendingMessage) {
return;
}
if (this.failed || this.fileFailed2Load) {
return;
}
const copy = { ...this.messageBody.msg };
if (this.messageRealUrl) {
copy.url = this.messageRealUrl;
}
this.$emit("open", { type: this.messageType, msg: copy });
}
this.$emit("open", { type: this.messageType, msg: copy });
}
private play() {
if (this.audioRef?.paused) {
this.audioRef?.load();
this.audioRef?.play();
} else {
this.audioRef?.pause();
private play() {
if (this.audioRef?.paused) {
this.audioRef?.load();
this.audioRef?.play();
} else {
this.audioRef?.pause();
}
}
}
private onPlay() {
this.playing = true;
}
private onPlay() {
this.playing = true;
}
private onPause() {
this.playing = false;
}
private onPause() {
this.playing = false;
}
private format2Link(text: string) {
return replaceText2Link(text);
}
private format2Link(text: string) {
return replaceText2Link(text);
}
}
</script>
<style lang="less" scoped>
.message-con {
margin: 20px 0;
margin: 20px 0;
&.my-message {
.msg-avatar {
margin-right: 0;
margin-left: 10px;
}
&.my-message {
.msg-avatar {
margin-right: 0;
margin-left: 10px;
}
.msg-name {
display: none;
}
.msg-detail {
margin-top: 0;
background-color: #dbf2ff;
border-radius: 8px 0 8px 8px;
.msg-detail {
margin-top: 0;
background-color: #dbf2ff;
border-radius: 8px 0 8px 8px;
&.image-message:not(.image-404),
&.file-message {
background-color: transparent;
border-radius: 4px;
border: 1px solid #c5d4e5;
}
&.image-message:not(.image-404),
&.file-message {
background-color: transparent;
border-radius: 4px;
border: 1px solid #c5d4e5;
}
&.voice-message {
> div {
flex-flow: row-reverse;
}
&.voice-message {
> div {
flex-flow: row-reverse;
}
svg {
transform: rotateY(180deg);
}
}
svg {
transform: rotateY(180deg);
&.video-message {
background-color: #000;
border-radius: 0;
}
}
}
&.video-message {
background-color: #000;
border-radius: 0;
}
}
.msg-read {
display: inline-block;
color: #bfe1ff;
margin-right: 15px;
user-select: none;
flex: none;
}
.msg-read {
display: inline-block;
color: #bfe1ff;
margin-right: 15px;
user-select: none;
flex: none;
.download-icon {
margin-right: 15px;
margin-left: 0;
margin-top: 0;
}
}
.download-icon {
margin-right: 15px;
margin-left: 0;
margin-top: 0;
> i {
height: 16px;
font-size: 16px;
margin-right: 10px;
}
}
> i {
height: 16px;
font-size: 16px;
margin-right: 10px;
}
}
.msg-avatar {
margin-right: 10px;
flex: 40px 0 0;
margin-right: 10px;
flex: 40px 0 0;
}
i.msg-avatar {
font-size: 30px;
background-color: #c0c4cc;
border-radius: 4px;
width: 40px;
height: 40px;
&:before {
position: relative;
left: 5px;
top: 5px;
color: #fff;
}
font-size: 30px;
background-color: #c0c4cc;
border-radius: 4px;
width: 40px;
height: 40px;
&:before {
position: relative;
left: 5px;
top: 5px;
color: #fff;
}
}
.msg-name {
font-size: 12px;
color: #888;
font-size: 14px;
color: #888;
text-align: right;
margin-bottom: 3px;
}
.msg-detail {
margin-top: 10px;
font-size: 14px;
line-height: 20px;
background: #f5f6fa;
border-radius: 0px 8px 8px;
padding: 10px;
word-break: break-word;
&.image-message,
&.file-message {
background-color: transparent;
border-radius: 4px;
border: 1px solid #c5d4e5;
}
margin-top: 10px;
font-size: 14px;
line-height: 20px;
background: #f5f6fa;
border-radius: 0px 8px 8px;
padding: 10px;
word-break: break-word;
&.image-message,
&.file-message {
background-color: transparent;
border-radius: 4px;
border: 1px solid #c5d4e5;
}
&.image-message {
line-height: 1;
&.image-message {
line-height: 1;
&.image-404 {
background: #f7f8fa;
display: flex;
align-items: center;
justify-content: center;
&.image-404 {
background: #f7f8fa;
display: flex;
align-items: center;
justify-content: center;
.file-icon {
margin: 0;
}
.file-icon {
margin: 0;
}
}
}
}
&.voice-message {
height: 40px;
width: 200px;
&.voice-message {
height: 40px;
width: 200px;
&.can-play {
cursor: pointer;
}
&.can-play {
cursor: pointer;
}
i {
font-size: 16px;
i {
font-size: 16px;
}
}
}
&.video-message {
height: 160px;
width: 200px;
background-color: #000;
border-radius: 0;
&.video-message {
height: 160px;
width: 200px;
background-color: #000;
border-radius: 0;
svg {
cursor: pointer;
svg {
cursor: pointer;
}
}
}
&.inline-text {
display: inline-block;
}
&.inline-text {
display: inline-block;
}
.file-message-name {
max-width: 130px;
}
.file-message-name {
max-width: 130px;
}
img {
max-width: 300px;
}
img {
max-width: 300px;
}
}
.download-icon {
cursor: pointer;
text-decoration: none;
margin-left: 15px;
margin-top: 42px;
cursor: pointer;
text-decoration: none;
margin-left: 15px;
margin-top: 42px;
i {
color: #fff;
font-size: 14px;
}
i {
color: #fff;
font-size: 14px;
}
}
.no-selection {
user-select: none;
user-select: none;
}
.image-message {
max-width: 300px;
box-sizing: content-box;
img {
width: 100%;
}
max-width: 300px;
box-sizing: content-box;
img {
width: 100%;
}
}
</style>
......@@ -5,6 +5,7 @@ import { ChatMember } from "../model";
import { isAccessibleUrl } from "../service/tools";
import { unique } from "../utils";
import { decode } from "../utils/jwt";
import { getUserInfo } from "../utils/user-info";
import Chat from "../xim";
import chatType from "../xim/chat-type";
import xim, { ChatNotifyListener } from "../xim/xim";
......@@ -548,14 +549,10 @@ export default {
chatMembers.map(async (member) => {
let result: NonNullable<ChatStore.STATE_CURRENT_CHAT_MEMBERS>[number];
try {
const info = await sdk()
.model("user")
.detail(member.eid)
.query();
const data = await getUserInfo(member.eid);
result = {
...member,
name: info.row.first_name.value as string,
phone: info.row.last_name.value as string,
...data,
};
} catch (error) {
// eslint-disable-next-line no-console
......@@ -621,7 +618,7 @@ export default {
});
detailManager.done();
await action.execute();
await new Promise(resolve => setTimeout(resolve, 500));
await new Promise((resolve) => setTimeout(resolve, 500));
await dispatch(ChatStore.ACTION_GET_CHAT_MEMBERS);
},
},
......
import Chat from "../xim";
export type UserMapping = {
[eid: string]: {
name: string;
phone: string;
};
};
const userMapping: UserMapping = {};
export const getUserMapping = () => userMapping;
export async function getUserInfo(eid: string) {
if (userMapping[eid] != null) return userMapping[eid];
const info = await Chat.getSdk().model("user").detail(eid).query();
const data = {
name: info.row.first_name.value as string,
phone: info.row.last_name.value as string,
};
userMapping[eid] = data;
return data;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment