Explorar o código

Merge branch 'develop5.0-tmd' of http://106.12.23.251:10000/TEAMMODEL/TEAMModelOS into develop5.0-tmd

zhouj1203@hotmail.com %!s(int64=3) %!d(string=hai) anos
pai
achega
17baac15e0

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/en-US/learnActivity.js

@@ -311,7 +311,7 @@ export default{
         unmark:'未阅',
         fullScore:'满分',
         zeroScore:'零分',
-        submit:'提交分数',
+        submit:'提交分数/批注',
         setting1:'打分自动切换学生',
         setting2:'完成批阅自动弹出切换',
         setting3:'打分自动切换题目',

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/learnActivity.js

@@ -312,7 +312,7 @@ export default{
         unmark:'未阅',
         fullScore:'满分',
         zeroScore:'零分',
-        submit:'提交分数',
+        submit:'提交分数/批注',
         setting1:'打分自动切换学生',
         setting2:'完成批阅自动弹出切换',
         setting3:'打分自动切换题目',

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/learnActivity.js

@@ -311,7 +311,7 @@ export default {
         unmark:'未閱',
         fullScore:'滿分',
         zeroScore:'零分',
-        submit:'提交分數',
+        submit:'提交分數/批註',
         setting1:'打分自動切換學生',
         setting2:'完成批閱自動彈出切換',
         setting3:'打分自動切換題目',

+ 274 - 38
TEAMModelOS/ClientApp/src/view/learnactivity/markpaper/MarkSetting.vue

@@ -10,9 +10,6 @@
         <vuescroll v-show="isSetting">
             <!-- 基础设置 -->
             <div class="setting-block">
-                <!-- <p class="block-title">
-                    {{$t('learnActivity.mark.baseSetting')}}
-                </p> -->
                 <div class="setting-content">
                     <Form ref="baseSetting" :model="setting" label-colon :label-width="100" :rules="ruleValidate">
                         <Row>
@@ -79,9 +76,6 @@
             </div>
 
             <div class="setting-block" id="teacher-wrap">
-                <!-- <p class="block-title">
-                    {{$t('learnActivity.mark.markRole')}}
-                </p> -->
                 <div class="setting-content" id="teacher-wrap-content">
                     <Form ref="teacherSet" :model="subsInfo" label-colon :label-width="100" :rules="ruleValidate" style="margin-top:15px">
                         <Row>
@@ -131,13 +125,13 @@
                             </Col>
                             <Col :md="24" :lg="24" :xl="24" :xxl="24" v-else>
                             <!-- 题目划块 -->
-                            <FormItem :label="$t('learnActivity.mark.quBlock')" class="setting-item-wrap dark-iview-table" prop="markers">
-                                <Table :columns="blockCol" :data="blockData" border>
+                            <FormItem :label="$t('learnActivity.mark.quBlock')" class="setting-item-wrap dark-iview-table">
+                                <Table :columns="blockCol" :data="quBlockData" border>
                                     <template slot-scope="{ row,index }" slot="action">
-                                        <Button type="info" size="small" style="margin-right:10px" @click="setQuStatus = true">
+                                        <Button type="info" size="small" style="margin-right:10px" @click="editBlock(row)">
                                             {{$t('learnActivity.mgtScEv.edit')}}
                                         </Button>
-                                        <Button type="error" size="small" @click="removeMarker(row,index)">{{$t('learnActivity.mark.remove')}}</Button>
+                                        <Button type="error" size="small" @click="removeBlock(row,index)">{{$t('learnActivity.mark.remove')}}</Button>
                                     </template>
                                     <template slot-scope="{ row }" slot="num">
                                         <span>{{evInfo.stuCount * setting.num}}</span>
@@ -181,15 +175,15 @@
             </Table>
         </Modal>
         <!-- 按题分配设置题块和老师 -->
-        <Modal v-model="setQuStatus" class-name="dark-iview-modal dark-iview-table" @on-ok="okSetQu" :width="1000">
+        <Modal v-model="setQuStatus" class-name="dark-iview-modal dark-iview-table" @on-ok="okSetQu" :width="1000" :loading="mLoading">
             <Tabs value="name1" style="color:white">
                 <TabPane label="题目" name="name1">
-
-                    <CheckboxGroup v-model="quBlock" style="margin-left:10px">
+                    <CheckboxGroup v-model="quIds" style="margin-left:10px">
                         <Checkbox :disabled="item.disabled" v-for="(item,index) in quNoList" :key="index" :label="item.value">
                             <span class="qu-no-label">
                                 {{item.label}}
                                 <span v-show="item.disabled" style="font-size:12px;color:#ff9900">(客)</span>
+                                <span v-show="assignQus.includes(item.value)" style="font-size:12px;color:#19be6b">(已)</span>
                             </span>
                         </Checkbox>
                     </CheckboxGroup>
@@ -234,8 +228,8 @@ export default {
     data() {
         let _this = this
         return {
-            quBlock: [],
-            blockData: [],
+            quIds: [],
+            mLoading: true,
             isSetting: false,
             ruleValidate: {
                 startTime: [
@@ -300,6 +294,8 @@ export default {
                 ],
 
             },
+            quBlockes: [], //按题分配数据结构
+            paperQuList: [],//各科试卷题目序号数据
             addTeaStatus: false,
             teacherList: [],
             sltTeachers: [], //按人分配时,设置老师
@@ -413,16 +409,17 @@ export default {
                 }
             },
             startTime: '',
-            endTime: ''
+            endTime: '',
+            editId: ''
         }
     },
     components: {
         MarkProgress, CptCount, ScanProgress, PersonalPhoto
     },
     methods: {
-        getQuLabels() {
+        getQuLabels(quNo) {
             return this.quNoList.filter(item => {
-                return this.quBlock.includes(item.value)
+                return quNo.includes(item.value)
             }).map(item => {
                 return item.label
             })
@@ -467,11 +464,58 @@ export default {
             } else {
                 this.$Message.error(this.$t('system.authErr'))
             }
-
-
         },
-        //确认设置阅卷题号
+        //移除题目分块
+        removeBlock(row, index) {
+            this.$Modal.confirm({
+                title: '删除题块',
+                content: '确认删除当前题块设置吗?',
+                onOk: () => {
+                    let blockData = this.quBlockes.find(item => {
+                        return item.id == this.subjects[this.curSubIndex].id
+                    })
+                    if (blockData) {
+                        blockData.quBlock.splice(index, 1)
+                    }
+                }
+            })
+        },
+        // 编辑题目分块
+        editBlock(row) {
+            this.editId = row.id
+            this.quIds = row.quNo
+            this.quTeachers = row.teachers
+            //初始化教师选中状态
+            if (this.quTeachers && this.quTeachers.length) {
+                let ids = this.quTeachers.map(item => {
+                    return item.id
+                })
+                for (let i in this.$refs.quTea.$refs.tbody.objData) {
+                    this.$refs.quTea.$refs.tbody.objData[i]._isChecked = ids.includes(this.$refs.quTea.$refs.tbody.objData[i].id)
+                }
+            }
+            this.setQuStatus = true
+        },
+        //确认设置题目划块
         okSetQu() {
+            if (!this.quIds.length) {
+                this.$Message.warning('请选择题目进行划块')
+                this.mLoading = false
+                setTimeout(() => {
+                    this.mLoading = true
+                }, 0)
+                return
+            }
+            if (!this.quTeachers.length) {
+                this.$Message.warning('请设置当前题块的阅卷老师')
+                this.mLoading = false
+                setTimeout(() => {
+                    this.mLoading = true
+                }, 0)
+                return
+            }
+            this.setQuStatus = false
+            //计算任务量
             if (this.quTeachers.length) {
                 let count = this.evInfo.stuCount * this.setting.num
                 let more = count % this.quTeachers.length
@@ -483,10 +527,36 @@ export default {
                     }
                 })
             }
-            this.blockData.push({
-                quNo: this.quBlock,
-                teachers: [...this.quTeachers]
+            let blockData = this.quBlockes.find(item => {
+                return item.id == this.subjects[this.curSubIndex].id
             })
+            if (!blockData) {
+                this.$Message.error('数据错误')
+                return
+            }
+            // 编辑
+            if (this.editId) {
+                let block = blockData.quBlock.find(item => {
+                    return item.id == this.editId
+                })
+                if (block) {
+                    block.quNo = [...this.quIds]
+                    block.teachers = [...this.quTeachers]
+                }
+            }
+            // 新增
+            else {
+                blockData.quBlock.push({
+                    id: this.$jsFn.uuid(),
+                    quNo: [...this.quIds],
+                    teachers: [...this.quTeachers]
+                })
+            }
+            //初始化状态
+            this.editId = ''
+            this.quIds = []
+            this.quTeachers = []
+            this.$refs.quTea.selectAll(false)
         },
         /**
          * 将日期控件时间格式转成时间戳
@@ -528,6 +598,77 @@ export default {
             })
             if (!full) return
 
+            if (this.setting.mode == 'qu') {
+                //验证按题分配模式 题目分块数据
+                let res = this.quBlockes.some(dataItem => {
+                    let allNo = []
+                    dataItem.quBlock.forEach(item => {
+                        allNo.push(...item.quNo)
+                    })
+                    let quListData = this.paperQuList.find(pQu => {
+                        return pQu.id == dataItem.id
+                    })
+                    //1、验证题目是否完全分配 some方法返回true的时候就会break循环, forEach方法不能break
+                    let last = quListData.quList.some(item => {
+                        return !allNo.includes(item.value) && !item.disabled
+                    })
+                    if (last) {
+                        this.$Message.error('当前题目划块设置题目尚未完全分配')
+                        return true
+                    }
+
+                    //2、验证题目是否重复分配
+                    let rep = allNo.some((item, index) => {
+                        return allNo.indexOf(item) != index
+                    })
+                    if (rep) {
+                        this.$Message.error('当前题目划块设置存在重复题目')
+                        return true
+                    }
+                })
+                if (res) return
+                console.log('通过验证', this.quBlockes)
+                //通过验证,将按题分配数据结构转成标准API结构
+
+                this.quBlockes.forEach(subItem => {
+                    let curSubData = this.setting.subs.find(item => {
+                        return item.id == subItem.id
+                    })
+                    if (curSubData) {
+                        curSubData.markers = []
+                        curSubData.model = subItem.quBlock.length
+                        subItem.quBlock.forEach(block => {
+                            let count = this.evInfo.stuCount * this.setting.num
+                            let more = count % block.teachers.length
+                            block.teachers.forEach((teacher, index) => {
+                                let c
+                                if (index < more) {
+                                    c = Math.ceil(count / block.teachers.length)
+                                } else {
+                                    c = Math.floor(count / block.teachers.length)
+                                }
+                                curSubData.markers.push({
+                                    id: teacher.id,
+                                    name: teacher.name,
+                                    qu: block.quNo.sort((a, b) => {
+                                        return a - b
+                                    }),
+                                    count: c
+                                })
+                            })
+                        })
+                    }
+                })
+            } else {
+                //如果先设置按题分配,然后切换成按人分配需要清空qu
+                this.setting.subs.forEach(subItem => {
+                    subItem.markers.forEach(t => {
+                        t.qu = []
+                    })
+                })
+            }
+            console.log('完整数据', this.setting)
+
             // 通过验证,保存设置
             this.setting.code = this.$store.state.userInfo.schoolCode
             this.$api.mark.UpsertMarkSet(this.setting).then(
@@ -585,28 +726,104 @@ export default {
                     if (res.correct) {
                         this.setting = res.correct
                         this.isSetting = true
+                        //如果是按题分配模式需要转换数据格式
+                        if (this.setting.mode == 'qu') {
+                            this.quBlockes = []
+                            this.setting.subs.forEach(subItem => {
+                                let item = {
+                                    id: subItem.id,
+                                    name: subItem.name,
+                                    quBlock: []
+                                }
+                                //根据题块进行分组
+                                let group = this.$jsFn.groupBy(subItem.markers, 'qu')
+                                group.forEach(gItem => {
+                                    let qItem = {
+                                        id: this.$jsFn.uuid(),
+                                        quNo: gItem[0].qu,
+                                        teachers: []
+                                    }
+                                    gItem.forEach(tItem => {
+                                        qItem.teachers.push({
+                                            id: tItem.id,
+                                            name: tItem.name
+                                        })
+                                    })
+                                    item.quBlock.push(qItem)
+                                })
+                                this.quBlockes.push(item)
+                            })
+                            console.log('处理结果',this.quBlockes)
+                        }
                     } else {
                         this.isSetting = false
                         if (this.evInfo.subjects) {
-                            this.setting.id = this.evInfo.id
-                            this.setting.source = this.evInfo.source
-                            this.setting.name = this.evInfo.name
-                            this.setting.school = this.$store.state.userInfo.schoolCode
-                            this.setting.code = this.$store.state.userInfo.schoolCode
-                            this.setting.scode = this.evInfo.code
-                            this.setting.creatorId = this.$store.state.userInfo.TEAMModelId
-                            this.setting.mode = 'stu'
-                            this.setting.createTime = new Date().getTime()
-                            this.setting.startTime = new Date().getTime()
-                            this.setting.endTime = new Date().getTime() + 86400000 * 2
-                            this.setting.subs = []
+                            this.setting = {
+                                id: this.evInfo.id,
+                                source: this.evInfo.source,
+                                name: this.evInfo.name,
+                                school: this.$store.state.userInfo.schoolCode,
+                                code: this.$store.state.userInfo.schoolCode,
+                                scode: this.evInfo.code,
+                                creatorId: this.$store.state.userInfo.TEAMModelId,
+                                mode: 'stu',
+                                num: 1,
+                                createTime: new Date().getTime(),
+                                startTime: new Date().getTime(),
+                                endTime: new Date().getTime() + 86400000 * 2,
+                                subs: []
+                            }
+
+                            //根据科目信息初始化各科基础数据
+                            this.quBlockes = []
                             this.evInfo.subjects.forEach((item) => {
+                                //初始化标准按人分配数据结构
                                 this.setting.subs.push({
                                     id: item.id,
                                     name: item.name,
-                                    markers: []
+                                    markers: [],
+                                    model: 1
+                                })
+                                //初始化按题分配的数据结构
+                                this.quBlockes.push({
+                                    id: item.id,
+                                    name: item.name,
+                                    quBlock: []
                                 })
                             })
+
+                            // 根据试卷信息初始化数据
+                            this.paperQuList = []
+                            this.evInfo.papers.forEach(paper => {
+                                //初始化各科试卷题号数据
+                                if (paper.item.length) {
+                                    let objectiveQu = ['single', 'multiple', 'judge']
+                                    let data = []
+                                    let realIndex = 0
+                                    paper.item.forEach((item, index) => {
+                                        if (item.children.length) {
+                                            item.children.forEach((childItem, childIndex) => {
+                                                data.push({
+                                                    label: (index + 1) + '-' + (childIndex + 1),
+                                                    value: realIndex++,
+                                                    disabled: objectiveQu.includes(childItem.type)
+                                                })
+                                            })
+                                        } else {
+                                            data.push({
+                                                label: index + 1,
+                                                value: realIndex++,
+                                                disabled: objectiveQu.includes(item.type)
+                                            })
+                                        }
+                                    })
+                                    this.paperQuList.push({
+                                        id: paper.subjectId,
+                                        name: paper.subjectName,
+                                        quList: data
+                                    })
+                                }
+                            })
                         }
                     }
                 },
@@ -634,7 +851,7 @@ export default {
     watch: {
         'evInfo.id': {
             handler(n, o) {
-                console.log('评测数据', this.evInfo)
+                this.curSubIndex = 0
                 if (this.evInfo.id) {
                     this.findSettingInfo()
                 } else {
@@ -672,6 +889,25 @@ export default {
         }
     },
     computed: {
+        //当前科目按题分配数据
+        quBlockData() {
+            let blockData = this.quBlockes.find(item => {
+                return item.id == this.subjects[this.curSubIndex].id
+            })
+            return blockData ? blockData.quBlock : []
+        },
+        // 当前科目已分配的题号
+        assignQus() {
+            if (this.quBlockData.length) {
+                let data = []
+                this.quBlockData.forEach(item => {
+                    data.push(...item.quNo)
+                })
+                return data
+            } else {
+                return []
+            }
+        },
         //当前科目的配置信息
         subsInfo() {
             let info = {

+ 125 - 0
TEAMModelOS/ClientApp/src/view/task/arb/Arbitration.vue

@@ -0,0 +1,125 @@
+<template>
+    <div class="arb-container">
+        <div class="arb-header">
+            <span :class="curBarIndex == 1 ? 'bar-item line-bottom-active line-bottom':'bar-item line-bottom'" @click="selectBar(1)">
+                未处理
+            </span>
+            <span :class="curBarIndex == 0 ? 'bar-item line-bottom-active line-bottom':'bar-item line-bottom'" @click="selectBar(0)">
+                已处理
+            </span>
+            <Tooltip class="score-tips" theme="light" max-width="200" content="误差控制值:双评差值的最大允许值称为误差控制值。误差控制值大于题目满分的1/6系统自动设置为仲裁卷。">
+                <span style="color:#ff9900;">
+                    误差控制值
+                    <Icon type="ios-help-circle-outline" />
+                </span>
+            </Tooltip>
+        </div>
+        <div class="arb-content">
+            <vuescroll>
+                <div class="arb-paper-item" v-for="(item,index) in arr" :key="index">
+                    <p class="qu-info-wrap">
+                        <span class="qu-info-label">题目:</span>
+                        <span class="qu-info-value">5-5</span>
+                    </p>
+                    <div style="flex:1">
+                        <p>
+                            <span class="score-info-label">分数1:</span>
+                            <span class="score-info-value">5</span>
+                            <span class="score-info-label">分数2:</span>
+                            <span class="score-info-value">15</span>
+                            <span class="score-info-label">配分:</span>
+                            <span class="score-info-value">20</span>
+                            <span class="score-info-label">
+                                <Icon type="md-time" />
+                                2021-09-01
+                            </span>
+                        </p>
+                        <!-- <p style="margin-top:5px">
+                            <Icon type="md-time" />
+                            2021-09-01
+                        </p> -->
+                    </div>
+                    <div style="width:100px">
+                        <Button type="primary" shape="circle" size="small" long>仲裁</Button>
+                    </div>
+                </div>
+            </vuescroll>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            curBarIndex: 0,
+            arr:[0,0,0,0,0,0,0,0,0,0,0]
+        }
+    },
+    created() {
+
+    },
+    methods: {
+        selectBar(index) {
+            this.curBarIndex = index
+        }
+    }
+}
+</script>
+<style scoped lang="less">
+.score-tips {
+    float: right;
+    margin-right: 30px;
+    cursor: pointer;
+}
+.qu-info-wrap {
+    width: 150px;
+    text-align: center;
+}
+.score-info-label {
+    color: #a5a5a5;
+    font-size: 14px;
+}
+.score-info-value {
+    color: white;
+    font-size: 16px;
+    margin-right: 30px;
+}
+.qu-info-label {
+    color: white;
+    font-size: 12px;
+}
+.qu-info-value {
+    color: white;
+    font-size: 20px;
+    margin-right: 30px;
+}
+.arb-container {
+    width: 100%;
+    height: 100%;
+    padding-left: 10px;
+}
+.arb-header {
+    width: 100%;
+    height: 45px;
+    line-height: 45px;
+    border-bottom: 1px solid #606060;
+    .bar-item {
+        display: inline-block;
+        cursor: pointer;
+    }
+}
+.arb-content {
+    width: 100%;
+    height: ~"calc(100% - 45px)";
+}
+.arb-paper-item {
+    width: ~"calc(100% - 20px)";
+    margin: 6px 5px;
+    border: 1px solid #363636;
+    background: #2b2a2f;
+    padding: 15px;
+    display: flex;
+    align-items: center;
+    border-radius: 0px;
+}
+</style>

+ 121 - 0
TEAMModelOS/ClientApp/src/view/task/err/ErrPaper.vue

@@ -0,0 +1,121 @@
+<template>
+    <div class="arb-container">
+        <div class="arb-header">
+            <span :class="curBarIndex == 1 ? 'bar-item line-bottom-active line-bottom':'bar-item line-bottom'" @click="selectBar(1)">
+                未处理
+            </span>
+            <span :class="curBarIndex == 0 ? 'bar-item line-bottom-active line-bottom':'bar-item line-bottom'" @click="selectBar(0)">
+                已处理
+            </span>
+            <Tooltip class="score-tips" theme="light" max-width="200" content="误差控制值:双评差值的最大允许值称为误差控制值。误差控制值大于题目满分的1/6系统自动设置为仲裁卷。">
+                <span style="color:#ff9900;">
+                    误差控制值
+                    <Icon type="ios-help-circle-outline" />
+                </span>
+            </Tooltip>
+        </div>
+        <div class="arb-content">
+            <vuescroll>
+                <div class="arb-paper-item" v-for="(item,index) in arr" :key="index">
+                    <p class="qu-info-wrap">
+                        <span class="qu-info-label">题目:</span>
+                        <span class="qu-info-value">5-5</span>
+                    </p>
+                    <div style="flex:1">
+                        <p>
+                            <span class="score-info-label">分数1:</span>
+                            <span class="score-info-value">5</span>
+                            <span class="score-info-label">分数2:</span>
+                            <span class="score-info-value">15</span>
+                            <span class="score-info-label">配分:</span>
+                            <span class="score-info-value">20</span>
+                            <span class="score-info-label">
+                                <Icon type="md-time" />
+                                2021-09-01
+                            </span>
+                        </p>
+                    </div>
+                    <div style="width:100px">
+                        <Button type="primary" shape="circle" size="small" long>仲裁</Button>
+                    </div>
+                </div>
+            </vuescroll>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            curBarIndex: 0,
+            arr:[0,0,0,0,0,0,0,0,0,0,0]
+        }
+    },
+    created() {
+
+    },
+    methods: {
+        selectBar(index) {
+            this.curBarIndex = index
+        }
+    }
+}
+</script>
+<style scoped lang="less">
+.score-tips {
+    float: right;
+    margin-right: 30px;
+    cursor: pointer;
+}
+.qu-info-wrap {
+    width: 150px;
+    text-align: center;
+}
+.score-info-label {
+    color: #a5a5a5;
+    font-size: 14px;
+}
+.score-info-value {
+    color: white;
+    font-size: 16px;
+    margin-right: 30px;
+}
+.qu-info-label {
+    color: white;
+    font-size: 12px;
+}
+.qu-info-value {
+    color: white;
+    font-size: 20px;
+    margin-right: 30px;
+}
+.arb-container {
+    width: 100%;
+    height: 100%;
+    padding-left: 10px;
+}
+.arb-header {
+    width: 100%;
+    height: 45px;
+    line-height: 45px;
+    border-bottom: 1px solid #606060;
+    .bar-item {
+        display: inline-block;
+        cursor: pointer;
+    }
+}
+.arb-content {
+    width: 100%;
+    height: ~"calc(100% - 45px)";
+}
+.arb-paper-item {
+    width: ~"calc(100% - 20px)";
+    margin: 6px 5px;
+    border: 1px solid #363636;
+    background: #2b2a2f;
+    padding: 15px;
+    display: flex;
+    align-items: center;
+    border-radius: 0px;
+}
+</style>

+ 51 - 41
TEAMModelOS/ClientApp/src/view/task/index.vue

@@ -15,6 +15,9 @@
                             <p class="ev-name">
                                 <span>{{item.name}}</span>
                                 <span class="mark-status-tag">{{$t('task.markStatus1')}}</span>
+                                <span class="mark-status-tag" style="color:#ff9900;border-color:#ff9900">
+                                    {{item.type === 1 ? '阅卷任务' : item.type == 2 ? '异常卷处理' : '仲裁卷处理'}}
+                                </span>
                             </p>
                             <p class="ev-info">
                                 <Icon type="md-time" style="margin-right:5px;" size="16" />
@@ -28,8 +31,12 @@
                         <EmptyData v-show="markList.length == 0" textContent="暂无阅卷任务" style="margin-top:80px"></EmptyData>
                     </vuescroll>
                 </div>
-                <!-- 阅卷信息 -->
-                <div slot="right" class="ev-mark-info">
+                <!-- 没有任务 -->
+                <div slot="right" v-if="!markList[curTaskIndex]" class="ev-mark-info">
+                    <EmptyData :top="140" slot="right" textContent="暂无任务"></EmptyData>
+                </div>
+                <!-- 阅卷老师 -->
+                <div slot="right" class="ev-mark-info" v-else-if="markList[curTaskIndex].type == 1">
                     <div class="ev-mark-header">
                         <span :class="curBarIndex == 1 ? 'task-bar-item line-bottom-active line-bottom':'task-bar-item line-bottom'" @click="selectBar(1)">
                             {{$t('task.markMode2')}}
@@ -39,7 +46,8 @@
                         </span>
                     </div>
                     <vuescroll class="mark-info-content" v-if="markList.length > 0">
-                        <StuProg v-show="curBarIndex == 1" @getStuId="toByStuView" :stusData="markData ? markData.attr : []" :total="markList[curTaskIndex] ? markList[curTaskIndex].count : 1"></StuProg>
+                        <!-- 按人阅卷学生信息 -->
+                        <StuProg v-show="curBarIndex == 1" @getStuId="toByStuView" :stusData="markData ? markData.objs : []" :total="markList[curTaskIndex] ? markList[curTaskIndex].count : 1" :qus="markList[curTaskIndex] ? markList[curTaskIndex].qu : []"></StuProg>
                         <!-- 按题 批阅进度 -->
                         <div class="setting-block" v-show="curBarIndex == 0" style="margin-top:15px">
                             <p class="block-title">
@@ -49,7 +57,7 @@
                             <div class="setting-content" :style="{height: fullQuProg ? 'fit-content' : '420px'}">
                                 <vuescroll>
                                     <!-- 按题阅卷题目进度条 -->
-                                    <QuProg :paperData="fullPaper" :stusData="markData ? markData.attr : []" :total="markList[curTaskIndex] ? markList[curTaskIndex].count : 1" @getQuIndex="toByQuView"></QuProg>
+                                    <QuProg :paperData="fullPaper" :stusData="markData ? markData.objs : []" :total="markList[curTaskIndex] ? markList[curTaskIndex].count : 1" @getQuIndex="toByQuView" :qus="markList[curTaskIndex] ? markList[curTaskIndex].qu : []"></QuProg>
                                 </vuescroll>
                             </div>
                         </div>
@@ -61,24 +69,13 @@
                                 <ProgPie :count="[marked.length,marking.length,unmarked]"></ProgPie>
                             </div>
                         </div>
-
-                        <!-- 异常 暂时隐藏-->
-                        <!-- <div class="setting-block">
-                            <p class="block-title">异常卷</p>
-                            <div class="setting-content dark-iview-table my-stripe-table">
-                                <Table :row-class-name="rowClassName" :columns="columns1" :data="data1"></Table>
-                            </div>
-                        </div> -->
-                        <!-- 仲裁 暂时隐藏-->
-                        <!-- <div class="setting-block">
-                            <p class="block-title">仲裁卷</p>
-                            <div class="setting-content dark-iview-table my-stripe-table">
-                                <Table :row-class-name="rowClassName" :columns="columns2" :data="data2"></Table>
-                            </div>
-                        </div> -->
                     </vuescroll>
                     <EmptyData textContent="暂无阅卷任务" :top="90" style="height:fit-content"></EmptyData>
                 </div>
+                <!-- 异常卷任务 -->
+                <ErrPaper slot="right" v-else-if="markList[curTaskIndex].type == 2"></ErrPaper>
+                <!-- 仲裁卷任务 -->
+                <Arbitration slot="right" v-else-if="markList[curTaskIndex].type == 3"></Arbitration>
             </Split>
         </div>
     </div>
@@ -88,9 +85,11 @@ import DataCompare from './mark/Compare.vue'
 import ProgPie from './mark/ProgPie.vue'
 import QuProg from './mark/QuProg.vue'
 import StuProg from './mark/StuProg.vue'
+import Arbitration from './arb/Arbitration.vue'
+import ErrPaper from './err/ErrPaper.vue'
 export default {
     components: {
-        DataCompare, ProgPie, QuProg, StuProg
+        DataCompare, ProgPie, QuProg, StuProg, Arbitration, ErrPaper
     },
     data() {
         return {
@@ -223,16 +222,22 @@ export default {
             let sas = this.$store.state.user.schoolProfile.blob_sas //目前只有校本评测安排阅卷任务
             let blobUrl = JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri //目前只有校本评测安排阅卷任务
 
-            let answer, score, sId
+            let answer, score, sId, quScore, stuData
             //批阅已经分配的学生
             if (stuId) {
-                let stuInfo = this.markData.attr.find(item => {
+                let stuInfo = this.markData.objs.find(item => {
                     return item.stuId == stuId
                 })
+                stuData = stuInfo
                 let index = stuInfo.tIds.indexOf(this.$store.state.userInfo.TEAMModelId)
                 let ansBlob = index > -1 ? stuInfo.marks[index] || stuInfo.blob : stuInfo.blob
                 answer = ansBlob ? JSON.parse(await this.$tools.getFile(`${blobUrl}/exam/${ansBlob}?${sas}`)) : []
-                score = stuInfo.scores
+                score = stuInfo.item.map(scoreItem => {
+                    return scoreItem.sc
+                })
+                quScore = stuInfo.item.map(scoreItem => {
+                    return scoreItem.ssc
+                })
                 sId = stuId
             }
             // 获取新学生
@@ -241,8 +246,15 @@ export default {
                 let index = resData.tIds.indexOf(this.$store.state.userInfo.TEAMModelId)
                 let ansBlob = index > -1 ? resData.marks[index] || resData.blob : resData.blob
                 answer = ansBlob ? JSON.parse(await this.$tools.getFile(`${blobUrl}/exam/${ansBlob}?${sas}`)) : []
-                score = resData.scores
+                resData.answer = answer
+                score = resData.item.map(item => {
+                    return item.sc
+                })
+                quScore = resData.item.map(item => {
+                    return item.ssc
+                })
                 sId = resData.stuId
+                stuData = resData
             }
             this.$router.push({
                 name: 'ByStu',
@@ -251,9 +263,11 @@ export default {
                     task: this.markList[this.curTaskIndex],
                     stuId: sId,
                     fullPaper: this.fullPaper,
-                    stusData: this.markData.attr,
+                    stusData: this.markData.objs,
+                    stuData,
                     answer,
-                    score
+                    score,
+                    quScore
                 }
             })
         },
@@ -263,15 +277,14 @@ export default {
         * childIndex 非必传
         */
         async toByQuView(data) {
-            let { quIndex, childIndex } = data
+            let quIndex = data
             sessionStorage.setItem('markFrom', this.$route.name)
             let sas = this.$store.state.user.schoolProfile.blob_sas //目前只有校本评测安排阅卷任务
             let blobUrl = JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri //目前只有校本评测安排阅卷任务
             // 获取学生作答数据
-            this.markData.attr.forEach(async item => {
+            this.markData.objs.forEach(async item => {
                 let index = item.tIds.indexOf(this.$store.state.userInfo.TEAMModelId)
                 let ansBlob = index > -1 ? item.marks[index] || item.blob : item.blob
-                console.log('遍历',ansBlob)
                 this.$set(item, 'answer', ansBlob ? JSON.parse(await this.$tools.getFile(`${blobUrl}/exam/${ansBlob}?${sas}`)) : [])
             })
             this.$router.push({
@@ -279,10 +292,9 @@ export default {
                 params: {
                     from: this.$route.name,
                     task: this.markList[this.curTaskIndex], //阅卷任务数据
-                    stusInfo: this.markData.attr, //已阅和进行中的学生数据
+                    stusInfo: this.markData.objs, //已阅和进行中的学生数据
                     paperData: this.fullPaper, //试卷数据
-                    quIndex,
-                    childIndex
+                    quIndex
                 }
             })
         },
@@ -354,12 +366,11 @@ export default {
             this.$api.mark.FindTeaData(requestData).then(
                 async res => {
                     if (!res.error) {
-                        this.markData = res
-                        //获取试卷详细数据
                         //获取试卷完整信息
                         this.fullPaper = await this.$evTools.getFullPaper({
-                            blob: this.markData.paper
+                            blob: res.paper
                         }, 'school')
+                        this.markData = res
                     }
                 },
                 err => {
@@ -383,9 +394,8 @@ export default {
         //当前阅卷任务未阅数量
         unmarked() {
             if (this.markList.length > 0) {
-                console.log(this.curTaskIndex, this.markList)
                 let total = this.markList[this.curTaskIndex].count
-                let marked = this.markData ? this.markData.attr.length : 0
+                let marked = this.markData ? this.markData.objs.length : 0
                 return total - marked
             } else {
                 return 0
@@ -393,8 +403,8 @@ export default {
         },
         //当前阅卷任务已阅学生信息
         marked() {
-            if (this.markData && this.markData.attr) {
-                return this.markData.attr.filter(item => {
+            if (this.markData && this.markData.objs) {
+                return this.markData.objs.filter(item => {
                     return item.scores.indexOf(-1) == -1
                 })
             } else {
@@ -403,8 +413,8 @@ export default {
         },
         //当前阅卷任务进行中学生信息
         marking() {
-            if (this.markData && this.markData.attr) {
-                return this.markData.attr.filter(item => {
+            if (this.markData && this.markData.objs) {
+                return this.markData.objs.filter(item => {
                     return item.scores.indexOf(-1) !== -1
                 })
             } else {

+ 151 - 51
TEAMModelOS/ClientApp/src/view/task/mark/ByQu.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="mark-area">
         <!-- 头部基础信息 -->
-        <div class="mark-header">
+        <div class="mark-header" v-show="!isComplete">
             <span class="quit-marking-text">
                 <Icon type="ios-arrow-back" class="quit-marking-icon" :title="$t('learnActivity.mark.quit')" @click="quit" />
             </span>
@@ -10,28 +10,23 @@
             <span class="info-label">{{$t('learnActivity.mark.reviewType')}}</span>
             <span class="info-value">{{$t('learnActivity.mark.byQu')}}</span>
             <span class="info-label">{{$t('learnActivity.mark.curQu')}}</span>
-            <span class="info-value cur-qu-index" v-if="childIndex > -1">{{`${quIndex + 1}-${childIndex + 1}`}}</span>
-            <span class="info-value cur-qu-index" v-else>{{quIndex + 1}}</span>
-            <span class="info-label">{{$t('learnActivity.mark.quProg')}}</span>
+            <span class="info-value cur-qu-index">{{quNoList[quIndex] ? quNoList[quIndex].label : '--'}}</span>
+            <span class="info-label">{{$t('learnActivity.mark.quProg')}}: </span>
             <span class="info-value stu-id-info">{{curProg}}</span>
-            <span class="info-label">{{$t('learnActivity.mark.stuId')}}</span>
+            <span class="info-label">{{$t('learnActivity.mark.stuId')}}: </span>
             <span class="info-value stu-id-info">{{stusInfo[stuIndex] ? stusInfo[stuIndex].stuId : ''}}</span>
             <div class="btn-wrap">
                 <span class="action-btn" @click="toggleStatus = !toggleStatus">
                     <Icon type="md-shuffle" class="action-btn-icon" />
                     {{$t('learnActivity.mark.toggleQu')}}
                 </span>
-                <!-- <span class="action-btn">
-                    <Icon type="md-refresh" class="action-btn-icon" />
-                    回评
-                </span> -->
-                <span class="action-btn" @click="exception">
+                <span class="action-btn" @click="errStatus = true">
                     <Icon custom="iconfont icon-exception" class="action-btn-icon" />
                     {{$t('learnActivity.mark.exception')}}
                 </span>
             </div>
         </div>
-        <div class="mark-main">
+        <div class="mark-main" v-show="!isComplete">
             <!-- 工具条 -->
             <div class="mark-tools-wrap">
                 <Icon custom="iconfont icon-move" class="tool-icon" :title="$t('learnActivity.mark.move')" @click="mouseStatus = 'move'" />
@@ -93,15 +88,42 @@
                 </div>
             </div>
         </div>
+        <!-- 完成阅卷的提示信息 -->
+        <div class="complete-mark" v-show="isComplete">
+            <div class="complete-box">
+                <Icon type="md-checkmark-circle-outline" class="ok-icon" />
+                <p style="margin-top:20px;font-size:14px">
+                    题目:{{quNoList[quIndex].label}}
+                </p>
+                <p style="font-size:20px">
+                    已阅完
+                </p>
+                <Button type="success" class="continue-btn" @click="continueMark">继续阅卷</Button>
+                <Button type="info" class="quit-btn" @click="quit">退出阅卷</Button>
+            </div>
+        </div>
         <!-- 用来单独渲染学生作答数据,提高tocanvas 的效率 -->
         <iframe id="markIframe1" :srcdoc="curAnswer" v-if="curAnswer"></iframe>
         <Modal v-model="toggleStatus" :title="$t('learnActivity.mark.toggleQu')" :width="800" footer-hide>
             <div class="qu-prog-wrap" style="height:600px">
                 <vuescroll>
-                    <QuProg :paperData="paperData" :stusData="stusInfo" :total="taskInfo.count || 1" @getQuIndex="setQuIndex"></QuProg>
+                    <QuProg :paperData="paperData" :stusData="stusInfo" :total="taskInfo.count || 1" @getQuIndex="setQuIndex" :qus="taskInfo ? taskInfo.qu : []"></QuProg>
                 </vuescroll>
             </div>
         </Modal>
+        <Modal v-model="errStatus" title="异常原因" :width="600" @on-ok="exception" :loading="loading">
+            <CheckboxGroup v-model="errReason">
+                <Checkbox label="twitter" class="reason-item">
+                    <span>答案不清晰,看不清楚</span>
+                </Checkbox>
+                <Checkbox label="facebook" class="reason-item">
+                    <span>答案图片不完整</span>
+                </Checkbox>
+                <Checkbox label="github" class="reason-item">
+                    <span>其他原因</span>
+                </Checkbox>
+            </CheckboxGroup>
+        </Modal>
     </div>
 </template>
 <script>
@@ -115,7 +137,12 @@ export default {
     },
     data() {
         return {
+            isComplete: false,
+            loading: true,
+            errReason: [],
+            errStatus: false,
             score: null,
+            quScore: 0,
             mouseStatus: 'move',
             drawImgData: '',
             ansImg: '',
@@ -125,7 +152,6 @@ export default {
             toggleStatus: false,
             isShowNum: true,
             quIndex: 0,
-            childIndex: -1,
             paperData: {
                 item: []
             },
@@ -135,14 +161,29 @@ export default {
         }
     },
     methods: {
+        //继续阅卷
+        continueMark(){
+            this.toggleStatus = true
+        },
         exception() {
-            this.$Message.warning('功能开发中')
+            if (this.errReason.length) {
+                this.errStatus = false
+                this.$Message.warning('暂未对接API')
+                this.errReason = []
+            } else {
+                this.loading = false
+                setTimeout(() => {
+                    this.loading = true
+                })
+                this.$Message.warning('请选择异常原因')
+            }
         },
         setQuIndex(data) {
-            let { quIndex, childIndex } = data
-            this.quIndex = quIndex
-            this.childIndex = childIndex
+            let index = data
+            this.quIndex = index
             this.toggleStatus = false
+            this.isComplete = false
+            this.getDefStu()
         },
         drawImg(imgIndex) {
             let curImg = new Image()
@@ -187,11 +228,8 @@ export default {
         /** 打分 */
         setScore(score) {
             this.score = score
-            let index = this.getScoreIndex(this.quIndex, this.childIndex)
-            this.$set(this.stusInfo[this.stuIndex].scores, index, score)
-            if (this.autoStu) {
-                this.submit()
-            }
+            // this.$set(this.stusInfo[this.stuIndex].scores, index, score)
+            this.stusInfo[this.stuIndex].item[this.quIndex].sc = score
         },
         //提交分数
         submit() {
@@ -201,7 +239,7 @@ export default {
                 if (this.markImg) {
                     let img = document.createElement('img')
                     img.src = this.markImg
-                    this.stuAnswer[this.getScoreIndex(this.quIndex, this.childIndex)] = img.outerHTML
+                    this.stuAnswer[this.quIndex] = img.outerHTML
                     mark = this.stuAnswer
                     this.markImg = undefined
                 }
@@ -210,14 +248,15 @@ export default {
                     stuId: this.stusInfo[this.stuIndex].stuId,
                     subjectId: this.taskInfo.subject,
                     tmdId: this.$store.state.userInfo.TEAMModelId,
-                    score: this.stusInfo[this.stuIndex].scores,
+                    score: this.stusInfo[this.stuIndex].item.map(item=>{
+                        return item.sc
+                    }),
                     count: this.taskInfo.count,
                     code: this.taskInfo.ecode.replace('Exam-', ''),
                     mark
                 }
                 this.$api.mark.saveScore(requstData).then(
                     res => {
-                        // this.$Message.success('保存成功')
                         //按题阅卷自动加载下一人
                         this.getDefStu()
                     },
@@ -262,24 +301,30 @@ export default {
         },
         //获取批阅学生数据
         getDefStu() {
-            let scoreIndex = this.getScoreIndex(this.quIndex, this.childIndex)
+            let scoreIndex = this.quIndex
             let has = false //当前数据是否有当前题目没有评分的学生
             for (let i = 0; i < this.stusInfo.length; i++) {
-                if (this.stusInfo[i].scores[scoreIndex] == -1) {
+                if (this.stusInfo[i].item[scoreIndex].sc == -1) {
                     this.stuIndex = i
                     this.score = null
                     has = true
+                    console.log('还有未评分的学生')
                 }
             }
+            if (has) return
+
             //当前数据没有未评,并且人数==阅卷任务量 —> 说明这道题目已阅完
-            if (!has && this.stusInfo.length == this.taskInfo.count) {
+            if (this.stusInfo.length == this.taskInfo.count) {
+                console.log('已阅完')
                 // 提示当前题目已阅完,切换题目
-                if (this.autoQu) {
-                    this.toggleStatus = true
-                } else {
-                    this.$Message.warning(this.$t('learnActivity.mark.completeQu'))
-                }
-            } else if (!has && this.stusInfo.length < this.taskInfo.count) {
+                // if (this.autoQu) {
+                //     this.toggleStatus = true
+                // } else {
+                //     this.$Message.warning(this.$t('learnActivity.mark.completeQu'))
+                // }
+                this.isComplete = true
+            } else if (this.stusInfo.length < this.taskInfo.count) {
+                console.log('随机下一位')
                 //当前学生数据已阅,需要继续随机获取学生进行阅卷
                 this.getNextStu()
             }
@@ -309,7 +354,7 @@ export default {
                         score: res.ans.score
                     })
                     this.stuIndex = this.stusInfo.length - 1
-                    this.score = res.ans.score[this.getScoreIndex(this.quIndex, this.childIndex)] == -1 ? null : res.ans.score[this.getScoreIndex(this.quIndex, this.childIndex)]
+                    this.score = res.ans.score[this.quIndex] == -1 ? null : res.ans.score[this.quIndex]
                 },
                 err => {
                     console.log(err)
@@ -319,7 +364,6 @@ export default {
     },
     mounted() {
         this.ansToImg()
-
     },
     created() {
         let routeData = this.$route.params
@@ -327,7 +371,7 @@ export default {
         this.stusInfo = routeData.stusInfo
         this.taskInfo = routeData.task
         this.quIndex = routeData.quIndex
-        this.childIndex = routeData.childIndex
+        console.log('路由数据', routeData)
         //获取一个学生数据
         this.getDefStu()
 
@@ -337,26 +381,51 @@ export default {
         }
     },
     computed: {
+        //试卷题号列表
+        quNoList() {
+            if (this.paperData.item.length) {
+                let data = []
+                let realIndex = 0
+                this.paperData.item.forEach((item, index) => {
+                    if (item.children.length) {
+                        item.children.forEach((childItem, childIndex) => {
+                            data.push({
+                                label: (index + 1) + '-' + (childIndex + 1),
+                                value: realIndex++,
+                                score: childItem.score
+                            })
+                        })
+                    } else {
+                        data.push({
+                            label: index + 1,
+                            value: realIndex++,
+                            score: item.score
+                        })
+                    }
+                })
+                console.log('题目信息', data)
+                return data
+            }
+            return []
+        },
         //当前题目进度
         curProg() {
-            let index = this.getScoreIndex(this.quIndex, this.childIndex)
+            let index = this.quIndex
             let marked = 0
             this.stusInfo.forEach(item => {
-                if (item.scores[index] != -1) {
+                if (item.item[index].sc != -1) {
                     marked++
                 }
             })
             return `${marked}/${this.taskInfo.count}`
         },
         curAnswer() {
-            console.log('学生数据', this.stusInfo, this.stuIndex)
             if (this.stusInfo && this.stusInfo[this.stuIndex]) {
-                let s = this.stusInfo[this.stuIndex].scores[this.getScoreIndex(this.quIndex, this.childIndex)]
+                let s = this.stusInfo[this.stuIndex].item[this.quIndex].sc
                 this.score = s == -1 ? null : s
                 if (this.stusInfo[this.stuIndex].answer && this.stusInfo[this.stuIndex].answer.length) {
-                    return this.stusInfo[this.stuIndex].answer[this.getScoreIndex(this.quIndex, this.childIndex)]
+                    return this.stusInfo[this.stuIndex].answer[this.quIndex]
                 } else {
-                    console.log('未作答')
                     return this.stusInfo[this.stuIndex].stuId + this.$t('learnActivity.mark.noAnswer')
                 }
             } else {
@@ -366,20 +435,51 @@ export default {
         /**当期题目分数数组 */
         quScoreArr() {
             let score = 0
-            console.log(this.quIndex, this.childIndex)
-            if (this.paperData.item) {
-                if (this.childIndex > -1 && this.paperData.item[this.quIndex] && this.paperData.item[this.quIndex].children) {
-                    score = this.paperData.item[this.quIndex].children[this.childIndex].score
-                } else {
-                    score = this.paperData.item[this.quIndex].score
-                }
-            }
+            // 这里可以从新的数据结构获取
+            let sInfo = this.quNoList[this.quIndex]
+            score = sInfo.score || score
             return Array.from(new Array(score + 1).keys())
         },
     }
 }
 </script>
 <style scoped lang="less">
+.continue-btn {
+    margin-top: 50px;
+    width: 150px;
+    display: block;
+}
+.quit-btn {
+    display: block;
+    width: 150px;
+    margin-top: 4px;
+}
+.complete-mark {
+    width: 100%;
+    height: 100%;
+    background: #fcfcfc;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .complete-box {
+        text-align: center;
+        margin-top: -50px;
+        font-size: 16px;
+        padding: 50px 80px;
+        height: fit-content;
+        box-shadow: 0px 0px 10px #dbdbdb;
+        background: white;
+    }
+    .ok-icon {
+        color: #19be6b;
+        display: block;
+        font-size: 110px;
+    }
+}
+.reason-item {
+    display: block;
+    margin: 10px;
+}
 #container {
     max-width: 100%;
 }

+ 231 - 176
TEAMModelOS/ClientApp/src/view/task/mark/ByStu.vue

@@ -1,8 +1,7 @@
 <template>
-    <!-- 未做多语言 -->
     <div class="mark-area">
         <!-- 头部基础信息 -->
-        <div class="mark-header">
+        <div class="mark-header" v-show="!isComplete">
             <span class="quit-marking-text">
                 <Icon type="ios-arrow-back" class="quit-marking-icon" :title="$t('learnActivity.mark.quit')" @click="quit" />
             </span>
@@ -12,27 +11,22 @@
             <span class="info-value">{{$t('learnActivity.mark.byStu')}}</span>
             <span class="info-label">{{$t('learnActivity.mark.stuId')}}</span>
             <span class="info-value stu-id-info">{{stuId}}</span>
-            <span class="info-label">{{$t('learnActivity.mark.score')}}</span>
-            <span class="info-value score-info">{{totalScore}}</span>
+            <!-- <span class="info-label">{{$t('learnActivity.mark.score')}}</span>
+            <span class="info-value score-info">{{totalScore}}</span> -->
             <span class="info-label">{{$t('learnActivity.mark.curQu')}}</span>
-            <span class="info-value cur-qu-index" v-if="childIndex > -1">{{`${quIndex + 1}-${childIndex + 1}`}}</span>
-            <span class="info-value cur-qu-index" v-else>{{quIndex + 1}}</span>
+            <span class="info-value cur-qu-index">{{quNoList[quIndex] ? quNoList[quIndex].label : '--'}}</span>
             <div class="btn-wrap">
-                <span class="action-btn" @click="toggleStatus = !toggleStatus">
+                <span class="action-btn" @click="continueMark">
                     <Icon type="md-shuffle" class="action-btn-icon" />
                     {{$t('learnActivity.mark.toggleStu')}}
                 </span>
-                <!-- <span class="action-btn">
-                    <Icon type="md-refresh" class="action-btn-icon" />
-                    回评
-                </span> -->
-                <span class="action-btn" @click="exception">
+                <span class="action-btn" @click="errStatus = true">
                     <Icon custom="iconfont icon-exception" class="action-btn-icon" />
                     {{$t('learnActivity.mark.exception')}}
                 </span>
             </div>
         </div>
-        <div class="mark-main">
+        <div class="mark-main" v-show="!isComplete">
             <!-- 工具条 -->
             <div class="mark-tools-wrap">
                 <Icon custom="iconfont icon-move" class="tool-icon" :title="$t('learnActivity.mark.move')" @click="mouseStatus = 'move'" />
@@ -48,7 +42,6 @@
                     </div>
                 </Poptip>
                 <Icon custom="iconfont icon-fresh" class="tool-icon" :title="$t('learnActivity.mark.clear')" @click="clear" />
-                <!-- <Icon :custom="isFull ? 'iconfont icon-cancel-full' : 'iconfont icon-full-screen'" class="tool-icon" :title="isFull ? '取消全屏' : '全屏'" @click="togglefull" /> -->
             </div>
             <div class="mark-stage">
                 <MarkCanvas ref="markCanvas" @getImg="saveMark" :status="mouseStatus" :bgImg="ansImg" :drawImgData="drawImgData" style="padding-bottom:85px"></MarkCanvas>
@@ -63,17 +56,8 @@
                         </span>
                     </div>
                     <div>
-                        <span v-for="(item,index) in paperData.item" :key="index">
-                            <!-- 综合题 -->
-                            <span v-if="item.children.length" :key="index">
-                                <span @click="toQu(index,childIndex)" v-for="(childItem,childIndex) in item.children" :key="childIndex" :class="['qu-index',stuScore[getScoreIndex(index,childIndex)] > -1 ? 'right-qu' : '']">
-                                    {{(index + 1) + '-' + (childIndex + 1)}}
-                                </span>
-                            </span>
-                            <!-- 其他题 -->
-                            <span v-else @click="toQu(index)" :class="['qu-index',stuScore[getScoreIndex(index)] > -1 ? 'right-qu' : '']">
-                                {{index + 1}}
-                            </span>
+                        <span v-show="!taskInfo.qu.length || taskInfo.qu.includes(index)" v-for="(item,index) in quNoList" :key="index" :class="['qu-index',stuScore[index] > -1 ? 'right-qu' : '']" @click="toQu(index)">
+                            {{item.label}}
                         </span>
                     </div>
                 </div>
@@ -82,19 +66,19 @@
             <div class="score-wrap">
                 <div class="quick-score-box score-input-box">
                     <span>{{$t('learnActivity.mark.score')}}</span>
-                    <InputNumber style="flex:1" :max="10" :min="1" v-model="score" @on-change="setScore"></InputNumber>
+                    <InputNumber style="flex:1" :max="quScore[quIndex]" :min="1" v-model="score" @on-change="setScore"></InputNumber>
                 </div>
                 <div class="quick-score-box">
-                    <Button size="small" type="info" style="margin-right:8px" ghost @click="score = 10">
+                    <Button size="small" type="info" style="margin-right:8px" ghost @click="setScore(quScoreArr.length - 1)">
                         {{$t('learnActivity.mark.fullScore')}}
                     </Button>
-                    <Button size="small" type="error" ghost @click="score = 0">
+                    <Button size="small" type="error" ghost @click="setScore(0)">
                         {{$t('learnActivity.mark.zeroScore')}}
                     </Button>
                     <Icon :type="isShowNum ? 'md-eye-off' : 'md-eye'" class="toggle-num-status" @click="isShowNum = !isShowNum" />
                     <div :class="['score-key-box', isShowNum ? '':'hind-key-box']">
                         <vuescroll>
-                            <span v-for="(item,index) in quScoreArr" :key="index" :class="['score-key', stuScore[getScoreIndex(quIndex,childIndex)] == index ? 'score-key-active':'']" @click="setScore(index)">
+                            <span v-for="(item,index) in quScoreArr" :key="index" :class="['score-key', stuScore[quIndex] == index ? 'score-key-active':'']" @click="setScore(index)">
                                 {{item}}
                             </span>
                         </vuescroll>
@@ -119,10 +103,37 @@
                 </div>
             </div>
         </div>
+        <!-- 完成阅卷的提示信息 -->
+        <div class="complete-mark" v-show="isComplete">
+            <div class="complete-box">
+                <Icon type="md-checkmark-circle-outline" class="ok-icon" />
+                <p style="margin-top:20px;font-size:14px">
+                    学生:{{stuId}}
+                </p>
+                <p style="font-size:20px;margin-top:5px">
+                    已阅完
+                </p>
+                <Button type="success" class="continue-btn" @click="continueMark">继续阅卷</Button>
+                <Button type="info" class="quit-btn" @click="quit">退出阅卷</Button>
+            </div>
+        </div>
         <!-- 用来单独渲染学生作答数据,提高tocanvas 的效率 -->
         <iframe id="markIframe" :srcdoc="curAnswer"></iframe>
         <Modal v-model="toggleStatus" :title="$t('learnActivity.mark.toggleStu')" :width="800" footer-hide>
-            <StuProg @getStuId="toByStuView" class="light-stu-prog" :total="taskInfo.count" :stusData="stusData"></StuProg>
+            <StuProg @getStuId="toByStuView" class="light-stu-prog" :total="taskInfo.count" :stusData="stusData" :qus="taskInfo ? taskInfo.qu : []"></StuProg>
+        </Modal>
+        <Modal v-model="errStatus" title="异常原因" :width="600" @on-ok="exception" :loading="loading">
+            <CheckboxGroup v-model="errReason">
+                <Checkbox label="twitter" class="reason-item">
+                    <span>答案不清晰,看不清楚</span>
+                </Checkbox>
+                <Checkbox label="facebook" class="reason-item">
+                    <span>答案图片不完整</span>
+                </Checkbox>
+                <Checkbox label="github" class="reason-item">
+                    <span>其他原因</span>
+                </Checkbox>
+            </CheckboxGroup>
         </Modal>
     </div>
 </template>
@@ -138,6 +149,10 @@ export default {
     },
     data() {
         return {
+            isComplete: false,
+            loading: true,
+            errReason: [],
+            errStatus: false,
             score: null,
             mouseStatus: 'move',
             drawImgData: '',
@@ -149,7 +164,6 @@ export default {
             activeIcon: -1,
             isShowNum: true,
             quIndex: 0,
-            childIndex: -1,
             stuData: {
                 name: '',
                 id: '',
@@ -162,16 +176,44 @@ export default {
             taskInfo: {},
             stusData: [],
             stuId: '',
-            markImg: undefined
+            markImg: undefined,
+            quScore: [] //题目配分数据
         }
     },
     methods: {
+        //继续阅卷
+        continueMark() {
+            let stu = this.stusData.find(item => {
+                return item.stuId == this.stuId
+            })
+            if (stu) {
+                stu.item.forEach((item, index) => {
+                    item.sc = this.stuScore[index]
+                })
+            } else {
+                this.stuData.item.forEach((item, index) => {
+                    item.sc = this.stuScore[index]
+                })
+                this.stusData.push(this.stuData)
+            }
+
+            this.toggleStatus = true
+        },
         exception() {
-            this.$Message.warning('功能开发中')
+            if (this.errReason.length) {
+                this.errStatus = false
+                this.$Message.warning('暂未对接API')
+                this.errReason = []
+            } else {
+                this.loading = false
+                setTimeout(() => {
+                    this.loading = true
+                })
+                this.$Message.warning('请选择异常原因')
+            }
         },
         //保存批注
         saveMark(data) {
-            console.log(data)
             this.markImg = data.base64
         },
         drawImg(imgIndex) {
@@ -182,6 +224,31 @@ export default {
                 this.drawImgData = curImg
             }
         },
+        /**
+         * index 题目index 必传
+         * childIndex 小题index 非必传 
+         */
+        getScoreIndex(index, childIndex) {
+            let realIndex = 0
+            this.paperData.item.forEach((item, itemIndex) => {
+                if (itemIndex <= index) {
+                    //综合题
+                    if (item.children.length) {
+                        item.children.forEach((childItem, cIndex) => {
+                            if (itemIndex < index) {
+                                realIndex++
+                            } else if (cIndex <= childIndex) {
+                                realIndex++
+                            }
+                        })
+                    }
+                    else {
+                        realIndex++
+                    }
+                }
+            })
+            return --realIndex
+        },
         //清除所有批注
         clear() {
             this.$refs['markCanvas'].clear()
@@ -202,7 +269,7 @@ export default {
                 answerIframe.style.width = (bodyWidth + 20) + 'px'
                 answerIframe.contentWindow.document.body.style.backgroundColor = '#f5f5f5'
                 html2canvas(answerIframe.contentWindow.document.body, {}).then((canvas) => {
-                    canvas.id = "canvas" + this.getScoreIndex(this.quIndex, this.childIndex)
+                    canvas.id = "canvas" + this.quIndex
                     this.ansImg = canvas.toDataURL()
                     // 将转出来的答案绘制到canvas上
                 })
@@ -211,40 +278,15 @@ export default {
         /** 打分 */
         setScore(score) {
             this.score = score
-            this.$set(this.stuScore, this.getScoreIndex(this.quIndex, this.childIndex), score)
-            if (this.autoQu) {
-                this.submit()
-            }
+            this.$set(this.stuScore, this.quIndex, score)
+            //暂时去掉打分自动提交的功能
+            // if (this.autoQu) {
+            //     this.submit()
+            // }
         },
-        toQu(index, childIndex) {
+        toQu(index) {
             this.quIndex = index
-            this.childIndex = childIndex
-            this.score = this.stuScore[this.getScoreIndex(this.quIndex, this.childIndex)] == -1 ? null : this.stuScore[this.getScoreIndex(this.quIndex, this.childIndex)]
-        },
-        /**
-         * index 题目index 必传
-         * childIndex 小题index 非必传 
-         */
-        getScoreIndex(index, childIndex) {
-            let realIndex = 0
-            this.paperData.item.forEach((item, itemIndex) => {
-                if (itemIndex <= index) {
-                    //综合题
-                    if (item.children.length) {
-                        item.children.forEach((childItem, cIndex) => {
-                            if (itemIndex < index) {
-                                realIndex++
-                            } else if (cIndex <= childIndex) {
-                                realIndex++
-                            }
-                        })
-                    }
-                    else {
-                        realIndex++
-                    }
-                }
-            })
-            return --realIndex
+            this.score = this.stuScore[index] == -1 ? null : this.stuScore[index]
         },
         //提交分数
         submit() {
@@ -254,7 +296,7 @@ export default {
                 if (this.markImg) {
                     let img = document.createElement('img')
                     img.src = this.markImg
-                    this.stuAnswer[this.getScoreIndex(this.quIndex, this.childIndex)] = img.outerHTML
+                    this.stuAnswer[this.quIndex] = img.outerHTML
                     mark = this.stuAnswer
                     this.markImg = undefined
                 }
@@ -266,6 +308,7 @@ export default {
                     score: this.stuScore,
                     count: this.taskInfo.count,
                     code: this.taskInfo.ecode.replace('Exam-', ''),
+                    qu: this.taskInfo.qu,
                     mark
                 }
                 this.$api.mark.saveScore(requstData).then(
@@ -283,105 +326,51 @@ export default {
             }
         },
         nextQuestion() {
-            //首先判断是都已阅完
-            if (!this.stuScore.includes(-1)) {
+            //首先判断是否都已评分
+            let s = this._.cloneDeep(this.stuScore)
+            if (this.taskInfo.qu.length) {
+                s = s.filter((item, index) => {
+                    return this.taskInfo.qu.includes(index)
+                })
+            }
+            if (!s.includes(-1)) {
                 if (this.autoStu) {
-                    this.toggleStatus = true
+                    this.isComplete = true
                 } else {
                     this.$Message.warning(this.$t('learnActivity.mark.completeStu'))
                 }
                 return
             }
-
-            // 当前不是最后一题
-            if (this.quIndex < this.paperData.item.length - 1) {
-                //当前题目是综合题
-                if (this.paperData.item[this.quIndex].children.length) {
-                    //当前小题不是最后一个
-                    if (this.childIndex < this.paperData.item[this.quIndex].children.length - 1) {
-                        this.childIndex++
-                    }
-                    //当前小题是最后一个,需要判断下一个题目类型
-                    //下一个题目是综合题
-                    else if (this.childIndex == this.paperData.item[this.quIndex].children.length - 1 && this.paperData.item[this.quIndex + 1].children.length) {
-                        this.quIndex++
-                        this.childIndex = 0
-                    }
-                    // 下一个题目不是综合题
-                    else {
-                        this.quIndex++
-                        this.childIndex = -1
+            //如果是按题分配的则在分配的题目里面获取下一题
+            if (this.taskInfo.qu.length) {
+                //指定题目的数组在保存的时候是做了排序的,所以这里可以直接循环判断大小即可
+                let has = false
+                for (let qu of this.taskInfo.qu) {
+                    if (qu > this.quIndex && this.stuScore[qu] == -1) {
+                        this.quIndex = qu
+                        has = true
+                        break
                     }
                 }
-                //当前题目不是综合题
-                else {
-                    //下一个题目是综合题
-                    if (this.paperData.item[this.quIndex + 1].children.length) {
-                        this.quIndex++
-                        this.childIndex = 0
-                    }
-                    // 下一个题目不是综合题
-                    else {
-                        this.quIndex++
-                        this.childIndex = -1
-                    }
+                if (!has) {
+                    this.$Message.success('还有未阅题目')
                 }
             }
-            //如果是最后一题
+            //按人分配则在所有题目里面获取下一题
             else {
-                //当前题目是综合题,并且不是小题最后一题
-                if (this.paperData.item[this.quIndex].children.length && this.childIndex < this.paperData.item[this.quIndex].children.length - 1) {
-                    this.childIndex++
-                }
-                //当前目不是综合题 则代表题号已经到最后一个
-                else {
-                    //检查所有题目是否完成评测
-                    if (this.stuScore.includes(-1)) {
-                        let qu = ''
-                        let quIndex = 0
-                        let childIndex = -1
-                        let realIndex = 0
-                        // 检测具体未评分的题目
-                        for (let i = 0; i < this.paperData.item.length; i++) {
-                            if (this.paperData.item[i].children.length) {
-                                let flag = false
-                                for (let j = 0; j < this.paperData.item[i].children.length; j++) {
-                                    if (this.stuScore[realIndex++] == -1) {
-                                        quIndex = i
-                                        childIndex = j
-                                        flag = true
-                                        break
-                                    }
-                                }
-                                if (flag) {
-                                    break
-                                }
-                            } else {
-                                if (this.stuScore[realIndex++] == -1) {
-                                    quIndex = i
-                                    break
-                                }
-                            }
-                        }
-                        qu = childIndex > -1 ? `${(quIndex + 1)}-${(childIndex + 1)}` : quIndex
-                        this.$Modal.confirm({
-                            title: this.$t('learnActivity.mark.ummarkQu'),
-                            content: `${qu}${this.$t('learnActivity.mark.unmarkContent')}`,
-                            onOk: () => {
-                                this.quIndex = quIndex
-                                this.childIndex = childIndex
-                            }
-                        })
-                    } else {
-                        this.$Message.success(this.$t('learnActivity.mark.finished'))
-                        if (this.autoStu) {
-                            //TODE 随机获取下一位学生
-                            this.toggleStatus = true
-                        }
+                let has = false
+                for (let qu of this.quNoList) {
+                    if (qu.value > this.quIndex && this.stuScore[qu] == -1) {
+                        this.quIndex = qu.value
+                        has = true
+                        break
                     }
                 }
+                if (!has) {
+                    this.$Message.success('还有未阅题目')
+                }
             }
-            this.score = this.stuScore[this.getScoreIndex(this.quIndex, this.childIndex)] == -1 ? null : this.stuScore[this.getScoreIndex(this.quIndex, this.childIndex)]
+            this.score = this.stuScore[this.quIndex] == -1 ? null : this.stuScore[this.quIndex]
         },
 
         quit() {
@@ -395,6 +384,7 @@ export default {
          */
         async toByStuView(stuId) {
             this.toggleStatus = false
+            this.isComplete = false
             // 如果挑选的是当前的学生
             if (stuId) {
                 let stuInfo = this.stusData.find(item => {
@@ -408,7 +398,9 @@ export default {
                     stuInfo.answer = ansBlob ? JSON.parse(await this.$tools.getFile(`${blobUrl}/exam/${ansBlob}?${sas}`)) : []
                 }
                 this.stuAnswer = stuInfo.answer
-                this.stuScore = stuInfo.scores
+                this.stuScore = stuInfo.item.map(item => {
+                    return item.sc
+                })
                 this.stuId = stuId
             }
             // 随机获取一名学生
@@ -435,7 +427,6 @@ export default {
          * @param stuId 如果传了stuid则会获取对应学生的数据,否则随机获取一个学生
          */
         getNextStu(stuId) {
-            console.log(this.markList, this.taskInfo)
             let requestData = {
                 code: this.taskInfo.ecode.replace('Exam-', ''),
                 id: this.taskInfo.id,
@@ -447,19 +438,18 @@ export default {
             this.$api.mark.FindNextStu(requestData).then(
                 async res => {
                     if (res && !res.msg) {
-                        console.log('数据格式', this.stusData)
                         this.stusData.push(res)
-
                         let sas = this.$store.state.user.schoolProfile.blob_sas //目前只有校本评测安排阅卷任务
                         let blobUrl = JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri //目前只有校本评测安排阅卷任务
-
                         let index = res.tIds.indexOf(this.$store.state.userInfo.TEAMModelId)
                         let ansBlob = index > -1 ? res.marks[index] || res.blob : res.blob
                         let answer = ansBlob ? JSON.parse(await this.$tools.getFile(`${blobUrl}/exam/${ansBlob}?${sas}`)) : []
 
                         this.stuId = res.stuId
                         this.stuAnswer = answer
-                        this.stuScore = res.scores
+                        this.stuScore = res.item.map(item => {
+                            return item.sc
+                        })
                         this.toggleStatus = false
                     } else {
                         this.$Message.error('API ERROR')
@@ -479,36 +469,38 @@ export default {
         this.paperData = routeData.fullPaper
         this.stuAnswer = routeData.answer
         this.stuScore = routeData.score
+        this.quScore = routeData.quScore
         this.stusData = routeData.stusData
         this.taskInfo = routeData.task
         this.stuId = routeData.stuId
-        //初始化题目index
-        if (this.paperData && this.paperData.item.length) {
-            this.quIndex = 0
-            if (this.paperData.item[this.quIndex] && this.paperData.item[this.quIndex].children.length) {
-                this.childIndex = 0
+        this.stuData = routeData.stuData
+        console.log('路由数据',routeData)
+        if (this.paperData && this.stuAnswer && this.stuScore && this.quScore && this.taskInfo && this.stuId) {
+            //初始化题目index
+            if (this.taskInfo.qu && this.taskInfo.qu.length) {
+                this.quIndex = this.taskInfo.qu[0]
+            } else {
+                this.quIndex = 0
             }
-        }
-        //默认表情包
-        for (let i = 0; i < 9; i++) {
-            this.imgs.push(require('@/assets/mark/' + i + '.svg'))
+            //默认表情包
+            for (let i = 0; i < 9; i++) {
+                this.imgs.push(require('@/assets/mark/' + i + '.svg'))
+            }
+        } else {
+            this.$Message.error('数据错误')
+            this.quit()
         }
     },
     computed: {
-        /**当期题目分数数组 */
+        /**题目分数数组 */
         quScoreArr() {
-            let score = 0
-            if (this.childIndex > -1 && this.paperData.item[this.quIndex] && this.paperData.item[this.quIndex].children) {
-                score = this.paperData.item[this.quIndex].children[this.childIndex].score
-            } else {
-                score = this.paperData.item[this.quIndex].score
-            }
+            let score = this.quScore[this.quIndex] || 10
             return Array.from(new Array(score + 1).keys())
         },
         /**当前题目作答数据 */
         curAnswer() {
             if (this.stuAnswer.length) {
-                let index = this.getScoreIndex(this.quIndex, this.childIndex)
+                let index = this.quIndex
                 this.score = this.stuScore[index] == -1 ? null : this.stuScore[index]
                 return this.stuAnswer[index]
             } else {
@@ -522,11 +514,74 @@ export default {
                 b = b == -1 ? 0 : b
                 return a + b
             }, 0)
+        },
+        //试卷题号列表
+        quNoList() {
+            if (this.paperData.item.length) {
+                let objectiveQu = ['single', 'multiple', 'judge']
+                let data = []
+                let realIndex = 0
+                this.paperData.item.forEach((item, index) => {
+                    if (item.children.length) {
+                        item.children.forEach((childItem, childIndex) => {
+                            data.push({
+                                label: (index + 1) + '-' + (childIndex + 1),
+                                value: realIndex++,
+                                disabled: objectiveQu.includes(childItem.type)
+                            })
+                        })
+                    } else {
+                        data.push({
+                            label: (index + 1) + '',
+                            value: realIndex++,
+                            disabled: objectiveQu.includes(item.type)
+                        })
+                    }
+                })
+                return data
+            }
+            return []
         }
     }
 }
 </script>
 <style scoped lang="less">
+.continue-btn {
+    margin-top: 50px;
+    width: 150px;
+    display: block;
+}
+.quit-btn {
+    display: block;
+    width: 150px;
+    margin-top: 4px;
+}
+.complete-mark {
+    width: 100%;
+    height: 100%;
+    background: #fcfcfc;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .complete-box {
+        text-align: center;
+        margin-top: -50px;
+        font-size: 16px;
+        padding: 50px 80px;
+        height: fit-content;
+        box-shadow: 0px 0px 10px #dbdbdb;
+        background: white;
+    }
+    .ok-icon {
+        color: #19be6b;
+        display: block;
+        font-size: 110px;
+    }
+}
+.reason-item {
+    display: block;
+    margin: 10px;
+}
 .light-stu-prog {
     margin-bottom: 15px;
 }

+ 0 - 1
TEAMModelOS/ClientApp/src/view/task/mark/MarkCanvas.vue

@@ -1,5 +1,4 @@
 <template>
-    <!-- 未做多语言 -->
     <div class="mark-stage">
         <vuescroll ref="canvasScroll">
             <!-- canvas部分 -->

+ 81 - 90
TEAMModelOS/ClientApp/src/view/task/mark/QuProg.vue

@@ -1,59 +1,24 @@
 <template>
     <div>
-        <div v-for="(item,index) in paperData.item" :key="index">
-            <!-- 综合题 -->
-            <div v-if="item.children.length">
-                <div class="qu-info-item" v-for="(childItem,childIndex) in item.children" :key="childIndex">
-                    <span :class="['qu-index', objectiveQu.includes(childItem.type) ? 'obj-index' : 'other-index']">
-                        {{`${index + 1}-${childIndex + 1}`}}
+        <div v-for="(item,index) in quNoList" :key="index" v-show="!item.disabled" class="qu-info-item">
+            <span :class="['qu-index', objectiveQu.includes(item.type) ? 'obj-index' : 'other-index']">
+                {{item.label}}
+            </span>
+            <div class="progress-wrap">
+                <Progress :percent="byQuPct[index]" />
+                <p>
+                    <span style="margin-right:10px">
+                        {{$t('task.mLabel2')}}:{{byQuCount[index]}}
                     </span>
-                    <div class="progress-wrap">
-                        <Progress :percent="objectiveQu.includes(childItem.type) ? 100 : byQuPct[getScoreIndex(index,childIndex)]" />
-                        <!-- <Progress :percent="byQuPct[getScoreIndex(index,childIndex)]" /> -->
-                        <p v-if="objectiveQu.includes(childItem.type)" class="prog-tips" style="color: #19be6b">
-                            {{$t('task.objectiveQu')}}
-                        </p>
-                        <p v-else class="prog-tips">
-                            <span style="margin-right:10px">
-                                {{$t('task.mLabel2')}}:{{byQuCount[getScoreIndex(index,childIndex)]}}
-                            </span>
-                            <span>
-                                {{$t('task.mLabel3')}}:{{total - byQuCount[getScoreIndex(index,childIndex)]}}
-                            </span>
-                        </p>
-                    </div>
-                    <div class="to-mark">
-                        <Button type="primary" shape="circle" :disabled="objectiveQu.includes(childItem.type)" size="small" style="width:120px" @click="setQuIndex(index, childIndex)">
-                            {{$t('task.mark')}}
-                        </Button>
-                    </div>
-                </div>
+                    <span>
+                        {{$t('task.mLabel3')}}:{{total - byQuCount[index]}}
+                    </span>
+                </p>
             </div>
-            <!-- 其他题 -->
-            <div v-else class="qu-info-item">
-                <span :class="['qu-index', objectiveQu.includes(item.type) ? 'obj-index' : 'other-index']">
-                    {{index + 1}}
-                </span>
-                <div class="progress-wrap">
-                    <Progress :percent="objectiveQu.includes(item.type) ? 100 : byQuPct[getScoreIndex(index)]" />
-                    <!-- <Progress :percent="byQuPct[getScoreIndex(index)]" /> -->
-                    <p v-if="objectiveQu.includes(item.type)" class="prog-tips" style="color: #19be6b">
-                        {{$t('task.objectiveQu')}}
-                    </p>
-                    <p v-else>
-                        <span style="margin-right:10px">
-                            {{$t('task.mLabel2')}}:{{byQuCount[getScoreIndex(index,-1)]}}
-                        </span>
-                        <span>
-                            {{$t('task.mLabel3')}}:{{total - byQuCount[getScoreIndex(index,-1)]}}
-                        </span>
-                    </p>
-                </div>
-                <div class="to-mark">
-                    <Button type="primary" shape="circle" :disabled="objectiveQu.includes(item.type)" size="small" style="width:120px" @click="setQuIndex(index, -1)">
-                        {{$t('task.mark')}}
-                    </Button>
-                </div>
+            <div class="to-mark">
+                <Button type="primary" shape="circle" :disabled="objectiveQu.includes(item.type)" size="small" style="width:120px" @click="setQuIndex(index)">
+                    {{$t('task.mark')}}
+                </Button>
             </div>
         </div>
     </div>
@@ -84,6 +49,14 @@ export default {
             type: Number,
             default: 1,
             required: true
+        },
+        //批阅题目
+        qus: {
+            type: Array,
+            default: () => {
+                return []
+            },
+            required: true
         }
     },
     data() {
@@ -92,33 +65,8 @@ export default {
         }
     },
     methods: {
-        /**
-         * index 题目index 必传
-         * childIndex 小题index 非必传 
-         */
-        getScoreIndex(index, childIndex) {
-            let realIndex = 0
-            this.paperData.item.forEach((item, itemIndex) => {
-                if (itemIndex <= index) {
-                    //综合题
-                    if (item.children.length) {
-                        item.children.forEach((childItem, cIndex) => {
-                            if (itemIndex < index) {
-                                realIndex++
-                            } else if (cIndex <= childIndex) {
-                                realIndex++
-                            }
-                        })
-                    }
-                    else {
-                        realIndex++
-                    }
-                }
-            })
-            return --realIndex
-        },
-        setQuIndex(quIndex, childIndex) {
-            this.$emit('getQuIndex', { quIndex, childIndex })
+        setQuIndex(index) {
+            this.$emit('getQuIndex', index)
         }
     },
     computed: {
@@ -140,25 +88,68 @@ export default {
         //题目进度百分比
         byQuPct() {
             let total = this.total || 1
-            return this.byQuCount.map(item => {
-                return item * 100 / total
+            let data = this.byQuCount.map(item => {
+                return parseFloat((item * 100 / total).toFixed(2))
             })
+            return data
         },
         //题目进度count
         byQuCount() {
             let res = new Array(this.quLength).fill(0)
             if (this.stusData) {
-                for (let i = 0; i < this.quLength; i++) {
-                    this.stusData.forEach(item => {
-                        if (item.scores[i] > -1) {
-                            res[i]++
-                        }
-                    })
+                if (this.qus.length) {
+                    //只处理需要批阅的题目数据
+                    for (let index of this.qus) {
+                        this.stusData.forEach(item => {
+                            if (item.item[index].sc > -1) {
+                                res[index]++
+                            }
+                        })
+                    }
+                } else {
+                    // 需要处理所有题目数据
+                    for (let i = 0; i < this.quLength; i++) {
+                        this.stusData.forEach(item => {
+                            if (item.item[i].sc > -1) {
+                                res[i]++
+                            }
+                        })
+                    }
                 }
-
             }
             return res
         },
+        //试卷题号列表
+        quNoList() {
+            if (this.paperData.item.length) {
+                let objectiveQu = ['single', 'multiple', 'judge']
+                let data = []
+                let realIndex = 0
+                this.paperData.item.forEach((item, index) => {
+                    if (item.children.length) {
+                        item.children.forEach((childItem, childIndex) => {
+                            data.push({
+                                label: (index + 1) + '-' + (childIndex + 1),
+                                value: realIndex,
+                                disabled: objectiveQu.includes(childItem.type) || (this.qus.length && !this.qus.includes(realIndex)),
+                                type: childItem.type
+                            })
+                            realIndex++
+                        })
+                    } else {
+                        data.push({
+                            label: index + 1,
+                            value: realIndex,
+                            disabled: objectiveQu.includes(item.type) || (this.qus.length && !this.qus.includes(realIndex)),
+                            type: item.type
+                        })
+                        realIndex++
+                    }
+                })
+                return data
+            }
+            return []
+        }
     }
 }
 </script>
@@ -185,10 +176,10 @@ export default {
         width: 380px;
     }
 }
-.obj-index{
+.obj-index {
     color: #606060;
 }
-.other-index{
+.other-index {
     color: white;
 }
 </style>

+ 37 - 5
TEAMModelOS/ClientApp/src/view/task/mark/StuProg.vue

@@ -62,6 +62,14 @@ export default {
             required: true,
             type: Number,
             default: 0
+        },
+        //老师需要批阅的题目,如果为空数组代表是批阅所有题目
+        qus: {
+            required: true,
+            type: Array,
+            default: () => {
+                return []
+            }
         }
     },
     data() {
@@ -90,9 +98,17 @@ export default {
         //当前阅卷任务已阅学生信息
         marked() {
             if (this.stusData) {
-                return this.stusData.filter(item => {
-                    return item.scores.indexOf(-1) == -1
-                    // return item.info.score.indexOf(-1) == -1
+                return this.stusData.filter((item) => {
+                    let scores = item.item.map(scoreItem => {
+                        return scoreItem.sc
+                    })
+                    //如果是按题分配的任务,只验证指定给老师的题目
+                    if (this.qus.length) {
+                        scores = scores.filter((sItem, sIndex) => {
+                            return this.qus.includes(sIndex)
+                        })
+                    }
+                    return !scores.includes(-1)
                 })
             } else {
                 return []
@@ -101,13 +117,29 @@ export default {
         //当前阅卷任务进行中学生信息
         marking() {
             if (this.stusData) {
-                return this.stusData.filter(item => {
-                    return item.scores.indexOf(-1) !== -1
+                return this.stusData.filter((item) => {
+                    let scores = item.item.map(scoreItem => {
+                        return scoreItem.sc
+                    })
+                    //如果是按题分配的任务,只验证指定给老师的题目
+                    if (this.qus.length) {
+                        scores = scores.filter((sItem, sIndex) => {
+                            return this.qus.includes(sIndex)
+                        })
+                    }
+                    return scores.includes(-1)
                 })
             } else {
                 return []
             }
         },
+    },
+    watch: {
+        // stusData: {
+        //     handler(n, o) {
+        //     },
+        //     deep: true
+        // }
     }
 }
 </script>