Commit 03c9c8d6 by panjiangyi

格式化代码

parent 342401e1
......@@ -71,25 +71,26 @@
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from "vue-property-decorator"
import { chatStore, ChatStore } from "@/customer-service/store/model"
import buttonThrottle from "@/utils/button-throttle";
import { Component, Prop, Vue } from "vue-property-decorator";
import { chatStore, ChatStore } from "@/customer-service/store/model";
// import { popupService } from "@/views/common-module/component/element-upgrades/fast-service-popup";
import buttonThrottle from "@/utils/button-throttle"
import Chat from "@/customer-service/xim"
import { formatTime, TimeFormatRule } from "@/customer-service/utils/time"
import { formatTime, TimeFormatRule } from "@/customer-service/utils/time";
import Chat from "@/customer-service/xim";
export function parserMessage(type: string, rawMsg: string) {
if (!type) return ""
if (!rawMsg) return ""
const msg = JSON.parse(rawMsg)
if (!type) return "";
if (!rawMsg) return "";
const msg = JSON.parse(rawMsg);
if (type === "text") {
return msg.text
return msg.text;
} else if (type === "image") {
return `[图片]`
return `[图片]`;
} else if (type === "file") {
return `[文件]`
return `[文件]`;
} else {
;`[不支持的消息格式]`
return `[不支持的消息格式]`;
}
}
type Chat = ChatStore.STATE_MY_CHAT_ROOM_LIST["list"][number]
......@@ -101,8 +102,10 @@ export default class ChatList extends Vue {
@chatStore.State(ChatStore.STATE_CHAT_CURRENT_CHAT_ID)
private readonly chatId!: ChatStore.STATE_CHAT_CURRENT_CHAT_ID
@chatStore.State(ChatStore.STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID)
private readonly currentChatUniplatId!: ChatStore.STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID
@chatStore.State(ChatStore.STATE_CHAT_CURRENT_CHAT_VERSION)
private readonly uniplatVersion!: ChatStore.STATE_CHAT_CURRENT_CHAT_VERSION
......@@ -127,58 +130,58 @@ export default class ChatList extends Vue {
private searchKeyword = ""
private get chatRooms() {
return this.chatList?.list || []
return this.chatList?.list || [];
}
private isSelected(item: Chat) {
if (this.currentChatUniplatId) {
return item.uniplatId === this.currentChatUniplatId
return item.uniplatId === this.currentChatUniplatId;
}
return this.selected === item.uniplatId
return this.selected === item.uniplatId;
}
async created() {
await this.getMyChatList()
this.setSource(ChatStore.StateChatSourceDirection.Server)
this.selectFirstChat()
await this.getMyChatList();
this.setSource(ChatStore.StateChatSourceDirection.Server);
this.selectFirstChat();
}
mounted() {
this.saveMyId()
this.goToOnlyRoom()
this.saveMyId();
this.goToOnlyRoom();
}
private goToOnlyRoom() {
if (this.chatRooms.length === 1) {
const wantedChat = this.chatRooms[0]
this.goToChatRoom(wantedChat)
const wantedChat = this.chatRooms[0];
this.goToChatRoom(wantedChat);
}
}
private selectFirstChat() {
if (this.chatId != null) return
if (!this.chatRooms.length) return
const { chat_id, uniplat_version, uniplatId } = this.chatRooms[0]
if (this.chatId != null) return;
if (!this.chatRooms.length) return;
const { chat_id, uniplat_version, uniplatId } = this.chatRooms[0];
this.saveChatId({
chatId: chat_id,
v: uniplat_version,
uniplatId,
})
});
}
@buttonThrottle()
private async search() {
this.searchKeyword = this.searchKeyword.trim()
this.searchKeyword = this.searchKeyword.trim();
if (!this.searchKeyword) {
await this.getMyChatList()
await this.getMyChatList();
} else {
await this.getMyChatList(this.searchKeyword)
await this.getMyChatList(this.searchKeyword);
}
}
private goToChatRoom(data: Chat) {
if (this.currentChatUniplatId === data.uniplatId) {
return
return;
}
this.saveChatId({
......@@ -186,21 +189,21 @@ export default class ChatList extends Vue {
.chat_id,
v: data.uniplat_version,
uniplatId: data.uniplatId,
}).finally(this.raiseChatIdChanged)
}).finally(this.raiseChatIdChanged);
this.saveChatTitle(data.uniplatId)
this.saveChatTitle(data.uniplatId);
}
private raiseChatIdChanged() {
this.$emit("change")
this.$emit("change");
}
private parseMesage(data: Chat) {
return parserMessage(data.msg_type, data.msg)
return parserMessage(data.msg_type, data.msg);
}
private formatTimestamp(v: number) {
return formatTime(v, { short: true, rule: TimeFormatRule.Hour12 })
return formatTime(v, { short: true, rule: TimeFormatRule.Hour12 });
}
}
</script>
......
......@@ -86,17 +86,18 @@
<script lang="ts">
import {
Component,
Watch,
Vue,
Ref,
Provide,
Prop,
} from "vue-property-decorator"
import MessageInput from "@/customer-service/message-input.vue"
import messages from "@/customer-service/message-list.vue"
Provide,
Ref,
Vue,
Watch,
} from "vue-property-decorator";
import MessageInput from "@/customer-service/message-input.vue";
import messages from "@/customer-service/message-list.vue";
// import CusomterInfo from "./customer-info.vue"
// import OrderInfo from "./order-info.vue"
import { ChatStore, chatStore } from "@/customer-service/store/model"
import { ChatStore, chatStore } from "@/customer-service/store/model";
type RoomInfoTab = "customer" | "order"
......@@ -114,25 +115,31 @@ export default class ChatRoom extends Vue {
@chatStore.Mutation(ChatStore.MUTATION_CLEAR_CURRENT_CHAT_MEMBERS)
private readonly clearChatMembers!: ChatStore.MUTATION_CLEAR_CURRENT_CHAT_MEMBERS
@chatStore.State(ChatStore.STATE_CURRENT_CHAT_TITLE)
private readonly chatTitle!: ChatStore.STATE_CURRENT_CHAT_TITLE
@chatStore.State(ChatStore.STATE_CURRENT_CHAT_INPUTING)
private readonly currentInputPeople!: ChatStore.STATE_CURRENT_CHAT_INPUTING
@chatStore.State(ChatStore.STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID)
private readonly currentChatUniplatId!: ChatStore.STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID
@chatStore.State(ChatStore.STATE_MY_CHAT_ROOM_LIST)
private readonly myChatList!: ChatStore.STATE_MY_CHAT_ROOM_LIST
private allChatList = { list: [] }
@Prop({ type: Function })
private close?: () => void
@Provide() showReadSummary = true
@Watch("currentChatUniplatId")
private whenCurrentChatIdChanged(newValue: string, oldValue: string) {
if (Number(oldValue) === Number(newValue)) return
this.hideMembers()
this.clearChatMembers()
if (Number(oldValue) === Number(newValue)) return;
this.hideMembers();
this.clearChatMembers();
}
private activeTab: RoomInfoTab = "customer"
......@@ -141,38 +148,41 @@ export default class ChatRoom extends Vue {
private get getCurrentInputingPeople() {
return this.currentInputPeople
.map((k) => "" /* this.userInfo[k].name */)
.join("、")
.join("、");
}
private get currentChat() {
const chatId = this.currentChatUniplatId
let result = this.myChatList.list.find((k) => k.uniplatId === chatId)
if (result) return result
result = this.allChatList.list.find((k) => k.uniplatId === chatId)
return result ?? {}
const chatId = this.currentChatUniplatId;
let result = this.myChatList.list.find((k) => k.uniplatId === chatId);
if (result) return result;
result = this.allChatList.list.find((k) => k.uniplatId === chatId);
return result ?? {};
}
private get notOnlyCheck(): boolean {
return true
return true;
}
private get customerInfoTabShow() {
return this.activeTab === "customer"
return this.activeTab === "customer";
}
private get orderInfoTabShow() {
return this.activeTab === "order"
return this.activeTab === "order";
}
private showMembers() {
this.membersPanelVisibility = !this.membersPanelVisibility
this.membersPanelVisibility = !this.membersPanelVisibility;
}
private hideMembers() {
this.membersPanelVisibility = false
this.membersPanelVisibility = false;
}
private onError(msg: string) {
console.error(msg)
this.$message.error(msg)
// eslint-disable-next-line no-console
console.error(msg);
this.$message.error(msg);
}
}
</script>
......
......@@ -19,11 +19,13 @@
</el-dialog>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator"
import MessageList from "./message-list.vue"
import ChatRoom from "./chat-room.vue"
import ChatList from "./chat-list.vue"
import { ChatStore, chatStore } from "@/customer-service/store/model"
import { Component, Vue } from "vue-property-decorator";
import ChatList from "./chat-list.vue";
import ChatRoom from "./chat-room.vue";
import MessageList from "./message-list.vue";
import { ChatStore, chatStore } from "@/customer-service/store/model";
@Component({ components: { MessageList, ChatRoom, ChatList } })
export default class Chat extends Vue {
......@@ -32,13 +34,15 @@ export default class Chat extends Vue {
@chatStore.State(ChatStore.STATE_CHAT_DIALOG_VISIBLE)
private readonly visible: ChatStore.STATE_CHAT_DIALOG_VISIBLE
@chatStore.Mutation(ChatStore.MUTATION_HIDE_CHAT)
private readonly hide: ChatStore.MUTATION_HIDE_CHAT
@chatStore.Action(ChatStore.ACTION_TERINATE_CHAT)
private readonly _terminate: ChatStore.ACTION_TERINATE_CHAT
private terminate() {
this._terminate()
this._terminate();
}
}
</script>
......
......@@ -3,9 +3,10 @@
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator"
import { Model } from "vue-property-decorator"
import { FileType, getSvg } from "./file-controller"
import { Component, Model, Vue } from "vue-property-decorator"
;
import { FileType, getSvg } from "./file-controller";
@Component({ components: {} })
export default class FileIcon extends Vue {
......@@ -13,55 +14,55 @@ export default class FileIcon extends Vue {
private value!: FileType
private get audio() {
return this.value === FileType.Audio
return this.value === FileType.Audio;
}
private get excel() {
return this.value === FileType.Excel
return this.value === FileType.Excel;
}
private get image() {
return this.value === FileType.Image
return this.value === FileType.Image;
}
private get others() {
return this.value === FileType.Others
return this.value === FileType.Others;
}
private get pdf() {
return this.value === FileType.Pdf
return this.value === FileType.Pdf;
}
private get ppt() {
return this.value === FileType.Ppt
return this.value === FileType.Ppt;
}
private get rp() {
return this.value === FileType.Rp
return this.value === FileType.Rp;
}
private get txt() {
return this.value === FileType.Txt
return this.value === FileType.Txt;
}
private get video() {
return this.value === FileType.Video
return this.value === FileType.Video;
}
private get word() {
return this.value === FileType.Word
return this.value === FileType.Word;
}
private get xmid() {
return this.value === FileType.Xmind
return this.value === FileType.Xmind;
}
private get zip() {
return this.value === FileType.Zip
return this.value === FileType.Zip;
}
private get html() {
return getSvg(this.value)
return getSvg(this.value);
}
}
</script>
......
......@@ -31,7 +31,7 @@
</template>
<script lang="ts">
import { Component, Vue, Model, Prop } from "vue-property-decorator"
import { Component, Model, Prop, Vue } from "vue-property-decorator";
@Component({ components: {} })
export default class ImagePreview extends Vue {
......@@ -42,8 +42,8 @@ export default class ImagePreview extends Vue {
private file!: { name: string; url: string }
private style: {
"max-height": number | string
"max-width": number | string
"max-height": number | string;
"max-width": number | string;
} = {
"max-height": "300px",
"max-width": "600px",
......@@ -54,19 +54,19 @@ export default class ImagePreview extends Vue {
() =>
(this.style = { "max-height": "300px", "max-width": "600px" }),
300
)
this.$emit("update", false)
);
this.$emit("update", false);
}
private set2Default() {
this.style = { "max-height": "1600px", "max-width": "1600px" }
this.style = { "max-height": "1600px", "max-width": "1600px" };
}
private get getAttachment() {
if (this.file) {
return this.file.name
return this.file.name;
}
return "文件下载"
return "文件下载";
}
}
</script>
......
......@@ -30,7 +30,7 @@
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator"
import { Component, Vue } from "vue-property-decorator";
@Component({ components: {} })
export default class VideoPlayerIcon extends Vue {}
......
......@@ -37,7 +37,7 @@
</template>
<script lang="ts">
import { Component, Vue, Model, Prop, Ref, Watch } from "vue-property-decorator"
import { Component, Model, Prop, Ref, Vue, Watch } from "vue-property-decorator";
@Component({ components: {} })
export default class VideoPreview extends Vue {
......@@ -51,8 +51,8 @@ export default class VideoPreview extends Vue {
private video!: HTMLVideoElement
private style: {
"max-height": number | string
"max-width": number | string
"max-height": number | string;
"max-width": number | string;
} = {
"max-height": "800px",
"max-width": "800px",
......@@ -63,28 +63,28 @@ export default class VideoPreview extends Vue {
() =>
(this.style = { "max-height": "300px", "max-width": "600px" }),
300
)
this.$emit("update", false)
);
this.$emit("update", false);
}
private set2Default() {
this.style = { "max-height": "1600px", "max-width": "1600px" }
this.style = { "max-height": "1600px", "max-width": "1600px" };
}
private get getAttachment() {
if (this.file) {
return this.file.name
return this.file.name;
}
return "视频下载"
return "视频下载";
}
@Watch("value")
private onOpen() {
if (this.value) {
this.video?.load()
setTimeout(() => this.video?.play(), 100)
this.video?.load();
setTimeout(() => this.video?.play(), 100);
} else {
this.video?.pause()
this.video?.pause();
}
}
}
......
......@@ -32,9 +32,9 @@
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator"
import { Prop } from "vue-property-decorator"
import { Watch } from "vue-property-decorator"
import { Component, Prop, Vue, Watch } from "vue-property-decorator"
;
@Component({ components: {} })
export default class VoiceIcon extends Vue {
......@@ -51,21 +51,21 @@ export default class VoiceIcon extends Vue {
private onLoadingChanged() {
if (this.loading) {
this.interval = window.setInterval(() => {
const v = this.status + 1
const v = this.status + 1;
if (v > 3) {
this.status = 0
this.status = 0;
} else {
this.status = v
this.status = v;
}
}, 500)
}, 500);
} else {
clearInterval(this.interval)
this.status = 0
clearInterval(this.interval);
this.status = 0;
}
}
beforeDestroy() {
clearInterval(this.interval)
clearInterval(this.interval);
}
}
</script>
......@@ -41,19 +41,21 @@
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Ref } from "vue-property-decorator"
import { namespace } from "vuex-class"
import { ChatStore } from "@/customer-service/store/model"
import xim from "@/customer-service/xim/xim"
import { unique } from "../utils"
import chat from "../xim"
import * as dto from "../model"
import { Component, Prop, Ref, Vue } from "vue-property-decorator";
import { namespace } from "vuex-class";
const chatStoreNamespace = namespace("chatStore")
import * as dto from "../model";
import { unique } from "../utils";
import { ChatStore } from "@/customer-service/store/model";
import xim from "@/customer-service/xim/xim";
const chatStoreNamespace = namespace("chatStore");
@Component({ components: {} })
export default class WhoReadList extends Vue {
@chatStoreNamespace.State(ChatStore.STATE_CHAT_CURRENT_CHAT_ID)
private readonly chatId!: ChatStore.STATE_CHAT_CURRENT_CHAT_ID
@chatStoreNamespace.State(ChatStore.STATE_CHAT_MY_ID)
private readonly chatMyId!: ChatStore.STATE_CHAT_MY_ID
......@@ -61,6 +63,7 @@ export default class WhoReadList extends Vue {
type: Number,
})
private msgId!: number
@Ref("list-con")
private listCon!: HTMLElement
......@@ -70,74 +73,79 @@ export default class WhoReadList extends Vue {
private unreadlist: { name: string; avatar: string }[] = []
private loading = false
private startLoading() {
this.loading = true
this.loading = true;
}
private endLoading() {
this.loading = false
this.loading = false;
}
public async created() {
this.startLoading()
await this.getReader()
this.endLoading()
this.startLoading();
await this.getReader();
this.endLoading();
}
public mounted() {
this.enableBlur()
this.enableBlur();
const { top, left } = (
this.listCon.parentNode as HTMLElement
).getBoundingClientRect()
this.top = top
this.left = left
).getBoundingClientRect();
this.top = top;
this.left = left;
}
private enableBlur() {
this.listCon.setAttribute("tabindex", "-1")
this.listCon.focus()
this.listCon.setAttribute("tabindex", "-1");
this.listCon.focus();
}
private async getUserNameByid(eid: string) {
const data = await this.sdk.model("user").detail(eid).query()
return data.row.first_name.value as string
const data = await this.sdk.model("user").detail(eid).query();
return data.row.first_name.value as string;
}
private async getReader() {
if (this.chatId == null) return
if (this.msgId == null) return
const userInfo = chat.getUserMapping()
const data = await xim.fetchMsgInBox(this.chatId, this.msgId)
if (this.chatId == null) return;
if (this.msgId == null) return;
const data = await xim.fetchMsgInBox(this.chatId, this.msgId);
const readerlist = this.uniqueReaderList(
data.args[0] as dto.OneWhoReadMessage[]
)
);
this.readlist = await Promise.all(
readerlist
.filter((k) => k.is_read)
.filter((k) => k.eid !== this.chatMyId)
.map(async (k) => {
const eid = k.eid
const name = await this.getUserNameByid(eid)
const eid = k.eid;
const name = await this.getUserNameByid(eid);
return {
eid,
name,
avatar: "",
}
};
})
)
);
this.unreadlist = await Promise.all(
readerlist
.filter((k) => !k.is_read)
.filter((k) => k.eid !== this.chatMyId)
.map(async (k) => {
const eid = k.eid
const name = await this.getUserNameByid(eid)
const eid = k.eid;
const name = await this.getUserNameByid(eid);
return {
eid,
name,
avatar: "",
}
};
})
)
);
}
private uniqueReaderList(data: dto.OneWhoReadMessage[]) {
return unique(data, function (item, all) {
return all.findIndex((k) => k.eid === item.eid)
})
return all.findIndex((k) => k.eid === item.eid);
});
}
}
</script>
......
......@@ -237,7 +237,7 @@ export default class Input extends Vue {
}
} else {
promiseArr.push(
new Promise<void>((reslove) => {
new Promise<void>((resolve) => {
const contentType = items[i].type;
items[i].getAsString((k) => {
/*
......@@ -267,7 +267,7 @@ export default class Input extends Vue {
}
} while (result);
}
reslove();
resolve();
});
})
);
......@@ -514,10 +514,6 @@ export default class Input extends Vue {
this.emojiPanelVisibility = false;
}
private noop() {
}
private setupEmoji() {
EmojiService.onReady(() => {
const service = new EmojiService();
......
......@@ -9,23 +9,26 @@
</div>
</template>
<script lang="ts">
import { Component, Ref, Vue, Watch } from "vue-property-decorator"
import { Component, Ref, Vue, Watch } from "vue-property-decorator";
import ChatInput, {
FILE_INFO_CLASS,
isImageOrFile,
} from "./hybrid-input/index.vue"
import { ChatStore, chatStore } from "@/customer-service/store/model"
import { ChatLoggerService } from "./xim/logger"
import xim from "./xim/xim"
import { Message } from "./model"
import { uploadFile } from "./service/upload"
} from "./hybrid-input/index.vue";
import { Message } from "./model";
import { uploadFile } from "./service/upload";
import { ChatLoggerService } from "./xim/logger";
import xim from "./xim/xim";
import { ChatStore, chatStore } from "@/customer-service/store/model";
let sendingMessageIndex = 1
let sendingMessageIndex = 1;
@Component({ components: { ChatInput } })
export default class MessageInput extends Vue {
@chatStore.State(ChatStore.STATE_CHAT_DIALOG_VISIBLE)
private readonly chatRoomVisible: ChatStore.STATE_CHAT_DIALOG_VISIBLE
@chatStore.Action(ChatStore.ACTION_SEND_MESSAGE)
private readonly sendMsg!: ChatStore.ACTION_SEND_MESSAGE
......@@ -55,44 +58,45 @@ export default class MessageInput extends Vue {
@Watch("chatRoomVisible")
private whenChatRoomShow() {
if (!this.chatRoomVisible) return
this.chatInput.focus()
if (!this.chatRoomVisible) return;
this.chatInput.focus();
}
private async sendMessage(msg: ChildNode[], done: () => void) {
if (this.chatIniting) {
return
return;
}
for (const item of msg) {
if (isImageOrFile(item)) {
if ((item as Element).classList.contains(FILE_INFO_CLASS)) {
this.sendFile(item, "file")
this.sendFile(item, "file");
} else {
this.sendFile(item, "image")
this.sendFile(item, "image");
}
continue
continue;
}
if (item.textContent) {
this.sendText(item.textContent)
this.sendText(item.textContent);
}
}
ChatLoggerService.logger?.debug("all messages sent")
done()
this.$emit("sent")
ChatLoggerService.logger?.debug("all messages sent");
done();
this.$emit("sent");
}
private async onInput() {
if (this.chatId == null) return
await xim.inputing(this.chatId)
if (this.chatId == null) return;
await xim.inputing(this.chatId);
}
private sendText(text: string) {
if (text && text.trim()) {
const msg = { text: text.trim() }
const msg = { text: text.trim() };
if (this.source) {
Object.assign(msg, { source: this.source })
Object.assign(msg, { source: this.source });
}
this.sendMsg({ msgType: "text", msg: JSON.stringify(msg) })
this.sendMsg({ msgType: "text", msg: JSON.stringify(msg) });
}
}
......@@ -100,24 +104,24 @@ export default class MessageInput extends Vue {
const src = JSON.parse(
file.attributes[`data-${type}`]?.value || ""
) as {
url: string
name: string
size: number
}
url: string;
name: string;
size: number;
};
if (src) {
const index = this.sendSendingMessage(type, src)
const file = await this.readBlobUrl2Base64(src.url, src.name)
const index = this.sendSendingMessage(type, src);
const file = await this.readBlobUrl2Base64(src.url, src.name);
if (file) {
let w = 0
let h = 0
let w = 0;
let h = 0;
if (type === "image") {
const img = new Image()
img.src = src.url
const img = new Image();
img.src = src.url;
img.onload = function () {
w = img.naturalWidth
h = img.naturalHeight
}
img.remove()
w = img.naturalWidth;
h = img.naturalHeight;
};
img.remove();
}
uploadFile(file, this.chatId || 0, w, h)
.then((r) => {
......@@ -126,42 +130,43 @@ export default class MessageInput extends Vue {
url: r,
name: file.name,
size: file.size,
}
};
if (this.source) {
Object.assign(msg, { source: this.source })
Object.assign(msg, { source: this.source });
}
if (w && h) {
Object.assign(msg, { w, h })
Object.assign(msg, { w, h });
}
this.sendMsg({
msgType: type,
msg: JSON.stringify(msg),
})
this.removeSendingMessages(index)
URL.revokeObjectURL(src.url)
});
this.removeSendingMessages(index);
URL.revokeObjectURL(src.url);
} else {
this.setMsg2Failed(index)
this.setMsg2Failed(index);
}
})
.catch((e) => {
console.error(e)
// eslint-disable-next-line no-console
console.error(e);
this.setMsg2Failed(index)
})
this.setMsg2Failed(index);
});
}
}
}
private setMsg2Failed(index: number) {
this.failedSendingMessage(index)
this.failedSendingMessage(index);
}
private sendSendingMessage(type: string, msg: any) {
const index = sendingMessageIndex++
const index = sendingMessageIndex++;
if (this.source) {
Object.assign(msg, { source: this.source, eid: this.chatMyId })
Object.assign(msg, { source: this.source, eid: this.chatMyId });
}
if (this.chatId) {
this.appendSendingMessages({
......@@ -170,20 +175,20 @@ export default class MessageInput extends Vue {
ts: Date.now(),
type,
msg: JSON.stringify(msg),
} as Message)
return -index
} as Message);
return -index;
}
return 0
return 0;
}
private readBlobUrl2Base64(url: string, name: string) {
return fetch(url)
.then((r) => r.blob())
.then((blob) => new File([blob], name))
.then((blob) => new File([blob], name));
}
private onError(e: any) {
this.$emit("error", e.message || e)
this.$emit("error", e.message || e);
}
}
</script>
import { RootStoreState } from "@/store/model";
import { Module } from "vuex";
import { ChatMember } from "../model";
......@@ -5,28 +6,25 @@ import { isAccessibleUrl } from "../service/tools";
import { unique } from "../utils";
import { decode } from "../utils/jwt";
import Chat from "../xim";
import chat from "../xim/";
import chatType from "../xim/chat-type";
import xim, { ChatNotifyListener } from "../xim/xim";
import { ChatMemberType, ChatStatus, ChatStore, ChatStoreState } from "./model";
import { RootStoreState } from "@/store/model";
export const ns = ChatStore.ns;
const sdk = chat.getSdk;
const sdk = Chat.getSdk;
const UniplatChatModelName = "UniplatChat";
const model = () => sdk().model(UniplatChatModelName);
const orgId = chat.getOrgId;
const getMyinfo = (function () {
let data;
return async () => {
if (data != null) return data;
data = sdk().getUserInfo();
return data;
};
})();
const orgId = Chat.getOrgId;
// const getMyinfo = (function () {
// let data;
// return async () => {
// if (data != null) return data;
// data = sdk().getUserInfo();
// return data;
// };
// })();
function uniqueMessages(
messages: NonNullable<ChatStore.STATE_CHAT_MSG_HISTORY>
) {
......@@ -49,23 +47,23 @@ const removeRegisterChatEvents: (() => void)[] = [];
async function preCacheImgs(msgs: any[]) {
await Promise.all(
msgs.map((k) => {
return new Promise((done: (p: void) => void) => {
return new Promise((resolve: (p: void) => void) => {
if (k.type === "image") {
const msg = JSON.parse(k.msg);
const url = msg.url;
if (!isAccessibleUrl(url)) {
done();
resolve();
}
if (url && isAccessibleUrl(url)) {
const preCache = new Image();
preCache.src = url;
preCache.onload = () => done();
setTimeout(done, 2000);
preCache.onload = () => resolve();
setTimeout(resolve, 2000);
} else {
done();
resolve();
}
} else {
done();
resolve();
}
});
})
......@@ -291,7 +289,7 @@ export default {
actions: {
async [ChatStore.ACTION_GET_MY_CHAT_LIST](
{ commit },
...params: Parameters<ChatStore.ACTION_GET_MY_CHAT_LIST>
// ...params: Parameters<ChatStore.ACTION_GET_MY_CHAT_LIST>
) {
const { pageData } = await model().list().query({
pageIndex: 1,
......@@ -316,12 +314,12 @@ export default {
total: pageData.record_count,
});
},
async [ChatStore.ACTION_JOIN_CHAT](
{ commit },
chatId: Parameters<ChatStore.ACTION_JOIN_CHAT>[0]
) {
// return await XimService.getInstance().joinChat(chatId)
},
// async [ChatStore.ACTION_JOIN_CHAT](
// { commit },
// chatId: Parameters<ChatStore.ACTION_JOIN_CHAT>[0]
// ) {
// // return await XimService.getInstance().joinChat(chatId)
// },
async [ChatStore.ACTION_GET_CHAT_MESSAGES]({ state, commit }) {
const chatId = state[ChatStore.STATE_CHAT_CURRENT_CHAT_ID];
if (chatId == null) return;
......@@ -332,6 +330,7 @@ export default {
commit(ChatStore.MUTATION_SCROLL_TO_BOTTOM);
return data;
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
},
......@@ -379,6 +378,7 @@ export default {
await dispatch(ChatStore.ACTION_GET_FRESH_MESSAGE);
return data;
} catch (error) {
// eslint-disable-next-line no-console
console.error("testing 信息发送失败", error);
}
},
......@@ -397,7 +397,7 @@ export default {
msgs[msgs.length - 1].id
);
}
const lastMsg = newMsgsArr[newMsgsArr.length - 1];
// const lastMsg = newMsgsArr[newMsgsArr.length - 1];
await preCacheImgs(newMsgsArr);
commit(ChatStore.MUTATION_SCROLL_TO_BOTTOM);
},
......@@ -432,7 +432,7 @@ export default {
detailManager.done();
const { id } = await action.dryExecute();
// 无法得到chat id
const data = await sdk()
await sdk()
.model(UniplatChatModelName)
.action("createXimChat")
.updateInitialParams({
......@@ -451,13 +451,13 @@ export default {
uniplatId: newChat.uniplatId,
});
},
async [ChatStore.ACTION_CREATE_NEW_CHAT_BY_CLIENT_SIDE](
{ commit, dispatch },
option: {
customerServiceId?: number | string;
customerServiceGroupId?: number;
}
) {},
// async [ChatStore.ACTION_CREATE_NEW_CHAT_BY_CLIENT_SIDE](
// { commit, dispatch },
// option: {
// customerServiceId?: number | string;
// customerServiceGroupId?: number;
// }
// ) {},
async [ChatStore.ACTION_REGISTER_EVENT]({ dispatch, commit, state }) {
const chatId = state[ChatStore.STATE_CHAT_CURRENT_CHAT_ID];
if (chatId == null) return;
......@@ -471,7 +471,6 @@ export default {
) {
return;
}
console.log("事件消息已读", e);
if (chatId !== e.chat_id) return;
const msgs = state[ChatStore.STATE_CHAT_MSG_HISTORY];
if (msgs == null) return;
......@@ -554,6 +553,7 @@ export default {
phone: info.row.last_name.value as string,
};
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
result = member;
}
......
......@@ -25,14 +25,14 @@ export class ImageCompresser {
maxWidth: number,
maxHeight: number
): Promise<File | null> {
return new Promise((resolve, reject) => {
return new Promise<File>((resolve, reject) => {
const img = new Image();
const reader = new FileReader();
reader.onload = (e) => {
if (e && e.target && e.target.result) {
img.src = e.target.result as string;
} else {
reject();
reject(new Error("file load failed"));
}
};
reader.readAsDataURL(file);
......@@ -49,7 +49,7 @@ export class ImageCompresser {
newFile.size <= file.size ? newFile : file
);
} else {
reject();
reject(new Error("file load failed"));
}
})
.catch(reject);
......@@ -77,7 +77,7 @@ export class ImageCompresser {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
if (!context) {
reject();
reject(new Error(" compress image failed"));
return;
}
const { width: originWidth, height: originHeight } = img; // 最大尺寸限制
......
......@@ -22,7 +22,7 @@ function base64_url_decode(str: string) {
output += "=";
break;
default:
throw "Illegal base64url string!";
throw new Error("Illegal base64url string!");
}
try {
......
......@@ -8,14 +8,14 @@ import tokenManager from "./token";
import xim from "./xim";
class Chat {
private _sdk?: () => UniplatSdk
private _orgId: () => string | number = () => "0"
private token!: TokenStringGetter
private _sdk?: () => UniplatSdk;
private _orgId: () => string | number = () => "0";
private token!: TokenStringGetter;
private userMapping: { [key: string]: { name: string; avatar: string } } =
{}
{};
private webHost = false
private webHost = false;
public async setup(option: ChatOption) {
if (!option) {
......@@ -46,11 +46,11 @@ class Chat {
public getSdk = () => {
if (this._sdk == null) return;
return this._sdk();
}
};
public getOrgId = () => {
return this._orgId();
}
};
public isWebHost() {
return this.webHost;
......
import { ChatServiceLogger } from "../model";
export class ChatLoggerService {
public static logger = console
......
......@@ -4,10 +4,11 @@ export enum UserType {
Customer, // 客户
}
export default interface User {
type User ={
uid: string;
oid: string;
eid: string;
jwt: string;
userType: UserType;
};;;;;;;;;;
};
export default User;
import { ChatOption, TokenStringGetter } from "./../model";
import { TokenStringGetter } from "./../model";
function Token() {
let _token: TokenStringGetter;
return {
......
......@@ -12,7 +12,7 @@ wampDebug(true);
const DefaultMsgPageSize = 20;
function emptyFunc() {
return null;
}
export type MsgListener = (msg: Message) => void
......@@ -58,7 +58,7 @@ export class Xim {
public async open(url: string, token: TokenStringGetter) {
this.connectionPending = true;
await new Promise((success: (p?: unknown) => void, failed) => {
await new Promise((resolve: (p?: unknown) => void, reject) => {
this.paramsForReconnection = { url, token };
this.close();
......@@ -67,15 +67,15 @@ export class Xim {
this.client = client;
client.onstatuschange = (status: any, details: any) => {
this.onStatusChange.call(this, status, details);
this.onStatusChange(status, details);
if (status === "DISCONNECTED" || status === "CLOSED") {
failed();
reject(status);
}
};
client.onconnected = () => {
this.onConnected.apply(this);
success();
resolve();
};
client.onmsg = this.handleMsg.bind(this);
......@@ -92,15 +92,16 @@ export class Xim {
* token过期或者切换用户登录时,需要设置新的token
*/
public async setToken(token: TokenStringGetter) {
const client = this.client!;
const client = this.client;
if (client == null) return;
client.close();
client.setToken(this.trimToken(await token()));
client.open();
}
public fetchMsgInBox(chatId: number, msgId: number) {
return this.client!.fetchMsgInBox(chatType, chatId, msgId);
if (this.client == null) return;
return this.client.fetchMsgInBox(chatType, chatId, msgId);
}
/**
......@@ -113,13 +114,14 @@ export class Xim {
msg: string
) {
this.checkConnected();
return this.client!.sendMsg(chatType, chatId, msgType, msg, "", {});
if (this.client == null) return;
return this.client.sendMsg(chatType, chatId, msgType, msg, "", {});
}
public inputing(chatId: number) {
this.checkConnected();
return this.client!.userInput(chatType, chatId);
if (this.client == null) return;
return this.client.userInput(chatType, chatId);
}
/*
......@@ -127,8 +129,8 @@ export class Xim {
*/
public fetchChatMembers(chat_id: number) {
this.checkConnected();
return this.client!.fetchChatMembers(chat_id);
if (this.client == null) return;
return this.client.fetchChatMembers(chat_id);
}
/**
......@@ -143,7 +145,8 @@ export class Xim {
desc = true
): Promise<Message[]> {
this.checkConnected();
const res = await this.client!.fetchChatMsgs(chatType, chatId, {
if (this.client == null) return;
const res = await this.client.fetchChatMsgs(chatType, chatId, {
lid,
rid,
limit,
......@@ -283,8 +286,9 @@ export class Xim {
}
private onConnected() {
if (this.client == null) return;
// 连接成功后,需要调用pubUserInfo, 否则服务端会认为此连接无效
this.client!.pubUserInfo("");
this.client.pubUserInfo("");
this.debug("xim connected");
}
......@@ -334,10 +338,12 @@ export class Xim {
}
private checkConnected() {
if (!this.client!.connected) {
if (this.client == null) return;
if (!this.client.connected) {
try {
this.client?.open();
} catch (e) {
// eslint-disable-next-line no-console
console.error("checkConnected", e);
this.reOpen();
}
......
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