From 04eac394df26d483765ce9d51bf69282e0cc7272 Mon Sep 17 00:00:00 2001
From: zhouwx <1175765986@qq.com>
Date: 星期三, 10 七月 2024 17:32:02 +0800
Subject: [PATCH] 提交

---
 src/views/onlineEducation/classHourBatch/components/chooseStudent.vue                         |  187 ++++++
 src/api/onlineEducation/courseManage.js                                                       |    9 
 src/views/onlineEducation/courseManage/components/courseManageDialog.vue                      |   12 
 src/api/onlineEducation/batch.js                                                              |   93 +++
 src/views/onlineEducation/systemManage/company/index.vue                                      |   15 
 src/router/index.js                                                                           |   14 
 src/views/onlineEducation/classHourBatch/components/batchDialog.vue                           |  290 +++++++++
 src/views/onlineEducation/groupExams/components/examDialog.vue                                |  400 +++++++++++++
 src/views/onlineEducation/classHourBatch/index.vue                                            |  153 ++++
 src/views/onlineEducation/classHourBatch/components/handleStudent.vue                         |  168 +++++
 src/views/onlineEducation/systemManage/company/components/companyDialog.vue                   |   20 
 src/views/onlineEducation/groupExams/index.vue                                                |  139 ++++
 src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue |   55 +
 src/api/onlineEducation/exam.js                                                               |   93 +++
 src/views/onlineEducation/classHourBatch/components/classHourChange.vue                       |  103 +++
 15 files changed, 1,721 insertions(+), 30 deletions(-)

diff --git a/src/api/onlineEducation/batch.js b/src/api/onlineEducation/batch.js
new file mode 100644
index 0000000..e2a0fa5
--- /dev/null
+++ b/src/api/onlineEducation/batch.js
@@ -0,0 +1,93 @@
+import request from '@/utils/request'
+
+export function getBatch(param) {
+    return request({
+        url: '/course-phase/list',
+        method: 'get',
+        params: param
+    })
+}
+
+export function addBatch(data) {
+    return request({
+        url: '/course-phase',
+        method: 'post',
+        data: data
+    })
+}
+
+
+export function editBatch(params) {
+    return request({
+        url: `/course-phase`,
+        method: 'put',
+        data: params
+    })
+}
+
+
+export function delBatch(userId) {
+    return request({
+        url: '/course-phase/' + userId,
+        method: 'delete'
+    })
+}
+
+export function checkBatchName(data) {
+    return request({
+        url: '/course-phase/checkNameUnique',
+        method: 'post',
+        data: data
+    })
+}
+
+//批次与学员关系
+  //批次下的学员列表(分页)
+export function getBatchStudent(param) {
+    return request({
+        url: '/phase-student/list',
+        method: 'get',
+        params: param
+    })
+}
+  // 校验学员是否已存在
+export function checkStudentUnique(data) {
+    return request({
+        url: '/phase-student/checkStudentUnique',
+        method: 'post',
+        data: data
+    })
+}
+// 批量新增学员
+export function batchAddStudent(data) {
+    return request({
+        url: '/phase-student/batchAdd',
+        method: 'post',
+        data: data
+    })
+}
+// 批量删除学员
+export function batchDelStudent(data) {
+    return request({
+        url: '/phase-student/batchDelete',
+        method: 'delete',
+        data: data
+    })
+}
+
+// 批量删除学员
+export function delBatchStu(userId) {
+    return request({
+        url: '/phase-student/' + userId,
+        method: 'delete'
+    })
+}
+
+//企业课时变更记录列表(分页)
+export function getCompanyPeriod(param) {
+    return request({
+        url: '/company-period/list',
+        method: 'get',
+        params: param
+    })
+}
diff --git a/src/api/onlineEducation/courseManage.js b/src/api/onlineEducation/courseManage.js
index 0024c74..bfa8431 100644
--- a/src/api/onlineEducation/courseManage.js
+++ b/src/api/onlineEducation/courseManage.js
@@ -16,6 +16,15 @@
     })
 }
 
+export function getApproveCourse(params) {
+    return request({
+        url: '/course/approvelist',
+        method: 'get',
+        params: params
+    })
+}
+
+
 export function addCourse(data) {
     return request({
         url: '/course',
diff --git a/src/api/onlineEducation/exam.js b/src/api/onlineEducation/exam.js
new file mode 100644
index 0000000..3292d01
--- /dev/null
+++ b/src/api/onlineEducation/exam.js
@@ -0,0 +1,93 @@
+import request from '@/utils/request'
+
+export function getExam(param) {
+    return request({
+        url: '/exam-paper/list',
+        method: 'get',
+        params: param
+    })
+}
+
+export function addExam(data) {
+    return request({
+        url: '/exam-paper',
+        method: 'post',
+        data: data
+    })
+}
+
+
+export function editExam(params) {
+    return request({
+        url: `/exam-paper`,
+        method: 'put',
+        data: params
+    })
+}
+
+
+export function delExam(userId) {
+    return request({
+        url: '/exam-paper/' + userId,
+        method: 'delete'
+    })
+}
+
+export function checkExamName(data) {
+    return request({
+        url: '/exam-paper/checkNameUnique',
+        method: 'post',
+        data: data
+    })
+}
+
+//批次与学员关系
+//批次下的学员列表(分页)
+// export function getBatchStudent(param) {
+//     return request({
+//         url: '/phase-student/list',
+//         method: 'get',
+//         params: param
+//     })
+// }
+// // 校验学员是否已存在
+// export function checkStudentUnique(data) {
+//     return request({
+//         url: '/phase-student/checkStudentUnique',
+//         method: 'post',
+//         data: data
+//     })
+// }
+// // 批量新增学员
+// export function batchAddStudent(data) {
+//     return request({
+//         url: '/phase-student/batchAdd',
+//         method: 'post',
+//         data: data
+//     })
+// }
+// // 批量删除学员
+// export function batchDelStudent(data) {
+//     return request({
+//         url: '/phase-student/batchDelete',
+//         method: 'delete',
+//         data: data
+//     })
+// }
+//
+// // 批量删除学员
+// export function delBatchStu(userId) {
+//     return request({
+//         url: '/phase-student/' + userId,
+//         method: 'delete'
+//     })
+// }
+//
+// //企业课时变更记录列表(分页)
+// export function getCompanyPeriod(param) {
+//     return request({
+//         url: '/company-period/list',
+//         method: 'get',
+//         params: param
+//     })
+// }
diff --git a/src/router/index.js b/src/router/index.js
index dd3cb3e..b5e29b4 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -62,6 +62,20 @@
         path: '/chapters',
         component: () => import('@/views/onlineEducation/courseManage/courseChapters/index.vue'),
         name: 'Chapters',
+        meta: { title: '章节',icon: 'form',  affix: true }
+      }
+    ]
+  },
+  {
+    path: '/chooseStu',
+    component: Layout,
+    redirect: '/chooseStu',
+    children: [
+      {
+        path: '/chooseStu',
+        component: () => import('@/views/onlineEducation/classHourBatch/components/handleStudent.vue'),
+        name: 'ChooseStu',
+        meta: { title: '批次学员',icon: 'form',  affix: true }
       }
     ]
   },
diff --git a/src/views/onlineEducation/classHourBatch/components/batchDialog.vue b/src/views/onlineEducation/classHourBatch/components/batchDialog.vue
new file mode 100644
index 0000000..1ae956a
--- /dev/null
+++ b/src/views/onlineEducation/classHourBatch/components/batchDialog.vue
@@ -0,0 +1,290 @@
+<template>
+  <div class="notice">
+    <el-dialog
+        v-model="dialogVisible"
+        :title="title"
+        width="500px"
+        :before-close="handleClose"
+    >
+      <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" >
+        <el-form-item label="所属公司:" prop="companyName" v-if="!state.isAdmin">
+          <el-input v-model.trim="state.form.companyName" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="批次名称:" prop="name">
+          <el-input v-model.trim="state.form.name" placeholder="请输入批次名称"></el-input>
+        </el-form-item>
+        <el-form-item label="培训级别:" prop="level" >
+          <el-select v-model="state.form.level" placeholder="请选择培训级别" style="width: 100%">
+            <el-option
+                v-for="item in state.levelList"
+                :key="item.id"
+                :label="item.name"
+                style="width: 100%"
+                :value="item.id">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="归属课程:" prop="courseName">
+          <el-select
+              v-model="state.form.courseName"
+              style="width: 100%"
+              v-loadMoreNew:[reselect]="handleScroll"
+              :popper-class="reselect.name"
+              @change="selectValue"
+              class="item-width"
+              placeholder="请选择题库"
+          >
+            <el-option
+                v-for="item in state.courseList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.name"
+            />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+            <el-button @click="handleClose" size="default">取 消</el-button>
+            <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs} from 'vue'
+import {ElMessage} from "element-plus";
+
+import {
+  getClassification
+} from "@/api/onlineEducation/courseClass";
+import {
+  addCourse,
+  checkCourseName,
+  editCourse,
+  getApproveCourse,
+  getCourse,
+  getCourseById
+} from "@/api/onlineEducation/courseManage";
+import {getToken} from "@/utils/auth";
+import {delPic, getBannerById} from "@/api/onlineEducation/banner";
+import Cookies from "js-cookie";
+import {
+  addQuestionBank,
+  checkQuestionBankName,
+  editQuestionBank,
+  getQuestionBank
+} from "@/api/onlineEducation/questionBank";
+import {addBatch, checkBatchName, editBatch} from "@/api/onlineEducation/batch";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const emit = defineEmits(["getList"]);
+const startUsername = ref('');
+const classifyRef = ref(null)
+const reselect = reactive({
+  name: 'course1'
+})
+const validateName = (rule, value, callback)=>{
+  if(value === ''){
+    callback(new Error('请输入批次名称'))
+  }else if(title.value === '编辑' && value === startUsername.value){
+    callback()
+  }else{
+    let param = {}
+    if(title.value === '新增') {
+      param = {
+        name:value
+      }
+    }else if(title.value === '编辑'){
+      param = {
+        name:value,
+        id: state.form.id
+      }
+    }
+    checkBatchName(param).then((res)=>{
+      if(res.data == false){
+        callback(new Error('批次名称已被占用,请更换其他名称'))
+      }else{
+        callback()
+      }
+    })
+  }
+}
+const state = reactive({
+  form: {
+    id: '',
+    name: '',
+    courseId: null,
+    companyName: '',
+    courseName: '',
+    companyId: null,
+    level: null
+  },
+  formRules: {
+    companyName:[{required: true,message: '', trigger: 'blur'}],
+    name: [{required: true, trigger: "blur", validator: validateName}],
+    courseName: [{required: true, message: '请选择课程', trigger: 'blur'}],
+    level: [{required: true, message: '请选择培训级别', trigger: 'blur'}],
+  },
+  classifyList: [],
+  isAdmin: false,
+  levelList: [
+    {
+      id: 1,
+      name: '公司级 '
+    },
+    {
+      id: 2,
+      name: '部门级'
+    },
+    {
+      id: 3,
+      name: '车间级'
+    },
+    {
+      id: 4,
+      name: '其他'
+    },
+  ],
+  courseList: [],
+  courseNum: 1,
+  courseSize: 10,
+  hasMoreItems: null, // 是否还有更多选项
+
+})
+
+const openDialog = async (type, value) => {
+  await loadMoreCourseData();
+  const userInfo = JSON.parse(Cookies.get('userInfo'))
+  console.log("userInfo",userInfo)
+  if(userInfo.userType === 0){
+    state.isAdmin = true;
+    state.form.companyName = ''
+    state.form.companyId = null
+  }else {
+    state.isAdmin = false;
+    state.form.companyName = userInfo.companyName
+    state.form.companyId = userInfo.companyId
+  }
+  title.value = type === 'addFirst' || type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ;
+  if(type === 'edit') {
+    startUsername.value = value.name;
+    state.form = value;
+  }
+  dialogVisible.value = true;
+}
+const handleScroll = () => {
+  if(state.courseNum >= state.hasMoreItems) return
+  state.courseNum++;
+  loadMoreCourseData()
+}
+
+const selectValue = (val) => {
+  state.courseList.forEach(item => {
+    if(item.name === val){
+      state.form.courseId = item.id
+    }
+  })
+}
+const loadMoreCourseData = async () => {
+  const queryParams = {
+    pageNum: state.courseNum,
+    pageSize: state.courseSize,
+  }
+  const res = await getApproveCourse(queryParams)
+  if (res.code == 200) {
+    state.hasMoreItems = res.data.totalPage
+    const data = res.data.list.filter(item => item.status == 0)
+    state.courseList = state.courseList.concat(data)
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+
+const onSubmit = async () => {
+  if(state.isAdmin){
+    ElMessage({
+      type: 'warning',
+      message: '管理员暂无权限'
+    });
+    return;
+  }
+  const valid = await busRef.value.validate();
+  if(valid){
+    if(title.value === '新增'){
+      const {id,courseName,companyName, ...data} = JSON.parse(JSON.stringify(state.form))
+      const res = await addBatch(data)
+      if(res.code === 200){
+        ElMessage({
+          type: 'success',
+          message: '新增成功'
+        });
+      }else{
+        ElMessage.warning(res.message)
+      }
+      emit("getList")
+      busRef.value.clearValidate();
+      reset();
+      dialogVisible.value = false;
+    }else if(title.value === '编辑'){
+      const {courseName,companyName,...data} = JSON.parse(JSON.stringify(state.form))
+      const res = await editBatch(data)
+      if(res.code === 200){
+        ElMessage({
+          type: 'success',
+          message: '编辑成功'
+        });
+      }else{
+        ElMessage.warning(res.message)
+      }
+      emit("getList")
+      busRef.value.clearValidate();
+      reset();
+      dialogVisible.value = false;
+    }
+  }
+}
+
+const handleClose = () => {
+  busRef.value.clearValidate();
+  reset();
+  dialogVisible.value = false;
+  emit("getList")
+
+}
+const reset = () => {
+  state.form = {
+    id: '',
+    name: '',
+    courseId: null,
+    companyName: '',
+    companyId: null,
+    level: null,
+    courseName: ''
+  }
+  state.courseNum = 1;
+  state.courseSize = 10;
+  state.courseList = []
+}
+defineExpose({
+  openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+  :deep(.el-form .el-form-item__label) {
+    font-size: 15px;
+  }
+  .file {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
+}
+</style>
diff --git a/src/views/onlineEducation/classHourBatch/components/chooseStudent.vue b/src/views/onlineEducation/classHourBatch/components/chooseStudent.vue
new file mode 100644
index 0000000..f7752af
--- /dev/null
+++ b/src/views/onlineEducation/classHourBatch/components/chooseStudent.vue
@@ -0,0 +1,187 @@
+<template>
+  <div class="notice">
+    <el-dialog
+        v-model="dialogVisible"
+        :title="title"
+        width="50%"
+        :before-close="handleClose"
+    >
+      <!-- 表格数据 -->
+      <el-table
+          ref="tableRef"
+          v-loading="loading"
+          :data="state.dataList"
+          :border="true"
+          :row-key="getRowKey"
+          @selection-change="handleSelectionChange"
+          v-model="state.selectRowKeys"
+      >
+        <el-table-column type="selection" :reserve-selection="true" width="55" align="center" />
+<!--        <el-table-column label="序号" type="index" align="center" width="80" />-->
+        <el-table-column label="工号" prop="empno" align="center" width="60"  />
+        <el-table-column label="姓名" prop="name" align="center"  />
+        <el-table-column label="性别" prop="sex" align="center" >
+          <template #default="scope">
+            <span>{{scope.row.sex == 0 ? '男':'女'}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="手机号" prop="phone" align="center" width="130"/>
+        <el-table-column label="身份证" prop="idNo" align="center" width="200" :show-overflow-tooltip="true"/>
+<!--        <el-table-column label="创建人" prop="createBy" align="center"/>-->
+        <el-table-column label="工作岗位" prop="post" align="center"/>
+        <el-table-column label="职务" prop="duty" align="center"/>
+<!--        <el-table-column label="一人一档" prop="duty" align="center" width="120">-->
+<!--          <template #default="scope">-->
+<!--            <el-button link type="primary">培训考试记录</el-button>-->
+<!--          </template>-->
+<!--        </el-table-column>-->
+      </el-table>
+
+      <pagination
+          v-show="state.total> 0"
+          :total="state.total"
+          v-model:page="state.queryParams.pageNum"
+          v-model:limit="state.queryParams.pageSize"
+          @pagination="getList"
+      />
+      <template #footer>
+        <span class="dialog-footer">
+            <el-button @click="handleClose" size="default">取 消</el-button>
+            <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {nextTick, reactive, ref, toRefs} from 'vue'
+import {ElMessage} from "element-plus";
+import Cookies from "js-cookie";
+import {addQuestionBank, checkQuestionBankName, editQuestionBank} from "@/api/onlineEducation/questionBank";
+import {getStudent} from "@/api/onlineEducation/student";
+import {batchAddStudent} from "@/api/onlineEducation/batch";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const tableRef = ref();
+const length = ref()
+const emit = defineEmits(["getList"]);
+const startUsername = ref('');
+const classifyRef = ref(null)
+const state = reactive({
+  form: [],
+  isAdmin: false,
+  total: 0,
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10
+  },
+  dataList: [],
+  totalItems: 0, // 总数据条数,从后端接口获取
+  phaseId: null,
+  chooseStu: [],
+  companyId: null,
+  selectRowKeys: []
+
+})
+const loading = ref(false);
+
+const getRowKey = (row) => {
+  return row.id
+}
+const openDialog = async (data) => {
+  // state.selectRowKeys = [10,11]
+
+  state.phaseId = data.queryParams.phaseId
+  title.value = '学员选择';
+  dialogVisible.value = true;
+  await getList()
+}
+
+const getList = async () => {
+  loading.value = true
+  const res = await getStudent(state.queryParams)
+  if(res.code == 200){
+    state.dataList = res.data.list
+    state.total = res.data.total
+    // await nextTick(() => {
+    //   const currentIds = state.dataList.map(row => row.id)
+    //   const selectIds = state.selectRowKeys.filter(id => currentIds.includes(id))
+    //   state.dataList.forEach(row => {
+    //     if (selectIds.includes(row.id)) {
+    //       tableRef.value.toggleRowSelection(row, true);
+    //     }
+    //   })
+    // });
+  }else{
+    ElMessage.warning(res.message)
+  }
+  loading.value = false
+}
+
+const onSubmit = async () => {
+    const res = await batchAddStudent(state.chooseStu)
+    if(res.code === 200){
+      ElMessage({
+        type: 'success',
+        message: '新增成功'
+      });
+    }else{
+      ElMessage.warning(res.message)
+    }
+    emit("getList")
+    reset();
+    dialogVisible.value = false;
+}
+
+const handleClose = () => {
+  reset();
+  dialogVisible.value = false;
+  emit("getList")
+}
+const reset = () => {
+  state.form = {
+    id: '',
+    name: '',
+    categoryId: null,
+    companyName: '',
+    companyId: null
+  }
+  tableRef.value.clearSelection();
+  state.dataList = []
+  state.total = 0
+  state.queryParams ={
+    pageNum: 1,
+    pageSize: 10
+  }
+}
+const handleSelectionChange = (val) => {
+
+  console.log("选中的行", val)
+  state.chooseStu = val.map(item => {
+    return {
+      companyId: item.companyId,
+      createId:item.createId,
+      phaseId:state.phaseId,
+      studentId: item.id
+    }
+  })
+}
+defineExpose({
+  openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+  :deep(.el-form .el-form-item__label) {
+    font-size: 15px;
+  }
+  .file {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
+}
+</style>
diff --git a/src/views/onlineEducation/classHourBatch/components/classHourChange.vue b/src/views/onlineEducation/classHourBatch/components/classHourChange.vue
new file mode 100644
index 0000000..51d6e63
--- /dev/null
+++ b/src/views/onlineEducation/classHourBatch/components/classHourChange.vue
@@ -0,0 +1,103 @@
+<template>
+  <div class="notice">
+    <el-dialog
+        v-model="dialogVisible"
+        :title="state.title"
+        width="50%"
+        :before-close="handleClose"
+    >
+      <el-table v-loading="state.loading" :data="state.dataList" :border="true">
+        <el-table-column label="创建时间" prop="createTime" align="center"  width="180" />
+        <el-table-column label="变动来源" prop="origin" align="center"  />
+        <el-table-column label="变动情况" prop="modifyPeriod" align="center"  />
+        <el-table-column label="变动后剩余(分)" prop="remainPeriod" align="center"  />
+<!--        <el-table-column label="操作" align="center" class-name="small-padding fixed-width"  width="180">-->
+<!--          <template #default="scope">-->
+<!--            <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>-->
+<!--          </template>-->
+<!--        </el-table-column>-->
+      </el-table>
+      <pagination
+        v-show="state.total > 0"
+        :total="state.total"
+        v-model:page="state.queryParams.pageNum"
+        v-model:limit="state.queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs} from 'vue'
+import {ElMessage} from "element-plus";
+
+import {
+  getClassification
+} from "@/api/onlineEducation/courseClass";
+import {addCourse, checkCourseName, editCourse, getCourseById} from "@/api/onlineEducation/courseManage";
+import {getToken} from "@/utils/auth";
+import {delPic, getBannerById} from "@/api/onlineEducation/banner";
+import Cookies from "js-cookie";
+import {addQuestionBank, checkQuestionBankName, editQuestionBank} from "@/api/onlineEducation/questionBank";
+import {getBatch, getCompanyPeriod} from "@/api/onlineEducation/batch";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const emit = defineEmits(["getList"]);
+const startUsername = ref('');
+const classifyRef = ref(null)
+
+const state = reactive({
+  loading: false,
+  dataList: [],
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10
+  },
+  total: 0,
+  title: ''
+})
+
+const openDialog = async (value) => {
+  state.title = '课时余量变动明细'
+  dialogVisible.value = true;
+  await getList()
+}
+const getList = async () => {
+  state.loading = true
+  const res = await getCompanyPeriod(state.queryParams)
+  if(res.code == 200){
+    state.dataList = res.data.list
+    state.total = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+  state.loading = false
+}
+
+const handleClose = () => {
+  dialogVisible.value = false;
+  emit("getList")
+
+}
+
+defineExpose({
+  openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+  :deep(.el-form .el-form-item__label) {
+    font-size: 15px;
+  }
+  .file {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
+}
+</style>
diff --git a/src/views/onlineEducation/classHourBatch/components/handleStudent.vue b/src/views/onlineEducation/classHourBatch/components/handleStudent.vue
new file mode 100644
index 0000000..a937f6b
--- /dev/null
+++ b/src/views/onlineEducation/classHourBatch/components/handleStudent.vue
@@ -0,0 +1,168 @@
+<template>
+  <div class="app-container">
+    <div style="margin-bottom: 10px;display: flex;align-items: center;justify-content: space-between">
+      <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="openDialog()"
+      >选择学员</el-button>
+      <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          @click="handleDeleteBatch"
+      >批量删除</el-button>
+    </div>
+    <!-- 表格数据 -->
+    <el-table ref="tableRef" v-loading="loading" :data="dataList" :border="true" :row-key="getRowKey"  @selection-change="handleSelectionChange">
+      <el-table-column type="selection" :reserve-selection="true" width="55" align="center" />
+      <el-table-column label="序号" type="index" align="center" width="80" />
+      <el-table-column label="批次名称" prop="phaseName" align="center"  />
+      <el-table-column label="学员名称" prop="studentName" align="center"  />
+      <el-table-column label="手机号" prop="studentPhone" align="center"  />
+      <el-table-column label="总进度" prop="totalProgress" align="center"  />
+      <el-table-column label="开始学习时间" prop="startTime" align="center"  />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width"  width="180">
+        <template #default="scope">
+          <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+
+    <choose-stu-dialog ref="dialogRef" @getList=getList></choose-stu-dialog>
+  </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import chooseStuDialog from './chooseStudent.vue'
+import Cookies from "js-cookie";
+import {delQuestionBank, getQuestionBank} from "@/api/onlineEducation/questionBank";
+import {batchDelStudent, delBatchStu, getBatchStudent} from "@/api/onlineEducation/batch";
+import {useRoute} from 'vue-router'
+const route = useRoute()
+
+
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const tableRef = ref();
+const data = reactive({
+  queryParams: {
+    pageId: null,
+    phaseId: null,
+    pageNum: 1,
+    pageSize: 10,
+  },
+  total: 0,
+  dataList: [],
+  isAdmin: false,
+  chooseStu: []
+
+});
+
+const { queryParams, total, dataList } = toRefs(data);
+
+onMounted(async ()=>{
+  const userInfo = JSON.parse(Cookies.get('userInfo'))
+  console.log("userInfo",userInfo)
+  if(userInfo.userType === 0){
+    data.isAdmin = true;
+  }else {
+    data.isAdmin = false;
+  }
+  const val = JSON.parse(route.query.val)
+  // data.queryParams.pageId = val.id
+  data.queryParams.phaseId = val.id
+  await getList()
+})
+onUnmounted(()=>{
+
+})
+
+const getRowKey = (row) => {
+  return row.id
+}
+const getList = async () => {
+  loading.value = true
+  const res = await getBatchStudent(data.queryParams)
+  if(res.code == 200){
+    data.dataList = res.data.list
+    data.total = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+  loading.value = false
+}
+
+const openDialog = () => {
+  dialogRef.value.openDialog(data);
+}
+
+/** 重置新增的表单以及其他数据  */
+function reset() {
+  proxy.resetForm("roleRef");
+}
+const handleSelectionChange = (val) => {
+
+  console.log("选中的行", val)
+  data.chooseStu = val.map(item => item.id)
+}
+const handleDelete = (val) => {
+  ElMessageBox.confirm(
+      '确定删除此条数据?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        const res = await delBatchStu(val.id)
+        if(res.code == 200){
+          ElMessage.success('数据删除成功')
+          await getList()
+          tableRef.value.clearSelection();
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+const handleDeleteBatch = () => {
+  if(data.chooseStu && data.chooseStu.length <=0){
+    ElMessage.warning('请选择要删除的学员');
+    return false;
+  }
+  ElMessageBox.confirm(
+      '确定删除选择的所有数据?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        // const param = {
+        //   phaseStudentIds: data.chooseStu
+        // }
+        const res = await batchDelStudent(data.chooseStu)
+        if(res.code == 200){
+          ElMessage.success('数据删除成功')
+          await getList()
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+
+</script>
diff --git a/src/views/onlineEducation/classHourBatch/index.vue b/src/views/onlineEducation/classHourBatch/index.vue
index a0120ed..af6dc53 100644
--- a/src/views/onlineEducation/classHourBatch/index.vue
+++ b/src/views/onlineEducation/classHourBatch/index.vue
@@ -1,12 +1,151 @@
 <template>
-<div>课时批次</div>
+  <div class="app-container">
+    <div style="margin-bottom: 10px;display: flex;align-items: center;justify-content: space-between">
+      <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="openDialog('add',{})"
+      >新增批次</el-button>
+      <span v-if="!data.isAdmin" style="font-size: 19px;font-weight: 600;margin-right: 20px">
+        {{data.companyName}},您的企业当前系统可用课时总计
+        <span style="font-size: 19px;font-weight: 600;color: #1ab394">{{data.remainPeriod}}</span> 分钟。<span @click="openDetail" style="cursor: pointer; font-size: 19px;font-weight: 600;color: #1890ff">[明细]</span>
+      </span>
+    </div>
+    <!-- 表格数据 -->
+    <el-table v-loading="loading" :data="dataList" :border="true">
+      <el-table-column label="批次编号" prop="code" align="center" width="135" />
+      <el-table-column label="创建时间" prop="createTime" align="center"  width="120" />
+      <el-table-column label="批次名称" prop="name" align="center"  />
+      <el-table-column label="创建企业" prop="companyName" align="center"  />
+      <el-table-column label="批次级别" prop="level" align="center"  >
+        <template #default="scope">
+          <span>{{scope.row.level === 1 ? '公司级' : scope.row.level === 2 ? '部门级' : scope.row.level === 3 ? '车间级' : '其他'  }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="课程" prop="courseName" align="center"  />
+      <el-table-column label="学习人数" prop="studentCount" align="center"  />
+      <el-table-column label="总课时" prop="coursePeriodNum" align="center"  />
+      <el-table-column label="已完成人数" prop="" align="center"  />
+      <el-table-column label="完成率" prop="" align="center"  />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width"  width="180">
+        <template #default="scope">
+          <el-button link type="primary" @click="toStuChoose(scope.row)">学生数据</el-button>
+          <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+          <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+    <batch-dialog ref="dialogRef" @getList=getList></batch-dialog>
+    <class-hour-change ref="classHourRef" @getList=getList></class-hour-change>
+  </div>
 </template>
+
 <script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import batchDialog from './components/batchDialog.vue'
+import classHourChange from './components/classHourChange.vue'
+import Cookies from "js-cookie";
+import {useRouter} from 'vue-router'
+const router = useRouter()
+import {delQuestionBank, getQuestionBank} from "@/api/onlineEducation/questionBank";
+import {delBatch, getBatch} from "@/api/onlineEducation/batch";
 
+
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const classHourRef = ref();
+const data = reactive({
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+  },
+  total: 0,
+  dataList: [],
+  isAdmin: false,
+  companyName: '',
+  remainPeriod: null
+
+});
+
+const { queryParams, total, dataList } = toRefs(data);
+
+onMounted(async ()=>{
+  const userInfo = JSON.parse(Cookies.get('userInfo'))
+  console.log("userInfo",userInfo)
+  if(userInfo.userType === 0){
+    data.isAdmin = true;
+  }else {
+    data.remainPeriod = userInfo.remainPeriod ? (userInfo.remainPeriod /60).toFixed(2).replace(/\.00$/, ''):''
+    data.isAdmin = false;
+    data.companyName = userInfo.companyName
+  }
+  await getList()
+})
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+  loading.value = true
+  const res = await getBatch(data.queryParams)
+  if(res.code == 200){
+    data.dataList = res.data.list.map(item => {
+      return {
+        ...item,
+        coursePeriodNum: item.coursePeriod ? (item.coursePeriod /60).toFixed(2).replace(/\.00$/, '') + '分钟':''
+      }
+    })
+    data.total = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+  loading.value = false
+}
+
+const openDialog = (type, value) => {
+  dialogRef.value.openDialog(type, value);
+}
+
+/** 重置新增的表单以及其他数据  */
+function reset() {
+  proxy.resetForm("roleRef");
+}
+const handleDelete = (val) => {
+  ElMessageBox.confirm(
+      '确定删除此条数据?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        const res = await delBatch(val.id)
+        if(res.code == 200){
+          ElMessage.success('数据删除成功')
+          await getList()
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+const toStuChoose = (val) => {
+  const v = JSON.stringify(val)
+  router.push({ path: "/chooseStu", query: { val: v } });
+}
+
+const openDetail = () => {
+  classHourRef.value.openDialog()
+}
 </script>
-
-
-
-<style scoped lang="scss">
-
-</style>
diff --git a/src/views/onlineEducation/courseManage/components/courseManageDialog.vue b/src/views/onlineEducation/courseManage/components/courseManageDialog.vue
index 9d397ac..6b78067 100644
--- a/src/views/onlineEducation/courseManage/components/courseManageDialog.vue
+++ b/src/views/onlineEducation/courseManage/components/courseManageDialog.vue
@@ -16,6 +16,7 @@
 <!--          </el-select>-->
           <el-cascader
               ref="classifyRef"
+              style="width: 100%"
               v-model="state.form.categoryId"
               :options="state.classifyList"
               :props="state.props"
@@ -24,11 +25,11 @@
               @change="handleChange"
           />
         </el-form-item>
-        <el-form-item label="要求课时:" prop="period">
-          <el-input v-model="state.form.period" placeholder="请输入要求课时">
-            <template #append>分钟</template>
-          </el-input>
-        </el-form-item>
+<!--        <el-form-item label="要求课时:" prop="period">-->
+<!--          <el-input v-model="state.form.period" placeholder="请输入要求课时">-->
+<!--            <template #append>分钟</template>-->
+<!--          </el-input>-->
+<!--        </el-form-item>-->
         <el-form-item label="提交单位:" prop="companyName" >
           <el-input v-model="state.form.companyName" disabled/>
         </el-form-item>
@@ -299,6 +300,7 @@
     logo: '',
     companyId: null
   }
+  state.imgList = []
 }
 defineExpose({
   openDialog
diff --git a/src/views/onlineEducation/groupExams/components/examDialog.vue b/src/views/onlineEducation/groupExams/components/examDialog.vue
new file mode 100644
index 0000000..e2ec21c
--- /dev/null
+++ b/src/views/onlineEducation/groupExams/components/examDialog.vue
@@ -0,0 +1,400 @@
+<template>
+  <div class="notice">
+    <el-dialog
+        v-model="dialogVisible"
+        width="800px"
+        :before-close="handleClose"
+    >
+      <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" >
+          <span style="font-size: 20px;font-weight: 800;margin-left: 20px">考试配置</span>
+          <div style="margin: 20px 20px">
+            <el-form-item label="考试名称:" prop="name">
+              <el-input v-model.trim="state.form.name" placeholder="请输入考试名称"></el-input>
+            </el-form-item>
+            <el-form-item label="课程分类:" prop="categoryId" >
+              <el-cascader
+                  style="width: 100%"
+                  ref="classifyRef"
+                  v-model="state.form.categoryId"
+                  :options="state.classifyList"
+                  :props="state.props"
+                  clearable
+                  :show-all-levels="false"
+                  @change="handleChange"
+              />
+            </el-form-item>
+          </div>
+        <span style="font-size: 20px;font-weight: 800;margin-left: 20px">组卷信息</span>
+        <div  style="display: flex">
+          <div class="group">
+            <div>
+              单选:<el-input style="max-width: 40px"></el-input>&nbsp;题
+            </div>
+            <div style="margin-left: 20px">
+              每题:<el-input style="max-width: 40px"></el-input>&nbsp;分
+            </div>
+          </div>
+          <div class="group" >
+           <div>
+             共&nbsp;<span style="max-width: 30px">xxx</span>&nbsp;分
+           </div>
+            <el-select
+                clearable
+                v-model="state.form.singleBankId"
+                style="width: 160px;margin: 0 20px"
+                v-loadMoreNew:[reselectSingle]="handleScroll"
+                :popper-class="reselectSingle.name"
+                class="item-width"
+                placeholder="请选择单选题题库"
+            >
+              <el-option
+                  v-for="item in state.bankListSingle"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+              />
+            </el-select>
+          <el-radio-group v-model="radio"  >
+            <el-radio :label="1" style="max-width: 30px">随机</el-radio>
+            <el-radio :label="2">默认</el-radio>
+          </el-radio-group>
+          </div>
+        </div>
+        <div  style="display: flex">
+          <div class="group">
+            <div>
+              多选:<el-input style="max-width: 40px"></el-input>&nbsp;题
+            </div>
+            <div style="margin-left: 20px">
+              每题:<el-input style="max-width: 40px"></el-input>&nbsp;分
+            </div>
+          </div>
+          <div class="group" >
+            <div>
+              共&nbsp;<span style="max-width: 30px">xxx</span>&nbsp;分
+            </div>
+            <el-select
+                clearable
+                v-model="state.form.singleBankId"
+                style="width: 160px;margin: 0 20px"
+                v-loadMoreNew:[reselectSingle]="handleScroll"
+                :popper-class="reselectSingle.name"
+                class="item-width"
+                placeholder="请选择单选题题库"
+            >
+              <el-option
+                  v-for="item in state.bankListSingle"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+              />
+            </el-select>
+            <el-radio-group v-model="radio"  >
+              <el-radio :label="1" style="max-width: 30px">随机</el-radio>
+              <el-radio :label="2">默认</el-radio>
+            </el-radio-group>
+          </div>
+        </div>
+        <div  style="display: flex">
+          <div class="group">
+            <div>
+              判断:<el-input style="max-width: 40px"></el-input>&nbsp;题
+            </div>
+            <div style="margin-left: 20px">
+              每题:<el-input style="max-width: 40px"></el-input>&nbsp;分
+            </div>
+          </div>
+          <div class="group" >
+            <div>
+              共&nbsp;<span style="max-width: 30px">xxx</span>&nbsp;分
+            </div>
+            <el-select
+                clearable
+                v-model="state.form.singleBankId"
+                style="width: 160px;margin: 0 20px"
+                v-loadMoreNew:[reselectSingle]="handleScroll"
+                :popper-class="reselectSingle.name"
+                class="item-width"
+                placeholder="请选择单选题题库"
+            >
+              <el-option
+                  v-for="item in state.bankListSingle"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+              />
+            </el-select>
+            <el-radio-group v-model="radio"  >
+              <el-radio :label="1" style="max-width: 30px">随机</el-radio>
+              <el-radio :label="2">默认</el-radio>
+            </el-radio-group>
+          </div>
+        </div>
+        <span class="group" style="margin-bottom: 10px">共计:xxx分</span>
+        <div style="display: flex;justify-content: space-between;align-items: center">
+          <el-form-item label="合格分数:" prop="">
+            <el-input-number v-model="num" :min="1" :max="10" style="margin-right: 10px" /> (大于等于)
+          </el-form-item>
+          <el-form-item label="限制时长:" prop="">
+            <el-input v-model="num1" style="max-width: 200px" >
+              <template #append>分钟</template>
+            </el-input>
+          </el-form-item>
+        </div>
+
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+            <el-button @click="handleClose" size="default">取 消</el-button>
+            <el-button type="primary"  @click="onSubmit" size="default" v-preReClick>确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {reactive, ref, toRefs} from 'vue'
+import {ElMessage} from "element-plus";
+
+import {
+  getClassification
+} from "@/api/onlineEducation/courseClass";
+import {addCourse, checkCourseName, editCourse, getCourseById} from "@/api/onlineEducation/courseManage";
+import {getToken} from "@/utils/auth";
+import {delPic, getBannerById} from "@/api/onlineEducation/banner";
+import Cookies from "js-cookie";
+import {
+  addQuestionBank,
+  checkQuestionBankName,
+  editQuestionBank,
+  getQuestionBank
+} from "@/api/onlineEducation/questionBank";
+import {checkExamName} from "@/api/onlineEducation/exam";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const emit = defineEmits(["getList"]);
+const startUsername = ref('');
+const classifyRef = ref(null)
+
+const validateName = (rule, value, callback)=>{
+  if(value === ''){
+    callback(new Error('请输入考试名称'))
+  }else if(title.value === '编辑' && value === startUsername.value){
+    callback()
+  }else{
+    let param = {}
+    if(title.value === '新增') {
+      param = {
+        name:value
+      }
+    }else if(title.value === '编辑'){
+      param = {
+        name:value,
+        id: state.form.id
+      }
+    }
+    checkExamName(param).then((res)=>{
+      if(res.data == false){
+        callback(new Error('考试名称已被占用,请更换其他名称'))
+      }else{
+        callback()
+      }
+    })
+  }
+}
+const reselectSingle = reactive({
+  name: 'Single'
+})
+const state = reactive({
+  form: {
+    id: '',
+    name: '',
+    categoryId: null,
+    companyName: '',
+    companyId: null
+  },
+  formRules: {
+    name: [{required: true, trigger: "blur", validator: validateName}],
+    categoryId: [{required: true, message: '请选择课程分类', trigger: 'blur'}],
+  },
+  classifyList: [],
+  isAdmin: false,
+  props: {
+    checkStrictly: true,
+  },
+  bankListSingle: [],
+  bankSinglePageNum: 1, // 当前页码
+  bankSinglePageSize: 10, // 每页显示的数量
+  hasMoreItemsSingle: null, // 是否还有更多选项
+})
+
+const openDialog = async (type, value) => {
+  await getClassifyList();
+  await loadMoreBankData()
+  const userInfo = JSON.parse(Cookies.get('userInfo'))
+  console.log("userInfo",userInfo)
+  if(userInfo.userType === 0){
+    state.isAdmin = true;
+    state.form.companyName = ''
+    state.form.companyId = null
+  }else {
+    state.isAdmin = false;
+    state.form.companyName = userInfo.companyName
+    state.form.companyId = userInfo.companyId
+  }
+  title.value = type === 'addFirst' || type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ;
+  if(type === 'edit') {
+    state.form.id = value.id
+    state.form.name = value.name
+    state.form.categoryId = value.categoryId
+    startUsername.value = value.name;
+  }else if(type === 'add' && value ){
+    state.form.parentId = value.id
+  }
+  dialogVisible.value = true;
+}
+
+const onSubmit = async () => {
+  if(state.isAdmin){
+    ElMessage({
+      type: 'warning',
+      message: '管理员暂无权限'
+    });
+    return;
+  }
+  const valid = await busRef.value.validate();
+  if(valid){
+    if(title.value === '新增'){
+      const {id, ...data} = JSON.parse(JSON.stringify(state.form))
+      const res = await addQuestionBank(data)
+      if(res.code === 200){
+        ElMessage({
+          type: 'success',
+          message: '新增成功'
+        });
+      }else{
+        ElMessage.warning(res.message)
+      }
+      emit("getList")
+      busRef.value.clearValidate();
+      reset();
+      dialogVisible.value = false;
+    }else if(title.value === '编辑'){
+      const {...data} = JSON.parse(JSON.stringify(state.form))
+      const res = await editQuestionBank(data)
+      if(res.code === 200){
+        ElMessage({
+          type: 'success',
+          message: '编辑成功'
+        });
+      }else{
+        ElMessage.warning(res.message)
+      }
+      emit("getList")
+      busRef.value.clearValidate();
+      reset();
+      dialogVisible.value = false;
+    }
+  }
+}
+const  getClassifyList = async () => {
+  const res = await getClassification();
+  if(res.code === 200){
+    state.classifyList = recursion(res.data)
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+const recursion = (data) => {
+  let tmp = []
+  for (let i = 0; i < data.length; i++) {
+    let item = data[i]
+    // children为空
+    if (item.children&& item.children.length==0) {
+      tmp.push({
+        value: item.id,
+        label: item.name
+      })
+      // 有children
+    } else {
+      tmp.push({
+        value: item.id,
+        label: item.name,
+        children:recursion(item.children)
+      })
+    }
+  }
+  return tmp;
+}
+const handleChange = ()=> {
+  console.log("label====",classifyRef.value.getCheckedNodes()[0].value)
+  state.form.categoryId = classifyRef.value.getCheckedNodes()[0].value
+  // 我这里只是打印了一下label的值哦,需要赋值的话自己去赋值哦
+}
+
+const handleClose = () => {
+  busRef.value.clearValidate();
+  reset();
+  dialogVisible.value = false;
+  emit("getList")
+
+}
+const reset = () => {
+  state.form = {
+    id: '',
+    name: '',
+    categoryId: null,
+    companyName: '',
+    companyId: null
+  }
+}
+const handleScroll = () => {
+  if(state.bankSinglePageNum >= state.hasMoreItemsSingle) return
+  state.bankSinglePageNum++;
+  loadMoreBankData()
+
+}
+const loadMoreBankData = async () => {
+  console.log(' Bank');
+  const queryParams = {
+    pageNum: state.bankSinglePageNum,
+    pageSize: state.bankSinglePageSize,
+  }
+  const res = await getQuestionBank(queryParams)
+  if (res.code == 200) {
+    state.hasMoreItemsSingle = res.data.totalPage
+    const data = res.data
+    state.bankListSingle = state.bankListSingle.concat(data.list)
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+defineExpose({
+  openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+  :deep(.el-form .el-form-item__label) {
+    font-size: 15px;
+  }
+  .file {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+  }
+  .group{
+    display: flex;
+    align-items:center;
+    font-size: 15px;
+    font-weight: 700;
+    margin: 20px 0 0 70px;
+  }
+}
+
+</style>
diff --git a/src/views/onlineEducation/groupExams/index.vue b/src/views/onlineEducation/groupExams/index.vue
index 60bea94..03fca18 100644
--- a/src/views/onlineEducation/groupExams/index.vue
+++ b/src/views/onlineEducation/groupExams/index.vue
@@ -1,12 +1,137 @@
 <template>
-<div>组卷考试分配</div>
+  <div class="app-container">
+    <div style="margin-bottom: 10px;display: flex;align-items: center;justify-content: space-between">
+      <el-button
+          type="primary"
+          plain
+          @click="openDialog('add',{})"
+      >开始组卷考试</el-button>
+    </div>
+    <!-- 表格数据 -->
+    <el-table v-loading="loading" :data="dataList" :border="true">
+      <el-table-column label="编号" prop="code" align="center" width="135" />
+      <el-table-column label="考试名称" prop="name" align="center"  />
+      <el-table-column label="企业名称" prop="companyName" align="center"  />
+      <el-table-column label="创建账户" prop="createBy" align="center"  />
+      <el-table-column label="科目/类别" prop="categoryName" align="center"  />
+      <el-table-column label="考生人数" prop="" align="center"  />
+      <el-table-column label="合格人数" prop="" align="center"  />
+      <el-table-column label="平均分数" prop="" align="center"  />
+      <el-table-column label="合格率" prop="" align="center"  />
+      <el-table-column label="限制时长" prop="limitTime" align="center"  />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width"  width="180">
+        <template #default="scope">
+          <el-button link type="primary" @click="toStuChoose(scope.row)">学生数据</el-button>
+          <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button>
+          <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
+    />
+    <exam-dialog ref="dialogRef" @getList=getList></exam-dialog>
+<!--    <class-hour-change ref="classHourRef" @getList=getList></class-hour-change>-->
+  </div>
 </template>
+
 <script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import examDialog from './components/examDialog.vue'
+// import classHourChange from './components/classHourChange.vue'
+import Cookies from "js-cookie";
+import {useRouter} from 'vue-router'
+const router = useRouter()
+import {delQuestionBank, getQuestionBank} from "@/api/onlineEducation/questionBank";
+import {delBatch, getBatch} from "@/api/onlineEducation/batch";
+import {delExam, getExam} from "@/api/onlineEducation/exam";
 
+
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+const classHourRef = ref();
+const data = reactive({
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+  },
+  total: 0,
+  dataList: [],
+  isAdmin: false,
+  companyName: '',
+  remainPeriod: null
+
+});
+
+const { queryParams, total, dataList } = toRefs(data);
+
+onMounted(async ()=>{
+  const userInfo = JSON.parse(Cookies.get('userInfo'))
+  console.log("userInfo",userInfo)
+  if(userInfo.userType === 0){
+    data.isAdmin = true;
+  }else {
+    data.isAdmin = false;
+    data.companyName = userInfo.companyName
+  }
+  await getList()
+})
+onUnmounted(()=>{
+
+})
+
+const getList = async () => {
+  loading.value = true
+  const res = await getExam(data.queryParams)
+  if(res.code == 200){
+    data.dataList = res.data.list
+    data.total = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+  loading.value = false
+}
+
+const openDialog = (type, value) => {
+  dialogRef.value.openDialog(type, value);
+}
+
+/** 重置新增的表单以及其他数据  */
+function reset() {
+  proxy.resetForm("roleRef");
+}
+const handleDelete = (val) => {
+  ElMessageBox.confirm(
+      '确定删除此条数据?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        const res = await delExam(val.id)
+        if(res.code == 200){
+          ElMessage.success('数据删除成功')
+          await getList()
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+const toStuChoose = (val) => {
+  const v = JSON.stringify(val)
+  router.push({ path: "/chooseStu", query: { val: v } });
+}
+
+const openDetail = () => {
+  classHourRef.value.openDialog()
+}
 </script>
-
-
-
-<style scoped lang="scss">
-
-</style>
diff --git a/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue b/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue
index c24f4c6..b92fe7d 100644
--- a/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue
+++ b/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue
@@ -352,6 +352,61 @@
     bankId: null,
     answer: ''
   }
+  state.singleQuestion= {
+    analyze: '',
+        items: [
+      {
+        prefix:"A",
+        content: ''
+      },
+      {
+        prefix:"B",
+        content: ''
+      },
+      {
+        prefix:"C",
+        content: ''
+      },
+      {
+        prefix:"D",
+        content: ''
+      },
+    ]
+  }
+  state.judgeQuestion= {
+    analyze: '',
+        items: [
+      {
+        prefix:"A",
+        content: '是'
+      },
+      {
+        prefix:"B",
+        content: '否'
+      },
+    ]
+  }
+      state. multiQuestion= {
+    analyze: '',
+        items: [
+      {
+        prefix:"A",
+        content: ''
+      },
+      {
+        prefix:"B",
+        content: ''
+      },
+      {
+        prefix:"C",
+        content: ''
+      },
+      {
+        prefix:"D",
+        content: ''
+      },
+    ]
+  },
   state.bankPageNum = 1;
   state.bankPageSize = 10;
   state.bankList = []
diff --git a/src/views/onlineEducation/systemManage/company/components/companyDialog.vue b/src/views/onlineEducation/systemManage/company/components/companyDialog.vue
index cd50548..51a91d4 100644
--- a/src/views/onlineEducation/systemManage/company/components/companyDialog.vue
+++ b/src/views/onlineEducation/systemManage/company/components/companyDialog.vue
@@ -8,33 +8,39 @@
     >
       <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" >
         <el-form-item label="企业信用代码:" prop="creditCode" v-if="title!=='分配课时'">
-          <el-input v-model.trim="state.form.creditCode"></el-input>
+          <el-input v-model.trim="state.form.creditCode" placeholder="请输入企业信用代码"></el-input>
         </el-form-item>
         <el-form-item label="企业名称:" prop="name" v-if="title!=='分配课时'">
-          <el-input v-model.trim="state.form.name" ></el-input>
+          <el-input v-model.trim="state.form.name" placeholder="请输入企业名称"></el-input>
         </el-form-item>
         <el-form-item label="负责人:" prop="major" v-if="title!=='分配课时'">
-          <el-input v-model.trim="state.form.major"></el-input>
+          <el-input v-model.trim="state.form.major" placeholder="请输入负责人"></el-input>
         </el-form-item>
         <el-form-item label="联系电话:" prop="phone" v-if="title!=='分配课时'">
-          <el-input v-model.trim="state.form.phone" ></el-input>
+          <el-input v-model.trim="state.form.phone" placeholder="请输入联系电话"></el-input>
         </el-form-item>
-        <el-form-item label="当前剩余课时(分):" prop="remainPeriod" v-if="title!=='分配课时'">
+        <el-form-item label="当前剩余课时(秒):" prop="remainPeriod" v-if="title!=='分配课时'">
           <el-input
+              placeholder="请输入剩余课时"
               v-model.trim="state.form.remainPeriod"
               @input="state.form.remainPeriod= state.form.remainPeriod.replace(/[^0-9]/g,'')">
+            <template #append v-if="state.form.remainPeriod"><span>{{(state.form.remainPeriod /60).toFixed(2).replace(/\.00$/, '') + '分钟'}}</span></template>
           </el-input>
         </el-form-item>
-        <el-form-item label="累计已用课时(分):" prop="spendPeriod" v-if="title!=='分配课时'">
+        <el-form-item label="累计已用课时(秒):" prop="spendPeriod" v-if="title!=='分配课时'">
           <el-input
+              placeholder="请输入已用课时"
               v-model.trim="state.form.spendPeriod"
               @input="state.form.spendPeriod= state.form.spendPeriod.replace(/[^0-9]/g,'')">
+            <template #append v-if="state.form.spendPeriod"><span>{{(state.form.spendPeriod /60).toFixed(2).replace(/\.00$/, '') + '分钟'}}</span></template>
           </el-input>
         </el-form-item>
-        <el-form-item label="总课时(分):" prop="totalPeriod">
+        <el-form-item label="总课时(秒):" prop="totalPeriod">
           <el-input
+              placeholder="请输入总课时"
               v-model.trim="state.form.totalPeriod"
               @input="state.form.totalPeriod = state.form.totalPeriod.replace(/[^0-9]/g,'')">
+            <template #append v-if="state.form.totalPeriod"><span>{{(state.form.totalPeriod /60).toFixed(2).replace(/\.00$/, '') + '分钟'}}</span></template>
           </el-input>
         </el-form-item>
       </el-form>
diff --git a/src/views/onlineEducation/systemManage/company/index.vue b/src/views/onlineEducation/systemManage/company/index.vue
index abdef60..cbb5355 100644
--- a/src/views/onlineEducation/systemManage/company/index.vue
+++ b/src/views/onlineEducation/systemManage/company/index.vue
@@ -15,9 +15,9 @@
       <el-table-column label="企业名称" prop="name" align="center" />
       <el-table-column label="负责人" prop="major" align="center"  />
       <el-table-column label="联系电话" prop="phone" align="center"/>
-      <el-table-column label="当前剩余课时(分)" prop="remainPeriod" align="center" width="150"/>
-      <el-table-column label="累计已用课时(分)" prop="spendPeriod" align="center" width="150"/>
-      <el-table-column label="总课时(分)" prop="totalPeriod" align="center"/>
+      <el-table-column label="当前剩余课时(分)" prop="remainPeriodMin" align="center" width="150"/>
+      <el-table-column label="累计已用课时(分)" prop="spendPeriodMin" align="center" width="150"/>
+      <el-table-column label="总课时(分)" prop="totalPeriodMin" align="center"/>
       <el-table-column label="课时变动详情" align="center" class-name="small-padding fixed-width" >
         <template #default="scope">
           <el-button link type="primary">查看详情</el-button>
@@ -76,7 +76,14 @@
   loading.value = true
   const res = await getCompany(data.queryParams)
   if(res.code == 200){
-    data.dataList = res.data.list
+    data.dataList = res.data.list.map(item => {
+      return{
+        ...item,
+        remainPeriodMin: item.remainPeriod ?(item.remainPeriod /60).toFixed(2).replace(/\.00$/, '') + '分钟':'',
+        spendPeriodMin:item.spendPeriod ?(item.spendPeriod /60).toFixed(2).replace(/\.00$/, '') + '分钟':'',
+        totalPeriodMin:item.totalPeriod ?(item.totalPeriod /60).toFixed(2).replace(/\.00$/, '') + '分钟':'',
+      }
+    })
     data.total = res.data.total
   }else{
     ElMessage.warning(res.message)

--
Gitblit v1.9.2