Explorar el Código

新增监管平台

Tang hace 2 años
padre
commit
f1c4b897d4
Se han modificado 26 ficheros con 5458 adiciones y 552 borrados
  1. 9 0
      src/newApi/business.js
  2. 1 1
      src/settings.js
  3. 1 0
      src/views/Marketing/goods/commodityManageMent/add/index.vue
  4. 24 1
      src/views/Marketing/goods/commodityManageMent/add/introduction.vue
  5. 1 0
      src/views/Marketing/goods/commodityManageMent/edit/index.vue
  6. 24 1
      src/views/Marketing/goods/commodityManageMent/edit/introduction.vue
  7. 6 1
      src/views/Marketing/order/pendingRefundOrder/index.vue
  8. 2 0
      src/views/Marketing/order/pendingRefundOrder/refundDia.vue
  9. 74 0
      src/views/classHoursReview/component/ChapterTable.vue
  10. 137 0
      src/views/classHoursReview/component/CheatDialog.vue
  11. 396 0
      src/views/classHoursReview/component/LessonTable.vue
  12. 58 0
      src/views/classHoursReview/component/ModulTable.vue
  13. 521 0
      src/views/classHoursReview/component/StudyTables.vue
  14. 89 0
      src/views/classHoursReview/index.vue
  15. 402 0
      src/views/classHoursReview/studyTimes.vue
  16. 561 538
      src/views/index.vue
  17. 10 6
      src/views/resource/bankManagement/testPaperManagement/PaperSort.vue
  18. 1 1
      src/views/resource/videoManagement/chapter/add/index.vue
  19. 1 1
      src/views/resource/videoManagement/chapter/edit/index.vue
  20. 1 2
      src/views/resource/videoManagement/courseManagement/chapterContent/index.vue
  21. 378 0
      src/views/secondJian/completionList/index.vue
  22. 814 0
      src/views/secondJian/courseList/index.vue
  23. 378 0
      src/views/secondJian/learningList/index.vue
  24. 378 0
      src/views/secondZao/completionList/index.vue
  25. 813 0
      src/views/secondZao/courseList/index.vue
  26. 378 0
      src/views/secondZao/learningList/index.vue

+ 9 - 0
src/newApi/business.js

@@ -79,5 +79,14 @@ export default {
             params: data
         })
     },
+    //根据名称查找业务层ID
+    coursebusinessqueryFullId(data) {
+        return request({
+            url: '/course/business/queryFullId',
+            method: 'get',
+            params: data
+        })
+    },
+    
 
 }

+ 1 - 1
src/settings.js

@@ -12,7 +12,7 @@ module.exports = {
   /**
    * 是否显示顶部导航
    */
-  topNav: true,
+  topNav: false,
 
   /**
    * 是否显示 tagsView

+ 1 - 0
src/views/Marketing/goods/commodityManageMent/add/index.vue

@@ -204,6 +204,7 @@ export default {
         certificateTypeId: "",
         showStatus: 1,
         externalLinkStatus:0,
+        commitPeriodStatus:0
       },
       rules: {
         year: [

+ 24 - 1
src/views/Marketing/goods/commodityManageMent/add/introduction.vue

@@ -1,5 +1,28 @@
 <template>
   <div id="introduction">
+    <template v-if="listData.goodsType === 1">
+      <el-form-item
+        label="是否提交官方审核"
+        :label-width="labelWidth"
+        prop="commitPeriodStatus"
+      >
+        <el-radio-group v-model="listData.commitPeriodStatus">
+          <el-radio :label="1">是</el-radio>
+          <el-radio :label="0">否</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item
+        label="提交官方审核备注说明"
+        :label-width="labelWidth"
+        prop="commitPeriodRemark"
+      >
+        <el-input
+          type="textarea"
+          v-model="listData.commitPeriodRemark"
+          placeholder="请输入官方审核备注说明"
+        ></el-input>
+      </el-form-item>
+    </template>
     <el-form-item label="商品简介" :label-width="labelWidth" prop="introduce">
       <el-input
         type="textarea"
@@ -66,7 +89,7 @@ export default {
   props: ["listData"],
   data() {
     return {
-      labelWidth: "90px",
+      labelWidth: "180px",
       active: 1,
     };
   },

+ 1 - 0
src/views/Marketing/goods/commodityManageMent/edit/index.vue

@@ -237,6 +237,7 @@ export default {
         coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
         goodsType: "",
         certificateTypeId: "",
+        commitPeriodStatus:0
       },
       rules: {
         year: [

+ 24 - 1
src/views/Marketing/goods/commodityManageMent/edit/introduction.vue

@@ -1,5 +1,28 @@
 <template>
   <div id="introduction">
+    <template v-if="listData.goodsType === 1">
+      <el-form-item
+        label="是否提交官方审核"
+        :label-width="labelWidth"
+        prop="commitPeriodStatus"
+      >
+        <el-radio-group v-model="listData.commitPeriodStatus">
+          <el-radio :label="1">是</el-radio>
+          <el-radio :label="0">否</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item
+        label="提交官方审核备注说明"
+        :label-width="labelWidth"
+        prop="commitPeriodRemark"
+      >
+        <el-input
+          type="textarea"
+          v-model="listData.commitPeriodRemark"
+          placeholder="请输入官方审核备注说明"
+        ></el-input>
+      </el-form-item>
+    </template>
     <el-form-item label="商品简介" :label-width="labelWidth" prop="introduce">
       <el-input
         type="textarea"
@@ -66,7 +89,7 @@ export default {
   props: ["listData"],
   data() {
     return {
-      labelWidth: "90px",
+      labelWidth: "180px",
       active: 1,
     };
   },

+ 6 - 1
src/views/Marketing/order/pendingRefundOrder/index.vue

@@ -34,7 +34,10 @@
         margin-bottom: 12px;
       "
     >
-      <span>退款订单:<span style="color: red;">{{ total || 0 }}</span>条</span>
+      <span
+        >退款订单:<span style="color: red">{{ total || 0 }}</span
+        >条</span
+      >
       <el-button
         size="small"
         type="primary"
@@ -191,6 +194,7 @@ export default {
         },
       ],
       formData: {
+        searchKey: "",
         goodsType: "",
         periodStatus: 0,
         pageSize: 10,
@@ -451,6 +455,7 @@ export default {
       if (int === 2) {
         this.formData = {
           // type: 2,
+          searchKey: "",
           goodsType: "",
           periodStatus: this.formData.periodStatus,
           pageSize: 10,

+ 2 - 0
src/views/Marketing/order/pendingRefundOrder/refundDia.vue

@@ -236,6 +236,7 @@ export default {
             this.dialogVisible = false;
             this.$parent.allCheckData = [];
             this.$parent.$refs.tableList.clearSelection();
+            this.$parent.formData.searchKey = "";
             this.$parent.search();
           })
           .catch((err) => {
@@ -249,6 +250,7 @@ export default {
             this.dialogVisible = false;
             this.$parent.allCheckData = [];
             this.$parent.$refs.tableList.clearSelection();
+            this.$parent.formData.searchKey = "";
             this.$parent.search();
           })
           .catch((err) => {

+ 74 - 0
src/views/classHoursReview/component/ChapterTable.vue

@@ -0,0 +1,74 @@
+<template>
+  <div>
+    <el-table
+      :default-expand-all="true"
+      border
+      :data="tabledata"
+      style="width: 100%; border-radius: 4px; overflow: hidden"
+      :header-cell-style="{
+        'background-color': '#D9ECFA',
+        padding: '8px',
+        color: '#1565C0',
+        'border-right-color': '#1565C0',
+        'border-left-color': '#1565C0',
+      }"
+    >
+      <el-table-column :label="label" type="expand" width="70px">
+        <template slot-scope="scope">
+          <Lesson-table
+            :tabledata="scope.row.classPeriodSectionList || []"
+          ></Lesson-table>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="realName" label="姓名">
+      </el-table-column>
+      <el-table-column align="center" prop="typeName" :label="label + '标题'">
+      </el-table-column>
+      <el-table-column align="center" prop="classHours" label="学时">
+      </el-table-column>
+      <el-table-column align="center" label="开始学习时间">
+        <template slot-scope="scope">
+          <span>
+            {{ $methodsTools.onlyForma(scope.row.studyStartTime) }}
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="结束学习时间">
+        <template slot-scope="scope">
+          <span>
+            {{ $methodsTools.onlyForma(scope.row.studyEndTime) }}
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="performance" label="测试成绩">
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import LessonTable from "./LessonTable.vue";
+export default {
+  props: {
+    tabledata: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    label: {
+      type: String,
+      default: "章",
+    },
+  },
+  data() {
+    return {};
+  },
+  components: {
+    LessonTable,
+  },
+};
+</script>
+
+<style>
+</style>

+ 137 - 0
src/views/classHoursReview/component/CheatDialog.vue

@@ -0,0 +1,137 @@
+<template>
+  <Base-dialog
+    title="操作提示:"
+    :disabledBtn="disabledBtn"
+    :isShow.sync="isShow"
+    @submit="submitForm"
+    @close="close"
+  >
+    <el-form
+      :model="formData"
+      ref="formData"
+      label-width="80px"
+      label-position="right"
+    >
+      <el-form-item
+        label="作弊原因"
+        prop="cheating_reason"
+        :rules="[
+          {
+            required: true,
+            message: '请填写作弊原因',
+            trigger: ['blur', 'change'],
+          },
+        ]"
+      >
+        <el-input
+          v-model="formData.cheating_reason"
+          type="textarea"
+          :rows="4"
+          placeholder="请输入作弊原因"
+        ></el-input>
+      </el-form-item>
+      <ul style="padding-left: 80px">
+        <li
+          class="li_sty"
+          @click="uploadText(item.label)"
+          v-for="(item, index) in msgTitle"
+          :key="index"
+        >
+          {{ item.label }}
+        </li>
+      </ul>
+    </el-form>
+  </Base-dialog>
+</template>
+
+<script>
+export default {
+  props: {
+    vidBoxHours: {
+      type: Boolean,
+      default: false,
+    },
+    disabledBtn: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      msgTitle: [
+        { label: "学习拍照异常", value: 1 },
+        {
+          label: "学习拍照太黑无法识别人像,请确保拍照光线充足并拍到全脸",
+          value: 2,
+        },
+        {
+          label: "学习拍照太模糊无法识别人像,请确保拍照光线充足并拍到全脸",
+          value: 3,
+        },
+        {
+          label: "学习拍照人像不全无法识别,请确保拍照光线充足并拍到全脸",
+          value: 4,
+        },
+      ],
+      formData: {
+        cheating_reason: "",
+      },
+    };
+  },
+  methods: {
+    submitForm() {
+      this.$refs.formData.validate((valid) => {
+        if (valid) {
+          this.$emit("submit", this.formData.cheating_reason);
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    uploadText(msg) {
+      this.formData.cheating_reason = msg;
+    },
+    close() {
+      this.$emit("close");
+    },
+  },
+  computed: {
+    isShow: {
+      get() {
+        return this.vidBoxHours;
+      },
+      set(val) {
+        this.$emit("update:vidBoxHours", false);
+      },
+    },
+  },
+  watch: {
+    vidBoxHours(val) {
+      if (val === false) {
+        this.uploadText("");
+      } else {
+        this.$nextTick(() => {
+          this.$refs.formData.clearValidate();
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style  lang="less" scoped>
+.li_sty {
+  cursor: pointer;
+  transition: all 0.3s;
+  background-color: #eee;
+  padding: 0px 10px;
+  margin-bottom: 6px;
+  font-size: 12px;
+  line-height: 26px;
+  display: table;
+  &:hover {
+    box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, 0.2);
+  }
+}
+</style>

+ 396 - 0
src/views/classHoursReview/component/LessonTable.vue

@@ -0,0 +1,396 @@
+<template>
+  <div>
+    <el-table
+      :default-expand-all="true"
+      border
+      :data="tabledata"
+      style="width: 100%; border-radius: 4px; overflow: hidden"
+      :header-cell-style="{
+        'background-color': '#F5F5F5',
+        padding: '8px',
+        color: '#666',
+      }"
+    >
+      <el-table-column label="节/卷" type="expand" width="70px">
+        <template slot-scope="scope">
+          <div class="dis_flexs">
+            <ul
+              style="flex: 1"
+              v-if="
+                scope.row.userStudyRecordPhotoList &&
+                scope.row.userStudyRecordPhotoList.length
+              "
+            >
+              <li
+                v-for="(its, inds) in scope.row.userStudyRecordPhotoList"
+                :key="inds"
+                class="liImgs"
+              >
+                <el-image
+                  style="width: 100%; height: 100%"
+                  :src="$methodsTools.splitImgHost(its.photo)"
+                  :preview-src-list="[$methodsTools.splitImgHost(its.photo)]"
+                >
+                </el-image>
+                <div class="abos">
+                  {{ $methodsTools.onlyForma(its.createTime) }}
+                </div>
+              </li>
+              <div style="clear: both"></div>
+            </ul>
+            <p v-else style="text-align: center; width: 100%">暂无拍照数据</p>
+            <div
+              class="styFlex"
+              v-if="
+                (periodStatus === 0 ||
+                  periodStatus === 2 ||
+                  periodStatus === 3) &&
+                scope.row.periodStatus === 1
+              "
+            >
+              <div>
+                <el-checkbox
+                  class="checkboxList"
+                  :label="scope.row.periodStatusId"
+                  :disabled="
+                    periodStatus === 3
+                      ? false
+                      : scope.row.status !== 2
+                      ? true
+                      : false
+                  "
+                  ><br
+                /></el-checkbox>
+              </div>
+              <el-button
+                :disabled="scope.row.status !== 2"
+                class="btnstyles"
+                size="small"
+                type="success"
+                :loading="disabledBtn"
+                @click="changeStatus(scope.row.periodStatusId, 1)"
+                >通过</el-button
+              >
+              <el-button
+                :disabled="scope.row.status !== 2"
+                class="btnstyles"
+                size="small"
+                type="danger"
+                @click="changeStatus(scope.row.periodStatusId, 0)"
+                >作弊</el-button
+              >
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column
+        v-for="(item, index) in tableSet"
+        :width="item.width"
+        :key="index"
+        :label="item.label"
+        align="center"
+      >
+        <template slot-scope="scope2">
+          <span v-if="item.scope === 'select'">
+            <span
+              v-for="(k, ds) in item.options"
+              :key="ds"
+              :style="
+                scope2.row[item.prop] === 0
+                  ? 'color:red;'
+                  : scope2.row[item.prop] === 2
+                  ? 'color:#0047D0;'
+                  : scope2.row[item.prop] === 1
+                  ? 'color:#67C23A;'
+                  : ''
+              "
+            >
+              {{ k.value == scope2.row[item.prop] ? k.label : "" }}
+            </span>
+          </span>
+          <div v-else-if="item.scope === 'activeNum'">
+            <el-select
+              v-model="scope2.row[item.prop]"
+              placeholder="请选择"
+              @change="getNewListchapt(scope2.$index, $event, scope2.row)"
+            >
+              <el-option
+                v-for="(items, indexs) in scope2.row['numList']"
+                :key="indexs"
+                :label="'第' + items + '次审核记录'"
+                :value="items"
+              >
+              </el-option>
+            </el-select>
+          </div>
+          <span v-else-if="item.scope === 'typeOptions'">
+            <span v-for="(is, ds) in item.options" :key="ds">
+              <span v-if="is.value === scope2.row[item.prop]">{{
+                is.label
+              }}</span>
+            </span>
+          </span>
+          <span v-else-if="item.scope === 'aTime'">
+            {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
+          </span>
+          <span v-else-if="item.scope === 'durTime' && scope2.row.type !== 5">
+            {{ $methodsTools.secondToDate(scope2.row[item.prop], false) }}
+          </span>
+          <div v-else-if="item.scope === 'aTimeSE'">
+            <span
+              v-if="
+                scope2.row['type'] === 3 &&
+                scope2.row['durationTime'] &&
+                scope2.row['studyStartTime'] &&
+                scope2.row['studyEndTime']
+              "
+              :style="comput(scope2.row)"
+            >
+              {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
+            </span>
+            <span v-else>
+              {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
+            </span>
+          </div>
+          <span v-else> {{ scope2.row[item.prop] }} </span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <Cheat-dialog
+      :vidBoxHours.sync="vidBoxHours"
+      @submit="submit"
+    ></Cheat-dialog>
+  </div>
+</template>
+
+<script>
+import CheatDialog from "./CheatDialog.vue";
+export default {
+  props: {
+    tabledata: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+  },
+  inject: ["getPeriodStatus", "getUserInfo", "getAllIds"],
+  data() {
+    return {
+      tableSet: [
+        {
+          label: "选择",
+          prop: "numIndex",
+          scope: "activeNum",
+          width: "180px",
+        },
+        {
+          label: "姓名",
+          prop: "realName",
+        },
+        {
+          label: "标题",
+          prop: "typeName",
+        },
+        {
+          label: "类型",
+          prop: "type",
+          scope: "typeOptions",
+          width: "90px",
+          options: [
+            {
+              label: "节",
+              value: 3,
+            },
+            {
+              label: "试卷",
+              value: 4,
+            },
+            {
+              label: "模块卷",
+              value: 5,
+            },
+          ],
+        },
+        {
+          label: "节时长",
+          prop: "durationTime",
+          width: "120px",
+          scope: "durTime",
+        },
+        {
+          label: "开始时间",
+          prop: "studyStartTime",
+          scope: "aTimeSE",
+        },
+        {
+          label: "结束时间",
+          prop: "studyEndTime",
+          scope: "aTimeSE",
+        },
+        {
+          label: "审核状态",
+          prop: "status",
+          scope: "select",
+          width: "100px",
+          options: [
+            {
+              label: "待审核",
+              value: 2,
+            },
+            {
+              label: "通过",
+              value: 1,
+            },
+            {
+              label: "作弊",
+              value: 0,
+            },
+            {
+              label: "待重修",
+              value: 3,
+            },
+          ],
+        },
+        {
+          label: "审核人",
+          prop: "auditUserName",
+          width: "100px",
+        },
+        {
+          label: "审核时间",
+          prop: "auditTime",
+          scope: "aTime",
+        },
+      ],
+      disabledBtn: false,
+      vidBoxHours: false,
+      formData: {
+        status: "",
+        id: "",
+      },
+    };
+  },
+  methods: {
+    submit(text) {
+      this.formData.auditReason = text;
+      this.$api
+        .editGradeUsereditPeriode(this.formData)
+        .then((res) => {
+          this.$message.success("修改成功");
+          this.vidBoxHours = false;
+          if (this.allIds.length == 1) {
+            this.$router.push({
+              name: "ListOfhoursToBeReviewed",
+            });
+          }
+          this.getUserInfo(true);
+        })
+        .finally(() => {
+          this.disabledBtn = false;
+        });
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    comput(item) {
+      var ast = item.studyEndTime - item.studyStartTime;
+      if (ast < item.durationTime) {
+        return "color:red;";
+      } else {
+        return "";
+      }
+    },
+    getNewListchapt(index, int, item) {
+      let { courseId, moduleId, chapterId, userId, goodsId, gradeId } = item;
+      let data = {
+        courseId: courseId,
+        moduleId,
+        chapterId,
+        numIndex: int,
+        userId,
+        goodsId,
+        gradeId,
+      };
+      if (item.type === 3) {
+        data.sectionId = item.id;
+      }
+      if (item.type === 4) {
+        data.examId = item.id;
+      }
+      this.$api.inquireGradegradelistPeriodAuditStatus(data).then((res) => {
+        this.$set(this.tabledata, index, res.data);
+      });
+    },
+    changeStatus(id, status) {
+      this.formData = {
+        status,
+        id,
+      };
+      if (status == 0) {
+        this.vidBoxHours = true;
+      } else {
+        this.submit();
+      }
+    },
+  },
+  computed: {
+    periodStatus() {
+      return this.getPeriodStatus();
+    },
+    allIds() {
+      return this.getAllIds();
+    },
+  },
+  components: {
+    CheatDialog,
+  },
+};
+</script>
+
+<style  lang="less" scoped>
+.liImgs {
+  float: left;
+  width: 210px;
+  height: 280px;
+  margin-right: 16px;
+  margin-bottom: 16px;
+  position: relative;
+  border-radius: 8px;
+  overflow: hidden;
+  .abos {
+    position: absolute;
+    bottom: 0px;
+    width: 100%;
+    height: 32px;
+    line-height: 32px;
+    font-size: 14px;
+    color: #fff;
+    text-align: center;
+    background-color: rgba(51, 51, 51, 0.7);
+  }
+}
+.dis_flexs {
+  display: flex;
+  align-items: center;
+  padding: 10px 18px;
+  ul {
+    margin-bottom: 0px;
+  }
+}
+.styFlex {
+  width: 80px;
+  text-align: center;
+}
+.checkboxList {
+  margin-bottom: 6px;
+  &/deep/.el-checkbox__label {
+    display: none;
+  }
+}
+.btnstyles {
+  margin-left: 0px;
+  margin-bottom: 10px;
+}
+</style>

+ 58 - 0
src/views/classHoursReview/component/ModulTable.vue

@@ -0,0 +1,58 @@
+<template>
+  <div>
+    <el-table
+      :default-expand-all="true"
+      border
+      :data="tabledata"
+      style="width: 100%; border-radius: 4px; overflow: hidden"
+      :header-cell-style="{
+        'background-color': '#CCDDF7',
+        padding: '8px',
+        color: '#0047D0',
+        'border-right-color': '#0047D0',
+        'border-left-color': '#0047D0',
+      }"
+    >
+      <el-table-column label="模块" type="expand" width="70px">
+        <template slot-scope="scope">
+          <Chapter-table
+            v-if="scope.row.classPeriods.length"
+            :tabledata="scope.row.classPeriods"
+          ></Chapter-table>
+          <Chapter-table
+            v-if="scope.row.arr"
+            label="卷"
+            :tabledata="scope.row.arr"
+          ></Chapter-table>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="realName" label="姓名">
+      </el-table-column>
+      <el-table-column align="center" prop="typeName" label="模块标题">
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import ChapterTable from "./ChapterTable.vue";
+export default {
+  props: {
+    tabledata: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+  },
+  data() {
+    return {};
+  },
+  components: {
+    ChapterTable,
+  },
+};
+</script>
+
+<style>
+</style>

+ 521 - 0
src/views/classHoursReview/component/StudyTables.vue

@@ -0,0 +1,521 @@
+<template>
+  <div class="studyRecordTable">
+    <div class="studyStyle" :class="{ 'isFixed': headerFixed }" :style="{'left':left}">
+      <div class="a_style">
+        <i></i>
+        <span>视频审核进度</span>
+        <div class="flex_style_study">
+          <div class="num_style" style="color: #0047d0">
+            待审:{{ userData.pending }}节
+          </div>
+          <div class="num_style" style="color: #e53935">
+            作弊:{{ userData.cheat }}节
+          </div>
+          <div class="num_style" style="color: #43a047">
+            通过:{{ userData.pass }}节
+          </div>
+          <div style="clear: both"></div>
+        </div>
+      </div>
+      <div class="a_style">
+        <i></i>
+        <span>做题审核进度</span>
+        <div class="flex_style_study">
+          <div class="num_style" style="color: #0047d0">
+            待审:{{ userData.examPending }}节
+          </div>
+          <div class="num_style" style="color: #e53935">
+            作弊:{{ userData.examCheat }}节
+          </div>
+          <div class="num_style" style="color: #43a047">
+            通过:{{ userData.examPass }}节
+          </div>
+          <div style="clear: both"></div>
+        </div>
+      </div>
+      <div class="a_style" style="width: 280px">
+        <i></i>
+        <span>学时审批状态</span>
+        <div class="flex_style_study">
+          <div class="num_style" style="color: #0047d0">
+            {{
+                ["不可审核", "未通过", "通过审核", "待审核", "审核中"][
+                periodStatus + 1
+                ]
+            }}
+          </div>
+          <div style="clear: both"></div>
+        </div>
+      </div>
+      <div class="s_sd">
+        <template v-if="periodStatus === 2">
+          <el-checkbox :disabled="!allIds.length" :indeterminate="isIndeterminate" v-model="checkAll"
+            @change="handleCheckAllChange">待审全选</el-checkbox>
+          <el-button style="margin-left: 10px" size="mini" type="success" @click="getChangeStatus(1)">勾选通过</el-button>
+          <el-button size="mini" type="danger" @click="getChangeStatus(2)">勾选作弊</el-button>
+        </template>
+
+        <template v-if="periodStatus === 3">
+          <el-button style="margin-left: 10px" size="mini" @click="checkBack">勾选数据,打回待审核状态</el-button>
+          <el-button size="mini" type="warning" @click="approvedOK = true">确认审核通过结果</el-button>
+        </template>
+        <!-- <el-button
+          v-if="periodStatus === 1"
+          style="margin-left: 10px"
+          size="mini"
+          @click="backToAudit"
+          >打回待审核状态</el-button
+        > -->
+      </div>
+    </div>
+
+    <el-checkbox-group v-model="checkList" @change="handleCheckedCitiesChange">
+      <component :is="keys[key]" v-for="key in Object.keys(tablesData)" :key="key" :tabledata="tablesData[key]"
+        :label="key == 5 ? '卷' : '章'"></component>
+    </el-checkbox-group>
+
+    <Cheat-dialog :disabledBtn="disabledBtn" :vidBoxHours.sync="vidBoxHours" @close="loadingClose" @submit="
+      (reason) => {
+        submitOK(2, reason);
+      }
+    "></Cheat-dialog>
+    <Base-dialog title="操作提示:" :disabledBtn="disabledBtn" :isShow.sync="through" @close="loadingClose" @submit="
+      () => {
+        submitOK(1);
+      }
+    ">
+      <div>
+        确定所勾选的内容,审核结果为【通过】?<br />
+        确认后,初审不可再修改,请检查清楚再操作!
+      </div>
+    </Base-dialog>
+    <Base-dialog title="操作提示:" :disabledBtn="disabledBtn" :isShow.sync="popback" @close="loadingClose"
+      @submit="uploadForm">
+      <div>
+        <div style="color: red">
+          <h4 style="margin: 0px">当前勾选了{{ checkList.length }}条数据:</h4>
+          <ul style="margin: 0px 0px 6px; max-height: 500px; overflow: auto">
+            <li v-for="(item, index) in checkList" :key="index">
+              {{ index + 1 }}.{{ getSecName(item) }}
+            </li>
+          </ul>
+        </div>
+        <div style="text-align: center; font-weight: bold">
+          所选数据,确定要打回待审核状态吗?<br />
+          打回后,重新走审核流程,请慎重操作。
+        </div>
+      </div>
+    </Base-dialog>
+    <Base-dialog title="操作提示:" :disabledBtn="disabledBtn" :isShow.sync="approvedOK" @close="loadingClose"
+      @submit="approvedOKFunc">
+      <div>
+        <div style="color: red">
+          <h4 style="margin: 0px">确认审核通过结果后:</h4>
+          <ul style="margin: 0px 0px 6px">
+            <li>
+              (1)有做官方接口的,自动触发【学时官方推送】<br />
+              (2)公开【学习学时记录-学时记录】按钮,权限人可查看【审核结果】<br />
+              (3)有匹配的预约考试,可走预约流程
+            </li>
+          </ul>
+        </div>
+        <div style="font-weight: bold; margin-top: 20px">
+          确认提交审核通过结果?<br />
+          确认后,不能再修改,请慎重操作。
+        </div>
+      </div>
+    </Base-dialog>
+  </div>
+</template>
+
+<script>
+import ModulTable from "./ModulTable.vue";
+import ChapterTable from "./ChapterTable.vue";
+import LessonTable from "./LessonTable.vue";
+import CheatDialog from "./CheatDialog.vue";
+import { rollBackPeriod } from "@/api/education/classManageMent";
+import { debounce } from '@/utils'
+import { mapGetters } from "vuex";
+export default {
+  props: {
+    tablesData: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+    userData: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+    setData: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+    getUserInfo: {
+      type: Function,
+      default: () => { },
+    },
+  },
+  provide() {
+    return {
+      getPeriodStatus: () => this.periodStatus,
+      getUserInfo: this.getUserInfo,
+      getAllIds: () => this.allIds,
+    };
+  },
+  data() {
+    return {
+      checkList: [],
+      allIds: [],
+      checkAll: false,
+      isIndeterminate: false,
+      vidBoxHours: false,
+      through: false,
+      popback: false,
+      approvedOK: false,
+      disabledBtn: false,
+      formData: {
+        cheating_reason: "",
+      },
+      statusPop: "", //1单个2批量
+      rules: {
+        cheating_reason: [
+          {
+            required: true,
+            message: "请填写作弊原因",
+            trigger: ["blur", "change"],
+          },
+        ],
+      },
+      msgTitle: [
+        { label: "学习拍照异常", value: 1 },
+        {
+          label: "学习拍照太黑无法识别人像,请确保拍照光线充足并拍到全脸",
+          value: 2,
+        },
+        {
+          label: "学习拍照太模糊无法识别人像,请确保拍照光线充足并拍到全脸",
+          value: 3,
+        },
+        {
+          label: "学习拍照人像不全无法识别,请确保拍照光线充足并拍到全脸",
+          value: 4,
+        },
+      ],
+      allType3List: [],
+      offsetTop: 0,
+      offsetHeight: 0,
+      headerFixed: false
+    };
+  },
+  methods: {
+    handleScroll() {
+      // 得到页面滚动的距离
+      let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
+      // 判断页面滚动的距离是否大于吸顶元素的位置
+      this.headerFixed = scrollTop > (this.offsetTop + this.offsetHeight);
+    },
+    submitAllSlect(reason) {
+      this.submitOK(2, reason);
+    },
+    handleCheckedCitiesChange(value) {
+      let checkedCount = value.length;
+      if (checkedCount) {
+        this.checkAll = checkedCount === this.allIds.length;
+      } else {
+        this.checkAll = false;
+      }
+      this.isIndeterminate =
+        checkedCount > 0 && checkedCount < this.allIds.length;
+    },
+    handleCheckAllChange(val) {
+      this.checkList = val ? this.allIds : [];
+      this.isIndeterminate = false;
+    },
+    getAllId(data) {
+      if (!data || !data.length) {
+        return;
+      }
+      data.forEach((ele) => {
+        if (ele.type == 3 || ele.type == 4) {
+          this.allType3List.push(ele);
+          ele.status === 2 && this.allIds.push(ele.periodStatusId);
+        } else {
+          if (ele.type == 1 && ele.arr) {
+            let item = ele.arr[0];
+            this.allType3List.push(item);
+            item.status === 2 && this.allIds.push(item.periodStatusId);
+          }
+          this.getAllId(
+            ele.type == 1 ? ele.classPeriods : ele.classPeriodSectionList
+          );
+        }
+      });
+    },
+    getChangeStatus(int) {
+      if (!this.checkList.length) {
+        this.$message.warning("请勾选需要操作的待审核数据");
+        return;
+      }
+      var data = {
+        gradeId: Number(this.setData.id),
+        userId: Number(this.setData.userId),
+        goodsId: Number(this.setData.goodsId),
+      };
+      if (int === 1) {
+        data.status = 1;
+        this.through = true;
+      }
+      if (int === 2) {
+        data.status = 0;
+        this.statusPop = 2;
+        this.formData.cheating_reason = "";
+        this.vidBoxHours = true;
+      }
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    submitOK(int, msg) {
+      this.disabledBtn = true;
+      var data = {
+        gradeId: Number(this.setData.id),
+        userId: Number(this.setData.userId),
+        goodsId: Number(this.setData.goodsId),
+        ids: this.checkList,
+      };
+      if (int === 1) {
+        data.status = 1;
+      }
+      if (int === 2) {
+        data.auditReason = msg;
+        data.status = 0;
+      }
+      this.$api
+        .editGradeUsereditPeriodeAll(data)
+        .then((res) => {
+          if (int === 1) {
+            this.$message.success("状态全部通过修改成功");
+            this.through = false;
+            this.checkAll && this.goReview();
+          }
+          if (int === 2) {
+            this.$message.success("状态全部作弊修改成功");
+            this.vidBoxHours = false;
+          }
+          this.checkList = [];
+          this.isIndeterminate = false;
+          this.checkAll = false;
+          this.getUserInfo(true);
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    getSecName(id) {
+      try {
+        return this.allType3List.find((e) => e.periodStatusId == id).typeName;
+      } catch (error) {
+        return "";
+      }
+    },
+    uploadText(msg) {
+      this.formData.cheating_reason = msg;
+    },
+    checkBack() {
+      if (!this.checkList.length) {
+        this.$message.warning("请勾选数据");
+        return;
+      }
+      this.popback = true;
+    },
+    // 打回审核状态
+    uploadForm() {
+      this.disabledBtn = true;
+      let data = {
+        gradeId: Number(this.setData.id),
+        userId: Number(this.setData.userId),
+        goodsId: Number(this.setData.goodsId),
+        ids: this.checkList,
+      };
+      this.$api
+        .editGradeUsereditrollbackPeriod(data)
+        .then((res) => {
+          this.checkList = []; //勾选列表
+          this.isIndeterminate = false; //待审半选
+          this.checkAll = false; //全选状态
+          this.getUserInfo(true);
+          this.$message.success("已打回待审核状态");
+          this.popback = false;
+          this.goReview();
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    // 确认审核结果
+    approvedOKFunc() {
+      this.disabledBtn = true;
+      let data = {
+        gradeId: Number(this.setData.id),
+        userId: Number(this.setData.userId),
+        goodsId: Number(this.setData.goodsId),
+      };
+      this.$api
+        .editGradeUsereditrollconfirmPeriod(data)
+        .then((res) => {
+          this.getUserInfo(true);
+          this.$message.success("审核通过");
+          this.approvedOK = false;
+          this.goReview();
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    backToAudit() {
+      this.$confirm("此操作将打回审核状态, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          rollBackPeriod({ orderGoodsId: this.userData.orderGoodsId }).then(
+            (res) => {
+              this.getUserInfo(true);
+              this.$message.success("已打回待审核状态");
+            }
+          );
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    goReview() {
+      this.$router.push({
+        name: "ListOfhoursToBeReviewed",
+      });
+    },
+  },
+
+  created() {
+    this.keys = {
+      1: "ModulTable",
+      2: "ChapterTable",
+      5: "ChapterTable",
+      6: "LessonTable",
+    };
+  },
+  components: { ModulTable, LessonTable, ChapterTable, CheatDialog },
+  watch: {
+    tablesData: {
+      handler() {
+        this.allIds = [];
+        for (const key in this.tablesData) {
+          this.getAllId(this.tablesData[key]);
+        }
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  computed: {
+    periodStatus() {
+      return this.userData.periodStatus;
+    },
+    ...mapGetters(["sidebar"]),
+    left() {
+      return this.sidebar.opened ? '206px' : '60px'
+    }
+  },
+  mounted() {
+    this.$nextTick(function () {
+      let header = document.getElementsByClassName("studyStyle")[0];
+      this.offsetTop = header.offsetTop;
+      this.offsetHeight = header.offsetHeight;
+    });
+    window.addEventListener('scroll', debounce(this.handleScroll, 50));
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.studyRecordTable {
+  .studyStyle {
+    margin: 16px 0;
+    display: flex;
+    align-items: center;
+
+    &>.a_style {
+      display: flex;
+      align-items: center;
+      margin-right: 16px;
+      padding: 11px 16px;
+      box-shadow: 0px 0px 8px 0px rgba(217, 217, 217, 0.8);
+      border-radius: 4px;
+      height: 40px;
+      width: 440px;
+      user-select: none;
+
+      i {
+        width: 2px;
+        height: 18px;
+        display: inline-block;
+        background-color: #0047d0;
+        margin-right: 8px;
+      }
+
+      span {
+        color: #666;
+        font-weight: bold;
+      }
+
+      .flex_style_study {
+        flex: 1;
+      }
+
+      .num_style {
+        float: right;
+        font-size: 14px;
+        margin-left: 14px;
+      }
+    }
+
+    .s_sd {
+      flex: 1;
+      justify-content: flex-end;
+      display: flex;
+      align-items: center;
+      flex-shrink: 0;
+
+      .dis_colu {
+        height: 55px;
+        margin-right: 14px;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-around;
+        font-size: 14px;
+      }
+    }
+  }
+
+  .isFixed {
+    position: fixed;
+    top: 84px;
+    right: 0;
+    z-index: 10;
+    background: #fff;
+    padding: 0 20px;
+    margin: 0;
+  }
+
+}
+</style>

+ 89 - 0
src/views/classHoursReview/index.vue

@@ -0,0 +1,89 @@
+<template>
+  <div id="classHoursReviews">
+    <el-tabs
+      v-model="parseSession.activeData"
+      :closable="parseSession.options.length > 1"
+      @tab-remove="removeTab"
+      :before-leave="beforeLeave"
+    >
+      <el-tab-pane
+        lazy
+        v-for="(item, index) in parseSession.options"
+        :key="item.keyId"
+        :label="item.realName + '-' + item.goodsName"
+        :name="item.keyId"
+        ><study-times :key="index" :setData="item" @removeTab="removeTab"
+      /></el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import studyTimes from "./studyTimes.vue";
+export default {
+  name: "ClassHoursReviews",
+  components: { studyTimes },
+  data() {
+    return {
+      parseSession: {
+        options: [],
+      },
+    };
+  },
+  created() {
+    this.init();
+  },
+  activated() {
+    this.init();
+  },
+  methods: {
+    init() {
+      const SESSION = sessionStorage.getItem("hoursAudit");
+      if (SESSION) {
+        this.parseSession = JSON.parse(SESSION);
+      } else {
+        console.log("错误处理");
+      }
+    },
+    beforeLeave(activeName) {
+      try {
+        console.log(activeName, "activeName处理");
+        this.parseSession.activeData = activeName;
+        sessionStorage.setItem("hoursAudit", JSON.stringify(this.parseSession));
+        console.log("处理成功");
+        return true;
+      } catch (error) {
+        console.log("错误处理");
+        return false;
+      }
+    },
+    removeTab(targetName) {
+      let tabs = JSON.parse(JSON.stringify(this.parseSession.options));
+      let activeName = this.parseSession.activeData;
+      if (activeName === targetName) {
+        tabs.forEach((tab, index) => {
+          if (tab.keyId === targetName) {
+            let nextTab = tabs[index + 1] || tabs[index - 1];
+            if (nextTab) {
+              activeName = nextTab.keyId;
+            }
+          }
+        });
+      }
+      let ary = tabs.filter((tab) => tab.keyId !== targetName);
+      this.$set(this.parseSession, "options", ary);
+      this.$set(this.parseSession, "activeData", activeName);
+    },
+  },
+  destroyed() {
+    sessionStorage.removeItem("hoursAudit");
+    console.log("清除");
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/ .el-tabs__content{
+  padding: 6px;
+}
+</style>

+ 402 - 0
src/views/classHoursReview/studyTimes.vue

@@ -0,0 +1,402 @@
+<template>
+  <div id="studyTimes">
+    <StudentInfo :userData="userData"></StudentInfo>
+    <Study-tables
+      class="box"
+      ref="study"
+      v-if="tablesData"
+      :tablesData="tablesData"
+      :userData="userData"
+      :setData="setData"
+      :getUserInfo="getUserInfo"
+    ></Study-tables>
+  </div>
+</template>
+
+<script>
+import StudyTables from "./component/StudyTables.vue";
+import StudentInfo from "@/components/Study/StudentInfo.vue";
+export default {
+  props: ["setData"],
+  data() {
+    return {
+      loading: false,
+      userData: {},
+      setTimeDOM: null, //定时器
+      tablesData: undefined,
+    };
+  },
+  created() {
+    this.$api
+      .inquireGradegradelockPeriodStatus({
+        gradeId: Number(this.setData.id),
+        userId: Number(this.setData.userId),
+        goodsId: Number(this.setData.goodsId),
+      })
+      .then((res) => {
+        if (res.msg) {
+          this.$alert(`${res.msg}正在操作该页面,请关闭当前页`, "提示", {
+            dangerouslyUseHTMLString: true,
+            showClose: false,
+          }).then((result) => {
+            const SESSION = sessionStorage.getItem("hoursAudit");
+            let parseSession = {};
+            if (SESSION) {
+              parseSession = JSON.parse(SESSION);
+            }
+            if (parseSession.options.length > 1) {
+              this.$emit("removeTab", this.setData.keyId);
+            } else {
+              this.$store
+                .dispatch("tagsView/delView", this.$route)
+                .then((results) => {
+                  this.$router.go(-1);
+                });
+            }
+          });
+        } else {
+          this.getSetTime();
+          // 每10秒调用一次 锁定页面
+          this.setTimeDOM = setInterval(() => {
+            this.getSetTime();
+          }, 10000);
+        }
+      });
+  },
+  mounted() {
+    this.getUserInfo(true);
+  },
+  methods: {
+    /**
+     * 每10秒调用一次 锁定页面
+     */
+    getSetTime() {
+      this.$api
+        .inquireGradegradelockPeriod({
+          gradeId: Number(this.setData.id),
+          userId: Number(this.setData.userId),
+          goodsId: Number(this.setData.goodsId),
+        })
+        .then((res) => {});
+    },
+    /**
+     *
+     * @param {Number} index 节索引
+     * @param {Number} int 节记录索引
+     * @param {Object} item 节完整数据
+     * @remards 节
+     */
+    getNewList(index, int, item) {
+      let data = {
+        courseId: item.courseId,
+        moduleId: item.moduleId,
+        chapterId: item.chapterId,
+        numIndex: int,
+        userId: this.setData.userId,
+        goodsId: this.setData.goodsId,
+        gradeId: this.setData.id,
+      };
+      if (item.type === 3) {
+        data.sectionId = item.id;
+      }
+      if (item.type === 4) {
+        data.examId = item.id;
+      }
+      this.$api.inquireGradegradelistPeriodAuditStatus(data).then((res) => {
+        this.$set(this.listData.tableData3, index, res.data);
+        this.getUserInfo();
+      });
+    },
+    /**
+     *
+     * @param {Number} a 章索引
+     * @param {Number} b 节索引
+     * @param {Number} int 节记录索引
+     * @param {Object} item 节完整数据
+     * @remards 章 节
+     */
+    getNewListchapt(a, b, int, item) {
+      let data = {
+        courseId: item.courseId,
+        moduleId: item.moduleId,
+        chapterId: item.chapterId,
+        numIndex: int,
+        userId: this.setData.userId,
+        goodsId: this.setData.goodsId,
+        gradeId: this.setData.id,
+      };
+      if (item.type === 3) {
+        data.sectionId = item.id;
+      }
+      if (item.type === 4) {
+        data.examId = item.id;
+      }
+      this.$api.inquireGradegradelistPeriodAuditStatus(data).then((res) => {
+        this.$set(
+          this.listData.tableData2[a].classPeriodSectionList,
+          b,
+          res.data
+        );
+        this.getUserInfo();
+      });
+    },
+    /**
+     *
+     * @param {Number} a 模块索引
+     * @param {Number} b 章索引
+     * @param {Number} c 节索引
+     * @param {Number} int 节记录索引
+     * @param {Object} item 节完整数据
+     * @remards 模块 章 节
+     */
+    getNewListMores(a, b, c, int, item) {
+      let data = {
+        courseId: item.courseId,
+        moduleId: item.moduleId,
+        chapterId: item.chapterId,
+        numIndex: int,
+        userId: this.setData.userId,
+        goodsId: this.setData.goodsId,
+        gradeId: this.setData.id,
+      };
+      if (item.type === 3) {
+        data.sectionId = item.id;
+      }
+      if (item.type === 4) {
+        data.examId = item.id;
+      }
+      this.$api.inquireGradegradelistPeriodAuditStatus(data).then((res) => {
+        this.$set(
+          this.listData.tableData1[a].classPeriods[b].classPeriodSectionList,
+          c,
+          res.data
+        );
+        this.getUserInfo();
+      });
+    },
+    //获取用户信息
+    getUserInfo(isS = false) {
+      this.$api
+        .inquireGradegradelistUserlistPeriod({
+          gradeId: this.setData.id,
+          userId: this.setData.userId,
+          goodsId: this.setData.goodsId,
+        })
+        .then((res) => {
+          this.userData = res.rows[0];
+          isS && this.search();
+        });
+    },
+    changeData(data) {
+      let obj = {};
+      data.forEach((e) => {
+        if (e.type == 5) {
+          e.classPeriodSectionList = [JSON.parse(JSON.stringify(e))];
+        }
+        // 区分章和模块卷
+        if (e.type == 1) {
+          e.classPeriods &&
+            e.classPeriods.forEach((ele, i) => {
+              if (ele.type == 5) {
+                ele.classPeriodSectionList = [JSON.parse(JSON.stringify(ele))];
+                e.arr = [ele];
+                e.classPeriods.splice(i, 1);
+              }
+            });
+        }
+        (obj[e.type] || (obj[e.type] = [])).push(e);
+      });
+      if (obj["3"]) {
+        obj["6"] = obj["3"];
+        delete obj["3"];
+      }
+      return obj;
+    },
+    //获取学时审核数据
+    search() {
+      let data = {
+        gradeId: this.setData.id,
+        userId: this.setData.userId,
+        goodsId: this.setData.goodsId,
+      };
+      this.loading = true;
+      this.$api
+        .inquireGradegradelistPeriodAudit(data)
+        .then((res) => {
+          this.tablesData = this.changeData(res.rows);
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+  },
+  components: {
+    StudyTables,
+    StudentInfo,
+  },
+  /**
+   * 离开页面前销毁定时器
+   */
+  beforeDestroy() {
+    if (this.setTimeDOM) {
+      clearInterval(this.setTimeDOM);
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+.top_style {
+  background: #ffffff;
+  box-shadow: 0px 0px 8px 0px rgba(217, 217, 217, 0.8);
+  border-radius: 8px;
+  padding: 8px 16px;
+  & > header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 48px;
+    line-height: 48px;
+    & > .left {
+      display: flex;
+      align-items: center;
+      i {
+        display: inline-block;
+        width: 2px;
+        height: 18px;
+        background: #0c5dfb;
+        margin-right: 8px;
+      }
+      span {
+        color: #666;
+        font-weight: bold;
+      }
+    }
+
+    & > span {
+      font-size: 14px;
+    }
+  }
+  & > .info_img {
+    display: flex;
+    height: 210px;
+    ul {
+      width: 320px;
+      li {
+        margin-bottom: 12px;
+        font-size: 14px;
+      }
+    }
+    .img_by {
+      flex: 1;
+      display: flex;
+      align-items: center;
+      .pos_bottom {
+        position: absolute;
+        z-index: 1;
+        bottom: 0px;
+        width: 100%;
+        height: 32px;
+        background-color: rgba(53, 53, 53, 0.6);
+        text-align: center;
+        color: #fff;
+        font-size: 16px;
+        line-height: 32px;
+      }
+      & > .photoSty1 {
+        width: 152px;
+        height: 208px;
+        position: relative;
+        overflow: hidden;
+        border-radius: 8px;
+        background-color: #f5f5f5;
+        margin-right: 75px;
+        & > img {
+          width: 106px;
+          height: 150px;
+          margin: 29px auto 0px;
+          display: block;
+        }
+      }
+      & > .photoSty2 {
+        width: 328px;
+        height: 208px;
+        position: relative;
+        overflow: hidden;
+        border-radius: 8px;
+        background-color: #f5f5f5;
+        margin-right: 75px;
+        & > img {
+          width: 243px;
+          height: 154px;
+          margin: 27px auto 0px;
+          display: block;
+        }
+        &:last-of-type {
+          margin-right: 0px;
+        }
+      }
+    }
+  }
+}
+/deep/ .el-table__expanded-cell {
+  background: #f5f5f5;
+}
+/deep/ .el-table__expanded-cell {
+  padding: 0px !important;
+}
+
+#studyTimes {
+  display: flex;
+  flex-direction: column;
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.box {
+  flex: 1;
+  overflow: hidden;
+}
+</style>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 561 - 538
src/views/index.vue


+ 10 - 6
src/views/resource/bankManagement/testPaperManagement/PaperSort.vue

@@ -60,12 +60,6 @@
           @click="handelClick(item.key)"
           >更多</el-button
         >
-        <p
-          style="color: red; padding-left: 76px"
-          v-if="item.key === 'caseQuestion'"
-        >
-          案例题是主观题,不算作分数,所以会随机切换
-        </p>
       </li>
     </ul>
     <Base-dialog
@@ -239,7 +233,17 @@ export default {
         if (!val) {
           this.init();
         } else {
+          var objs = Object.keys(JSON.parse(val));
           this.form = JSON.parse(val);
+          if (!objs.includes("trueFalseQuestion")) {
+            this.form.trueFalseQuestion = {
+              knowledIds: [],
+              knum: 0,
+              orderNum: 3,
+              qnum: 0,
+              randomNum: 1,
+            };
+          }
         }
       },
       deep: true,

+ 1 - 1
src/views/resource/videoManagement/chapter/add/index.vue

@@ -420,7 +420,7 @@
       temUrl="/oss/images/file/20220518/1652842582633.xlsx"
       apiKey="drCourseSectionimportDataBusiness"
       checkKey="inquireCourseSection"
-      :param="{ businessJson: newSujectApis }"
+      :param="{ businessJson: JSON.stringify(newSujectApis) }"
       @success="success"
     ></batch-import-dialoga>
     <video-preview ref="preview" />

+ 1 - 1
src/views/resource/videoManagement/chapter/edit/index.vue

@@ -393,7 +393,7 @@
       temUrl="/oss/images/file/20220518/1652842582633.xlsx"
       apiKey="drCourseSectionimportDataBusiness"
       checkKey="inquireCourseSection"
-      :param="{ businessJson: newSujectApis }"
+      :param="{ businessJson: JSON.stringify(newSujectApis) }"
       @success="success"
     ></batch-import-dialoga>
     <video-preview ref="preview" />

+ 1 - 2
src/views/resource/videoManagement/courseManagement/chapterContent/index.vue

@@ -26,7 +26,6 @@
       lazy
       :load="load"
       :props="layoutTreeProps"
-      default-expand-all
       @node-click="handleNodeClick"
     >
       <span class="custom-tree-node" slot-scope="{ node, data }">
@@ -557,7 +556,7 @@ export default {
           // this.noStudent = false;
         }
       });
-    this.getDs();
+    // this.getDs();
     this.search();
   },
   methods: {

+ 378 - 0
src/views/secondJian/completionList/index.vue

@@ -0,0 +1,378 @@
+<template>
+  <div id="">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="jumpPage(props.scope.row)"
+          >学习记录</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { tableList, pagination },
+  data() {
+    return {
+      size: "small",
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "完成列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formData: {
+        profileStatus: "",
+        periodStatus: 1,
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "学员编码",
+          prop: "studentCode",
+          hidden: false,
+        },
+        {
+          label: "学员姓名",
+          prop: "realName",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "绑定手机号码",
+          prop: "telPhone",
+          hidden: false,
+        },
+        {
+          label: "所购商品",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "所在班级",
+          prop: "className",
+          hidden: true,
+        },
+        {
+          label: "班级有效期",
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          hidden: false,
+          scope: "TimeLists",
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+          hidden: false,
+        },
+        {
+          label: "视频学习进度(节)",
+          prop1: "stuAllNum",
+          prop2: "secAllNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "做题进度(章卷)",
+          prop1: "recordNum",
+          prop2: "examNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "学习开始时间",
+          prop: "startTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习结束时间",
+          prop: "endTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习服务期",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
+          hidden: false,
+          Diszing: true,
+          scope: "TimeLists",
+        },
+        {
+          label: "填写资料审核状态",
+          prop: "profileStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "审核通过",
+              value: 1,
+            },
+            {
+              label: "待审核",
+              value: 2,
+            },
+            {
+              label: "审核不通过",
+              value: 3,
+            },
+          ],
+        },
+        {
+          label: "学时审批状态",
+          prop: "periodStatus",
+          hidden: true,
+          scope: "statusPeriod",
+        },
+        {
+          label: "审核通过时间",
+          prop: "periodTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "待重修(视频节和题卷)",
+          prop: "waitRebuildNum",
+          prop1: "rebuildNum",
+          hidden: false,
+          scope: "againStudent",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "建造师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    jumpPage(v) {
+      this.$api
+        .inquireGradegradelockPeriodStatus({
+          gradeId: v.gradeId,
+          userId: v.userId,
+          goodsId: v.goodsId,
+        })
+        .then((res) => {
+          if (res.msg) {
+            this.$message.warning(res.msg + "正在操作");
+            return;
+          } else {
+            let data = {
+              userId: v.userId,
+              realName: v.realName,
+              id: v.gradeId,
+              className: v.className,
+              goodsId: v.goodsId,
+              goodsName: v.goodsName,
+              keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
+            };
+            this.checkSession(data)
+              .then(() => {
+                //学员详情
+                this.$router.push({
+                  name: "ClassHoursReviews",
+                });
+              })
+              .catch(() => {
+                this.$message.error("存在异常,请联系开发人员");
+              });
+          }
+        });
+    },
+    checkSession(row) {
+      return new Promise((resolve, reject) => {
+        const SESSION = sessionStorage.getItem("hoursAudit");
+        try {
+          if (SESSION) {
+            let parseSession = JSON.parse(SESSION);
+            const STATUS = parseSession.options.some((item) => {
+              return (
+                item.userId == row.userId &&
+                item.goodsId == row.goodsId &&
+                item.id == row.id
+              );
+            });
+            if (!STATUS) {
+              parseSession.options.push(row);
+            }
+            parseSession.activeData = `${row.userId}-${row.goodsId}-${row.id}`;
+            sessionStorage.setItem("hoursAudit", JSON.stringify(parseSession));
+          } else {
+            let data = {
+              activeData: `${row.userId}-${row.goodsId}-${row.id}`,
+              options: [row],
+            };
+            sessionStorage.setItem("hoursAudit", JSON.stringify(data));
+          }
+
+          resolve();
+        } catch (error) {
+          reject();
+        }
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGradegradelistUserPeriods(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 814 - 0
src/views/secondJian/courseList/index.vue

@@ -0,0 +1,814 @@
+<template>
+  <div id="">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="msgInfo(props.scope.row)"
+          >课程内容详情</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="1300px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">{{ goodsBoxName }}</div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div class="dis_flexs">
+        <div class="leftBoxs">
+          <span v-if="!activeId" style="font-size: 30px"
+            >请打开目录详情,点击播放您需要观看的视频内容。</span
+          >
+          <div v-show="vid" id="player"></div>
+          <div v-show="vidzb" id="playerzb"></div>
+        </div>
+        <div class="rightBoxslist">
+          <div v-for="(item, index) in courseList" :key="index" class="bg_ls">
+            <div
+              class="jus_sty"
+              :style="
+                item.checked
+                  ? 'border-bottom: 1px dotted #666;margin-bottom:6px;'
+                  : ''
+              "
+            >
+              <div style="font-size: 12px">{{ item.courseName }}</div>
+              <div class="line_h" @click="getCourseInfos(item, index)">
+                {{ item.checked ? "—" : "+" }}
+              </div>
+            </div>
+            <template v-if="item.checked">
+              <div v-for="(items, indexs) in item.children" :key="indexs">
+                <div
+                  class="firstSty"
+                  @click="getSecouredInfos(items, index, indexs)"
+                >
+                  <div class="typeIcon" v-if="items.type === 3">
+                    {{ getTypeName(items.sectionType) }}
+                  </div>
+                  <i
+                    v-if="items.type !== 3"
+                    :class="
+                      items.checked
+                        ? 'el-icon-caret-bottom'
+                        : 'el-icon-caret-right'
+                    "
+                  ></i>
+                  <span :style="activeId === items.onlyId ? 'color:red;' : ''">
+                    {{ items.menuName }}
+                  </span>
+                  <span v-if="items.type === 3" class="itemsty">{{
+                    $methodsTools.secondToDate(items.durationTime, false)
+                  }}</span>
+                </div>
+                <template v-if="items.checked">
+                  <div
+                    v-for="(its, ids) in items.children"
+                    :key="ids"
+                    style="padding-left: 14px"
+                  >
+                    <div
+                      class="firstSty"
+                      @click="getTemsInfo(its, index, indexs, ids)"
+                    >
+                      <div class="typeIcon" v-if="its.type === 3">
+                        {{ getTypeName(its.sectionType) }}
+                      </div>
+                      <i
+                        v-if="its.type !== 3"
+                        :class="
+                          its.checked
+                            ? 'el-icon-caret-bottom'
+                            : 'el-icon-caret-right'
+                        "
+                      ></i>
+                      <span
+                        :style="activeId === its.onlyId ? 'color:red;' : ''"
+                      >
+                        {{ its.menuName }}
+                      </span>
+                      <span v-if="its.type === 3" class="itemsty">{{
+                        $methodsTools.secondToDate(its.durationTime, false)
+                      }}</span>
+                    </div>
+                    <template v-if="its.checked">
+                      <div
+                        v-for="(itschild, ids) in its.children"
+                        :key="ids"
+                        style="padding-left: 14px"
+                        @click="getTemsInfo(itschild)"
+                      >
+                        <div class="firstSty">
+                          <div class="typeIcon">
+                            {{ getTypeName(itschild.sectionType) }}
+                          </div>
+                          <span
+                            :style="
+                              activeId === itschild.onlyId ? 'color:red;' : ''
+                            "
+                          >
+                            {{ itschild.menuName }}
+                          </span>
+                          <span class="itemsty">{{
+                            $methodsTools.secondToDate(
+                              itschild.durationTime,
+                              false
+                            )
+                          }}</span>
+                        </div>
+                      </div>
+                    </template>
+                  </div>
+                </template>
+              </div>
+            </template>
+          </div>
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "二建-课程查询列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        changeWidth: "150px",
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formData: {
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+        commitPeriodStatus:1
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "教育类型",
+          prop: "educationName",
+          hidden: true,
+        },
+        {
+          label: "业务层次",
+          prop1: "projectName",
+          prop2: "businessName",
+          hidden: true,
+          scope: "InfoMore",
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+          hidden: false,
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "商品状态",
+          prop: "status",
+          hidden: false,
+          scope: "hasTime",
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+          hidden: true,
+        },
+        {
+          label: "官方审核备注说明",
+          prop: "commitPeriodRemark",
+          hidden: true,
+        },
+        {
+          label: "学习服务期",
+          prop1: "serviceTimeType",
+          prop2: "serviceTimeNum",
+          prop3: "studyStartTime",
+          prop4: "studyEndTime",
+          scope: "studentServicePeriod",
+          hidden: false,
+        },
+        
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      dialogVisible: false,
+      courseList: [], //详情列表
+      activeId: "", //当前选中ID
+      vodPlayerJs: "https://player.polyv.net/script/player.js",
+      vid: "",
+      playerJs:
+        "https://player.polyv.net/resp/live-h5-player/latest/liveplayer.min.js",
+      uidzb: "egsxlptzdq",
+      vidzb: "",
+      goodsId: "",
+      goodsBoxName: "",
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "建造师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    getTypeName(type) {
+      let ast = "";
+      switch (type) {
+        case 1:
+          ast = "录播";
+          break;
+        case 2:
+          ast = "直播";
+          break;
+        case 3:
+          ast = "回放";
+          break;
+        default:
+          break;
+      }
+      return ast;
+    },
+    /**
+     * 关闭详情触发事件
+     */
+    close() {
+      this.dialogVisible = false;
+      this.clears();
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGoods(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    /**
+     * 点击详情
+     */
+    msgInfo(option) {
+      this.goodsBoxName = option.goodsName;
+      this.$api.obtainCourseSgoodsId(option.goodsId).then(async (res) => {
+        // if (res.rows.length) {
+        if (!res.rows.length) {
+          this.dialogVisible = true;
+        } else {
+          res.rows.forEach((item, index) => {
+            item.checked = false;
+          });
+          this.courseList = res.rows;
+          await this.autoGetCourseInfos(res.rows[0], 0);
+          this.dialogVisible = true;
+        }
+        // } else {
+        //   this.$message.warning("该商品暂无课程");
+        //   return;
+        // }
+      });
+    },
+    /**
+     * 自动播放第一个视频
+     */
+    autoGetCourseInfos(option, int) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .inquireCoursemenuListS({ courseId: option.courseId })
+          .then((res) => {
+            res.rows.forEach((item) => {
+              if (item.type !== 3) {
+                item.checked = false;
+              }
+              if (item.type === 3) {
+                item.onlyId = `${option.courseId}-0-0-${item.menuId}`;
+              }
+            });
+            this.$set(this.courseList[int], "children", res.rows);
+            this.$set(this.courseList[int], "checked", true);
+            if (this.courseList[0].children.length) {
+              switch (this.courseList[0].children[0].type) {
+                case 1:
+                  this.$api
+                    .inquireCourseListmodulechapter(
+                      this.courseList[0].children[0].menuId
+                    )
+                    .then((resz) => {
+                      resz.data.forEach((item) => {
+                        if (item.type !== 3) {
+                          item.checked = false;
+                          item.type = 2;
+                          item.courseId =
+                            this.courseList[0].children[0].courseId;
+                          item.menuName = item.name;
+                        }
+                      });
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "children",
+                        resz.data
+                      );
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "checked",
+                        true
+                      );
+                      if (this.courseList[int].children[0].children.length) {
+                        this.$api
+                          .inquireCoursechaptersectionlist(
+                            this.courseList[0].children[0].children[0].chapterId
+                          )
+                          .then((result) => {
+                            result.data.forEach((item) => {
+                              item.type = 3;
+                              item.menuName = item.name;
+                              item.onlyId = `${this.courseList[0].children[0].children[0].courseId}-${this.courseList[0].children[0].children[0].moduleId}-${this.courseList[0].children[0].children[0].chapterId}-${item.sectionId}`;
+                            });
+                            this.$set(
+                              this.courseList[int].children[0].children[0],
+                              "children",
+                              result.data
+                            );
+                            this.$set(
+                              this.courseList[int].children[0].children[0],
+                              "checked",
+                              true
+                            );
+                            if (
+                              this.courseList[int].children[0].children[0]
+                                .children.length
+                            ) {
+                              this.activeId =
+                                this.courseList[0].children[0].children[0].children[0].onlyId;
+                              this.initVideo(
+                                this.courseList[0].children[0].children[0]
+                                  .children[0]
+                              );
+                            }
+                          });
+                      }
+                    });
+                  break;
+                case 2:
+                  this.$api
+                    .inquireCoursechaptersectionlist(
+                      this.courseList[0].children[0].menuId
+                    )
+                    .then((result) => {
+                      result.data.forEach((item) => {
+                        item.type = 3;
+                        item.menuName = item.name;
+                        item.onlyId = `${this.courseList[0].children[0].courseId}-0-${this.courseList[0].children[0].menuId}-${item.sectionId}`;
+                      });
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "children",
+                        result.data
+                      );
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "checked",
+                        true
+                      );
+                      if (this.courseList[0].children[0].children.length) {
+                        this.activeId =
+                          this.courseList[0].children[0].children[0].onlyId;
+                        this.initVideo(
+                          this.courseList[0].children[0].children[0]
+                        );
+                      }
+                    });
+                  break;
+                case 3:
+                  this.activeId = this.courseList[0].children[0].onlyId;
+                  this.initVideo(this.courseList[0].children[0]);
+                  break;
+
+                default:
+                  break;
+              }
+            }
+            resolve();
+          });
+      });
+    },
+    /**
+     * 点击课程
+     */
+    getCourseInfos(option, int) {
+      if (option.checked) {
+        this.$set(this.courseList[int], "checked", false);
+      } else {
+        if (option.children) {
+          this.$set(this.courseList[int], "checked", true);
+          return;
+        }
+        this.$api
+          .inquireCoursemenuListS({ courseId: option.courseId })
+          .then((res) => {
+            res.rows.forEach((item) => {
+              if (item.type !== 3) {
+                item.checked = false;
+              }
+              if (item.type === 3) {
+                item.onlyId = `${option.courseId}-0-0-${item.menuId}`;
+              }
+            });
+            this.$set(this.courseList[int], "children", res.rows);
+            this.$set(this.courseList[int], "checked", true);
+          });
+      }
+    },
+    getSecouredInfos(option, int, ints) {
+      if (option.type === 3) {
+        //触发节函数
+        this.activeId = option.onlyId;
+        this.initVideo(option);
+      } else {
+        if (option.checked) {
+          this.$set(this.courseList[int].children[ints], "checked", false);
+        } else {
+          if (option.children) {
+            this.$set(this.courseList[int].children[ints], "checked", true);
+            return;
+          }
+          if (option.type === 1) {
+            this.$api
+              .inquireCourseListmodulechapter(option.menuId)
+              .then((res) => {
+                res.data.forEach((item) => {
+                  if (item.type !== 3) {
+                    item.checked = false;
+                    item.type = 2;
+                    item.courseId = option.courseId;
+                    item.menuName = item.name;
+                  }
+                });
+                this.$set(
+                  this.courseList[int].children[ints],
+                  "children",
+                  res.data
+                );
+                this.$set(this.courseList[int].children[ints], "checked", true);
+              });
+          }
+          if (option.type === 2) {
+            this.$api
+              .inquireCoursechaptersectionlist(option.menuId)
+              .then((res) => {
+                res.data.forEach((item) => {
+                  item.type = 3;
+                  item.menuName = item.name;
+                  item.onlyId = `${option.courseId}-0-${option.menuId}-${item.sectionId}`;
+                });
+                this.$set(
+                  this.courseList[int].children[ints],
+                  "children",
+                  res.data
+                );
+                this.$set(this.courseList[int].children[ints], "checked", true);
+              });
+          }
+        }
+      }
+    },
+    getTemsInfo(option, int, ints, ids) {
+      if (option.type === 3) {
+        //触发节函数
+        this.initVideo(option);
+      } else {
+        if (option.checked) {
+          this.$set(
+            this.courseList[int].children[ints].children[ids],
+            "checked",
+            false
+          );
+        } else {
+          if (option.children) {
+            this.$set(
+              this.courseList[int].children[ints].children[ids],
+              "checked",
+              true
+            );
+            return;
+          }
+          if (option.type === 2) {
+            this.$api
+              .inquireCoursechaptersectionlist(option.chapterId)
+              .then((res) => {
+                res.data.forEach((item) => {
+                  item.type = 3;
+                  item.menuName = item.name;
+                  item.onlyId = `${option.courseId}-${option.moduleId}-${option.chapterId}-${item.sectionId}`;
+                });
+                this.$set(
+                  this.courseList[int].children[ints].children[ids],
+                  "children",
+                  res.data
+                );
+                this.$set(
+                  this.courseList[int].children[ints].children[ids],
+                  "checked",
+                  true
+                );
+              });
+          }
+        }
+      }
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    async initVideo(option) {
+      await this.clears();
+      this.activeId = option.onlyId;
+      if (option.sectionType === 2) {
+        this.vidzb = option.liveUrl;
+        this.loadPlayerScriptzb(this.loadPlayerzb);
+      } else {
+        this.vid = option.recordingUrl;
+        this.loadPlayerScript(this.loadPlayer);
+      }
+    },
+    loadPlayerScript(callback) {
+      if (!window.polyvPlayer) {
+        const myScript = document.createElement("script");
+        myScript.setAttribute("src", this.vodPlayerJs);
+        myScript.onload = callback;
+        document.body.appendChild(myScript);
+      } else {
+        callback();
+      }
+    },
+    loadPlayer() {
+      var self = this;
+      const polyvPlayer = window.polyvPlayer;
+      self.player = polyvPlayer({
+        wrap: "#player",
+        width: 932,
+        height: 627,
+        vid: self.vid,
+        teaser_show: 0,
+        playsafe: function (vid, next) {
+          self.$api.obtainpolyvvideosign(vid).then((res) => {
+            next(res.data);
+          });
+        },
+      });
+    },
+    /**
+     * @param {String} 关闭视频窗口-销毁实例
+     */
+    clears() {
+      return new Promise((resolve, reject) => {
+        this.activeId = "";
+        this.vid = "";
+        this.vidzb = "";
+        if (this.player) {
+          this.player.destroy();
+        }
+        if (this.playerzb) {
+          this.playerzb.destroy();
+        }
+        resolve();
+      });
+    },
+    /**
+     * @param {String} 直播预览
+     */
+    loadPlayerScriptzb(callback) {
+      if (!window.polyvLivePlayer) {
+        const myScript = document.createElement("script");
+        myScript.setAttribute("src", this.playerJs);
+        myScript.onload = callback;
+        document.body.appendChild(myScript);
+      } else {
+        callback();
+      }
+    },
+
+    loadPlayerzb() {
+      const polyvLivePlayer = window.polyvLivePlayer;
+      this.playerzb = polyvLivePlayer({
+        wrap: "#playerzb",
+        width: 932,
+        height: 627,
+        uid: this.uidzb,
+        vid: this.vidzb,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.dis_flexs {
+  display: flex;
+}
+.leftBoxs {
+  width: 932px;
+  height: 627px;
+  border: 1px solid #eee;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.rightBoxslist {
+  flex: 1;
+  max-height: 627px;
+  overflow-y: auto;
+  margin-left: 10px;
+}
+.bg_ls {
+  background-color: #eee;
+  padding: 8px;
+  margin-bottom: 10px;
+}
+.jus_sty {
+  display: flex;
+  justify-content: space-between;
+  padding: 6px 0px;
+}
+.line_h {
+  font-size: 14px;
+  height: 18px;
+  width: 18px;
+  font-weight: bold;
+  color: #000;
+  background-color: rgb(153, 153, 153);
+  line-height: 18px;
+  text-align: center;
+  cursor: pointer;
+}
+.firstSty {
+  font-size: 13px;
+  margin-bottom: 6px;
+  cursor: pointer;
+  &:hover {
+    color: red;
+  }
+}
+.typeIcon {
+  display: inline-block;
+  border-radius: 8px;
+  border: 1px solid #000;
+  padding: 0px 4px;
+  color: #000 !important;
+  font-size: 12px;
+}
+.itemsty {
+  font-size: 13px;
+  color: purple;
+  margin-left: 14px;
+}
+</style>

+ 378 - 0
src/views/secondJian/learningList/index.vue

@@ -0,0 +1,378 @@
+<template>
+  <div id="">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="jumpPage(props.scope.row)"
+          >学习记录</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { tableList, pagination },
+  data() {
+    return {
+      size: "small",
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "学习列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formData: {
+        profileStatus: "",
+        periodStatus: "",
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "学员编码",
+          prop: "studentCode",
+          hidden: false,
+        },
+        {
+          label: "学员姓名",
+          prop: "realName",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "绑定手机号码",
+          prop: "telPhone",
+          hidden: false,
+        },
+        {
+          label: "所购商品",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "所在班级",
+          prop: "className",
+          hidden: true,
+        },
+        {
+          label: "班级有效期",
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          hidden: false,
+          scope: "TimeLists",
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+          hidden: false,
+        },
+        {
+          label: "视频学习进度(节)",
+          prop1: "stuAllNum",
+          prop2: "secAllNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "做题进度(章卷)",
+          prop1: "recordNum",
+          prop2: "examNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "学习开始时间",
+          prop: "startTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习结束时间",
+          prop: "endTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习服务期",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
+          hidden: false,
+          Diszing: true,
+          scope: "TimeLists",
+        },
+        {
+          label: "填写资料审核状态",
+          prop: "profileStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "审核通过",
+              value: 1,
+            },
+            {
+              label: "待审核",
+              value: 2,
+            },
+            {
+              label: "审核不通过",
+              value: 3,
+            },
+          ],
+        },
+        {
+          label: "学时审批状态",
+          prop: "periodStatus",
+          hidden: true,
+          scope: "statusPeriod",
+        },
+        {
+          label: "审核通过时间",
+          prop: "periodTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "待重修(视频节和题卷)",
+          prop: "waitRebuildNum",
+          prop1: "rebuildNum",
+          hidden: false,
+          scope: "againStudent",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "建造师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    jumpPage(v) {
+      this.$api
+        .inquireGradegradelockPeriodStatus({
+          gradeId: v.gradeId,
+          userId: v.userId,
+          goodsId: v.goodsId,
+        })
+        .then((res) => {
+          if (res.msg) {
+            this.$message.warning(res.msg + "正在操作");
+            return;
+          } else {
+            let data = {
+              userId: v.userId,
+              realName: v.realName,
+              id: v.gradeId,
+              className: v.className,
+              goodsId: v.goodsId,
+              goodsName: v.goodsName,
+              keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
+            };
+            this.checkSession(data)
+              .then(() => {
+                //学员详情
+                this.$router.push({
+                  name: "ClassHoursReviews",
+                });
+              })
+              .catch(() => {
+                this.$message.error("存在异常,请联系开发人员");
+              });
+          }
+        });
+    },
+    checkSession(row) {
+      return new Promise((resolve, reject) => {
+        const SESSION = sessionStorage.getItem("hoursAudit");
+        try {
+          if (SESSION) {
+            let parseSession = JSON.parse(SESSION);
+            const STATUS = parseSession.options.some((item) => {
+              return (
+                item.userId == row.userId &&
+                item.goodsId == row.goodsId &&
+                item.id == row.id
+              );
+            });
+            if (!STATUS) {
+              parseSession.options.push(row);
+            }
+            parseSession.activeData = `${row.userId}-${row.goodsId}-${row.id}`;
+            sessionStorage.setItem("hoursAudit", JSON.stringify(parseSession));
+          } else {
+            let data = {
+              activeData: `${row.userId}-${row.goodsId}-${row.id}`,
+              options: [row],
+            };
+            sessionStorage.setItem("hoursAudit", JSON.stringify(data));
+          }
+
+          resolve();
+        } catch (error) {
+          reject();
+        }
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGradegradelistUserPeriods(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 378 - 0
src/views/secondZao/completionList/index.vue

@@ -0,0 +1,378 @@
+<template>
+  <div id="">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="jumpPage(props.scope.row)"
+          >学习记录</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { tableList, pagination },
+  data() {
+    return {
+      size: "small",
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "完成列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formData: {
+        profileStatus: "",
+        periodStatus: 1,
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "学员编码",
+          prop: "studentCode",
+          hidden: false,
+        },
+        {
+          label: "学员姓名",
+          prop: "realName",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "绑定手机号码",
+          prop: "telPhone",
+          hidden: false,
+        },
+        {
+          label: "所购商品",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "所在班级",
+          prop: "className",
+          hidden: true,
+        },
+        {
+          label: "班级有效期",
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          hidden: false,
+          scope: "TimeLists",
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+          hidden: false,
+        },
+        {
+          label: "视频学习进度(节)",
+          prop1: "stuAllNum",
+          prop2: "secAllNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "做题进度(章卷)",
+          prop1: "recordNum",
+          prop2: "examNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "学习开始时间",
+          prop: "startTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习结束时间",
+          prop: "endTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习服务期",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
+          hidden: false,
+          Diszing: true,
+          scope: "TimeLists",
+        },
+        {
+          label: "填写资料审核状态",
+          prop: "profileStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "审核通过",
+              value: 1,
+            },
+            {
+              label: "待审核",
+              value: 2,
+            },
+            {
+              label: "审核不通过",
+              value: 3,
+            },
+          ],
+        },
+        {
+          label: "学时审批状态",
+          prop: "periodStatus",
+          hidden: true,
+          scope: "statusPeriod",
+        },
+        {
+          label: "审核通过时间",
+          prop: "periodTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "待重修(视频节和题卷)",
+          prop: "waitRebuildNum",
+          prop1: "rebuildNum",
+          hidden: false,
+          scope: "againStudent",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "造价师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    jumpPage(v) {
+      this.$api
+        .inquireGradegradelockPeriodStatus({
+          gradeId: v.gradeId,
+          userId: v.userId,
+          goodsId: v.goodsId,
+        })
+        .then((res) => {
+          if (res.msg) {
+            this.$message.warning(res.msg + "正在操作");
+            return;
+          } else {
+            let data = {
+              userId: v.userId,
+              realName: v.realName,
+              id: v.gradeId,
+              className: v.className,
+              goodsId: v.goodsId,
+              goodsName: v.goodsName,
+              keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
+            };
+            this.checkSession(data)
+              .then(() => {
+                //学员详情
+                this.$router.push({
+                  name: "ClassHoursReviews",
+                });
+              })
+              .catch(() => {
+                this.$message.error("存在异常,请联系开发人员");
+              });
+          }
+        });
+    },
+    checkSession(row) {
+      return new Promise((resolve, reject) => {
+        const SESSION = sessionStorage.getItem("hoursAudit");
+        try {
+          if (SESSION) {
+            let parseSession = JSON.parse(SESSION);
+            const STATUS = parseSession.options.some((item) => {
+              return (
+                item.userId == row.userId &&
+                item.goodsId == row.goodsId &&
+                item.id == row.id
+              );
+            });
+            if (!STATUS) {
+              parseSession.options.push(row);
+            }
+            parseSession.activeData = `${row.userId}-${row.goodsId}-${row.id}`;
+            sessionStorage.setItem("hoursAudit", JSON.stringify(parseSession));
+          } else {
+            let data = {
+              activeData: `${row.userId}-${row.goodsId}-${row.id}`,
+              options: [row],
+            };
+            sessionStorage.setItem("hoursAudit", JSON.stringify(data));
+          }
+
+          resolve();
+        } catch (error) {
+          reject();
+        }
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGradegradelistUserPeriods(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 813 - 0
src/views/secondZao/courseList/index.vue

@@ -0,0 +1,813 @@
+<template>
+  <div id="">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="msgInfo(props.scope.row)"
+          >课程内容详情</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="1300px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">{{ goodsBoxName }}</div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div class="dis_flexs">
+        <div class="leftBoxs">
+          <span v-if="!activeId" style="font-size: 30px"
+            >请打开目录详情,点击播放您需要观看的视频内容。</span
+          >
+          <div v-show="vid" id="player"></div>
+          <div v-show="vidzb" id="playerzb"></div>
+        </div>
+        <div class="rightBoxslist">
+          <div v-for="(item, index) in courseList" :key="index" class="bg_ls">
+            <div
+              class="jus_sty"
+              :style="
+                item.checked
+                  ? 'border-bottom: 1px dotted #666;margin-bottom:6px;'
+                  : ''
+              "
+            >
+              <div style="font-size: 12px">{{ item.courseName }}</div>
+              <div class="line_h" @click="getCourseInfos(item, index)">
+                {{ item.checked ? "—" : "+" }}
+              </div>
+            </div>
+            <template v-if="item.checked">
+              <div v-for="(items, indexs) in item.children" :key="indexs">
+                <div
+                  class="firstSty"
+                  @click="getSecouredInfos(items, index, indexs)"
+                >
+                  <div class="typeIcon" v-if="items.type === 3">
+                    {{ getTypeName(items.sectionType) }}
+                  </div>
+                  <i
+                    v-if="items.type !== 3"
+                    :class="
+                      items.checked
+                        ? 'el-icon-caret-bottom'
+                        : 'el-icon-caret-right'
+                    "
+                  ></i>
+                  <span :style="activeId === items.onlyId ? 'color:red;' : ''">
+                    {{ items.menuName }}
+                  </span>
+                  <span v-if="items.type === 3" class="itemsty">{{
+                    $methodsTools.secondToDate(items.durationTime, false)
+                  }}</span>
+                </div>
+                <template v-if="items.checked">
+                  <div
+                    v-for="(its, ids) in items.children"
+                    :key="ids"
+                    style="padding-left: 14px"
+                  >
+                    <div
+                      class="firstSty"
+                      @click="getTemsInfo(its, index, indexs, ids)"
+                    >
+                      <div class="typeIcon" v-if="its.type === 3">
+                        {{ getTypeName(its.sectionType) }}
+                      </div>
+                      <i
+                        v-if="its.type !== 3"
+                        :class="
+                          its.checked
+                            ? 'el-icon-caret-bottom'
+                            : 'el-icon-caret-right'
+                        "
+                      ></i>
+                      <span
+                        :style="activeId === its.onlyId ? 'color:red;' : ''"
+                      >
+                        {{ its.menuName }}
+                      </span>
+                      <span v-if="its.type === 3" class="itemsty">{{
+                        $methodsTools.secondToDate(its.durationTime, false)
+                      }}</span>
+                    </div>
+                    <template v-if="its.checked">
+                      <div
+                        v-for="(itschild, ids) in its.children"
+                        :key="ids"
+                        style="padding-left: 14px"
+                        @click="getTemsInfo(itschild)"
+                      >
+                        <div class="firstSty">
+                          <div class="typeIcon">
+                            {{ getTypeName(itschild.sectionType) }}
+                          </div>
+                          <span
+                            :style="
+                              activeId === itschild.onlyId ? 'color:red;' : ''
+                            "
+                          >
+                            {{ itschild.menuName }}
+                          </span>
+                          <span class="itemsty">{{
+                            $methodsTools.secondToDate(
+                              itschild.durationTime,
+                              false
+                            )
+                          }}</span>
+                        </div>
+                      </div>
+                    </template>
+                  </div>
+                </template>
+              </div>
+            </template>
+          </div>
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "课程列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        changeWidth: "150px",
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formData: {
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+        commitPeriodStatus:1
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "教育类型",
+          prop: "educationName",
+          hidden: true,
+        },
+        {
+          label: "业务层次",
+          prop1: "projectName",
+          prop2: "businessName",
+          hidden: true,
+          scope: "InfoMore",
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+          hidden: false,
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "商品状态",
+          prop: "status",
+          hidden: false,
+          scope: "hasTime",
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+          hidden: true,
+        },
+        {
+          label: "官方审核备注说明",
+          prop: "commitPeriodRemark",
+          hidden: true,
+        },
+        {
+          label: "学习服务期",
+          prop1: "serviceTimeType",
+          prop2: "serviceTimeNum",
+          prop3: "studyStartTime",
+          prop4: "studyEndTime",
+          scope: "studentServicePeriod",
+          hidden: false,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      dialogVisible: false,
+      courseList: [], //详情列表
+      activeId: "", //当前选中ID
+      vodPlayerJs: "https://player.polyv.net/script/player.js",
+      vid: "",
+      playerJs:
+        "https://player.polyv.net/resp/live-h5-player/latest/liveplayer.min.js",
+      uidzb: "egsxlptzdq",
+      vidzb: "",
+      goodsId: "",
+      goodsBoxName: "",
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "造价师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    getTypeName(type) {
+      let ast = "";
+      switch (type) {
+        case 1:
+          ast = "录播";
+          break;
+        case 2:
+          ast = "直播";
+          break;
+        case 3:
+          ast = "回放";
+          break;
+        default:
+          break;
+      }
+      return ast;
+    },
+    /**
+     * 关闭详情触发事件
+     */
+    close() {
+      this.dialogVisible = false;
+      this.clears();
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGoods(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    /**
+     * 点击详情
+     */
+    msgInfo(option) {
+      this.goodsBoxName = option.goodsName;
+      this.$api.obtainCourseSgoodsId(option.goodsId).then(async (res) => {
+        // if (res.rows.length) {
+        if (!res.rows.length) {
+          this.dialogVisible = true;
+        } else {
+          res.rows.forEach((item, index) => {
+            item.checked = false;
+          });
+          this.courseList = res.rows;
+          await this.autoGetCourseInfos(res.rows[0], 0);
+          this.dialogVisible = true;
+        }
+        // } else {
+        //   this.$message.warning("该商品暂无课程");
+        //   return;
+        // }
+      });
+    },
+    /**
+     * 自动播放第一个视频
+     */
+    autoGetCourseInfos(option, int) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .inquireCoursemenuListS({ courseId: option.courseId })
+          .then((res) => {
+            res.rows.forEach((item) => {
+              if (item.type !== 3) {
+                item.checked = false;
+              }
+              if (item.type === 3) {
+                item.onlyId = `${option.courseId}-0-0-${item.menuId}`;
+              }
+            });
+            this.$set(this.courseList[int], "children", res.rows);
+            this.$set(this.courseList[int], "checked", true);
+            if (this.courseList[0].children.length) {
+              switch (this.courseList[0].children[0].type) {
+                case 1:
+                  this.$api
+                    .inquireCourseListmodulechapter(
+                      this.courseList[0].children[0].menuId
+                    )
+                    .then((resz) => {
+                      resz.data.forEach((item) => {
+                        if (item.type !== 3) {
+                          item.checked = false;
+                          item.type = 2;
+                          item.courseId =
+                            this.courseList[0].children[0].courseId;
+                          item.menuName = item.name;
+                        }
+                      });
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "children",
+                        resz.data
+                      );
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "checked",
+                        true
+                      );
+                      if (this.courseList[int].children[0].children.length) {
+                        this.$api
+                          .inquireCoursechaptersectionlist(
+                            this.courseList[0].children[0].children[0].chapterId
+                          )
+                          .then((result) => {
+                            result.data.forEach((item) => {
+                              item.type = 3;
+                              item.menuName = item.name;
+                              item.onlyId = `${this.courseList[0].children[0].children[0].courseId}-${this.courseList[0].children[0].children[0].moduleId}-${this.courseList[0].children[0].children[0].chapterId}-${item.sectionId}`;
+                            });
+                            this.$set(
+                              this.courseList[int].children[0].children[0],
+                              "children",
+                              result.data
+                            );
+                            this.$set(
+                              this.courseList[int].children[0].children[0],
+                              "checked",
+                              true
+                            );
+                            if (
+                              this.courseList[int].children[0].children[0]
+                                .children.length
+                            ) {
+                              this.activeId =
+                                this.courseList[0].children[0].children[0].children[0].onlyId;
+                              this.initVideo(
+                                this.courseList[0].children[0].children[0]
+                                  .children[0]
+                              );
+                            }
+                          });
+                      }
+                    });
+                  break;
+                case 2:
+                  this.$api
+                    .inquireCoursechaptersectionlist(
+                      this.courseList[0].children[0].menuId
+                    )
+                    .then((result) => {
+                      result.data.forEach((item) => {
+                        item.type = 3;
+                        item.menuName = item.name;
+                        item.onlyId = `${this.courseList[0].children[0].courseId}-0-${this.courseList[0].children[0].menuId}-${item.sectionId}`;
+                      });
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "children",
+                        result.data
+                      );
+                      this.$set(
+                        this.courseList[int].children[0],
+                        "checked",
+                        true
+                      );
+                      if (this.courseList[0].children[0].children.length) {
+                        this.activeId =
+                          this.courseList[0].children[0].children[0].onlyId;
+                        this.initVideo(
+                          this.courseList[0].children[0].children[0]
+                        );
+                      }
+                    });
+                  break;
+                case 3:
+                  this.activeId = this.courseList[0].children[0].onlyId;
+                  this.initVideo(this.courseList[0].children[0]);
+                  break;
+
+                default:
+                  break;
+              }
+            }
+            resolve();
+          });
+      });
+    },
+    /**
+     * 点击课程
+     */
+    getCourseInfos(option, int) {
+      if (option.checked) {
+        this.$set(this.courseList[int], "checked", false);
+      } else {
+        if (option.children) {
+          this.$set(this.courseList[int], "checked", true);
+          return;
+        }
+        this.$api
+          .inquireCoursemenuListS({ courseId: option.courseId })
+          .then((res) => {
+            res.rows.forEach((item) => {
+              if (item.type !== 3) {
+                item.checked = false;
+              }
+              if (item.type === 3) {
+                item.onlyId = `${option.courseId}-0-0-${item.menuId}`;
+              }
+            });
+            this.$set(this.courseList[int], "children", res.rows);
+            this.$set(this.courseList[int], "checked", true);
+          });
+      }
+    },
+    getSecouredInfos(option, int, ints) {
+      if (option.type === 3) {
+        //触发节函数
+        this.activeId = option.onlyId;
+        this.initVideo(option);
+      } else {
+        if (option.checked) {
+          this.$set(this.courseList[int].children[ints], "checked", false);
+        } else {
+          if (option.children) {
+            this.$set(this.courseList[int].children[ints], "checked", true);
+            return;
+          }
+          if (option.type === 1) {
+            this.$api
+              .inquireCourseListmodulechapter(option.menuId)
+              .then((res) => {
+                res.data.forEach((item) => {
+                  if (item.type !== 3) {
+                    item.checked = false;
+                    item.type = 2;
+                    item.courseId = option.courseId;
+                    item.menuName = item.name;
+                  }
+                });
+                this.$set(
+                  this.courseList[int].children[ints],
+                  "children",
+                  res.data
+                );
+                this.$set(this.courseList[int].children[ints], "checked", true);
+              });
+          }
+          if (option.type === 2) {
+            this.$api
+              .inquireCoursechaptersectionlist(option.menuId)
+              .then((res) => {
+                res.data.forEach((item) => {
+                  item.type = 3;
+                  item.menuName = item.name;
+                  item.onlyId = `${option.courseId}-0-${option.menuId}-${item.sectionId}`;
+                });
+                this.$set(
+                  this.courseList[int].children[ints],
+                  "children",
+                  res.data
+                );
+                this.$set(this.courseList[int].children[ints], "checked", true);
+              });
+          }
+        }
+      }
+    },
+    getTemsInfo(option, int, ints, ids) {
+      if (option.type === 3) {
+        //触发节函数
+        this.initVideo(option);
+      } else {
+        if (option.checked) {
+          this.$set(
+            this.courseList[int].children[ints].children[ids],
+            "checked",
+            false
+          );
+        } else {
+          if (option.children) {
+            this.$set(
+              this.courseList[int].children[ints].children[ids],
+              "checked",
+              true
+            );
+            return;
+          }
+          if (option.type === 2) {
+            this.$api
+              .inquireCoursechaptersectionlist(option.chapterId)
+              .then((res) => {
+                res.data.forEach((item) => {
+                  item.type = 3;
+                  item.menuName = item.name;
+                  item.onlyId = `${option.courseId}-${option.moduleId}-${option.chapterId}-${item.sectionId}`;
+                });
+                this.$set(
+                  this.courseList[int].children[ints].children[ids],
+                  "children",
+                  res.data
+                );
+                this.$set(
+                  this.courseList[int].children[ints].children[ids],
+                  "checked",
+                  true
+                );
+              });
+          }
+        }
+      }
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    async initVideo(option) {
+      await this.clears();
+      this.activeId = option.onlyId;
+      if (option.sectionType === 2) {
+        this.vidzb = option.liveUrl;
+        this.loadPlayerScriptzb(this.loadPlayerzb);
+      } else {
+        this.vid = option.recordingUrl;
+        this.loadPlayerScript(this.loadPlayer);
+      }
+    },
+    loadPlayerScript(callback) {
+      if (!window.polyvPlayer) {
+        const myScript = document.createElement("script");
+        myScript.setAttribute("src", this.vodPlayerJs);
+        myScript.onload = callback;
+        document.body.appendChild(myScript);
+      } else {
+        callback();
+      }
+    },
+    loadPlayer() {
+      var self = this;
+      const polyvPlayer = window.polyvPlayer;
+      self.player = polyvPlayer({
+        wrap: "#player",
+        width: 932,
+        height: 627,
+        vid: self.vid,
+        teaser_show: 0,
+        playsafe: function (vid, next) {
+          self.$api.obtainpolyvvideosign(vid).then((res) => {
+            next(res.data);
+          });
+        },
+      });
+    },
+    /**
+     * @param {String} 关闭视频窗口-销毁实例
+     */
+    clears() {
+      return new Promise((resolve, reject) => {
+        this.activeId = "";
+        this.vid = "";
+        this.vidzb = "";
+        if (this.player) {
+          this.player.destroy();
+        }
+        if (this.playerzb) {
+          this.playerzb.destroy();
+        }
+        resolve();
+      });
+    },
+    /**
+     * @param {String} 直播预览
+     */
+    loadPlayerScriptzb(callback) {
+      if (!window.polyvLivePlayer) {
+        const myScript = document.createElement("script");
+        myScript.setAttribute("src", this.playerJs);
+        myScript.onload = callback;
+        document.body.appendChild(myScript);
+      } else {
+        callback();
+      }
+    },
+
+    loadPlayerzb() {
+      const polyvLivePlayer = window.polyvLivePlayer;
+      this.playerzb = polyvLivePlayer({
+        wrap: "#playerzb",
+        width: 932,
+        height: 627,
+        uid: this.uidzb,
+        vid: this.vidzb,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.dis_flexs {
+  display: flex;
+}
+.leftBoxs {
+  width: 932px;
+  height: 627px;
+  border: 1px solid #eee;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.rightBoxslist {
+  flex: 1;
+  max-height: 627px;
+  overflow-y: auto;
+  margin-left: 10px;
+}
+.bg_ls {
+  background-color: #eee;
+  padding: 8px;
+  margin-bottom: 10px;
+}
+.jus_sty {
+  display: flex;
+  justify-content: space-between;
+  padding: 6px 0px;
+}
+.line_h {
+  font-size: 14px;
+  height: 18px;
+  width: 18px;
+  font-weight: bold;
+  color: #000;
+  background-color: rgb(153, 153, 153);
+  line-height: 18px;
+  text-align: center;
+  cursor: pointer;
+}
+.firstSty {
+  font-size: 13px;
+  margin-bottom: 6px;
+  cursor: pointer;
+  &:hover {
+    color: red;
+  }
+}
+.typeIcon {
+  display: inline-block;
+  border-radius: 8px;
+  border: 1px solid #000;
+  padding: 0px 4px;
+  color: #000 !important;
+  font-size: 12px;
+}
+.itemsty {
+  font-size: 13px;
+  color: purple;
+  margin-left: 14px;
+}
+</style>

+ 378 - 0
src/views/secondZao/learningList/index.vue

@@ -0,0 +1,378 @@
+<template>
+  <div id="">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="jumpPage(props.scope.row)"
+          >学习记录</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { tableList, pagination },
+  data() {
+    return {
+      size: "small",
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "学习列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formData: {
+        profileStatus: "",
+        periodStatus: "",
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "学员编码",
+          prop: "studentCode",
+          hidden: false,
+        },
+        {
+          label: "学员姓名",
+          prop: "realName",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "绑定手机号码",
+          prop: "telPhone",
+          hidden: false,
+        },
+        {
+          label: "所购商品",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "所在班级",
+          prop: "className",
+          hidden: true,
+        },
+        {
+          label: "班级有效期",
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          hidden: false,
+          scope: "TimeLists",
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+          hidden: false,
+        },
+        {
+          label: "视频学习进度(节)",
+          prop1: "stuAllNum",
+          prop2: "secAllNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "做题进度(章卷)",
+          prop1: "recordNum",
+          prop2: "examNum",
+          hidden: false,
+          scope: "computer",
+        },
+        {
+          label: "学习开始时间",
+          prop: "startTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习结束时间",
+          prop: "endTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习服务期",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
+          hidden: false,
+          Diszing: true,
+          scope: "TimeLists",
+        },
+        {
+          label: "填写资料审核状态",
+          prop: "profileStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "审核通过",
+              value: 1,
+            },
+            {
+              label: "待审核",
+              value: 2,
+            },
+            {
+              label: "审核不通过",
+              value: 3,
+            },
+          ],
+        },
+        {
+          label: "学时审批状态",
+          prop: "periodStatus",
+          hidden: true,
+          scope: "statusPeriod",
+        },
+        {
+          label: "审核通过时间",
+          prop: "periodTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "待重修(视频节和题卷)",
+          prop: "waitRebuildNum",
+          prop1: "rebuildNum",
+          hidden: false,
+          scope: "againStudent",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "造价师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    jumpPage(v) {
+      this.$api
+        .inquireGradegradelockPeriodStatus({
+          gradeId: v.gradeId,
+          userId: v.userId,
+          goodsId: v.goodsId,
+        })
+        .then((res) => {
+          if (res.msg) {
+            this.$message.warning(res.msg + "正在操作");
+            return;
+          } else {
+            let data = {
+              userId: v.userId,
+              realName: v.realName,
+              id: v.gradeId,
+              className: v.className,
+              goodsId: v.goodsId,
+              goodsName: v.goodsName,
+              keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
+            };
+            this.checkSession(data)
+              .then(() => {
+                //学员详情
+                this.$router.push({
+                  name: "ClassHoursReviews",
+                });
+              })
+              .catch(() => {
+                this.$message.error("存在异常,请联系开发人员");
+              });
+          }
+        });
+    },
+    checkSession(row) {
+      return new Promise((resolve, reject) => {
+        const SESSION = sessionStorage.getItem("hoursAudit");
+        try {
+          if (SESSION) {
+            let parseSession = JSON.parse(SESSION);
+            const STATUS = parseSession.options.some((item) => {
+              return (
+                item.userId == row.userId &&
+                item.goodsId == row.goodsId &&
+                item.id == row.id
+              );
+            });
+            if (!STATUS) {
+              parseSession.options.push(row);
+            }
+            parseSession.activeData = `${row.userId}-${row.goodsId}-${row.id}`;
+            sessionStorage.setItem("hoursAudit", JSON.stringify(parseSession));
+          } else {
+            let data = {
+              activeData: `${row.userId}-${row.goodsId}-${row.id}`,
+              options: [row],
+            };
+            sessionStorage.setItem("hoursAudit", JSON.stringify(data));
+          }
+
+          resolve();
+        } catch (error) {
+          reject();
+        }
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGradegradelistUserPeriods(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio