XW 2 rokov pred
rodič
commit
e896a84c17

+ 3 - 0
TEAMModelOS/ClientApp/src/api/studentWeb.js

@@ -248,4 +248,7 @@ export default {
     setArtScore: function(data) {
         return post("/common/art/update-state", data)
     },
+    getErrList: function(data) {
+        return post("/common/exam/get-error-item", data)
+    },
 }

+ 6 - 0
TEAMModelOS/ClientApp/src/components/student-web/WrongQusetion/QuesList.less

@@ -211,6 +211,12 @@
                     min-width: 60px;
                 }
             }
+
+            .question {
+                width: calc(96% - 40px);
+                display: inline-block;
+
+            }
         }
 
     }

+ 194 - 65
TEAMModelOS/ClientApp/src/components/student-web/WrongQusetion/QuesList.vue

@@ -7,7 +7,7 @@
             </span>
             <span class="test-title">{{ $t("courseManage.base.courseName") }}:罗老师小课堂</span>
         </div> -->
-        <Scroll class="list-scroll">
+        <!-- <Scroll class="list-scroll"> -->
             <!-- 筛选 -->
             <div :class="['filter-type', {'show-filter': isOpen, 'no-filter': winHeight}]">
                 <div>
@@ -66,11 +66,12 @@
                     <!-- <DatePicker type="date" :placeholder="$t('studentWeb.wrongTopic.date')" :options="options" @on-change="dateChange"
                                 style="width: 200px" class="light-iview-input"
                     /> -->
-                    <span class="have-total">
+                    <!-- 先不展示 -->
+                    <!-- <span class="have-total">
                         {{ $t('studentWeb.wrongTopic.word1') }}
                         <span>{{ topicTotal }}</span>
                         {{ $t('studentWeb.wrongTopic.topic') }}
-                    </span>
+                    </span> -->
                 </div>
                 <Icon type="md-arrow-dropdown" @click="isOpen = !isOpen" v-show="!isOpen" />
                 <Icon type="md-arrow-dropup" @click="isOpen = !isOpen" v-show="isOpen" />
@@ -82,50 +83,64 @@
                     <span style="float: right">
                         {{ $t('studentWeb.wrongTopic.check') }}:
                         <span style="font-size: 18px; font-weight: bold;">{{ checkNum }}</span>
-                        <span :class="['start-btn-primary', {'start-btn': checkNum}]" @click="startPra">{{ $t('studentWeb.wrongTopic.startPractice') }}</span>
+                        <span :class="['start-btn-primary', {'start-btn':  checkNum}]" @click="startPra">{{ $t('studentWeb.wrongTopic.startPractice') }}</span>
                     </span>
                 </div> -->
                 <template v-if="exerciseList.length">
-                    <!-- <Scroll class="list-scroll"> -->
+                    <Scroll :on-reach-bottom="handleReachTop" class="list-scroll">
                         <!-- <CheckboxGroup v-model="checkTopicArr"> -->
                             <!-- <Checkbox :label="index" v-for="(item, index) in exerciseList" :key="index" class="topic-box"> -->
                             <div v-for="(item, index) in exerciseList" :key="index" class="topic-box">
-                                <div style="width: 100%;">
-                                    <span style="vertical-align: top; margin-right: 5px; cursor: pointer;" @click="onCollection">
-                                        <Icon custom="iconfont icon-shoucang1" size="19" color="#3B660C" v-show="!iscollection"></Icon>
-                                        <Icon custom="iconfont icon-shoucang2" size="19" color="#EA8F3E" v-show="iscollection"></Icon>
+                                <div style="width: 100%; position: relative;">
+                                <div style="position: absolute; top: 0; right: 0;">
+                                    <span v-show="item.open" @click="closeDetail(index)">
+                                        <Icon type="ios-arrow-dropup" class="ansDetail" size="25" :title="$t('studentWeb.exam.report.closeExam')" />
                                     </span>
-                                    <span style="vertical-align: top;">{{ pageSize * (pageNum - 1) + index + 1 }}. </span>
-                                    <div v-html="item.question" style="width: calc(99% - 40px); display: inline-block;"></div>
-                                    <div class="answer-area">
-                                        <span class="answer-tip">【{{ $t('evaluation.answer') }}】</span>
-                                        <p>
-                                            这首诗之所以震撼人心,最重要的原因是诗人忘我的精神、博大的胸襟,如“安得广厦千万间,大庇天下寒士俱欢颜"这样的诗句,表现出作者在自己生活极度艰难的情景下,依然不忘忧国忧民,情真意切.感人至深。
-                                        </p>
-                                    </div>
-                                    <div class="answer-area">
-                                        <span class="answer-tip">【{{ $t('evaluation.explain') }}】</span>
-                                        <p>
-                                            这首诗之所以震撼人心,最重要的原因是诗人忘我的精神、博大的胸襟。这首诗之所以震撼人心,最重要的原因是诗人忘我的精神、博大的胸襟。这首诗之所以震撼人心,最重要的原因是诗人忘我的精神、博大的胸襟。
-                                        </p>
+                                    <span v-show="!item.open" @click="closeDetail(index)">
+                                        <Icon type="ios-arrow-dropdown" class="ansDetail" size="25" :title="$t('studentWeb.exam.report.openExam')" />
+                                    </span>
+                                </div>
+                                    <span style="vertical-align: top; margin-right: 5px; margin-top: 1px;" class="tag-style">{{ $t(`studentWeb.exam.queType.${item.type}`) }}</span>
+                                    <span style="vertical-align: top; margin-right: 5px; cursor: pointer;" @click="onCollection(index)">
+                                        <Icon custom="iconfont icon-shoucang1" size="19" color="#3B660C" v-show="!item.star"></Icon>
+                                        <Icon custom="iconfont icon-shoucang2" size="19" color="#EA8F3E" v-show="item.star"></Icon>
+                                    </span>
+                                    <span style="vertical-align: top;">{{ index + 1 }}. </span>
+                                    <div class="question" v-html="item.question"></div>
+                                    <div v-show="item.open">
+                                        <div>
+                                            <div v-for="(option, oIndex) in item.option" :key="oIndex" style="display: flex; margin-top: 5px; margin-left: 5px;">
+                                                {{option.code}}. <div style="margin-left:10px" v-html="option.value"></div>
+                                            </div>
+                                        </div>
+                                        <div v-if="item.children.length" style="margin-left: 20px;">
+                                            <div v-for="(child, cIndex) in item.children" :key="cIndex" class="topic-box">
+                                                <span style="vertical-align: top;">({{ cIndex + 1 }}). </span>
+                                                <div v-html="child.question" style="width: calc(94% - 40px); display: inline-block;"></div>
+                                                <div v-for="(optionC, indexoptionC) in child.option" :key="indexoptionC" style="display:flex; margin-top:5px; margin-left: 5px;">
+                                                    {{optionC.code}}. <div style="margin-left:10px" v-html="optionC.value"></div>
+                                                </div>
+                                                <div class="answer-area">
+                                                    <span class="answer-tip">【{{ $t('evaluation.answer') }}】</span>
+                                                    <p v-html="child.answer[0]"></p>
+                                                </div>
+                                                <div class="answer-area">
+                                                    <span class="answer-tip">【{{ $t('evaluation.explain') }}】</span>
+                                                    <p v-html="child.explain"></p>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <template v-else>
+                                            <div class="answer-area">
+                                                <span class="answer-tip">【{{ $t('evaluation.answer') }}】</span>
+                                                <p v-html="item.answer[0]"></p>
+                                            </div>
+                                            <div class="answer-area">
+                                                <span class="answer-tip">【{{ $t('evaluation.explain') }}】</span>
+                                                <p v-html="item.explain"></p>
+                                            </div>
+                                        </template>
                                     </div>
-                                    <!-- <div class="topic-type">
-                                        <span>
-                                            {{ $t('studentWeb.wrongTopic.type') }}:{{ typeObj[item.type] }}
-                                        </span>
-                                        <span>
-                                            {{ $t('studentWeb.wrongTopic.diff') }}:{{ diffList[item.level - 1] }}
-                                        </span>
-                                        <span>
-                                            {{ $t('studentWeb.wrongTopic.level') }}:{{ levelList[item.field] }}
-                                        </span>
-                                        <span>
-                                            {{ $t('studentWeb.wrongTopic.wrong') }}:15%
-                                        </span>
-                                        <span>
-                                            {{ $t('studentWeb.wrongTopic.wrongNum') }}:2
-                                        </span>
-                                    </div> -->
                                     <div class="topic-type">
                                         <span>
                                             {{ $t('studentWeb.wrongQues.nextTime') }}:2022-11-5
@@ -140,13 +155,13 @@
                                 </div>
                             </div>
                         <!-- </CheckboxGroup> -->
-                    <!-- </Scroll> -->
+                    </Scroll>
                 </template>
-                <Page :total="topicTotal" show-sizer show-total :page-size="pageSize" @on-page-size-change="pageSizeChange"
+                <!-- <Page :total="topicTotal" show-sizer show-total :page-size="pageSize" @on-page-size-change="pageSizeChange"
                         :current="pageNum" @on-change="pageChange" :page-size-opts="[5, 10, 15, 20]"
-                        style="text-align: center; margin-top: 20px;" />
+                        style="text-align: center; margin-top: 20px;" /> -->
             </div>
-        </Scroll>
+        <!-- </Scroll> -->
         <Modal v-model="pointShow" :title="$t('studentWeb.wrongTopic.checkPoint')" @on-ok="okPoint" class="wrong-ques-modal">
             <p>
                 <!-- <span style="margin-left: 50px;">学段:初中</span> -->
@@ -167,6 +182,7 @@
 </template>
 
 <script>
+import { mapGetters, mapState } from 'vuex';
 export default {
     name: "",
     data () {
@@ -183,7 +199,7 @@ export default {
             typeList: [ //题型
                 this.$t("studentWeb.type.all"),
                 this.$t("studentWeb.exam.queType.single"),
-                this.$t("studentWeb.exam.queType.multiply"),
+                this.$t("studentWeb.exam.queType.multiple"),
                 this.$t("studentWeb.exam.queType.judge"),
                 this.$t("studentWeb.exam.queType.complete"),
                 this.$t("studentWeb.exam.queType.subjective"),
@@ -198,7 +214,7 @@ export default {
                 connector: this.$t("studentWeb.exam.queType.connector"),
                 correct: this.$t("studentWeb.exam.queType.correct"),
                 judge: this.$t("studentWeb.exam.queType.judge"),
-                multiple: this.$t("studentWeb.exam.queType.multiply"),
+                multiple: this.$t("studentWeb.exam.queType.multiple"),
                 single: this.$t("studentWeb.exam.queType.single"),
                 subjective: this.$t("studentWeb.exam.queType.subjective"),
             },
@@ -234,6 +250,8 @@ export default {
             iscollection: false,
             isOpen: false,
             winHeight: 0,
+            sasInfo: undefined,
+            continuationToken: null,
         }
     },
     async created () {
@@ -250,6 +268,7 @@ export default {
             { name: "文言文释义"},
             { name: "拟人"}
         ]
+        this.sasInfo = await this.getSas()
         this.getTopicList()
     },
     mounted () {
@@ -262,33 +281,135 @@ export default {
         checkPoint() {
 
         },
+        
+        getSas() {
+            return new Promise(async (r, j) => {
+                let code = this.courseNow.scope === "school" ? this.courseNow.school : this.courseNow.roster.teacherId
+                let sasInfo = await this.$tools.getBlobSas(code)
+                r(sasInfo)
+            })
+        },
         // 获取题目
         getTopicList() {
             this.isLoading = true
+            this.topicList = []
             var queryData = {
-                "@DESC": "createTime",
-                "code": "hbcn",
-                "periodId": [],
-                "gradeIds[*]": [],
-                "subjectId": ["8b94c6b6-2572-41e5-89b9-a82fcf13891e"],
-                "level": [],
-                "type": [],
-                "field": [],
-                "scope": "school",
-                "knowledge[*]": [],
-                "pid": null
+                stuId: this.userInfo.sub,
+                // code: this.courseNow.school,
+                subjectId: this.courseNow.subject.id ? this.courseNow.subject.id : this.courseNow.id,
+                count: 1,
+                // token: '',
+            }
+            if(this.userInfo.scope === 'student') {
+                queryData.code = this.courseNow.school
             }
-            this.$api.newEvaluation.FindExerciseList(queryData).then(res => {
-                if(res.items){
-                    this.topicRes = res.items
-                    this.topicList = this.topicRes
-                    this.topicTotal = this.topicList.length
-                    this.pageChange(1)
+            if(this.continuationToken) {
+                queryData.token = this.continuationToken
+            }
+            this.$api.studentWeb.getErrList(queryData).then(res => {
+                this.continuationToken = res.token
+                if(res.errorItems) {
                     this.isLoading = false
+                    res.errorItems.forEach(paper => {
+                        paper.its.map(item => {
+                            this.topicList.push(item)
+                        })
+                    })
+                    this.getJson()
                 }
             }).catch((e) => {
             });
         },
+        getAllData() {
+            return new Promise((resolve, reject) => {
+                let promiseArr = []
+                this.topicList.forEach(item => {
+                    promiseArr.push(new Promise(async (r, j) => {
+                        try {
+                            let info = undefined
+                            let codes = this.courseNow.scope === 'private' ? this.courseNow.roster.teacherId : this.courseNow.school
+                            let fullPath = `${this.sasInfo.url}/${codes}${item.blob}/${item.id}.json?${this.sasInfo.sas}`
+                            let jsonData = JSON.parse(await this.$tools.getFile(fullPath))
+                            let paper = {
+                                blob: item.blob,
+                                code: codes,
+                                examId: codes,
+                                scope: this.courseNow.scope,
+                            }
+                            // 调整渲染试题数据结构
+                            jsonData.exercise.question = jsonData.item[0].question
+                            jsonData.exercise.option = jsonData.item[0].option
+                            jsonData.exercise.parentInfo = undefined
+                            jsonData.exercise.pid = jsonData.pid
+                            jsonData.exercise.id = jsonData.id
+                            jsonData.exercise.children = []
+                            jsonData.exercise.star = false
+                            jsonData.exercise.open = false
+                            jsonData.exercise = await this.$evTools.doAddHost(jsonData.exercise, paper)
+                            if(jsonData.pid) {
+                                let pPath = `${this.sasInfo.url}/${codes}${item.blob}/${jsonData.pid}.json?${this.sasInfo.sas}`
+                                let pData = JSON.parse(await this.$tools.getFile(pPath))
+                                pData.exercise.question = pData.item[0].question
+                                pData.exercise.option = pData.item[0].option
+                                pData.exercise.id = pData.id
+                                pData.exercise.parentInfo = undefined
+                                pData.exercise.pid = null
+                                pData.exercise.children = [jsonData.exercise]
+                                pData.exercise.star = false
+                                pData.exercise.open = false
+                                pData.exercise = await this.$evTools.doAddHost(pData.exercise, paper)
+                                info = pData.exercise
+                            } else {
+                                info = jsonData.exercise
+                            }
+                            r(info)
+                        } catch (e) {
+                            j(e)
+                        }
+                    }))
+                })
+                Promise.allSettled(promiseArr).then(result => {
+                    if (result.length) {
+                        // resolve(result)
+                        resolve(result.filter(i => i.status === 'fulfilled').map(j => j.value))
+                    } else {
+                        resolve([])
+                    }
+                })
+            })
+        },
+        async getJson() {
+            let data = await this.getAllData()
+            console.log(data);
+            data.forEach(item => {
+                // 查找有没有重复id
+                let needPid = this.exerciseList.findIndex(exe => {
+                    return exe.id === item.id
+                })
+                if(needPid === -1) {
+                    this.exerciseList.push(item)
+                } else {
+                    this.exerciseList[needPid].children.push(item.children[0])
+                }
+            })
+        },
+        handleReachTop () {
+            return new Promise(resolve => {
+                setTimeout(() => {
+                    if(this.continuationToken) {
+                        this.getTopicList()
+                        // this.getRecordList()
+                    } else {
+                        this.$Message.warning("没有更多数据")
+                    }
+                    resolve()
+                }, 2000);
+            });
+        },
+        // 控制收缩试卷的按钮
+        closeDetail(index) {
+            this.exerciseList[index].open = !this.exerciseList[index].open
+        },
         okPoint() {
             this.showPoint = []
             this.checkPointArr.forEach(item => {
@@ -308,13 +429,13 @@ export default {
             this.pageSize = val;
             this.pageChange(1);
         },
-        getSas() {
+        /* getSas() {
             return new Promise(async (r, j) => {
                 let code = this.userInfo.scope === 'student' ? this.userInfo.azp : this.userInfo.sub
                 let sasInfo = await this.$tools.getBlobSas(code)
                 r(sasInfo)
             })
-        },
+        }, */
         /**
          * 切换页码操作
          * @param page
@@ -389,7 +510,8 @@ export default {
             // })
         },
         // 收藏题目
-        onCollection() {
+        onCollection(index) {
+            this.exerciseList[index].star = !this.exerciseList[index].star
             this.iscollection = !this.iscollection
         },
         handlerScroll(e) {
@@ -409,6 +531,13 @@ export default {
             }
             return num
         },
+        ...mapGetters(['getNowCourse']),
+        ...mapState({
+            userInfo: state => state.userInfo
+        }),
+        courseNow() {
+            return this.getNowCourse || JSON.parse(decodeURIComponent(localStorage.course, "utf-8"))
+        },
     },
     watch: {
         checkAll: {