Procházet zdrojové kódy

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

CrazyIter_Bin před 1 rokem
rodič
revize
326b7e7781

+ 7 - 6
TEAMModelOS/ClientApp/public/lang/en-US.js

@@ -87,14 +87,14 @@ const LANG_EN_US = {
         tip13: '設置成功!當前互評狀態為:',
         tip14: '設置失敗!',
         tip15: '當前教師暫未上傳活動pdf作業,無法通過!',
-        tip16: '操作成功!',
+        tip16: 'Operate successfully!',
         tip17: '確認將所有教師參與的 不需要提交的 以及 需要並且已經提交PDF 的研修活動全部設置為通過嗎?',
         tip18: '確認將所有教師已經自評過的微能力點全部設置為合格嗎?',
         tip19: '操作失敗!',
         tip20: '確認將所有教師已提交的課堂實錄全部設置為合格嗎?',
         tip21: '確認將當前所有教師的校本研修評定為合格嗎?',
         tip22: '批量操作',
-        tip23: '設置成功!',
+        tip23: 'Setup successfully!',
         noProvince: '暫未對接省平臺',
     },
     // 研修模块
@@ -1631,6 +1631,7 @@ const LANG_EN_US = {
         canChoose: 'choice(s)',
         xkw: 'zxxk.com',
         xkwMode: 'Academic Web Design',
+        df: 'Overweight',
         importItems: 'Import Question',
         composePaper: 'Form Exam File',
         syncItems: 'Synchronize questions to the question bank',
@@ -3720,7 +3721,7 @@ const LANG_EN_US = {
         delNotifyContent: 'Are you sure you want to delete ',
         yes: 'Yes',
         no: 'No',
-        delOk: 'Delete Successfully',
+        delOk: 'Delete successfully',
         delErr: 'Failed to delete',
         classTitle: 'Create Class Announcement',
         classLabel: 'Class',
@@ -4027,11 +4028,11 @@ const LANG_EN_US = {
         hiTeach: 'HiTeach Serial Number',
         csTips1: 'Zoomed in to the maximum magnification!',
         csTips2: 'Zoomed out to the minimum magnification!',
-        csTips3: 'Save Successfully!',
+        csTips3: 'Save successfully!',
         csTips4: 'Need to keep at least one!',
-        csTips5: 'Upload Successfully!',
+        csTips5: 'Upload successfully!',
         csTips6: 'This serial number is already linked to a classroom!',
-        csTips7: 'Delete Successfully!',
+        csTips7: 'Delete successfully!',
         presetClassroomName: 'Classroom',
         presetHeadmaster: 'No class teacher assigned',
         sokapp: 'Sokrates Lesson Observation',

+ 1 - 0
TEAMModelOS/ClientApp/public/lang/zh-CN.js

@@ -1630,6 +1630,7 @@ const LANG_ZH_CN = {
         canChoose: '道题可选',
         xkw: '学科网',
         xkwMode: '学科网组卷',
+        df: '多分',
         importItems: '试题导入',
         composePaper: '组成试卷',
         syncItems: '同步试题到题库',

+ 1 - 0
TEAMModelOS/ClientApp/public/lang/zh-TW.js

@@ -1633,6 +1633,7 @@ const LANG_ZH_TW = {
         canChoose: '道題可選',
         xkw: '學科網',
         xkwMode: '學科網組卷',
+        df: '多分',
         importItems: '試題匯入',
         composePaper: '組成試卷',
         syncItems: '同步試題到題庫',

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

@@ -80,6 +80,12 @@
 									 
 								</span>
 							</DropdownItem>
+							<DropdownItem name="go_df" v-if="isTestSite">
+								<span @click="dodfAuth" class="bank-tools-btn">
+									<Icon type="ios-send" size="16" />
+									<span>{{ $t("evaluation.df") }}</span>
+								</span>
+							</DropdownItem>
 						</DropdownMenu>
 					</template>
 				</Dropdown>
@@ -248,6 +254,12 @@
 						});
 				});
 			},
+			// 跳转页面,进行多分题库挑选
+			dodfAuth() {
+				this.$router.push({
+					name: this.isSchool ? 'schoolDf' : 'privateDf',
+				})
+			},
 
 			/**
 			 * exList的collapseList变化
@@ -365,7 +377,7 @@
 				return true;
 			},
 			isTestSite() {
-				return window.location.host.includes("test.teammodel.cn");
+				return this.$store.state.config.srvAdrType === "test"
 			}
 		},
 		beforeRouteLeave(to, from, next) {

+ 18 - 5
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChild.vue

@@ -23,8 +23,12 @@
       </div>
       <div class="item-btn-toggle">
         <template v-if="!inBank">
-          <InputNumber :min="0" v-model="item.score" v-if="isShowScore" :step="0.5" style="display: inline-block ;width: 60px;margin-right: 10px;height: 30px;" @click.stop>
-          </InputNumber>
+          <template v-if="isShowScore">
+            <InputNumber :min="0" v-model="item.score" v-if="df" :step="0.5" @on-change="val => scoreChange(val, item.pid, item.id)" style="display: inline-block ;width: 60px;margin-right: 10px;height: 30px;" @click.stop>
+            </InputNumber>
+            <InputNumber :min="0" v-model="item.score" v-else :step="0.5" style="display: inline-block ;width: 60px;margin-right: 10px;height: 30px;" @click.stop>
+            </InputNumber>
+          </template>
           <span v-if="!isShowScore" style="margin-right: 10px;color: #2db7f5;font-weight: bold;">{{ item.score }}</span>
           <span style="margin-right: 20px;">{{$t('evaluation.paperList.score')}}</span>
         </template>
@@ -185,7 +189,16 @@ export default {
     canFix: {
       type: Boolean,
       default: false
-    }
+    },
+    df: {
+      type: Boolean,
+      default: false
+    },
+    scoreChange: {
+      type: Function,
+      require: true,
+      default: null
+    },
   },
   data() {
     return {
@@ -307,9 +320,9 @@ export default {
         this.collapseList.splice(listIndex, 1);
       } else {
         this.collapseList.push(index);
-        let exerciseItemDom = e.path.filter(
+        /* let exerciseItemDom = e.path.filter(
           (i) => i.className === "exercise-item"
-        );
+        ); */
         // if (exerciseItemDom.length) {
         // 	this.pageScrollTo(exerciseItemDom[0].offsetTop + 240);
         // }

+ 1 - 13
TEAMModelOS/ClientApp/src/view/evaluation/index/DfPage.less

@@ -77,18 +77,6 @@
                     }
                 }
 
-                .item-tools-wrap {
-                    position: absolute;
-                    right: -2px;
-                    top: -32px;
-                    width: auto;
-                    height: 30px;
-                    margin: 0;
-                    padding: 0;
-                    background: #01b4ef;
-                    display: none;
-                }
-
                 .item-tools-t {
                     height: 100%;
                     padding: 0 15px;
@@ -117,7 +105,7 @@
         position: fixed;
         right: 50px;
         bottom: 27px;
-        z-index: 9999;
+        z-index: 1;
 
         .ivu-poptip-popper {
             width: 360px !important;

+ 594 - 88
TEAMModelOS/ClientApp/src/view/evaluation/index/DfPage.vue

@@ -202,61 +202,97 @@
             <Page :total="totalNum" show-sizer show-total :page-size="pageSize" :current="pageNum" @on-page-size-change="pageSizeChange" @on-change="pageChange" :page-size-opts="[10, 20, 30]" />
         </div>
         <Drawer title="已选择题目" width="40" :mask-closable="false" v-model="showQues" class="select-ques">
-            <RadioGroup v-model="saveType" @on-change="saveTypeChange">
+            <!-- <RadioGroup v-model="saveType" @on-change="saveTypeChange">
                 <Radio label="quesBank">题库</Radio>
                 <Radio label="paper">试卷</Radio>
-            </RadioGroup>
+            </RadioGroup> -->
             <div v-if="!selShowList.length">未选择题目</div>
-            <div v-else class="content-wrap" style="height: 95%;">
+            <div v-else class="content-wrap" style="height: 90%;">
                 <vuescroll>
+                    <!-- 只在学校题库出现 -->
+                    <Form ref="selEvalInfo" :model="selEvalInfo" :rules="evalValidate" label-colon :label-width="100">
+                        <template v-if="isSchool">
+                            <FormItem :label="$t('evaluation.newExercise.choosePeriod')">
+                                <Select v-model="selEvalInfo.paperPeriod" style="width:150px" @on-change="onPeriodChange">
+                                    <Option v-for="(period, index) in schoolInfo.period" :value="index" :key="index">{{ period.name }}</Option>
+                                </Select>
+                            </FormItem>
+                            <FormItem :label="$t('evaluation.newExercise.chooseGrade')" prop="publish">
+                                <Select v-model="selEvalInfo.paperGrade" style="width:150px">
+                                    <Option v-for="(grade, index) in schGradeList" :value="index" :key="grade">{{ grade }}</Option>
+                                </Select>
+                            </FormItem>
+                            <FormItem :label="$t('evaluation.newExercise.chooseSubject')">
+                                <Select v-model="selEvalInfo.paperSubject" style="width:150px">
+                                    <Option v-for="(subject, index) in schSubjectList" :value="index" :key="index">{{ subject.name }}</Option>
+                                </Select>
+                            </FormItem>
+                        </template>
+                        <FormItem label="试卷名称" v-show="selEvalInfo.savetype.includes('paper')" prop="paperName">
+                            <Input v-model="selEvalInfo.paperName" placeholder="请输入" />
+                        </FormItem>
+                        <FormItem label="试卷总分" v-show="selEvalInfo.savetype.includes('paper')" prop="score">
+                            <InputNumber :min="1" v-model="totalScore"></InputNumber>
+                        </FormItem>
+                    </Form>
+                    <div style="display: flex; align-items: center; justify-content: space-between; flex-direction: row-reverse; padding-bottom: 15px;">
+                        <Button type="info" @click="saveTypeChange(saveType === 'type' ? 'list' : 'type')" style="float: right;">
+                            {{ saveType === 'type' ? '题型展示' : '题号展示' }}
+                        </Button>
+                        <div v-show="selEvalInfo.savetype.includes('paper')">
+                            <!-- <span>总分:{{ totalScore }}</span> -->
+                            <span>未分配分:
+                                <span :style="{'color': surPlusScore === 0 ? '' : 'red'}">{{ surPlusScore }}</span>
+                            </span>
+                        </div>
+                    </div>
                     <div class="list-view" v-for="(quesItem, quesIndex) in selShowList" :key="quesIndex">
-                        <p v-show="saveType === 'paper' && quesItem.list.length" class="type-name">
+                        <p v-show="saveType === 'type' && quesItem.list.length" class="type-name">
                             {{ $tools.getChineseByNum(getLatestTypeIndex(quesItem.type) + 1) }} : {{ exersicesType[quesItem.type] }}
                             <span style="font-size: 14px;font-weight: 600;">
                                 ({{ `${$t('answerSheet.tip9')} ${quesItem.list.length}${$t('answerSheet.tip17')}${quesItem.score || 0}${$t('evaluation.paperList.score')}` }})
                             </span>
                         </p>
-                        <div class="exercise-item" v-for="(item, index) in quesItem.list" :key="index" @click="onQuestionToggle(index, item.id, $event)">
+                        <div class="exercise-item" v-for="(item, index) in quesItem.list" :key="index" @click="onQuestionToggle(index, item.id, $event, true)">
                             <!-- 工具栏部分 -->
-                            <div class="item-tools-wrap" v-show="saveType === 'paper'">
-                                <div class="item-tools-t flex-row-center" @click.stop="handleDelete(quesItem.list,item,index)">
+                            <div class="item-tools-wrap" v-show="selEvalInfo.savetype.includes('paper')">
+                                <div class="item-tools-t flex-row-center" @click.stop="handleDelete(quesItem.list, item, index)">
                                     <Icon type="ios-archive-outline" />{{$t('evaluation.deleteItem')}}
                                 </div>
-                                <div class="item-tools-t flex-row-center" v-show="index != 0" @click.stop="handleMoveUp(quesItem.list,index)">
+                                <div class="item-tools-t flex-row-center" v-show="index != 0" @click.stop="handleMoveUp(quesItem.list, index)">
                                     <Icon type="md-arrow-up" />{{$t('evaluation.exerciseList.moveUp')}}
                                 </div>
-                                <div class="item-tools-t flex-row-center" v-show="index != (quesItem.list.length - 1)" @click.stop="handleMoveDown(quesItem.list,index)">
+                                <div class="item-tools-t flex-row-center" v-show="index != (quesItem.list.length - 1)" @click.stop="handleMoveDown(quesItem.list, index)">
                                     <Icon type="md-arrow-down" />{{$t('evaluation.exerciseList.moveDown')}}
                                 </div>
                             </div>
-                            <div class="item-question">
-                                <div>
-                                    <div class="item-question-order">{{ index + 1 }} :</div>
-                                    <div class="item-question-text" v-html="item.question"></div>
+                            <div style="max-width: 85%;">
+                                <div class="item-question">
+                                    <div>
+                                        <div class="item-question-order">{{ index + 1 }} :</div>
+                                        <div class="item-question-text" v-html="item.question"></div>
+                                    </div>
                                 </div>
-                                <span class="item-btn-toggle" style="justify-content: flex-end;">
-                                    <Icon v-if="item.type !== 'compose'" :type="selcollaList.indexOf(index) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown'" />
-                                </span>
-                            </div>
-                            <div class="exercise-item-children" v-if="item.children.length">
-                                <BaseChild ref="childRef" :children="item.children" inBank></BaseChild>
-                            </div>
-                            <div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options">
-                                <div class="item-option-content">
-                                    <div class="item-option-order">
-                                        {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} :
+                                <div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options">
+                                    <div class="item-option-content">
+                                        <div class="item-option-order">
+                                            {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} :
+                                        </div>
+                                        <div class="item-option-text" v-html="option.value"></div>
                                     </div>
-                                    <div class="item-option-text" v-html="option.value"></div>
                                 </div>
                             </div>
-                            <div class="item-btn-toggle" v-show="saveType === 'paper'">
-                                <!-- 可调整分数 -->
-                                <InputNumber v-if="item.type !== 'compose'" :max="item.score + surPlusScore" :min="scoreStep" :step="scoreStep" v-model="item.score" style="display: inline-block ;width: 60px;margin-right: 10px;height: 30px;" @click.stop>
-                                </InputNumber>
-                                <span style="margin-right: 10px;" v-if="item.type === 'compose'">{{ getComposeScore(item) }}</span>
-                                <span style="margin-right: 10px;">{{$t('evaluation.paperList.score')}}</span>
-                                <!-- <span class="item-score" title="设置题目分数" @click.stop="onSetSingleItem(item,index)" v-else>{{ item.score }} 分</span> -->
-                                <Icon @click.stop="onQuestionToggle(selectedArr.indexOf(item), item.id, $event, quesItem.list)" :type="selcollaList.indexOf(selectedArr.indexOf(item)) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown'" v-if="item.type !== 'compose'" />
+                            <div class="exercise-item-children" v-if="item.children.length">
+                                <BaseChild :children="item.children" :totalScore="item.score" :isShowScore="selEvalInfo.savetype.includes('paper')" :df="true" :scoreChange="scoreChange"></BaseChild>
+                            </div>
+                            <div class="item-btn-toggle">
+                                <template @click.stop v-if="selEvalInfo.savetype.includes('paper')">
+                                    <!-- 可调整分数 -->
+                                    <InputNumber v-if="item.type !== 'compose'" :max="item.score + surPlusScore" :min="scoreStep" :step="scoreStep" v-model="item.score" style="display: inline-block ;width: 60px;margin-right: 10px;height: 30px;" @click.stop></InputNumber>
+                                    <span style="margin-right: 10px;" v-if="item.type === 'compose'">{{ getComposeScore(item) }}</span>
+                                    <span style="margin-right: 10px;">{{$t('evaluation.paperList.score')}}</span>
+                                </template>
+                                <Icon @click.stop="onQuestionToggle(selectedArr.indexOf(item), item.id, $event, true)" :type="selcollaList.indexOf(selectedArr.indexOf(item)) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown'" v-if="item.type !== 'compose'" />
                             </div>
                             <transition name="slide" v-if="item.type !== 'compose'">
                                 <div v-show="selcollaList.indexOf(selectedArr.indexOf(item)) > -1" class="toggle-area">
@@ -318,9 +354,12 @@
                     </div>
                 </vuescroll>
             </div>
-            <div style="display: flex; justify-content: space-between;" v-show="selShowList.length">
-                <Button v-show="saveType === 'paper'" @click="saveDFQues('paper')">保存为试卷</Button>
-                <Button v-show="saveType != 'paper'" @click="saveDFQues('quesBank')">加入题库</Button>
+            <div style="display: flex; justify-content: space-between; padding-top: 20px;" v-show="selShowList.length">
+                <CheckboxGroup v-model="selEvalInfo.savetype">
+                    <Checkbox label="quesBank">同步试题到题库</Checkbox>
+                    <Checkbox label="paper">组成试卷</Checkbox>
+                </CheckboxGroup>
+                <Button @click="saveDFQues()">保存</Button>
             </div>
         </Drawer>
     </div>
@@ -347,7 +386,7 @@ export default {
                 {id: '历史', name: '历史'},
                 {id: '生物', name: '生物'},
                 {id: '政治', name: '政治'},
-            ],
+            ], // 多分学科
             typeList: [
                 {id: 'C', name: '选择'},
                 {id: 'F', name: '填空'},
@@ -358,8 +397,8 @@ export default {
             exersicesDiff: this.$GLOBAL.EXERCISE_DIFFS(),
             exersicesType: this.$GLOBAL.EXERCISE_TYPES(),
             exersicesField: this.$GLOBAL.EXERCISE_LEVELS(),
-            filterGrade: 10,
-            filterSubject: '物理',
+            filterGrade: 1,
+            filterSubject: '语文',
             filterType: 'all',
             filterDiff: 'all',
             searchVal: '',
@@ -368,8 +407,8 @@ export default {
             pageNum: 1,
             exerciseList: [],
             collapseList: [],
-            selectedArr: [],
             selcollaList: [],
+            selectedArr: [],
             orderList: [],
             groupList: [],
             selShowList: [],
@@ -377,7 +416,7 @@ export default {
             isShowAnswer: true,
             isAllOpen: false,
             showQues: false,
-            saveType: 'quesBank',
+            saveType: 'list',
             shoppingCarClass: 'question-shopping-car',
             quesTypeList: {
                 single: 0,
@@ -388,8 +427,22 @@ export default {
                 compose: 0
             },
             scoreStep: 0.5,
-            surPlusScore: 0,
             needSaveCosmosArr: [],
+            selEvalInfo: {
+                paperPeriod: 0,
+                paperGrade: 0,
+                paperSubject: 0,
+                paperName: '',
+                savetype: ['quesBank'],
+            },
+            evalValidate: {
+                paperName: [{required: true, message: '请输入', trigger: 'blur'}],
+                score: [{required: true, type: Number, message: '请输入', trigger: 'blur'}],
+            },
+            totalScore: 100,
+            schoolInfo: {},
+            schGradeList: [], //当前学校的年级
+            schSubjectList: [], //当前学校的学科
         }
     },
     created() {
@@ -407,9 +460,21 @@ export default {
         isSchool() {
             return this.$route.name === 'schoolDf'
         },
+        getComposeScore() {
+            return item => {
+                return item.children.length ? item.children.reduce((a, b) => a + b.score, 0) : 0
+            }
+        },
+        surPlusScore() {
+            return this.totalScore - this.selectedArr.reduce((p, e) => Number(p) + Number(e.score), 0)
+        },
     },
     watch: {
     },
+    async mounted () {
+        this.schoolInfo = await this.getSchoolBaseInfo()
+        this.onPeriodChange(0)
+    },
     methods: {
         getDfList() {
             this.isLoading = true
@@ -481,7 +546,7 @@ export default {
                 },
             });
         },
-        onQuestionToggle(index, id, e) {
+        onQuestionToggle(index, id, e, isDrawer) {
             console.log(e)
             this.shoppingCarClass = 'question-shopping-car animated heartBeat'
             setTimeout(() => {
@@ -497,15 +562,29 @@ export default {
             )
                 return
             e.stopPropagation()
-            let listIndex = this.collapseList.indexOf(index)
-            if (listIndex > -1) {
-                this.collapseList.splice(listIndex, 1)
+            if(isDrawer) {
+                let listIndex = this.selcollaList.indexOf(index)
+                if (listIndex > -1) {
+                    this.selcollaList.splice(listIndex, 1)
+                } else {
+                    this.selcollaList.push(index)
+                    let path = this.$tools.composedPath(e)
+                    let exerciseItemDom = path.filter((i) => i.className === "exercise-item")
+                    if (exerciseItemDom.length) {
+                        // this.pageScrollTo(exerciseItemDom[0].offsetTop + 180)
+                    }
+                }
             } else {
-                this.collapseList.push(index)
-                let path = this.$tools.composedPath(e)
-                let exerciseItemDom = path.filter((i) => i.className === "exercise-item")
-                if (exerciseItemDom.length) {
-                    this.pageScrollTo(exerciseItemDom[0].offsetTop + 180)
+                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.pageScrollTo(exerciseItemDom[0].offsetTop + 180)
+                    }
                 }
             }
         },
@@ -524,6 +603,7 @@ export default {
             this.shoppingCarClass = 'question-shopping-car'
         },
         goToPreview() {
+            if(!this.selectedArr.length) return
             this.orderList = []
             this.groupList = []
             let that = this
@@ -539,14 +619,23 @@ export default {
                     }
                 })
             }
-            this.orderList.push({list: this._.cloneDeep(this.selectedArr)})
-            this.selShowList = this._.cloneDeep(this.orderList)
-            // 总分默认100
-            this.surPlusScore = 100 - this.selectedArr.reduce((p, e) => Number(p) + Number(e.score), 0);
+            this.orderList.push({list: this.selectedArr})
+            this.selShowList = this.saveType === 'list' ? this.orderList : this.groupList
             this.showQues = true
-            // this.$emit('goToPreview')
             // 使用弹出框展示已选题目,再选择加入题库/组成试卷
         },
+        scoreChange(val, pid, id) {
+            let parent = this.selectedArr.find(item => item.id === pid)
+            parent.score = 0
+            parent.children.forEach(child => {
+                if(child.id === id) {
+                    child.score = val
+                }
+                parent.score += child.score
+            })
+            // 总分默认100
+            // this.surPlusScore = this.totalScore - this.selectedArr.reduce((p, e) => Number(p) + Number(e.score), 0)
+        },
         async onSelectAll() {
             this.selectedArr = this.isSelectAll ? this._.cloneDeep(this.exerciseList) : []
             let groupResult = await this.$jsFn.groupBy(this.selectedArr, 'type')
@@ -569,11 +658,8 @@ export default {
             }
         },
         saveTypeChange(val) {
-            if(val === 'quesBank') {
-                this.selShowList = this._.cloneDeep(this.orderList)
-            } else {
-                this.selShowList = this._.cloneDeep(this.groupList)
-            }
+            this.saveType = val
+            this.selShowList = val === 'list' ? this.orderList : this.groupList
         },
         getLatestTypeIndex(type) {
             let arr = []
@@ -584,11 +670,6 @@ export default {
             })
             return arr.indexOf(type)
         },
-        getComposeScore() {
-            return item => {
-                return item.children.length ? item.children.reduce((a, b) => a + b.score, 0) : 0
-            }
-        },
         // 子题顺序操作
         moveItems(arr, index1, index2) {
             arr[index1] = arr.splice(index2, 1, arr[index1])[0]
@@ -611,31 +692,60 @@ export default {
                 title: this.$t('evaluation.newExercise.modalTip'),
                 content: this.$t('evaluation.exerciseList.confirmDelete'),
                 onOk: () => {
-                    this.surPlusScore += item.score
-                    arr.splice(index, 1)
+                    // this.surPlusScore += item.score
+                    // arr.splice(index, 1)
                     this.selectedArr.splice(this.selectedArr.indexOf(item), 1)
                     this.$Message.success(this.$t('evaluation.deleteSuc'))
                 }
             })
         },
-        saveDFQues(type) {
-            if(type === 'paper') {
-
+        /** 获取当前学校基础数据 */
+        getSchoolBaseInfo() {
+            return new Promise((r, j) => {
+                this.$store.dispatch("user/getSchoolProfile").then((res) => {
+                    let schoolBaseInfo = res.school_base;
+                    if (schoolBaseInfo) {
+                        this.schoolInfo = schoolBaseInfo
+                        r(schoolBaseInfo)
+                    } else {
+                        r(null)
+                    }
+                });
+            })
+        },
+        /* 学段切换 */
+        onPeriodChange(val) {
+            this.schGradeList = this.schoolInfo.period[val].grades
+            this.schSubjectList = this.schoolInfo.period[val].subjects
+        },
+        saveDFQues() {
+            if(!this.selectedArr.length) {
+                this.$Message.warning('请先选择题目')
+                return
+            }
+            if(!this.selEvalInfo.savetype.length) {
+                this.$Message.warning('请选择导入题库或组成试卷')
+                return
+            }
+            if(this.selEvalInfo.savetype.includes('paper') && (!this.selEvalInfo.paperName || !this.totalScore)) {
+                this.$Message.warning('请完善信息')
+                return
+            }
+            // 弹出框让用户选择学段、年级、学科,以及试卷名称
+            if(this.isSchool) {
+                this.selectedArr.forEach(item => {
+                    item.periodId = this.schoolInfo.period[this.selEvalInfo.paperPeriod].id
+                    item.gradeIds = [String(this.selEvalInfo.paperGrade)]
+                    item.subjectId = this.schSubjectList[this.selEvalInfo.paperSubject].id
+                })
+            }
+            console.log('开始保存');
+            // 组成试卷,必要将题目保存在blob
+            if(this.selEvalInfo.savetype.includes('paper')) {
+                this.savePaper(this.selectedArr)
             } else {
-                this.saveQuesBank(this.selShowList[0].list, true).then(async res => {
-                    console.log(res);
-                    // 校本组卷情况下 同步知识点数据
-                    /* if (this.isSchool && this.isSavePoints && this.evaluationInfo.createType === 'import') {
-                        if (this.importKnowledges.length) {
-                        let paperItem = {
-                            code: this.editPaper ? this.editPaper.code.replace('Paper-', '') : (this.isSchool ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId),
-                            subjectId: this.isSchool ? this.subjectList[this.evaluationInfo.paperSubject].id : null,
-                            periodId: this.isSchool ? this.schoolInfo.period[this.evaluationInfo.paperPeriod].id : null,
-                        }
-                        this.importKnowledges.push(...refreshList.map(i => i.knowledge).flat(1))
-                        await this.saveImportPoints([...new Set(this.importKnowledges)], paperItem)
-                        }
-                    } */
+                // 同步到题库
+                this.saveQuesBank(this.selectedArr, true).then(async res => {
                     this.$Spin.hide()
                     this.$Message.success(this.$t('evaluation.paperList.saveSuc'))
                     this.isLoading = false
@@ -725,7 +835,6 @@ export default {
                             // 首先保存新题目的JSON文件到Blob 然后返回URL链接
                             let file = new File([JSON.stringify(itemJsonFile)], item.id + ".json")
                             blobFiles.push(file)
-                            console.log(isToItemBank);
                             try {
                                 if (!isToItemBank) {
                                     r({
@@ -779,7 +888,6 @@ export default {
                     // 主观题的answer为空数组
                     let nullType = ['complete', 'subjective', 'compose', 'correct', 'connector']
                     result.map(i => i.cosmosItem).forEach(item => {
-                        console.log(item)
                         let o = {
                             url: item.id + '.json',
                             type: item.type,
@@ -806,7 +914,360 @@ export default {
             })
         },
         async savePaper(list) {
-            
+            let noScoreList = this.selectedArr.filter(item => item.score === 0) // 判断是否有未配分的题目
+            let groupTypeList = this.groupList
+            let paperName = this.selEvalInfo.paperName.trim()
+            if (paperName === '') {
+                this.$Message.warning(this.$t('evaluation.paperList.emptyNameTip'))
+                return
+            }
+            if (this.surPlusScore === 0) {
+                if (!noScoreList.length) {
+                    let isPaperExist = await this.isPaperExist(this.selEvalInfo.paperName)
+                    let isContainerFull = await this.isContainerFull()
+                    if (!isPaperExist) {
+                        if (list.length) {
+                            // 拿到题型顺序的试题数组进行拼接
+                            let arr = []
+                            groupTypeList.forEach(i => {
+                                arr = arr.concat(i.list)
+                            })
+                            if (!this.checkComposeScore(arr)) return
+                            if (isContainerFull) {
+                                this.$Message.warning(this.$t('evaluation.paperList.noSpaceTip'))
+                            } else {
+                                // 只按照默认顺序保存
+                                let saveArr = this.saveType === 'type' ? arr : list
+                                this.doSavePaper(saveArr)
+                            }
+                        } else {
+                            this.isLoading = false
+                            this.$Message.warning(this.$t('evaluation.paperList.noItemTip'))
+                        }
+                    } else {
+                        // 处理已存在同名称的试卷
+                        this.$Modal.confirm({
+                            title: this.$t('evaluation.newExercise.modalTip'),
+                            content: this.$t('evaluation.paperList.isExistPaperTip'),
+                            onOk: async () => {
+                                // 拿到题型顺序的试题数组进行拼接
+                                let arr = []
+                                groupTypeList.forEach(i => {
+                                    arr = arr.concat(i.list)
+                                })
+                                if (!this.checkComposeScore(arr)) return
+                                try {
+                                    // 如果是已存在相同名称的试卷,则进行覆盖,先删除原来的目录再进行保存
+                                    let blobList = await this.getPaperFiles('paper/' + this.selEvalInfo.paperName + '/')
+                                    let files = blobList.blobList.map(i => {
+                                        return {
+                                            blob: i.blob,
+                                            size: i.size
+                                        }
+                                    })
+                                    this.deleteNoUseItem(files, arr).then(r => {
+                                        if (isContainerFull) {
+                                            this.$Message.warning(this.$t('evaluation.paperList.noSpaceTip'))
+                                        } else {
+                                            // 只按照默认顺序保存 arr代表题型排序 list代表的是顺序排序
+                                            let saveArr = this.saveType === 'type' ? arr : list
+                                            this.doSavePaper(saveArr)
+                                        }
+                                    })
+                                } catch (e) {
+                                    this.$Message.error(e)
+                                    this.isLoading = false
+                                }
+                            },
+                            onCancel: () => {
+                                this.isLoading = false
+                                this.$Message.warning(this.$t('evaluation.paperList.cancelSaveTip'))
+                            }
+                        })
+                    }
+                } else {
+                    this.$Message.warning(this.$t('evaluation.paperList.hasNoScoreTip'))
+                    this.isLoading = false
+                }
+            } else {
+                this.$Message.warning(this.$t('evaluation.paperList.noCompleteScoreTip'))
+                this.isLoading = false
+            }
+        },
+        /* 保存试卷业务 */
+        async doSavePaper(list) {
+            this.$Modal.remove()
+            // 将传进来的试题 如果是导入的试题 则需要补充年级学段等信息
+            let isToItemBank = this.selEvalInfo.savetype.includes('quesBank')
+            // 初始化试卷数据
+            let guid = this.$tools.guid()
+            let paperItem = {
+                id: guid,
+                code: this.isSchool ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
+                scope: this.isSchool ? 'school' : 'private',
+                itemSort: this.saveType === 'list' ? 1 : 0,
+                gradeIds: this.isSchool ? [String(this.selEvalInfo.paperGrade)] : [],
+                subjectId: this.isSchool ? this.schSubjectList[this.selEvalInfo.paperSubject].id : null,
+                subjectName: this.isSchool ? this.schSubjectList[this.selEvalInfo.paperSubject].name : '',
+                periodId: this.isSchool ? this.schoolInfo.period[this.selEvalInfo.paperPeriod].id : null,
+                name: this.selEvalInfo.paperName,
+                points: this.getPaperPoints(list),
+                scoring: this.getAnswers(list),
+                score: this.totalScore,
+                sheet: null, //答题卡
+                tags: [],
+                multipleRule: 1, //阅卷规则
+                typeSummaryInfo: {}, //说明文本
+                orderTemp: this.orderTempIndex //题号模板
+            }
+            this.isLoading = true
+            // 保存导入的试题到BLOB以及COSMOS
+            this.saveQuesBank(list, isToItemBank).then(async res => {
+                console.error(res)
+                let blobPaper = await this.$evTools.createBlobPaper(paperItem, res.slides)
+                // 首先保存新题目的JSON文件到Blob 然后返回URL链接
+                let paperFile = new File([JSON.stringify(blobPaper)], "index.json");
+                // 获取初始化Blob需要的数据
+                let sasData = this.isSchool ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
+                //初始化Blob
+                let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, this.isSchool ? 'school' : 'private')
+                try {
+                    let promiseArr = []
+                    let blobFile = null
+                    // 放入试题json文件
+                    for (let i = 0; i < res.files.length; i++) {
+                        promiseArr.push(new Promise(async (r, j) => {
+                            try {
+                                let item = res.files[i]
+                                const itemJsonFile = await this.$evTools.createBlobItem(item)
+                                let file = new File([JSON.stringify(itemJsonFile)], item.id + ".json");
+                                containerClient.upload(file, {
+                                    path: 'paper/' + paperItem.name,
+                                    checkSize: false
+                                }).then(res => {
+                                    r(200)
+                                })
+                            } catch (e) {
+                                console.log(e)
+                            }
+                        }))
+                    }
+                    // 放入index.json文件
+                    promiseArr.push(new Promise(async (r, j) => {
+                        try {
+                            blobFile = await containerClient.upload(paperFile, {
+                                path: 'paper/' + paperItem.name,
+                                checkSize: false
+                            })
+                            console.log('上传到试卷目录下', blobFile)
+                            r(blobFile)
+                        } catch (e) {
+                            j(e)
+                            this.$Message.error(e.spaceError)
+                            this.isLoading = false
+                        }
+                    }))
+                    // 不存在多媒体
+
+                    // 进行试卷文件上传Blob 先上传所有题目 再上传index.json文件
+                    Promise.all(promiseArr).then(async result => {
+                        try {
+                            // 检查试卷目录下是否有 已被移除的试题 有则进行删除操作
+                            let blobList = await this.getPaperFiles('paper/' + paperItem.name + '/')
+                            let files = blobList.blobList.map(i => {
+                                return {
+                                    blob: i.blob,
+                                    size: i.size
+                                }
+                            })
+                            await this.deleteNoUseItem(files, res.files)
+
+                            if (blobFile.blob) {
+                                // 试卷保存更新后需要重新生成答题卡
+                                paperItem.blob = blobFile.blob.split('/index.json')[0]
+
+                                let params = {
+                                    paper: await this.$evTools.createCosmosPaper(paperItem),
+                                    option: this.isEditPaper ? 'update' : 'insert'
+                                }
+                                //  保存试卷到cosmos
+                                this.$api.learnActivity.SaveExamPaper(params).then(res => {
+                                    if (res.error == null) {
+                                        this.$Message.success(this.$t('evaluation.paperList.saveSuc'))
+                                        this.isLoading = false
+                                        this.$Spin.hide()
+                                        // this.savePeriodInfos()
+                                        // 清空已选试题
+                                        this.showQues = false
+                                        this.selectedArr = []
+                                        this.groupList = []
+                                        this.orderList = []
+                                        this.selShowList = []
+                                    } else {
+                                        this.$Message.error(this.$t('evaluation.paperList.saveFail'))
+                                        this.$Spin.hide()
+                                        this.isLoading = false
+                                    }
+                                },err => {
+                                    this.$Message.error(this.$t('evaluation.paperList.saveFail'))
+                                    this.isLoading = false
+                                    this.$Spin.hide()
+                                })
+                            } else {
+                                console.error(blobFile)
+                            }
+                        } catch (e) {
+                            console.log(e)
+                        }
+                    })
+                } catch (e) {
+                    console.log(e)
+                    this.$Message.error(this.$t('evaluation.paperList.saveItemsFailTip'))
+                    this.isLoading = false
+                }
+            }).catch(e => {
+                this.$Message.error(this.$t('evaluation.paperList.saveItemsFailTip'))
+                this.isLoading = false
+            })
+        },
+        /* 获取整张试卷的知识点集合 */
+        getPaperPoints(items) {
+            let arr = []
+            items.forEach((i, index) => {
+                if (i.knowledge) {
+                    arr = arr.concat(i.knowledge)
+                }
+            })
+            return arr
+        },
+        /* 获取整张试卷的答案合计Answers */
+        getAnswers(items) {
+            let arr = []
+            // 主观题的answer为空数组
+            let nullType = ['complete', 'subjective', 'compose', 'correct', 'connector']
+            items.forEach((i, index) => {
+                arr.push({
+                    type: i.type,
+                    ans: nullType.includes(i.type) ? [] : i.answer,
+                    score: i.score
+                })
+            })
+            return arr
+        },
+        // 判断空间状态
+        isContainerFull() {
+            return new Promise(async (r, j) => {
+                let scope = this.isSchool ? 'school' : 'private'
+                // 获取初始化Blob需要的数据
+                let sasData = this.isSchool ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
+                //初始化Blob
+                let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, scope)
+                containerClient.isContainerFull(scope).then((res) => {
+                    r(res)
+                },(err) => {
+                    j(err)
+                    this.$Message.error('API Error')
+                })
+            })
+        },
+        // 判断试卷是否存在于Blob中
+        isPaperExist(paperName) {
+            return new Promise(async (r, j) => {
+                // 获取初始化Blob需要的数据
+                let sasData = this.isSchool ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
+                //初始化Blob
+                let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, this.isSchool ? 'school' : 'private')
+                containerClient.exists('paper/' + paperName + '/index.json').then((res) => {
+                    r(res)
+                },(err) => {
+                    j(err)
+                    this.$Message.error('API Error')
+                })
+            })
+        },
+        /* 检查综合题配分是否正确 */
+        checkComposeScore(arr) {
+            let flag = true
+            for (let index = 0; index < arr.length; index++) {
+                let i = arr[index]
+                if (i.type === 'compose' && i.children.length) {
+                    let childTotalScore = i.children.reduce((p, e) => p + e.score, 0)
+                    let hasNoScoreChild = i.children.filter(j => !j.score).length > 0
+                    if (i.score !== childTotalScore || hasNoScoreChild) {
+                        console.log(i.score)
+                        console.log(childTotalScore)
+                        console.log(index)
+                        /* let exList = this.$refs.testPaper.$refs.exList
+                        let exerciseDom = Array.from(exList.$el.getElementsByClassName('exercise-item')).filter(item => item.dataset.id === i.id)[0]
+                        exerciseDom.style.backgroundColor = '#ffa7a7'
+                        this.$nextTick(() => {
+                            if (this.$refs.paperRef) {
+                                this.$refs['paperRef'].scrollTo({y: exerciseDom.offsetTop}, 500)
+                            }
+                        })
+                        setTimeout(() => {
+                            exerciseDom.style.backgroundColor = '#fff'
+                        }, 2000) */
+                        this.$Message.warning(`${this.$t('evaluation.createPaper.tip1')} ${index + 1} ${this.$t('evaluation.createPaper.tip2')}${i.score > childTotalScore ? this.$t('evaluation.createPaper.tip3') : this.$t('evaluation.createPaper.tip4')},${this.$t('evaluation.createPaper.tip5')}`)
+                        flag = false
+                        this.isLoading = false
+                        break
+                    }
+                } else {
+                    flag = true
+                }
+            }
+            return flag
+        },
+        /* 获取指定路径试卷下的所有文件 */
+        getPaperFiles(path) {
+            return new Promise(async (r, j) => {
+                // 获取初始化Blob需要的数据
+                let sasData = this.isSchool ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
+                //初始化Blob
+                let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, this.isSchool ? 'school' : 'private')
+                // 等待blob的返回结果
+                containerClient.listBlob({prefix: path}).then((res) => {
+                    r(res)
+                },(err) => {
+                    this.$Message.error('API Error')
+                })
+            })
+        },
+        /* 删除同名试卷覆盖情况下 已被移除的试题 */
+        deleteNoUseItem(blobList, arr) {
+            return new Promise(async (resolve, reject) => {
+                let needDeleteUrlArr = []
+                blobList.forEach(s => {
+                    if (s.blob.includes('.json')) {
+                        let id = s.blob.split('/')[s.blob.split('/').length - 1].replace('.json', '')
+                        if (id !== 'index' && arr.map(i => i.id).indexOf(id) === -1) {
+                            needDeleteUrlArr.push(s)
+                        }
+                    }
+                })
+                if (!needDeleteUrlArr.length) {
+                    resolve(200)
+                } else {
+                    let promiseArr = []
+                    let sas = this.isSchool ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
+                    let blobClient = new blobTool(sas.url, sas.name, sas.sas, this.isSchool ? 'school' : 'private')
+                    needDeleteUrlArr.forEach(item => {
+                        promiseArr.push(new Promise((r, j) => {
+                            blobClient.deleteBlob(item.blob, item.size).then((res) => {
+                                r(200)
+                            },(err) => {
+                                j(err)
+                            })
+                        }))
+                    })
+                    Promise.all(promiseArr).then(result => {
+                        resolve(200)
+                    }).catch(e => {
+                        reject(e)
+                    })
+                }
+            })
         },
     },
 }
@@ -818,5 +1279,50 @@ export default {
 <style lang="less">
 .select-ques {
     background-color: #f6f6f6;
+    .list-view {
+        margin-top: 20px;
+    }
+    .exercise-item {
+        &:hover {
+            .item-tools-wrap{
+                display: block;
+            }
+        }
+        .item-tools-wrap {
+            position: absolute;
+            right: -2px;
+            top: -32px;
+            width: auto;
+            height: 30px;
+            margin: 0;
+            padding: 0;
+            background: #01b4ef;
+            display: none;
+        }
+        .flex-row-center {
+            display: flex;
+            flex-direction: row;
+            justify-content: center;
+            align-items: center;
+        }
+        .item-tools-t {
+            height: 100%;
+            padding: 0 15px;
+            float: left;
+            color: white;
+            cursor: pointer;
+            font-size: 14px;
+        }
+
+        .item-question .item-question-text {
+            display: inline-block;
+            width: calc(90% - 30px);
+        }
+        .exercise-item-children {
+            .child-tools-wrap {
+                display: none !important;
+            }
+        }
+    }
 }
 </style>