Bläddra i källkod

Merge branch 'develop3.0-tmd' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop3.0-tmd

OnePsycho 4 år sedan
förälder
incheckning
60054fba80

+ 5 - 7
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/vote.css

@@ -1,16 +1,14 @@
 .vote .checkAnswer {
-  display: flex;
-  width:100%;
-  margin-top: 20px;
-  margin-left: 0px;
+    display: inline-flex;
+    min-width:100px;
+    margin-top: 15px;
+    margin-right:20px;
 }
 .vote .checkAnswer .testBtn {
   margin: 10px 0px;
   position: relative;
   z-index: 2;
-  width:50%;
   font-weight: bolder;
-  padding-left: 20px;
   cursor: pointer;
 }
 .vote .checkAnswer .testBtn input[type="checkbox"] {
@@ -44,7 +42,7 @@
     .vote  .vote-title {
         width: 100%;
         /*display: flex;*/
-    }
+}
     .vote .vote-title .title-rect-group{
         display:flex;
     }

+ 18 - 19
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue

@@ -39,26 +39,25 @@
                 </div>
                 <!--和評測模組一樣-->
                 <div class="question-box"><span v-html="voteInfo.description"></span></div>
-                <div class="checkAnswer">
-                    <label class="testBtn"
-                           v-for="(item, index) in voteInfo.options"
-                           :key="index">
-                        <input type="checkbox" :value="item" v-model="voteChecked" @click="getVote(item)" />
-                        <div class="testbg">
-                            <div class="vote-info">
-                                <span style="display:flex;margin-right:5px">{{item.code}}.<span v-html="item.value"></span></span>
+                <div>
+                    <div class="checkAnswer"  v-for="(item, index) in voteInfo.options" :key="index">
+                        <label class="testBtn">
+                            <input type="checkbox" :value="item" v-model="voteChecked" @click="getVote(item)" />
+                            <div class="testbg">
+                                <div class="vote-info">
+                                    <span style="display:flex;margin-right:5px">{{item.code}}.<span v-html="item.value"></span></span>
+                                </div>
+                                <InputNumber v-model="item.count"
+                                             :formatter="value => `${value}` +$t('studentWeb.vote.tickets')"
+                                             :parser="value => value.replace($t('studentWeb.vote.tickets'), '')"
+                                             :min="0"
+                                             v-if="voteInfo.repeat"
+                                             @on-change="setVoteNum(item)"
+                                             :disabled="!voteStatus">
+                                </InputNumber>
                             </div>
-                            <InputNumber v-model="item.count"
-                                         :formatter="value => `${value}` +$t('studentWeb.vote.tickets')"
-                                         :parser="value => value.replace($t('studentWeb.vote.tickets'), '')"
-                                         :min="0"
-                                         v-if="voteInfo.repeat"
-                                         @on-change="setVoteNum(item)"
-                                         :disabled="!voteStatus"
-                                         >
-                            </InputNumber>
-                        </div>
-                    </label>
+                        </label>
+                    </div>
                 </div>
                 <Button :disabled="!isVote" size="large" type="success" @click="submitMessage()">
                     <svg-icon icon-class="vote" class="uploadBtn-icon" />

+ 49 - 12
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue

@@ -26,21 +26,31 @@
                             <div @click="sentEventStatus('all')">
                                 <DropdownItem>{{ $t("studentWeb.event.allStatus") }}</DropdownItem>
                             </div>
-                            <div @click="sentEventStatus('unFinsish')">
+                            <div @click="sentEventStatus('going')">
                                 <DropdownItem>{{ $t("studentWeb.event.unFinished") }}</DropdownItem>
                             </div>
                             <div @click="sentEventStatus('finish')">
                                 <DropdownItem>{{ $t("studentWeb.event.Fineshed") }}</DropdownItem>
                             </div>
-                            <div @click="sentEventStatus('overTime')">
-                                <DropdownItem>{{ $t("studentWeb.event.Timeout") }}</DropdownItem>
+                            <Dropdown placement="right-start">
+                                <DropdownItem>
+                                    时间选择
+                                    <Icon type="ios-arrow-forward"></Icon>
+                                </DropdownItem>
+                                <DropdownMenu slot="list">
+                                    <DropdownItem>学期</DropdownItem>
+                                    <DropdownItem>学年</DropdownItem>
+                                </DropdownMenu>
+                            </Dropdown>
+                            <!--<div @click="sentEventStatus('finish')">
+                                <DropdownItem divided>当月</DropdownItem>
                             </div>
-                            <div @click="sentEventStatus('reExam')">
-                                <DropdownItem divided>{{ $t("studentWeb.event.makeupExam") }}</DropdownItem>
-                            </div>
-                            <div @click="sentEventStatus('reMake')">
-                                <DropdownItem>{{ $t("studentWeb.event.makeupHw") }}</DropdownItem>
+                            <div @click="sentEventStatus('finish')">
+                                <DropdownItem>学期</DropdownItem>
                             </div>
+                            <div @click="sentEventStatus('finish')">
+                                <DropdownItem>学年</DropdownItem>
+                            </div>-->
                         </DropdownMenu>
                     </Dropdown>
                 </div>
@@ -179,6 +189,28 @@
                         iconClass: "quesnaire",
                     },
                 ],
+                activityType: [
+                    {
+                        type: "all",
+                        status:"所有活动状态"
+                    },
+                    {
+                        type: "going",
+                        status:"进行中"
+                    },
+                    {
+                        type: "finish",
+                        status:"已完成"
+                    },
+                    //{
+                    //    type: "all",
+                    //    status:"所有活动状态"
+                    //},
+                    //{
+                    //    type: "all",
+                    //    status:"所有活动状态"
+                    //},
+                ],
                 mockdata: "",
                 eventPageType: ["preview", "exam", "homeWork", "vote", "survey"], //本頁出現的類型
                 openSearch: false, //打開搜尋器
@@ -288,12 +320,10 @@
                 var y = 0;
                 if (!e) var e = window.event;
                 if (e.pageX || e.pageY) {
-                    x =
-                        e.pageX -
+                    x = e.pageX -
                         document.documentElement.scrollLeft -
                         document.body.scrollLeft;
-                    y =
-                        e.pageY -
+                    y = e.pageY -
                         document.documentElement.scrollTop -
                         document.body.scrollTop;
                 } else if (e.clientX || e.clientY) {
@@ -372,6 +402,7 @@
             },
             //下拉数据筛选
             dropDownShowCondition(status, item) {
+                console.log(status,item)
                 if (status == "reMake") {
                     this.hideIconbtn = true;
                     return (
@@ -390,9 +421,15 @@
                         item.isDone == false
                     );
                 } else if (status == "unFinish") {
+                    return (
+                        item.progress == "going"
+                    );
                     this.hideIconbtn = false;
                     return item.isDone == false;
                 } else if (status == "finish") {
+                    return (
+                        item.progress == "finish"
+                    );
                     this.hideIconbtn = false;
                     return item.isDone == true;
                 } else if (status == "overTime") {

+ 3 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/MgtPrivEva.vue

@@ -81,7 +81,7 @@
                 </div>
                 <!-- 试卷评测打分 -->
                 <div :class="curBarIndex == 0 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="curBarIndex == 0">
-                    <Scoring :examInfo="examDetaiInfo" ref="score-box"></Scoring>
+                    <PrivScoring :examInfo="examDetaiInfo" ref="score-box"></PrivScoring>
                 </div>
             </div>
         </Split>
@@ -89,11 +89,11 @@
 </template>
 <script>
 import TestPaper from '@/view/evaluation/index/TestPaper.vue'
-import Scoring from './Scoring.vue'
+import PrivScoring from './PrivScoring.vue'
 export default {
     components: {
         TestPaper,
-        Scoring
+        PrivScoring
     },
     inject: ['reload'],
     data() {

+ 11 - 5
TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue

@@ -320,6 +320,11 @@ export default {
             default: '',
             required: true
         },
+        examScope:{
+            type: String,
+            default: '',
+            required: true
+        },
         subjectId: {
             type: String,
             default: '',
@@ -379,7 +384,7 @@ export default {
                 "subjectId": this.subjectId,
                 "classId": this.studentAnswer.classId,
                 // "code": this.paperInfo.code,//这种方式paper code规则调整了,会多Paper-"
-                "code": this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
+                "code": this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
             }).then(
                 res => {
                     this.$Message.success(this.$t('learnActivity.score.markOk'))
@@ -492,12 +497,12 @@ export default {
             let requestData = {
                 "id": this.examId,
                 // "code": this.paperInfo.code,//这种方式paper code规则调整了,会多Paper-"
-                "code": this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
+                "code": this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
                 "point": this.studentAnswer.scores,
                 "studentId": this.studentAnswer.id,
                 "classId": this.studentAnswer.classId,
                 // "school": this.paperInfo.code,//这种方式paper code规则调整了,会多Paper-"
-                "school": this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
+                "school": this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
                 "subjectId": this.subjectId
             }
             this.$api.learnActivity.UpsertAllRecord(requestData).then(res => {
@@ -580,6 +585,7 @@ export default {
         },
         paperInfo: {
             handler(newPaper) {
+                console.log('newPaper',newPaper)
                 if (newPaper && newPaper.item) {
                     this.dataLoading = true
                     let that = this
@@ -613,8 +619,8 @@ export default {
                 if (!this.studentAnswer.status) {
                     if (newValue.answers.length) {
                         try {
-                            let sas = this.scope == 'school' ? this.$store.state.user.schoolProfile.blob_sas : this.$store.state.user.userProfile.blob_sas
-                            let container = this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
+                            let sas = this.examScope == 'school' ? this.$store.state.user.schoolProfile.blob_sas : this.$store.state.user.userProfile.blob_sas
+                            let container = this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
                             //为了兼容原来完整的路径,这里做判断
                             let a = null
                             if (newValue.answers[0].indexOf('https://teammodelstorage') > -1) {

+ 97 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.less

@@ -0,0 +1,97 @@
+@main-bgColor: rgb(40,40,40); //主背景颜色
+@borderColor: #424242;
+@primary-textColor: #fff; //文本主颜色
+@second-textColor: #a5a5a5; //文本副级颜色
+@primary-fontSize: 14px;
+@second-fontSize: 16px;
+
+.ev-scoring {
+    width: 100%;
+    height: 100%;
+    padding: 0px 0px 20px 0px;
+}
+.ev-scoring {
+    .ev-scoring-header {
+        width: 100%;
+        height: 36px;
+        line-height: 36px;
+        color: @second-textColor;
+        border-bottom: 1px solid @borderColor;
+    }
+
+    .subject-item {
+        display: inline-block;
+        margin-right: 15px;
+        color: @second-textColor;
+        cursor: pointer;
+        line-height: 30px;
+        padding:0px 5px;
+        font-size: 15px;
+        text-align: center;
+        margin-left: 10px;
+    }
+
+    .subject-item-active {
+        color: @primary-textColor;
+        border-bottom: 2px solid white;
+        font-weight: 500;
+    }
+}
+.common-icon-text {
+    color: white;
+    cursor: pointer;
+    user-select: none;
+}
+.scoring-main-wrap {
+    width: ~"calc(100% - 10px)";
+    // width: 100%;
+    height: ~"calc(100% - 45px)";
+}
+
+.ev-target-box {
+    // margin-top: 20px;
+    width: ~"calc(100% - 10px)";
+    color: #ffffff;
+    background: rgba(50, 50, 50, 1);
+    padding: 10px 10px 10px 5px;
+    position: sticky;
+    top: 0px;
+    z-index: 9999;
+    .filter-select {
+        display: inline-block;
+        width: 120px;
+        margin-right: 25px;
+    }
+}
+
+.scoring-handle-box {
+    height: 100%;
+    background:white;
+    padding-bottom:15px;
+}
+
+.stu-status-tag{
+    background: #ed4014;
+    font-size: 12px;
+    padding: 3px 8px;
+    font-weight: 800;
+    border-radius: 4px;
+    color: white;
+}
+.select-status-tag{
+    display: inline-block;
+    width: 7px;
+    height: 7px;
+    border-radius: 50%;
+    margin-right: 5px;
+}
+.simple-analysis-box{
+    width: 100%;
+    height: 200px;
+    // background: white;
+}
+.page-wrap{
+    float: right;
+    margin-top: 15px;
+    color: white;
+}

+ 703 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.vue

@@ -0,0 +1,703 @@
+<template>
+    <div class="ev-scoring dark-iview-table">
+        <vuescroll ref="score-main-warp">
+            <SimpleAnalysis :examInfo="examInfo" v-show="!showTest" :overviewInfo="overviewInfo"></SimpleAnalysis>
+            <div class="ev-target-box dark-iview-select">
+                <span class="filter-label" v-if="examInfo.grades && examInfo.grades.length > 0">{{$t('learnActivity.score.gradeLabel')}}</span>
+                <Select filterable v-model="chooseGrade" class="filter-select" size="small" v-if="examInfo.grades && examInfo.grades.length > 0" style="margin-right:5px" transfer>
+                    <Option v-for="(item,index) in examInfo.grades" :value="item.id" :key="index">{{ item.name }}</Option>
+                </Select>
+                <span>{{$t('learnActivity.score.classLabel')}}</span>
+                <Select filterable v-model="chooseClass" class="filter-select" style="width:140px;" @on-change="getClassStudent" size="small" transfer>
+                    <Option v-for="(item,index) in classList" :value="item.id" :key="index">{{ item.name }}</Option>
+                </Select>
+                <span style="margin-left:5px" v-show="showTest">{{$t('learnActivity.score.stuLabel')}}</span>
+                <Select filterable v-model="chooseStudent.id" label-in-value class="filter-select" style="width:140px;" size="small" clearable @on-change="setStuInfo" v-show="showTest" transfer>
+                    <Option v-for="(item,index) in students" :value="item.id" :key="index">
+                        <span class="select-status-tag" :style="{'background':item.status == 1 ? '#ed4014' : item.status == 2 ? '#ff9900' : '#19be6b'}"></span>
+                        {{ item.name }}
+                    </Option>
+                </Select>
+                <span v-show="showTest" class="common-icon-text" style=" float: right; margin-right: 25px;" @click="toggleScoreStatus" icon="md-apps">
+                    <Icon :custom="showTest ? 'iconfont icon-table':'iconfont icon-scoring'" style="margin-right:5px;" />
+                    {{showTest ? $t('learnActivity.score.scoreView'):$t('learnActivity.score.scoring')}}
+                </span>
+            </div>
+            <div class="scoring-main-wrap">
+                <Table v-show="!showTest" class="score-box" border :columns="tableColumn" :data="tableData" :loading="tableLoading" @on-sort-change="onSortChange" :no-data-text="$t('learnActivity.score.classNoStu')">
+                    <template slot-scope="{ row,index }" :slot="'qu'+qIndex" v-for="(item,qIndex) in quCount">
+                        <div :key="'qu'+qIndex" @click="getStuScore(row,qIndex)" style="cursor:pointer;">
+                            <span @click="noAnswer" v-if="row.data[qIndex] == -1 && row.status == 1">- -</span>
+                            <Icon size="20" type="ios-create-outline" color="#2db7f5" v-else-if="row.data[qIndex] == -1 && row.status !== 1" />
+                            <span style="color:#2db7f5;" v-else>{{row.data[qIndex]}}</span>
+                        </div>
+                    </template>
+                    <!-- <template slot-scope="{ row,index }" slot="total">
+                        <strong>{{getcount(studentScore[row._index].data)}}</strong>
+                    </template> -->
+                    <!-- 1: 未作答 2:未评分 3:已评分 -->
+                    <template slot-scope="{ row,index }" slot="status">
+                        <span class="stu-status-tag" @click="getStuScore(row,0)" :style="{'background':row.status == 1 ? '#c5c8ce' : row.status == 2 ? '#ff9900' : '#19be6b', 'cursor':row.status == 1 ? 'text':'pointer'}">
+                            {{row.status == 1 ? $t('learnActivity.score.status1') : row.status == 2 ? $t('learnActivity.score.status2') : $t('learnActivity.score.status3')}}
+                        </span>
+                    </template>
+                    <Loading slot="loading" :top="-50"></Loading>
+                </Table>
+                <!-- 分页 -->
+                <div class="page-wrap dark-ivew-select" v-show="!showTest">
+                    <Page show-total size="small" :current="currentPage" :total="studentScore.length" :page-size="pageSize" :page-size-opts="pageSizeOpts" @on-change="pageChange" @on-page-size-change="pageSizeChange" show-sizer />
+                </div>
+                <div class="dark-iview-table scoring-handle-box" v-show="showTest">
+                    <PaperScore ref="paperScore" :defaultIndex="defaultIndex" :examId="examInfo.id" :examScope="examInfo.scope" :paper="paperInfo" :studentAnswer="chooseStudent" :subjectId="chooseSubject" @nextStu="getNextStu" style="color:#515a6e;"></PaperScore>
+                    <Loading :top="200" type="1" style="text-align:center" v-show="dataLoading"></Loading>
+                </div>
+            </div>
+        </vuescroll>
+    </div>
+</template>
+<script>
+import PaperScore from "./PaperScore.vue";
+import SimpleAnalysis from "./SimpleAnalysis.vue";
+export default {
+    props: {
+        examInfo: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        }
+    },
+    components: {
+        PaperScore, SimpleAnalysis
+    },
+    data() {
+        return {
+            schoolClassList: [],
+            originData: [],
+            studentScore: [],
+            tableData: [],
+            currentPage: 1,
+            pageSize: 10,
+            pageSizeOpts: [5, 10, 20, 30, 40],
+            overviewInfo: {
+                total: 0,
+                answered: 0,
+                noAnswer: 0,
+                scored: 0,
+                noScore: 0
+            },
+            defaultIndex: 0,
+            tableLoading: false,
+            showTest: false, //是否评分
+            studentData: [],
+            dataLoading: false,
+            chooseGrade: "",
+            chooseClass: "",
+            chooseSubject: "",
+            chooseStudent: {
+                id: "",
+                name: "",
+                scores: [],
+                answers: []
+            },
+            classStudents:[], //校本名单学生列表,可以从这里面获取班级信息
+            scoreList: [
+                {
+                    title: this.$t('learnActivity.score.column1'),
+                    key: "name",
+                    fixed: "left",
+                    align: "center",
+                    minWidth: 150,
+                },
+                {
+                    title: this.$t('learnActivity.score.column2'),
+                    key: "total",
+                    align: "center",
+                    sortable: true,
+                    fixed: "right",
+                    width: 100
+                },
+                {
+                    title: this.$t('learnActivity.score.column3'),
+                    slot: "status",
+                    align: "center",
+                    fixed: "right",
+                    width: 100,
+                }
+            ],
+            tableColumn: [],
+            quCount: [],
+            paperInfo: {},
+            students: [],
+            privStuList: undefined,
+            routerScope: ''
+        }
+    },
+    methods: {
+        // 排序操作
+        onSortChange(data) {
+            let order = data.order // 当前排序方式 升序、降序、正常
+            let key = data.key // 当前排序依据
+            switch (order) {
+                case 'asc':
+                    this.studentScore = this.originData.sort((a, b) => { return Number(a[key]) - Number(b[key]) })
+                    break
+                case 'desc':
+                    this.studentScore = this.originData.sort((a, b) => { return Number(b[key]) - Number(a[key]) })
+                    break
+                case 'normal':
+                    this.studentScore = this.students
+                    break
+                default:
+                    break
+            }
+            console.log('1', this.studentScore[0].name)
+            console.log(2, this.originData[0].name)
+            this.pageChange(1)
+        },
+        // 页面size变化
+        pageSizeChange(val) {
+            this.pageSize = val
+            this.pageChange(1)
+        },
+        // 分页页面变化
+        pageChange(page) {
+            let start = this.pageSize * (page - 1)
+            let end = this.pageSize * page
+            this.currentPage = page
+            this.tableData = this.studentScore.slice(start, end)
+        },
+        toggleScoreStatus() {
+            this.$refs['paperScore'].isComplete = false
+            this.showTest = !this.showTest
+        },
+        getNextStu() {
+            let flag = false
+            for (let index in this.paperInfo[this.chooseClass].studentAns.studentScores) {
+                if (this.paperInfo[this.chooseClass].studentAns.studentScores[index].indexOf(-1) >= 0) {
+                    if (this.paperInfo[this.chooseClass].studentAns.studentAnswers[index].length) {
+                        flag = true
+                        this.chooseStudent.id = this.paperInfo[this.chooseClass].studentAns.studentIds[index]
+                        let curStu = this.students.find(item => {
+                            return item.id == this.chooseStudent.id
+                        })
+                        if (curStu) this.chooseStudent.name = curStu.name
+                        this.chooseStudent.answers = this.paperInfo[this.chooseClass].studentAns.studentAnswers[index]
+                        this.chooseStudent.scores = this.paperInfo[this.chooseClass].studentAns.studentScores[index]
+                        this.chooseStudent.classId = this.chooseClass
+                        this.chooseStudent.status = false
+                        this.$refs['paperScore'].isComplete = false
+                        break
+                    }
+                }
+            }
+            if (!flag) {
+                this.showTest = false
+                this.$Message.warning(this.$t('learnActivity.score.finishScore'))
+            }
+        },
+        //学生未作答提示
+        noAnswer() {
+            this.$Message.warning(this.$t('learnActivity.score.unableScore'))
+        },
+        //点击学生题号前往评分页面
+        getStuScore(data, qIndex) {
+            if (data.status == 2 || data.status == 3) {
+                this.$refs['paperScore'].isComplete = false
+                this.showTest = true
+                this.defaultIndex = qIndex
+                this.chooseStudent.id = data.id
+                this.chooseStudent.name = data.name
+                this.chooseStudent.classId = this.chooseClass
+                let answerIndex = this.paperInfo[this.chooseClass].studentAns.studentIds.indexOf(data.id)
+                if (answerIndex >= 0) {
+                    this.chooseStudent["scores"] = this.paperInfo[this.chooseClass].studentAns.studentScores[answerIndex]
+                    this.chooseStudent["answers"] = this.paperInfo[this.chooseClass].studentAns.studentAnswers[answerIndex]
+                    this.chooseStudent["status"] = false
+                }
+            }
+        },
+        //获取当前学生信息
+        setStuInfo(data) {
+            if (data) {
+                this.chooseStudent.name = data.label;
+                this.chooseStudent.classId = this.chooseClass
+                let answerIndex = this.paperInfo[this.chooseClass].studentAns.studentIds.indexOf(data.value);
+                if (answerIndex >= 0) {
+                    this.chooseStudent["scores"] = this.paperInfo[this.chooseClass].studentAns.studentScores[answerIndex];
+                    this.chooseStudent["answers"] = this.paperInfo[this.chooseClass].studentAns.studentAnswers[answerIndex];
+                    this.chooseStudent["status"] = false;
+                }
+            }
+        },
+        //分数求和
+        getcount(arr) {
+            return arr.reduce((total, item) => {
+                if (item !== -1) {
+                    return total + item;
+                } else {
+                    return total;
+                }
+            }, 0);
+        },
+        // 获取班级名单
+        async getClassStudent() {
+            this.showTest = false
+            this.tableLoading = true
+            if (!this.chooseClass) return
+            let stuRes = undefined
+            try {
+                //个人自定义名单则直接根据学生id换name
+                if (this.examInfo.scope == 'private') {
+                    let stuListInfo = this.privStuList.find(item => {
+                        return item.id == this.chooseClass
+                    })
+                    if (stuListInfo) {
+                        stuRes = await this.$api.courseMgmt.findStuSummary({
+                            students: stuListInfo.students
+                        })
+                    }
+                }
+                //校本名单或教室则根据班级id或学生
+                else {
+                    let requestData = {
+                        ids: [this.chooseClass],
+                        scope: this.examInfo.scope == 'private' ? 'private' : 'school',
+                        // school_code: this.examInfo.scope == 'private' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode,
+                        school_code: this.$store.state.userInfo.schoolCode
+                    }
+                    stuRes = await this.$api.schoolSetting.getClassroomStudent(requestData)
+                }
+            } catch (e) {
+                this.$Message.error('获取学生名单失败')
+            }
+            console.log('***', stuRes)
+            if (!stuRes.error) {
+                if (!this.paperInfo[this.chooseClass]) {
+                    this.paperInfo[this.chooseClass] = {}
+                }
+                let classStu = {
+                    students: this.examInfo.scope == 'private' ? stuRes.stus || [] : stuRes.stus ? stuRes.stus[0] : [],
+                    id: this.chooseClass
+                }
+                this.$set(this.paperInfo[this.chooseClass], "students", classStu)
+                this.students = []
+                this.tableData = []
+                this.studentScore = []
+                this.tableColumn = [...this.scoreList]
+                let defSocre = []
+                if (this.examInfo.progress == 'pending') {//如果评测未发布,没有学生数据,则直接渲染表格
+                    this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0
+                    for (let i = 0; i < this.quCount; i++) {
+                        let data = {
+                            title: "Q" + (i + 1),
+                            slot: "qu" + i,
+                            align: "center",
+                            minWidth: 65,
+                        }
+                        this.tableColumn.push(data)
+                        defSocre.push(-1)
+                    }
+                    let classStu = this.paperInfo[this.chooseClass].students.students
+                    for (let k = 0; k < classStu.length; k++) {
+                        let score = {}
+                        score.name = classStu[k].name
+                        score.id = classStu[k].id
+                        score.data = defSocre
+                        score.total = 0
+                        score.status = 1
+                        this.studentScore.push(score)
+                    }
+                    this.pageChange(1)
+                    this.tableLoading = false
+                } else {//如果获取进行中或已结束则需要拉取学生数据
+                    this.getStudentAnswer()
+                }
+            } else {
+                this.$Message.error("API ERROR!");
+            }
+        },
+        //计算总览数据
+        calcOverView(data) {
+            //计算已作答未作答
+            this.overviewInfo.noAnswer = 0
+            data.studentAnswers.forEach(item => {
+                if (item.length == 0) {
+                    this.overviewInfo.noAnswer++
+                }
+            })
+            this.overviewInfo.answered = data.studentAnswers.length - this.overviewInfo.noAnswer
+            // 计算已评分未评分
+            this.overviewInfo.noScore = 0
+            data.studentScores.forEach(item => {
+                let flag = item.find(item => {
+                    return item == -1
+                })
+                if (flag) {
+                    this.overviewInfo.noScore++
+                }
+            })
+            this.overviewInfo.scored = data.studentScores.length - this.overviewInfo.noScore
+            // 班级总人数
+            this.overviewInfo.total = data.studentIds.length
+        },
+        getStudentAnswer() {
+            this.dataLoading = true
+            let requestData = {
+                id: this.examInfo.id,
+                code: this.examInfo.scope == 'school' ? this.$store.state.user.schoolCode : this.$store.state.userInfo.TEAMModelId,
+                subjectId: this.chooseSubject,
+                classId: this.chooseClass,
+            };
+            this.$api.learnActivity.FindAllStudent(requestData).then(
+                (res) => {
+                    if (res.examClassResults) {
+                        this.paperInfo[this.chooseClass]["studentAns"] = res.examClassResults[0];
+                        this.setTableData();
+                        if (res.examClassResults[0]) {
+                            this.calcOverView(res.examClassResults[0])
+                        }
+                    }
+                },
+                (err) => {
+                    this.$Message.error("API ERROR!");
+                }
+            ).finally(() => {
+                setTimeout(() => {
+                    this.dataLoading = false
+                    this.tableLoading = false
+                }, 500);
+            });
+        },
+        //初始化表单数据
+        setTableData() {
+            if (this.paperInfo[this.chooseClass] && this.paperInfo[this.chooseClass]["students"] && this.paperInfo[this.chooseClass]["studentAns"]) {
+                let studentData = this.paperInfo[this.chooseClass]["students"]
+                let studentAns = this.paperInfo[this.chooseClass]["studentAns"]
+                this.studentScore = []
+                this.tableColumn = [...this.scoreList]
+                this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
+                // this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0 //不用试卷信息计算题目
+                for (let i = 0; i < this.quCount; i++) {
+                    let data = {
+                        title: "Q" + (i + 1),
+                        slot: "qu" + i,
+                        align: "center",
+                        minWidth: 65,
+                    }
+                    this.tableColumn.push(data);
+                }
+                let ans = []
+                for (let i = 0; i < studentAns.studentIds.length; i++) {
+                    for (let k = 0; k < studentData.students.length; k++) {
+                        let score = {}
+                        if (studentAns.studentIds[i] == studentData.students[k].id) {
+                            score.name = studentData.students[k].name
+                            score.id = studentAns.studentIds[i]
+                            score.data = studentAns.studentScores[i]
+                            score.total = this.getcount(score.data)
+                            if (studentAns.studentAnswers[i].length == 0) {//学生未作答
+                                score.status = 1
+                            } else if (studentAns.studentScores[i].indexOf(-1) >= 0) {//已作答,未评分
+                                score.status = 2
+                            } else {//已批改
+                                score.status = 3
+                            }
+                            this.studentScore.push(score)
+                        }
+                    }
+                }
+                this.originData = this._.cloneDeep(this.studentScore)
+                this.students = this._.cloneDeep(this.studentScore)
+                this.pageChange(1)
+                if (ans.length) {
+                    for (let k = 0; k < this.paperInfo.papers.item.length; k++) {
+                        this.$set(
+                            this.paperInfo.papers.item[k],
+                            "answerData",
+                            ans[k]
+                        );
+                        this.$set(
+                            this.paperInfo.papers.item[k],
+                            "stuScore",
+                            score[k]
+                        );
+                    }
+                }
+            }
+
+        },
+        getBack(data) {
+            if (data == "1") {
+                this.getClassStudent();
+            }
+            this.showTest = false;
+        },
+        //获取单个学生作答数据
+        getStudentInfo(data, index) {
+            this.dataLoading = true;
+            if (this.studentInfo !== undefined) {
+                let filData = "";
+                filData = this.studentInfo.id;
+                let ans = [];
+                let score = [];
+                for (let i = 0; i < this.classDatas.studentIds.length; i++) {
+                    if (this.classDatas.studentIds[i] == filData) {
+                        ans = this.classDatas.studentAnswers[i];
+                        score = this.classDatas.studentScores[i];
+                    }
+                }
+                if (ans.length) {
+                    for (let k = 0; k < this.paperInfo.papers.item.length; k++) {
+                        this.$set(this.paperInfo.papers.item[k], "answerData", ans[k]);
+                        this.$set(this.paperInfo.papers.item[k], "stuScore", score[k]);
+                    }
+                }
+                this.dataLoading = false;
+            } else {
+                this.dataLoading = false;
+                this.$Message.warning(this.$t('learnActivity.score.stStuWarning'));
+            }
+            this.selectIndex = index;
+        },
+        getAnswer(data) {
+            //处理学生作答信息
+            let listArr = [];
+            data.forEach(function (el, index) {
+                for (var i = 0; i < listArr.length; i++) {
+                    if (listArr[i].group == el.group) {
+                        listArr[i].listInfo.push(el);
+                        return;
+                    }
+                }
+                listArr.push({
+                    group: el.group,
+                    listInfo: [el],
+                });
+            });
+            return listArr;
+        },
+    },
+    watch: {
+        examInfo: {
+            handler(n, o) {
+                this.privStuList = undefined
+                if (n.subjects && n.subjects.length) {
+                    this.chooseSubject = n.subjects[0].id;
+                }
+                if (n.grades && n.grades.length) {
+                    this.chooseGrade = n.grades[0].id;
+                }
+                if (n.papers && n.papers.length) {
+                    this.paperInfo = n.papers[0] //个人评测只有单科
+                } else {
+                    this.paperInfo = {};
+                }
+                if (n.scope == 'school') {
+                    let requestData = {
+                        ids: this.examInfo.targetClassIds,
+                        scope: this.examInfo.scope,
+                        school_code: this.$store.state.userInfo.schoolCode
+                    }
+                    this.$api.schoolSetting.getClassroomStudent(requestData).then(
+                        res => {
+                            if (res && res.stus) {
+                                this.classStudents = res.stus
+                            }
+                        },
+                        err => {
+                            console.log('获取发布对象失败')
+                        }
+                    )
+                }
+            },
+            deep: true,
+        },
+        classList: {
+            handler(n, o) {
+                if (n && n.length) {
+                    this.chooseClass = n[0].id;
+                    this.getClassStudent();
+                } else {
+                    this.chooseClass = undefined
+                }
+            },
+            deep: true,
+        },
+        chooseStudent: {
+            handler(n, o) {
+                if (n.id) {
+                    let curStu = this.studentScore.find(item => {
+                        return item.id == n.id
+                    })
+                    if (curStu.status == 2) {
+                        let flag = n.scores.find(item => {
+                            return item == -1
+                        })
+                        if (!flag) {
+                            curStu.status = 3
+                            this.overviewInfo.noScore--
+                            this.overviewInfo.scored++
+                        }
+                    }
+                }
+            },
+            deep: true
+        }
+    },
+    computed: {
+        classList() {
+            if (this.examInfo && this.examInfo.targetClassIds) {
+                //发布对象为校本名单
+                if (this.examInfo.scope == 'school') {
+                    this.showTest = false
+                    //classStudents 监听评测数据的时候就获取了
+                    let classes = this.classStudents.map(item=>{
+                        return {
+                            id: item[0].classId,
+                            name: item[0].className
+                        }
+                    })
+                    console.log('班级学生数据',classes)
+                    return classes
+                }
+                // 发布对象为个人创建的自定义名单
+                else {
+                    if (!this.privStuList) {
+                        //查询当前老师所有stulist
+                        let params = {
+                            code: this.$store.state.userInfo.TEAMModelId,
+                            scope: 'private'
+                        }
+                        this.$api.courseMgmt.findStulist(params).then(
+                            res => {
+                                this.privStuList = res.stuList
+                            },
+                            err => {
+                                this.$Message.error('API error')
+                            }
+                        )
+                        return this.privStuList
+                    } else {
+                        //过滤当前评测对象
+                        let list = this.privStuList.filter(item => {
+                            return this.examInfo.targetClassIds.indexOf(item.id) >= 0
+                        })
+                        return list
+                    }
+                }
+            } else {
+                return []
+            }
+        },
+    },
+    created() {
+        this.$store.dispatch('user/getSchoolProfile').then(
+            res => {
+                this.schoolBase = res.school_base
+                this.schoolClassList = res.school_classes
+            }
+        )
+        if (this.$route.name == 'privateEvaluation') {
+            this.routerScope = 'private'
+        } else {
+            this.routerScope = 'school'
+        }
+    }
+};
+</script>
+
+<style scoped lang="less">
+@import "./Scoring.less";
+</style>
+<style lang="less">
+.scoring-main-wrap .ivu-table-fixed-body {
+    background: #353535;
+    // background: #2b2b2e;
+    // max-height: 653px;
+}
+.scoring-main-wrap .ivu-table-tip {
+    position: relative;
+    z-index: 9999;
+}
+.scoring-main-wrap .ivu-table-fixed-right::before,
+.scoring-main-wrap .ivu-table-fixed::before {
+    display: none;
+}
+.scoring-main-wrap .ivu-table-fixed-header thead tr th {
+    background: #353535;
+    // background: #2b2b2e;
+    border-color: #606060;
+    color: white;
+}
+.scoring-main-wrap {
+    .ivu-table-header thead tr th {
+        // background: #353535;
+        background: rgba(53, 53, 53, 0.5);
+    }
+    .ivu-table td {
+        // background: #353535;
+        background: rgba(53, 53, 53, 0.5);
+    }
+}
+.page-wrap .ivu-page-item {
+    background: rgba(40, 40, 40, 0.5);
+}
+
+.page-wrap .ivu-page-item:hover {
+    border-color: #e4eadb;
+}
+
+.page-wrap .ivu-page-item-active {
+    background: #bfbfb9;
+}
+
+.page-wrap .ivu-page-item a {
+    color: #f1f1f1;
+}
+
+.page-wrap .ivu-page-next,
+.page-wrap .ivu-page-prev {
+    background: rgba(0, 0, 0, 0);
+}
+
+.page-wrap .ivu-page-next a,
+.page-wrap .ivu-page-prev a {
+    color: #e4eadb;
+}
+
+.page-wrap .ivu-page-next:hover,
+.page-wrap .ivu-page-prev:hover {
+    border-color: #e4eadb;
+}
+
+.page-wrap .ivu-page-item-active,
+.page-wrap .ivu-page-item:hover a {
+    border-color: #e4eadb;
+}
+
+.page-wrap .ivu-page-item-active a {
+    color: #595959;
+}
+.page-wrap
+    .ivu-select-small.ivu-select-single
+    .ivu-select-selection
+    .ivu-select-selected-value {
+    height: 27px;
+    line-height: 27px;
+    font-size: 12px;
+}
+.page-wrap .ivu-select-single .ivu-select-selection {
+    height: 30px;
+    background: transparent;
+    border: 1px solid #595959;
+    box-shadow: none;
+    color: #cecece;
+}
+
+.page-wrap .ivu-select-single .ivu-select-placeholder {
+    height: 30px;
+    line-height: 30px;
+    font-size: 16px;
+}
+</style>

+ 45 - 25
TEAMModelOS/ClientApp/src/view/learnactivity/Scoring.vue

@@ -3,16 +3,16 @@
         <vuescroll ref="score-main-warp">
             <SimpleAnalysis :examInfo="examInfo" v-show="!showTest" :overviewInfo="overviewInfo"></SimpleAnalysis>
             <div class="ev-target-box dark-iview-select">
-                <span class="filter-label" v-show="examInfo.grades.length > 0">{{$t('learnActivity.score.gradeLabel')}}</span>
-                <Select filterable v-model="chooseGrade" class="filter-select" size="small" v-show="examInfo.grades.length > 0" style="margin-right:5px" transfer>
+                <span class="filter-label" v-if="examInfo.grades && examInfo.grades.length > 0">{{$t('learnActivity.score.gradeLabel')}}</span>
+                <Select filterable v-model="chooseGrade" class="filter-select" size="small" v-if="examInfo.grades && examInfo.grades.length > 0" style="margin-right:5px" transfer>
                     <Option v-for="(item,index) in examInfo.grades" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
                 <span>{{$t('learnActivity.score.classLabel')}}</span>
                 <Select filterable v-model="chooseClass" class="filter-select" style="width:140px;" @on-change="getClassStudent" size="small" transfer>
                     <Option v-for="(item,index) in classList" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
-                <span class="filter-label" v-show="examInfo.scope == 'school'">{{$t('learnActivity.score.subjectLabel')}}</span>
-                <Select filterable v-model="chooseSubject" class="filter-select" size="small" @on-change="getCurPaper" v-show="examInfo.scope == 'school'" transfer>
+                <span class="filter-label" v-show="examInfo.code == 'Exam-'+$store.state.userInfo.schoolCode">{{$t('learnActivity.score.subjectLabel')}}</span>
+                <Select filterable v-model="chooseSubject" class="filter-select" size="small" @on-change="getCurPaper" v-show="examInfo.code == 'Exam-'+$store.state.userInfo.schoolCode" transfer>
                     <Option v-for="(item,index) in examInfo.subjects" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
                 <span style="margin-left:5px" v-show="showTest">{{$t('learnActivity.score.stuLabel')}}</span>
@@ -52,7 +52,7 @@
                     <Page show-total size="small" :current="currentPage" :total="studentScore.length" :page-size="pageSize" :page-size-opts="pageSizeOpts" @on-change="pageChange" @on-page-size-change="pageSizeChange" show-sizer />
                 </div>
                 <div class="dark-iview-table scoring-handle-box" v-show="showTest">
-                    <PaperScore ref="paperScore" :defaultIndex="defaultIndex" :examId="examInfo.id" :paper="paperInfo" :studentAnswer="chooseStudent" :subjectId="chooseSubject" @nextStu="getNextStu" style="color:#515a6e;"></PaperScore>
+                    <PaperScore ref="paperScore" :defaultIndex="defaultIndex" :examId="examInfo.id" :examScope="examInfo.scope" :paper="paperInfo" :studentAnswer="chooseStudent" :subjectId="chooseSubject" @nextStu="getNextStu" style="color:#515a6e;"></PaperScore>
                     <Loading :top="200" type="1" style="text-align:center" v-show="dataLoading"></Loading>
                 </div>
             </div>
@@ -129,13 +129,11 @@ export default {
                 }
             ],
             tableColumn: [],
-
             quCount: [],
             paperInfo: {},
             students: [],
-            privClassList: undefined,
+            privStuList: undefined,
             routerScope: ''
-
         }
     },
     methods: {
@@ -210,6 +208,7 @@ export default {
             let paperInfo = this.examInfo.papers.find((item) => {
                 return item.subjectId == this.chooseSubject;
             })
+            console.log('试卷数据', paperInfo)
             this.paperInfo = this._.cloneDeep(paperInfo)
             this.getClassStudent()
         },
@@ -261,11 +260,11 @@ export default {
             let requestData = {
                 ids: [this.chooseClass],
                 scope: this.examInfo.scope == 'private' ? 'private' : 'school',
-                school_code: this.examInfo.scope == 'private' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode,
+                // school_code: this.examInfo.scope == 'private' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode,
+                school_code: this.$store.state.userInfo.schoolCode
             };
             this.$api.schoolSetting.getClassroomStudent(requestData).then((res) => {
                 if (!res.error) {
-                    console.log('paper', this.paperInfo)
                     if (!this.paperInfo[this.chooseClass]) {
                         this.paperInfo[this.chooseClass] = {}
                     }
@@ -372,8 +371,8 @@ export default {
                 let studentAns = this.paperInfo[this.chooseClass]["studentAns"]
                 this.studentScore = []
                 this.tableColumn = [...this.scoreList]
-                // this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
-                this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0
+                this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
+                // this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0 //不用试卷信息计算题目
                 for (let i = 0; i < this.quCount; i++) {
                     let data = {
                         title: "Q" + (i + 1),
@@ -477,7 +476,7 @@ export default {
     watch: {
         examInfo: {
             handler(n, o) {
-                this.privClassList = undefined
+                this.privStuList = undefined
                 if (n.subjects && n.subjects.length) {
                     this.chooseSubject = n.subjects[0].id;
                 }
@@ -485,9 +484,8 @@ export default {
                 if (n.grades && n.grades.length) {
                     this.chooseGrade = n.grades[0].id;
                 }
-                console.log('评测详细信息', n)
                 if (n.papers && n.papers.length) {
-                    if (n.scope == 'school') {
+                    if (n.code == 'Exam' + this.$store.state.userInfo.schoolCode) { //**现在不能通过scope判断是校本还是个人发布的评测
                         let res = n.papers.find((item) => {
                             return item.subjectId == this.chooseSubject;
                         });
@@ -536,29 +534,51 @@ export default {
     computed: {
         classList() {
             if (this.examInfo && this.examInfo.targetClassIds) {
+                //发布对象为校本名单
                 if (this.examInfo.scope == 'school') {
                     this.showTest = false
                     let classes = this.schoolClassList.filter(item => {
                         return this.examInfo.targetClassIds.indexOf(item.id) >= 0 && (item.gradeId == this.chooseGrade || !this.chooseGrade)
                     })
                     return classes
-                } else {
+                }
+                // 发布对象为个人创建的自定义名单
+                else {
                     //根据targetClassIds查询班级信息
-                    if (!this.privClassList) {
-                        this.$api.schoolSetting.getClassByIds({
+                    if (!this.privStuList) {
+                        // this.$api.schoolSetting.getClassByIds({
+                        //     code: this.$store.state.userInfo.TEAMModelId,
+                        //     ids: this.examInfo.targetClassIds
+                        // }).then(
+                        //     res => {
+                        //         if (res.className && res.className.length) this.chooseClass = res.className[0].id
+                        //         this.privStuList = res.className
+                        //     },
+                        //     err => {
+                        //         console.log(err)
+                        //     }
+                        // )
+                        //查询当前老师所有stulist
+                        let params = {
                             code: this.$store.state.userInfo.TEAMModelId,
-                            ids: this.examInfo.targetClassIds
-                        }).then(
+                            scope: 'private'
+                        }
+                        this.$api.courseMgmt.findStulist(params).then(
                             res => {
-                                if (res.className && res.className.length) this.chooseClass = res.className[0].id
-                                this.privClassList = res.className
+                                this.privStuList = res.stuList
                             },
                             err => {
-                                console.log(err)
+                                this.$Message.error('API error')
                             }
                         )
+                        return this.privStuList
+                    } else {
+                        //过滤当前评测对象
+                        let list = this.privStuList.filter(item => {
+                            return this.examInfo.targetClassIds.indexOf(item.id) >= 0
+                        })
+                        return list
                     }
-                    return this.privClassList
                 }
             } else {
                 return []
@@ -590,7 +610,7 @@ export default {
 .scoring-main-wrap .ivu-table-fixed-body {
     background: #353535;
     // background: #2b2b2e;
-    max-height: 653px;
+    // max-height: 653px;
 }
 .scoring-main-wrap .ivu-table-tip {
     position: relative;

+ 7 - 10
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -59,7 +59,7 @@
                     <div class="course-classroom-list" slot="left">
                         <div class="course-classroom-list-header">
                             <span class="course-classroom-label">{{$t('courseManage.classroom.classroomList')}}</span>
-                            <Icon custom="iconfont icon-schedule" v-show="listType == 'school'" class="add-icon" size="16" title="课表模式" />
+                            <!-- <Icon custom="iconfont icon-schedule" v-show="listType == 'school'" class="add-icon" size="16" title="课表模式" /> -->
                             <Icon type="md-add" v-show="listType == 'private'" class="add-icon" @click="newSlStatus = true" />
                             <!-- 暂未处理编辑个人自定义名单 -->
                             <!-- <Icon type="md-create" v-show="listType == 'private' && teaClassList.length" class="add-icon" @click="editClassStatus = true" /> -->
@@ -68,17 +68,18 @@
                         <div class="course-classroom-list-content">
                             <vuescroll>
                                 <div v-for="(item,index) in teaClassList" :key="index" @click="changeClassroom(index)" :class="['block-bg','tea-class-item',curClassIndex == index ? 'block-bg-active':'']">
-                                    <p class="class-attr-item">
+                                    <p class="class-attr-item" v-show="listType == 'school'">
                                         <span class="attr-label">教室:</span>
                                         <span class="class-name">{{item.classId ? item.classInfo.name:'未设置'}}</span>
-                                        <!-- <span class="class-label" :style="{color:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900',borderColor:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900'}">
-                                                    {{item.type}}
-                                                </span> -->
                                     </p>
                                     <p class="class-attr-item">
                                         <span class="attr-label">名单:</span>
                                         <span :class="item.stulist ? 'class-name':'def-class-name'">{{item.stulist ? item.listName : '默认名单'}}</span>
                                     </p>
+                                    <p class="class-attr-item" v-show="listType == 'private'">
+                                        <span class="attr-label">学生数:</span>
+                                        <span class="class-name">{{item.students ? item.students.length : 0}}人</span>
+                                    </p>
                                 </div>
                                 <EmptyData v-if="teaClassList.length == 0" :top="160" textContent="暂无上课名单"></EmptyData>
                             </vuescroll>
@@ -752,7 +753,7 @@ export default {
                     'link', // 插入链接
                     'image' // 插入图片
                 ],
-                    noticeEditor.customConfig.showLinkImg = false
+                noticeEditor.customConfig.showLinkImg = false
                 noticeEditor.customConfig.uploadFileName = 'files'
                 noticeEditor.create()
                 noticeEditor.txt.html(this.listType == 'school' ? this.courseListS[this.curCusIndex][0].notice : this.courseListP[this.curCusIndex].notice)
@@ -829,10 +830,6 @@ export default {
                         notice: '',
                         listName: this.listName,
                         stulist: stuList.id,
-                        // teacher: {
-                        //     id: this.$store.state.userInfo.TEAMModelId,
-                        //     name: this.$store.state.userInfo.name
-                        // },
                         teacherId: this.$store.state.userInfo.TEAMModelId,
                         teacherName: this.$store.state.userInfo.name,
                         time:[]

+ 14 - 54
TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue

@@ -185,57 +185,6 @@
                             </vuescroll>
                         </div>
                     </div>
-                    <!-- 添加名单UI 单个添加 暂时去掉-->
-                    <div slot="right" class="class-setting dark-el-cascader dark-iview-select dark-iview-table" style="display:none">
-                        <div class="add-list-header">
-                            <span class="add-list-label">教室:</span>
-                            <el-cascader size="small" placeholder="请设置上课教室" :show-all-levels="false" clearable v-model="schedule.classId" :options="csOptions" :props="props" @change="setClassName($event,'insert')" style="width:180px;">
-                            </el-cascader>
-                            <span v-show="schedule.classId" class="attr-label" style="margin-left:20px">默认名单</span>
-                            <Tooltip v-show="schedule.classId" content="默认名单为教室对应的名单,否则需要指定自定义名单。" max-width="200">
-                                <Icon type="ios-information-circle-outline" style="margin-left:2px;margin-right:5px" />
-                            </Tooltip>
-                            <span v-show="schedule.classId">
-                                <i-switch v-model="preDefault" size="small" />
-                            </span>
-                            <span class="add-list-label" v-show="!preDefault || !schedule.classId" style="margin-left:40px">名单:</span>
-                            <Select ref="sltStuList" v-show="!preDefault || !schedule.classId" clearable v-model="schedule.stulist" style="width:200px;margin-right:5px" size="small">
-                                <Option v-for="(item,index) in stuList" :value="item.id" :key="index" @click.native="getStuList(item.name)">{{ item.name }}</Option>
-                            </Select>
-                            <Icon type="md-add-circle" v-show="!preDefault || !schedule.classId" class="create-list-icon" @click="addStuListStatus = true" />
-                            <div class="action-btn-wrap">
-                                <span class="action-btn" style="margin-right:40px" @click="confirmAddSchd">
-                                    <Icon type="md-add" size="16" />
-                                    <span>确认添加</span>
-                                </span>
-                                <span class="action-btn" @click="cancelAddSchd">
-                                    <Icon type="md-close" size="16" />
-                                    <span>取消添加</span>
-                                </span>
-                            </div>
-                        </div>
-                        <Table :columns="schedule.stulist ? listColumn : classColumn" :data="preStus" class="stu-list-table" :loading="stuLoading" no-data-text="暂无学生">
-                            <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
-                            <template slot-scope="{ row }" slot="picture">
-                                <PersonalPhoto :name="row.name" :picture="row.picture" />
-                            </template>
-                            <template slot-scope="{ row,index }" slot="no">
-                                <span>{{row.no}}</span>
-                            </template>
-                            <template slot-scope="{ row ,index}" slot="action">
-                                <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
-                                    <Icon type="md-create" size="18" color="white" @click="resetNo(index)" :title="$t('schoolBaseInfo.editSeat')" />
-                                    <Icon type="md-remove-circle" size="18" color="white" style="margin-left:10px" @click="removeStudent(index)" :title="$t('schoolBaseInfo.delStuBtn')" />
-                                </div>
-                            </template>
-                            <template slot-scope="{ row, index }" slot="groupId">
-                                <span>{{row.groupId ? row.groupId : '- -'}}</span>
-                            </template>
-                            <template slot-scope="{ row, index }" slot="groupName">
-                                <span>{{row.groupName ? row.groupName : '未分组'}}</span>
-                            </template>
-                        </Table>
-                    </div>
                     <!-- 添加名单UI 批量添加-->
                     <div slot="right" class="class-setting dark-iview-input dark-iview-select dark-iview-table" v-show="isAddStuList">
                         <vuescroll>
@@ -256,12 +205,12 @@
                                     </span>
                                 </div>
                             </div>
-                            <Table v-show="addType == 'class'" :columns="classroomCol" :data="calssTable" style="margin-top:10px" @on-selection-change="(selection)=>{sltClass = selection}">
+                            <Table ref="sltClass" v-show="addType == 'class'" :columns="classroomCol" :data="calssTable" style="margin-top:10px" @on-selection-change="(selection)=>{sltClass = selection}">
                                 <template slot-scope="{ row }" slot="grade">
                                     <span>{{$jsFn.getGradeName(schoolBase,row.gradeId)}}</span>
                                 </template>
                             </Table>
-                            <Table v-show="addType == 'stulist'" :columns="listCol" :data="stuList" style="margin-top:10px" @on-selection-change="(selection)=>{sltList = selection}">
+                            <Table ref="sltList" v-show="addType == 'stulist'" :columns="listCol" :data="stuList" style="margin-top:10px" @on-selection-change="(selection)=>{sltList = selection}">
                                 <template slot-scope="{ row }" slot="count">
                                     <span>{{row.students.length}}</span>
                                 </template>
@@ -284,7 +233,7 @@
                                     </span>
                                 </div>
                             </div>
-                            <Table :columns="teaCol" :data="teacherList" style="margin-top:10px" @on-selection-change="(selection)=>{sltTeachers = selection}">
+                            <Table ref="sltTea" :columns="teaCol" :data="teacherList" style="margin-top:10px" @on-selection-change="(selection)=>{sltTeachers = selection}">
                                 <template slot-scope="{ row }" slot="picture">
                                     <PersonalPhoto :name="row.name" :picture="row.picture" />
                                 </template>
@@ -630,6 +579,11 @@ export default {
                 }
             )
         },
+        clearTable(){
+            this.$refs.sltTea.selectAll(false)
+            this.$refs.sltList.selectAll(false)
+            this.$refs.sltClass.selectAll(false)
+        },
         selectCus(index) {
             this.selectClass(0)
             this.selectTea(0)
@@ -850,6 +804,7 @@ export default {
                         this.courseListShow[this.curCusIndex].schedule.push(JSON.parse(JSON.stringify(this.schedule)))
                     }
                 })
+                this.sltClass = []
             } else if (this.addType == 'stulist' && this.sltList.length > 0) {
                 //先判断是否有空的schedule(只是添加了老师,没有教室和名单)
                 this.courseListShow[this.curCusIndex].schedule.forEach((item, index) => {
@@ -868,6 +823,7 @@ export default {
                         this.courseListShow[this.curCusIndex].schedule.push(JSON.parse(JSON.stringify(this.schedule)))
                     }
                 })
+                this.sltList = []
             } else {
                 this.$Message.warning('请先选择名单或者教室')
                 return
@@ -875,11 +831,13 @@ export default {
             this.isAddStuList = false
             this.updCusInfo()
             this.initSchedule()
+            this.clearTable()
         },
         //取消添加Schd
         cancelAddSchd() {
             this.isAddStuList = false
             this.initSchedule()
+            this.clearTable()
         },
         //确认或取消添加后初始化数据
         initSchedule() {
@@ -898,6 +856,7 @@ export default {
         //取消添加老师
         cancelAddTea() {
             this.addTeaStatus = false
+            this.clearTable()
         },
         //确认添加教师
         confirmAddTea() {
@@ -920,6 +879,7 @@ export default {
                 })
                 this.updCusInfo()
                 this.sltTeachers = []
+                this.clearTable()
             }
         },
         // 更新课程数据

+ 8 - 7
TEAMModelOS/ClientApp/src/view/newcourse/TimeSetting.vue

@@ -12,9 +12,9 @@
                                     <span class="content">{{ '('+item.label+')'}}</span>
                                 </div>
                                 <div class="action-box">
-                                    <Icon type="md-add" @click="showAddTime(curTmIndex)" color="white" size="18" style="cursor:pointer;" />
-                                    <Icon type="md-trash" @click="delTimeNode(curTmIndex)" color="white" size="18" style="cursor:pointer;" />
-                                    <Icon type="md-create" @click="editTimeNode(curTmIndex)" color="white" size="18" style="cursor:pointer;" />
+                                    <Icon type="md-add" @click="showAddTime(index)" color="white" size="18" style="cursor:pointer;" />
+                                    <Icon type="md-trash" @click="delTimeNode(index)" color="white" size="18" style="cursor:pointer;" />
+                                    <Icon type="md-create" @click="editTimeNode(index)" color="white" size="18" style="cursor:pointer;" />
                                 </div>
                             </div>
                         </TimelineItem>
@@ -28,16 +28,16 @@
                 </vuescroll>
             </div>
         </div>
-        <Modal v-model="addTimeStatus" :title="status == 0 ? '添加节点' : '编辑节点'" class-name="dark-iview-modal dark-iview-form" @on-ok="confirmAddTime" @on-cancel="initTimeNode">
+        <Modal v-model="addTimeStatus" :title="status == 0 ? '添加时段' : '编辑时段'" class-name="dark-iview-modal dark-iview-form" @on-ok="confirmAddTime" @on-cancel="initTimeNode">
             <Form ref="timeNode" :model="timeNode" :label-width="80" label-colon :rules="ruleValidate">
                 <FormItem label="名称" prop="label">
-                    <Input v-model="timeNode.label" placeholder="输入节点名称......" style="width: 240px"></Input>
+                    <Input v-model="timeNode.label" placeholder="输入时段名称......" style="width: 240px"></Input>
                 </FormItem>
                 <FormItem label="开始" prop="start">
-                    <TimePicker v-model="timeNode.start" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
+                    <TimePicker v-model="timeNode.start" :steps="[1, 5]" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
                 </FormItem>
                 <FormItem label="结束">
-                    <TimePicker v-model="timeNode.end" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
+                    <TimePicker v-model="timeNode.end" :steps="[1, 5]" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
                 </FormItem>
                 <FormItem label="类型" prop="type">
                     <RadioGroup v-model="timeNode.type" style="color: white;">
@@ -106,6 +106,7 @@ export default {
         },
         //编辑时间节点
         editTimeNode(index) {
+            console.log(index)
             this.status = 1
             this.timeNodeIndex = index
             let times = this.timetable[index].time.split(' - ')

+ 17 - 1
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -844,6 +844,22 @@ namespace TEAMModelOS.Controllers
                 List<string> classIds = new List<string>();
                 //存放当前学生所在班级ID或者名单ID
                 HashSet<string> resultIds = new HashSet<string>();
+                //List<string> ids = new List<string>();
+                //处理班级人数(公共部分的校本名单)
+                //List<Student> students = new List<Student>();
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select c.classId id from c where c.id = '{studentId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{school}") }))
+                {
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                        while (accounts.MoveNext())
+                        {
+                            JsonElement account = accounts.Current;
+                            resultIds.Add(account.GetProperty("id").GetString());
+                        }
+                    }
+                }
                 //获取自定义名单信息
                 List<StuList> stuLists = new List<StuList>();
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: $"select c.id from c join A0 in c.students where A0.id = '{studentId}'" ,
@@ -878,7 +894,7 @@ namespace TEAMModelOS.Controllers
                         }
 
                     }
-                    
+
                 }
                 //存放该学生所在班级参与当前评测的ID
                 List<string> infoIds = new List<string>();

+ 22 - 4
TEAMModelOS/Controllers/Core/ImportController.cs

@@ -253,7 +253,7 @@ namespace TEAMModelOS.Controllers
         }
 
         /// <summary>
-        /// htmlString AnalyzeHtml
+        /// word直接转题目
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
@@ -268,16 +268,34 @@ namespace TEAMModelOS.Controllers
              (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(doc);
             return Ok(new { tests, emferror= error });
         }
+
+
+        /// <summary>
+        /// word转html
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("parse-docx")]
+        public IActionResult ParseDocx([FromForm] IFormFile file)
+        {
+            if (!FileType.GetExtention(file.FileName).ToLower().Equals("docx"))
+            {
+                return BadRequest(new Dictionary<string, object> { { "msg", "type is not docx!" }, { "code", ResponseCode.FAILED } });
+            }
+            var doc = _DOXC2HTMLTranslator.Translate(file.OpenReadStream());
+           // (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(doc);
+            return Ok(new { html= doc });
+        }
         /// <summary>
-        /// htmlString AnalyzeHtml
+        /// html转题目
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
         [HttpPost("parse-html")]
         public IActionResult AnalyzeHtml(JsonElement request)
         {
-            if (!request.TryGetProperty("htmlString", out JsonElement htmlString)) { return BadRequest(); }
-            (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(htmlString.GetString());
+            if (!request.TryGetProperty("html", out JsonElement html)) { return BadRequest(); }
+            (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(html.GetString());
             return Ok(new { tests, emferror= error });
         }
 

+ 33 - 19
TEAMModelOS/Controllers/School/ClassRoomController.cs

@@ -402,7 +402,7 @@ namespace TEAMModelOS.Controllers
                     //ids.Add(id[i].ToJsonString());
                     info += ids[i].ToJsonString() + ",";
                 }
-                List<object> scList = new List<object>();
+                //List<object> scList = new List<object>();
                 List<object> suList = new List<object>();
                 List<(string id, string name, string pic, string code, string classId ,string groupId, string groupName, string no)> listStudent = new List<(string id, string name, string pic, string code, string classId, string groupId, string groupName, string no)>();
                 //var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(ids[i].GetString(), new PartitionKey($"Class-{schoolId}"));
@@ -452,7 +452,7 @@ namespace TEAMModelOS.Controllers
                         }
                     }
                 }
-                var scinfos = listStudent.Select(o =>
+                var grpBalance = listStudent.GroupBy(m => new { m.classId }).Distinct().Select(t =>t.ToList().Select(o =>
                                     new
                                     {
                                         o.id,
@@ -464,9 +464,9 @@ namespace TEAMModelOS.Controllers
                                         o.groupId,
                                         o.groupName,
                                         o.no
-                                    });
-                scList.AddRange(scinfos);
-                stus.Add(scList);
+                                    })
+                );
+                stus.AddRange(grpBalance);              
                 List<(string id, string code, string stuId, string name)> listStuList = new List<(string id, string code, string stuId, string name)>();
                 if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
                 {
@@ -488,16 +488,27 @@ namespace TEAMModelOS.Controllers
                             }
 
                         }
-                        var infos = listStuList.Select(o =>
+                        var infos = listStuList.GroupBy(m => new { m.stuId }).Distinct().Select(t => new
+                        {
+                            stuId = t.ToList().Select(o =>
+                                    new
+                                    {
+                                        o.id,
+                                        o.code,
+                                        o.stuId,
+                                        o.name
+                                    })
+                        });
+/*                        var infos = listStuList.Select(o =>
                                     new
                                     {
                                         o.id,
                                         o.code,
                                         o.stuId,
                                         o.name
-                                    });
-                        suList.AddRange(infos);
-                        stus.Add(suList);
+                                    });*/
+                        stus.AddRange(infos);
+                        //stus.Add(suList);
                     }
                 }
                 else
@@ -531,16 +542,19 @@ namespace TEAMModelOS.Controllers
                                 }
                             }
                         }
-                        var infos = listStuList.Select(o =>
-                                   new
-                                   {
-                                       o.id,
-                                       o.code,
-                                       o.stuId,
-                                       o.name
-                                   });
-                        suList.AddRange(infos);
-                        stus.Add(suList);
+                        var infos = listStuList.GroupBy(m => new { m.stuId }).Distinct().Select(t => new
+                        {
+                            stuId = t.ToList().Select(o =>
+                                    new
+                                    {
+                                        o.id,
+                                        o.code,
+                                        o.stuId,
+                                        o.name
+                                    })
+                        });
+                        stus.AddRange(infos);
+                        //stus.Add(suList);
                     }
                 }             
                 return Ok(new { stus });