Explorar o código

Merge branch 'develop' of http://52.130.252.100:10000/TEAMMODEL/TEAMModelOS into develop

CrazyIter_Bin hai 9 meses
pai
achega
4a70c5f3dc

+ 277 - 0
TEAMModelOS/ClientApp/src/components/evaluation/BasePaperItemPicker.vue

@@ -0,0 +1,277 @@
+<template>
+    <div class="ev-cp-list-container paper-item-picker-container" style="width: 100%; margin: 0 auto">
+		<Loading :top="100" v-show="dataLoading" hideMask></Loading>
+		<div v-if="!paperList.length" class="no-data-text">
+			<img src="@/assets/icon/no_data_evaluation.png" width="120" />
+			<span style="margin-top: 15px; color: #808080">{{ $t("evaluation.noData") }}</span>
+		</div>
+        <div class="cp-content-wrap" ref="mathJaxContainer" v-else>
+            <Collapse simple v-if="paperList.length" accordion @on-change="onPaperClick">
+                <Panel v-for="(paper, index) in paperList" :key="index" color="primary" :name="paper.id">
+                <span style="display:inline-flex;align-items: center">
+                    <span style="margin-right:10px">{{ paper.name }}</span>
+                    <Tag color="blue">{{ paper.scoring ? paper.scoring.length : 0 }}{{ $t('evaluation.paperPickTip2') }}</Tag>
+                    <span style="margin-left: 8px;" v-for="(tag, tagIndex) in paper.tags" :key="tagIndex">
+                        <Tag color="geekblue">{{ tag }}</Tag>
+                    </span>
+                    <span style="margin-left: 8px;" v-if="paper.mode">
+                        <Tag color="green">{{ paper.mode }}</Tag>
+                    </span>
+                    <span style="margin-left: 8px;" v-if="paper.markModel">
+                        <Tag color="cyan">{{ $t('evaluation.markMode.tip4') }}</Tag>
+                    </span>
+                </span>
+                <template #content>
+                    <div class="question-list" v-if="questionList.length">
+                        <div :class="['cp-exercise-item']" v-for="(item, index) in questionList" :key="index">
+                            <!-- 题干部分 -->
+                            <div class="item-question" @click="onQuestionToggle(index, item.id, $event)">
+                                <div>
+                                    <!-- <Tag>{{ exersicesType[item.type] }}</Tag> -->
+                                    <div class="item-question-order">{{ index + 1 }} :</div>
+                                    <div class="item-question-text" v-html="item.question"></div>
+                                </div>
+                                <!-- <span class="item-btn-toggle print-hidden">
+                                    <p v-if="checkIdsList.includes(item.id)" @click.stop="onPrintItem($event, index)">{{ $t("evaluation.downloadQuestionPDF") }}</p>
+                                    <Icon :type="checkIdsList.includes(item.id) ? 'ios-arrow-dropup' : 'ios-arrow-dropdown'" />
+                                </span> -->
+                            </div>
+                            <!-- 选项部分 -->
+                            <div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options" @click="onQuestionToggle(index, item.id, $event)">
+                                <div class="item-option-content">
+                                    <div class="item-option-order">
+                                        <!-- {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} : -->
+                                        {{ option.code }} :
+                                    </div>
+                                    <div class="item-option-text" v-html="option.value"></div>
+                                </div>
+                            </div>
+                            <div class="exercise-item-children" v-if="item.children.length">
+                                <BaseChild :parentIndex="index" :children="item.children" inBank></BaseChild>
+                            </div>
+                            <transition name="slide" v-if="item.type !== 'compose'">
+                                <div v-if="collapseList.includes(questionList.indexOf(item))" class="toggle-area">
+                                    <p v-if="inSyllabus" class="print-hidden" style="cursor: pointer; text-decoration: underline; color: #4eb0e8; margin-left: 5px" @click.stop="onPrintItem($event, index)">
+                                        {{ $t("evaluation.downloadQuestionPDF") }}
+                                    </p>
+                                    <div>
+                                        <!-- 答案展示部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.answer") }}】</span>
+                                            <div class="item-explain-details">
+                                                <!-- 问答题答案 -->
+                                                <div v-if="item.type === 'subjective' || item.type === 'complete' || item.type === 'connector' || item.type === 'correct'">
+                                                    <span v-for="(answer, index) in item.answer" :key="index" v-html="item.answer.length ? answer : $t('utils.noData')"></span>
+                                                </div>
+                                                <!-- 问答题答案 -->
+                                                <div v-else-if="item.type === 'judge'">
+                                                    <span>{{ item.answer.length ? (item.answer[0] === "A" ? $t("evaluation.isTrue") : $t("evaluation.isFalse")) : $t("utils.noData") }}</span>
+                                                </div>
+                                                <!-- 其余题型答案 -->
+                                                <div v-else>
+                                                    <span :class="[item.type === 'complete' ? 'item-answer-item' : '']" v-for="(answer, index) in item.answer" :key="index">{{ answer }}</span>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <!-- 解析部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.explain") }}】</span>
+                                            <div class="item-explain-details">
+                                                <span v-html="item.explain || $t('utils.noData')"></span>
+                                            </div>
+                                        </div>
+                                        <!-- 知识点部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.knowledgePoints") }}】</span>
+                                            <div class="item-explain-details">
+                                                <span v-if="!item.knowledge || !item.knowledge.length">{{ $t("utils.noData") }}</span>
+                                                <div v-else>
+                                                    <span v-for="(point, pointIndex) in item.knowledge" class="item-point-tag" :key="pointIndex">
+                                                        {{ point }}
+                                                    </span>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <!-- 认知层次部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title" :style="{ color: isShowAnalysis ? '#099209' : '#10abe7' }">【{{ $t("evaluation.field") }}】</span>
+                                            <div class="item-explain-details">
+                                                <span>{{ exersicesField[item.field - 1] }}</span>
+                                            </div>
+                                        </div>
+                                        <!-- 补救资源部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.newExercise.repair") }}】</span>
+                                            <div class="item-explain-details">
+                                                <div v-if="item.repair && item.repair.length" style="display: flex; flex-wrap: wrap">
+                                                    <div class="repair-item" v-for="(link, index) in item.repair" :key="index">
+                                                        <img :src="$tools.getFileThum(link.type, link.name)" width="20" />
+                                                        <span class="repair-item-link" @click.stop="onRepairLinkClick(link)">{{ link.name }}</span>
+                                                    </div>
+                                                </div>
+                                                <span v-else>{{ $t("utils.noData") }}</span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <!-- 如果是综合题 则加载子题渲染组件 -->
+                                    <!-- <div v-else>
+                                        <BaseChild :children="item.children"></BaseChild>
+                                    </div> -->
+                                </div>
+                            </transition>
+                            <!-- 底部题目操作栏 -->
+                            <div class="item-tools">
+                                <span class="item-tools-info">{{ $t("evaluation.filter.type") }}:{{ exersicesType[item.type] }}</span>
+                                <span class="item-tools-info">{{ $t("evaluation.filter.diff") }}:{{ exersicesDiff[item.level - 1] }}</span>
+                                <!-- <span class="item-tools-info">{{$t('evaluation.filter.level')}}:{{ exersicesField[item.field - 1] }}</span> -->
+                                <!-- <span class="item-tools-info">{{$t('evaluation.filter.useCount')}}:{{ item.usageCount || 0 }} {{ $t('unit.text4') }}</span> -->
+                                <!-- <span class="item-tools-info">{{$t('evaluation.updateTime')}}:{{ $tools.formatTime(item.createTime)  || 0 }} </span> -->
+                                <Button type="info" :style="{ backgroundColor: checkIdsList.includes(item.id) ? '#bbbbbb' : '#2db7f5' }" @click.stop="onSelectItem(item, index)">
+                                    {{ checkIdsList.includes(item.id) ? $t("evaluation.remove") : $t("evaluation.choose") }}
+                                </Button>
+                            </div>
+                        </div>
+                    </div>
+                </template>
+                </Panel>
+            </Collapse>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        paperList: {
+            type: Array,
+            default: () => {
+                return [];
+            }
+        },
+        inSyllabus: {
+            type: Boolean,
+            default: false
+        },
+        isShowAnalysis: {
+            type: Boolean,
+            default: false
+        },
+    },
+    data () {
+        return {
+            dataLoading: false,
+            // paperList: [],
+            questionList: [],
+            checkList: [],
+            // checkIdsList: [],
+            originQuestionList: [],
+            exersicesType: this.$GLOBAL.EXERCISE_TYPES(),
+			exersicesDiff: this.$GLOBAL.EXERCISE_DIFFS(),
+            exersicesField: this.$GLOBAL.EXERCISE_LEVELS(),
+			collapseList: [],
+        }
+    },
+    computed: {
+        checkIdsList() {
+            let ids = this.checkList.map(item => item.id) || []
+            return ids
+        },
+    },
+    methods: {
+        async onPaperClick(paperId) {
+            if (!paperId.length) return
+            this.dataLoading = true
+            this.questionList = []
+            let paper = this.paperList.find(i => i.id === paperId[0])
+            let fullPaperJson = await this.$evTools.getFullPaper(paper)
+            this.questionList = fullPaperJson.item
+            this.originQuestionList = this._.cloneDeep(fullPaperJson.item)
+            this.questionList.forEach(i => {
+                i.question = i.question.replace(/<[^>]+>/g, "")
+            })
+            window.MathJax.startup.promise.then(() => {
+                window.MathJax.typesetPromise([this.$refs.mathJaxContainer])
+            })
+            this.dataLoading = false
+        },
+        /**
+         * 题干展开与收缩
+         * @param index
+         * @param id
+         */
+        onQuestionToggle(index, id, e) {
+            console.log(e);
+            let curClassName = e.target.className;
+            if (curClassName === "item-tools" || curClassName === "richText-video" || curClassName === "richText-audio") return;
+            e.stopPropagation();
+            let listIndex = this.collapseList.indexOf(index);
+            if (listIndex > -1) {
+                this.collapseList.splice(listIndex, 1);
+            } else {
+                this.collapseList.push(index);
+                let path = this.$tools.composedPath(e);
+                let exerciseItemDom = path.filter((i) => i.className === "exercise-item");
+                if (exerciseItemDom.length) {
+                    this.$emit("pageScroll", exerciseItemDom[0].offsetTop);
+                    exerciseItemDom[0].style.border = "2px solid #2db7f5";
+                    setTimeout(() => {
+                        exerciseItemDom[0].style.border = "2px solid transparent";
+                    }, 2000);
+                }
+            }
+            this.$emit("toggleChange", this.collapseList);
+        },
+        onSelectItem(item, index) {
+            let findIndex = this.checkList.findIndex(i => i.id === item.id)
+            if (findIndex > -1) {
+                this.checkList.splice(findIndex, 1)
+                // this.checkIdsList.splice(findIndex, 1)
+            } else {
+                let newItem = this.originQuestionList.find(i => i.id === item.id)
+                newItem.score = 0
+                this.checkList.push(newItem)
+                // this.checkIdsList.push(newItem.id)
+            }
+            this.$emit("on-question-change", this.checkList, 0);
+            console.log(this.checkList);
+            console.log(item);
+        },
+        /* 补救资源点击事件 */
+        onRepairLinkClick(link) {
+            window.open(/^(http:|https:)/i.test(link.blobUrl) ? link.blobUrl : "http://" + link.blobUrl);
+        },
+    },
+}
+</script>
+
+<style src="./ExerciseList.less" lang="less" scoped></style>
+<style lang="less">
+.paper-item-picker-container {
+    // min-height: 400px;
+    .ivu-collapse {
+        border: none;
+    }
+    .ivu-collapse-header {
+        height: 50px !important;
+        line-height: 50px !important;
+    }
+
+    .ivu-collapse-content {
+        padding: 0 45px;
+    }
+
+    .question-item {
+        margin: 10px 0;
+        display: flex;
+        justify-content: space-between;
+        border: 1px dashed #ccc;
+        padding: 10px;
+        cursor: pointer;
+    }
+
+    .question-item-active {
+        background: #42a676;
+        color: #fff;
+    }
+}
+</style>

+ 83 - 0
TEAMModelOS/ClientApp/src/components/evaluation/SyllabusPicker.less

@@ -0,0 +1,83 @@
+.syllabus-tree-main {
+    width: 100%;
+    height: 100%;
+    padding-left: 20px;
+
+    .el-tree {
+        background: transparent;
+        // color: #fff;
+        padding-top: 10px;
+        padding-bottom: 100px;
+
+        .ivu-tooltip-inner {
+            max-width: none;
+            font-size: 12px;
+        }
+    }
+
+    .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
+        background-color: var(--active-item-start) !important;
+    }
+
+    .el-tree-node__content {
+        height: 40px;
+        padding-left: 0 !important;
+
+        &:hover {
+            height: 40px;
+            background: var(--hover-text-color);
+        }
+
+        .el-tree-node__expand-icon {
+            padding: 4px 6px;
+        }
+    }
+
+    .el-tree-node {
+        &:focus {
+            &>.el-tree-node__content {
+                background: var(--active-item-start);
+            }
+        }
+    }
+
+    .el-tree__empty-block {
+        display: none;
+    }
+}
+
+.custom-tree-node {
+    width: 95%;
+    height: 100%;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    .tree-node-lable {
+        width: 100%;
+
+        .ivu-icon {
+            margin-left: 10px;
+            font-size: 16px;
+            color: #7d7d7d;
+        }
+    }
+
+
+}
+
+.ques-num {
+    padding-right: 10px;
+    color: rgb(115, 115, 115);
+}
+
+/* .custom-tree-tools {
+    position: absolute;
+    right: 0;
+
+    .ivu-icon {
+        margin-right: 10px;
+        color: var(--normal-icon-color);
+    }
+} */

+ 363 - 0
TEAMModelOS/ClientApp/src/components/evaluation/SyllabusPicker.vue

@@ -0,0 +1,363 @@
+<template>
+    <div class="ev-cp-list-container syllabus-tree-main" style="width: 100%; margin: 0 auto">
+        <Loading :top="100" v-show="dataLoading" hideMask></Loading>
+        <EmptyData v-if="!treeData.length"></EmptyData>
+        <div v-else style="display: flex; height: 100%;">
+            <div style="width: 30%; height: 100%; margin-right: 20px;">
+                <vuescroll>
+                    <el-tree ref="tree" :data="treeData" :props="defaultProps" class="tree" node-key="id" check-on-click-node accordion highlight-current @node-click="onNodeClick" :expand-on-click-node="false">
+                        <div class="custom-tree-node" slot-scope="{ node, data }">
+                            <span class="tree-node-lable">
+                                <span class="text-cut" style="width: 60%;display: inline-block;vertical-align: bottom;" :title="data.title">
+                                    {{ data.title }}
+                                </span>
+                            </span>
+                            <span class="ques-num">
+                                {{ $t('evaluation.index.item') }}:{{ data.quesList.length }}{{ $t('evaluation.paperPickTip2')}}
+                            </span>
+                        </div>
+                    </el-tree>
+                </vuescroll>
+            </div>
+            <div style="width: 70%; height: 100%;" ref="mathJaxContainer">
+                <vuescroll>
+                    <div v-if="questionList.length" class="cp-content-wrap">
+                        <div :class="['cp-exercise-item']" v-for="(item, index) in questionList" :key="index">
+                            <!-- 题干部分 -->
+                            <div class="item-question" @click="onQuestionToggle(index, item.id, $event)">
+                                <div>
+                                    <!-- <Tag>{{ exersicesType[item.type] }}</Tag> -->
+                                    <div class="item-question-order">{{ index + 1 }} :</div>
+                                    <div class="item-question-text" v-html="item.question"></div>
+                                </div>
+                                <!-- <span class="item-btn-toggle print-hidden">
+                                    <p v-if="checkIdsList.includes(item.id)" @click.stop="onPrintItem($event, index)">{{ $t("evaluation.downloadQuestionPDF") }}</p>
+                                    <Icon :type="checkIdsList.includes(item.id) ? 'ios-arrow-dropup' : 'ios-arrow-dropdown'" />
+                                </span> -->
+                            </div>
+                            <!-- 选项部分 -->
+                            <div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options" @click="onQuestionToggle(index, item.id, $event)">
+                                <div class="item-option-content">
+                                    <div class="item-option-order">
+                                        <!-- {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} : -->
+                                        {{ option.code }} :
+                                    </div>
+                                    <div class="item-option-text" v-html="option.value"></div>
+                                </div>
+                            </div>
+                            <div class="exercise-item-children" v-if="item.children.length">
+                                <BaseChild :parentIndex="index" :children="item.children" inBank></BaseChild>
+                            </div>
+                            <transition name="slide" v-if="item.type !== 'compose'">
+                                <div v-if="collapseList.includes(questionList.indexOf(item))" class="toggle-area">
+                                    <p v-if="inSyllabus" class="print-hidden" style="cursor: pointer; text-decoration: underline; color: #4eb0e8; margin-left: 5px" @click.stop="onPrintItem($event, index)">
+                                        {{ $t("evaluation.downloadQuestionPDF") }}
+                                    </p>
+                                    <div>
+                                        <!-- 答案展示部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.answer") }}】</span>
+                                            <div class="item-explain-details">
+                                                <!-- 问答题答案 -->
+                                                <div v-if="item.type === 'subjective' || item.type === 'complete' || item.type === 'connector' || item.type === 'correct'">
+                                                    <span v-for="(answer, index) in item.answer" :key="index" v-html="item.answer.length ? answer : $t('utils.noData')"></span>
+                                                </div>
+                                                <!-- 问答题答案 -->
+                                                <div v-else-if="item.type === 'judge'">
+                                                    <span>{{ item.answer.length ? (item.answer[0] === "A" ? $t("evaluation.isTrue") : $t("evaluation.isFalse")) : $t("utils.noData") }}</span>
+                                                </div>
+                                                <!-- 其余题型答案 -->
+                                                <div v-else>
+                                                    <span :class="[item.type === 'complete' ? 'item-answer-item' : '']" v-for="(answer, index) in item.answer" :key="index">{{ answer }}</span>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <!-- 解析部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.explain") }}】</span>
+                                            <div class="item-explain-details">
+                                                <span v-html="item.explain || $t('utils.noData')"></span>
+                                            </div>
+                                        </div>
+                                        <!-- 知识点部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.knowledgePoints") }}】</span>
+                                            <div class="item-explain-details">
+                                                <span v-if="!item.knowledge || !item.knowledge.length">{{ $t("utils.noData") }}</span>
+                                                <div v-else>
+                                                    <span v-for="(point, pointIndex) in item.knowledge" class="item-point-tag" :key="pointIndex">
+                                                        {{ point }}
+                                                    </span>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <!-- 认知层次部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title" :style="{ color: isShowAnalysis ? '#099209' : '#10abe7' }">【{{ $t("evaluation.field") }}】</span>
+                                            <div class="item-explain-details">
+                                                <span>{{ exersicesField[item.field - 1] }}</span>
+                                            </div>
+                                        </div>
+                                        <!-- 补救资源部分 -->
+                                        <div class="item-explain">
+                                            <span class="explain-title">【{{ $t("evaluation.newExercise.repair") }}】</span>
+                                            <div class="item-explain-details">
+                                                <div v-if="item.repair && item.repair.length" style="display: flex; flex-wrap: wrap">
+                                                    <div class="repair-item" v-for="(link, index) in item.repair" :key="index">
+                                                        <img :src="$tools.getFileThum(link.type, link.name)" width="20" />
+                                                        <span class="repair-item-link" @click.stop="onRepairLinkClick(link)">{{ link.name }}</span>
+                                                    </div>
+                                                </div>
+                                                <span v-else>{{ $t("utils.noData") }}</span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <!-- 如果是综合题 则加载子题渲染组件 -->
+                                    <!-- <div v-else>
+                                        <BaseChild :children="item.children"></BaseChild>
+                                    </div> -->
+                                </div>
+                            </transition>
+                            <!-- 底部题目操作栏 -->
+                            <div class="item-tools">
+                                <span class="item-tools-info">{{ $t("evaluation.filter.type") }}:{{ exersicesType[item.type] }}</span>
+                                <span class="item-tools-info">{{ $t("evaluation.filter.diff") }}:{{ exersicesDiff[item.level - 1] }}</span>
+                                <!-- <span class="item-tools-info">{{$t('evaluation.filter.level')}}:{{ exersicesField[item.field - 1] }}</span> -->
+                                <!-- <span class="item-tools-info">{{$t('evaluation.filter.useCount')}}:{{ item.usageCount || 0 }} {{ $t('unit.text4') }}</span> -->
+                                <!-- <span class="item-tools-info">{{$t('evaluation.updateTime')}}:{{ $tools.formatTime(item.createTime)  || 0 }} </span> -->
+                                <Button type="info" :style="{ backgroundColor: checkIdsList.includes(item.id) ? '#bbbbbb' : '#2db7f5' }" @click.stop="onSelectItem(item, index)">
+                                    {{ checkIdsList.includes(item.id) ? $t("evaluation.remove") : $t("evaluation.choose") }}
+                                </Button>
+                            </div>
+                        </div>
+                    </div>
+                    <EmptyData v-else style="margin-top: 120px" :textContent="$t('evaluation.addTip5')"></EmptyData>
+                </vuescroll>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        treeOrigin: {
+            type: Array,
+            default: () => {
+                return []
+            }
+        },
+        inSyllabus: {
+            type: Boolean,
+            default: false
+        },
+        isShowAnalysis: {
+            type: Boolean,
+            default: false
+        },
+    },
+    data() {
+        return {
+            dataLoading: false,
+            // treeData: [],
+            defaultProps: {
+                children: 'children',
+                label: 'title'
+            },
+            questionList: [],
+            collapseList: [],
+            checkList: [],
+            exersicesType: this.$GLOBAL.EXERCISE_TYPES(),
+			exersicesDiff: this.$GLOBAL.EXERCISE_DIFFS(),
+            exersicesField: this.$GLOBAL.EXERCISE_LEVELS(),
+        }
+    },
+    mounted() {
+    },
+    computed: {
+        checkIdsList() {
+            let ids = this.checkList.map(item => item.id) || []
+            return ids
+        },
+        treeData() {
+            let arr = this._.cloneDeep(this.treeOrigin)
+            this.getQuesNum(arr)
+            return arr
+        },
+    },
+    watch: {
+        treeData: {
+            handler(n, o) {
+                if(n.length) {
+                    this.$nextTick().then(() => {
+                        this.$refs.tree.setCurrentKey(n[0].id)
+                        this.onNodeClick(n[0])
+                    })
+                }
+            },
+            deep: true,
+        },
+    },
+    methods: {
+        onNodeClick(data, node) {
+            console.log(data)
+            this.onNodeClick(data)
+            // this.questionList = data.quesList
+            /* if (!data) return
+            this.curNode = node
+            this.curData = data */
+        },
+        /**
+         * 题干展开与收缩
+         * @param index
+         * @param id
+         */
+        onQuestionToggle(index, id, e) {
+            console.log(e);
+            let curClassName = e.target.className;
+            if (curClassName === "item-tools" || curClassName === "richText-video" || curClassName === "richText-audio") return;
+            e.stopPropagation();
+            let listIndex = this.collapseList.indexOf(index);
+            if (listIndex > -1) {
+                this.collapseList.splice(listIndex, 1);
+            } else {
+                this.collapseList.push(index);
+                let path = this.$tools.composedPath(e);
+                let exerciseItemDom = path.filter((i) => i.className === "exercise-item");
+                if (exerciseItemDom.length) {
+                    this.$emit("pageScroll", exerciseItemDom[0].offsetTop);
+                    exerciseItemDom[0].style.border = "2px solid #2db7f5";
+                    setTimeout(() => {
+                        exerciseItemDom[0].style.border = "2px solid transparent";
+                    }, 2000);
+                }
+            }
+            this.$emit("toggleChange", this.collapseList);
+        },
+        onSelectItem(item, index) {
+            let findIndex = this.checkList.findIndex(i => i.id === item.id)
+            if (findIndex > -1) {
+                this.checkList.splice(findIndex, 1)
+            } else {
+                let newItem = this.questionList.find(i => i.id === item.id)
+                newItem.score = 0
+                this.checkList.push(newItem)
+            }
+            this.$emit("on-question-change", this.checkList, 0);
+        },
+        /* 补救资源点击事件 */
+        onRepairLinkClick(link) {
+            window.open(/^(http:|https:)/i.test(link.blobUrl) ? link.blobUrl : "http://" + link.blobUrl);
+        },
+        // 处理树中题目数量
+        getQuesNum(arr) {
+            arr.forEach(item => {
+                if(item.children.length) {
+                    this.getQuesNum(item.children)
+                }
+                item.quesList = item.rnodes.filter(nodes => nodes.type === 'item') || []
+            })
+        },
+        /* 点击某个节点 */
+        async onNodeClick(data) {
+            // 如果当前节点有关联试题资源 则需要去拿到试题完整信息 来给title赋值 保证为最新数据
+            if (data.quesList.length) {
+                this.dataLoading = true
+                let itemNodeArr = data.quesList
+                if (itemNodeArr.length) {
+                    let sas = await this.$evTools.getBlobPrivateSas(itemNodeArr[0].cntr)
+                    let promiseArr = []
+                    // 获取关联的试题数据
+                    itemNodeArr.forEach(async item => {
+                        promiseArr.push(new Promise(async (r, j) => {
+                            let indexJsonFile = await this.$tools.getFile(this.$evTools.getBlobHost() + '/' + item.cntr + item.link + sas)
+                            let jsonData = JSON.parse(indexJsonFile)
+                            jsonData.exercise.question = jsonData.item[0].question
+                            jsonData.exercise.option = jsonData.item[0].option
+                            jsonData.exercise.id = jsonData.id
+                            jsonData.exercise.pid = jsonData.pid
+                            jsonData.exercise = await this.$evTools.doAddHost(jsonData.exercise, null, null, true)
+                            r(jsonData.exercise)
+                        }))
+                    })
+                    Promise.all(promiseArr).then(result => {
+                        this.questionList = result
+                        window.MathJax.startup.promise.then(() => {
+                            window.MathJax.typesetPromise([this.$refs.mathJaxContainer])
+                        })
+                        this.dataLoading = false
+                    })
+                } else {
+                    this.questionList = []
+                }
+            } else {
+                this.questionList = []
+            }
+            console.log('当前点击节点数据 ==== ', data.title, data.rnodes)
+        },
+    }
+}
+</script>
+
+<style lang="less" src="./ExerciseList.less" scoped></style>
+<style lang="less" src="./SyllabusPicker.less"></style>
+<style scoped>
+.syllabus-tree-main .cp-exercise-item {
+    /* margin-top: 10px; */
+}
+.tree /deep/ .el-tree-node {
+  position: relative;
+  padding-left: 16px;
+}
+
+.tree /deep/ .el-tree-node__children {
+  padding-left: 16px;
+}
+
+.tree /deep/ .el-tree-node :last-child:before {
+  height: 38px;
+}
+
+.tree /deep/ .el-tree > .el-tree-node:before {
+  border-left: none;
+}
+
+.tree-container /deep/ .el-tree > .el-tree-node:after {
+  border-top: none;
+}
+
+.tree /deep/ .el-tree-node:before {
+  content: "";
+  left: -4px;
+  position: absolute;
+  right: auto;
+  border-width: 1px;
+}
+
+.tree /deep/ .el-tree-node:after {
+  content: "";
+  left: -4px;
+  position: absolute;
+  right: auto;
+  border-width: 1px;
+}
+
+.tree /deep/ .el-tree-node:before {
+  border-left: 1px dashed #bebebe;
+  bottom: 0px;
+  height: 100%;
+  top: -20px;
+  width: 1px;
+}
+
+.tree /deep/ .el-tree-node:after {
+  border-top: 1px dashed #bebebe;
+  height: 20px;
+  top: 20px;
+  width: 12px;
+}
+
+.tree /deep/ .ivu-tooltip-popper {
+  font-size: 12px !important;
+}
+</style>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -136,7 +136,7 @@
 <script>
 import blobTool from '@/utils/blobTool.js'
 import AutoCreate from '@/view/learnactivity/AutoCreateNew.vue'
-import ManualCreate from '@/view/learnactivity/ManualCreate.vue'
+import ManualCreate from '@/view/learnactivity/ManualCreateNew.vue'
 import BaseImport from '../components/BaseImport.vue'
 import TestPaper from './TestPaper.vue'
 

+ 634 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/ManualCreateNew.vue

@@ -0,0 +1,634 @@
+<template>
+    <div style="height: 100%; position: relative">
+		<Poptip padding="0px 0px" offset="10" placement="top-end" width="300" trigger="hover" :class="shoppingCarClass">
+			<Badge type="primary" :count="shoppingQuestionList.length" show-zero :offset="[-3, -3]" @mouseenter.native="changeActive($event)" @mouseleave.native="removeActive($event)">
+				<Icon custom="iconfont icon-sp-car" color="#05C19C" size="50" />
+			</Badge>
+			<div slot="content">
+				<div class="shopping-car-detail">
+					<p class="shopping-car-detail-title">
+						{{ $t("evaluation.createPaper.total") }}
+                        <span style="margin: 0px 5px">{{ shoppingQuestionList.length }}</span>
+                        {{ $t("evaluation.createPaper.nums") }}
+					</p>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.single") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('single')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.single }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.multiple") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('multiple')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.multiple }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.judge") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('judge')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.judge }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.complete") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('complete')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.complete }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.subjective") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('subjective')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.subjective }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.connector") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('connector')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.connector }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.correct") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('correct')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.correct }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<div class="shopping-car-detail-item">
+						<span class="question-type">{{ $t("evaluation.compose") }}:</span>
+						<Progress stroke-color="#6bdfc3" :percent="getPercent('compose')" :stroke-width="15" style="width: 165px; vertical-align: top; padding-top: 2px" hide-info />
+						<span class="question-num">{{ groupList.compose }}{{ $t("evaluation.createPaper.spc") }}</span>
+					</div>
+					<p class="shopping-car-detail-bottom" @click="goToPreview">{{ $t("evaluation.createPaper.goDetails") }}</p>
+				</div>
+			</div>
+		</Poptip>
+		<vuescroll ref="manualScroll">
+			<div class="manual-filter-wrap">
+				<Col style="width: 100%">
+                    <div class="manual-filter-item">
+                        <span class="manual-filter-label">{{ $t('learnActivity.mgtScEv.ftType') }}</span>
+                        <Select v-model="manualFilter.source" size="small" style="display: inline-block; width: 150px" @on-change="checkAll($event, 'source')">
+                            <Option value="quesBank">{{ $t('evaluation.cpTip1') }}</Option>
+                            <Option value="paper">{{ $t('evaluation.cpTip2') }}</Option>
+                            <Option value="syllabus">{{ $t('evaluation.cpTip3') }}</Option>
+                        </Select>
+                    </div>
+					<div class="manual-filter-item" v-if="!isSchool">
+						<span class="manual-filter-label">{{ $t("evaluation.filter.origin") }}:</span>
+						<CheckboxGroup v-model="manualFilter.code" style="display: inline-block" @on-change="checkAll($event, 'origin')">
+							<Checkbox :label="$store.state.userInfo.TEAMModelId" v-if="!isSchool">{{ $t('cusMgt.private') }}</Checkbox>
+							<Checkbox :label="$store.state.userInfo.schoolCode" :disabled="!hasSchool">{{ $t('cusMgt.school') }}</Checkbox>
+						</CheckboxGroup>
+					</div>
+					<div class="manual-filter-item" v-if="isSchool">
+						<span class="manual-filter-label">{{ $t("evaluation.filter.range") }}:</span>
+						<Tag color="blue">{{ condName.periodName }}</Tag>
+						<Tag color="geekblue">{{ condName.subjectName }}</Tag>
+						<Tag color="purple">{{ condName.gradeName }}</Tag>
+					</div>
+					<div class="manual-filter-item evaluation-attr-form light-iview-select" v-show="isPeriod && !isSchool">
+						<span class="manual-filter-label">{{ $t("evaluation.filter.period") }}:</span>
+						<Select v-model="manualFilter.periodCode[0]" size="small" style="display: inline-block; width: 140px" @on-change="checkAll($event, 'periodCode')">
+							<Option v-for="(item, index) in schoolPeriod" :value="item.id" :key="index">{{ item.name }}</Option>
+						</Select>
+						<span class="manual-filter-label" style="margin-left: 30px">{{ $t("evaluation.filter.subject") }}:</span>
+						<Select v-model="manualFilter.subjectCode[0]" size="small" style="display: inline-block; width: 140px; margin-right: 30px" @on-change="checkAll($event, 'subjectCode')">
+							<Option v-for="(item, index) in subjectList" :value="item.id" :key="index">{{ item.name }}</Option>
+						</Select>
+					</div>
+					<div class="manual-filter-item" v-show="manualFilter.source === 'quesBank'">
+						<span class="manual-filter-label">{{ $t("evaluation.filter.type") }}:</span>
+						<CheckboxGroup v-model="manualFilter.type" border style="display: inline-block" @on-change="checkAll($event, 'type')">
+							<Checkbox label="all">{{ $t("evaluation.filter.all") }}</Checkbox>
+							<Checkbox label="single">{{ $t("evaluation.single") }}</Checkbox>
+							<Checkbox label="multiple">{{ $t("evaluation.multiple") }}</Checkbox>
+							<Checkbox label="judge">{{ $t("evaluation.judge") }}</Checkbox>
+							<Checkbox label="complete">{{ $t("evaluation.complete") }}</Checkbox>
+							<Checkbox label="subjective">{{ $t("evaluation.subjective") }}</Checkbox>
+							<Checkbox label="connector">{{ $t("evaluation.connector") }}</Checkbox>
+							<Checkbox label="correct">{{ $t("evaluation.correct") }}</Checkbox>
+							<Checkbox label="compose" v-if="!isMarkModel">{{ $t("evaluation.compose") }}</Checkbox>
+						</CheckboxGroup>
+					</div>
+					<div class="manual-filter-item" v-show="manualFilter.source === 'quesBank'">
+						<span class="manual-filter-label">{{ $t("evaluation.filter.diff") }}:</span>
+						<CheckboxGroup v-model="manualFilter.level" border style="display: inline-block" @on-change="checkAll($event, 'level')">
+							<Checkbox label="all">{{ $t("evaluation.filter.all") }}</Checkbox>
+							<Checkbox v-for="(item, index) in exersicesDiff" :key="index" :label="index + 1">{{ item }}</Checkbox>
+						</CheckboxGroup>
+					</div>
+					<div class="manual-filter-item" v-show="manualFilter.source === 'quesBank'">
+						<span class="manual-filter-label">{{ $t("evaluation.filter.level") }}:</span>
+						<Select v-model="manualFilter.field" size="small" style="display: inline-block; width: 100px" @on-change="checkAll($event, 'field')">
+							<Option value="all">{{ $t("evaluation.filter.all") }}</Option>
+							<Option v-for="(item, index) in fieldList" :value="index" :key="index">{{ item }}</Option>
+						</Select>
+						<span class="manual-filter-label" style="margin-left: 20px">{{ $t("evaluation.knowledgePoints") }}:</span>
+						<div style="display: inline-flex; align-items: center">
+							<Tag color="success" v-for="(item, index) in relatePoints" :key="item" :name="item" closable @on-close="handleClosePoint(index)">{{ item }}</Tag>
+							<Icon type="md-add-circle" size="18" color="#888888" style="cursor: pointer; margin-left: 5px" @click="selectPointsModal = true" />
+						</div>
+					</div>
+					<div class="manual-filter-item" v-show="manualFilter.source === 'paper'">
+						<span class="manual-filter-label">{{ $t('evaluation.tag') }}:</span>
+						<CheckboxGroup v-model="manualFilter.tag" border style="display: inline-block" @on-change="checkAll($event, 'tag')">
+							<Checkbox label="all">{{ $t("evaluation.filter.all") }}</Checkbox>
+							<Checkbox v-for="(item, index) in tags" :key="index" :label="item">{{ item }}</Checkbox>
+						</CheckboxGroup>
+					</div>
+					<div class="manual-filter-item" v-show="manualFilter.source === 'syllabus'">
+						<span class="manual-filter-label">{{ $t('selflearn.choose.book') }}:</span>
+                        <template v-if="volumeList.length">
+                            <RadioGroup v-model="manualFilter.volume" border style="display: inline-block" @on-change="checkAll($event, 'volume')">
+                                <Radio v-for="(item, index) in volumeList" :key="index" :label="index + 1">{{ item.name }}</Radio>
+                            </RadioGroup>
+                        </template>
+                        <span v-else>{{ $t('assessment.no') }}</span>
+					</div>
+				</Col>
+			</div>
+			<div class="question-list-wrap">
+				<!-- <Loading :top="100" v-show="isLoading"></Loading> -->
+				<ExerciseList v-if="manualFilter.source === 'quesBank'" ref="exList" :propsList="questionList" @pageScroll="doScroll" @on-question-change="selectQuestion"></ExerciseList>
+				<BasePaperItemPicker v-else-if="manualFilter.source === 'paper'" ref="paperItemList" :paperList="paperList" @on-question-change="selectQuestion" />
+				<SyllabusPicker v-else-if="manualFilter.source === 'syllabus'" ref="syllabusTree" :treeOrigin="treeOrigin" @on-question-change="selectQuestion" />
+                <EmptyData style="margin-top: 120px" v-if="!isLoading && !questionList.length && !paperList.length && !treeOrigin.length" :textContent="$t('evaluation.addTip5')"></EmptyData>
+				<!-- <div class="page-wrap">
+                    <Page :current.sync="pageNum" :total="totalNum" show-total :page-size="pageSize" size="small" show-sizer @on-change="getCurrentPageData" />
+                </div> -->
+			</div>
+        </vuescroll>
+		<Modal v-model="selectPointsModal" :title="$t('evaluation.newExercise.choosePoint')" ref="pointRef" footer-hide width="600px" class="related-point-modal" style="z-index: 99999">
+			<BasePoints v-if="selectPointsModal" :period="manualFilter.periodCode[0]" :subject="manualFilter.subjectCode[0]" @onCheckChange="onCheckChange" @onCancel="selectPointsModal = false" :points="relatePoints" scope="school"></BasePoints>
+			<!-- <div slot="footer">
+				<Button type="text" @click="selectPointsModal = false">{{$t('evaluation.cancel')}}</Button>
+				<Button type="primary" @click="selectPointsModal = false">{{$t('evaluation.confirm')}}</Button>
+			</div> -->
+		</Modal>
+    </div>
+</template>
+
+<script>
+import ExerciseList from "@/components/evaluation/ExerciseList.vue";
+import BasePaperItemPicker from "@/components/evaluation/BasePaperItemPicker.vue";
+import SyllabusPicker from "@/components/evaluation/SyllabusPicker.vue";
+export default {
+    components: {
+        ExerciseList, BasePaperItemPicker, SyllabusPicker
+    },
+    props: {
+        isMarkModel: {
+            type: Boolean,
+            default: false
+        },
+        selQue: {
+            type: Array,
+            default: () => {
+                return [];
+            }
+        },
+        gradeCode: {
+            type: Array,
+            default: () => []
+        },
+        subjectCode: {
+            type: String,
+            default: ""
+        },
+        periodCode: {
+            type: String,
+            default: ""
+        }
+    },
+    data() {
+        return {
+            condName: {
+                periodName: "",
+                subjectName: "",
+                gradeName: ""
+            },
+			shoppingCarClass: "question-shopping-car",
+			shoppingQuestionList: [],
+            groupList: {
+                single: 0,
+                multiple: 0,
+                judge: 0,
+                complete: 0,
+                subjective: 0,
+                connector: 0,
+                correct: 0,
+                compose: 0
+            },
+            manualFilter: {
+                source: 'quesBank',
+                periodCode: [],
+                code: [],
+                points: ["all"],
+                type: ["all"],
+                level: ["all"],
+                subjectCode: [],
+                gradeIds: [],
+                scoped: "school",
+                field: "all",
+                tag: ["all"],
+                volume: '',
+            },
+            schoolPeriod: [],
+            showQuestion: [],
+            subjectList: [],
+			exersicesDiff: this.$GLOBAL.EXERCISE_DIFFS(),
+            fieldList: [this.$t("evaluation.level1"), this.$t("evaluation.level2"), this.$t("evaluation.level3"), this.$t("evaluation.level4"), this.$t("evaluation.level5"), this.$t("evaluation.level6")],
+            questionList: [],
+            paperList: [],
+            originList: [],
+            tags: [],
+            volumeList: [],
+            treeOrigin: [],
+            isLoading: false,
+            selectPointsModal: false,
+            relatePoints: [],
+        }
+    },
+    mounted() {
+        console.error(this.selQue);
+        if (this.selQue.length) {
+            let data = this.selQue;
+            this.shoppingQuestionList = JSON.parse(JSON.stringify(data));
+            let groupResult = this.$jsFn.groupBy(data, "type");
+            this.groupList = { ...this.groupQuestion };
+            for (let i = 0; i < groupResult.length; i++) {
+                this.groupList[groupResult[i][0].type] = groupResult[i].length;
+            }
+        }
+        this.manualFilter.code = this.isSchool ? [this.$store.state.userInfo.schoolCode] : [this.$store.state.userInfo.TEAMModelId];
+        this.getSchoolBaseInfo().then((res) => {
+            if (res === "noSchool") {
+                this.queryQuestionByPage();
+            } else {
+                this.schoolPeriod = res.period;
+                if (this.isSchool && this.periodCode && this.subjectCode) {
+                    this.manualFilter.periodCode = [this.periodCode];
+                    let curPeriod = this.schoolPeriod.find((i) => i.id === this.periodCode);
+                    this.subjectList = curPeriod.subjects;
+                    this.gradeList = curPeriod.grades;
+                    this.manualFilter.subjectCode = [this.subjectCode];
+                    // 获取学段和科目名称
+                    (this.condName.periodName = curPeriod.name), (this.condName.subjectName = curPeriod.subjects.find((i) => i.id === this.subjectCode).name);
+                }
+                console.log(this.manualFilter);
+                if (!this.isSchool) {
+                    this.queryQuestionByPage();
+                }
+            }
+            console.log("获取学校数据", this.subjectList);
+        });
+        this.$EventBus.$off("onPaperItemChange");
+        this.$EventBus.$on("onPaperItemChange", (data) => {
+            console.log("eventBus", data);
+            this.shoppingQuestionList = JSON.parse(JSON.stringify(data));
+            this.$nextTick(() => {
+                if (this.$refs.exList) {
+                    this.$refs.exList.selectList = JSON.parse(JSON.stringify(data));
+                }
+                if(this.$refs.paperItemList) {
+                    this.$refs.paperItemList.checkList = JSON.parse(JSON.stringify(data));
+                }
+                if(this.$refs.syllabusTree) {
+                    this.$refs.syllabusTree.checkList = JSON.parse(JSON.stringify(data));
+                }
+            });
+            let groupResult = this.$jsFn.groupBy(data, "type");
+            this.groupList = { ...this.groupQuestion };
+            for (let i = 0; i < groupResult.length; i++) {
+                this.groupList[groupResult[i][0].type] = groupResult[i].length;
+            }
+        });
+    },
+    computed: {
+        //判断是否为校本题库
+        isPeriod() {
+            return this.manualFilter.code.indexOf(this.$store.state.userInfo.schoolCode) > -1;
+        },
+        isSchool() {
+            return this.$route.name === "newSchoolPaper";
+        },
+        hasSchool() {
+            return this.$store.state.userInfo.hasSchool;
+        },
+        getPercent(type) {
+            return (type) => {
+                return this.shoppingQuestionList.length ? (this.groupList[type] * 100) / this.shoppingQuestionList.length : 0;
+            };
+        }
+    },
+    watch: {
+        periodCode: {
+            handler(n) {
+                if (n) {
+                    this.manualFilter.periodCode[0] = n;
+                    let curPeriod = this.schoolPeriod.length ? this.schoolPeriod.find((i) => i.id === n) : null;
+                    if (curPeriod) {
+                        this.subjectList = curPeriod.subjects || [];
+                        this.gradeList = curPeriod.grades || [];
+                        this.condName.periodName = this.schoolPeriod.find((i) => i.id === n).name;
+                    }
+                }
+            }
+        },
+        subjectCode: {
+            handler(n, o) {
+                if (n) {
+                    this.manualFilter.subjectCode[0] = n;
+                    let curSubject = this.subjectList.find((i) => i.id === n);
+                    if (curSubject) {
+                        this.condName.subjectName = curSubject.name;
+                        this.queryQuestionByPage("subject");
+                    }
+                }
+            }
+        },
+        gradeCode: {
+            handler(n, o) {
+                console.error(n);
+                if (n) {
+                    this.manualFilter.gradeIds = n.length ? n.map((i) => i + "") : [];
+                    this.condName.gradeName = n.length ? n.map((i) => this.gradeList[i]).join(",") : this.$t("evaluation.filter.allGrades");
+                    this.queryQuestionByPage("grade");
+                }
+            },
+            deep: true
+        }
+    },
+    methods: {
+        goToPreview() {
+            this.$emit("goToPreview");
+        },
+        changeActive(e) {
+            this.shoppingCarClass = "question-shopping-car animated pulse";
+        },
+        removeActive() {
+            this.shoppingCarClass = "question-shopping-car";
+        },
+        /**
+         * 选择全部逻辑
+         * @param data:选中数据
+         * @param key:字段名
+         */
+        checkAll(data, key) {
+            console.log("点击了筛选区域");
+            // 切换学段
+            if (key === "periodCode" && this.manualFilter.periodCode[0]) {
+                console.log(this.manualFilter.periodCode);
+                console.log(this.schoolPeriod);
+                this.subjectList = this.schoolPeriod.length ? this.schoolPeriod.filter((i) => i.id === this.manualFilter.periodCode[0])[0].subjects : [];
+                this.manualFilter.subjectCode = this.schoolPeriod.length ? [this.subjectList[0].id] : [];
+                this.queryQuestionByPage();
+                return;
+            }
+            // 切换科目
+            if (key === "subjectCode") {
+                this.queryQuestionByPage();
+                return;
+            }
+
+            if (key === "origin") {
+                this.queryQuestionByPage();
+                return;
+            }
+
+            if (key === "field") {
+                this.queryQuestionByPage();
+                return;
+            }
+
+            if(key === "volume") {
+                this.getTreeByVolumeId(this.volumeList[this.manualFilter.volume - 1])
+                return
+            }
+
+            // 切换其余筛选项
+            if (this.manualFilter[key].length !== 1 && this.manualFilter[key].indexOf("all") === 0) {
+                this.manualFilter[key].splice(this.manualFilter[key].indexOf("all"), 1);
+            } else if (this.manualFilter[key].indexOf("all") > 0) {
+                this.manualFilter[key].length = 0;
+                this.$set(this.manualFilter[key], 0, "all");
+            } else if (this.manualFilter[key].length === 0) {
+                this.$set(this.manualFilter[key], 0, "all");
+            }
+            this.pageNum = 1;
+            this.queryQuestionByPage(key);
+        },
+        /* 查询操作 */
+        async queryQuestionByPage(key) {
+            this.isLoading = true;
+            let resultList = [];
+            if (this.manualFilter.code.length > 0) {
+                console.warn("进行了查询", key, this.manualFilter.subjectCode[0]);
+                for (let i = 0; i < this.manualFilter.code.length; i++) {
+                    let code = this.manualFilter.code[i];
+                    let scope = code === this.$store.state.userInfo.TEAMModelId ? "private" : "school";
+                    try {
+                        let data = []
+                        console.log('222222222222', this.manualFilter.source);
+                        if(this.manualFilter.source === 'quesBank') {
+                            data = await this.queryQuestion(scope, code);
+                        } else if(this.manualFilter.source === 'syllabus') {
+                            data = await this.getVolumeList(scope, code);
+                        } else if(this.manualFilter.source === 'paper') {
+                            data = await this.findPaper(scope, code);
+                        }
+                        resultList = resultList.concat(data);
+                    } catch (e) {
+                        console.log(e);
+                    }
+                }
+                if(this.manualFilter.source === 'quesBank') {
+                    this.questionList = resultList;
+                    this.totalNum = this.questionList.length;
+                } else if(this.manualFilter.source === 'syllabus') {
+                    this.treeOrigin = []
+                    this.volumeList = resultList
+                    if(this.volumeList.length) {
+                        this.manualFilter.volume = 1
+                        this.getTreeByVolumeId(this.volumeList[0])
+                    }
+                } else if(this.manualFilter.source === 'paper') {
+                    this.paperList = resultList
+                    this.originList = this._.cloneDeep(resultList)
+                    if (resultList.length > 0) {
+                        this.tags = [...new Set(resultList.map(i => i.tags).flat(1))]
+                    }
+                }
+                if(key === 'source') {
+                    if (this.$refs.exList) {
+                        this.$refs.exList.selectList = JSON.parse(JSON.stringify(this.shoppingQuestionList));
+                    }
+                    if(this.$refs.paperItemList) {
+                        this.$refs.paperItemList.checkList = JSON.parse(JSON.stringify(this.shoppingQuestionList));
+                    }
+                    if(this.$refs.syllabusTree) {
+                        this.$refs.syllabusTree.checkList = JSON.parse(JSON.stringify(this.shoppingQuestionList));
+                    }
+                }
+                this.isLoading = false;
+            } else {
+                this.$Message.warning(this.$t("evaluation.createPaper.noOriginTips"));
+                this.isLoading = false;
+            }
+        },
+        // 访问查询接口
+        queryQuestion(scope, code) {
+            let typeResult = this.deleteAll(this.manualFilter.type)
+            let queryData = {
+                "@DESC": "createTime",
+                code: code,
+                periodId: scope === "school" ? this.deleteAll(this.manualFilter.periodCode) : [],
+                "gradeIds[*]": this.manualFilter.gradeIds,
+                subjectId: scope === "school" ? this.deleteAll(this.manualFilter.subjectCode) : [],
+                level: this.deleteAll(this.manualFilter.level),
+                type: this.isMarkModel ? typeResult.length ? typeResult : ['single','multiple','judge','complete','subjective','connector','correct'] : this.deleteAll(this.manualFilter.type),
+                field: this.manualFilter.field !== "all" ? this.manualFilter.field + 1 : [],
+                scope: scope,
+                "knowledge[*]": this.relatePoints,
+                pid: null
+            }
+            return new Promise((resolve, reject) => {
+                this.$api.newEvaluation.FindExerciseList(queryData).then((res) => {
+                    if (res.items) {
+                        resolve(res.items);
+                    }
+                }).catch((e) => {
+                    reject(e);
+                });
+            });
+        },
+        findPaper(scope, code) {
+            let findParams = {
+                '@DESC': "createTime",
+                'code': code,
+                'gradeIds[*]': this.manualFilter.gradeIds,
+                'periodId': scope === "school" ? this.deleteAll(this.manualFilter.periodCode) : [],
+                'scope': scope,
+                'subjectId': scope === "school" ? this.deleteAll(this.manualFilter.subjectCode) : [],
+                'tags[*]': this.deleteAll(this.manualFilter.tag)
+            }
+            return new Promise((resolve, reject) => {
+                this.$api.learnActivity.FindExamPaper(findParams).then(res => {
+                    if(res.papers) {
+                        res.papers = res.papers.filter(i => !i.qamode)
+                        resolve(res.papers)
+                    }
+                }).catch((e) => {
+                    reject(e);
+                })
+            })
+        },
+        getVolumeList(scope, code) {
+            let findParams = {
+                "scope": scope,
+                "code": code,
+                "periodId": scope === "school" ? this.deleteAll(this.manualFilter.periodCode)[0] : '',
+                "subjectId": scope === "school" ? this.deleteAll(this.manualFilter.subjectCode)[0] : '',
+                // gradeIds: this.manualFilter.gradeIds,
+                "status": 1,
+            }
+            if(this.manualFilter.gradeIds.length) findParams.gradeIds = this.manualFilter.gradeIds.map(item => Number(item))
+            return new Promise((resolve, reject) => {
+                this.$api.syllabus.FindVolumes(findParams).then(res => {
+                    if(!res.error) {
+                        resolve(res.volumes)
+                    }
+                }).catch((e) => {
+                    reject(e);
+                })
+            })
+        },
+        /* 根据册别查询对应课纲树形结构 */
+        getTreeByVolumeId(volume) {
+            this.$api.syllabus.GetTreeByVolume({
+                volumeId: volume.id,
+                volumeCode: volume.code,
+                scope: volume.scope
+            }).then(res => {
+                if (!res.error) {
+                    this.treeOrigin = res.tree.map(i =>{
+                        return i.trees[0]
+                    })
+                } else {
+                    this.$Message.warning(res.error);
+                    this.treeOrigin = []
+                }
+            }).catch(err => {
+                this.treeOrigin = []
+            }).finally(() => {
+                this.isLoading = false
+            })
+        },
+        /* 去除无效值 */
+        deleteAll(data) {
+            if (data.length == 1) {
+                if (data[0] == "all") {
+                    return [];
+                } else {
+                    return data;
+                }
+            } else {
+                return data;
+            }
+        },
+        handleClosePoint(index) {
+            this.relatePoints.splice(index, 1);
+            this.queryQuestionByPage();
+        },
+        /* 页面滚动逻辑 */
+        doScroll(scrollDistance) {
+            this.$nextTick(() => {
+                this.$refs.manualScroll.scrollTo(
+                    {
+                        y: scrollDistance
+                    },
+                    500,
+                    "easeInQuad"
+                );
+            });
+        },
+        /*选择题目||取消选择题目*/
+        async selectQuestion(data, info) {
+            this.groupList = { ...this.groupQuestion };
+            this.shoppingQuestionList = data;
+            this.shoppingCarClass = "question-shopping-car animated heartBeat";
+            setTimeout(() => {
+                this.shoppingCarClass = "question-shopping-car";
+            }, 1000);
+            let groupResult = await this.$jsFn.groupBy(this.shoppingQuestionList, "type");
+            console.log(groupResult);
+            for (let i = 0; i < groupResult.length; i++) {
+                this.groupList[groupResult[i][0].type] = groupResult[i].length;
+            }
+            console.log(this.shoppingQuestionList);
+            console.log(data);
+            this.$emit("selectedQuestion", {
+                questions: this.shoppingQuestionList,
+                item: data
+            });
+        },
+        onCheckChange(val) {
+            this.relatePoints = val;
+            this.selectPointsModal = false;
+            this.queryQuestionByPage();
+        },
+        /** 获取当前学校基础数据 */
+        getSchoolBaseInfo() {
+            return new Promise((r, j) => {
+                this.$store.dispatch("user/getSchoolProfile").then((res) => {
+                    let schoolBaseInfo = res.school_base;
+                    if (schoolBaseInfo) {
+                        r(schoolBaseInfo);
+                    } else {
+                        r("noSchool");
+                    }
+                });
+            });
+        }
+    }
+}
+</script>
+
+<style lang="less" scoped>
+.question-list-wrap {
+    height: 100%;
+}
+</style>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/learnactivity/markpaper/PublishTask.vue

@@ -280,7 +280,7 @@ export default {
                     align: 'center'
                 },
                 {
-                    title: this.$t('learnActivity.mark.markNum'),
+                    title: `${this.$t('learnActivity.mark.markNum')}/${this.$t('learnActivity.mark.totalMarkNum')}`,
                     slot: 'count',
                     align: 'center'
                 },