<template>
|
<div class="classManagePage-box">
|
<div class="classManagePage-nav">
|
<el-breadcrumb :separator-icon="ArrowRight">
|
<el-breadcrumb-item>我的班级</el-breadcrumb-item>
|
<el-breadcrumb-item>{{ classInfo?.name }}</el-breadcrumb-item>
|
<el-breadcrumb-item>教学互动</el-breadcrumb-item>
|
</el-breadcrumb>
|
</div>
|
<div class="classManagePage-content">
|
<div class="teachPlaneBox">
|
<div class="titleBox">
|
<div class="titleOptions">
|
<span>教学互动</span>
|
</div>
|
<div class="searchBox">
|
<el-input
|
v-model="searchKey"
|
clearable
|
@clear="searchData()"
|
placeholder="请输入关键字"
|
@keydown.enter="searchData()"
|
>
|
<template #append>
|
<el-button type="primary" @click="searchData()" class="searchBtn" :icon="Search" />
|
</template>
|
</el-input>
|
</div>
|
</div>
|
</div>
|
<div class="listBox">
|
<el-table
|
:header-cell-style="{ background: '#eee' }"
|
:data="cmsDataList"
|
max-height="700px"
|
style="width: 100%"
|
v-loading="cmsLoading"
|
>
|
<el-table-column prop="id" label="序号" width="100" />
|
<el-table-column prop="name" label="标题" width="500" />
|
<el-table-column prop="address" label="已互动学生数" #default="scoped">
|
<div>
|
<span style="color: #019e58">{{ scoped.row.subList.length }}</span>
|
</div>
|
</el-table-column>
|
<el-table-column prop="address" label="最后提交时间" #default="scoped">
|
<span v-if="scoped.row.updateDate"> {{ scoped.row.updateDate }} </span>
|
<span v-else> - </span>
|
</el-table-column>
|
<el-table-column prop="address" label="操作" #default="scoped">
|
<el-button link type="success" @click="toDetail(scoped.row)">查看详情</el-button>
|
<el-button link style="color: #409eff" @click="getQuestions(scoped.row)"
|
>浏览答题</el-button
|
>
|
</el-table-column>
|
</el-table>
|
<!-- 浏览答题 -->
|
<el-dialog
|
class="customDialog"
|
title="浏览答题"
|
v-model="visible"
|
destroy-on-close
|
width="1000"
|
align-center
|
:before-close="close"
|
>
|
<div class="pubContent" v-if="dialogList.length > 0 && !dialogLLoading">
|
<div v-for="(item, index) in dialogList" :key="index">
|
<span class="userName">答题人:{{ item.userName ?? '-' }}</span>
|
<question-dom
|
v-if="item.questionTypeList.length > 0"
|
:questionList="item.questionTypeList"
|
:noCheckbox="false"
|
:is-preview="true"
|
:is-interaction="true"
|
/>
|
</div>
|
</div>
|
<div class="pubContent" v-if="dialogLLoading" v-loading="dialogLLoading"></div>
|
<div class="pubContent noData" v-if="dialogList.length == 0 && !dialogLLoading">
|
<el-empty></el-empty>
|
</div>
|
<template #footer>
|
<div class="selectedFooter" style="padding: 0">
|
<el-button type="primary" @click="visible = false"> 关闭 </el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { Search, ArrowRight } from '@element-plus/icons-vue'
|
import moment from 'moment'
|
import { ref, onMounted, inject } from 'vue'
|
import { useRoute, useRouter } from 'vue-router'
|
import questionDom from './components/questionDom.vue'
|
|
const route: any = useRoute()
|
const router: any = useRouter()
|
const MG: any = inject('MG')
|
const config: any = inject('config')
|
const classInfo = JSON.parse(route.query.classInfo)
|
const userInfo = ref()
|
|
const teachInteractionInfo: any = ref([])
|
const searchKey = ref('')
|
const dataList: any = ref([])
|
const currentClass = ref()
|
const cmsDataList: any = ref([])
|
const cmsLoading = ref(true)
|
|
const visible = ref(false)
|
const dialogList: any = ref([])
|
const dialogLLoading = ref(true)
|
const defaultCmsPath = ref('')
|
|
onMounted(() => {
|
const userCache: any = localStorage.getItem(config.userInfoKey)
|
if (userCache) {
|
userInfo.value = JSON.parse(userCache)
|
}
|
defaultCmsPath.value = classInfo.bookRefCode ? '*' : config.goodsStore
|
getData()
|
})
|
|
const searchData = () => {
|
const data = [...cmsDataList.value]
|
if (!searchKey.value) {
|
getCmsList()
|
} else {
|
const list = data.filter((item) => item.name.indexOf(searchKey.value) > -1)
|
cmsDataList.value = list
|
}
|
}
|
|
const close = () => {
|
visible.value = false
|
}
|
|
// 获取教学互动
|
const getCmsList = () => {
|
cmsLoading.value = true
|
cmsDataList.value = []
|
try {
|
MG.store
|
.getProductDetail({
|
path: defaultCmsPath.value,
|
queryType: '*',
|
productId: classInfo.bookId,
|
cmsPath: classInfo.rootCmsItemId
|
})
|
.then((res: any) => {
|
try {
|
const data = res.datas?.cmsDatas[0]?.datas.find(
|
(item: any) => item.refCode == 'questionBank'
|
)
|
MG.store
|
.getProductDetail({
|
path: defaultCmsPath.value,
|
queryType: '*',
|
productId: classInfo.bookId,
|
cmsPath: data.productLinkPath
|
})
|
.then((res: any) => {
|
try {
|
const dataTeach = res.datas.cmsDatas[0]?.datas.find(
|
(item: any) => item.refCode == 'jsek_interaction'
|
)
|
MG.store
|
.getProductDetail({
|
path: defaultCmsPath.value,
|
queryType: '*',
|
productId: classInfo.bookId,
|
cmsPath: dataTeach.productLinkPath
|
})
|
.then((res: any) => {
|
let datas = res.datas.cmsDatas[0] ? res.datas.cmsDatas[0].datas : []
|
if (datas?.length > 0) {
|
datas.forEach((item: any) => {
|
MG.store
|
.getProductDetail({
|
path: defaultCmsPath.value,
|
queryType: '*',
|
productId: classInfo.bookId,
|
cmsPath: item.productLinkPath,
|
cmsSort: {
|
ProductLinkOrder: 'Desc'
|
}
|
})
|
.then(async (cmsRes: any) => {
|
cmsLoading.value = false
|
if (
|
cmsRes.datas.cmsDatas[0].datas &&
|
cmsRes.datas.cmsDatas[0].datas.length > 0
|
) {
|
cmsRes.datas.cmsDatas[0].datas.forEach((item: any) => {
|
item.subList = []
|
if (dataList.value.length > 0) {
|
dataList.value.forEach((mitem: any) => {
|
if (mitem.name == item.name) {
|
item.updateDate = moment(dataList.value[0].updateDate).format(
|
'YYYY-MM-DD HH:mm:ss'
|
)
|
item.subList.push(mitem)
|
}
|
})
|
}
|
cmsDataList.value.push(item)
|
})
|
}
|
})
|
})
|
}
|
})
|
} catch (error) {
|
cmsLoading.value = false
|
cmsDataList.value = []
|
}
|
})
|
} catch (error) {
|
cmsLoading.value = false
|
cmsDataList.value = []
|
}
|
})
|
} catch (error) {
|
cmsLoading.value = false
|
cmsDataList.value = []
|
}
|
}
|
|
// 获取Messsagetopic
|
const getTopicInfo = () => {
|
const pramas = {
|
classId: classInfo.id,
|
refCodes: [config.refCode.teachInteraction]
|
}
|
MG.edu.getClassTopic(pramas).then((res: any) => {
|
const list = res
|
teachInteractionInfo.value = list.find(
|
(item: any) => item.refCode == config.refCode.teachInteraction
|
)
|
if (teachInteractionInfo.value.id) {
|
getMessage()
|
}
|
})
|
}
|
|
// 获取当前MessageList
|
const getMessage = () => {
|
const data = {
|
start: 0,
|
size: 999,
|
appRefCode: config.appRefCode,
|
topicIdOrRefCode: String(teachInteractionInfo.value.id),
|
sort: {
|
type: 'Desc',
|
field: 'CreateDate'
|
},
|
searchList: searchKey.value
|
? [
|
{
|
keywords: searchKey.value,
|
field: 'Name',
|
compareType: 'Contains'
|
}
|
]
|
: []
|
}
|
MG.ugc.getTopicMessageList(data).then((res: any) => {
|
dataList.value = res.datas.map((item: any) => {
|
item.question = []
|
item.bookId = null
|
item.path = ''
|
try {
|
const obj = JSON.parse(item.content)
|
if (obj.bookId) {
|
item.question = obj.content.map((citem: any) => {
|
return {
|
...citem,
|
updateDate: moment(item.updateDate).format('YYYY-MM-DD HH:mm:ss'),
|
userId: item.appUserCreator.userId
|
}
|
})
|
item.bookId = obj.bookId
|
item.path = obj.path
|
item.userName = obj.userName
|
}
|
} catch (error) {
|
console.log(item)
|
}
|
return {
|
...item
|
}
|
})
|
console.log(dataList.value, 'datal')
|
getCmsList()
|
})
|
}
|
|
// 获取班级
|
const getData = () => {
|
MG.edu
|
.getCourseClass({
|
ClassIdOrRefCode: String(classInfo.id)
|
})
|
.then((res: any) => {
|
if (res) {
|
currentClass.value = res
|
}
|
getTopicInfo()
|
})
|
}
|
|
// 获取题目列表
|
const getQuestions = (pitem: any) => {
|
visible.value = true
|
dialogLLoading.value = true
|
MG.store
|
.getProductDetail({
|
path: '*',
|
queryType: '*',
|
productId: classInfo.bookId,
|
cmsPath: pitem.productLinkPath,
|
itemFields: {
|
Embedded_QuestionBank_AnalysisCon: [],
|
Embedded_QuestionBank_Answer: [],
|
Embedded_QuestionBank_Difficulty: [],
|
Embedded_QuestionBank_KnowledgePoint: [],
|
Embedded_QuestionBank_Option: [],
|
Embedded_QuestionBank_OptionStyle: [],
|
Embedded_QuestionBank_QuestionType: [],
|
Embedded_QuestionBank_Score: [],
|
Embedded_QuestionBank_Stem: [],
|
Embedded_QuestionBank_StemStyle: []
|
}
|
})
|
.then((res: any) => {
|
try {
|
let list = []
|
list = res.datas.cmsDatas[0]?.datas.map((item: any) => {
|
try {
|
if (item.Embedded_QuestionBank_Stem) {
|
item.questionStem = JSON.parse(item.Embedded_QuestionBank_Stem)
|
}
|
if (
|
item.Embedded_QuestionBank_Option &&
|
item.Embedded_QuestionBank_Option.indexOf('[') > -1
|
) {
|
item.questionOption = JSON.parse(item.Embedded_QuestionBank_Option)
|
}
|
if (
|
item.Embedded_QuestionBank_Answer &&
|
item.Embedded_QuestionBank_Answer.indexOf('[') > -1
|
) {
|
item.Embedded_QuestionBank_Answer = JSON.parse(item.Embedded_QuestionBank_Answer)
|
}
|
return {
|
...item,
|
questionType: item.Embedded_QuestionBank_QuestionType,
|
questionAnalysisCon: item.Embedded_QuestionBank_AnalysisCon,
|
questionAnswer: item.Embedded_QuestionBank_Answer,
|
customAnswer: null,
|
updateDate: pitem.updateDate
|
}
|
} catch (error) {
|
console.log(item)
|
}
|
})
|
dialogList.value = chageData(pitem.subList, list)
|
dialogLLoading.value = false
|
} catch (error) {
|
dialogList.value = []
|
dialogLLoading.value = false
|
}
|
})
|
}
|
|
// 处理数据结构
|
const chageData = (arr: any, zrr: any) => {
|
// 题库题目类型
|
const questionTypeList = [
|
{ name: '单选题', value: 'singleChoice', data: [] },
|
{ name: '多选题', value: 'multipleChoice', data: [] },
|
{ name: '判断题', value: 'judge', data: [] },
|
{ name: '简答题', value: 'shortAnswer', data: [] },
|
{ name: '论述题', value: 'discuss', data: [] },
|
{ name: '填空题', value: 'completion', data: [] },
|
{ name: '连线题', value: 'matching', data: [] },
|
{ name: '分类题', value: 'classification', data: [] }
|
]
|
for (let i = 0; i < arr.length; i++) {
|
const item = arr[i]
|
item.questionTypeList = JSON.parse(JSON.stringify(questionTypeList))
|
item.other = []
|
for (let j = 0; j < item.question.length; j++) {
|
const ele = item.question[j]
|
const data = zrr.find((sitem: any) => sitem.id == ele.cmsItemId)
|
const index = findIndexById(zrr, ele.cmsItemId)
|
if (index > -1) {
|
item.other[index] = { ...data, userAnswer: ele.answer }
|
}
|
}
|
if (item.other.length > 0) {
|
item.other.forEach((aitem: any) => {
|
const index = findIndexByValue(item.questionTypeList, aitem.questionType)
|
if (index > -1) {
|
item.questionTypeList[index].data.push(aitem)
|
}
|
})
|
}
|
item.questionTypeList = item.questionTypeList.filter((xitem: any) => xitem.data.length > 0)
|
}
|
return arr
|
}
|
|
const findIndexByValue = (res: any, type: string) => {
|
for (let i = 0; i < res.length; i++) {
|
if (res[i].value == type) {
|
return i
|
}
|
}
|
return -1 // 如果未找到,则返回 -1
|
}
|
|
const findIndexById = (res: any, id: string) => {
|
for (let i = 0; i < res.length; i++) {
|
if (res[i].id == id) {
|
return i
|
}
|
}
|
return -1 // 如果未找到,则返回 -1
|
}
|
|
// 去详情
|
const toDetail = (item: any) => {
|
const obj = classInfo
|
obj.questionName = item.name
|
obj.teachInteractionId = teachInteractionInfo.value.id
|
router.push({
|
path: '/interactionDetail',
|
query: {
|
classInfo: JSON.stringify(obj)
|
}
|
})
|
}
|
</script>
|
|
<style lang="less" scoped>
|
.classManagePage-box {
|
padding: 20px;
|
.classManagePage-nav {
|
padding-bottom: 20px;
|
border-bottom: 1px solid #e6e8ed;
|
margin-bottom: 20px;
|
}
|
.classManagePage-content {
|
width: 100%;
|
.teachPlaneBox {
|
width: 100%;
|
.titleBox {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
.titleOptions {
|
width: 160px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
span {
|
height: 30px;
|
font-family: PingFang SC;
|
font-weight: bold;
|
font-size: 16px;
|
color: #333;
|
line-height: 30px;
|
text-align: left;
|
border-left: 6px solid #019e58;
|
padding-left: 10px;
|
}
|
}
|
.searchBox {
|
width: 300px;
|
float: left;
|
.searchBtn {
|
background-color: var(--el-color-primary);
|
color: #fff;
|
border-top-left-radius: 0;
|
border-bottom-left-radius: 0;
|
}
|
}
|
}
|
}
|
.pubContent {
|
height: 80vh;
|
padding: 10px;
|
box-sizing: border-box;
|
overflow-y: auto;
|
.userName {
|
color: #019e58;
|
}
|
}
|
}
|
}
|
</style>
|