From 8c4c26f554cb2a1edad849df9c2d3d7bd1cdc949 Mon Sep 17 00:00:00 2001
From: THK3121 <thk121969318@163.com>
Date: Wed, 11 Oct 2023 16:59:50 +0800
Subject: [PATCH] =?UTF-8?q?im=E9=A1=B5=E9=9D=A2=E5=AE=8C=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md                    |   6 +-
 src/api/talk.ts              |  22 ++
 src/assets/images/SP.png     | Bin 0 -> 5848 bytes
 src/assets/images/XC.png     | Bin 0 -> 5791 bytes
 src/config/index.ts          |  14 +-
 src/utils/request/indexs.ts  | 131 +++++++
 src/views/business/index.vue | 686 +++++++++++++++++++++++++++++++++++
 7 files changed, 852 insertions(+), 7 deletions(-)
 create mode 100644 src/api/talk.ts
 create mode 100644 src/assets/images/SP.png
 create mode 100644 src/assets/images/XC.png
 create mode 100644 src/utils/request/indexs.ts
 create mode 100644 src/views/business/index.vue

diff --git a/README.md b/README.md
index 2a2fad7..343abb1 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,8 @@ TypeScript cannot handle type information for `.vue` imports by default, so we r
 If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
 
 1. Disable the built-in TypeScript Extension
-   1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
-   2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+    1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+    2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
 2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
 
 ## Customize configuration
@@ -44,5 +44,3 @@ npm run build
 ```sh
 npm run lint
 ```
-
-zmj 分支
diff --git a/src/api/talk.ts b/src/api/talk.ts
new file mode 100644
index 0000000..ca397c3
--- /dev/null
+++ b/src/api/talk.ts
@@ -0,0 +1,22 @@
+import request from "@/utils/request/indexs";
+
+/**
+ * 绑定scoket
+ */
+export const bindScoket = (data: any) =>
+  request.post({ url: "/common/im/doBindUid", data });
+// 发送消息
+export const sendMsgApi = (data: any) =>
+  request.post({ url: "/common/im/sendTextMsg", data });
+// 发送文件
+export const sendFileApi = (data: any) =>
+  request.post({ url: "/common/im/sendFileMsg", data });
+// 消息列表
+export const getMsgListApi = (data: any) =>
+  request.post({ url: "/common/im/msgList", data });
+// 片区经理id
+export const getAreaManagerApi = (data: any) =>
+  request.post({ url: "/common/im/getAreaManager", data });
+// 联系人列表
+export const getContactListApi = (data: any) =>
+  request.post({ url: "/common/im/contactList", data });
diff --git a/src/assets/images/SP.png b/src/assets/images/SP.png
new file mode 100644
index 0000000000000000000000000000000000000000..a786f632b32c4ffb5d16eebfcb61a9da623511c0
GIT binary patch
literal 5848
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
PQZ-0V+eoVd?G*YSEvZYz

literal 0
HcmV?d00001

diff --git a/src/assets/images/XC.png b/src/assets/images/XC.png
new file mode 100644
index 0000000000000000000000000000000000000000..e9eba659d1b75a4c32ae586be0a9a25bafd7436e
GIT binary patch
literal 5791
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
OknzRK`Y&|x_x}sa-!)7C

literal 0
HcmV?d00001

diff --git a/src/config/index.ts b/src/config/index.ts
index efe50ec..b6d5725 100644
--- a/src/config/index.ts
+++ b/src/config/index.ts
@@ -2,11 +2,19 @@ const config = {
   terminal: 1, //终端
   title: "后台管理系统", //网站默认标题
   version: "1.6.0", //版本号
-  baseUrl: `${
-    import.meta.env.VITE_APP_BASE_URL
-  }/`, //请求接口域名
+  baseUrl: `${import.meta.env.VITE_APP_BASE_URL}/`, //请求接口域名
   urlPrefix: "adminapi", //请求默认前缀
   timeout: 20 * 1000, //请求超时时长
 };
 
 export default config;
+// const config = {
+//   terminal: 1, //终端
+//   title: "后台管理系统", //网站默认标题
+//   version: "1.6.0", //版本号
+//   baseUrl: `https://worker-task.lihaink.cn`, //请求接口域名
+//   urlPrefix: "adminapi", //请求默认前缀
+//   timeout: 20 * 1000, //请求超时时长
+// };
+
+// export default config;
diff --git a/src/utils/request/indexs.ts b/src/utils/request/indexs.ts
new file mode 100644
index 0000000..530f736
--- /dev/null
+++ b/src/utils/request/indexs.ts
@@ -0,0 +1,131 @@
+import { merge } from "lodash";
+import configs from "@/config";
+import { Axios } from "./axios";
+import {
+  ContentTypeEnum,
+  RequestCodeEnum,
+  RequestMethodsEnum,
+} from "@/enums/requestEnums";
+import type { AxiosHooks } from "./type";
+import { clearAuthInfo, getToken } from "../auth";
+import feedback from "../feedback";
+import NProgress from "nprogress";
+import { AxiosError, type AxiosRequestConfig } from "axios";
+import router from "@/router";
+import { PageEnum } from "@/enums/pageEnum";
+
+// 处理axios的钩子函数
+const axiosHooks: AxiosHooks = {
+  requestInterceptorsHook(config) {
+    NProgress.start();
+    const { withToken, isParamsToData } = config.requestOptions;
+    const params = config.params || {};
+    const headers = config.headers || {};
+
+    // 添加token
+    if (withToken) {
+      const token = getToken();
+      headers.token = token;
+    }
+    // POST请求下如果无data,则将params视为data
+    if (
+      isParamsToData &&
+      !Reflect.has(config, "data") &&
+      config.method?.toUpperCase() === RequestMethodsEnum.POST
+    ) {
+      config.data = params;
+      config.params = {};
+    }
+    config.headers = headers;
+    return config;
+  },
+  requestInterceptorsCatchHook(err) {
+    NProgress.done();
+    return err;
+  },
+  async responseInterceptorsHook(response) {
+    NProgress.done();
+    const { isTransformResponse, isReturnDefaultResponse } =
+      response.config.requestOptions;
+
+    //返回默认响应,当需要获取响应头及其他数据时可使用
+    if (isReturnDefaultResponse) {
+      return response;
+    }
+    // 是否需要对数据进行处理
+    if (!isTransformResponse) {
+      return response.data;
+    }
+    const { code, data, show, msg } = response.data;
+    switch (code) {
+      case RequestCodeEnum.SUCCESS:
+        if (show) {
+          msg && feedback.msgSuccess(msg);
+        }
+        return data;
+      case RequestCodeEnum.FAIL:
+        if (show) {
+          msg && feedback.msgError(msg);
+        }
+        return Promise.reject(data);
+      case RequestCodeEnum.LOGIN_FAILURE:
+        clearAuthInfo();
+        router.push(PageEnum.LOGIN);
+        return Promise.reject();
+      case RequestCodeEnum.OPEN_NEW_PAGE:
+        window.location.href = data.url;
+        return data;
+      default:
+        return data;
+    }
+  },
+  responseInterceptorsCatchHook(error) {
+    NProgress.done();
+    if (error.code !== AxiosError.ERR_CANCELED) {
+      error.message && feedback.msgError(error.message);
+    }
+    return Promise.reject(error);
+  },
+};
+
+const defaultOptions: AxiosRequestConfig = {
+  //接口超时时间
+  timeout: configs.timeout,
+  // 基础接口地
+  baseURL: configs.baseUrl,
+
+  // baseURL: "http://192.168.1.11:8081/",
+
+  //请求头
+  headers: { "Content-Type": ContentTypeEnum.JSON, version: configs.version },
+  // 处理 axios的钩子函数
+  axiosHooks: axiosHooks,
+  // 每个接口可以单独配置
+  requestOptions: {
+    // 是否将params视为data参数,仅限post请求
+    isParamsToData: true,
+    //是否返回默认的响应
+    isReturnDefaultResponse: false,
+    // 需要对返回数据进行处理
+    isTransformResponse: true,
+    // 接口拼接地址
+    urlPrefix: "",
+    // 忽略重复请求
+    ignoreCancelToken: false,
+    // 是否携带token
+    withToken: true,
+    // 开启请求超时重新发起请求请求机制
+    isOpenRetry: true,
+    // 重新请求次数
+    retryCount: 2,
+  },
+};
+
+function createAxios(opt?: Partial<AxiosRequestConfig>) {
+  return new Axios(
+    // 深度合并
+    merge(defaultOptions, opt || {})
+  );
+}
+const request = createAxios();
+export default request;
diff --git a/src/views/business/index.vue b/src/views/business/index.vue
new file mode 100644
index 0000000..9454242
--- /dev/null
+++ b/src/views/business/index.vue
@@ -0,0 +1,686 @@
+<template>
+    <div class="box">
+        <div class="talk-list">
+            <div class="mt-4 serch">
+                <el-input v-model="queryUserName" placeholder="搜索联系人" class="input-with-select">
+                    <template #append>
+                        <el-button :icon="Search" @click="serchUserFn" />
+                    </template>
+                </el-input>
+            </div>
+            <div style="height: 5vh;"></div>
+
+            <div class="contacts" v-for="(item, index) in userList" :key="index" @click="choseTalkFn(item, index)">
+                <div class="l">
+                    <div style="position: relative;">
+                        <el-image style="width: 40px; height: 40px" :src="item.avatar" />
+                        <div class="brage" v-if="item.no_read_num">{{ item.no_read_num }}</div>
+                    </div>
+                    <div class="tit-a">
+                        <div>{{ item.name }}</div>
+                        <div v-if="item.last_msg_type == 'text'" class="value">{{ item.last_msg_content }}</div>
+                        <div v-if="item.last_msg_type == 'image'" class="value">[图片]</div>
+                        <div v-if="item.last_msg_type == 'video'" class="value">[视频]</div>
+                    </div>
+                </div>
+                <div class="r">
+                    {{ timeFn(item.last_msg_time) }}
+                </div>
+            </div>
+        </div>
+        <div class="talk-detail" id="content">
+            <div class="top">
+                {{ talkDetail.name }}
+            </div>
+            <div style="height: 4vh"></div>
+            <div class="center" id="center" @scroll="handleScroll">
+                <div class="talk" v-for="(item, index) in talkDetail.talkList" :key="index">
+
+                    <div style="text-align: center;" v-show="index % 5 == 0">{{ timeFn(item.create_time) }}</div>
+                    <!-- 我的消息 -->
+                    <div class="my_task" v-if="item.from_user_id == user_id">
+                        <div class="content">
+                            <!-- 文本 -->
+                            <div v-if="item.type == 'text'">
+                                <a :href="item.content" v-if="isLink(item.content)" target="_blank"
+                                    style="color: #576B95;">{{
+                                        item.content }}
+                                </a>
+                                <div v-else> {{ item.content }}</div>
+                            </div>
+                            <!-- 图片 -->
+                            <div v-if="item.type == 'image'">
+                                <el-image style="width: 100px;height: auto;" :src="item.content" :preview-src-list="srcList"
+                                    @click="PreviewImgFn(item)"></el-image>
+                            </div>
+                            <!-- 视频 -->
+                            <div v-if="item.type == 'video'">
+                                <video controls :src="item.content"></video>
+                            </div>
+                        </div>
+                        <el-image style="width: 40px; height: 40px" :src="userStore.userInfo.avatar" />
+                    </div>
+                    <!-- 对方消息 -->
+                    <div class="to_task" v-else>
+                        <el-image style="width: 40px; height: 40px;margin-right: 5px;" :src="item.from_user_avatar" />
+                        <div class="content">
+                            <!-- 文本 -->
+                            <div v-if="item.type == 'text'">
+                                <a :href="item.content" target="_blank" v-if="isLink(item.content)"
+                                    style="color: #576B95;">{{
+                                        item.content }}
+                                </a>
+                                <div v-else> {{ item.content }}</div>
+                            </div>
+                            <!-- 图片 -->
+                            <div v-if="item.type == 'image'">
+                                <el-image style="width: 100px;height: auto;" :src="item.content" :preview-src-list="srcList"
+                                    @click="PreviewImgFn(item)"></el-image>
+                            </div>
+                            <!-- 视频 -->
+                            <div v-if="item.type == 'video'">
+                                <video controls :src="item.content"></video>
+                            </div>
+                        </div>
+                    </div>
+
+                </div>
+                <!-- 本地 -->
+                <div v-show="item.status" class="my_task" v-for="item, index in local">
+                    <!-- <div></div> -->
+                    <!-- <div >上传中</div> -->
+                    <div class="content" v-loading="true">
+                        <div style="width: 120px;margin-right: 10px;">
+                            <video controls :src="item.localSrc" v-if="item.type == 'video'"></video>
+                            <img controls :src="item.localSrc" v-else />
+                        </div>
+                        <!-- <el-progress :text-inside="true" :stroke-width="14" :percentage="item.percentage" /> -->
+                    </div>
+                    <el-image style="width: 40px; height: 40px;margin-right: 10px;" :src="url" />
+                </div>
+
+            </div>
+            <div class="bottom">
+                <div style="display: flex;">
+                    <el-upload :action="base_url + '/common/im/sendFileMsg'" :data="{
+                        from_user_id: user_id,
+                        to_user_id: talkDetail.to_user_id,
+                        scene: 1,
+                        type: 'image',
+                        msg_id: msg_id
+
+                    }" multiple :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="changeFile">
+                        <img class="img_cls" src="@/assets/images/XC.png" style="width: 50px;height: 50px;" />
+                    </el-upload>
+                    <el-upload :action="base_url + '/common/im/sendFileMsg'" :data="{
+                        from_user_id: user_id,
+                        to_user_id: talkDetail.to_user_id,
+                        scene: 1,
+                        type: 'video',
+                        msg_id: msg_id
+                    }" multiple :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="changeFile1">
+
+                        <img style="width: 50px; height: 50px" src="@/assets/images/SP.png" />
+                    </el-upload>
+                </div>
+                <el-input v-model="textarea" style="border: none;outline: none;" placeholder="请输入..."
+                    @keydown="keyup_submit(event)" />
+                <div class="send-btn" @click="sendMsgFn">发送</div>
+            </div>
+            <!-- <div style="height: 30vh;"></div> -->
+        </div>
+    </div>
+</template>
+
+<script lang="ts" scoped setup>
+import { reactive, ref, onBeforeUnmount } from 'vue';
+import { Search } from '@element-plus/icons-vue'
+import feedback from '@/utils/feedback'
+import {
+    sendMsgApi, getMsgListApi, bindScoket, sendFileApi, getContactListApi
+} from "@/api/talk"
+import { ElMessage } from 'element-plus'
+import useUserStore from "@/stores/modules/user";
+import { inject } from "vue";
+const base_url: any = inject("base_url").replace('adminapi', '');
+const userStore = useUserStore();
+const user_id = userStore.userInfo.id
+let page_no = 1
+let to_id: any = null
+// 图片预览
+const srcList: any = reactive(
+    []
+)
+const PreviewImgFn = (item: any) => {
+    srcList[0] = item.content
+}
+// 上拉加载
+const handleScroll = (e) => {
+    let top = e.target.scrollTop
+    if (top <= 0) {
+        page_no++
+        getMsgListApi({
+            from_user_id: user_id,
+            to_user_id: to_id,
+            scene: 1,
+            page_no: page_no,
+            page_size: 10
+        }).then(res2 => {
+            if (res2.length <= 0) return
+            talkDetail.talkList = res2.reverse().concat(talkDetail.talkList)
+            e.target.scrollTop = 100
+        })
+    }
+}
+let bind = false
+// 获取用户列表
+const userList = reactive([])
+let queryList = reactive([])
+const talkDetail = reactive({
+    name: "",
+    to_user_id: "",
+    talkList: [],
+    index: 0,
+})
+getContactListApi({ user_id: user_id }).then(res => {
+    res.forEach((element: any) => {
+        userList.push(element)
+        queryList.push(element)
+    });
+    // queryList = userList
+    console.log(queryList, 6666)
+    talkDetail.name = userList[0].name
+    talkDetail.to_user_id = userList[0].id
+    to_id = userList[0].id
+    getMsgListApi({
+        from_user_id: user_id,
+        to_user_id: userList[0].id,
+        scene: 1,
+        page_no: 1,
+        page_size: 10
+    }).then(res2 => {
+        talkDetail.talkList = res2.reverse()
+        // console.log(talkDetail)
+    })
+})
+const url = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
+// 用户搜索
+const queryUserName = ref('')
+const serchUserFn = () => {
+    getContactListApi({ user_id: user_id, keywords: queryUserName.value }).then(res => {
+        userList.splice(0, userList.length);
+        res.forEach((element: any) => {
+            // @ts-ignore
+            userList.push(element)
+            // queryList.push(element)
+        });
+    })
+}
+// 发送文本消息
+const isLink = (text: string) => {
+    var pattern = /^(https?:\/\/|www\.|.*\.com).*$/i;
+    return pattern.test(text);
+}
+const textarea = ref("")
+const sendMsgFn = () => {
+    if (!textarea.value) return
+    sendMsgApi({
+        from_user_id: user_id,
+        to_user_id: talkDetail.to_user_id,
+        type: "text",
+        content: textarea.value,
+        scene: 1,
+        msg_id: msg_id.value
+    }).then(res => {
+        talkDetail.talkList.push(res)
+        userList[talkDetail.index].last_msg_content = textarea.value
+        userList[talkDetail.index].last_msg_time = res.create_time
+        userList[talkDetail.index].last_msg_type = 'text'
+        // userList[talkDetail.index].last_msg_content = textarea.value
+        scrollFn()
+        textarea.value = ""
+        generateRandId()
+
+
+    })
+}
+const keyup_submit = (evt: any) => {
+    var evt = window.event || evt;
+    if (evt.keyCode == 13) {
+        sendMsgFn()
+    }
+}
+// 发送媒体消息
+let msg_id: any = ref('')
+const generateRandId = () => {
+    var d = new Date().getTime();
+    var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
+        var r = (d + Math.random() * 16) % 16 | 0;
+        d = Math.floor(d / 16);
+        return (c == "x" ? r : r & 0x3 | 0x8).toString(16);
+    });
+    // return uuid;
+    msg_id.value = uuid
+}
+generateRandId()
+const local = reactive([])
+let localData = () => {
+    return {
+        status: false,
+        localType: null,
+        localSrc: null,
+        type: "",
+        percentage: 0,
+        msg_id: msg_id.value
+    }
+}
+const changeFile = (res) => {
+    console.log(res.type)
+
+    if (!res.type.includes('image')) {
+        ElMessage.error('请选择正确的图片格式!!')
+        return false
+    }
+    local.push(localData())
+    let type = 'image'
+    var localIndex = local.findIndex(function (element) {
+        return element.msg_id === msg_id.value;
+    });
+    // userList[talkDetail.index].last_msg_type = type
+    let file = res
+    local[localIndex].type = type
+    const blob = file;
+    var reader = new FileReader();
+    reader.readAsDataURL(blob);
+    //监听文件读取结束后事件
+    reader.onloadend = function (e) {
+        local[localIndex].status = true
+        local[localIndex].localSrc = e.target?.result
+        scrollFn()
+        generateRandId()
+    };
+}
+const changeFile1 = (res) => {
+    if (!res.type.includes('video')) {
+        ElMessage.error('请选择正确的视频格式!!')
+        return false
+    }
+    local.push(localData())
+    let type = 'video'
+    var localIndex = local.findIndex(function (element) {
+        return element.msg_id === msg_id.value;
+    });
+    // userList[talkDetail.index].last_msg_type = type
+    let file = res
+    local[localIndex].type = type
+    const blob = file;
+    var reader = new FileReader();
+    reader.readAsDataURL(blob);
+    //监听文件读取结束后事件
+    reader.onloadend = function (e) {
+        local[localIndex].status = true
+        local[localIndex].localSrc = e.target?.result
+        scrollFn()
+        generateRandId()
+    };
+}
+const handleAvatarSuccess: any = (
+    res: any
+) => {
+    if (res.show == 0) {
+        talkDetail.talkList.push(res.data)
+    }
+    else {
+        feedback.msgError(res.msg)
+    }
+    var localIndex = local.findIndex(function (element) {
+        return element.msg_id === res.data.msg_id;
+    });
+    local[localIndex].status = false
+    userList[talkDetail.index].last_msg_type = res.data.type
+    console.log(res.data)
+
+}
+// 选择聊天
+const choseTalkFn = (item: any, index: number) => {
+    userList[index].no_read_num = 0
+    talkDetail.name = item.name
+    talkDetail.to_user_id = item.id
+    talkDetail.index = index
+    to_id = item.id
+    getMsgListApi({
+        from_user_id: user_id,
+        to_user_id: item.id,
+        scene: 1,
+        page_no: 1,
+        page_size: 10
+    }).then(res2 => {
+        talkDetail.talkList = res2.reverse()
+        scrollFn()
+
+    })
+}
+// 滚动底部
+let scrollTop: any = null
+onMounted(() => {
+    scrollTop = document.getElementById('center')
+
+})
+const scrollFn = () => {
+    setTimeout(() => {
+        scrollTop.scrollTop = 9999999
+    }, 100)
+}
+// 时间处理
+const timeFn = (time) => {
+    const currentDate = new Date(); // 当前日期对象
+    const targetDate = new Date(time * 1000);
+    if (isSameDay(currentDate, targetDate)) {
+        const hours = targetDate.getHours(); // 小时
+        const minutes = targetDate.getMinutes(); // 分钟
+        return hours + ':' + (minutes < 10 ? '0' + minutes : minutes);
+
+    } else if (isYesterday(currentDate, targetDate)) {
+        return '昨天';
+    }
+    const month = targetDate.getMonth() + 1; // 月份(注意月份从0开始,需要加1)
+    const day = targetDate.getDate(); // 日期
+    return month + '月' + day + '日';
+
+
+}
+const isSameDay = (date1, date2) => {
+    return (
+        date1.getFullYear() === date2.getFullYear() &&
+        date1.getMonth() === date2.getMonth() &&
+        date1.getDate() === date2.getDate()
+    );
+}
+const isYesterday = (currentDate, targetDate) => {
+    const yesterday = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() - 1);
+    return isSameDay(yesterday, targetDate);
+}
+// scoket
+const socket = new WebSocket('wss://worker-task.lihaink.cn/wss');
+const onSocketOpen = (event: any) => {
+    console.log('WebSocket连接已打开');
+}
+const onSocketMessage = (event: any) => {
+    let data = JSON.parse(event.data)
+    if (!bind) {
+        let client_id = (JSON.parse(event.data).client_id)
+        bindScoket({
+            client_id: client_id,
+            user_id: user_id,
+            scene: 1,
+        }).then(res => {
+            bind = true
+            console.log('绑定成功')
+        })
+    }
+    else if (data.id) {
+        var index = userList.findIndex(function (element) {
+            return element.id == data.from_user_id;
+        });
+        // talkDetail.talkList.push(data)
+        if (data.from_user_id == talkDetail.to_user_id) {
+            console.log(data, "收到scoket消息")
+            talkDetail.talkList.push(data)
+            userList[index].last_msg_content = data.content
+            userList[index].last_msg_time = data.create_time
+            userList[index].last_msg_type = data.type
+
+            scrollFn()
+        } else {
+            userList[index].no_read_num++
+            userList[index].last_msg_content = data.content
+            userList[index].last_msg_time = data.create_time
+            userList[index].last_msg_type = data.type
+
+            // userList.forEach
+        }
+    }
+    console.log(data)
+}
+const onSocketClose = (event: any) => {
+    console.log('WebSocket连接已关闭');
+}
+const onSocketError = (event: any) => {
+    console.error('WebSocket连接发生错误');
+}
+socket.addEventListener('open', onSocketOpen);
+socket.addEventListener('message', onSocketMessage);
+socket.addEventListener('close', onSocketClose);
+socket.addEventListener('error', onSocketError);
+onBeforeUnmount(() => {
+    socket.close()
+})
+
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-input__wrapper) {
+    box-shadow: none !important;
+    // border-bottom: 1px solid black;
+    border-radius: 0;
+}
+
+.box {
+    display: flex;
+
+    .serch {
+        background-color: #F6F6F6;
+        position: fixed;
+        top: 9vh;
+        width: 17vw;
+        z-index: 99;
+        padding-left: 10px;
+        padding-top: 10px;
+
+    }
+
+    .talk-list {
+        width: 20vw;
+        overflow: hidden;
+        height: 85vh;
+        position: relative;
+        // background-color: #fff;
+        cursor: pointer;
+
+        .contacts {
+            // margin-bottom: 10px;
+            // background-color: red;
+            padding: 10px;
+            display: flex;
+            justify-content: space-between;
+
+            .l {
+                display: flex;
+
+                .tit-a {
+                    margin-left: 10px;
+                    display: flex;
+                    flex-direction: column;
+                    justify-content: space-around;
+
+                    .value {
+                        overflow: hidden;
+                        text-overflow: ellipsis;
+                        white-space: nowrap;
+                        width: 8vw;
+
+                    }
+
+                }
+            }
+        }
+
+    }
+
+    .contacts:active {
+        background-color: #fff;
+    }
+
+    .contacts:hover {
+        background-color: #fff;
+
+    }
+
+    .talk-list::-webkit-scrollbar {
+        width: 2px;
+        /* 滚动条宽度 */
+    }
+
+    .talk-list::-webkit-scrollbar-thumb {
+        background-color: #888;
+        /* 滚动条颜色 */
+        border-radius: 1px;
+        /* 滚动条圆角 */
+    }
+
+    .img_cls {
+
+        margin-right: 10PX;
+        margin-bottom: 10PX;
+        cursor: pointer;
+    }
+
+    .talk-list:hover {
+        // background-color: #888;
+        overflow: scroll;
+
+    }
+
+    .talk-detail {
+        width: 80vw;
+        height: 85vh;
+
+        .top {
+            position: fixed;
+            height: 4vh;
+            width: 70vw;
+            box-sizing: border-box;
+            padding: 10px;
+            background-color: #fff;
+            z-index: 9;
+            border-bottom: 1px solid #EAE8E7;
+        }
+
+        .center {
+            height: 65vh;
+
+            overflow-y: scroll;
+            background-color: #fff;
+
+        }
+
+        .bottom {
+            position: fixed;
+            background-color: white;
+            height: 20vh;
+            border-top: 1px solid #EAE8E7;
+            width: 70vw;
+            box-sizing: border-box;
+            // padding-top: 10px;
+            padding: 10px;
+        }
+
+        // overflow: scroll;
+
+    }
+
+
+
+    .center::-webkit-scrollbar {
+        width: 2px;
+        /* 滚动条宽度 */
+    }
+
+    .center::-webkit-scrollbar-thumb {
+        background-color: #888;
+        /* 滚动条颜色 */
+        border-radius: 5px;
+        /* 滚动条圆角 */
+    }
+
+    .talk {
+        // height: 4vh;
+        // background-color: #fff;
+        padding: 10px;
+        margin-bottom: 10px;
+
+    }
+
+    .send-btn {
+        width: 50px;
+        height: 30px;
+        background-color: green;
+        color: white;
+        line-height: 30px;
+        text-align: center;
+        border-radius: 5px;
+        float: right;
+        margin-top: 5px;
+        cursor: pointer;
+
+    }
+
+    .send-btn:active {
+        background-color: yellowgreen;
+    }
+
+    .my_task {
+        display: flex;
+        justify-content: flex-end;
+
+        .content {
+            background-color: #95EC69;
+            border-radius: 5px;
+            // height: 30px;
+            padding: 5px;
+            // height: 40px;
+            // min-height: 40px;
+            margin-right: 5px;
+            line-height: 30px;
+            max-width: 20vw;
+            // overflow: hidden;
+            word-break: break-all;
+            overflow-wrap: break-word;
+
+        }
+    }
+
+    .to_task {
+        display: flex;
+        // justify-content: flex-end;
+
+        .content {
+            background-color: #95EC69;
+            border-radius: 5px;
+            // height: 30px;
+            padding: 5px 10px;
+            // height: 40px;
+            // min-height: 40px;
+            margin-right: 5px;
+            line-height: 30px;
+            max-width: 20vw;
+            word-break: break-all;
+            overflow-wrap: break-word;
+        }
+    }
+
+    .brage {
+        background-color: red;
+        color: white;
+        width: 16px;
+        height: 16px;
+        border-radius: 16px;
+        text-align: center;
+        line-height: 16px;
+        position: absolute;
+        font-size: 12px;
+        top: -8px;
+        right: -5px;
+    }
+}
+</style>
\ No newline at end of file