fuliqi
2024-07-04 ff3b5c2ba2a757f050cf833f1af340f384874934
教学资源加班级
9个文件已修改
546 ■■■■■ 已修改文件
src/api/meet.js 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/enumItem.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/education/resource/list.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exam/exam/MarkPaper.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exam/paper/edit.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exam/paper/list.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/meet/index.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/train/data-list/index.vue 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/train/index.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/meet.js
@@ -1,61 +1,68 @@
import axios from "./request";
import axios from './request'
// 获取会议表分页
export const getMeets = (params) => {
    return axios({
        url: "/api/admin/meet/page",
        method: "GET",
        params: params
    })
  return axios({
    url: '/api/admin/meet/page',
    method: 'GET',
    params: params
  })
}
// 获取会议表列表
export const getMeetList = () => {
    return axios({
        url: "/api/admin/meet/list",
        method: "GET"
    })
  return axios({
    url: '/api/admin/meet/list',
    method: 'GET'
  })
}
// 通过id获取会议表
export const getMeetById = (params) => {
    return axios({
        url: "/api/admin/meet/" + params,
        method: "GET"
    })
  return axios({
    url: '/api/admin/meet/' + params,
    method: 'GET'
  })
}
// 通过id删除会议表
export const deleteMeetById = (params) => {
    return axios({
        url: "/api/admin/meet/" + params,
        method: "DELETE"
    })
  return axios({
    url: '/api/admin/meet/' + params,
    method: 'DELETE'
  })
}
// 批量删除会议表
export const deleteMeetByIds = (params) => {
    return axios({
        url: "/api/admin/meet/batch",
        method: "DELETE",
        data: params
    })
  return axios({
    url: '/api/admin/meet/batch',
    method: 'DELETE',
    data: params
  })
}
// 修改会议表
export const editMeet = (params) => {
    return axios({
        url: "/api/admin/meet/",
        method: "PUT",
        data: params
    })
  return axios({
    url: '/api/admin/meet/',
    method: 'PUT',
    data: params
  })
}
// 修改会议表
export const startMeet = (params) => {
  return axios({
    url: '/api/admin/meet/start',
    method: 'PUT',
    data: params
  })
}
// 添加会议表
export const addMeet = (params) => {
    return axios({
        url: "/api/admin/meet/",
        method: "POST",
        data: params
    })
  return axios({
    url: '/api/admin/meet/',
    method: 'POST',
    data: params
  })
}
src/store/modules/enumItem.js
@@ -3,9 +3,12 @@
  user: {
    sexEnum: [{ key: 1, value: '男' }, { key: 2, value: '女' }],
    statusEnum: [{ key: 1, value: '启用' }, { key: 2, value: '禁用' }],
    levelEnum: [{ key: 1, value: '一年级' }, { key: 2, value: '二年级' }, { key: 3, value: '三年级' }, { key: 4, value: '四年级' }, { key: 5, value: '五年级' }, { key: 6, value: '六年级' },
    { key: 7, value: '初一' }, { key: 8, value: '初二' }, { key: 9, value: '初三' },
    { key: 10, value: '高一' }, { key: 11, value: '高二' }, { key: 12, value: '高三' }],
    levelEnum: [{ key: 1, value: '一年级' }, { key: 2, value: '二年级' }, { key: 3, value: '三年级' }, {
      key: 4,
      value: '四年级'
    }, { key: 5, value: '五年级' }, { key: 6, value: '六年级' },
      { key: 7, value: '初一' }, { key: 8, value: '初二' }, { key: 9, value: '初三' },
      { key: 10, value: '高一' }, { key: 11, value: '高二' }, { key: 12, value: '高三' }],
    roleEnum: [{ key: 1, value: '学生' }, { key: 2, value: '教师' }, { key: 3, value: '管理员' }],
    statusTag: [{ key: 1, value: 'success' }, { key: 2, value: 'danger' }],
    statusBtn: [{ key: 1, value: '禁用' }, { key: 2, value: '启用' }]
@@ -15,15 +18,18 @@
      paperTypeEnum: [{ key: 1, value: '固定试卷' }, { key: 2, value: '随机试卷' }, { key: 3, value: '随序试卷' }]
    },
    question: {
      typeEnum: [{ key: 1, value: '单选题' }, { key: 2, value: '多选题' }, { key: 3, value: '判断题' }, { key: 4, value: '填空题' }, { key: 5, value: '简答题' }, { key: 6, value: '语音题' }, { key: 7, value: '计算题' }, { key: 8, value: '分析题' }],
      typeEnum: [{ key: 1, value: '单选题' }, { key: 2, value: '多选题' }, { key: 3, value: '判断题' }, {
        key: 4,
        value: '填空题'
      }, { key: 5, value: '简答题' }, { key: 6, value: '语音题' }, { key: 7, value: '计算题' }, { key: 8, value: '分析题' }],
      editUrlEnum: [{ key: 1, value: '/exam/question/edit/singleChoice', name: '单选题' },
      { key: 2, value: '/exam/question/edit/multipleChoice', name: '多选题' },
      { key: 3, value: '/exam/question/edit/trueFalse', name: '判断题' },
      { key: 4, value: '/exam/question/edit/gapFilling', name: '填空题' },
      { key: 5, value: '/exam/question/edit/shortAnswer', name: '简答题' },
      { key: 6, value: '/exam/question/edit/audio', name: '语音题' },
      { key: 7, value: '/exam/question/edit/calculate', name: '计算题' },
      { key: 8, value: '/exam/question/edit/analysis', name: '分析题' }],
        { key: 2, value: '/exam/question/edit/multipleChoice', name: '多选题' },
        { key: 3, value: '/exam/question/edit/trueFalse', name: '判断题' },
        { key: 4, value: '/exam/question/edit/gapFilling', name: '填空题' },
        { key: 5, value: '/exam/question/edit/shortAnswer', name: '简答题' },
        { key: 6, value: '/exam/question/edit/audio', name: '语音题' },
        { key: 7, value: '/exam/question/edit/calculate', name: '计算题' },
        { key: 8, value: '/exam/question/edit/analysis', name: '分析题' }],
      answer: {
        doRightTag: [{ key: true, value: 'success' }, { key: false, value: 'danger' }, { key: null, value: 'warning' }],
        doRightEnum: [{ key: true, value: '正确' }, { key: false, value: '错误' }, { key: null, value: '待批改' }],
src/views/education/resource/list.vue
@@ -3,7 +3,13 @@
    <div class="search">
      <el-form :inline="true" :model="searchForm" class="demo-form-inline">
        <el-form-item label="主题">
          <el-input v-model="searchForm.introduction" size="small" placeholder="主题内容" clearable @clear="page"></el-input>
          <el-input v-model="searchForm.introduction" size="small" placeholder="主题内容" clearable
                    @clear="page"></el-input>
        </el-form-item>
        <el-form-item label="班级">
          <el-select v-model="searchForm.classId" clearable @clear="page" @change="page" placeholder="班级">
            <el-option v-for="item in classesIds" :key="item.id" :label="item.className" :value="item.id"/>
          </el-select>
        </el-form-item>
        <el-form-item label="科目">
          <el-select v-model="searchForm.subjectId" clearable @clear="page" @change="page" placeholder="科目">
@@ -21,11 +27,12 @@
      </div>
    </div>
    <el-table :data="tableData" border @selection-change="handleSelectionChange" style="width: 100%">
      <el-table-column type="selection" width="55">
      </el-table-column>
      <el-table-column fixed prop="introduction" label="主题简介">
      </el-table-column>
      <el-table-column prop="className" label="班级">
      </el-table-column>
      <el-table-column prop="typeName" label="科目">
      </el-table-column>
@@ -34,26 +41,30 @@
      <el-table-column label="文件内容" width="240">
        <template slot-scope="scope">
          <video controls v-if="scope.row.contentType === 'video'" :src="'/api/files/' + scope.row.contentUrl.url"
                 class="showContent" />
                 class="showContent"/>
          <el-image v-if="scope.row.contentType === 'img'" :src="'/api/files/' + scope.row.contentUrl.url"
                    class="showContent"></el-image>
          <!-- <img v-if="scope.row.contentType === 'img'" :src="'/api/files/' + scope.row.contentUrl.url"
            class="showContent" /> -->
          <el-link type="primary" v-if="scope.row.contentType === 'pdf'" class="showContent"
                   @click="checkPdf('/api/files/' + scope.row.contentUrl.url)">点击查看</el-link>
                   @click="checkPdf('/api/files/' + scope.row.contentUrl.url)">点击查看
          </el-link>
        </template>
      </el-table-column>
      <el-table-column prop="attachment" label="附件">
        <template slot-scope="scope">
          <div v-for="item in scope.row.attachment" :key="item.url">
            <el-link type="primary" :href="'/api/upload/download?url=' + item.url +'&fileName=' + item.name" >{{ item.name }}</el-link>
            <el-link type="primary" :href="'/api/upload/download?url=' + item.url +'&fileName=' + item.name">
              {{ item.name }}
            </el-link>
          </div>
        </template>
      </el-table-column>
      <el-table-column fixed="right" label="操作" width="140">
        <template slot-scope="scope">
          <el-button @click="handleUpdate(scope.row)" type="primary" size="small"
                     style="margin-right: 5px">修改</el-button>
                     style="margin-right: 5px">修改
          </el-button>
          <el-popconfirm :title="getTitle(scope.row.typeName)" @confirm="remove(scope.row.id)">
            <el-button slot="reference" type="danger" size="small">删除</el-button>
          </el-popconfirm>
@@ -62,13 +73,22 @@
    </el-table>
    <pagination v-show="total > 0" :total="total" :page.sync="searchForm.pageNum" :limit.sync="searchForm.pageSize"
                @pagination="page" />
                @pagination="page"/>
    <el-dialog :title="dialogTitle" :visible.sync="open" width="600px" :close-on-click-modal="false"
               :before-close="handleClose">
      <el-form label-position="left" label-width="120px" ref="form" :rules="rules" :model="form">
        <el-form-item label="主题简介" prop="introduction">
          <el-input v-model="form.introduction" placeholder="主题内容"></el-input>
        </el-form-item>
        <el-form-item label="班级" >
          <el-select
            v-model="form.classId"
            placeholder="班级"
            clearable
          >
            <el-option v-for="item in classesIds" :key="item.id" :label="item.className" :value="item.id"/>
          </el-select>
        </el-form-item>
        <el-form-item label="科目" prop="subjectId">
          <el-select v-model="form.subjectId" placeholder="科目">
@@ -85,11 +105,11 @@
        </el-form-item>
        <el-form-item label="上传文件(一个)" prop="contentUrl">
          <upload v-show="form.contentType" ref="upload" :fileUrl="form.contentUrl" :fileType="form.contentType"
                  :fileSizeLimitM="1024" :uploadNum="1" @getUploadUrl="getUploadUrl" @removeFile="removeFile" />
                  :fileSizeLimitM="1024" :uploadNum="1" @getUploadUrl="getUploadUrl" @removeFile="removeFile"/>
        </el-form-item>
        <el-form-item label="附件(最多3个)" prop="attachment">
          <upload :fileSizeLimitM="1024" :uploadNum="3" :fileUrl="form.attachment"
                  @getUploadUrl="getUploadAttachmentUrl" @removeFile="removeAttachmentFile" />
                  @getUploadUrl="getUploadAttachmentUrl" @removeFile="removeAttachmentFile"/>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
@@ -105,26 +125,29 @@
</template>
<script>
import Pagination from '@/components/Pagination';
import EducationResourceAPI from '@/api/educationResource';
import SubjectAPI from '@/api/subject';
import Upload from '@/components/UploadC';
import Pagination from '@/components/Pagination'
import EducationResourceAPI from '@/api/educationResource'
import SubjectAPI from '@/api/subject'
import Upload from '@/components/UploadC'
import { myClasses } from '@/api/classes'
import VueOfficePdf from '@vue-office/pdf';
import VueOfficePdf from '@vue-office/pdf'
export default {
  name: 'type',
  components: { Upload, Pagination, VueOfficePdf },
  computed: {
    fileContentUrl: () => {
      return this.form ? this.form.contentUrl ? [this.form.contentUrl] : [] : [];
      return this.form ? this.form.contentUrl ? [this.form.contentUrl] : [] : []
    }
  },
  data() {
  data () {
    return {
      pdf: '',
      dialogTitle: '添加学习内容',
      ids: [],
      typeList: [],
      classesIds: [],
      searchForm: {
        pageNum: 1,
        pageSize: 5,
@@ -139,6 +162,7 @@
        contentType: 'video',
        introduction: '',
        belongType: 2,
        classId: null,
        contentUrl: [],
        attachment: [],
        temp: []
@@ -157,101 +181,107 @@
          { required: true, message: '请选择文件类型', trigger: 'change' }
        ]
      }
    };
    }
  },
  methods: {
    checkPdf(url) {
      this.pdf = url;
      this.pdfDialog = true;
    // 获取我的班级
    getClasses () {
      myClasses().then(re => {
        this.classesIds = re.data.data
      })
    },
    closePdfDialog() {
      this.pdfDialog = false;
    checkPdf (url) {
      this.pdf = url
      this.pdfDialog = true
    },
    rendered() {
    closePdfDialog () {
      this.pdfDialog = false
    },
    rendered () {
    },
    fileChange() {
      this.form.contentUrl = [];
    fileChange () {
      this.form.contentUrl = []
    },
    handleSelectionChange(val) {
      this.ids = val.map(item => item.id);
    handleSelectionChange (val) {
      this.ids = val.map(item => item.id)
    },
    typeFormatter(row) {
    typeFormatter (row) {
      if (row.contentType === 'video') {
        return "视频";
        return '视频'
      }
      if (row.contentType === 'img') {
        return "图片";
        return '图片'
      }
      if (row.contentType === 'pdf') {
        return "PDF";
        return 'PDF'
      }
    },
    clearFile() {
      this.form.contentUrl = [];
      this.$refs.upload.clearFile();
    clearFile () {
      this.form.contentUrl = []
      this.$refs.upload.clearFile()
    },
    removeFile() {
      this.form.contentUrl = [];
    removeFile () {
      this.form.contentUrl = []
    },
    removeAttachmentFile (fileList, fileName) {
      this.form.attachment = fileList.filter(item => item.name !== fileName);
      this.form.attachment = fileList.filter(item => item.name !== fileName)
    },
    getUploadAttachmentUrl (uploadData) {
      this.form.attachment = uploadData;
      this.form.attachment = uploadData
    },
    getUploadUrl (uploadData) {
      this.form.contentUrl = uploadData;
      this.form.contentUrl = uploadData
    },
    remove (id) {
      EducationResourceAPI.remove([id]).then(res => {
        if (res.code === 1) {
          this.$message.success('删除成功');
          this.$message.success('删除成功')
          this.page()
        }
      });
      })
    },
    batchRemove() {
    batchRemove () {
      if (this.ids.length < 1) {
        this.$message.warning("请选择要删除的数据");
        this.$message.warning('请选择要删除的数据')
      }
      EducationResourceAPI.remove(this.ids).then(res => {
        if (res.code === 1) {
          this.$message.success('删除成功');
          this.ids = [];
          this.$message.success('删除成功')
          this.ids = []
        }
      });
      })
    },
    getTitle (typeName) {
      return '确定要删除' + typeName + '这个文件吗?';
      return '确定要删除' + typeName + '这个文件吗?'
    },
    handlerSubmit () {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          const temp = JSON.parse(JSON.stringify(this.form));
          const temp = JSON.parse(JSON.stringify(this.form))
          // this.form.contentUrl = this.form.contentUrl[0]
          temp.contentUrl = temp.contentUrl[0];
          temp.contentUrl = temp.contentUrl[0]
          if (temp.id) {
            EducationResourceAPI.update(temp).then(res => {
              if (res.code === 1) {
                this.$message.success('修改成功');
                this.open = false;
                this.page();
                this.$message.success('修改成功')
                this.open = false
                this.page()
              }
            });
            })
          } else {
            EducationResourceAPI.add(temp).then(res => {
              if (res.code === 1) {
                this.$message.success('添加成功');
                this.open = false;
                this.page();
                this.$message.success('添加成功')
                this.open = false
                this.page()
              }
            });
            })
          }
        }
      });
      })
    },
    resetForm() {
    resetForm () {
      this.form = {
        contentType: 'video',
        introduction: '',
@@ -259,45 +289,48 @@
        contentUrl: [],
        attachment: [],
        temp: []
      };
      }
    },
    handleClose() {
      this.open = false;
      this.resetForm();
    handleClose () {
      this.open = false
      this.resetForm()
    },
    handlerAdd() {
      this.resetForm();
      this.open = true;
      this.dialogTitle = '添加学习内容';
    handlerAdd () {
      this.resetForm()
      this.open = true
      this.dialogTitle = '添加学习内容'
    },
    page() {
    page () {
      EducationResourceAPI.page(this.searchForm).then(res => {
        if (res.code === 1) {
          this.tableData = res.data;
          this.total = res.total;
          this.tableData = res.data
          this.total = res.total
        }
      });
      })
    },
    handleUpdate(row) {
      this.form.id = row.id;
      this.form.contentType = row.contentType;
      this.form.contentUrl = [row.contentUrl] || [];
      this.form.attachment = row.attachment || [];
      this.form.introduction = row.introduction;
      this.form.belongType = row.belongType;
      this.dialogTitle = '修改学习内容';
      this.open = true;
    handleUpdate (row) {
      this.form.id = row.id
      this.form.contentType = row.contentType
      this.form.classesId = row.classesId
      this.form.subjectId = row.subjectId
      this.form.contentUrl = [row.contentUrl] || []
      this.form.attachment = row.attachment || []
      this.form.introduction = row.introduction
      this.form.belongType = row.belongType
      this.dialogTitle = '修改学习内容'
      this.open = true
    }
  },
  mounted() {
    this.page();
  mounted () {
    this.page()
    this.getClasses()
    SubjectAPI.list().then(res => {
      if (res.code === 1) {
        this.typeList = res.data;
        this.typeList = res.data
      }
    });
    })
  }
};
}
</script>
<style scoped>
@@ -314,6 +347,7 @@
.search {
  margin-top: 10px;
}
::v-deep .el-image__error {
  position: absolute;
  top: 0;
src/views/exam/exam/MarkPaper.vue
@@ -71,12 +71,6 @@
      >
      </el-table-column>
      <el-table-column
        align="center"
        prop="phone"
        label="系统自动估分(选择题型)"
      >
      </el-table-column>
      <el-table-column
        label="操作"
        align="center"
        width="300px"
src/views/exam/paper/edit.vue
@@ -1,11 +1,6 @@
<template>
  <div class="app-container">
    <el-form :model="form" ref="form" label-width="150px" v-loading="formLoading" :rules="rules">
      <el-form-item label="学科:" prop="subjectId" required>
        <el-select v-model="form.subjectId" placeholder="学科">
          <el-option v-for="item in subjects" :key="item.id" :label="item.name" :value="item.id"/>
        </el-select>
      </el-form-item>
      <el-form-item label="试卷类型:" prop="paperType" required>
        <el-select v-model="form.paperType" placeholder="试卷类型">
          <el-option v-for="item in paperTypeEnum" :key="item.key" :value="item.key" :label="item.value"></el-option>
@@ -77,14 +72,15 @@
      </el-form-item>
      <!-- 题目配置信息 随机试卷或新建随序才显示 -->
      <el-form-item v-show="form.paperType ===2 || (form.paperType ===3 && !form.id)" :key="index"
                    :label="translateQuestionType(item.questionType)+':'" v-for="(item,index) in form.questionSetting">
                    :label="translateQuestionType(item.questionType)+':'" v-for="(item,index) in form.questionSetting"
      >
        <div>
          <span style="margin-right: 10px">{{ '标题' }}</span>
          <el-input v-model="item.title" style="margin-bottom: 20px;margin-right: 30px;width: 800px"/>
          <el-button type="primary" @click=addToQuestionSetting(item.questionType) >添加</el-button>
          <el-button type="primary" @click=addToQuestionSetting(item.questionType)>添加</el-button>
          <div style="display: flex;" :key="index" v-for="(setting,index) in item.settingList">
            <span style="margin-right: 10px;margin-bottom: 10px;">{{ '难度' }}</span>
          <div style="display: flex;margin-bottom: 10px;" :key="index" v-for="(setting,index) in item.settingList">
            <span style="margin-right: 10px;">{{ '难度' }}</span>
            <el-rate v-model="setting.difficult" :precision="0" :min="0" style="margin-right: 25px;padding: 5px 0"/>
            <span style="margin-right: 10px">{{ '科目' }}</span>
            <el-select v-model="setting.subjectId" placeholder="学科" style="margin-right: 25px">
@@ -93,7 +89,9 @@
            <span style="margin-right: 10px">{{ '数量' }}</span>
            <el-input-number v-model="setting.num" :precision="0" :min="0" style="margin-right: 25px"/>
            <span style="margin-right: 10px">{{ '每题分数' }}</span>
            <el-input-number v-model="setting.score" :min="0" :precision="1"/>
            <el-input-number v-model="setting.score" :min="0" :precision="1" style="margin-right: 25px"/>
            <el-button type="danger" icon="el-icon-delete" circle
                       @click="removeQuestionSetting(item,index)"></el-button>
          </div>
        </div>
@@ -129,6 +127,11 @@
      <el-form :model="questionPage.queryParam" ref="queryForm" :inline="true">
        <el-form-item label="ID:">
          <el-input v-model="questionPage.queryParam.id" clearable></el-input>
        </el-form-item>
        <el-form-item label="学科:">
          <el-select v-model="questionPage.queryParam.subjectIdInt" placeholder="学科">
            <el-option v-for="item in subjects" :key="item.id" :label="item.name" :value="item.id"/>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="queryForm">查询</el-button>
@@ -171,7 +174,6 @@
    return {
      form: {
        id: null,
        subjectId: null,
        paperType: 1,
        name: '',
        num: 0,
@@ -243,12 +245,6 @@
      subjects: [],
      formLoading: false,
      rules: {
        level: [
          { required: true, message: '请选择年级', trigger: 'change' }
        ],
        subjectId: [
          { required: true, message: '请选择学科', trigger: 'change' }
        ],
        paperType: [
          { required: true, message: '请选择试卷类型', trigger: 'change' }
        ],
@@ -264,6 +260,7 @@
        showDialog: false,
        queryParam: {
          id: null,
          subjectIdInt: null,
          questionType: [],
          subjectId: [],
          pageIndex: 1,
@@ -386,6 +383,13 @@
    addQuestion (titleItem) {
      this.currentTitleItem = titleItem
      this.questionPage.queryParam.questionType = []
      if (!titleItem.questionType) {
        this.$message({
          message: '请先选择题型',
          type: 'warning'
        })
        return
      }
      this.questionPage.queryParam.questionType.push(titleItem.questionType)
      this.questionPage.showDialog = true
      this.search()
@@ -405,8 +409,12 @@
      this.updateTotalScore()
      this.form.num = this.form.num - 1
    },
    removeQuestionSetting (item, index) {
      item.settingList.splice(index, 1)
    },
    queryForm () {
      this.questionPage.queryParam.pageIndex = 1
      this.questionPage.queryParam.subjectId = [this.questionPage.queryParam.subjectIdInt]
      this.search()
    },
    confirmQuestionSelect () {
@@ -420,8 +428,6 @@
      this.questionPage.showDialog = false
    },
    search () {
      this.questionPage.queryParam.subjectId = []
      this.questionPage.queryParam.subjectId.push(this.form.subjectId)
      this.questionPage.listLoading = true
      questionApi.pageList(this.questionPage.queryParam).then(data => {
        const re = data.data
@@ -448,14 +454,46 @@
        deductTypeScore: 0,
        visibility: '1',
        questionSetting: [
          { questionType: 1, title: '单选题', score: null, num: null },
          { questionType: 2, title: '多选题', score: null, num: null },
          { questionType: 3, title: '判断题', score: null, num: null },
          { questionType: 4, title: '填空题', score: null, num: null },
          { questionType: 5, title: '简答题', score: null, num: null },
          { questionType: 6, title: '语音题', score: null, num: null },
          { questionType: 7, title: '计算题', score: null, num: null },
          { questionType: 8, title: '分析题', score: null, num: null },
          {
            title: '单选题',
            questionType: 1,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          },
          {
            title: '多选题',
            questionType: 2,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          },
          {
            title: '判断题',
            questionType: 3,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          },
          {
            title: '填空题',
            questionType: 4,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          },
          {
            title: '简答题',
            questionType: 5,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          },
          {
            title: '语音题',
            questionType: 6,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          },
          {
            title: '计算题',
            questionType: 7,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          },
          {
            title: '分析题',
            questionType: 8,
            settingList: [{ difficult: null, score: null, num: null, subjectId: null }]
          }
        ],
        questionTitleList: []
      }
@@ -470,8 +508,10 @@
    totalNum () {
      if (this.form.paperType === 2 || this.form.paperType === 3) {
        let total = 0
        for (let item of this.form.questionSetting) {
          total += parseInt(item.num || 0, 10)
        for (let settings of this.form.questionSetting) {
          for (let item of settings.settingList) {
            total += parseInt(item.num || 0, 10)
          }
        }
        this.form.num = total
        return total
@@ -482,10 +522,12 @@
    totalScore () {
      if (this.form.paperType === 2 || this.form.paperType === 3) {
        let total = 0
        for (let item of this.form.questionSetting) {
          const num = parseInt(item.num || 0, 10)
          const score = parseFloat(item.score || 0)
          total += num * score
        for (let settings of this.form.questionSetting) {
          for (let item of settings.settingList) {
            const num = parseInt(item.num || 0, 10)
            const score = parseFloat(item.score || 0)
            total += num * score
          }
        }
        this.form.score = total.toFixed(1)
        return total.toFixed(1) // 保留一位小数
src/views/exam/paper/list.vue
@@ -7,7 +7,7 @@
      <el-form-item>
        <el-button type="primary" @click="submitForm">查询</el-button>
        <router-link :to="{path:'/exam/paper/edit'}" class="link-left">
          <el-button type="primary">添加</el-button>
          <el-button type="primary" >添加</el-button>
        </router-link>
      </el-form-item>
    </el-form>
src/views/meet/index.vue
@@ -1,17 +1,23 @@
<template>
  <div id="meet" ref="meet" />
  <div id="meet" ref="meet">
    <div>
      <span>
        {{ '156165165' }}
      </span>
    </div>
  </div>
</template>
<script>
let jitsiApi = null;
let jitsiApi = null
export default {
  mounted() {
    const width = window.innerWidth;
    const height = window.innerHeight;
    const domain = this.$route.query.domain;
    const roomName = this.$route.query.roomName;
    const userInfoStr = this.$route.query.userInfoStr;
    const userInfo = userInfoStr ? JSON.parse(userInfoStr) : null;
  mounted () {
    const width = window.innerWidth
    const height = window.innerHeight
    const domain = this.$route.query.domain
    const roomName = this.$route.query.roomName
    const userInfoStr = this.$route.query.userInfoStr
    const userInfo = userInfoStr ? JSON.parse(userInfoStr) : null
    const options = {
      roomName: roomName,
      width: width,
@@ -28,12 +34,12 @@
        }
      },
      toolbarButtons: ['whiteboard']
    };
    jitsiApi = new window.JitsiMeetExternalAPI(domain, options);
    }
    jitsiApi = new window.JitsiMeetExternalAPI(domain, options)
    jitsiApi.addListener('readyToClose', () => {
      window.close();
    });
      window.close()
    })
  }
}
src/views/train/data-list/index.vue
@@ -14,6 +14,10 @@
                <div class="info-text">{{ item.teacherName }}</div>
              </div>
              <div class="info-time">
                <div class="info-label">状态:</div>
                <div class="info-text">{{ translateStatus(item.status) }}</div>
              </div>
              <div class="info-time">
                <div class="info-label">开始时间:</div>
                <div class="info-text">{{ item.startTime }}</div>
              </div>
@@ -22,7 +26,7 @@
                <div class="info-text">{{ item.endTime }}</div>
              </div>
              <div class="button-container">
                <el-button @click="start(item)">开始上课</el-button>
                <el-button v-if="item.status!==2" @click="start(item)">开始上课</el-button>
                <el-button @click="handleUpdate(item)">编辑</el-button>
                <el-button @click="remove(item)">删除</el-button>
              </div>
@@ -42,16 +46,25 @@
  },
  methods: {
    handleUpdate (item) {
      this.$emit('handleUpdate',item)
      this.$emit('handleUpdate', item)
    },
    remove (item) {
      this.$emit('remove',item)
      this.$emit('remove', item)
    },
    start (item) {
      this.$emit('start',item)
      this.$emit('start', item)
    },
    translateStatus (status) {
      if (status === 0) {
        return '待开始'
      } else if (status === 1) {
        return '进行中'
      } else {
        return '已结束'
      }
    }
  }
};
}
</script>
<style lang="scss" scoped>
src/views/train/index.vue
@@ -9,15 +9,16 @@
              <div class="card-header">
                <div class="header-tab">
                  <el-tabs v-model="activeName" @tab-click="handleClick">
                    <el-tab-pane label="全部" name="1"></el-tab-pane>
                    <el-tab-pane label="未开始" name="2"></el-tab-pane>
                    <el-tab-pane label="进行中" name="3"></el-tab-pane>
                    <el-tab-pane label="已结束" name="4"></el-tab-pane>
                    <el-tab-pane label="全部" name="all"></el-tab-pane>
                    <el-tab-pane label="未开始" name="0"></el-tab-pane>
                    <el-tab-pane label="进行中" name="1"></el-tab-pane>
                    <el-tab-pane label="已结束" name="2"></el-tab-pane>
                  </el-tabs>
                </div>
                <div class="header-search">
                  <el-input v-model="queryParam.meetName" @input="getList" clearable @clear="getList" placeholder="请输入课程名称"/>
                  <el-button type="primary" class="ml-4" @click="getList" >搜索</el-button>
                  <el-input v-model="queryParam.meetName" @input="getList" clearable @clear="getList"
                            placeholder="请输入课程名称"/>
                  <el-button type="primary" class="ml-4" @click="getList">搜索</el-button>
                </div>
                <div>
                  <el-button type="primary" @click="handleAdd()">添加</el-button>
@@ -26,23 +27,25 @@
              <div class="card-main flex-1 my-5 relative">
                <div class="main-content absolute top-0 bottom-0 left-0 right-0">
                  <DataList :tableData="tableData" @handleUpdate="handleUpdate" @remove = "remove" @start = "start"></DataList>
                  <DataList :tableData="tableData" @handleUpdate="handleUpdate" @remove="remove"
                            @start="start"></DataList>
                  <div id="meet" ref="meet"></div>
                </div>
              </div>
              <pagination v-show="total>0" :total="total" :page.sync="queryParam.pageIndex" :limit.sync="queryParam.pageSize"
              <pagination v-show="total>0" :total="total" :page.sync="queryParam.pageIndex"
                          :limit.sync="queryParam.pageSize"
                          @pagination="getList"/>
            </div>
          </el-card>
          <!-- 添加会议对话框 -->
          <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
            <el-form label-width="80px" ref="form" :model="form" :rules="rules" >
              <el-form-item label="房间名" prop="meetName" >
            <el-form label-width="80px" ref="form" :model="form" :rules="rules">
              <el-form-item label="房间名" prop="meetName">
                <el-input v-model="form.meetName" placeholder="请输入房间名" style="width: 300px"></el-input>
              </el-form-item>
              <el-form-item label="班级" >
              <el-form-item label="班级">
                <el-select
                  v-model="form.classesId"
                  placeholder="班级"
@@ -51,18 +54,18 @@
                  <el-option v-for="item in classesIds" :key="item.id" :label="item.className" :value="item.id"/>
                </el-select>
              </el-form-item>
              <el-form-item label="上课时间" prop="time" >
                  <el-date-picker
                    v-model="form.time"
                    type="datetimerange"
                    format="yyyy-MM-dd HH:mm:ss"
                    value-format="yyyy-MM-dd HH:mm:ss"
                    range-separator="至"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期">
                  </el-date-picker>
              <el-form-item label="上课时间" prop="time">
                <el-date-picker
                  v-model="form.time"
                  type="datetimerange"
                  format="yyyy-MM-dd HH:mm:ss"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期">
                </el-date-picker>
              </el-form-item>
              <el-form-item label="状态" >
              <el-form-item label="状态">
                <el-radio v-model="form.status" :label="0">待开始</el-radio>
                <el-radio v-model="form.status" :label="1">进行中</el-radio>
                <el-radio v-model="form.status" :label="2">已结束</el-radio>
@@ -83,11 +86,11 @@
<script>
import DataList from './data-list/index.vue'
import Pagination from '@/components/Pagination'
import { getMeets,addMeet,editMeet,deleteMeetById } from '@/api/meet'
import { getMeets, addMeet, editMeet, deleteMeetById, startMeet } from '@/api/meet'
import { myClasses } from '@/api/classes'
export default {
  components: { DataList,Pagination},
  components: { DataList, Pagination },
  data () {
    return {
      queryParam: {
@@ -103,7 +106,7 @@
      form: {},
      tableData: [],
      classesIds: [],
      activeName: '1',
      activeName: 'all',
      searchText: '',
      rules: {
        meetName: [
@@ -124,6 +127,12 @@
  },
  methods: {
    handleClick () {
      if (this.activeName !== 'all') {
        this.queryParam.status = this.activeName
      } else {
        this.queryParam.status = null
      }
      this.getList()
    },
    remove (item) {
      deleteMeetById(item.id).then(re => {
@@ -139,15 +148,15 @@
    start (item) {
      // 修改房间状态为进行中
      item.status = 1
      editMeet(item).then(re => {
      startMeet(item).then(re => {
        if (re.data.code === 1) {
          this.getList()
          let routeUrl = this.$router.resolve({
            path: "/meet",
            path: '/meet',
            query: {
              domain: 'ycl.easyblog.vip:8443/' + item.id,
              roomName: item.meetName,
              userInfoStr:  JSON.stringify({
              userInfoStr: JSON.stringify({
                displayName: item.teacherName
              })
            }
@@ -240,6 +249,7 @@
:deep(.el-tabs__nav-wrap:after) {
  display: none;
}
.train-container {
  width: 100%;
  height: 100%;
@@ -253,12 +263,14 @@
    width: 100%;
  }
}
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}
.header-search {
  display: flex;
  align-items: center;