Browse Source

chore:1-17

bzkf3 2 years ago
parent
commit
76a87f2f09

+ 0 - 0
src/components/archives-card/index.vue


+ 8 - 3
src/components/chat-stu-card/index.vue

@@ -2,12 +2,12 @@
 import type { type_dyaw_xlfw_zxhd } from '~/types';
 const props = defineProps<{ d: type_dyaw_xlfw_zxhd }>()
 
-const showMsg = (() => {
+const showMsg = $computed(() => {
   switch (props.d.dxz_last_msg_type) {
     case '1': return decodeURIComponent(props.d.dxz_last_msg);
     case '2': return '[ 图片 ]';
   }
-})()
+})
 </script>
 
 <template>
@@ -19,7 +19,7 @@ const showMsg = (() => {
         <div class="opacity-40 text-sm">{{ d.dxz_last_msg_datetime }}</div>
       </div>
       <div class="flex justify-between">
-        <div class="opacity-40 text-sm text_wrapper" v-html="showMsg"></div>
+        <div class="opacity-40 text-sm text_wrapper max-w-50 h-20px overflow-hidden" v-html="showMsg"></div>
         <el-tag type="danger" effect="dark" round size="small">{{ d.dxz_unread_msg_num }}</el-tag>
       </div>
     </div>
@@ -30,5 +30,10 @@ const showMsg = (() => {
 .text_wrapper :deep(p) {
   margin: 0;
   padding: 0;
+  text-overflow: ellipsis;
+  height: 100%;
+  white-space: nowrap;
+  overflow: hidden;
+  width: 100%;
 }
 </style>

+ 1 - 1
src/components/info-item/index.vue

@@ -15,7 +15,7 @@ function formatTimestamp(t: string) {
   return getDatabaseTime(1000 * parseInt(t))
 }
 
-const showMsg = decodeURIComponent(props.d.dxzl_last_msg_content)
+const showMsg = decodeURIComponent(props.d.dxzl_last_msg_content!)
 </script>
 
 <template>

+ 40 - 5
src/pages/student/consult.vue

@@ -1,7 +1,8 @@
 <script setup lang="ts">
 import type { type_dyaw_xlfw_zxhd, type_dyaw_xlfw_zxhd_log } from '~/types';
 import user from '~/store/user';
-import { createSocket } from '~/utils/ws';
+import { createSocket, socketSend } from '~/utils/ws';
+import type { TSocketRes } from '~/utils/ws';
 
 const router = useRouter()
 let teacher
@@ -24,7 +25,7 @@ const dyaw_xlfw_zxhd: type_dyaw_xlfw_zxhd = (await request({
 
 const ChatAudioRef = $ref<typeof import('~/components/chat-audio/index.vue')['default']>()
 function handleClickEnd() {
-  ChatAudioRef && ChatAudioRef.open()
+  // ChatAudioRef && ChatAudioRef.open()
 }
 let infoList = $ref<Array<type_dyaw_xlfw_zxhd_log>>([])
 let inputValue = $ref('')
@@ -53,6 +54,14 @@ async function handleClickSend() {
     data: {
       dyaw_xlfw_zxhd_log: reqDate
     }
+  }).then(res => {
+    if (res.code === '1') {
+      socketSend(ws, {
+        create_user_id: user.user_id,
+        create_dateline: Date.now().toString().slice(0, 10),
+        ...reqDate
+      })
+    }
   })
 }
 
@@ -66,8 +75,34 @@ request({
     infoList = res.data.page_data.reverse()
   }
 })
-// const ws = createSocket()
+const ws = createSocket(
+  { teacher: teacher.user_id, student: user.user_id },
+  {
+    message(socketRes: TSocketRes<type_dyaw_xlfw_zxhd_log>) {
+      if (socketRes.from_client_name.endsWith('teacher')) {
+        infoList.push(socketRes.content)
+      }
+    }
+  }
+)
 
+const scrollbarRef = $ref<HTMLElement>()
+function scrollToBottom() {
+  if (!scrollbarRef) return;
+  const scrollHeight = scrollbarRef!.scrollHeight;
+  scrollbarRef!.scrollTo(0, scrollHeight);
+}
+watch(
+  () => (infoList),
+  () => {
+    nextTick(() => {
+      scrollToBottom()
+    })
+  },
+  {
+    deep: true,
+  }
+)
 
 </script>
 
@@ -79,8 +114,8 @@ request({
         <div class="text-pink-300 text-sm bg-white w-100px h-32px flex_center rounded-2xl cursor-pointer"
           @click="handleClickEnd">结束会话</div>
       </div>
-      <div
-        class="bg-hex-fff8fb h-410px p-6 scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
+      <div ref="scrollbarRef"
+        class="bg-hex-fff8fb space-y-2 h-410px p-6 scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
         <info-item v-for="item in infoList" :left="item.create_user_id === user.user_id" :d="item"></info-item>
       </div>
       <div class="bg-white h-180px p-5px flex flex-col justify-between">

+ 66 - 17
src/pages/teacher/consult.vue

@@ -2,23 +2,28 @@
 import type { type_dyaw_xlfw_zxhd, type_dyaw_xlfw_zxhd_log } from '~/types';
 import { Search } from '@element-plus/icons-vue'
 import user from '~/store/user';
-import { createSocket } from '~/utils/ws';
+import { createSocket, socketSend } from '~/utils/ws';
+import type { TSocketRes } from '~/utils/ws';
 
 let dyaw_xlfw_zxhd = $ref<type_dyaw_xlfw_zxhd | undefined>()
-const dyaw_xlfw_zxhd_list: type_dyaw_xlfw_zxhd[] = (await request({
-  url: '/dyaw/xlfw_zxhd/index',
-  data: {
-    dxz_tea_user_id: user.user_id
-  }
-})).data.page_data
-console.log('dyaw_xlfw_zxhd_list :>> ', dyaw_xlfw_zxhd_list);
+let dyaw_xlfw_zxhd_list = $ref<type_dyaw_xlfw_zxhd[] | undefined>()
+
+
+let timer: NodeJS.Timeout;
+(async function loop() {
+  dyaw_xlfw_zxhd_list = (await request({
+    url: '/dyaw/xlfw_zxhd/index',
+    data: {
+      dxz_tea_user_id: user.user_id
+    }
+  })).data.page_data
+  timer = setTimeout(async () => {
+    await loop();
+  }, 60 * 1000);
+})();
 
 const searchValue = $ref('')
 
-const ChatAudioRef = $ref<typeof import('~/components/chat-audio/index.vue')['default']>()
-function handleClickEnd() {
-  ChatAudioRef && ChatAudioRef.open()
-}
 let infoList = $ref<Array<type_dyaw_xlfw_zxhd_log>>([])
 let inputValue = $ref('')
 let TinyRef = $ref<typeof import('~/components/tinymce-area/index.vue')['default']>()
@@ -47,13 +52,24 @@ async function handleClickSend() {
     data: {
       dyaw_xlfw_zxhd_log: reqDate
     }
+  }).then(res => {
+    if (res.code === '1') {
+      socketSend(ws!, {
+        create_user_id: user.user_id,
+        create_dateline: Date.now().toString().slice(0, 10),
+        ...reqDate
+      })
+    }
   })
 }
 
-// const ws = createSocket()
+let ws = $ref<WebSocket>()
+
 
 function handleClickStuCard(stu: type_dyaw_xlfw_zxhd) {
   dyaw_xlfw_zxhd = stu
+  stu.dxz_unread_msg_num = "0"
+  ws?.close()
   request({
     url: '/dyaw/xlfw_zxhd_log/index',
     data: {
@@ -63,10 +79,43 @@ function handleClickStuCard(stu: type_dyaw_xlfw_zxhd) {
   }).then(res => {
     if (res.code === '1') {
       infoList = res.data.page_data.reverse()
+      ws = createSocket(
+        { teacher: user.user_id, student: stu.dxz_stu_user_id },
+        {
+          message(socketRes: TSocketRes<type_dyaw_xlfw_zxhd_log>) {
+            if (socketRes.from_client_name.endsWith('student')) {
+              infoList.push(socketRes.content)
+            }
+          }
+        }
+      )
     }
   })
+
 }
 
+const scrollbarRef = $ref<HTMLElement>()
+function scrollToBottom() {
+  if (!scrollbarRef) return;
+  const scrollHeight = scrollbarRef!.scrollHeight;
+  scrollbarRef!.scrollTo(0, scrollHeight);
+}
+watch(
+  () => (infoList),
+  () => {
+    nextTick(() => {
+      scrollToBottom()
+    })
+  },
+  {
+    deep: true,
+  }
+)
+
+
+onBeforeUnmount(() => {
+  clearInterval(timer)
+})
 </script>
 
 <template>
@@ -82,10 +131,11 @@ function handleClickStuCard(stu: type_dyaw_xlfw_zxhd) {
     <div class="w-680px h-full divide-y flex flex-col">
       <template v-if="dyaw_xlfw_zxhd">
         <div class="bg-pink-300 flex justify-between h-48px items-center px-18px">
-          <span class="text-lg px-1 tracking-wider">王晓宇 当阳中学 六年级(1)班</span>
+          <span class="text-lg px-1 tracking-wider">{{ dyaw_xlfw_zxhd.dxz_stu_user_realname }}
+            {{ dyaw_xlfw_zxhd.dxz_stu_school_name }} {{ dyaw_xlfw_zxhd.dxz_class_name }}</span>
         </div>
-        <div
-          class="bg-hex-fff8fb h-410px p-6 scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
+        <div ref="scrollbarRef"
+          class="bg-hex-fff8fb space-y-2 h-410px p-6 scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
           <info-item v-for="item in infoList" :left="item.create_user_id === user.user_id" :d="item"></info-item>
         </div>
         <div class="bg-white h-180px p-5px flex flex-col justify-between">
@@ -113,7 +163,6 @@ function handleClickStuCard(stu: type_dyaw_xlfw_zxhd) {
     </div>
   </div>
 
-  <!-- <chat-audio ref="ChatAudioRef"></chat-audio> -->
 </template>
 
 <style scoped lang="scss">

+ 4 - 2
src/types.ts

@@ -1,4 +1,4 @@
-import type { ReactiveVariable } from 'vue';
+// import type { ReactiveVariable } from 'vue';
 
 export type type_dyaw_xlfw_zxhd = {
   dxz_stu_user_id: string;
@@ -9,6 +9,8 @@ export type type_dyaw_xlfw_zxhd = {
   dxz_last_msg: string;
   dxz_unread_msg_num: string;
   dxz_last_msg_type: string;
+  dxz_stu_school_name: string;
+  dxz_class_name: string;
   dxz_id: string;
 }
 
@@ -19,7 +21,7 @@ export type type_dyaw_xlfw_zxhd_log = {
   dxzl_stu_user_realname: string;
   dxzl_tea_user_id: string;
   dxzl_tea_user_realname: string;
-  dxzl_last_msg_content?: string | ReactiveVariable<string>;
+  dxzl_last_msg_content?: string;
   dxzl_type: string;
   create_user_id: string;
   create_dateline: string

+ 43 - 7
src/utils/ws.ts

@@ -1,14 +1,32 @@
-import user from '~/store/user';
+import user, { UserRole } from '~/store/user';
 
-export function createSocket() {
+export type TSocketRes<T> = {
+  content: T
+  from_client_id: string
+  from_client_name: string
+  time: string
+  to_client_id: string
+  type: string
+}
+
+const CLIENT_NAME = `${user.user_id}|${user.user_realname}|${UserRole}`
+export function createSocket(
+  options: { teacher: string, student: string },
+  hooks: {
+    message: Function
+  }
+) {
   const ws = new WebSocket("wss://socket.bozedu.net")
 
   ws.addEventListener('message', (e) => {
     if (e.data) {
       try {
-        const data = JSON.parse(e.data)
+        const data: TSocketRes<string> = JSON.parse(e.data)
+        if (CLIENT_NAME === data.from_client_name) return
         if (data.type !== 'ping') {
-          console.log('ws message :>> ', data);
+          console.groupCollapsed(`Socket : ${data.type}`)
+          console.log(data);
+          console.groupEnd();
         }
 
         if (data.type === 'login') {
@@ -16,7 +34,15 @@ export function createSocket() {
         }
 
         if (data.type === 'say') {
+          const content =  {
+            ...data,
+            content: JSON.parse(decodeURIComponent(data.content))
+          }
+          console.groupCollapsed(`|- Socket Say:`)
+          console.log(content);
+          console.groupEnd();
 
+          hooks.message(content)
         }
       } catch (error) {
         console.error(error);
@@ -31,11 +57,21 @@ export function createSocket() {
   ws.addEventListener('open', (e) => {
     ws.send(JSON.stringify({
       "type": "login",
-      // "client_id": user.user_id,
-      "client_name": user.user_id + '|' + user.user_realname,
-      "room_id": 'aiwen_consult'
+      "client_name": CLIENT_NAME,
+      "room_id": `aiwen_consult_${options.teacher}_${options.student}`
     }))
   })
 
+
   return ws
 }
+
+export function socketSend(ws: WebSocket, content: unknown) {
+  ws.send(
+    JSON.stringify({
+      type: "say",
+      to_client_id: 'all',
+      content: encodeURIComponent(JSON.stringify(content))
+    })
+  )
+}