Compare commits

...

5 Commits

13 changed files with 336 additions and 133 deletions

View File

@ -80,6 +80,8 @@ import { updateUserInfo } from '@/api/system/user'
import logoIco from '@/assets/images/logo.png' import logoIco from '@/assets/images/logo.png'
import { listEvaluation } from '@/api/classManage/index' import { listEvaluation } from '@/api/classManage/index'
import { sessionStore } from '@/utils/store' import { sessionStore } from '@/utils/store'
import Chat from '@/utils/chat' // im
if (!Chat.imChat) Chat.init()
let homeTitle = ref(import.meta.env.VITE_APP_TITLE) let homeTitle = ref(import.meta.env.VITE_APP_TITLE)
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
@ -143,6 +145,7 @@ function handleCommand(command) {
break break
case 'logout': case 'logout':
logout() logout()
Chat?.logout() // im 退
break break
default: default:
break break

View File

@ -19,8 +19,11 @@ import AppMain from './components/AppMain.vue'
import Uploader from './components/Uploader.vue' import Uploader from './components/Uploader.vue'
import AiChart from '@/components/ai-chart/index.vue' import AiChart from '@/components/ai-chart/index.vue'
import uploaderState from '@/store/modules/uploader' import uploaderState from '@/store/modules/uploader'
// import Chat from '@/utils/chat'
let uploaderStore = ref(uploaderState()) let uploaderStore = ref(uploaderState())
// window.test = Chat
// Chat.init()
</script> </script>

View File

@ -70,7 +70,10 @@ export class ImChat {
// 日志监听 // 日志监听
this.timChat.TIMSetLogCallback({ this.timChat.TIMSetLogCallback({
callback: data => { callback: data => {
this.setConsole('%cchat-log ', data[1]) const [type, log] = data
if (type == log_level) { // 打印对应日志
this.setConsole('%cchat-log ', log)
}
}, },
user_data: '' user_data: ''
}) })
@ -86,7 +89,7 @@ export class ImChat {
if (code == 0) { // 初始化成功 if (code == 0) { // 初始化成功
this.setConsole('%cim-chat: init', '初始化成功') this.setConsole('%cim-chat: init', '初始化成功')
this.status.isConnect = true this.status.isConnect = true
this.setConfig() // 设置日志级别 // this.setConfig() // 设置日志级别
resolve(this) resolve(this)
} else { // 失败具体请看code } else { // 失败具体请看code
console.error('[im-chat]:初始化失败', code) console.error('[im-chat]:初始化失败', code)
@ -227,10 +230,11 @@ export class ImChat {
}) })
} }
// 删除群组 // 删除群组
deleteGroup() { deleteGroup(timGroupId) {
if (!this.timGroupId) return const groupId = timGroupId || this.timGroupId
if (!groupId) return
return this.timChat.TIMGroupDelete({ return this.timChat.TIMGroupDelete({
groupId: this.timGroupId, groupId,
data: '', // 用户自定义数据 data: '', // 用户自定义数据
}) })
} }
@ -249,7 +253,7 @@ export class ImChat {
} }
// 获取群组列表 // 获取群组列表
getGroupList() { getGroupList() {
return this.timChat.getGroupList().then(res => { return this.timChat.TIMGroupGetJoinedGroupList().then(res => {
console.log('获取群组列表', res) console.log('获取群组列表', res)
return res return res
}).catch(error => { }).catch(error => {

View File

@ -0,0 +1,98 @@
/**
* 实现单例模式
*/
import useUserStore from '@/store/modules/user'
import { ImChat } from '@/plugins/imChat'
import * as http from '@/api/apiService' // 自定义api service
export class Chat {
instance = null;
sdkAppId = 0; // 应用id
sign = ''; // 签名
imUserId = ''; // 用户id
imChat = null; // IM实例
constructor() {
if (!Chat.instance) { // 存在的时候
Chat.instance = this;
}
return Chat.instance;
}
/**
* 初始化 获取IM签名
* @param {*} isInit : 是否初始化IM
* @param {*} isLogin : 是否登录IM
* @param {*} callback: 监听消息回调函数
* @returns Promise<ImChat>
*/
async init(isInit = true, isLogin = true, callback) {
// 特殊处理只传1个参数且为函数则默认为callbackisInit和isLogin默认为true
if (typeof isInit == 'function'){
callback = isInit
isInit = true
isLogin = true
}
const userStore = useUserStore()
const { timuserid: imUserId } = userStore.user
// 获取腾讯云签名
const res = await http.imChat.getTxCloudSign({imUserId})
if (res && res.code == 200) {
const { sdkAppId, sign } = res.data
this.sdkAppId = sdkAppId
this.sign = sign
this.imUserId = imUserId
// 初始化IM
if (isInit) return await this.initIM(isLogin, callback)
}
}
// 初始化IM
async initIM(isLogin, callback) {
const imChat = new ImChat(this.sdkAppId, this.sign, this.imUserId)
this.imChat = imChat
await imChat.init() // 初始化IM
callback && this.listenMsg(callback) // 监听消息
if(isLogin) await imChat.login() // 登录IM
return imChat
}
// 监听消息
async listenMsg(callback) {
if (!callback) return
if (!this.imChat) return
await this.imChat?.watch(msg => callback(msg))
}
// 解散群
async dismissGroup(groupId) {
if (!this.imChat) return
await this.imChat?.deleteGroup(groupId)
}
// 退出登录
async logout() {
if (!this.imChat) return
await this.imChat?.logout()
imChat = null
this.imChat = null
}
// 发群消息
async sendMsg(conv_id, msg) {
if (!this.imChat) return
await this.imChat?.sendMsg(conv_id, msg)
}
// 发群消息
async sendMsgGroup(msg, head, type) {
if (!this.imChat) return
this.imChat?.sendMsgGroup(msg, head, type)
}
// 发群消息
async sendMsgGroupId(groupId, msg, head, type) {
if (!this.imChat) return
const msgObj = this.imChat?.getMsgObj(head, msg, type)
this.imChat?.sendMsg(groupId, msgObj)
}
// 获取群列表
async getGroupList() {
if (!this.imChat) return
return await this.imChat?.getGroupList()
}
}
export default new Chat()

View File

@ -11,6 +11,7 @@
v-if="item.bookImg" v-if="item.bookImg"
@open-edit="reservDialog.openDialog(item)" @open-edit="reservDialog.openDialog(item)"
@delete-reserv="deleteReserv(item)" @delete-reserv="deleteReserv(item)"
@change="(...o) => emit('change', ...o)"
></reserv-item> ></reserv-item>
<reserv-item-apt <reserv-item-apt
v-if="!item.bookImg" v-if="!item.bookImg"
@ -18,6 +19,7 @@
:item="item" :item="item"
@open-edit="reservDialog.openDialog(item)" @open-edit="reservDialog.openDialog(item)"
@delete-reserv="deleteReserv(item)" @delete-reserv="deleteReserv(item)"
@change="(...o) => emit('change', ...o)"
></reserv-item-apt> ></reserv-item-apt>
</template> </template>
</div> </div>
@ -34,6 +36,10 @@ import Reserv from '@/views/prepare/container/reserv.vue'
import { useToolState } from '@/store/modules/tool' import { useToolState } from '@/store/modules/tool'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import ReservItemApt from '@/views/classManage/reserv-item-apt.vue' import ReservItemApt from '@/views/classManage/reserv-item-apt.vue'
// import Chat from '@/utils/chat' // im
// if (!Chat.imChat) Chat.init()
const emit = defineEmits(['change'])
const reservDialog = ref(null) const reservDialog = ref(null)
const tabOptions = ref(['进行中', '已结束']) const tabOptions = ref(['进行中', '已结束'])
const tabActive = ref('进行中') const tabActive = ref('进行中')

View File

@ -7,14 +7,14 @@
<span>{{item.caption}}</span> <span>{{item.caption}}</span>
</div> </div>
<div class="class-reserv-item-tool" style="width: 200px;max-width: 300px"> <div class="class-reserv-item-tool" style="width: 200px;max-width: 300px">
<el-tag v-if="item.status === 'close'" style="margin-right: 5px" type="success">已结束</el-tag> <el-tag v-if="item.status === 'closed'" style="margin-right: 5px" type="success">已结束</el-tag>
<el-tag v-if="item.status === 'open'" style="margin-right: 5px" type="danger">上课中</el-tag> <el-tag v-if="item.status === 'open'" style="margin-right: 5px" type="danger">上课中</el-tag>
<el-button v-if="item.status === 'open'" :disabled="toolStore.isToolWin" size="small" type="primary" @click="startClassR(item)" <el-button v-if="item.status === 'open'" :disabled="toolStore.isToolWin" size="small" type="primary" @click="startClassR(item)"
>继续上课</el-button >继续上课</el-button
> >
<!-- <el-button v-if="item.status === '未开始'" @click="openEdit">编辑</el-button>--> <!-- <el-button v-if="item.status === '未开始'" @click="openEdit">编辑</el-button>-->
<el-button v-if="item.status === 'open'" size="small" type="info" @click="endClassR(item)" <el-button v-if="item.status === 'open'" :loading="loading" size="small" type="info" @click="endClassR(item)"
>下课</el-button >下课{{ loading?'中...':'' }}</el-button
> >
</div> </div>
<div class="class-reserv-item-tool" style="width: 50px;"> <div class="class-reserv-item-tool" style="width: 50px;">
@ -25,13 +25,14 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'
import { useToolState } from '@/store/modules/tool' import { useToolState } from '@/store/modules/tool'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import { createWindow } from '@/utils/tool' import { createWindow } from '@/utils/tool'
import { deleteSmartReserv, startClass, endClass } from '@/api/classManage' import { deleteSmartReserv, startClass, endClass } from '@/api/classManage'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { listEntpcourse } from '@/api/teaching/classwork' import { listEntpcourse } from '@/api/teaching/classwork'
const emit = defineEmits(['openEdit', 'deleteReserv']) const emit = defineEmits(['openEdit', 'deleteReserv', 'change'])
const props = defineProps({ const props = defineProps({
item: { item: {
type: Object, type: Object,
@ -40,6 +41,7 @@ const props = defineProps({
}) })
const basePath = import.meta.env.VITE_APP_BUILD_BASE_PATH const basePath = import.meta.env.VITE_APP_BUILD_BASE_PATH
const toolStore = useToolState() // -tool const toolStore = useToolState() // -tool
const loading = ref(false) // loading
const openEdit = () => { const openEdit = () => {
emit('openEdit', props.item) emit('openEdit', props.item)
} }
@ -54,42 +56,15 @@ const deleteReserv = () => {
} }
}) })
} }
//
const startClassR = (item) => { const startClassR = (item) => {
// startClass(item.id).then((res) => { emit('change', 'continue', item)
// if (res.data === true) {
// item.status = ''
// openLesson()
// }
// })
// item.status = ''
openLesson()
} }
//
const endClassR = (item) => { const endClassR = (item) => {
/*endClass(item.id).then((res) => { emit('change', 'close', item, { type: 2, loading })
if (res.data === true) {
ElMessage({
message: '下课成功',
type: 'success'
})
item.status = '已结束'
}
})*/
}
// const toolStore = useToolState()
let wins = null;
// -
const openLesson = () => {
// startClass(props.item.id)
/*listEntpcourse({
evalid: props.item.ex2,
edituserid: useUserStore().user.userId,
pageSize: 500
}).then(async res=>{
if (res.rows[0].id) {
wins = await createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + res.rows[0].id + "&reservId=" + props.item.id })
}
})*/
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.class-reserv-item { .class-reserv-item {

View File

@ -13,8 +13,8 @@
>继续上课</el-button >继续上课</el-button
> >
<!-- <el-button v-if="item.status === '未开始'" @click="openEdit">编辑</el-button>--> <!-- <el-button v-if="item.status === '未开始'" @click="openEdit">编辑</el-button>-->
<el-button v-if="item.status === '上课中'" size="small" type="info" @click="endClassR(item)" <el-button v-if="item.status === '上课中'" :loading="loading" size="small" type="info" @click="endClassR(item)"
>下课</el-button >下课{{ loading?'中...':'' }}</el-button
> >
</div> </div>
<div class="class-reserv-item-tool" style="width: 50px;"> <div class="class-reserv-item-tool" style="width: 50px;">
@ -25,13 +25,14 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'
import { useToolState } from '@/store/modules/tool' import { useToolState } from '@/store/modules/tool'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import { createWindow } from '@/utils/tool' import { createWindow } from '@/utils/tool'
import { deleteSmartReserv, startClass, endClass } from '@/api/classManage' import { deleteSmartReserv, startClass, endClass } from '@/api/classManage'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { listEntpcourse } from '@/api/teaching/classwork' import { listEntpcourse } from '@/api/teaching/classwork'
const emit = defineEmits(['openEdit', 'deleteReserv']) const emit = defineEmits(['openEdit', 'deleteReserv','change'])
const props = defineProps({ const props = defineProps({
item: { item: {
type: Object, type: Object,
@ -40,6 +41,7 @@ const props = defineProps({
}) })
const basePath = import.meta.env.VITE_APP_BUILD_BASE_PATH const basePath = import.meta.env.VITE_APP_BUILD_BASE_PATH
const toolStore = useToolState() // -tool const toolStore = useToolState() // -tool
const loading = ref(false) // loading
const openEdit = () => { const openEdit = () => {
emit('openEdit', props.item) emit('openEdit', props.item)
} }
@ -80,15 +82,7 @@ const openLesson = () => {
}) })
} }
const endClassR = (item) => { const endClassR = (item) => {
endClass(item.id).then((res) => { emit('change', 'close', item, { type: 2, loading })
if (res.data === true) {
ElMessage({
message: '下课成功',
type: 'success'
})
item.status = '已结束'
}
})
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -15,11 +15,11 @@ const chartRef = ref(null);
// //
const dataList = ref([ const dataList = ref([
{name: '', value: 0,rating:1}, {name: '完美', value: 0,rating:1,max:100,min:100,},
{name: '优-', value: 0,rating:2}, {name: '优', value: 0,rating:2,max:99,min:80,},
{name: '良', value: 0,rating:3}, {name: '良', value: 0,rating:3,max:79,min:70,},
{name: '良-', value: 0,rating:4}, {name: '及格', value: 0,rating:4,max:69,min:60,},
{name: '', value: 0,rating:5}, {name: '不及格', value: 0,rating:5,max:59,min:0,},
]); ]);
// //
@ -81,10 +81,13 @@ function initChart() {
} }
// //
const showEcharts =() => { const showEcharts =() => {
useOverview.tableList.forEach(item => { useOverview.tableList.forEach((item,index) => {
const index = dataList.value.findIndex(item1 => item1.rating === item.rating) if(item.rating === 0) return //
if(index !== -1) dataList.value.forEach((item1,index1) => {
dataList.value[index].value ++ if(item1.min <= Number(item.scoingRate) && Number(item.scoingRate) <= item1.max ){
item1.value ++
}
})
}) })
} }
watch(() => useOverview.tableList,() => { watch(() => useOverview.tableList,() => {

View File

@ -1,7 +1,7 @@
<template> <template>
<el-tabs :tab-position="tabPosition" style="height: 100%" class="demo-tabs" @tabChange="handelChange"> <el-tabs :tab-position="tabPosition" style="height: 100%" class="demo-tabs" @tabChange="handelChange">
<template v-for="(item,index) in leftList" :key="index"> <template v-for="(item,index) in leftList" :key="index">
<el-tab-pane :label="item.label" style="text-align:left"> <el-tab-pane :label="item.label" style="text-align:left" stretch="true">
<template v-if="item.stuList.length > 0"> <template v-if="item.stuList.length > 0">
<template v-for="(stuItem,stuIndex) in item.stuList" :key="stuIndex"> <template v-for="(stuItem,stuIndex) in item.stuList" :key="stuIndex">
<el-tag style="margin:5px 10px 0 0" type="primary">{{stuItem.studentname}}</el-tag> <el-tag style="margin:5px 10px 0 0" type="primary">{{stuItem.studentname}}</el-tag>
@ -23,29 +23,40 @@ const useOverview = overviewStore()
const tabPosition = ref('left') const tabPosition = ref('left')
const leftList = ref([ const leftList = ref([
{ {
label:'', label:'完美',
stuList:[], stuList:[],
rating:1 rating:1,
max:100,
min:100,
}, },
{ {
label:'优-', label:'优',
stuList:[], stuList:[],
rating:2 rating:2,
max:99,
min:80,
}, },
{ {
label:'良', label:'良',
stuList:[], stuList:[],
rating:3 rating:3,
max:79,
min:70,
}, },
{ {
label:'良-', label:'及格',
stuList:[], stuList:[],
rating:4 rating:4,
max:69,
min:60,
}, },
{ {
label:'', label:'不及格',
stuList:[], stuList:[],
rating:5 rating:5,
max:59,
min:0,
}, },
]) ])
// //
@ -54,9 +65,12 @@ const handelChange = (item) => {
} }
// //
const showStudents = (index) => { const showStudents = (index) => {
console.log(useOverview.tableList,'lef')
leftList.value[index].stuList = useOverview.tableList.filter(item => { leftList.value[index].stuList = useOverview.tableList.filter(item => {
if(item.rating == leftList.value[index].rating) return item if(item.rating > 0){
if(leftList.value[index].min <= Number(item.scoingRate || 0) && Number(item.scoingRate || 0) <= leftList.value[index].max ){
return item
}
}
}) })
} }
watch(() => useOverview.tableList,() => { watch(() => useOverview.tableList,() => {
@ -107,9 +121,9 @@ watch(() => useOverview.tableList,() => {
:deep(.el-tabs__item.is-active){ :deep(.el-tabs__item.is-active){
background-color: rgb(238, 241, 246); background-color: rgb(238, 241, 246);
} }
:deep(.el-tabs--left .el-tabs__item.is-left){ :deep(.el-tabs--left .el-tabs__item.is-left, .el-tabs--right .el-tabs__item.is-left){
text-align: left; text-align: left;
justify-content: flex-start; justify-content: flex-start !important;
} }
</style> </style>

View File

@ -24,9 +24,10 @@
<el-col :span="24"> <el-col :span="24">
<c-form v-bind="classForm"> <c-form v-bind="classForm">
<template #item_classid="{prop, form}"> <template #item_classid="{prop, form}">
<el-select v-model="form[prop]" placeholder="请选择班级"> <span v-if="dt.ctCourse">{{ dt.ctCourse?.caption }}</span>
<el-select v-else v-model="form[prop]" placeholder="请选择班级">
<el-option v-for="item in listData.classList" :value="item.id" <el-option v-for="item in listData.classList" :value="item.id"
:label="`${item.caption} (${item.classstudentcount}人)`" /> :label="`${item.caption} (${item.classstudentcount}人)`" />
</el-select> </el-select>
</template> </template>
</c-form> </c-form>
@ -118,7 +119,9 @@ const dt = reactive({ // 其他数据
isHistory: false, // - isHistory: false, // -
loading: false, // -loading loading: false, // -loading
loadingDel: false, // -loading loadingDel: false, // -loading
atClass: {}, //
atCourse: {}, // atCourse: {}, //
ctCourse: null, //
}) })
let chat = null // im-chat let chat = null // im-chat
@ -128,9 +131,10 @@ onMounted(() => {
}) })
/** /**
* @description 暴露方法-打开对话框 * @description 暴露方法-打开对话框
* @param row 课件对象 * @param id 课件id
* @param classObj 课程对象-用于继续上课
*/ */
const open = async (id) => { const open = async (id, classObj) => {
visible.value = true visible.value = true
if (id) { if (id) {
// //
@ -139,6 +143,11 @@ const open = async (id) => {
await getAptInfo(id) await getAptInfo(id)
// //
getClassList() getClassList()
//
if (!!classObj) {
dt.ctCourse = classObj
teacherForm.form.classcourseid = classObj.id
}
// im-chat // im-chat
nextTick(async() => { nextTick(async() => {
chat = await imChatRef.value?.initImChat() chat = await imChatRef.value?.initImChat()
@ -148,8 +157,9 @@ const open = async (id) => {
// //
const handleClose = async () => { const handleClose = async () => {
reset() // reset() //
await chat?.logout() // await chat?.logout()
chat = null // chat = null
dt.ctCourse = null
emit('close') emit('close')
} }
// - // -
@ -177,8 +187,10 @@ const reset = () => {
teacherForm.form = { classcourseid: 0 } teacherForm.form = { classcourseid: 0 }
dt.isCreate = false dt.isCreate = false
dt.isHistory = false dt.isHistory = false
dt.atClass = {}
dt.atCourse = {} dt.atCourse = {}
} }
// APT // APT
const getAptInfo = async (id) => { const getAptInfo = async (id) => {
const res = await Http_Entpcoursefile.getEntpcoursefile(id) const res = await Http_Entpcoursefile.getEntpcoursefile(id)
@ -338,9 +350,9 @@ const chatChange = (type, data, ...args) => {
// -id // -id
watch(() => classForm.form.classid, (val)=> { watch(() => classForm.form.classid, (val)=> {
// //
dt.atCourse = listData.classList.find(o => o.id === val) || {} dt.atClass = listData.classList.find(o => o.id === val) || {}
// - // -
listData.activeStudentList = dt.atCourse?.classstudentlist || [] // listData.activeStudentList = dt.atClass?.classstudentlist || []
// //
listData.classcourseList = [] listData.classcourseList = []
// , // ,

View File

@ -102,7 +102,7 @@ import { deleteSmarttalk, updateSmarttalk, getPrepareById } from '@/api/file'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import outLink from '@/utils/linkConfig' import outLink from '@/utils/linkConfig'
import { sessionStore } from '@/utils/store' import { sessionStore } from '@/utils/store'
import { listClasscourseNew } from '@/api/teaching/classcourse' import { listClasscourseNew, updateClasscourse } from '@/api/teaching/classcourse'
import { endClass, getSelfReserv } from '@/api/classManage' import { endClass, getSelfReserv } from '@/api/classManage'
import { listEntpcourse } from '@/api/teaching/classwork' import { listEntpcourse } from '@/api/teaching/classwork'
import { createWindow } from '@/utils/tool' import { createWindow } from '@/utils/tool'
@ -137,7 +137,7 @@ export default {
} }
}, },
expose: ['openFileWin'], expose: ['openFileWin'],
emits: { 'on-start-class': null, 'on-delete': null, 'on-set': null, 'on-delhomework': null,'on-filearg': null }, emits: { 'on-start-class': null, 'on-delete': null, 'on-set': null, 'on-delhomework': null,'on-filearg': null, 'change': null },
data() { data() {
return { return {
listenList: [], listenList: [],
@ -148,27 +148,24 @@ export default {
this.userInfo = useUserStore().user this.userInfo = useUserStore().user
}, },
methods: { methods: {
getOpenCourse() { //
return Promise.all([listClasscourseNew({teacherid: this.userInfo.userId,status:"open",evalid: this.curNode.id,pageSize:1000}), getSelfReserv({ex2:this.curNode.id})]).then(([res1,res2])=>{ getOpenCourse(isApt) {
let list2 = res1.rows || [] const curNodeId = this.curNode.id
let list = res2.data || [] if (isApt) { // APT
let one = list.find(item1 => { const params = {teacherid: this.userInfo.userId,status:"open",evalid: curNodeId,pageSize:1000}
if (item1.status === "上课中") { return listClasscourseNew(params).then(res => {
return true return (res.rows || [])
}
}) })
if (one) { } else { // PPT
return one return getSelfReserv({ex2: curNodeId}).then(res => {
} return (res.data || []).filter(o => o.status === "上课中")
if (list2.length>0) { })
one = list2[0] }
}
return one
})
}, },
clickStartClass(item) { clickStartClass(item) {
this.getOpenCourse().then(res=>{ const isApt = item.fileFlag === 'apt'
if(!res){ this.getOpenCourse(isApt).then(res => {
if(!res || res.length === 0){
this.$emit('on-start-class', item) this.$emit('on-start-class', item)
}else{ }else{
ElMessageBox.alert('<strong>上次课程尚未结束,是否继续上课?</strong>', '', { ElMessageBox.alert('<strong>上次课程尚未结束,是否继续上课?</strong>', '', {
@ -185,51 +182,80 @@ export default {
confirmButtonClass: "el-button--danger", confirmButtonClass: "el-button--danger",
center: true, center: true,
beforeClose: (action, instance, done) => { beforeClose: (action, instance, done) => {
const obj = res[0]
// console.log(action, obj, item)
if (action === 'confirm'){ if (action === 'confirm'){
// //
if (res.bookImg) { this.$emit('change', 'close', obj, { type: 1, instance, done })
//PPT // if (obj.bookImg) {
endClass(res.id).then((res1) => { // // //PPT
if (res1.data === true) { // // endClass(obj.id).then((res1) => {
ElMessage({ // // if (res1.data === true) {
message: '下课成功', // // ElMessage({
type: 'success' // // message: '',
}) // // type: 'success'
res.status = '已结束' // // })
done() // // obj.status = ''
} // // done()
}) // // }
}else { // // })
//APT // }else {
} // //APT -
// // this.$emit('change', 'close', obj, { type: 1, instance, done })
// // this.closeCourse(obj, instance, done)
// }
} }
if (action === 'cancel'){ if (action === 'cancel'){
// //
if (res.bookImg) { if (obj.bookImg) {
console.log('PPT')
//PPT //PPT
listEntpcourse({ listEntpcourse({
evalid: res.ex2, evalid: obj.ex2,
edituserid: useUserStore().user.userId, edituserid: useUserStore().user.userId,
pageSize: 500 pageSize: 500
}).then(async res1=>{ }).then(async res1=>{
if (res1.rows[0].id) { if (res1.rows[0].id) {
createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + res1.rows[0].id + "&reservId=" + res.id }) createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + res1.rows[0].id + "&reservId=" + obj.id })
done() done()
} }
}) })
}else { }else {
//APT //APT
this.$emit('on-start-class', item, obj)
done()
} }
} }
if (action === 'close') { if (action === 'close') {
done() done()
} }
}, },
}) }).catch(() => {})
} }
}) })
// this.$emit('on-start-class', item) // this.$emit('on-start-class', item)
}, },
// ()
// async closeCourse(row, instance, done) {
// instance.confirmButtonLoading = true
// instance.confirmButtonText = '...'
// // -
// if (!!row.timgroupid) {
// const msg = { msgKey: 'closed', actor: 'teacher', classcourseid: row.id }
// Chat.sendMsg(row.timgroupid, msg)
// }
// // -
// const params = { id: row.id, status: 'closed', timgroupid: '' }
// await updateClasscourse(params)
// //
// setTimeout(async() => {
// if (!!row.timgroupid) await Chat.dismissGroup(row.timgroupid)
// instance.confirmButtonLoading = false
// instance.confirmButtonText = ''
// done()
// ElMessage({ type: 'success', message: `` })
// }, 1000)
// },
editTalk(item) { editTalk(item) {
ElMessageBox.prompt('请输入新的标签', '添加标签', { ElMessageBox.prompt('请输入新的标签', '添加标签', {
confirmButtonText: '确认', confirmButtonText: '确认',

View File

@ -24,12 +24,14 @@
:curNode="currentNode" :curNode="currentNode"
@on-delete="deleteTalk" @on-delete="deleteTalk"
@on-start-class="startClass" @on-start-class="startClass"
@change="changeClass"
> >
</kj-list-item> </kj-list-item>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="教学实录" name="教学实录" class="prepare-center-jxsl"> <el-tab-pane label="教学实录" name="教学实录" class="prepare-center-jxsl">
<class-reserv v-if="activeAptTab==='教学实录'" :curNode="currentNode"></class-reserv> <class-reserv v-if="activeAptTab==='教学实录'" :curNode="currentNode"
@change="changeClass"></class-reserv>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -155,16 +157,21 @@ import { parseCataByNode, creatPPT, asyncLocalFile } from '@/utils/talkFile'
import FileOperBatch from '@/views/prepare/container/file-oper-batch.vue' import FileOperBatch from '@/views/prepare/container/file-oper-batch.vue'
import SetHomework from '@/components/set-homework/index.vue' import SetHomework from '@/components/set-homework/index.vue'
import outLink from '@/utils/linkConfig' import outLink from '@/utils/linkConfig'
import { createWindow, sessionStore, getAppInstallUrl } from '@/utils/tool' import { createWindow, sessionStore, getAppInstallUrl, ipcMsgSend } from '@/utils/tool'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import { delClasswork, listEntpcourse } from '@/api/teaching/classwork' import { delClasswork, listEntpcourse } from '@/api/teaching/classwork'
import { getClassInfo, getSelfReserv } from '@/api/classManage' import { updateClasscourse } from '@/api/teaching/classcourse'
import { getClassInfo, getSelfReserv, endClass } from '@/api/classManage'
import { useGetHomework } from '@/hooks/useGetHomework' import { useGetHomework } from '@/hooks/useGetHomework'
import { addEntpcoursefileReturnId } from '@/api/education/entpcoursefile' import { addEntpcoursefileReturnId } from '@/api/education/entpcoursefile'
import ClassReserv from '@/views/classManage/classReserv.vue' import ClassReserv from '@/views/classManage/classReserv.vue'
import classStart from './container/class-start.vue' // import classStart from './container/class-start.vue' //
const toolStore = useToolState() import MsgEnum from '@/plugins/imChat/msgEnum' // im
import Chat from '@/utils/chat' // im
import msgEnum from '@/plugins/imChat/msgEnum'
if (!Chat.imChat) Chat.init()
const toolStore = useToolState()
const fs = require('fs') const fs = require('fs')
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
@ -272,7 +279,8 @@ export default {
// } // }
// }, // },
methods: { methods: {
startClass(item) { //
startClass(item, classObj) {
// () // ()
const id = sessionStore.has('activeClass.id') ? sessionStore.get('activeClass.id') : null const id = sessionStore.has('activeClass.id') ? sessionStore.get('activeClass.id') : null
if (id && id == item.id) return ElMessage.warning('当前正在上课,请勿重复操作') if (id && id == item.id) return ElMessage.warning('当前正在上课,请勿重复操作')
@ -283,11 +291,68 @@ export default {
this.openReserv() this.openReserv()
} }
if(item.fileFlag === 'apt') { if(item.fileFlag === 'apt') {
this.$refs.calssRef.open(item.fileId) this.$refs.calssRef.open(item.fileId, classObj)
}
},
// -apt
async changeClass(type, row, other) {
switch(type) {
case 'continue': { //
const aptFileId = row.entpcoursefileid
this.$refs.calssRef.open(aptFileId, row)
break
}
case 'close': { //
const head = MsgEnum.HEADS.MSG_closed // closed
const msgT = msgEnum.TYPES.TEACHER // teacher
const isApt = !row.bookImg // bookImg ppt Apt
row.ex3 == 'undefined' && (row.ex3 = null)
const timgroupid = isApt ? row.timgroupid : row.ex3 // ex3 ppt Apt
if (other.type == 1) { // -
other.instance.confirmButtonLoading = true
other.instance.confirmButtonText = '下课中...'
} else { // -
other.loading.value = true
}
// -
if (!!timgroupid) {
const msg = { msgKey: head, actor: msgT, classcourseid: row.id }
Chat.sendMsg(timgroupid, msg)
}
if (isApt) { // Apt
// -
await updateClasscourse({ id: row.id, status: head, timgroupid: '' })
} else { // PPT
const toolStore = useToolState()
//
if (toolStore.isToolWin) {
toolStore.resetDef() //
ipcMsgSend('tool-sphere:close') //
}
// -
await endClass(row.id)
}
//
setTimeout(async() => {
if (!!timgroupid) await Chat.dismissGroup(timgroupid)
if (other.type == 1) { // -
other.instance.confirmButtonLoading = false
other.instance.confirmButtonText = '下课'
other.done()
} else {
other.loading.value = false
row.status = isApt ? head : '已结束'
}
ElMessage({ type: 'success', message: `下课成功!` })
}, 1000)
break
}
default:
break
} }
}, },
closeChange() { // - closeChange() { // -
console.log('关闭上课弹窗') // console.log('')
// this.activeClass = null // this.activeClass = null
sessionStore.delete('activeClass') sessionStore.delete('activeClass')
}, },

View File

@ -239,7 +239,7 @@ const sideChange = async o => {
// 2 // 2
setTimeout(async() => { setTimeout(async() => {
await imChatRef.value?.deleteGroup() // await imChatRef.value?.deleteGroup() //
await imChatRef.value?.logout() // 退im // await imChatRef.value?.logout() // 退im
elMsg.close() elMsg.close()
ipcMsgSend('tool-sphere:close') // ipcMsgSend('tool-sphere:close') //
}, 500); }, 500);