Merge branch 'main' into lyc-dev
This commit is contained in:
commit
d534340f88
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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个参数且为函数,则默认为callback,isInit和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()
|
|
@ -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('进行中')
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
||||||
import { listByDeadDate, listClassworkdata, listClassworkdataNew } from '@/api/classTask'
|
import { listByDeadDate, listClassworkdata, listClassworkdataNew } from '@/api/classTask'
|
||||||
|
|
||||||
import TaskItem from '@/views/classTask/container/task-item.vue'
|
import TaskItem from '@/views/classTask/container/classTask/task-item.vue'
|
||||||
// import ItemDialog from '@/views/classTask/container/item-dialog.vue'
|
// import ItemDialog from '@/views/classTask/container/item-dialog.vue'
|
||||||
import { useToolState } from '@/store/modules/tool'
|
import { useToolState } from '@/store/modules/tool'
|
||||||
import { getCurrentTime, getTomorrow } from '@/utils/date'
|
import { getCurrentTime, getTomorrow } from '@/utils/date'
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 作业内容编辑 -->
|
<!-- 作业内容详情 -->
|
||||||
<el-dialog v-model="workEdit" title="作业内容详情" width="90%" append-to-body>
|
<el-dialog v-model="workEdit" title="作业内容详情" width="90%" append-to-body>
|
||||||
<!-- 课标研读 目标设定 教材研读 框架梳理 学科定位 -->
|
<!-- 课标研读 目标设定 教材研读 框架梳理 学科定位 -->
|
||||||
<div v-if="currentTag=='习题训练'" :style="{'padding': '15px', 'overflow': 'auto'}">
|
<div v-if="currentTag=='习题训练'" :style="{'padding': '15px', 'overflow': 'auto'}">
|
||||||
|
@ -125,30 +125,73 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 框架梳理 -->
|
||||||
<div v-if="currentTag=='框架梳理'" :style="{'padding': '15px', 'overflow': 'auto'}">
|
<div v-if="currentTag=='框架梳理'" :style="{'padding': '15px', 'overflow': 'auto'}">
|
||||||
<div style="margin: 5px; background-color: white">
|
<div style="margin: 5px; background-color: white">
|
||||||
|
<template v-for="(_item,index) in workConfObj.chooseWorkLists" :key="index">
|
||||||
<template v-for="(item) in workConfObj.chooseWorkLists" :key="item.id">
|
<div v-if="_item.worktype=='框架梳理'">
|
||||||
<div v-if="item.worktype==workConfObj.worktype">
|
<div style="color: silver; display: flex;align-items: center;">
|
||||||
<div class="choose-work">
|
<div style="flex: 1;">{{ _item.worktype }}</div>
|
||||||
<div class="choose-work-title">{{ item.worktype }}</div>
|
<div style="flex: 1;">分值:{{ _item.score }}</div>
|
||||||
<div class="choose-work-content">
|
|
||||||
<div style="color: silver; display: flex;align-items: center;flex: 1;">
|
|
||||||
<el-form-item label="分值">
|
|
||||||
<el-input-number v-model="item.score" :min="1" :max="100" size="small"></el-input-number >
|
|
||||||
</el-form-item>
|
|
||||||
<div style="display: flex;align-items: center;flex: 1;justify-content: flex-end;">
|
<div style="display: flex;align-items: center;flex: 1;justify-content: flex-end;">
|
||||||
<el-button @click="prevRead(item)">预览</el-button>
|
<el-button @click="prevRead(_item)">预览</el-button>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO 课堂展示 、常规作业 预览待开发-->
|
||||||
|
<!-- 常规作业:包含多个格式(图片略缩图展示,点击放大;其他附件跳转另外弹窗查看) -->
|
||||||
|
<div v-if="currentTag=='常规作业'" :style="{'padding': '15px', 'overflow': 'auto'}">
|
||||||
|
<div style="margin: 5px; background-color: white">
|
||||||
|
<div v-if="workConfObj.teacherFeedContentList.length > 0">
|
||||||
|
<div class="image_list">
|
||||||
|
<div v-if="workConfObj.teachImageList.length > 0">
|
||||||
|
<div style="margin-bottom: 5px;text-align: left;">
|
||||||
|
<span style="color: red">温馨提示:点击图片可放大预览 </span>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; flex-wrap: nowrap; flex-direction: row;">
|
||||||
|
<div v-for="(imageItem, index) in workConfObj.teachImageList" :key="index" style="margin: 0 15px;">
|
||||||
|
<el-image
|
||||||
|
style="width: 100px; height: 100px"
|
||||||
|
:src="imageItem.url"
|
||||||
|
:zoom-rate="1.2"
|
||||||
|
:max-scale="7"
|
||||||
|
:min-scale="0.2"
|
||||||
|
:preview-src-list="
|
||||||
|
workConfObj.teachImageList
|
||||||
|
.filter(
|
||||||
|
(item) =>
|
||||||
|
item.name.indexOf('jpg') > -1 ||
|
||||||
|
item.name.indexOf('jpeg') > -1 ||
|
||||||
|
item.name.indexOf('png') > -1
|
||||||
|
)
|
||||||
|
.map((item) => item.url)
|
||||||
|
"
|
||||||
|
:initial-index="4"
|
||||||
|
fit="contain"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 其他类型附件 -->
|
||||||
|
<div v-if="workConfObj.teachFileList.length > 0">
|
||||||
|
<div style="margin: 10px 0;text-align: left; margin: auto 0; cursor: pointer;">
|
||||||
|
<span style="color: #409eff" @click="openFile">预览其他类型附件!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div v-if="workConfObj.teachFileList.length > 0">
|
||||||
|
<div style="margin: 10px 0;text-align: left; margin: auto 0; cursor: pointer;">
|
||||||
|
<span style="color: #409eff" @click="openFile">预览其他类型附件!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,6 +293,12 @@
|
||||||
<el-button type="primary" @click="handleTaskAssignToAllClassType()" >{{'推送'}}</el-button>
|
<el-button type="primary" @click="handleTaskAssignToAllClassType()" >{{'推送'}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 预览框 -->
|
||||||
|
<prevReadMsgDialog ref="prevReadMsgDialogRef" :bookobj="courseObj"/>
|
||||||
|
<!-- 其他附件预览框 acceptParams-->
|
||||||
|
<prevReadImgFileDialog ref="prevReadImgFileDialogRef"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -268,6 +317,9 @@ import { useGetHomework } from '@/hooks/useGetHomework'
|
||||||
import { processList } from '@/hooks/useProcessList'
|
import { processList } from '@/hooks/useProcessList'
|
||||||
import { uniqBy, groupBy } from 'lodash'
|
import { uniqBy, groupBy } from 'lodash'
|
||||||
import { getCurrentTime } from '@/utils/date'
|
import { getCurrentTime } from '@/utils/date'
|
||||||
|
import prevReadMsgDialog from '@/views/classTask/container/newTask/prevReadMsg-Dialog.vue'
|
||||||
|
import prevReadImgFileDialog from '@/views/classTask/container/classTask/prevReadImgFileDialog.vue'
|
||||||
|
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
const userStore = useUserStore().user
|
const userStore = useUserStore().user
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
@ -284,7 +336,8 @@ const props = defineProps({
|
||||||
// ---------------------------------------------------
|
// ---------------------------------------------------
|
||||||
|
|
||||||
const isCollapse = ref(false)
|
const isCollapse = ref(false)
|
||||||
|
const prevReadMsgDialogRef = ref(null);// 预览框ref
|
||||||
|
const prevReadImgFileDialogRef = ref(null);// 其他附件类型预览框ref
|
||||||
|
|
||||||
const courseObj = reactive({
|
const courseObj = reactive({
|
||||||
// 课程相关参数: 教材id,单元id,章节id,课程名称
|
// 课程相关参数: 教材id,单元id,章节id,课程名称
|
||||||
|
@ -308,9 +361,13 @@ const currentWorkEdit = reactive({
|
||||||
currentIndex: 0,
|
currentIndex: 0,
|
||||||
})// 当前作业编辑
|
})// 当前作业编辑
|
||||||
const currentTag = ref('');// 当前作业类型
|
const currentTag = ref('');// 当前作业类型
|
||||||
|
// 作业列表-详情展示内容
|
||||||
const workConfObj = reactive({
|
const workConfObj = reactive({
|
||||||
quizlist: [], // 习题list
|
quizlist: [], // 习题list
|
||||||
|
chooseWorkLists: [], // 框架梳理
|
||||||
|
teacherFeedContentList: [],//常规作业
|
||||||
|
teachFileList: [], // 常规作业文件list
|
||||||
|
teachImageList: [],// 常规作业图片list
|
||||||
});
|
});
|
||||||
|
|
||||||
// 推送相关
|
// 推送相关
|
||||||
|
@ -391,6 +448,10 @@ const getTaskList = async () => {
|
||||||
let model = [];
|
let model = [];
|
||||||
let mission = [];
|
let mission = [];
|
||||||
|
|
||||||
|
if(res.rows&&res.rows.length > 0){
|
||||||
|
// 根据创建时间 倒序排列一下
|
||||||
|
res.rows.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
|
||||||
|
}
|
||||||
for (let item of res.rows){
|
for (let item of res.rows){
|
||||||
item.taskconfig = [];
|
item.taskconfig = [];
|
||||||
|
|
||||||
|
@ -473,6 +534,7 @@ const getTaskList = async () => {
|
||||||
}
|
}
|
||||||
list.push(item);
|
list.push(item);
|
||||||
}
|
}
|
||||||
|
// 根据 父项、子项 创建时间倒序排列一下
|
||||||
taskList.value = list;
|
taskList.value = list;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
})
|
})
|
||||||
|
@ -512,24 +574,27 @@ let classtaskObj = reactive({
|
||||||
// this.attainmentList = row.workcodesList?.attlist;
|
// this.attainmentList = row.workcodesList?.attlist;
|
||||||
// this.courseQualityList = row.workcodesList?.qualist;
|
// this.courseQualityList = row.workcodesList?.qualist;
|
||||||
if (row.worktype == '框架梳理') {
|
if (row.worktype == '框架梳理') {
|
||||||
this.$nextTick(()=>{
|
//包含 entpcourseworklistarray 内容
|
||||||
this.getFlowData()
|
var listCourseWork = [];
|
||||||
|
for (var i=0; i < row.entpcourseworklistarray.length; i++) {
|
||||||
|
listCourseWork.push(row.entpcourseworklistarray[i]);
|
||||||
|
}
|
||||||
|
nextTick(()=>{
|
||||||
|
// 框架梳理对应只有一个内容 默认读取第一个id即可
|
||||||
|
getEvaluationclue(listCourseWork[0].id).then(res => {
|
||||||
|
if ( res.data==null || res.data==undefined ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.data.worktype = '框架梳理';
|
||||||
|
res.data.score = listCourseWork[0].score;
|
||||||
|
|
||||||
|
console.log('框架梳理的列表', res.data);
|
||||||
|
// 预览list赋值
|
||||||
|
workConfObj.chooseWorkLists = [res.data];
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// if (row.worktype == '学科定位') {
|
|
||||||
// // TODO 后续需要再迁
|
|
||||||
// rootid:entpcoursework里的id rootid: row.entpcourseworklistarray[0].id,
|
|
||||||
// listEvaluationclue({ cluegroup: 'graph', edusubject: this.courseObj.edusubject, pageSize: 1000 }).then((res) => {
|
|
||||||
// var glist = [];
|
|
||||||
// for (var i = 0; i < res.rows.length; i++) {
|
|
||||||
// glist.push(res.rows[i]);
|
|
||||||
// }
|
|
||||||
// this.isEditable = false;
|
|
||||||
// this.preKnowList = glist;
|
|
||||||
// this.$refs.jsMind.updateFromParent(this.preKnowList, this.courseObj.edusubject);
|
|
||||||
// this.$refs.jsMind.initJsMindMap();
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 课标研读 目标设定 教材研读 框架梳理 学科定位
|
// // 课标研读 目标设定 教材研读 框架梳理 学科定位
|
||||||
if (row.worktype == '习题训练') {
|
if (row.worktype == '习题训练') {
|
||||||
|
@ -567,20 +632,23 @@ let classtaskObj = reactive({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 常规作业、课堂展示
|
//TODO 待完善 课堂展示
|
||||||
if(row.worktype == '常规作业' || row.worktype == '课堂展示'){
|
if(row.worktype == '常规作业'){
|
||||||
console.log(row,'常规作业-课堂展示');
|
console.log(row,'常规作业');
|
||||||
// 老师布置的附件 workcodes ?? 与批改哪里这个字段值不一样
|
workConfObj.teacherFeedContentList = [];
|
||||||
|
workConfObj.teachImageList = [];
|
||||||
|
workConfObj.teachFileList = [];
|
||||||
|
|
||||||
if(row.workcodes != ''){
|
if(row.workcodes != ''){
|
||||||
const teachWorkFileList = JSON.parse(row.workcodes);
|
const teachWorkFileList = JSON.parse(row.workcodes);
|
||||||
teachWorkFileList&&teachWorkFileList.forEach(item => {
|
teachWorkFileList&&teachWorkFileList.forEach(item => {
|
||||||
if(item.name.indexOf('jpg') > -1 || item.name.indexOf('jpeg') > -1 || item.name.indexOf('png') > -1){
|
if(item.name.indexOf('jpg') > -1 || item.name.indexOf('jpeg') > -1 || item.name.indexOf('png') > -1){
|
||||||
this.teachImageList.push(item);
|
workConfObj.teachImageList.push(item);
|
||||||
}else{
|
}else{
|
||||||
this.teachFileList.push(item);
|
workConfObj.teachFileList.push(item);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.teacherFeedContentList.push(teachWorkFileList);
|
workConfObj.teacherFeedContentList.push(teachWorkFileList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -592,12 +660,10 @@ const newHandleWorkEdit2ClassWorkQuizAdd = async (row, index) =>{
|
||||||
listCourseWork.push(row.entpcourseworklistarray[i]);
|
listCourseWork.push(row.entpcourseworklistarray[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (listCourseWork.length > 0) {
|
if (listCourseWork.length > 0) {
|
||||||
classtaskObj.id= row.id; //
|
classtaskObj.id= row.id; //
|
||||||
classtaskObj.bookObj = courseObj; // 教材对象
|
classtaskObj.bookObj = courseObj; // 教材对象
|
||||||
classtaskObj.bookName = row.evaltitle? row.evalparenttitle+'/'+row.evaltitle: row.evalparenttitle// 课程名称:单元/章节: 单元
|
classtaskObj.bookName = row.evaltitle? row.evalparenttitle? row.evalparenttitle+'/'+row.evaltitle : row.evaltitle: row.evalparenttitle// 课程名称:单元/章节: 单元
|
||||||
classtaskObj.uniquekey= row.uniquekey; // 设计中的标题
|
classtaskObj.uniquekey= row.uniquekey; // 设计中的标题
|
||||||
classtaskObj.title= row.title; // 设计中的说明
|
classtaskObj.title= row.title; // 设计中的说明
|
||||||
classtaskObj.worktype= row.worktype; // 设计中的作业类型
|
classtaskObj.worktype= row.worktype; // 设计中的作业类型
|
||||||
|
@ -1062,6 +1128,24 @@ const handleNewClassWorkDialog = () => {
|
||||||
router.push({ path: '/newClassTask' });
|
router.push({ path: '/newClassTask' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预览框
|
||||||
|
*/
|
||||||
|
const prevRead = (item) => {
|
||||||
|
proxy.$refs.prevReadMsgDialogRef.openDialog(item);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 常规作业:其他附件预览
|
||||||
|
*/
|
||||||
|
const openFile = () => {
|
||||||
|
const obj = {
|
||||||
|
teacherFeedContentList: workConfObj.teacherFeedContentList,//常规作业
|
||||||
|
teachFileList: workConfObj.teachFileList, // 常规作业文件list
|
||||||
|
teachImageList: workConfObj.teachImageList,// 常规作业图片list
|
||||||
|
}
|
||||||
|
proxy.$refs.prevReadImgFileDialogRef.acceptParams(obj);
|
||||||
|
}
|
||||||
|
|
||||||
// 作业说明编辑-确认
|
// 作业说明编辑-确认
|
||||||
const submitWorkTitle = () => {
|
const submitWorkTitle = () => {
|
||||||
if(currentWorkEdit.currentTask.title == currentWorkEdit.currentTitle){
|
if(currentWorkEdit.currentTask.title == currentWorkEdit.currentTitle){
|
||||||
|
|
|
@ -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,() => {
|
||||||
|
|
|
@ -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>
|
|
@ -196,7 +196,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="teachFileList.length > 0">
|
<div v-if="teachFileList.length > 0">
|
||||||
<div style="margin: 10px 0;text-align: left;">
|
<div style="margin: 10px 0;text-align: left; cursor: pointer;">
|
||||||
<span style="color: red" @click="openFile"
|
<span style="color: red" @click="openFile"
|
||||||
>温馨提示:点击此处 可预览其他类型附件!
|
>温馨提示:点击此处 可预览其他类型附件!
|
||||||
</span>
|
</span>
|
||||||
|
@ -245,7 +245,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="fileList.length > 0">
|
<div v-if="fileList.length > 0">
|
||||||
<div style="margin: 10px 0;text-align: left;">
|
<div style="margin: 10px 0;text-align: left; cursor: pointer;">
|
||||||
<span style="color: red" @click="openFile"
|
<span style="color: red" @click="openFile"
|
||||||
>温馨提示:点击此处 可预览其他类型附件!
|
>温馨提示:点击此处 可预览其他类型附件!
|
||||||
</span>
|
</span>
|
|
@ -0,0 +1,179 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="fileReadopen"
|
||||||
|
title="文件预览"
|
||||||
|
width="80%"
|
||||||
|
:style="{ height: '72vh' }"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<div class="file-read-dialog">
|
||||||
|
<div>
|
||||||
|
<!-- 老师附件 -->
|
||||||
|
<div v-if="teachFileList.length > 0">
|
||||||
|
<el-card style="max-width: 480px">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>文件列表</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
v-for="item in teachFileList"
|
||||||
|
:key="item"
|
||||||
|
style="margin: 10px; display: flex; align-items: center"
|
||||||
|
>
|
||||||
|
<span style="margin-right: 10px">{{ item.name }}</span>
|
||||||
|
<el-button type="primary" @click="onFileRead(item)">预览</el-button>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 100%" :style="{ height: '72vh' }">
|
||||||
|
<div style="margin-left: 10px">
|
||||||
|
预览展示区域<span style="color: red; margin-left: 10px">
|
||||||
|
温馨提示:若预览失败,<span style="margin-left: 10px">{{ props.name }}</span
|
||||||
|
>可点击此处<a
|
||||||
|
:href="fileitem.url ? fileitem.url : ''"
|
||||||
|
target="_blank"
|
||||||
|
style="color: blue"
|
||||||
|
>下载!</a
|
||||||
|
></span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<ReFilePreview
|
||||||
|
:name="fileitem.name"
|
||||||
|
:type="fileitem.type"
|
||||||
|
:file-type="fileitem.type"
|
||||||
|
:file-path="fileitem.url"
|
||||||
|
:text-content="textContent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="prevReadImgFileDialogRef">
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import ReFilePreview from '@/components/refile-preview/index.vue'
|
||||||
|
|
||||||
|
const props = defineProps({})
|
||||||
|
|
||||||
|
const fileReadopen = ref(false)
|
||||||
|
|
||||||
|
// 老师常规作业、课堂展示布置题目附件list
|
||||||
|
const teacherFeedContentList = ref([])
|
||||||
|
const teachImageList = ref([])
|
||||||
|
const teachFileList = ref([])
|
||||||
|
|
||||||
|
|
||||||
|
// 确定的线上图片数据
|
||||||
|
//#region 文件内容相关
|
||||||
|
const fileitem = reactive({
|
||||||
|
name: '',
|
||||||
|
type: '',
|
||||||
|
url: ''
|
||||||
|
})
|
||||||
|
// 文件预览
|
||||||
|
const onFileRead = (file) => {
|
||||||
|
textContent.value = '1'
|
||||||
|
//
|
||||||
|
fileitem.type = file.name.split('.').pop().toLowerCase()
|
||||||
|
fileitem.url = file.url
|
||||||
|
fileitem.name = file.name
|
||||||
|
|
||||||
|
// txt 读取
|
||||||
|
if (fileitem.type == 'txt') {
|
||||||
|
loadFileTextContent(fileitem.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// txt文件读取
|
||||||
|
const textContent = ref('')
|
||||||
|
const loadFileTextContent = async (url) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
textContent.value = '文件读取失败,您可以点击上方链接跳到另外页面查看'
|
||||||
|
throw new Error('文件读取失败')
|
||||||
|
}
|
||||||
|
textContent.value = await response.text()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('读取文件时出错:', error)
|
||||||
|
textContent.value = '文件读取失败,您可以点击上方链接跳到另外页面查看'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 接收父组件传过来的参数
|
||||||
|
const acceptParams = (params) => {
|
||||||
|
console.log(params)
|
||||||
|
fileReadopen.value = true;
|
||||||
|
teacherFeedContentList.value = params.teacherFeedContentList
|
||||||
|
teachImageList.value = params.teachImageList
|
||||||
|
teachFileList.value = params.teachFileList
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 初始化请求
|
||||||
|
// onMounted(() => {})
|
||||||
|
|
||||||
|
// 暴露给父组件的参数和方法(外部需要什么,都可以从这里暴露出去)
|
||||||
|
defineExpose({
|
||||||
|
acceptParams
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
|
||||||
|
.card-header{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image_list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.file-read-dialog {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
/* margin-bottom: 20px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.score-circle {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: pink;
|
||||||
|
color: red;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 13px;
|
||||||
|
margin: 0 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score-circle.active {
|
||||||
|
background-color: red;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header{
|
||||||
|
align-items: left;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -167,7 +167,7 @@ import useUserStore from '@/store/modules/user'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { getCurrentTime, getAfterMinutes } from '@/utils/date'
|
import { getCurrentTime, getAfterMinutes } from '@/utils/date'
|
||||||
import { processList } from '@/hooks/useProcessList'
|
import { processList } from '@/hooks/useProcessList'
|
||||||
import ItemDialogScore from '@/views/classTask/container/item-dialog-score.vue'
|
import ItemDialogScore from '@/views/classTask/container/classTask/item-dialog-score.vue'
|
||||||
// zdg: 组件导入
|
// zdg: 组件导入
|
||||||
import quizStats from '@/views/classTask/container/quizStats.vue'
|
import quizStats from '@/views/classTask/container/quizStats.vue'
|
||||||
import ClassOverview from '@/views/classTask/container/classOverview.vue'
|
import ClassOverview from '@/views/classTask/container/classOverview.vue'
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
<template>
|
||||||
|
<!-- 预览框 -->
|
||||||
|
<el-dialog v-if="prevReadMsg.visible" v-model="prevReadMsg.visible" class="prev-read-zy-wrap" width="90%" style="height: 80vh" append-to-body>
|
||||||
|
<!-- <div v-if="prevReadMsg.type=='课标研读'" style="height: 100%;">
|
||||||
|
<standard book-type="课标研读" :show-cata="true" :show-tools="false" :course-obj="courseObj" :bookdatahtml="versionObj.bookdata" :teachResObj="activeTeachResOfStandard"></standard>
|
||||||
|
</div>
|
||||||
|
<div v-if="prevReadMsg.type=='目标设定'" style="height: 100%;display: flex;">
|
||||||
|
<degreeevolution :courseObj="courseObj" :show-class="true" :teachResObj="activeTeachResOfStandard" :attainmentList="attainmentList" :courseQualityList="courseQualityList"/>
|
||||||
|
</div>
|
||||||
|
<div v-if="prevReadMsg.type=='教材研读'" style="height: 100%;">
|
||||||
|
<standard book-type="教材研读" :course-obj="courseObj" :show-tools="false" :bookdatahtml="versionObj.bookdata" :teachResObj="activeTeachResOfStandard"></standard>
|
||||||
|
</div> -->
|
||||||
|
<div v-if="prevReadMsg.type=='框架梳理'" style="height: 100%;">
|
||||||
|
<FlowChart ref="flowref" :flowHeight="mainHeight" :dataSource="flowData"/>
|
||||||
|
</div>
|
||||||
|
<!-- <div v-if="prevReadMsg.type=='学科定位'" style="height: 100%;">
|
||||||
|
<teachJsMind :course-obj="courseObj" :teachResObj="activeTeachResOfStandard"></teachJsMind>
|
||||||
|
</div> -->
|
||||||
|
<!-- <div v-if="prevReadMsg.type=='习题训练'">习题训练</div> -->
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="prevReadMsgDialogRef">
|
||||||
|
import { onMounted, ref, watch, reactive, getCurrentInstance } from 'vue'
|
||||||
|
|
||||||
|
import { listEntpcoursefile } from '@/api/education/entpcoursefile'
|
||||||
|
import { useGetHomework } from '@/hooks/useGetHomework'
|
||||||
|
import FlowChart from "@/components/Flowchart/index.vue";
|
||||||
|
|
||||||
|
// import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
|
||||||
|
// import { addClassworkReturnId } from '@/api/teaching/classwork'
|
||||||
|
// import { updateClasswork, listEvaluationclue,readFile, listClassworkeval,delClassworkeval,addClassworkeval,updateClassworkeval } from '@/api/classTask'
|
||||||
|
// import { listEvaluation } from '@/api/subject'
|
||||||
|
|
||||||
|
// import { listKnowledgePoint } from "@/api/knowledge/knowledgePoint";
|
||||||
|
|
||||||
|
|
||||||
|
import FileUpload from "@/components/FileUpload/index.vue";
|
||||||
|
import whiteboard from '@/components/whiteboard/whiteboard.vue'
|
||||||
|
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
const userStore = useUserStore().user
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
bookobj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const mainHeight = ref(document.documentElement.clientHeight - 110)
|
||||||
|
|
||||||
|
// 预览
|
||||||
|
const prevReadMsg = reactive({
|
||||||
|
visible: false,
|
||||||
|
type: ""
|
||||||
|
});// 预览msg
|
||||||
|
// 框架梳理----------
|
||||||
|
const flowData = ref({})// 框架梳理
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 1、打开弹窗: 预览资源
|
||||||
|
const openDialog = async (item) => {
|
||||||
|
prevReadMsg.visible = true;
|
||||||
|
prevReadMsg.type = item.worktype;
|
||||||
|
// // if (item.worktype==='课标研读'){
|
||||||
|
// // //获取教材文件和批注信息
|
||||||
|
// // listEvaluation({itemkey: 'subject', edusubject: userStore.edusubject, edustage: userStore.edustage}).then(res => {
|
||||||
|
// // // TODO 课标研读-还未接入
|
||||||
|
// // console.log("课标研读-还未接入",res);
|
||||||
|
// // // this.versionObj = res.rows[0];
|
||||||
|
// // // // 读取出课标文件的每一行
|
||||||
|
// // // if (this.versionObj.fileurl.length > 0) {
|
||||||
|
// // // readFile({cluelink: this.versionObj.fileurl}).then(fileres => {
|
||||||
|
// // // this.versionObj.bookdata = fileres;
|
||||||
|
// // // this.activeTeachResOfStandard = item;
|
||||||
|
// // // })
|
||||||
|
// // // }
|
||||||
|
// // })
|
||||||
|
// // }
|
||||||
|
// // if (item.worktype==='目标设定'){
|
||||||
|
// // // TODO 目标设定-还未接入
|
||||||
|
// // // this.activeTeachResOfStandard = item;
|
||||||
|
// // }
|
||||||
|
// if (item.worktype==='教材研读'){
|
||||||
|
// // TODO 教材研读-还未接入
|
||||||
|
// // getEvaluation(this.courseObj.evalrootid).then(bookres => {
|
||||||
|
// // this.versionObj = bookres.data;
|
||||||
|
// // if (this.versionObj.fileurl.length > 0) {
|
||||||
|
// // readFile({cluelink: this.versionObj.fileurl}).then(fileres => {
|
||||||
|
// // this.versionObj.bookdata = fileres;
|
||||||
|
// // this.activeTeachResOfStandard = item;
|
||||||
|
// // })
|
||||||
|
// // }
|
||||||
|
// // })
|
||||||
|
// }
|
||||||
|
if (item.worktype==='框架梳理'){
|
||||||
|
flowData.value = {};
|
||||||
|
const { chapterId } = await useGetHomework(props.bookobj.node)
|
||||||
|
// this.entpcourseid = chapterId
|
||||||
|
let queryParams = {
|
||||||
|
entpcourseid: chapterId,
|
||||||
|
ppttype: '教材分析',
|
||||||
|
parentid: item.id,
|
||||||
|
title: '逻辑框架建构',
|
||||||
|
filetype: 'draw'
|
||||||
|
}
|
||||||
|
listEntpcoursefile(queryParams).then(response=>{
|
||||||
|
if (response.rows.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flowData.value = JSON.parse(response.rows[0].datacontent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// if (item.worktype==='学科定位'){
|
||||||
|
// // TODO 学科定位-还未接入
|
||||||
|
// // this.activeTeachResOfStandard = item;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
watch(() => props.bookobj.levelSecondId, (newVal) => {
|
||||||
|
console.log(props.bookobj,'课程选择')
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openDialog,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.prev-read-zy-wrap .el-dialog__header{
|
||||||
|
padding: 0!important;
|
||||||
|
}
|
||||||
|
.prev-read-zy-wrap .el-dialog__header button{
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.prev-read-zy-wrap .el-dialog__body{
|
||||||
|
padding: 0!important;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -223,24 +223,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 预览框 -->
|
<!-- 预览框 -->
|
||||||
<el-dialog v-if="prevReadMsg.visible" v-model="prevReadMsg.visible" class="prev-read-zy-wrap" width="90%" style="height: 80vh" append-to-body>
|
<prevReadMsgDialog ref="prevReadMsgDialogRef" :bookobj="props.bookobj"/>
|
||||||
<!-- <div v-if="prevReadMsg.type=='课标研读'" style="height: 100%;">
|
|
||||||
<standard book-type="课标研读" :show-cata="true" :show-tools="false" :course-obj="courseObj" :bookdatahtml="versionObj.bookdata" :teachResObj="activeTeachResOfStandard"></standard>
|
|
||||||
</div>
|
|
||||||
<div v-if="prevReadMsg.type=='目标设定'" style="height: 100%;display: flex;">
|
|
||||||
<degreeevolution :courseObj="courseObj" :show-class="true" :teachResObj="activeTeachResOfStandard" :attainmentList="attainmentList" :courseQualityList="courseQualityList"/>
|
|
||||||
</div>
|
|
||||||
<div v-if="prevReadMsg.type=='教材研读'" style="height: 100%;">
|
|
||||||
<standard book-type="教材研读" :course-obj="courseObj" :show-tools="false" :bookdatahtml="versionObj.bookdata" :teachResObj="activeTeachResOfStandard"></standard>
|
|
||||||
</div> -->
|
|
||||||
<div v-if="prevReadMsg.type=='框架梳理'" style="height: 100%;">
|
|
||||||
<FlowChart ref="flowref" :flowHeight="mainHeight" :dataSource="flowData"/>
|
|
||||||
</div>
|
|
||||||
<!-- <div v-if="prevReadMsg.type=='学科定位'" style="height: 100%;">
|
|
||||||
<teachJsMind :course-obj="courseObj" :teachResObj="activeTeachResOfStandard"></teachJsMind>
|
|
||||||
</div> -->
|
|
||||||
<!-- <div v-if="prevReadMsg.type=='习题训练'">习题训练</div> -->
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -260,16 +243,16 @@ import { listKnowledgePoint } from "@/api/knowledge/knowledgePoint";
|
||||||
import { useGetHomework } from '@/hooks/useGetHomework'
|
import { useGetHomework } from '@/hooks/useGetHomework'
|
||||||
import { processList } from '@/hooks/useProcessList'
|
import { processList } from '@/hooks/useProcessList'
|
||||||
import { getCurrentTime } from '@/utils/date'
|
import { getCurrentTime } from '@/utils/date'
|
||||||
import FlowChart from "@/components/Flowchart/index.vue";
|
|
||||||
import FileUpload from "@/components/FileUpload/index.vue";
|
import FileUpload from "@/components/FileUpload/index.vue";
|
||||||
import whiteboard from '@/components/whiteboard/whiteboard.vue'
|
import whiteboard from '@/components/whiteboard/whiteboard.vue'
|
||||||
|
import prevReadMsgDialog from '@/views/classTask/container/newTask/prevReadMsg-Dialog.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'
|
||||||
const userStore = useUserStore().user
|
const userStore = useUserStore().user
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const toolStore = useToolState()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
bookobj: {
|
bookobj: {
|
||||||
|
@ -286,12 +269,8 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const prevReadMsgDialogRef = ref(null);// 预览框ref
|
||||||
|
|
||||||
const isDialogOpen = ref(false)
|
|
||||||
const toolStore = useToolState()
|
|
||||||
const openDialog = () => {
|
|
||||||
isDialogOpen.value = true
|
|
||||||
}
|
|
||||||
const classWorkFormRef = ref(null);
|
const classWorkFormRef = ref(null);
|
||||||
const entpCourseWorkTypeList = ref([
|
const entpCourseWorkTypeList = ref([
|
||||||
{value: 0, label: "不限"},
|
{value: 0, label: "不限"},
|
||||||
|
@ -372,12 +351,6 @@ const listWorkType = ref(['习题训练', '框架梳理', '课堂展示', '常
|
||||||
|
|
||||||
// 课堂展示-------
|
// 课堂展示-------
|
||||||
const boardLoading = ref(false);
|
const boardLoading = ref(false);
|
||||||
const prevReadMsg = reactive({
|
|
||||||
visible: false,
|
|
||||||
type: ""
|
|
||||||
});// 预览msg
|
|
||||||
// 框架梳理----------
|
|
||||||
const flowData = ref({})// 框架梳理
|
|
||||||
//常规作业----------
|
//常规作业----------
|
||||||
const fileLoading = ref(false); // 常规作业loading
|
const fileLoading = ref(false); // 常规作业loading
|
||||||
|
|
||||||
|
@ -388,8 +361,6 @@ const changeFormType = (val) => {
|
||||||
classWorkForm.worktype = val;
|
classWorkForm.worktype = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(props.propsformobj)
|
|
||||||
console.log(classWorkForm,'==============zizujian===================')
|
|
||||||
/**
|
/**
|
||||||
* @desc: 根据查询参数查询试题
|
* @desc: 根据查询参数查询试题
|
||||||
* @return: {*}
|
* @return: {*}
|
||||||
|
@ -565,61 +536,7 @@ const handleClassWorkQuizAdd = (fromsrc, entpcourseworkid) => {
|
||||||
* 预览资源
|
* 预览资源
|
||||||
*/
|
*/
|
||||||
const prevRead = async (item) => {
|
const prevRead = async (item) => {
|
||||||
prevReadMsg.visible = true;
|
proxy.$refs.prevReadMsgDialogRef.openDialog(item);
|
||||||
prevReadMsg.type = item.worktype;
|
|
||||||
if (item.worktype==='课标研读'){
|
|
||||||
//获取教材文件和批注信息
|
|
||||||
listEvaluation({itemkey: 'subject', edusubject: userStore.edusubject, edustage: userStore.edustage}).then(res => {
|
|
||||||
// TODO 课标研读-还未接入
|
|
||||||
console.log("课标研读-还未接入",res);
|
|
||||||
// this.versionObj = res.rows[0];
|
|
||||||
// // 读取出课标文件的每一行
|
|
||||||
// if (this.versionObj.fileurl.length > 0) {
|
|
||||||
// readFile({cluelink: this.versionObj.fileurl}).then(fileres => {
|
|
||||||
// this.versionObj.bookdata = fileres;
|
|
||||||
// this.activeTeachResOfStandard = item;
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (item.worktype==='目标设定'){
|
|
||||||
// TODO 目标设定-还未接入
|
|
||||||
// this.activeTeachResOfStandard = item;
|
|
||||||
}
|
|
||||||
if (item.worktype==='教材研读'){
|
|
||||||
// TODO 教材研读-还未接入
|
|
||||||
// getEvaluation(this.courseObj.evalrootid).then(bookres => {
|
|
||||||
// this.versionObj = bookres.data;
|
|
||||||
// if (this.versionObj.fileurl.length > 0) {
|
|
||||||
// readFile({cluelink: this.versionObj.fileurl}).then(fileres => {
|
|
||||||
// this.versionObj.bookdata = fileres;
|
|
||||||
// this.activeTeachResOfStandard = item;
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
if (item.worktype==='框架梳理'){
|
|
||||||
flowData.value = {};
|
|
||||||
const { chapterId } = await useGetHomework(props.bookobj.node)
|
|
||||||
// this.entpcourseid = chapterId
|
|
||||||
let queryParams = {
|
|
||||||
entpcourseid: chapterId,
|
|
||||||
ppttype: '教材分析',
|
|
||||||
parentid: item.id,
|
|
||||||
title: '逻辑框架建构',
|
|
||||||
filetype: 'draw'
|
|
||||||
}
|
|
||||||
listEntpcoursefile(queryParams).then(response=>{
|
|
||||||
if (response.rows.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
flowData.value = JSON.parse(response.rows[0].datacontent)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (item.worktype==='学科定位'){
|
|
||||||
// TODO 学科定位-还未接入
|
|
||||||
// this.activeTeachResOfStandard = item;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 添加到作业
|
* 添加到作业
|
||||||
|
@ -831,7 +748,10 @@ const handleClassWorkSave = async () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 编辑作业内容
|
||||||
|
* @param cform 表单数据
|
||||||
|
*/
|
||||||
const editWork = async (cform) =>{
|
const editWork = async (cform) =>{
|
||||||
// 基础参数
|
// 基础参数
|
||||||
cform.id= classWorkForm.id;
|
cform.id= classWorkForm.id;
|
||||||
|
|
|
@ -152,7 +152,7 @@ import useUserStore from '@/store/modules/user'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { getCurrentTime, getAfterMinutes } from '@/utils/date'
|
import { getCurrentTime, getAfterMinutes } from '@/utils/date'
|
||||||
import { processList } from '@/hooks/useProcessList'
|
import { processList } from '@/hooks/useProcessList'
|
||||||
import ItemDialogScore from '@/views/classTask/container/item-dialog-score.vue'
|
import ItemDialogScore from '@/views/classTask/container/classTask/item-dialog-score.vue'
|
||||||
// zdg: 组件导入
|
// zdg: 组件导入
|
||||||
import quizStats from '@/views/classTask/container/quizStats.vue'
|
import quizStats from '@/views/classTask/container/quizStats.vue'
|
||||||
import ClassOverview from '@/views/classTask/container/classOverview.vue'
|
import ClassOverview from '@/views/classTask/container/classOverview.vue'
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
<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>
|
||||||
|
@ -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 = []
|
||||||
// 如果当前显示历史, 就从新获取
|
// 如果当前显示历史, 就从新获取
|
||||||
|
|
|
@ -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: '确认',
|
||||||
|
|
|
@ -28,12 +28,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>
|
||||||
|
@ -161,16 +163,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 || {}
|
||||||
|
|
||||||
|
@ -279,7 +286,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('当前正在上课,请勿重复操作')
|
||||||
|
@ -290,11 +298,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')
|
||||||
},
|
},
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue