项目实训记录(第12-13周)

前言

最近就在开发帮助教师统计分数的功能


一、统计分数功能设想

1、学生最后的分数由三部分组成:讨论分数,作业分数,考试分数
2、教师通过拖动滑动条设置这三部分成绩占比
3、教师上传学生考试成绩单
4、生成总的成绩表
5、导出成绩表
6、根据总成绩绘制学生成绩分布图

二、部分代码展示

<template>

  <div id="classes">
    <el-row :gutter="20">

      <el-col :span="12" :offset="1">
        <span class="demonstration">
          请依次为讨论、作业和期末考试赋予相应的权重,且和不超过100
        </span>
      </el-col>

      <el-col :span="16" :offset="1">
        <div class="block2">
          <el-slider
              v-model="value0"
              show-input>
          </el-slider>
        </div>
      </el-col>

      <el-col :span="16" :offset="1">
        <div class="block2">
          <el-slider
              v-model="value1"
              show-input>
          </el-slider>
        </div>
      </el-col>

      <el-col :span="16" :offset="1">
        <div class="block2">
          <el-slider
              v-model="value2"
              show-input>
          </el-slider>
        </div>
      </el-col>

    </el-row>

    <el-row>
      <el-col :span="3" :offset="1">
        <el-button
            type="primary" plain
            icon="el-icon-edit"
            class="filter-item"
            @click="calculate()">计算得分
        </el-button>
      </el-col>
    </el-row>

    <el-divider>

    </el-divider>


    <el-button class="btn-seal" @click="uploadTestScore()">
      上传考试分数
    </el-button>

    <el-button class="btn-seal" @click="getExportList()">
      导出成绩单
    </el-button>

    <el-button class="btn-seal" @click="hh()">
      画成绩分布图
    </el-button>

    <div class="body">
      <template>

        <el-table
            id="student-table"
            :data="tableData"
            stripe
            style="width: 100%">

          <el-table-column
              prop="sid"
              label="学号"
              width="180">
          </el-table-column>

          <el-table-column
              prop="name"
              label="姓名"
              width="180">
          </el-table-column>

          <el-table-column
              prop="discussion_score"
              label="讨论分数"
              width="180">
          </el-table-column>

          <el-table-column
              prop="homework_score"
              label="作业分数"
              width="180">
          </el-table-column>

          <el-table-column
              prop="test_score"
              label="考试分数"
              width="180">
          </el-table-column>

          <el-table-column
              prop="final_score"
              label="总得分"
              width="180">
          </el-table-column>

        </el-table>

      </template>

    </div>

    <!--这是要上传考试成绩单 -->
    <el-dialog :visible.sync="dialogFormVisible">
      <el-form
          :model="questionForm"
          ref="dataForm"
          label-position="left"
          label-width="90px"
          style="width: 400px; margin-left:50px;"
      >

        <el-form-item label="课程号" prop="cid">
          <el-input v-model="questionForm.cid" />
        </el-form-item>
        <el-form-item label="课程名" prop="classname">
          <el-input v-model="questionForm.classname" />
        </el-form-item>
        <el-form-item label="教工号" prop="tid">
          <el-input v-model="questionForm.tid" />
        </el-form-item>


        <el-form-item label="考试成绩单" prop="cid">
          <div class="upset">
            <el-upload drag
                       :limit=limitNum
                       :auto-upload="false"
                       accept=".xlsx"
                       :action="UploadUrl()"
                       :before-upload="beforeUploadFile"
                       :on-change="fileChange"
                       :on-exceed="exceedFile"
                       :on-success="handleSuccess"
                       :on-error="handleError"
                       :file-list="fileList">
              <i class="el-icon-upload">

              </i>

              <div class="el-upload__text">
                将xlsx文件拖到此处,或<em>点击上传</em>
              </div>

              <div class="el-upload__tip" slot="tip">
                格式要求
              </div>
            </el-upload>
            <br/>

          </div>
        </el-form-item>

      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click=" createData() ">
          确定
        </el-button>
      </div>
    </el-dialog>

    <el-divider>
    </el-divider>

    <!--这是要画成绩分布图 -->
    <div id="myChart123" :style="{width: '800px', height: '550px'}"></div>


  </div>



</template>


<script>
import * as echarts from 'echarts'
import {onMounted} from "vue";
export default {
  name: "score",
  props: ['cid'],

  data() {
    return{
      score_y : [],//新建的数值型数组
      //到这里都是负责上传考试成绩的功能
      questionForm: {

        cid: "",
        classname: "",
        tid: "",

      },
      dialogFormVisible: false,
      limitNum: 1,  // 上传excell时,同时允许上传的最大数
      fileList: [],   // excel文件列表

      //考试成绩功能上传结束

      value0: 0,
      value1: 0,
      value2: 0,
      my_user:'',
      class_id:'',
      tableData:[] ,//cid,name
      input: "",
      classname:'',
      drawscorelist:[],

    };

  },
  created() {

  },
  methods: {

    //这里是上传考试成绩的代码
    uploadTestScore() {
      this.questionForm = {

        cid: "",
        classname: "",
        tid: "",

      };
      this.dialogFormVisible = true;
    },
    beforeUpload(file){
      var formdata = new FormData();
      formdata.append('file',file);
      this.$axios.post('http://127.0.0.1:8080/excel',formdata,{ headers : { 'Content-type':'multipart/form-data'}});
    },

    // 文件超出个数限制时的钩子
    exceedFile(files, fileList) {
      this.$message.warning(`只能选择 ${this.limitNum} 个文件,当前共选择了 ${files.length + fileList.length}`);
    },

    // 文件状态改变时的钩子
    fileChange(file, fileList) {
      console.log(file.raw);
      this.fileList.push(file.raw) ;
      console.log(this.fileList);
    },

    // 上传文件之前的钩子, 参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传
    beforeUploadFile(file) {
      console.log('before upload');
      console.log(file);
      let extension = file.name.substring(file.name.lastIndexOf('.')+1);
      let size = file.size / 1024 / 1024;
      if(extension !== 'xlsx') {
        this.$message.warning('只能上传后缀是.xlsx的文件');
      }
      if(size > 10) {
        this.$message.warning('文件大小不得超过10M');
      }
    },

    // 文件上传成功时的钩子
    handleSuccess(res, file, fileList) {
      this.$message.success('文件上传成功');
    },

    // 文件上传失败时的钩子
    handleError(err, file, fileList) {
      this.$message.error('文件上传失败');
    },
    UploadUrl:function(){
      // 因为action参数是必填项,我们使用二次确认进行文件上传时,直接填上传文件的url会因为没有参数导致api报404,所以这里将action设置为一个返回为空的方法就行,避免抛错
      return ""
    },

    uploadFile() {
      if (this.fileList.length === 0){
        this.$message.warning('请上传文件');
      } else {
        let form = new FormData();

        form.append('file', this.fileList[0]);
        this.axios({
          method:"post",
          url: "/teacher/upload_score",
          headers:{
            'Content-type': 'multipart/form-data'
          },
          data:form

        }).then(
            res=>{

            },err =>{
            });
      }
    },

    async createData() {
      if (this.fileList.length === 0){
        this.$message.warning('请上传文件');
      } else {
        let form = new FormData();
        form.append('file', this.fileList[0]);
        form.append('cid', this.questionForm.cid);
        form.append('classname', this.questionForm.classname);
        form.append('tid', this.questionForm.tid);

        this.axios({
          method:"post",
          url: "/teacher/upload_score",
          headers:{
            'Content-type': 'multipart/form-data'
          },
          data:form

        }).then(
            res=>{

            },err =>{
            });
      }


      //如果需要调用接口,请打开注释
      //   const res = await saveSubject(params);
      //   console.log(res);
      //   if (res.code === "0000") {
      //     this.$message({
      //       type: "info",
      //       message: "保存成功",
      //     });
      //     this.dialogFormVisible = false;
      //     this.getQuerySubjectList();
      //     return;
      //   }
      //   this.$message({
      //     type: "error",
      //     message: "保存失败",
      //   });
      this.dialogFormVisible = false;
    },

//和上传考试成绩相关的代码结束

    calculate() {

      console.log(this.cid)
      console.log("cccc")

      this.class_id=this.cid
      this.my_user=this.$store.getters.id

      if(this.my_user===''){
        this.my_user=sessionStorage.getItem('teacher_id')
      }
      console.log("qwqwqwqwqwqw")
      console.log(this.value0/100)
      console.log(this.value1/100)
      console.log(this.value2/100)

      console.log("qwqwqwqwqwqw")
      this.axios({
        url: '/teacher/checkscore',
        method: 'get',
        params: {
          teacher_id: this.my_user,
          class_id: this.class_id,
          value0:this.value0/100,
          value1:this.value1/100,
          value2:this.value2/100,
        },
      }).then(
          (res) => {
            console.log(res)
            this.tableData = res.data
          },
          function (res) {
            console.log(res)
            console.log('啊呀,出错啦')
          }
      )


    },

    //试一试导出excel表格
    getExportList() {
      const _self=this
      let jsonData = {
        trade:{
          tHeader: ["学号","姓名","讨论分数","作业分数","考试分数","总得分"],
          filterVal: ["sid","name","discussion_score","homework_score","test_score","final_score"],
          list: _self.tableData
        }
      }
      _self.exportPathMethod(jsonData)// 调用exportPathMethod对数据进行处理导出
      _self.exportShow=false
    },

    exportPathMethod(data) {
      /*
      *注:csv文件:","逗号换列,\n换行,\t防止excel将长数字变科学计算法等样式
      */
      //要导出的json数据
      let mainLists = data.trade   //主表
      let _self = this
      //## 数据处理
      //一级表
      let mainTitle = mainLists.tHeader;//一级标题
      let mainTitleForKey = mainLists.filterVal;//一级过滤
      let mainList = mainLists.list;//一级数据
      let mainStr = [];
      mainStr.push(mainTitle.join("\t,")+"\n");   //标题添加上换列转成字符串并存进数组
      for(let i=0;i<mainList.length;i++){
        let temp = [];
        for(let j=0;j<mainTitleForKey.length;j++){
          temp.push(mainList[i][mainTitleForKey[j]]); //根据过滤器拿出对应的值
        }
        mainStr.push(temp.join("\t,")+"\n");    //取出来的值加上逗号换列转字符串存数组
      }
      // console.log(JSON.stringify(mainStr.join("")));//打印文本

      //两个表数组转成字符串合并
      let merged = mainStr.join("")
      //console.log(JSON.stringify(merged));//打印结果

      //## 导出操作
      // encodeURIComponent解决中文乱码
      const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(merged)
      // 通过创建a标签实现
      let link = document.createElement('a')
      link.href = uri


      //这里需要查询根据课程号查询出课程名
      this.axios({
        url: '/teacher/checkClassname',
        method: 'get',
        params: {
          cid: this.class_id
        },
      }).then(
          (res) => {
            console.log(res)
            this.classname = res.data
          },
          function (res) {
            console.log(res)
            console.log('啊呀,出错啦')
          }
      )


      // 对下载的文件命名
      link.download = `${_self.class_id}-${_self.classname}.csv`
      document.body.appendChild(link)
      link.click()
    },

    //下面是负责画成绩折线图的
    async hh(){
      //先是要获得五个区间的人数都分别是多少
      await this.axios({
        url: '/teacher/drawscore',
        method: 'get',
        params: {
          teacher_id: this.my_user,
          class_id: this.class_id,
          value0:this.value0/100,
          value1:this.value1/100,
          value2:this.value2/100,
        },
      }).then(
          (res) => {
            console.log(res)
            this.drawscorelist = res.data
          },
          function (res) {
            console.log(res)
            console.log('啊呀,出错啦')
          }
      )
      console.log("这到底是是第几变数")

      for(var i=0;i<this.drawscorelist.length;i++){
        console.log(this.drawscorelist[i])
        this.score_y.push(parseInt(this.drawscorelist[i]))
      }
      console.log("ssssssssssss")
      console.log(this.score_y.length)

      let myChart = echarts.init(document.getElementById("myChart123"));
      // 绘制图表
      myChart.setOption({
        xAxis: {
          data: ["[0,60)", "[60,65)", "[65-70)", "[70-75)", "[75-80)", "[80-85)", "[85-90)", "[90,95)","[95-100]"]
        },
        yAxis:{},
        series: [
          {
            name: "成绩统计",
            type: "line",
            data: this.score_y
          }
        ]
      });

    }

  },


}
</script>

由于后端的代码不是整块的,这里就不做展示了

三、效果实现

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单片机C语言程序设计实训100例是一套基于PIC单片机的C语言程序设计课程,通过Proteus仿真软件进行实验验证。这套教材主要包含了100个实例,涵盖了单片机C语言程序的各个方面,旨在让学生能够全面掌握单片机的编程技巧和应用方法。 该实训课程设置了从基础到高级的实例,逐步引导学生从简单的LED亮灭控制、蜂鸣器控制,到进阶的数码管显示、按键输入检测,再到复杂的温湿度传感器应用、红外遥控应用等。每个实例都包括了实验原理、硬件电路连接图和相应的C语言程序代码,通过Proteus仿真软件可以直观地观察实验结果。 通过这套实训教材,学生可以在实践中巩固所学的理论知识,提高单片机C语言编程的能力。同时,通过在Proteus仿真软件中进行实验,学生可以更加直观地观察到实验的过程和结果,培养了解决实际问题的能力。 不仅如此,这套实训教材还鼓励学生进行实验的拓展,要求学生从已有的基础上进行创新和改进。学生可以根据实际需求设计硬件电路和程序代码,达到特定的功能要求。这样的实践培养了学生的问题解决能力和创新思维。 综上所述,单片机C语言程序设计实训100例--基于PIC Proteus仿真是一套全面、系统的实践课程,通过Proteus仿真软件的应用,帮助学生掌握单片机C语言编程的技巧和应用,培养学生的问题解决能力和创新思维。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值