Browse Source

赛课——成绩公示

XW 1 year ago
parent
commit
2ff7c83e3e

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

@@ -10,4 +10,7 @@ export default {
     websiteManage: function(data) {
         return post('/activity/website-manage', data)
     },
+    teaContest: function(data) {
+        return post('/activity/teacher-contest', data)
+    },
 }

+ 192 - 95
TEAMModelOS/ClientApp/src/view/signupActivity/infoComponent/skContent.vue

@@ -143,36 +143,62 @@
                 <div class="data-box" id="score-position" v-if="contestInfo.modules.includes('score')">
                     <div class="module-title">成绩统计</div>
                     <div class="module-data">
-                        <div class="tab-header">
-                            <div v-show="!awardsing">
-                                <Button @click="setAwards()">设置奖项</Button>
-                                <Button @click="openAch()" style="margin-left: 20px;">公示成绩</Button>
+                        <div class="tab-header join-data">
+                            <div>
+                                <p>个人查看自己成绩</p>
+                                <p>{{ contestInfo.score.showDetail ? '展示细项得分' : '只展示总分' }}</p>
                             </div>
-                            <div v-show="awardsing">
-                                <Button @click="awardsShow = true">批量设置</Button>
-                                <Button @click="awardTypes()" style="margin-left: 20px;">取消</Button>
+                            <div>
+                                <p>统计作品公布方式</p>
+                                <p>{{ contestInfo.score.showType ? '按等级分布' : '按分数公布' }}</p>
+                            </div>
+                            <div v-show="!contestInfo.score.showType">
+                                <p>统计公布成绩范围</p>
+                                <p>{{ contestInfo.score.top }}</p>
+                            </div>
+                            <div v-show="contestInfo.score.showType">
+                                <p>等级排序方式</p>
+                                <p>{{ contestInfo.score.levelType ? '按照等级数量' : '按照分数范围' }}</p>
                             </div>
                         </div>
-                        <Table :columns="scoreColumns" :data="scoreList" height="600">
-                            <template #score1="{row}">
-                                <div v-show="!row.edit">
-                                    <span>{{ row.score1 }}</span>
+                        <div class="tab-header">
+                            <Button @click="awardsShow = true">统计成绩设置</Button>
+                            <Button @click="openAch()" style="margin-left: 20px;">公示成绩</Button>
+                            <!-- <Button style="float: right;" @click="ruleDrawer = true">成绩公示预览</Button> -->
+                        </div>
+                        <Alert type="warning" v-show="contestInfo.score.actState === 'going'">
+                            <Icon type="ios-alert" color="orange" />
+                            已到成绩公示阶段,请及时发布成绩
+                        </Alert>
+                        <Table :columns="scoreColumns" :data="teacherScores" height="600">
+                            <template #poster="{row}">
+                                <PersonalPhoto :name="row.name" :picture="row.picture" />
+                                <!-- <img :src="row.picture" alt="" style="height: 50px;"> -->
+                            </template>
+                            <template #score="{row}">
+                                <span>{{ row.score === -1 ? '-' : row.score }}</span>
+                            </template>
+                            <template #maskScore="{row}">
+                                <span>{{ row.maskScore === -1 ? '-' : row.maskScore }}</span>
+                                <!-- <div v-show="!row.edit">
+                                    <span>{{ row.maskScore }}</span>
                                     <Icon type="md-nutrition" @click="row.edit = true" />
                                 </div>
                                 <div v-show="row.edit">
-                                    <InputNumber :min="0" v-model="row.score1" />
+                                    <InputNumber :min="0" v-model="row.maskScore" />
                                     <Icon type="md-checkmark-circle" @click="row.edit = false" />
                                     <Icon type="md-close-circle" @click="row.edit = false" />
-                                </div>
+                                </div> -->
                             </template>
-                            <template #awards="{row}">
-                                <span v-if="!awardsing">{{ row.awards ? row.awards : '-' }}</span>
-                                <div v-else>
-                                    <Select v-model="row.awards" style="width:200px" :transfer="true">
-                                        <Option v-for="item in awardsList" :value="item.value" :key="item.value">{{ item.label }}</Option>
-                                    </Select>
-                                    <Icon type="md-add-circle" @click="addAward = true" />
-                                </div>
+                            <template #showScore="{row}">
+                                <Tag color="green" v-show="!row.showScore">专家评分为准</Tag>
+                                <Tag color="orange" v-show="row.showScore">建议分数为准</Tag>
+                            </template>
+                            <template #scoreLevel="{row}">
+                                <span>{{ row.scoreLevel ? row.scoreLevel : '-' }}</span>
+                            </template>
+                            <template #action="{row}">
+                                <Button type="info" size="small" @click="changeScore(row)">调整</Button>
                             </template>
                         </Table>
                     </div>
@@ -269,13 +295,31 @@
                 <Radio v-for="item in processList" :key="item.id" :label="item.id">{{ item.iname }}</Radio>
             </RadioGroup>
         </Modal>
-        <Modal v-model="awardsShow" title="批量设置奖项">
-            <Select v-model="awardsSel" style="width:200px">
-                <Option v-for="item in awardsList" :value="item.value" :key="item.value">{{ item.label }}</Option>
-            </Select>
+        <Modal v-model="awardsShow" title="成绩等级设置" width="1000" :footer-hide="true">
+            <UpdateScore :actInfo="actInfo" :scoreSet="contestInfo.score" @scoreLevelChange="scoreLevelChange" />
         </Modal>
-        <Modal v-model="addAward" title="新增奖项" @on-ok="addAwardOK()">
-            <Input v-model="addAwardWord" placeholder="Enter something..." style="width: 300px" />
+        <Modal v-model="maskType" title="调整参数作品分数" :footer-hide="true">
+            <Form v-if="maskInfo">
+                <FormItem label="作品:">
+                    <span>{{ maskInfo.uploadName }}</span>
+                </FormItem>
+                <FormItem label="分数展示:">
+                    <RadioGroup v-model="maskInfo.showScore">
+                        <Radio :label="0">
+                            <span>专家评分为准</span>
+                        </Radio>
+                        <Radio :label="1">
+                            <span>建议分数为准</span>
+                        </Radio>
+                    </RadioGroup>
+                </FormItem>
+                <FormItem label="建议分数:">
+                    <InputNumber :max="100" :min="0" v-model="maskInfo.maskScore" placeholder="请输入" />
+                </FormItem>
+                <FormItem>
+                    <Button long type="primary" @click="saveMask()">保存</Button>
+                </FormItem>
+            </Form>
         </Modal>
     </div>
 </template>
@@ -283,10 +327,12 @@
 <script>
 import expertImport from './expertImport.vue'
 import RuleDrawer from './ruleDrawer.vue'
+import UpdateScore from './updateScore.vue'
 export default {
     components: {
         expertImport,
         RuleDrawer,
+        UpdateScore,
     },
     props: {
         actInfo: {
@@ -466,80 +512,63 @@ export default {
                     label: '三等奖'
                 },
             ],
-            awardsing: false,
             awardsShow: false,
             awardsSel: '',
             scoreColumns: [
+                {
+                    title: ' ',
+                    slot: 'poster',
+                    align: 'center',
+                    width: 50,
+                },
                 {
                     title: '姓名/组名',
                     key: 'name',
+                    align: 'center',
                 },
                 {
-                    title: '专家评分',
-                    key: 'score'
+                    title: '醍摩豆ID',
+                    key: 'tmdid',
+                    align: 'center',
                 },
                 {
-                    title: '建议分数',
-                    slot: 'score1'
+                    title: '学校',
+                    key: 'schoolName',
+                    align: 'center',
                 },
                 {
-                    title: '奖项',
-                    slot: 'awards'
-                },
-                /* {
-                    title: '操作',
-                    slot: 'actions',
-                    width: 150,
+                    title: '作品名称',
+                    key: 'uploadName',
                     align: 'center',
-                }, */
-            ],
-            scoreList: [
-                {
-                    name: '数学组',
-                    score: '67',
-                    score1: 85,
-                    awards: '',
-                    edit: false,
                 },
                 {
-                    name: '语文组',
-                    score: '92',
-                    score1: 85,
-                    awards: '',
-                    edit: false,
+                    title: '专家评分',
+                    slot: 'score',
+                    align: 'center',
                 },
                 {
-                    name: '数学组',
-                    score: '67',
-                    score1: 85,
-                    awards: '',
-                    edit: false,
+                    title: '建议分数',
+                    slot: 'maskScore',
+                    align: 'center',
                 },
                 {
-                    name: '语文组',
-                    score: '92',
-                    score1: 75,
-                    awards: '',
-                    edit: false,
+                    title: '分数展示',
+                    slot: 'showScore',
+                    align: 'center',
                 },
                 {
-                    name: '数学组',
-                    score: '67',
-                    score1: 45,
-                    awards: '',
-                    edit: false,
+                    title: '预设奖项',
+                    slot: 'scoreLevel',
+                    align: 'center',
                 },
                 {
-                    name: '语文组',
-                    score: '92',
-                    score1: 68,
-                    awards: '',
-                    edit: false,
+                    title: '操作',
+                    slot: 'action',
+                    width: 150,
+                    align: 'center',
                 },
             ],
             workProNum: 1,
-            addAward: false,
-            addAwardWord: '',
             teacherModal: false,
             teacherCloumns: [
                 {
@@ -602,6 +631,9 @@ export default {
             proIndex: null,
             workDrawer: false,
             workIndex: -1,
+            teacherScores: [],
+            maskInfo: undefined,
+            maskType: false,
         }
     },
     computed: {
@@ -617,6 +649,7 @@ export default {
         // this.applicationColumns[2].filters = this.actInfo.invitedSchools
         this.getProList()
         this.actTeaList()
+        this.getScore()
     },
     methods: {
         // 获取老师列表
@@ -1131,34 +1164,98 @@ export default {
                 }) */
             }
         },
-        setAwards() {
-            this.awardsing = true
-            this.scoreColumns.unshift({
-                type: 'selection',
-                width: 60,
-                align: 'center'
-            })
-            this.$forceUpdate()
-        },
         openAch() {
             this.$Modal.confirm({
                 title: '公示成绩',
-                content: '是否公示评审规则的细项分数?',
-                okText: '公示总分和细项分数',
-                cancelText: '公示总分',
+                content: '确认公示成绩后,参赛者将可以查看成绩排名和个人成绩',
+                okText: '确认公示',
+                cancelText: '取消',
                 onOk: () => {
-
+                    let params = {
+                        grant_type: 'update-scoreStatus',
+                        activityId: this.actInfo.id,
+                        scoreStatus: 1,
+                    }
+                    this.$api.areaActivity.manageAct(params).then(res => {
+                        if(res.code === 200) {
+                            this.$Message.success('已开始公示成绩')
+                        }
+                    })
                 }
             })
         },
-        awardTypes() {
-            this.awardsing = false
-            this.scoreColumns.splice(0, 1)
+        getScore() {
+            let params = {
+                grant_type: 'get-scores',
+                activityId: this.actInfo.id,
+            }
+            this.$api.areaActivity.manageAct(params).then(res => {
+                if(res.code === 200) {
+                    this.teacherScores = res.teacherScores.map(item => {
+                        item.scoreLevel = ''
+                        return item
+                    })
+                    this.getLevelScore()
+                }
+            })
         },
-        addAwardOK() {
-            this.awardsList.push({
-                value: this.addAwardWord,
-                label: this.addAwardWord
+        getLevelScore() {
+            let params = {
+                grant_type: 'preview-scores',
+                activityId: this.actInfo.id,
+            }
+            this.$api.areaActivity.manageAct(params).then(res => {
+                if(res.code === 200) {
+                    res.contestScores.forEach(item => {
+                        item.scores.forEach(score => {
+                            let infoIndex = this.teacherScores.findIndex(tea => tea.tmdid === score.tmdid)
+                            if(infoIndex != -1) {
+                                this.teacherScores[infoIndex].scoreLevel = score.scoreLevel
+                            }
+                        })
+                    })
+                }
+            })
+        },
+        scoreLevelChange(info) {
+            this.contestInfo.score = info
+            this.getLevelScore()
+            this.awardsShow = false
+        },
+        changeScore(row) {
+            if(this.contestInfo.score.actState != 'going') {
+                this.$Message.warning(this.contestInfo.score.actState === 'finish' ? '公示时间已结束' : '未到成绩公示时间')
+                return
+            }
+            this.maskInfo = this._.cloneDeep(row)
+            this.maskInfo.maskScore = this.maskInfo.maskScore === -1 ? null : this.maskInfo.maskScore
+            this.maskType = true
+        },
+        saveMask() {
+            if(this.maskInfo.maskScore && this.maskInfo.showScore === null) {
+                this.$Message.warning('请输入建议分数')
+                return
+            }
+            let params = {
+                grant_type: 'update-maskScore',
+                activityId: this.actInfo.id,
+                maskScoreDatas: []
+            }
+            params.maskScoreDatas.push({
+                uploadId: this.maskInfo.uploadId,
+                showScore: this.maskInfo.showScore,
+                maskScore: this.maskInfo.maskScore === null ? -1 : this.maskInfo.maskScore,
+            })
+            this.$api.areaActivity.manageAct(params).then(res => {
+                if(res.code === 200) {
+                    this.$Message.success('修改成功')
+                    let info = this.teacherScores.find(item => item.tmdid === this.maskInfo.tmdid)
+                    info.showScore = this.maskInfo.showScore
+                    info.maskScore = this.maskInfo.maskScore
+                    this.this.maskType = false
+                } else {
+                    this.$Message.warning('修改失败')
+                }
             })
         },
     }

+ 216 - 0
TEAMModelOS/ClientApp/src/view/signupActivity/infoComponent/updateScore.vue

@@ -0,0 +1,216 @@
+<template>
+    <div>
+        <Form :model="scoreInfo" label-position="top">
+            <FormItem label="个人查看自己成绩:">
+                <RadioGroup v-model="scoreInfo.showDetail">
+                    <Radio :label="0">
+                        <span>只展示总分</span>
+                    </Radio>
+                    <Radio :label="1">
+                        <span>展示细项得分</span>
+                    </Radio>
+                </RadioGroup>
+            </FormItem>
+            <FormItem label="成绩公布说明:">
+                <Input v-model="scoreInfo.attention" placeholder="请输入" />
+            </FormItem>
+            <FormItem label="统计作品公布方式:">
+                <RadioGroup v-model="scoreInfo.showType">
+                    <Radio :label="0">
+                        <span>按分数公布</span>
+                    </Radio>
+                    <Radio :label="1">
+                        <span>按等级分布</span>
+                    </Radio>
+                </RadioGroup>
+            </FormItem>
+            <FormItem label="统计公布成绩范围:" v-show="!scoreInfo.showType">
+                <InputNumber :max="100" :min="1" v-model="scoreInfo.top" />
+                <span>
+                    <Icon type="ios-alert-outline" color="#ffad16" size="18" />
+                    不填则表示公布所有
+                </span>
+            </FormItem>
+            <FormItem label="等级排序方式:" v-show="scoreInfo.showType">
+                <RadioGroup v-model="scoreInfo.levelType">
+                    <Radio :label="0">
+                        <span>按照分数范围</span>
+                    </Radio>
+                    <Radio :label="1">
+                        <span>按照等级数量</span>
+                    </Radio>
+                </RadioGroup>
+            </FormItem>
+            <FormItem label="等级分数设置:" v-show="scoreInfo.showType">
+                <Alert type="warning" show-icon v-show="!scoreInfo.levelType">各等级的最小值要与上一级的最大值一致,否则会保存失败</Alert>
+                <div>
+                    <Input v-model="levelInfo.lable" placeholder="请输入等级标签" style="width: 200px;" />
+                    <InputNumber :max="100" :min="0" v-model="levelInfo.min" v-show="!scoreInfo.levelType" placeholder="最小值" style="width: 70px; margin-left: 10px;" />
+                    <InputNumber :max="100" :min="1" v-model="levelInfo.max" v-show="!scoreInfo.levelType" placeholder="最大值" style="width: 70px; margin-left: 10px;" />
+                    <InputNumber :max="100" :min="1" v-model="levelInfo.top" v-show="scoreInfo.levelType" placeholder="数量" style="width: 70px; margin-left: 10px;" />
+                    <Button type="success" @click="addLevel()" style="margin-left: 10px;">添加</Button>
+                </div>
+                <div class="score-level">
+                    <span>等级名称</span>
+                    <span v-show="!scoreInfo.levelType">最小值</span>
+                    <span v-show="!scoreInfo.levelType">最大值</span>
+                    <span v-show="scoreInfo.levelType">数量</span>
+                </div>
+                <div v-for="(item, index) in scoreLevels" :key="index" class="score-level">
+                    <span>{{ item.lable }}</span>
+                    <span v-show="!scoreInfo.levelType">{{ item.min }}</span>
+                    <span v-show="!scoreInfo.levelType">{{ item.max }}</span>
+                    <span v-show="scoreInfo.levelType">{{ item.top }}</span>
+                    <Icon type="md-close" @click="deleteLevel(index)" />
+                </div>
+            </FormItem>
+            <FormItem>
+                <Button long type="primary" @click="saveLevel()">保存</Button>
+            </FormItem>
+        </Form>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        actInfo: {
+            type: Object,
+            default: {},
+        },
+        scoreSet: {
+            type: Object,
+            default: {},
+        },
+    },
+    data () {
+        return {
+            scoreInfo: {
+                showType: 0,
+                showDetail: 0,
+                levelType: 0,
+                top: null,
+                attention: '',
+            },
+            levelInfo: {
+                lable: '',
+                max: 1,
+                min: 0,
+                top: 1,
+            },
+            scoreLevels: []
+        }
+    },
+    created () {
+        this.scoreInfo = this._.cloneDeep(this.scoreSet)
+        this.scoreLevels = this._.cloneDeep(this.scoreSet.scoreLevels)
+    },
+    watch: {
+        scoreSet: {
+            handler(n, o) {
+                this.scoreInfo = n
+            },
+            deep: true,
+        },
+        'scoreInfo.levelType': {
+            handler(n, o) {
+                this.scoreLevels = []
+                this.levelInfo = {
+                    lable: '',
+                    max: 1,
+                    min: 0,
+                    top: 1
+                }
+            }
+        },
+    },
+    methods: {
+        addLevel() {
+            if(!this.levelInfo.lable || this.scoreInfo.levelType ? !this.levelInfo.top : (!this.levelInfo.max || this.levelInfo.min === null)) {
+                return
+            }
+            /* if(!this.levelInfo.lable || !this.levelInfo.max || this.levelInfo.min === null) {
+                return
+            } */
+            if(!this.scoreInfo.levelType) {
+                if(!this.scoreInfo.levelType && this.levelInfo.max <= this.levelInfo.min) {
+                    this.$Message.warning('等级分数最大值必须大于最小值')
+                    return
+                }
+                let overlap = this.scoreLevels.find(item => {
+                    return item.min < this.levelInfo.max && item.max > this.levelInfo.min
+                })
+                if(overlap) {
+                    this.$Message.warning('等级分数重叠,请重新设置')
+                    return
+                }
+            }
+            this.scoreLevels.push(this._.cloneDeep(this.levelInfo))
+            this.levelInfo = {
+                lable: '',
+                max: 1,
+                min: 0,
+                top: 1
+            }
+            this.scoreLevels = this.scoreLevels.sort((a, b) => b.max - a.max)
+        },
+        deleteLevel(index) {
+            this.scoreLevels.splice(index, 1)
+        },
+        saveLevel() {
+            let params = {
+                grant_type: 'update-scoreShowTypeOrLevel',
+                activityId: this.actInfo.id,
+                showType: this.scoreInfo.showType,
+                showDetail: this.scoreInfo.showDetail,
+                levelType: this.scoreInfo.levelType,
+                top: this.scoreInfo.top === null ? -1 : this.scoreInfo.top,
+                attention: this.scoreInfo.attention,
+                scoreLevels: this.scoreLevels
+            }
+            let levelWarn = params.scoreLevels.filter((item, index) => {
+                return index != (params.scoreLevels.length - 1) && item.min != params.scoreLevels[index + 1].max
+            })
+            if(!this.scoreInfo.levelType && levelWarn.length) {
+                this.$Message.warning('等级分数未完全覆盖,请添加或修改')
+                return
+            }
+            params.scoreLevels = params.scoreLevels.map((item, index) => {
+                item.order = index + 1
+                return item
+            })
+            this.$api.areaActivity.manageAct(params).then(res => {
+                if(res.code === 200) {
+                    this.$Message.success('设置成功')
+                    this.$emit('scoreLevelChange', params)
+                } else {
+                    this.$Message.warning('设置失败')
+                }
+            })
+        },
+    }
+}
+</script>
+
+<style lang="less" scoped>
+.score-level {
+    margin-left: 5px;
+
+    &>span {
+        display: inline-block;
+        width: 70px;
+        margin-right: 10px;
+
+        &:first-of-type {
+            width: 200px;
+        }
+    }
+    .ivu-icon {
+        cursor: pointer;
+
+        &:hover {
+            color: #bf2626;
+        }
+    }
+}
+</style>

+ 6 - 2
TEAMModelOS/ClientApp/src/view/signupActivity/infoGoing.vue

@@ -261,10 +261,14 @@ export default {
                         res.contest[item].startTime = this.$tools.formatTime(res.contest[item].stime, 'yyyy-MM-dd hh:mm:ss')
                         res.contest[item].endTime = this.$tools.formatTime(res.contest[item].etime, 'yyyy-MM-dd hh:mm:ss')
                         res.contest[item].actState = nowDate < res.contest[item].stime ? 'notStart' : (nowDate > res.contest[item].etime ? 'finish' : 'going')
-                        if(res.contest[item].actState === 'going') {
+                        /* if(res.contest[item].actState === 'going') {
                             this.currentSk = [0, 1].includes(index) ? 0 : (index === 2 ? 1 : (index === 3 ? 2 : 3))
-                        }
+                        } */
+                    })
+                    let index = res.contest.modules.findIndex(item => {
+                        return res.contest[item].actState === 'going'
                     })
+                    this.currentSk = index === -1 ? 4 : [0, 1].includes(index) ? 0 : (index === 2 ? 1 : (index === 3 ? 2 : 3))
                     this.contestInfo = res.contest
                     this.ruleInfo = res.reviewRule
                     if(this.actInfo.scope === 'area') {