|
@@ -1,383 +0,0 @@
|
|
|
-<script setup lang="ts">
|
|
|
-import AgoraRTC from "agora-rtc-sdk-ng"
|
|
|
-import type { IAgoraRTCClient, IMicrophoneAudioTrack, ICameraVideoTrack } from "agora-rtc-sdk-ng"
|
|
|
-import type { type_dyaw_xlfw_zxhd, type_dyaw_xlfw_zxhd_log, type_archives_item } from '~/types';
|
|
|
-import { Search } from '@element-plus/icons-vue'
|
|
|
-import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
-import user from '~/store/user';
|
|
|
-import { createSocket, socketSend } from '~/utils/ws';
|
|
|
-import type { TSocketRes } from '~/utils/ws';
|
|
|
-import { formatTimestamp2Date } from '~/utils/time';
|
|
|
-import { CHAT_STATUS, CHAT_OPERATION } from '~/types';
|
|
|
-let dyaw_xlfw_zxhd = $ref<type_dyaw_xlfw_zxhd | undefined>()
|
|
|
-let dyaw_xlfw_zxhd_list = $ref<type_dyaw_xlfw_zxhd[] | undefined>()
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-const searchValue = $ref('搜索')
|
|
|
-watch(
|
|
|
- () => searchValue,
|
|
|
- async (val, oldVal) => {
|
|
|
- if (oldVal === '搜索') return;
|
|
|
- dyaw_xlfw_zxhd_list = (await request({
|
|
|
- url: '/dyaw/xlfw_zxhd/index',
|
|
|
- data: {
|
|
|
- dxz_tea_user_id: user.user_id,
|
|
|
- dxz_stu_user_realname: searchValue === '搜索' ? undefined : searchValue,
|
|
|
- limit: 20,
|
|
|
- last_msg: 1
|
|
|
- }
|
|
|
- })).data.page_data
|
|
|
- }
|
|
|
-)
|
|
|
-
|
|
|
-
|
|
|
-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,
|
|
|
- dxz_stu_user_realname: searchValue === '搜索' ? undefined : searchValue,
|
|
|
- limit: 20,
|
|
|
- last_msg: 1
|
|
|
- }
|
|
|
- })).data.page_data
|
|
|
- if (dyaw_xlfw_zxhd !== undefined) {
|
|
|
- const temp = dyaw_xlfw_zxhd_list!.find(item => item.dxz_stu_user_id === dyaw_xlfw_zxhd!.dxz_stu_user_id)
|
|
|
- if (temp?.dxz_id !== dyaw_xlfw_zxhd?.dxz_id) {
|
|
|
- dyaw_xlfw_zxhd = temp
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- timer = setTimeout(async () => {
|
|
|
- await loop();
|
|
|
- }, 60 * 1000);
|
|
|
-})();
|
|
|
-
|
|
|
-let infoList = $ref<Array<type_dyaw_xlfw_zxhd_log>>([])
|
|
|
-let inputValue = $ref('')
|
|
|
-let isSending = $ref(false)
|
|
|
-let TinyRef = $ref<typeof import('~/components/tinymce-area/index.vue')['default']>()
|
|
|
-async function handleClickSend() {
|
|
|
- if (!dyaw_xlfw_zxhd) return;
|
|
|
- if (isSending) return;
|
|
|
- isSending = true
|
|
|
- const reqDate = {
|
|
|
- dxz_id: dyaw_xlfw_zxhd.dxz_id,
|
|
|
- dxzl_stu_user_id: dyaw_xlfw_zxhd.dxz_stu_user_id,
|
|
|
- dxzl_stu_user_realname: dyaw_xlfw_zxhd.dxz_stu_user_realname,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd.dxz_tea_user_id,
|
|
|
- dxzl_tea_user_realname: dyaw_xlfw_zxhd.dxz_tea_user_realname,
|
|
|
- dxzl_last_msg_content: encodeURIComponent(inputValue),
|
|
|
- dxzl_type: inputValue.includes('><img') ? '2' : '1'
|
|
|
- }
|
|
|
-
|
|
|
- // infoList.push({
|
|
|
- // create_user_id: user.user_id,
|
|
|
- // create_dateline: Date.now().toString().slice(0, 10),
|
|
|
-
|
|
|
- // ...reqDate
|
|
|
- // })
|
|
|
- TinyRef?.clear()
|
|
|
- // console.log('inputValue :>> ', inputValue);
|
|
|
- request({
|
|
|
- url: '/dyaw/xlfw_zxhd_log/add',
|
|
|
- data: {
|
|
|
- dyaw_xlfw_zxhd_log: reqDate
|
|
|
- }
|
|
|
- }).then(res => {
|
|
|
- if (res.code === '1') {
|
|
|
- const fullSendData = {
|
|
|
- create_user_id: user.user_id,
|
|
|
- create_dateline: Date.now().toString().slice(0, 10),
|
|
|
- ...reqDate,
|
|
|
- dxzl_id: `${res.data.insert_id}`
|
|
|
- }
|
|
|
- infoList.push(fullSendData)
|
|
|
- socketSend(ws!, fullSendData)
|
|
|
- isSending = false
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-let ws = $ref<WebSocket>()
|
|
|
-
|
|
|
-let cardLoading = $ref(false)
|
|
|
-let unreadNum = $ref(0)
|
|
|
-
|
|
|
-// function getAllUnreadMsg() {
|
|
|
-// request({
|
|
|
-// url: '/dyaw/xlfw_zxhd_log/index',
|
|
|
-// data: {
|
|
|
-// dxzl_stu_user_id: dyaw_xlfw_zxhd?.dxz_stu_user_id,
|
|
|
-// dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
-// limit: 1
|
|
|
-// }
|
|
|
-// }).then(res => {
|
|
|
-// if (res.code === '1') {
|
|
|
-// ifScroll = false
|
|
|
-// infoList = (res.data.page_data.reverse())
|
|
|
-// unreadNum = 0
|
|
|
-// }
|
|
|
-// nextTick(() => {
|
|
|
-// ifScroll = true
|
|
|
-// // scrollbarRef!.scrollTo(0, 0);
|
|
|
-// })
|
|
|
-// })
|
|
|
-// }
|
|
|
-
|
|
|
-function handleClickStuCard(stu: type_dyaw_xlfw_zxhd) {
|
|
|
- cardLoading = true
|
|
|
- dyaw_xlfw_zxhd = stu
|
|
|
- unreadNum = parseInt(stu.dxz_unread_msg_num)
|
|
|
- stu.dxz_unread_msg_num = "0"
|
|
|
- archivesList = []
|
|
|
-
|
|
|
- ws?.close()
|
|
|
- request({
|
|
|
- url: '/dyaw/xlfw_zxhd_log/index',
|
|
|
- data: {
|
|
|
- dxzl_stu_user_id: stu.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- }
|
|
|
- }).then(res => {
|
|
|
- if (res.code === '1') {
|
|
|
- infoList = res.data.page_data.reverse()
|
|
|
- cardLoading = false
|
|
|
- ws = createSocket(
|
|
|
- { teacher: user.user_id, student: stu.dxz_stu_user_id },
|
|
|
- {
|
|
|
- message(socketRes: TSocketRes<type_dyaw_xlfw_zxhd_log & { $?: boolean, dxz_stu_user_id?: string, dyaw_xlfw_zxhd: type_dyaw_xlfw_zxhd }>) {
|
|
|
- if (socketRes.from_client_name.endsWith('student')) {
|
|
|
- if (socketRes.content.$) {
|
|
|
- if (socketRes.content?.dxz_stu_user_id === dyaw_xlfw_zxhd?.dxz_stu_user_id) {
|
|
|
- dyaw_xlfw_zxhd = socketRes.content.dyaw_xlfw_zxhd
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
- infoList.push(socketRes.content)
|
|
|
- request({
|
|
|
- url: '/dyaw/xlfw_zxhd_log/index',
|
|
|
- data: {
|
|
|
- dxzl_stu_user_id: stu.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- limit: 0
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- )
|
|
|
-
|
|
|
- handleQueryArchives()
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-let ifScroll = $ref(true)
|
|
|
-function handleLoadMoreInfo() {
|
|
|
- request({
|
|
|
- url: '/dyaw/xlfw_zxhd_log/index',
|
|
|
- data: {
|
|
|
- dxzl_stu_user_id: dyaw_xlfw_zxhd?.dxz_stu_user_id,
|
|
|
- dxzl_tea_user_id: dyaw_xlfw_zxhd!.dxz_tea_user_id,
|
|
|
- zxhd_log_id: infoList[0].dxzl_id
|
|
|
- }
|
|
|
- }).then(res => {
|
|
|
- if (res.code === '1') {
|
|
|
- ifScroll = false
|
|
|
- if (res.data.page_data.length === 0) return ElMessage.info('暂无更多消息');
|
|
|
- infoList.unshift(...res.data.page_data.reverse())
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-const scrollbarRef = $ref<HTMLElement>()
|
|
|
-function scrollToBottom() {
|
|
|
- if (!scrollbarRef) return;
|
|
|
- const scrollHeight = scrollbarRef!.scrollHeight;
|
|
|
- scrollbarRef!.scrollTo(0, scrollHeight);
|
|
|
-}
|
|
|
-watch(
|
|
|
- () => (infoList),
|
|
|
- () => {
|
|
|
- nextTick(() => {
|
|
|
- ifScroll && scrollToBottom();
|
|
|
- ifScroll = true
|
|
|
- })
|
|
|
- },
|
|
|
- {
|
|
|
- deep: true,
|
|
|
- }
|
|
|
-)
|
|
|
-
|
|
|
-
|
|
|
-onBeforeUnmount(() => {
|
|
|
- clearInterval(timer)
|
|
|
-})
|
|
|
-
|
|
|
-const ArchivesCardRef = $ref<typeof import('~/components/archives-card/index.vue')['default']>()
|
|
|
-function handleSubmitArchives() {
|
|
|
- ElMessageBox.confirm('一次咨询只能提交一次档案,请确认完毕后点击提交', '提示')
|
|
|
- .then(() => {
|
|
|
- request({
|
|
|
- url: '/dyaw/xlfw_xsda_dajl/add',
|
|
|
- data: {
|
|
|
- dyaw_xlfw_xsda_dajl: ArchivesCardRef!.form
|
|
|
- }
|
|
|
- }).then(res => {
|
|
|
- if (res.code === '1') {
|
|
|
-
|
|
|
- handleQueryArchives()
|
|
|
- }
|
|
|
- })
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- ElMessage({
|
|
|
- type: 'info',
|
|
|
- message: '取消提交',
|
|
|
- })
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-let archivesList = $ref<type_archives_item[]>([])
|
|
|
-function handleQueryArchives() {
|
|
|
- request({
|
|
|
- url: '/dyaw/xlfw_xsda_dajl/index',
|
|
|
- data: {
|
|
|
- user_id: dyaw_xlfw_zxhd!.dxz_stu_user_id
|
|
|
- }
|
|
|
- }).then(res => {
|
|
|
- if (res.code === '1') {
|
|
|
- archivesList = res.data.page_data
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-// ==========
|
|
|
-// chat audio/video
|
|
|
-// ==========
|
|
|
-
|
|
|
-let RtcDialogRef = $ref<typeof import("~/components/rtc-dialog/index.vue")['default']>()
|
|
|
-
|
|
|
-const ws2 = createSocket(
|
|
|
- { teacher: user.user_id, student: '*' },
|
|
|
- {
|
|
|
- message(socketRes: TSocketRes<type_dyaw_xlfw_zxhd_log & { operate: CHAT_OPERATION }>) {
|
|
|
- if (socketRes.from_client_name.endsWith('student')) {
|
|
|
- // infoList.push(socketRes.content)
|
|
|
- if (socketRes.content.dxzl_tea_user_id === user.user_id) {
|
|
|
- RtcDialogRef!.publisher(socketRes.content)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-)
|
|
|
-onMounted(() => {
|
|
|
- RtcDialogRef!.init(ws2)
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-async function handleAudioChatStart() {
|
|
|
- RtcDialogRef!.open(dyaw_xlfw_zxhd, 'audio')
|
|
|
-}
|
|
|
-
|
|
|
-async function handleVideoChatStart() {
|
|
|
- RtcDialogRef!.open(dyaw_xlfw_zxhd, 'video')
|
|
|
-}
|
|
|
-
|
|
|
-function emitUpdateInfo(info: type_dyaw_xlfw_zxhd_log, isUpdate?: boolean) {
|
|
|
- if (!isUpdate) {
|
|
|
- if (info.dxz_id === dyaw_xlfw_zxhd?.dxz_id)
|
|
|
- infoList.push(info)
|
|
|
- }
|
|
|
- else {
|
|
|
- const target = infoList.find(item => (item.dxzl_id)?.toString() === info.dxzl_id?.toString())
|
|
|
- if (target)
|
|
|
- target.dxzl_last_msg_content = info.dxzl_last_msg_content
|
|
|
- }
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<template>
|
|
|
- <div class="h-590px bg-hex-f2f2f295 flex justify-center divide-x">
|
|
|
- <div class="w-320px p-10px h-full flex flex-col justify-start bg-white space-y-4">
|
|
|
- <el-input autocomplete="off" name="searchValue" v-model="searchValue" size="large" :prefix-icon="Search"
|
|
|
- @focus="searchValue = ''" clearable placeholder="搜索"
|
|
|
- :style="`${searchValue === '搜索' && '--ep-input-text-color:var(--ep-text-color-placeholder);'}`"></el-input>
|
|
|
- <div
|
|
|
- class="max-h-520px flex flex-col flex-none divide-y scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
|
|
|
- <chat-stu-card v-for="item in dyaw_xlfw_zxhd_list" :d="item" @click="handleClickStuCard(item)"
|
|
|
- class="h-68px"></chat-stu-card>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="w-680px h-full divide-y flex flex-col relative">
|
|
|
- <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">{{ dyaw_xlfw_zxhd.dxz_stu_user_realname }}
|
|
|
- {{ dyaw_xlfw_zxhd.dxz_stu_school_name }} {{ dyaw_xlfw_zxhd.dxz_class_name }}</span>
|
|
|
- </div>
|
|
|
- <div ref="scrollbarRef"
|
|
|
- class="bg-hex-fff8fb space-y-2 h-410px py-2 px-6 scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent relative">
|
|
|
- <div v-show="!cardLoading" @click="handleLoadMoreInfo"
|
|
|
- class="w-full text-center text-sm text-blue-400 hover:underline underline-blue-400 cursor-pointer">查看更多
|
|
|
- </div>
|
|
|
- <info-item v-for="item in infoList" :key="item.dxzl_id" :left="item.create_user_id !== user.user_id" :d="item"
|
|
|
- :w="500"></info-item>
|
|
|
-
|
|
|
- </div>
|
|
|
- <!-- -->
|
|
|
- <!-- <div v-show="unreadNum > 10"
|
|
|
- class="absolute bg-white right-2 bottom-200px text-blue-400 rounded-l-full cursor-pointer z-100 flex items-center space-x-1 p-2 text-sm"
|
|
|
- @click="getAllUnreadMsg">
|
|
|
- <i:material-symbols:keyboard-double-arrow-up />
|
|
|
- <span>{{ unreadNum }}条消息</span>
|
|
|
- </div> -->
|
|
|
- <div class="bg-white h-180px p-5px flex flex-col justify-between">
|
|
|
- <tinymce-area v-model="inputValue" ref="TinyRef" @click:audio="handleAudioChatStart"
|
|
|
- @click:video="handleVideoChatStart" @click:submit="handleClickSend"></tinymce-area>
|
|
|
- <div class="flex justify-end">
|
|
|
- <div class="bg-pink-300 text-sm text-white w-80px h-32px flex_center rounded-2xl cursor-pointer"
|
|
|
- @click="handleClickSend">发送</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <div class="bg-pink-300 flex justify-between h-48px items-center px-18px"></div>
|
|
|
- <div class="bg-hex-fff8fb flex-auto w-full flex_center">
|
|
|
- <el-empty description="请先选择聊天的学生"></el-empty>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
-
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="w-400px h-full bg-white overflow-y-auto flex flex-col items-center px-2 py-2 divide-y scrollbar scrollbar-thin scrollbar-thumb-rounded-md scrollbar-thumb-gray-200 scrollbar-track-transparent">
|
|
|
- <div v-if="dyaw_xlfw_zxhd" :key="dyaw_xlfw_zxhd.dxz_stu_user_id">
|
|
|
- <div class="w-full"
|
|
|
- v-if="archivesList && (archivesList.length === 0 || dyaw_xlfw_zxhd.dxz_id !== archivesList[0].dxz_id)">
|
|
|
- <archives-card storage ref="ArchivesCardRef"
|
|
|
- :d="{ dxz_id: dyaw_xlfw_zxhd.dxz_id, user_id: dyaw_xlfw_zxhd.dxz_stu_user_id, dxxd_lfzxm: dyaw_xlfw_zxhd.dxz_stu_user_realname, dxxd_jfls: dyaw_xlfw_zxhd.dxz_tea_user_realname, dxxd_school_name: dyaw_xlfw_zxhd.dxz_stu_school_name, dxxd_class_name: dyaw_xlfw_zxhd.dxz_class_name, dxxd_date: formatTimestamp2Date(dyaw_xlfw_zxhd.create_dateline) }"></archives-card>
|
|
|
- <div class="flex_center py-2">
|
|
|
- <el-button @click="handleSubmitArchives" type="primary" size="small">提交</el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="bg-hex-FFF7FA py-2 space-y-1">
|
|
|
- <div class="flex_center text-lg">历史档案</div>
|
|
|
- <el-empty v-show="archivesList.length === 0" :image-size="60" description="暂无历史档案"></el-empty>
|
|
|
- <archives-card disabled v-for="item in archivesList" :d="item" :key="item.dxxd_id"></archives-card>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- <rtc-dialog ref="RtcDialogRef" @update-info="emitUpdateInfo"></rtc-dialog>
|
|
|
-</template>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
-</style>
|