Эх сурвалжийг харах

Merge branch 'seven' of http://120.79.166.78:19005/zhongzheng-edu/saas_entrepot_admin into dev

Tang 3 жил өмнө
parent
commit
b658bf6bfd
47 өөрчлөгдсөн 2766 нэмэгдсэн , 1993 устгасан
  1. 3 0
      .env.production
  2. 4 0
      .env.staging
  3. 1 2
      public/index.html
  4. BIN
      src/assets/images/idcardF.png
  5. BIN
      src/assets/images/idcardZ.png
  6. BIN
      src/assets/images/peopleImg.png
  7. 45 5
      src/components/tableList.vue
  8. 16 1
      src/newApi/business.js
  9. 8 0
      src/newApi/modules.js
  10. 0 5
      src/router/index.js
  11. 258 0
      src/views/2Cport/filterItemSettings/index.vue
  12. 2 3
      src/views/Marketing/goods/commodityManageMent/add/courseContent/index.vue
  13. 6 3
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue
  14. 3 1
      src/views/Marketing/goods/commodityManageMent/edit/index.vue
  15. 50 43
      src/views/Marketing/goods/commodityManageMent/poppleSet.vue
  16. 5 3
      src/views/Marketing/order/offlineOrder/batchRecord/firstStep/index.vue
  17. 33 3
      src/views/Marketing/order/offlineOrder/index.vue
  18. 10 1
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/costPrice.vue
  19. 18 5
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/goodsInfos.vue
  20. 33 3
      src/views/Marketing/order/offlineOrder/orderChargeInfo/topBox.vue
  21. 3 3
      src/views/Marketing/order/offlineOrder/orderDetailsT/index.vue
  22. 0 102
      src/views/dashboard/BarChart.vue
  23. 0 135
      src/views/dashboard/LineChart.vue
  24. 0 181
      src/views/dashboard/PanelGroup.vue
  25. 0 79
      src/views/dashboard/PieChart.vue
  26. 0 116
      src/views/dashboard/RaddarChart.vue
  27. 3 0
      src/views/education/classManageMent/classHoursReview/index.vue
  28. 353 254
      src/views/education/classManageMent/classHoursReview/studyTimes.vue
  29. 689 0
      src/views/education/classManageMent/hoursTimesRecord/index.vue
  30. 175 85
      src/views/education/classManageMent/learningHoursRecordList/hoursTimesRecord.vue
  31. 138 130
      src/views/education/classManageMent/learningHoursRecordList/index.vue
  32. 344 270
      src/views/education/classManageMent/learningHoursRecordList/studyTimesRecord.vue
  33. 2 2
      src/views/education/examManagement/applicationData/byTrainee.vue
  34. 52 4
      src/views/education/studentManageMent/studentList/index.vue
  35. 1 0
      src/views/index.vue
  36. 0 98
      src/views/index_v1.vue
  37. 0 215
      src/views/loginCopy.vue
  38. 0 208
      src/views/register.vue
  39. 49 5
      src/views/resource/baseManageInfos/resource/businessLevel/index.vue
  40. 1 0
      src/views/resource/videoManagement/chapter/add/index.vue
  41. 3 3
      src/views/resource/videoManagement/chapter/edit/index.vue
  42. 1 1
      src/views/resource/videoManagement/courseManagement/basicInfoEdit/index.vue
  43. 1 1
      src/views/resource/videoManagement/courseManagement/chapterContent/index.vue
  44. 1 1
      src/views/resource/videoManagement/festival/edit/index.vue
  45. 221 2
      src/views/resource/videoManagement/moduleManagement/add/index.vue
  46. 233 19
      src/views/resource/videoManagement/moduleManagement/edit/index.vue
  47. 1 1
      src/views/system/menu/index.vue

+ 3 - 0
.env.production

@@ -7,3 +7,6 @@ ENV = 'production'
 # 中正云教育管理后台/生产环境
 VUE_APP_BASE_API = 'https://cloud.xyyxt.net/'
 VUE_APP_IMG_API = 'https://file.xyyxt.net'
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 4 - 0
.env.staging

@@ -8,4 +8,8 @@ ENV = 'staging'
 
 # 中正云教育管理后台/预发布环境
 VUE_APP_BASE_API = 'http://120.79.166.78:19007/'
+VUE_APP_BASE_API1 = 'http://192.168.1.222:5030/'
 VUE_APP_IMG_API = 'https://file-dev.xyyxt.net'
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 1 - 2
public/index.html

@@ -11,8 +11,7 @@
     <%= webpackConfig.name %>
   </title>
   <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
-
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
+  <script src="https://manage.xyyxt.net/static/js/gsap.min.js"></script>
   <style>
     html,
     body,

BIN
src/assets/images/idcardF.png


BIN
src/assets/images/idcardZ.png


BIN
src/assets/images/peopleImg.png


+ 45 - 5
src/components/tableList.vue

@@ -974,6 +974,17 @@
                 : ""
             }}
           </span>
+          <div
+            v-else-if="item.scope === 'RealPrice'"
+            :style="
+              scope.row[item.prop2] != null ? 'color:rgb(132, 0, 255);' : ''
+            "
+          >
+            ¥{{ scope.row[item.prop1] }}
+            <span v-if="scope.row[item.prop2] != null">
+              (实收¥{{ scope.row[item.prop2] }})</span
+            >
+          </div>
           <span
             v-else-if="item.scope === 'statusPeriod'"
             :style="scope.row[item.prop] === 2 ? 'color:red' : ''"
@@ -1204,6 +1215,15 @@
             @click="editInfo(scope.row)"
             >{{ scope.row[item.prop] }}
           </span>
+          <div v-else-if="item.scope === 'editName'">
+            <span>{{ scope.row[item.prop] }}</span>
+            <el-button
+              style="margin-left: 6px"
+              type="text"
+              @click="editInfo(scope.row, 2)"
+              >修改</el-button
+            >
+          </div>
           <span
             class="editInfoSty"
             v-else-if="item.scope === 'editInfoMore'"
@@ -1398,6 +1418,24 @@
               >
             </template>
           </div>
+          <div v-else-if="item.scope === 'isOptionsDY'">
+            <template v-for="(itemt, indext) in item.options">
+              <span
+                :key="indext"
+                v-if="itemt.value === scope.row[item.prop]"
+                :style="
+                  scope.row[item.prop] == 5 ? 'color:rgb(132, 0, 255);' : ''
+                "
+                >{{ itemt.label }}
+                <el-button
+                  type="text"
+                  v-if="itemt.click"
+                  @click="backFunc(scope.row)"
+                  >查看</el-button
+                ></span
+              >
+            </template>
+          </div>
           <div v-else-if="item.scope === 'orderGoodsStatus'">
             {{
               scope.row[item.prop] === -1
@@ -1433,14 +1471,14 @@
           <div v-else-if="item.scope === 'priceRed'" style="color: red">
             ¥{{ scope.row[item.prop] ? scope.row[item.prop] : 0 }}
           </div>
-          <span v-else
-            >{{ scope.row[item.prop] }}
+          <div v-else>
+            {{ scope.row[item.prop] }}
             {{
               (scope.row[item.prop] || scope.row[item.prop] === 0) && item.ch
                 ? item.ch
                 : ""
-            }}</span
-          >
+            }}
+          </div>
         </template>
       </af-table-column>
 
@@ -2591,7 +2629,9 @@ export default {
       this.$emit("load", tree, treeNode, resolve);
     },
     editInfo(option, int) {
-      if (int === 3) {
+      if (int === 2) {
+        this.$emit("editName", option);
+      } else if (int === 3) {
         this.$emit("aboutGoods", option);
       } else {
         this.$emit("editInfo", option);

+ 16 - 1
src/newApi/business.js

@@ -55,7 +55,6 @@ export default {
             data
         })
     },
-
     //修改业务层次-退款审核
     editRefundPeriodUserIdsCourseBusiness(data) {
         return request({
@@ -64,5 +63,21 @@ export default {
             data
         })
     },
+    //新增业务层次过滤器
+    addBasefilter(data) {
+        return request({
+            url: '/base/filter',
+            method: 'post',
+            data
+        })
+    },
+    //查询业务层次过滤器列表
+    basefilterlist(data) {
+        return request({
+            url: '/base/filter/list',
+            method: 'get',
+            params: data
+        })
+    },
 
 }

+ 8 - 0
src/newApi/modules.js

@@ -45,4 +45,12 @@ export default {
             method: 'get',
         })
     },
+    //导入章节模板
+    CoursemoduleimportData(data) {
+        return request({
+            url: '/course/module/importData',
+            method: 'post',
+            data
+        })
+    },
 }

+ 0 - 5
src/router/index.js

@@ -48,11 +48,6 @@ export const constantRoutes = [
     component: (resolve) => require(['@/views/login'], resolve),
     hidden: true
   },
-  {
-    path: '/register',
-    component: (resolve) => require(['@/views/register'], resolve),
-    hidden: true
-  },
   {
     path: '/404',
     component: (resolve) => require(['@/views/error/404'], resolve),

+ 258 - 0
src/views/2Cport/filterItemSettings/index.vue

@@ -0,0 +1,258 @@
+<template>
+  <div id="filterItemSettings">
+    <div class="filter_style" v-for="(item, index) in listSet" :key="index">
+      <h4>{{ item.title }}</h4>
+      <div class="over_flow">
+        <el-tree
+          :props="props"
+          :load="loadNode"
+          lazy
+          show-checkbox
+          node-key="keyId"
+          default-expand-all
+          :ref="`tree${item.value}`"
+          :default-checked-keys="item.activeKeyId"
+        >
+          <span class="custom-tree-node" slot-scope="{ node }">
+            <span
+              >{{ node.label }}
+              <span v-if="node.data.projectId"
+                >(别名:{{ node.data.aliasName }})</span
+              ></span
+            >
+          </span>
+        </el-tree>
+      </div>
+      <div class="margin_bth">
+        <el-button
+          :size="size"
+          @click="submitFunc(`tree${item.value}`, item.value)"
+          >保存</el-button
+        >
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "FilterItemSettings",
+  data() {
+    return {
+      //按钮及输入框尺寸
+      size: "mini",
+      //字段设置
+      listSet: [
+        {
+          title: "视频课程筛选项",
+          value: 1,
+          activeKeyId: [],
+        },
+        {
+          title: "直播课程筛选项",
+          value: 6,
+          activeKeyId: [],
+        },
+        {
+          title: "题库筛选项",
+          value: 2,
+          activeKeyId: [],
+        },
+      ],
+      props: {
+        label: "name",
+        children: "zones",
+        isLeaf(data, node) {
+          return data.noChildren ? true : false;
+        },
+      },
+    };
+  },
+  mounted() {
+    this.$api.basefilterlist().then((res) => {
+      res.rows.forEach((item) => {
+        this.listSet.forEach((items) => {
+          if (items.value === item.type) {
+            const NewTheList = item.subjectIds.split(",").map(Number);
+            items.activeKeyId = NewTheList.map((itx) => {
+              return `${item.educationId}-${item.projectId}-${item.businessId}-${itx}`;
+            });
+          }
+        });
+      });
+      console.log(this.listSet);
+    });
+  },
+  methods: {
+    getInitEduSet() {
+      return new Promise((resolve, reject) => {
+        //获取教育类型
+        this.$api
+          .inquireCourseEducationType({ status: 1 })
+          .then((res) => {
+            const LIST = res.rows.map((item) => {
+              return {
+                id: item.id,
+                keyId: item.id,
+                name: item.educationName,
+                type: 1, //1教育类型--区分类型优化数据分类处理过程
+              };
+            });
+            resolve(LIST);
+          })
+          .catch((err) => {
+            this.$message.error("教育类型获取失败");
+          });
+      });
+    },
+    getInitBusSet(id) {
+      return new Promise((resolve, reject) => {
+        //获取项目类型-业务层次
+        this.$api
+          .inquirebusinessList({ status: 1, educationId: id })
+          .then((res) => {
+            const LIST = res.rows.map((item) => {
+              return {
+                id: item.id,
+                educationId: item.educationId,
+                projectId: item.projectId,
+                keyId: `${item.educationId}-${item.projectId}-${item.id}`,
+                name: `${item.projectName} - ${item.businessName}`,
+                aliasName: item.aliasName || "",
+                type: 2, //2业务层次类型--区分类型优化数据分类处理过程
+              };
+            });
+            resolve(LIST);
+          })
+          .catch((err) => {
+            this.$message.error("业务层级获取失败");
+          });
+      });
+    },
+    getInitSubjectSet(id, parentKeyId) {
+      return new Promise((resolve, reject) => {
+        //获取科目
+        this.$api
+          .inquireCourseSubject({ status: 1, businessId: id })
+          .then((res) => {
+            const LIST = res.rows.map((item) => {
+              return {
+                id: item.id,
+                keyId: `${parentKeyId}-${item.id}`,
+                parentKeyId: parentKeyId,
+                name: item.subjectName,
+                noChildren: true,
+                type: 3, //3科目类型--区分类型优化数据分类处理过程
+              };
+            });
+            resolve(LIST);
+          })
+          .catch((err) => {
+            this.$message.error("科目获取失败");
+          });
+      });
+    },
+    loadNode(node, resolve) {
+      if (node.level === 0) {
+        this.getInitEduSet().then((list) => {
+          return resolve(list);
+        });
+      } else if (node.level === 1) {
+        this.getInitBusSet(node.data.id).then((list) => {
+          return resolve(list);
+        });
+      } else if (node.level === 2) {
+        this.getInitSubjectSet(node.data.id, node.data.keyId).then((list) => {
+          return resolve(list);
+        });
+      } else {
+        return resolve([]);
+      }
+    },
+    /**
+     * @param {String} 'ref组件名'
+     * @param {Number} '保存筛选项类型'
+     */
+    submitFunc(refName, typeValue) {
+      //获取半/全选中数据数组列表
+      const ITEMLIST = this.$refs[refName][0].getCheckedNodes(false, true);
+      //半选中/全选中--业务层次数组
+      let BusList = [];
+      //选中科目数组
+      let subjectList = [];
+      //半/全选中数据数组列表分类
+      ITEMLIST.forEach((item) => {
+        if (item.type === 2) {
+          BusList.push({
+            type: typeValue,
+            educationId: item.educationId,
+            projectId: item.projectId,
+            businessId: item.id,
+            status: 1,
+            subjectIds: [],
+            keyId: item.keyId,
+          });
+        }
+        if (item.type === 3) {
+          subjectList.push(item);
+        }
+      });
+      BusList.forEach((item) => {
+        subjectList.forEach((items) => {
+          if (items.parentKeyId === item.keyId) {
+            item.subjectIds.push(items.id);
+          }
+        });
+      });
+      for (let i = 0; i < BusList.length; i++) {
+        BusList[i].subjectIds = BusList[i].subjectIds.toString();
+        delete BusList[i].keyId;
+      }
+      //数据整理完毕-执行提交
+      this.sendFunc(BusList);
+    },
+    sendFunc(item) {
+      this.$api.addBasefilter(item).then((res) => {
+        this.$message.success("保存成功");
+        //重新获取最新数据
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.filter_style {
+  border-radius: 6px;
+  border: 1px solid #666;
+  float: left;
+  margin: 0px 3% 16px 0px;
+  padding: 6px 14px;
+  width: 30%;
+  h4 {
+    height: 36px;
+    line-height: 36px;
+    margin: 4px 0px;
+    font-weight: 500;
+  }
+}
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 14px;
+  padding: 4px 0px;
+  margin: 4px 0px;
+}
+.margin_bth {
+  text-align: center;
+}
+.over_flow {
+  max-height: 76vh;
+  overflow: auto;
+}
+/deep/ .el-tree-node__content {
+  margin: 4px 0px;
+}
+</style>

+ 2 - 3
src/views/Marketing/goods/commodityManageMent/add/courseContent/index.vue

@@ -108,8 +108,6 @@
     <popple-set
       :key="Math.random()"
       ref="poppleSet"
-      :tableData="tableData"
-      :auditionList="auditionList"
       @uploadArrays="uploadArrays"
     />
     <course-check ref="courseCheck" @backData="backVideoData" />
@@ -314,7 +312,8 @@ export default {
      * 点击试听函数
      */
     openAudition() {
-      this.$refs.poppleSet.dialogVisible = true;
+      console.log(this.tableData,this.auditionList)
+      this.$refs.poppleSet.openExpand(this.tableData,this.auditionList)
     },
     /**
      * 试听回调数据

+ 6 - 3
src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue

@@ -115,8 +115,6 @@
     <popple-set
       :key="Math.random()"
       ref="poppleSet"
-      :tableData="tableData"
-      :auditionList="auditionList"
       @uploadArrays="uploadArrays"
     />
     <course-check ref="courseCheck" @backData="backVideoData" />
@@ -234,6 +232,10 @@ export default {
     getMoreList(id) {
       this.$api.inquireCoursemenuListS({ courseId: id }).then((res) => {
         res.rows.forEach((item) => {
+          item.auditionMinute = this.$methodsTools.secondToDate(
+            item.durationTime,
+            false
+          );
           item.name = item.menuName;
         });
         this.tableData = res.rows;
@@ -366,7 +368,8 @@ export default {
      * 点击试听函数
      */
     openAudition() {
-      this.$refs.poppleSet.dialogVisible = true;
+      console.log(this.tableData, this.auditionList);
+      this.$refs.poppleSet.openExpand(this.tableData, this.auditionList);
     },
     /**
      * 试听回调数据

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

@@ -795,7 +795,7 @@ export default {
     checkSubmitInfo() {
       this.$api.gradecheckGoodsChange({ goodsId: this.goodsId }).then((res) => {
         if (res.data > 0) {
-          this.submitStatusInfo = true;
+          // this.submitStatusInfo = true;
         }
       });
     },
@@ -977,6 +977,7 @@ export default {
               item.sort = Number(item.sort);
               return item;
             });
+            data.courseList = []
           } else {
             data.courseList = this.$refs.courseContent.tableData.map((item) => {
               return {
@@ -984,6 +985,7 @@ export default {
                 sort: Number(item.sort),
               };
             });
+            data.menuList = []
           }
         } else {
           data.courseList = [];

+ 50 - 43
src/views/Marketing/goods/commodityManageMent/poppleSet.vue

@@ -3,10 +3,10 @@
     <el-dialog
       :visible.sync="dialogVisible"
       width="60%"
-      @open="openExpand"
       :show-close="false"
       :close-on-click-modal="false"
       destroy-on-close
+      @closed="showPop = false"
     >
       <div slot="title" class="hearders">
         <div class="leftTitle">试听设置</div>
@@ -21,39 +21,39 @@
       <div style="text-align: end">
         <el-button type="text" @click="inits">重置</el-button>
       </div>
-        <el-tree
-          v-if="showPop"
-          ref="trees"
-          :data="datas"
-          :props="layoutTreeProps"
-          :load="loadNode"
-          lazy
-          :default-checked-keys="audition"
-          :show-checkbox="true"
-          :check-strictly="true"
-          @check-change="getCheckedKeys"
-          node-key="onlyId"
-        >
-          <span class="custom-tree-node" slot-scope="{ node }">
-            <span>{{ node.label }}</span>
-            <span v-if="node.checked && node.data.sectionType !== 2"
-              >试听前
-              <el-time-picker
-                style="width: 140px"
-                size="mini"
-                value-format="HH:mm:ss"
-                range-separator="-"
-                v-model="node.data.auditionMinute"
-                :picker-options="{
-                  selectableRange: compTimes(node.data.durationTime),
-                }"
-                placeholder="请选择试听时长"
-                @blur="changeNum(node)"
-              >
-              </el-time-picker>
-            </span>
+      <el-tree
+        v-if="showPop"
+        ref="trees"
+        :data="datas"
+        :props="layoutTreeProps"
+        :load="loadNode"
+        lazy
+        :default-checked-keys="audition"
+        :show-checkbox="true"
+        :check-strictly="true"
+        @check-change="getCheckedKeys"
+        node-key="onlyId"
+      >
+        <span class="custom-tree-node" slot-scope="{ node }">
+          <span>{{ node.label }}</span>
+          <span v-if="node.checked && node.data.sectionType !== 2"
+            >试听前
+            <el-time-picker
+              style="width: 140px"
+              size="mini"
+              value-format="HH:mm:ss"
+              range-separator="-"
+              v-model="node.data.auditionMinute"
+              :picker-options="{
+                selectableRange: compTimes(node.data.durationTime),
+              }"
+              placeholder="请选择试听时长"
+              @blur="changeNum(node)"
+            >
+            </el-time-picker>
           </span>
-        </el-tree>
+        </span>
+      </el-tree>
       <span slot="footer" class="dialog-footer">
         <el-button @click="dialogVisible = false">取 消</el-button>
         <el-button type="primary" @click="submitTable">确 定</el-button>
@@ -64,9 +64,10 @@
 
 <script>
 export default {
-  props: ["tableData", "auditionList"],
   data() {
     return {
+      tableData: [],
+      auditionitem: [],
       copyData: [],
       showPop: false,
       datas: [],
@@ -170,11 +171,14 @@ export default {
     /**
      * 弹窗打开触发
      */
-    openExpand() {
-      this.showPop = true;
-      if (this.auditionList) {
-        this.auditionListCope = JSON.parse(JSON.stringify(this.auditionList));
+    openExpand(item, auditionitem) {
+      this.auditionitem = JSON.parse(JSON.stringify(auditionitem));
+      this.tableData = JSON.parse(JSON.stringify(item));
+      if (auditionitem) {
+        this.auditionListCope = JSON.parse(JSON.stringify(auditionitem));
       }
+      this.dialogVisible = true;
+      this.showPop = true;
     },
     /**
      * @param {Objact,Bool} 当前点击数据 当前是否勾选
@@ -240,23 +244,26 @@ export default {
         this.$message.warning("请勾选至少一节的试听时间");
         return;
       }
-      this.auditionListCope.forEach((item) => {
-        if (!item.auditionMinute || item.auditionMinute === "00:00:00") {
+      for (let i = 0; i < this.auditionListCope.length; i++) {
+        if (
+          !this.auditionListCope[i].auditionMinute ||
+          this.auditionListCope[i].auditionMinute === "00:00:00"
+        ) {
           this.$message.warning("不允许填写时长为0的节,请重新输入");
           return;
         }
-      });
+      }
       this.$emit("uploadArrays", this.auditionListCope);
       this.dialogVisible = false;
     },
     loadNode(node, resolve) {
       var self = this;
       if (node.level === 0) {
+        console.log(11)
         if (this.tableData[0].type > 0) {
           this.tableData.forEach((item) => {
             item.TypeId = `${item.type}-${item.menuId}`;
             if (item.type === 3) {
-              console.log(item,'item')
               item.hasChildren = false;
               item.disabled = false;
               item.onlyId = `${item.courseId || 0}-0-0-${item.menuId}`;
@@ -264,7 +271,7 @@ export default {
                 self.getAllSeNum.push(item.onlyId);
               }
               if (self.auditionListCope) {
-                self.auditionListCope.map((items) => {
+                self.auditionListCope.forEach((items) => {
                   if (items.TypeId === item.TypeId) {
                     if (self.audition.indexOf(item.onlyId) === -1) {
                       self.audition.push(item.onlyId);

+ 5 - 3
src/views/Marketing/order/offlineOrder/batchRecord/firstStep/index.vue

@@ -257,7 +257,11 @@ export default {
     uploadList(arr) {
       let ays = JSON.parse(JSON.stringify(arr));
       ays.forEach((item) => {
-        item.subjectIds = item.subjectIds.split(",").map(Number);
+        if(item.subjectIds){
+          item.subjectIds = item.subjectIds.split(",").map(Number);
+        }else{
+          item.subjectIds = []
+        }
       });
       let newObjs = this.tableData.concat(ays);
       this.tableData = this.$methodsTools.uniqueFunc(newObjs, "userId");
@@ -413,8 +417,6 @@ export default {
 }
 .rowSty {
   display: flex;
-  .ulSty {
-  }
   .spanSty {
     width: 50px;
     flex-shrink: 0;

+ 33 - 3
src/views/Marketing/order/offlineOrder/index.vue

@@ -25,6 +25,7 @@
           >订单详情</el-button
         >
         <el-button type="text" @click="theOrderJump(props.scope.row, 2)"
+        :disabled="props.scope.row.orderFrom == 5"
           >计费单收费</el-button
         >
         <el-button type="text" @click="theOrderJump(props.scope.row, 3)"
@@ -142,10 +143,10 @@ export default {
         },
         {
           label: "已收总金额",
-          prop: "goodsReceived",
+          prop1: "goodsReceived",
+          prop2: "goodsRealPrice",
           hidden: true,
-          scope: "leftCh",
-          ch: "¥",
+          scope: "RealPrice",
         },
         {
           label: "已退总金额",
@@ -161,6 +162,35 @@ export default {
           hidden: true,
           scope: "outStandingAmount",
         },
+        {
+          label: "订单来源",
+          prop: "orderFrom",
+          hidden: true,
+          scope: "isOptionsDY",
+          width: "130px",
+          options: [
+            {
+              label: "业务员普通单",
+              value: "1",
+            },
+            {
+              label: "祥粤云学堂小程序",
+              value: "2",
+            },
+            {
+              label: "祥粤云学堂网站",
+              value: "3",
+            },
+            {
+              label: "祥粤e管证小程序",
+              value: "4",
+            },
+            {
+              label: "业务员录单",
+              value: "5",
+            },
+          ],
+        },
         {
           label: "录单人",
           prop: "createUsername",

+ 10 - 1
src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/costPrice.vue

@@ -91,6 +91,7 @@
           <el-col :span="12">
             <el-form-item label="付款时间">
               <el-input
+                class="inputStyle"
                 disabled
                 :value="$methodsTools.onlyForma(listData.payTime)"
               ></el-input>
@@ -130,6 +131,7 @@
           <el-col :span="12">
             <el-form-item label="收款时间">
               <el-input
+                class="inputStyle"
                 disabled
                 :value="$methodsTools.onlyForma(listData.collectionTime)"
               ></el-input>
@@ -170,7 +172,11 @@
           </el-col>
           <el-col :span="12">
             <el-form-item label="收费金额" prop="amount">
-              <el-input disabled v-model="costList.amount"></el-input>
+              <el-input
+                class="inputStyle"
+                disabled
+                v-model="costList.amount"
+              ></el-input>
             </el-form-item>
           </el-col>
           <el-col :span="24">
@@ -326,4 +332,7 @@ export default {
   color: #666;
   margin-bottom: 10px;
 }
+/deep/ .inputStyle > .el-input__inner {
+  color: rgb(132, 0, 255);
+}
 </style>

+ 18 - 5
src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/goodsInfos.vue

@@ -59,6 +59,7 @@
                 :size="size"
                 :disabled="item.disabled ? false : true"
                 v-else
+                :class="item.color ? 'inputStyle' : ''"
                 v-model="listData[item.prop]"
               ></el-input>
             </template>
@@ -196,6 +197,7 @@
             </el-select>
             <el-input
               :size="size"
+              :class="item.color ? 'inputStyle' : ''"
               :disabled="item.noDisabled ? false : true"
               v-else
               v-model="listData[item.prop]"
@@ -327,12 +329,19 @@ export default {
           label: "支付金额",
           prop: "goodsReceived",
           dataType: "listData",
+          color: true,
         },
         {
           label: "商品类型",
           prop: "goodsType",
           scope: "select",
         },
+        {
+          label: "实收金额",
+          prop: "goodsRealPrice",
+          dataType: "listData",
+          color: true,
+        },
         {
           label: "支付状态",
           prop: "payStatus",
@@ -347,6 +356,11 @@ export default {
           label: "商品名称",
           prop: "goodsName",
         },
+        {
+          label: "商品标准价格明细",
+          prop: "payer",
+          scope: "table",
+        },
         {
           label: "业务层级",
           prop1: "educationName",
@@ -354,11 +368,6 @@ export default {
           prop3: "businessName",
           scope: "yecj",
         },
-        {
-          label: "商品标准价格明细",
-          prop: "payer",
-          scope: "table",
-        },
         {
           label: "商品有效期",
           prop: "validity",
@@ -400,6 +409,7 @@ export default {
         {
           label: "录单人",
           prop: "createBy",
+          color: true,
         },
       ],
       copyStatus: "", //拷贝订单状态
@@ -501,4 +511,7 @@ export default {
 /deep/ .el-input__inner {
   width: 350px;
 }
+/deep/ .inputStyle > .el-input__inner {
+  color: rgb(132, 0, 255);
+}
 </style>

+ 33 - 3
src/views/Marketing/order/offlineOrder/orderChargeInfo/topBox.vue

@@ -9,6 +9,7 @@
             size="mini"
           >
             <el-input
+              :class="item.color ? 'inputStyle' : ''"
               readonly
               :value="(formData[item.prop1] - formData[item.prop2]).toFixed(2)"
             ></el-input>
@@ -29,6 +30,22 @@
               "
             ></el-input>
           </el-form-item>
+          <el-row v-else-if="item.scope === 'span'">
+            <el-col :span="15">
+              <el-form-item :label="item.label1" size="mini">
+                <el-input
+                  readonly
+                  :value="formData[item.prop1]"
+                ></el-input></el-form-item
+            ></el-col>
+            <el-col :span="9"
+              ><el-form-item  label-width="90px" :label="item.label2" size="mini">
+                <el-input
+                  readonly
+                  :value="formData[item.prop2]"
+                ></el-input> </el-form-item
+            ></el-col>
+          </el-row>
           <el-form-item
             v-else-if="item.scope === 'time'"
             :label="item.label"
@@ -58,7 +75,11 @@
             ><span style="margin: 0px 6px">商品</span>
           </el-form-item>
           <el-form-item v-else :label="item.label" size="mini">
-            <el-input readonly :value="formData[item.prop]"></el-input>
+            <el-input
+              :class="item.color ? 'inputStyle' : ''"
+              readonly
+              :value="formData[item.prop]"
+            ></el-input>
           </el-form-item>
         </el-col>
       </el-row>
@@ -83,8 +104,12 @@ export default {
           scope: "busin",
         },
         {
-          label: "已收金额:",
-          prop: "goodsReceived",
+          label1: "已收金额:",
+          label2: "实收金额:",
+          prop1: "goodsReceived",
+          prop2: "goodsRealPrice",
+          color: true,
+          scope: "span",
         },
         {
           label: "订单时间:",
@@ -98,6 +123,7 @@ export default {
         {
           label: "已退金额:",
           prop: "goodsRefund",
+          color: true,
         },
         {
           label: "录单人:",
@@ -112,6 +138,7 @@ export default {
           prop1: "payPrice",
           prop2: "goodsReceived",
           scope: "comput",
+          color: true,
         },
         {
           label: "下单结果:",
@@ -147,4 +174,7 @@ export default {
 #topBox {
   flex-shrink: 0;
 }
+/deep/ .inputStyle > .el-input__inner {
+  color: rgb(132, 0, 255);
+}
 </style>

+ 3 - 3
src/views/Marketing/order/offlineOrder/orderDetailsT/index.vue

@@ -259,10 +259,10 @@ export default {
         },
         {
           label: "已收金额",
-          prop: "goodsReceived",
+          prop1: "goodsReceived",
+          prop2: "goodsRealPrice",
           hidden: true,
-          scope: "leftCh",
-          ch: "¥",
+          scope: "RealPrice",
         },
         {
           label: "未收金额",

+ 0 - 102
src/views/dashboard/BarChart.vue

@@ -1,102 +0,0 @@
-<template>
-  <div :class="className" :style="{height:height,width:width}" />
-</template>
-
-<script>
-import echarts from 'echarts'
-require('echarts/theme/macarons') // echarts theme
-import resize from './mixins/resize'
-
-const animationDuration = 6000
-
-export default {
-  mixins: [resize],
-  props: {
-    className: {
-      type: String,
-      default: 'chart'
-    },
-    width: {
-      type: String,
-      default: '100%'
-    },
-    height: {
-      type: String,
-      default: '300px'
-    }
-  },
-  data() {
-    return {
-      chart: null
-    }
-  },
-  mounted() {
-    this.$nextTick(() => {
-      this.initChart()
-    })
-  },
-  beforeDestroy() {
-    if (!this.chart) {
-      return
-    }
-    this.chart.dispose()
-    this.chart = null
-  },
-  methods: {
-    initChart() {
-      this.chart = echarts.init(this.$el, 'macarons')
-
-      this.chart.setOption({
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: { // 坐标轴指示器,坐标轴触发有效
-            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
-          }
-        },
-        grid: {
-          top: 10,
-          left: '2%',
-          right: '2%',
-          bottom: '3%',
-          containLabel: true
-        },
-        xAxis: [{
-          type: 'category',
-          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
-          axisTick: {
-            alignWithLabel: true
-          }
-        }],
-        yAxis: [{
-          type: 'value',
-          axisTick: {
-            show: false
-          }
-        }],
-        series: [{
-          name: 'pageA',
-          type: 'bar',
-          stack: 'vistors',
-          barWidth: '60%',
-          data: [79, 52, 200, 334, 390, 330, 220],
-          animationDuration
-        }, {
-          name: 'pageB',
-          type: 'bar',
-          stack: 'vistors',
-          barWidth: '60%',
-          data: [80, 52, 200, 334, 390, 330, 220],
-          animationDuration
-        }, {
-          name: 'pageC',
-          type: 'bar',
-          stack: 'vistors',
-          barWidth: '60%',
-          data: [30, 52, 200, 334, 390, 330, 220],
-          animationDuration
-        }]
-      })
-    }
-  }
-}
-</script>

+ 0 - 135
src/views/dashboard/LineChart.vue

@@ -1,135 +0,0 @@
-<template>
-  <div :class="className" :style="{height:height,width:width}" />
-</template>
-
-<script>
-import echarts from 'echarts'
-require('echarts/theme/macarons') // echarts theme
-import resize from './mixins/resize'
-
-export default {
-  mixins: [resize],
-  props: {
-    className: {
-      type: String,
-      default: 'chart'
-    },
-    width: {
-      type: String,
-      default: '100%'
-    },
-    height: {
-      type: String,
-      default: '350px'
-    },
-    autoResize: {
-      type: Boolean,
-      default: true
-    },
-    chartData: {
-      type: Object,
-      required: true
-    }
-  },
-  data() {
-    return {
-      chart: null
-    }
-  },
-  watch: {
-    chartData: {
-      deep: true,
-      handler(val) {
-        this.setOptions(val)
-      }
-    }
-  },
-  mounted() {
-    this.$nextTick(() => {
-      this.initChart()
-    })
-  },
-  beforeDestroy() {
-    if (!this.chart) {
-      return
-    }
-    this.chart.dispose()
-    this.chart = null
-  },
-  methods: {
-    initChart() {
-      this.chart = echarts.init(this.$el, 'macarons')
-      this.setOptions(this.chartData)
-    },
-    setOptions({ expectedData, actualData } = {}) {
-      this.chart.setOption({
-        xAxis: {
-          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
-          boundaryGap: false,
-          axisTick: {
-            show: false
-          }
-        },
-        grid: {
-          left: 10,
-          right: 10,
-          bottom: 20,
-          top: 30,
-          containLabel: true
-        },
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'cross'
-          },
-          padding: [5, 10]
-        },
-        yAxis: {
-          axisTick: {
-            show: false
-          }
-        },
-        legend: {
-          data: ['expected', 'actual']
-        },
-        series: [{
-          name: 'expected', itemStyle: {
-            normal: {
-              color: '#FF005A',
-              lineStyle: {
-                color: '#FF005A',
-                width: 2
-              }
-            }
-          },
-          smooth: true,
-          type: 'line',
-          data: expectedData,
-          animationDuration: 2800,
-          animationEasing: 'cubicInOut'
-        },
-        {
-          name: 'actual',
-          smooth: true,
-          type: 'line',
-          itemStyle: {
-            normal: {
-              color: '#3888fa',
-              lineStyle: {
-                color: '#3888fa',
-                width: 2
-              },
-              areaStyle: {
-                color: '#f3f8ff'
-              }
-            }
-          },
-          data: actualData,
-          animationDuration: 2800,
-          animationEasing: 'quadraticOut'
-        }]
-      })
-    }
-  }
-}
-</script>

+ 0 - 181
src/views/dashboard/PanelGroup.vue

@@ -1,181 +0,0 @@
-<template>
-  <el-row :gutter="40" class="panel-group">
-    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('newVisitis')">
-        <div class="card-panel-icon-wrapper icon-people">
-          <svg-icon icon-class="peoples" class-name="card-panel-icon" />
-        </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            访客
-          </div>
-          <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
-        </div>
-      </div>
-    </el-col>
-    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('messages')">
-        <div class="card-panel-icon-wrapper icon-message">
-          <svg-icon icon-class="message" class-name="card-panel-icon" />
-        </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            消息
-          </div>
-          <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
-        </div>
-      </div>
-    </el-col>
-    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('purchases')">
-        <div class="card-panel-icon-wrapper icon-money">
-          <svg-icon icon-class="money" class-name="card-panel-icon" />
-        </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            金额
-          </div>
-          <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
-        </div>
-      </div>
-    </el-col>
-    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('shoppings')">
-        <div class="card-panel-icon-wrapper icon-shopping">
-          <svg-icon icon-class="shopping" class-name="card-panel-icon" />
-        </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            订单
-          </div>
-          <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
-        </div>
-      </div>
-    </el-col>
-  </el-row>
-</template>
-
-<script>
-import CountTo from 'vue-count-to'
-
-export default {
-  components: {
-    CountTo
-  },
-  methods: {
-    handleSetLineChartData(type) {
-      this.$emit('handleSetLineChartData', type)
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.panel-group {
-  margin-top: 18px;
-
-  .card-panel-col {
-    margin-bottom: 32px;
-  }
-
-  .card-panel {
-    height: 108px;
-    cursor: pointer;
-    font-size: 12px;
-    position: relative;
-    overflow: hidden;
-    color: #666;
-    background: #fff;
-    box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
-    border-color: rgba(0, 0, 0, .05);
-
-    &:hover {
-      .card-panel-icon-wrapper {
-        color: #fff;
-      }
-
-      .icon-people {
-        background: #40c9c6;
-      }
-
-      .icon-message {
-        background: #36a3f7;
-      }
-
-      .icon-money {
-        background: #f4516c;
-      }
-
-      .icon-shopping {
-        background: #34bfa3
-      }
-    }
-
-    .icon-people {
-      color: #40c9c6;
-    }
-
-    .icon-message {
-      color: #36a3f7;
-    }
-
-    .icon-money {
-      color: #f4516c;
-    }
-
-    .icon-shopping {
-      color: #34bfa3
-    }
-
-    .card-panel-icon-wrapper {
-      float: left;
-      margin: 14px 0 0 14px;
-      padding: 16px;
-      transition: all 0.38s ease-out;
-      border-radius: 6px;
-    }
-
-    .card-panel-icon {
-      float: left;
-      font-size: 48px;
-    }
-
-    .card-panel-description {
-      float: right;
-      font-weight: bold;
-      margin: 26px;
-      margin-left: 0px;
-
-      .card-panel-text {
-        line-height: 18px;
-        color: rgba(0, 0, 0, 0.45);
-        font-size: 16px;
-        margin-bottom: 12px;
-      }
-
-      .card-panel-num {
-        font-size: 20px;
-      }
-    }
-  }
-}
-
-@media (max-width:550px) {
-  .card-panel-description {
-    display: none;
-  }
-
-  .card-panel-icon-wrapper {
-    float: none !important;
-    width: 100%;
-    height: 100%;
-    margin: 0 !important;
-
-    .svg-icon {
-      display: block;
-      margin: 14px auto !important;
-      float: none !important;
-    }
-  }
-}
-</style>

+ 0 - 79
src/views/dashboard/PieChart.vue

@@ -1,79 +0,0 @@
-<template>
-  <div :class="className" :style="{height:height,width:width}" />
-</template>
-
-<script>
-import echarts from 'echarts'
-require('echarts/theme/macarons') // echarts theme
-import resize from './mixins/resize'
-
-export default {
-  mixins: [resize],
-  props: {
-    className: {
-      type: String,
-      default: 'chart'
-    },
-    width: {
-      type: String,
-      default: '100%'
-    },
-    height: {
-      type: String,
-      default: '300px'
-    }
-  },
-  data() {
-    return {
-      chart: null
-    }
-  },
-  mounted() {
-    this.$nextTick(() => {
-      this.initChart()
-    })
-  },
-  beforeDestroy() {
-    if (!this.chart) {
-      return
-    }
-    this.chart.dispose()
-    this.chart = null
-  },
-  methods: {
-    initChart() {
-      this.chart = echarts.init(this.$el, 'macarons')
-
-      this.chart.setOption({
-        tooltip: {
-          trigger: 'item',
-          formatter: '{a} <br/>{b} : {c} ({d}%)'
-        },
-        legend: {
-          left: 'center',
-          bottom: '10',
-          data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
-        },
-        series: [
-          {
-            name: 'WEEKLY WRITE ARTICLES',
-            type: 'pie',
-            roseType: 'radius',
-            radius: [15, 95],
-            center: ['50%', '38%'],
-            data: [
-              { value: 320, name: 'Industries' },
-              { value: 240, name: 'Technology' },
-              { value: 149, name: 'Forex' },
-              { value: 100, name: 'Gold' },
-              { value: 59, name: 'Forecasts' }
-            ],
-            animationEasing: 'cubicInOut',
-            animationDuration: 2600
-          }
-        ]
-      })
-    }
-  }
-}
-</script>

+ 0 - 116
src/views/dashboard/RaddarChart.vue

@@ -1,116 +0,0 @@
-<template>
-  <div :class="className" :style="{height:height,width:width}" />
-</template>
-
-<script>
-import echarts from 'echarts'
-require('echarts/theme/macarons') // echarts theme
-import resize from './mixins/resize'
-
-const animationDuration = 3000
-
-export default {
-  mixins: [resize],
-  props: {
-    className: {
-      type: String,
-      default: 'chart'
-    },
-    width: {
-      type: String,
-      default: '100%'
-    },
-    height: {
-      type: String,
-      default: '300px'
-    }
-  },
-  data() {
-    return {
-      chart: null
-    }
-  },
-  mounted() {
-    this.$nextTick(() => {
-      this.initChart()
-    })
-  },
-  beforeDestroy() {
-    if (!this.chart) {
-      return
-    }
-    this.chart.dispose()
-    this.chart = null
-  },
-  methods: {
-    initChart() {
-      this.chart = echarts.init(this.$el, 'macarons')
-
-      this.chart.setOption({
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: { // 坐标轴指示器,坐标轴触发有效
-            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
-          }
-        },
-        radar: {
-          radius: '66%',
-          center: ['50%', '42%'],
-          splitNumber: 8,
-          splitArea: {
-            areaStyle: {
-              color: 'rgba(127,95,132,.3)',
-              opacity: 1,
-              shadowBlur: 45,
-              shadowColor: 'rgba(0,0,0,.5)',
-              shadowOffsetX: 0,
-              shadowOffsetY: 15
-            }
-          },
-          indicator: [
-            { name: 'Sales', max: 10000 },
-            { name: 'Administration', max: 20000 },
-            { name: 'Information Techology', max: 20000 },
-            { name: 'Customer Support', max: 20000 },
-            { name: 'Development', max: 20000 },
-            { name: 'Marketing', max: 20000 }
-          ]
-        },
-        legend: {
-          left: 'center',
-          bottom: '10',
-          data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
-        },
-        series: [{
-          type: 'radar',
-          symbolSize: 0,
-          areaStyle: {
-            normal: {
-              shadowBlur: 13,
-              shadowColor: 'rgba(0,0,0,.2)',
-              shadowOffsetX: 0,
-              shadowOffsetY: 10,
-              opacity: 1
-            }
-          },
-          data: [
-            {
-              value: [5000, 7000, 12000, 11000, 15000, 14000],
-              name: 'Allocated Budget'
-            },
-            {
-              value: [4000, 9000, 15000, 15000, 13000, 11000],
-              name: 'Expected Spending'
-            },
-            {
-              value: [5500, 11000, 12000, 15000, 12000, 12000],
-              name: 'Actual Spending'
-            }
-          ],
-          animationDuration: animationDuration
-        }]
-      })
-    }
-  }
-}
-</script>

+ 3 - 0
src/views/education/classManageMent/classHoursReview/index.vue

@@ -83,4 +83,7 @@ export default {
 </script>
 
 <style lang="less" scoped>
+/deep/ .el-tabs__content{
+  padding: 6px;
+}
 </style>

+ 353 - 254
src/views/education/classManageMent/classHoursReview/studyTimes.vue

@@ -1,117 +1,153 @@
 <template>
   <div id="studyTimes">
-    <div class="topBoxStyle">
-      <div class="dis_fs" :style="showBox ? '' : 'height:0px;'">
-        <ul class="ul_ls">
+    <div class="top_style">
+      <header>
+        <div class="left"><i></i><span>学员信息</span></div>
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「1」</strong>所购商品:{{
+            userData.goodsName
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「2」</strong>所在班级:{{
+            userData.className
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「3」</strong>学时:{{
+            userData.classHours
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「4」</strong>完成{{
+            userData.stuAllNum + userData.recordNum
+          }}节的内容学习</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「5」</strong>学习时间:{{
+            $methodsTools.onlyForma(userData.studyStartTime, false)
+          }}
+          - {{ $methodsTools.onlyForma(userData.studyEndTime, false) }}</span
+        >
+        <el-button type="primary" size="mini" @click="showBox = !showBox">{{
+          showBox ? "收起" : "展开"
+        }}</el-button>
+      </header>
+      <div class="info_img" v-show="showBox">
+        <ul>
           <li>学员编码:{{ userData.studentCode }}</li>
           <li>学员姓名:{{ userData.realName }}</li>
           <li>学员身份证号码:{{ userData.idCard }}</li>
           <li>绑定手机号码:{{ userData.telPhone }}</li>
         </ul>
-        <div class="photoSty1">
-          <img
-            style="width: 100%; height: 100%"
-            v-if="!userData.oneInchPhotos"
-            src="@/assets/404_images/wuyuxaog.png"
-            alt=""
-          />
-          <el-image
-            v-else
-            style="width: 100%; height: 100%"
-            :src="$methodsTools.splitImgHost(userData.oneInchPhotos)"
-            :preview-src-list="[
-              $methodsTools.splitImgHost(userData.oneInchPhotos),
-            ]"
-          >
-          </el-image>
-          <div class="pos_bottom">一寸头像图</div>
-        </div>
-        <div class="photoSty2">
-          <img
-            style="width: 100%; height: 100%"
-            v-if="!userData.idCardImg1"
-            src="@/assets/404_images/wuyuxaog.png"
-            alt=""
-          />
-          <el-image
-            v-else
-            style="width: 100%; height: 100%"
-            :src="$methodsTools.splitImgHost(userData.idCardImg1)"
-            :preview-src-list="[
-              $methodsTools.splitImgHost(userData.idCardImg1),
-            ]"
-          >
-          </el-image>
-          <div class="pos_bottom">身份证头像照</div>
-        </div>
-        <div class="photoSty2" style="margin-right: 0px">
-          <img
-            style="width: 100%; height: 100%"
-            v-if="!userData.idCardImg2"
-            src="@/assets/404_images/wuyuxaog.png"
-            alt=""
-          />
-          <el-image
-            v-else
-            style="width: 100%; height: 100%"
-            :src="$methodsTools.splitImgHost(userData.idCardImg2)"
-            :preview-src-list="[
-              $methodsTools.splitImgHost(userData.idCardImg2),
-            ]"
-          >
-          </el-image>
-          <div class="pos_bottom">身份证国徽照</div>
+        <div class="img_by">
+          <div class="photoSty1">
+            <img
+              v-if="!userData.oneInchPhotos"
+              src="@/assets/images/peopleImg.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.oneInchPhotos)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.oneInchPhotos),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">一寸头像图</div>
+          </div>
+          <div class="photoSty2">
+            <img
+              v-if="!userData.idCardImg1"
+              src="@/assets/images/idcardF.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg1)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg1),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证头像照</div>
+          </div>
+          <div class="photoSty2" style="margin-right: 0px">
+            <img
+              v-if="!userData.idCardImg2"
+              src="@/assets/images/idcardZ.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg2)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg2),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证国徽照</div>
+          </div>
         </div>
       </div>
-      <el-button
-        class="btn_styleShow"
-        type="primary"
-        size="mini"
-        @click="showBox = !showBox"
-        >{{ showBox ? "收起" : "展开" }}</el-button
-      >
     </div>
-
-    <div class="dis_fls">
-      <div class="s_sd">
-        <div class="dis_colu">
-          <div class="jdNumSty" style="margin-bottom: 4px">
-            视频学习进度:{{ userData.stuAllNum }}/{{ userData.secAllNum }}
-            {{
-              userData.stuAllNum == 0 && userData.secAllNum == 0
-                ? "0"
-                : ((userData.stuAllNum / userData.secAllNum) * 100).toFixed(2)
-            }}% 通过:{{ userData.pass }}节
-            <span style="color: #f56c6c">作弊:{{ userData.cheat }}节</span>
-            <span style="color: #409eff"> 待审:{{ userData.pending }}节</span>
+    <div class="studyStyle">
+      <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="jdNumSty">
-            做题学习进度:{{ userData.recordNum }}/{{ userData.examNum }}
-            {{
-              userData.recordNum == 0 && userData.examNum == 0
-                ? "0"
-                : ((userData.recordNum / userData.examNum) * 100).toFixed(2)
-            }}% 通过:{{ userData.examPass }}节
-            <span style="color: #f56c6c">作弊:{{ userData.examCheat }}节</span>
-            <span style="color: #409eff">
-              待审:{{ userData.examPending }}节</span
-            >
+          <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 class="shbtns">
-          学时审批状态:{{
-            userData.periodStatus === 0
-              ? "未通过"
-              : userData.periodStatus === 2
-              ? "待审核"
-              : userData.periodStatus === -1
-              ? "不可审核"
-              : userData.periodStatus === 1
-              ? "通过审核"
-              : userData.periodStatus === 3
-              ? "审核中"
-              : "未知状态,请联系管理员"
-          }}
+      </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">
+            {{
+              userData.periodStatus === 0
+                ? "未通过"
+                : userData.periodStatus === 2
+                ? "待审核"
+                : userData.periodStatus === -1
+                ? "不可审核"
+                : userData.periodStatus === 1
+                ? "通过审核"
+                : userData.periodStatus === 3
+                ? "审核中"
+                : "未知状态,请联系管理员"
+            }}
+          </div>
+          <div style="clear: both"></div>
         </div>
       </div>
       <div class="s_sd">
@@ -127,12 +163,14 @@
           <el-button
             style="margin-left: 10px"
             size="mini"
+            type="success"
             v-if="userData.periodStatus === 2"
             @click="getChangeStatus(1)"
             >勾选通过</el-button
           >
           <el-button
             size="mini"
+            type="danger"
             v-if="userData.periodStatus === 2"
             @click="getChangeStatus(2)"
             >勾选作弊</el-button
@@ -170,25 +208,29 @@
                 : ''
             ]
           "
-          style="width: 100%"
+          style="width: 100%; border-radius: 4px; overflow: hidden"
           :header-cell-style="
             asrt.value === 0
               ? {
-                  'background-color': 'skyblue',
+                  'background-color': '#CCDDF7',
                   padding: '8px',
-                  color: '#333',
+                  color: '#0047D0',
+                  'border-right-color': '#0047D0',
+                  'border-left-color': '#0047D0',
                 }
               : asrt.value === 1
               ? {
-                  'background-color': 'rgb(255,255,204)',
+                  'background-color': '#D9ECFA',
                   padding: '8px',
-                  color: '#333',
+                  color: '#1565C0',
+                  'border-right-color': '#1565C0',
+                  'border-left-color': '#1565C0',
                 }
               : asrt.value === 2
               ? {
-                  'background-color': '#eee',
+                  'background-color': '#F5F5F5',
                   padding: '8px',
-                  color: '#333',
+                  color: '#666',
                 }
               : ''
           "
@@ -278,7 +320,7 @@
                     :disabled="scope.row.status !== 2"
                     class="btnstyles"
                     size="small"
-                    type="warning"
+                    type="danger"
                     @click="changeStatus(scope.row, 2, scope.$index)"
                     >作弊</el-button
                   >
@@ -296,20 +338,21 @@
                     ? scope.row.classPeriodSectionList
                     : ''
                 "
-                style="width: 98%; margin-left: 2%"
                 :default-expand-all="defaultExpand"
                 :header-cell-style="
                   scope.row.type === 1
                     ? {
-                        'background-color': 'rgb(255,255,204)',
+                        'background-color': '#D9ECFA',
                         padding: '8px',
-                        color: '#333',
+                        color: '#1565C0',
+                        'border-right-color': '#1565C0',
+                        'border-left-color': '#1565C0',
                       }
                     : scope.row.type === 2
                     ? {
-                        'background-color': '#eee',
+                        'background-color': '#f5f5f5',
                         padding: '8px',
-                        color: '#333',
+                        color: '#666',
                       }
                     : ''
                 "
@@ -411,7 +454,7 @@
                           :disabled="scope2.row.status !== 2"
                           class="btnstyles"
                           size="small"
-                          type="warning"
+                          type="danger"
                           @click="
                             changeStatusCharpter(
                               scope2.row,
@@ -434,14 +477,13 @@
                           ? scope2.row.classPeriodSectionList
                           : ''
                       "
-                      style="width: 98%; margin-left: 2%"
                       :default-expand-all="defaultExpand"
                       :header-cell-style="
                         scope2.row.type === 2
                           ? {
-                              'background-color': '#eee',
+                              'background-color': '#f5f5f5',
                               padding: '8px',
-                              color: '#333',
+                              color: '#666',
                             }
                           : ''
                       "
@@ -533,7 +575,7 @@
                                 :disabled="scope3.row.status !== 2"
                                 class="btnstyles"
                                 size="small"
-                                type="warning"
+                                type="danger"
                                 @click="
                                   changeStatusModule(
                                     scope3.row,
@@ -565,7 +607,13 @@
                               v-for="(k, ds) in item.options"
                               :key="ds"
                               :style="
-                                scope3.row[item.prop] === 0 ? 'color:red;' : ''
+                                scope3.row[item.prop] === 0
+                                  ? 'color:red;'
+                                  : scope3.row[item.prop] === 2
+                                  ? 'color:#0047D0;'
+                                  : scope3.row[item.prop] === 1
+                                  ? 'color:#67C23A;'
+                                  : ''
                               "
                             >
                               {{
@@ -658,7 +706,15 @@
                       <span
                         v-for="(k, ds) in item.options"
                         :key="ds"
-                        :style="scope2.row[item.prop] === 0 ? 'color:red;' : ''"
+                        :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>
@@ -743,7 +799,15 @@
                 <span
                   v-for="(k, ds) in item.options"
                   :key="ds"
-                  :style="scope.row[item.prop] === 0 ? 'color:red;' : ''"
+                  :style="
+                    scope.row[item.prop] === 0
+                      ? 'color:red;'
+                      : scope.row[item.prop] === 2
+                      ? 'color:#0047D0;'
+                      : scope.row[item.prop] === 1
+                      ? 'color:#67C23A;'
+                      : ''
+                  "
                 >
                   {{ k.value == scope.row[item.prop] ? k.label : "" }}
                 </span>
@@ -1039,10 +1103,6 @@ export default {
           label: "模块标题",
           prop: "typeName",
         },
-        {
-          label: "学时",
-          prop: "classHours",
-        },
       ],
       tableSet2: [
         {
@@ -1091,6 +1151,7 @@ export default {
           label: "类型",
           prop: "type",
           scope: "typeOptions",
+          width: "90px",
           options: [
             {
               label: "节",
@@ -1105,7 +1166,7 @@ export default {
         {
           label: "节时长",
           prop: "durationTime",
-          width: "180px",
+          width: "120px",
           scope: "durTime",
         },
         {
@@ -1122,6 +1183,7 @@ export default {
           label: "审核状态",
           prop: "status",
           scope: "select",
+          width: "100px",
           options: [
             {
               label: "待审核",
@@ -1144,6 +1206,7 @@ export default {
         {
           label: "审核人",
           prop: "auditUserName",
+          width: "100px",
         },
         {
           label: "审核时间",
@@ -1223,7 +1286,7 @@ export default {
               parseSession = JSON.parse(SESSION);
             }
             if (parseSession.options.length > 1) {
-              this.$emit("removeTab",this.setData.keyId)
+              this.$emit("removeTab", this.setData.keyId);
             } else {
               this.$store
                 .dispatch("tagsView/delView", this.$route)
@@ -1873,16 +1936,157 @@ export default {
   },
 };
 </script>
-
 <style lang="less" scoped>
-.topBoxStyle {
-  position: relative;
-  .btn_styleShow {
-    position: absolute;
-    top: 0;
-    right: 0;
+.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;
+        }
+      }
+    }
+  }
+}
+.studyStyle {
+  margin: 16px 0px 0px;
+  display: flex;
+  align-items: center;
+  & > .a_style {
+    display: flex;
+    align-items: center;
+    margin: 0px 16px 16px 0px;
+    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;
+    margin: 0px 16px 16px 0px;
+    .dis_colu {
+      height: 55px;
+      margin-right: 14px;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-around;
+      font-size: 14px;
+    }
   }
 }
+/deep/ .el-table__expanded-cell {
+  background: #f5f5f5;
+}
+/deep/ .el-table__expanded-cell {
+  padding: 0px !important;
+}
 .li_sty {
   cursor: pointer;
   transition: all 0.3s;
@@ -1918,135 +2122,30 @@ export default {
 .dis_flexs {
   display: flex;
   align-items: center;
-}
-.dis_fs {
-  display: flex;
-  align-items: center;
-  height: 211px;
-  background-color: #eee;
-  padding: 0px 30px;
-  overflow: auto;
-  .ul_ls {
-    margin-right: 30px;
-    align-self: flex-start;
-    li {
-      font-size: 14px;
-      white-space: nowrap;
-      margin-bottom: 14px;
-    }
-  }
-  &::-webkit-scrollbar {
-    width: 14px;
-    height: 14px;
-  }
-
-  &::-webkit-scrollbar-track,
-  &::-webkit-scrollbar-thumb {
-    border-radius: 999px;
-    border: 5px solid transparent;
-  }
-
-  &::-webkit-scrollbar-track {
-    box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2) inset;
-  }
-
-  &::-webkit-scrollbar-thumb {
-    min-height: 20px;
-    background-clip: content-box;
-    box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.2) inset;
-  }
-
-  &::-webkit-scrollbar-corner {
-    background: transparent;
-  }
-}
-.photoSty1 {
-  flex-shrink: 0;
-  width: 150px;
-  height: 160px;
-  background-color: #fff;
-  margin-right: 60px;
-  position: relative;
-}
-.photoSty2 {
-  position: relative;
-  flex-shrink: 0;
-  width: 230px;
-  height: 160px;
-  margin-right: 60px;
-  background-color: #fff;
-}
-.pos_bottom {
-  position: absolute;
-  height: 20px;
-  bottom: 0px;
-  left: 0px;
-  right: 0px;
-  background-color: rgba(0, 0, 0, 0.8);
-  text-align: center;
-  line-height: 20px;
-  font-size: 14px;
-  color: #fff;
-}
-.dis_fls {
-  height: 65px;
-  margin: 16px 0px;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  flex-wrap: wrap;
-  .s_sd {
-    display: flex;
-    align-items: center;
-    flex-shrink: 0;
-    margin-bottom: 10px;
-    .dis_colu {
-      height: 55px;
-      margin-right: 14px;
-      display: flex;
-      flex-direction: column;
-      justify-content: space-around;
-      font-size: 14px;
-    }
+  padding: 10px 18px;
+  ul {
+    margin-bottom: 0px;
   }
 }
-.jdNumSty {
-  border: 1px solid #000;
-  border-radius: 6px;
-  padding: 6px;
-}
-.shbtns {
-  padding: 0px 10px;
-  height: 55px;
-  line-height: 55px;
-  background-color: #eee;
-  border-radius: 6px;
-}
-.btnStys {
-  border: 1px solid #666;
-  padding: 0px 8px;
-  border-radius: 4px;
-  font-size: 15px;
-  margin-right: 8px;
-  cursor: pointer;
-}
 .liImgs {
   float: left;
-  width: 250px;
-  height: 250px;
-  margin-right: 20px;
-  margin-bottom: 20px;
+  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: 44px;
-    line-height: 44px;
-    font-size: 16px;
-    color: #000;
+    height: 32px;
+    line-height: 32px;
+    font-size: 14px;
+    color: #fff;
     text-align: center;
-    background-color: rgba(90, 90, 90, 0.7);
+    background-color: rgba(51, 51, 51, 0.7);
   }
 }
 /deep/.el-button {

+ 689 - 0
src/views/education/classManageMent/hoursTimesRecord/index.vue

@@ -0,0 +1,689 @@
+<template>
+  <div id="hoursTimesRecord">
+    <div class="top_style">
+      <header>
+        <div class="left"><i></i><span>学员信息</span></div>
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「1」</strong>所购商品:{{
+            objs.goodsName
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「2」</strong>所在班级:{{
+            objs.className
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「3」</strong>学时:{{
+            objs.classHours
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「4」</strong>完成{{
+            userData.stuAllNum + userData.recordNum
+          }}节的内容学习</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「5」</strong>学习时间:{{
+            $methodsTools.onlyForma(userData.studyStartTime, false)
+          }}
+          - {{ $methodsTools.onlyForma(userData.studyEndTime, false) }}</span
+        >
+        <el-button type="primary" size="mini" @click="showBox = !showBox">{{
+          showBox ? "收起" : "展开"
+        }}</el-button>
+      </header>
+      <div class="info_img" v-show="showBox">
+        <ul>
+          <li>学员编码:{{ userData.studentCode }}</li>
+          <li>学员姓名:{{ userData.realName }}</li>
+          <li>学员身份证号码:{{ userData.idCard }}</li>
+          <li>绑定手机号码:{{ userData.telPhone }}</li>
+        </ul>
+        <div class="img_by">
+          <div class="photoSty1">
+            <img
+              v-if="!userData.oneInchPhotos"
+              src="@/assets/images/peopleImg.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.oneInchPhotos)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.oneInchPhotos),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">一寸头像图</div>
+          </div>
+          <div class="photoSty2">
+            <img
+              v-if="!userData.idCardImg1"
+              src="@/assets/images/idcardF.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg1)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg1),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证头像照</div>
+          </div>
+          <div class="photoSty2" style="margin-right: 0px">
+            <img
+              v-if="!userData.idCardImg2"
+              src="@/assets/images/idcardZ.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg2)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg2),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证国徽照</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <el-tabs
+      style="margin-top: 14px"
+      v-if="show"
+      v-model="activeCourseId"
+      type="card"
+      :before-leave="changeActiveCourseIdFunc"
+    >
+      <el-tab-pane
+        v-for="(item, index) in courseList"
+        :key="index"
+        :label="item.courseName"
+        :name="item.courseId + ''"
+      ></el-tab-pane>
+    </el-tabs>
+    <div class="footerTableStyle">
+      <el-table
+        v-if="!loading"
+        v-loading="loading"
+        ref="multipleTable"
+        :data="tableData"
+        border
+        :span-method="objectSpanMethod"
+        :header-cell-style="{
+          'background-color': '#CCDDF7',
+          padding: '2px',
+          color: '#0047D0',
+          'border-right-color': '#0047D0',
+          'border-left-color': '#0047D0',
+        }"
+      >
+        <el-table-column
+          v-for="(item, index) in tableList"
+          :width="item.width"
+          :key="index"
+          :label="item.label"
+          align="center"
+          :show-overflow-tooltip="true"
+          header-align="center"
+        >
+          <template slot-scope="scope">
+            <span v-if="item.scope === 'status'">
+              {{
+                scope.row[item.prop] == 1
+                  ? "及格"
+                  : scope.row[item.prop] == 0
+                  ? "不及格"
+                  : ""
+              }}
+            </span>
+            <span v-else-if="item.scope === 'sectionType'">
+              {{
+                scope.row[item.prop] == 1
+                  ? "录播"
+                  : scope.row[item.prop] == 2
+                  ? "直播"
+                  : scope.row[item.prop] == 3
+                  ? "回放"
+                  : scope.row[item.prop] == 4
+                  ? "题卷"
+                  : ""
+              }}
+            </span>
+            <div v-else-if="item.scope === 'moreTime'">
+              {{ $methodsTools.onlyForma(scope.row[item.prop1]) }} -
+              {{ $methodsTools.onlyForma(scope.row[item.prop2]) }}
+            </div>
+            <span v-else-if="item.scope === 'durationTime'">
+              {{
+                scope.row[item.prop]
+                  ? $methodsTools.secondToDate(scope.row[item.prop], false)
+                  : ""
+              }}
+            </span>
+            <span v-else-if="item.scope === 'score'">
+              {{ scope.row[item.prop] ? scope.row[item.prop] + "分" : "" }}
+            </span>
+            <span v-else>{{ scope.row[item.prop] }}</span></template
+          >
+        </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "HoursTimesRecord",
+  data() {
+    return {
+      size: "medium",
+      loading: false,
+      userData: {},
+      tableList: [
+        {
+          label: "模块标题",
+          prop: "moduleName",
+        },
+        {
+          label: "章标题",
+          prop: "chapterName",
+        },
+        {
+          label: "节标题",
+          prop: "sectionName",
+        },
+        {
+          label: "学习类型",
+          prop: "sectionType",
+          scope: "sectionType",
+        },
+        {
+          label: "节时长",
+          prop: "durationTime",
+          scope: "durationTime",
+        },
+        {
+          label: "学习/做题的次数",
+          prop: "newVisitNum",
+          width: "140px",
+        },
+        {
+          label: "学习/做题时间",
+          prop1: "studyStartTime",
+          prop2: "studyEndTime",
+          scope: "moreTime",
+          width: "310px",
+        },
+        {
+          label: "学习/做题状态",
+          prop: "status",
+          scope: "status",
+          width: "140px",
+        },
+        {
+          label: "做题成绩",
+          prop: "score",
+          scope: "score",
+        },
+        {
+          label: "做题正确率",
+          prop: "rightRate",
+        },
+      ],
+      tableData: [],
+      formData: {},
+      total: 0,
+      showBox: true,
+      //路由参数
+      objs: {},
+      //课程列表
+      courseList: [],
+      //选中课程Id
+      activeCourseId: "",
+      //等待获取课程成功后渲染
+      show: false,
+      typeNameArr: [],
+      typeNamePos: 0,
+      storeArr: [],
+      storePos: 0,
+      feeArr: [],
+      feePos: 0,
+    };
+  },
+  created() {
+    this.objs = this.$route.query;
+  },
+  mounted() {
+    //获取用户信息
+    this.getUserInfo();
+    //获取课程列表
+    this.getGoodsCourseList(this.objs.goodsId).then((newName) => {
+      this.changeActiveCourseIdFunc(newName);
+    });
+  },
+  watch: {
+    tableData(val) {
+      this.merage();
+    },
+  },
+  methods: {
+    //获取商品课程列表
+    getGoodsCourseList(id) {
+      return new Promise((resolve, reject) => {
+        this.$api.obtainCourseSgoodsId(id).then((res) => {
+          if (res.rows.length > 0) {
+            this.courseList = res.rows;
+            this.activeCourseId = res.rows[0].courseId + "";
+            this.show = true;
+            resolve(res.rows[0].courseId + "");
+          } else {
+            this.$message.warning("查无该商品课程列表");
+            reject();
+          }
+        });
+      });
+    },
+    //获取用户信息
+    getUserInfo() {
+      this.$api
+        .inquireGradegradelistUserlistPeriod({
+          gradeId: this.objs.gradeId,
+          userId: this.objs.userId,
+          goodsId: this.objs.goodsId,
+        })
+        .then((res) => {
+          this.userData = res.rows[0];
+        });
+    },
+    //选中课程触发方法
+    changeActiveCourseIdFunc(newName, oldName) {
+      return new Promise((resolve, reject) => {
+        this.loading = true;
+        const data = {
+          gradeId: this.objs.gradeId,
+          userId: this.objs.userId,
+          goodsId: this.objs.goodsId,
+          courseId: newName,
+        };
+        this.$api
+          .gradegradelistUserStudyRecord(data)
+          .then((res) => {
+            if (res.code === 200) {
+              let COURSELISTMX = [];
+              res.rows.forEach((item) => {
+                if (item.recordList && item.recordList.length) {
+                  for (let i = 0; i < item.recordList.length; i++) {
+                    let ary = { ...item };
+                    ary.recordList[i].newVisitNum = i + 1;
+                    COURSELISTMX.push(Object.assign(ary, ary.recordList[i]));
+                  }
+                } else {
+                  if (item.studyStartTime || item.studyEndTime) {
+                    item.newVisitNum = 1;
+                  } else {
+                    item.newVisitNum = "未参与";
+                  }
+
+                  COURSELISTMX.push(item);
+                }
+              });
+              this.tableData = COURSELISTMX;
+              resolve();
+            } else {
+              reject();
+            }
+          })
+          .finally(() => {
+            this.loading = false;
+          });
+      });
+    },
+    merageInit() {
+      // 在下文的时候会用到,对数据进行初始化是很有必要的
+      this.typeNameArr = [];
+      this.typeNamePos = 0;
+      this.storeArr = [];
+      this.storePos = 0;
+      this.feeArr = [];
+      this.feePos = 0;
+    },
+    merage() {
+      this.merageInit(); // 前文的初始化数据函数
+      let arys = JSON.parse(JSON.stringify(this.tableData));
+      for (let i = 0; i < arys.length; i += 1) {
+        if (i === 0) {
+          // 第一行必须存在
+          this.typeNameArr.push(1);
+          this.typeNamePos = 0;
+          this.storeArr.push(1);
+          this.storePos = 0;
+          this.feeArr.push(1);
+          this.feePos = 0;
+        } else {
+          // 判断当前元素与上一个元素是否相同,eg:this.typeNamePos 是 this.typeNameArr序号
+          // 第一列 下面的是eslint的不限制语法
+          // eslint-disable-next-line no-lonely-if
+          if (arys[i].moduleName === arys[i - 1].moduleName) {
+            this.typeNameArr[this.typeNamePos] += 1;
+            this.typeNameArr.push(0);
+          } else {
+            this.typeNameArr.push(1);
+            this.typeNamePos = i;
+          }
+          // 第二列
+          if (
+            arys[i].chapterName === arys[i - 1].chapterName &&
+            arys[i].moduleName === arys[i - 1].moduleName
+          ) {
+            this.storeArr[this.storePos] += 1;
+            this.storeArr.push(0);
+          } else {
+            this.storeArr.push(1);
+            this.storePos = i;
+          }
+          // 第三列
+          if (
+            arys[i].sectionName === arys[i - 1].sectionName &&
+            arys[i].chapterName === arys[i - 1].chapterName &&
+            arys[i].moduleName === arys[i - 1].moduleName
+          ) {
+            this.feeArr[this.feePos] += 1;
+            this.feeArr.push(0);
+          } else {
+            this.feeArr.push(1);
+            this.feePos = i;
+          }
+        }
+      }
+    },
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex === 0) {
+        // 第一列的合并方法
+        const row1 = this.typeNameArr[rowIndex];
+        const col1 = row1 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row1,
+          colspan: col1,
+        };
+      } else if (columnIndex === 1) {
+        // 第二列的合并方法
+        const row2 = this.storeArr[rowIndex];
+        const col2 = row2 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row2,
+          colspan: col2,
+        };
+      } else if (columnIndex === 2) {
+        // 第三列的合并方法
+        const row3 = this.feeArr[rowIndex];
+        const col3 = row3 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row3,
+          colspan: col3,
+        };
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+#hoursTimesRecord {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - 145px);
+}
+.footerTableStyle {
+  flex: 1;
+  overflow: auto;
+}
+.btn_styleShow {
+  float: right;
+}
+.styFlex {
+  width: 80px;
+  text-align: center;
+}
+.btnstyles {
+  margin-left: 0px;
+  margin-bottom: 10px;
+}
+.dis_flexs {
+  display: flex;
+  align-items: center;
+}
+.dis_fs {
+  display: flex;
+  align-items: center;
+  height: 211px;
+  background-color: #eee;
+  padding: 0px 30px;
+  overflow: auto;
+  flex-shrink: 0;
+  .ul_ls {
+    margin-right: 30px;
+    align-self: flex-start;
+    li {
+      font-size: 14px;
+      white-space: nowrap;
+      margin-bottom: 14px;
+    }
+  }
+  &::-webkit-scrollbar {
+    width: 14px;
+    height: 14px;
+  }
+
+  &::-webkit-scrollbar-track,
+  &::-webkit-scrollbar-thumb {
+    border-radius: 999px;
+    border: 5px solid transparent;
+  }
+
+  &::-webkit-scrollbar-track {
+    box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2) inset;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    min-height: 20px;
+    background-clip: content-box;
+    box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.2) inset;
+  }
+
+  &::-webkit-scrollbar-corner {
+    background: transparent;
+  }
+}
+.photoSty1 {
+  flex-shrink: 0;
+  width: 150px;
+  height: 160px;
+  background-color: #fff;
+  margin-right: 60px;
+  position: relative;
+}
+.photoSty2 {
+  position: relative;
+  flex-shrink: 0;
+  width: 230px;
+  height: 160px;
+  margin-right: 60px;
+  background-color: #fff;
+}
+.pos_bottom {
+  position: absolute;
+  height: 20px;
+  bottom: 0px;
+  left: 0px;
+  right: 0px;
+  background-color: rgba(0, 0, 0, 0.8);
+  text-align: center;
+  line-height: 20px;
+  font-size: 14px;
+  color: #fff;
+}
+.dis_fls {
+  margin: 16px 0px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  .s_sd {
+    display: flex;
+    align-items: center;
+    flex-shrink: 0;
+    margin-bottom: 10px;
+    .dis_colu {
+      height: 55px;
+      margin-right: 14px;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-around;
+      font-size: 14px;
+    }
+  }
+}
+.jdNumSty {
+  border: 1px solid #000;
+  border-radius: 6px;
+  padding: 6px;
+}
+.shbtns {
+  padding: 0px 10px;
+  height: 55px;
+  line-height: 55px;
+  background-color: #eee;
+  border-radius: 6px;
+}
+.btnStys {
+  border: 1px solid #666;
+  padding: 0px 8px;
+  border-radius: 4px;
+  font-size: 15px;
+  margin-right: 8px;
+  cursor: pointer;
+}
+.liImgs {
+  float: left;
+  width: 250px;
+  height: 250px;
+  margin-right: 20px;
+  margin-bottom: 20px;
+  position: relative;
+  .abos {
+    position: absolute;
+    bottom: 0px;
+    width: 100%;
+    height: 44px;
+    line-height: 44px;
+    font-size: 16px;
+    color: #000;
+    text-align: center;
+    background-color: rgba(90, 90, 90, 0.7);
+  }
+}
+.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;
+    & > span {
+      font-size: 14px;
+    }
+    & > .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;
+      }
+    }
+  }
+  & > .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{
+  border-radius: 8px;
+  overflow: hidden;
+}
+</style>

+ 175 - 85
src/views/education/classManageMent/learningHoursRecordList/hoursTimesRecord.vue

@@ -1,92 +1,93 @@
 <template>
   <div id="hoursTimesRecord">
-    <div style="margin-bottom: 10px">
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「1」</strong>所在班级:{{
-          objs.className
-        }}</span
-      >
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「2」</strong>学时:{{
-          objs.classHours
-        }}</span
-      >
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「3」</strong>完成{{
-          userData.stuAllNum + userData.recordNum
-        }}节的内容学习</span
-      >
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「4」</strong>学习时间:{{
-          $methodsTools.onlyForma(userData.studyStartTime, false)
-        }}
-        - {{ $methodsTools.onlyForma(userData.studyEndTime, false) }}</span
-      >
-
-      <el-button
-        class="btn_styleShow"
-        type="primary"
-        size="mini"
-        @click="showBox = !showBox"
-        >{{ showBox ? "收起" : "展开" }}</el-button
-      >
-    </div>
-    <div class="dis_fs" :style="showBox ? '' : 'height:0px;'">
-      <ul class="ul_ls">
-        <li>学员编码:{{ userData.studentCode }}</li>
-        <li>学员姓名:{{ userData.realName }}</li>
-        <li>学员身份证号码:{{ userData.idCard }}</li>
-        <li>绑定手机号码:{{ userData.telPhone }}</li>
-      </ul>
-      <div class="photoSty1">
-        <img
-          style="width: 100%; height: 100%"
-          v-if="!userData.oneInchPhotos"
-          src="@/assets/404_images/wuyuxaog.png"
-          alt=""
-        />
-        <el-image
-          v-else
-          style="width: 100%; height: 100%"
-          :src="$methodsTools.splitImgHost(userData.oneInchPhotos)"
-          :preview-src-list="[
-            $methodsTools.splitImgHost(userData.oneInchPhotos),
-          ]"
+    <div class="top_style">
+      <header>
+        <div class="left"><i></i><span>学员信息</span></div>
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「1」</strong>所在班级:{{
+            objs.className
+          }}</span
         >
-        </el-image>
-        <div class="pos_bottom">一寸头像图</div>
-      </div>
-      <div class="photoSty2">
-        <img
-          style="width: 100%; height: 100%"
-          v-if="!userData.idCardImg1"
-          src="@/assets/404_images/wuyuxaog.png"
-          alt=""
-        />
-        <el-image
-          v-else
-          style="width: 100%; height: 100%"
-          :src="$methodsTools.splitImgHost(userData.idCardImg1)"
-          :preview-src-list="[$methodsTools.splitImgHost(userData.idCardImg1)]"
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「2」</strong>学时:{{
+            objs.classHours
+          }}</span
         >
-        </el-image>
-        <div class="pos_bottom">身份证头像照</div>
-      </div>
-      <div class="photoSty2" style="margin-right: 0px">
-        <img
-          style="width: 100%; height: 100%"
-          v-if="!userData.idCardImg2"
-          src="@/assets/404_images/wuyuxaog.png"
-          alt=""
-        />
-        <el-image
-          v-else
-          style="width: 100%; height: 100%"
-          :src="$methodsTools.splitImgHost(userData.idCardImg2)"
-          :preview-src-list="[$methodsTools.splitImgHost(userData.idCardImg2)]"
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「3」</strong>完成{{
+            userData.stuAllNum + userData.recordNum
+          }}节的内容学习</span
         >
-        </el-image>
-        <div class="pos_bottom">身份证国徽照</div>
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「4」</strong>学习时间:{{
+            $methodsTools.onlyForma(userData.studyStartTime, false)
+          }}
+          - {{ $methodsTools.onlyForma(userData.studyEndTime, false) }}</span
+        >
+        <el-button type="primary" size="mini" @click="showBox = !showBox">{{
+          showBox ? "收起" : "展开"
+        }}</el-button>
+      </header>
+      <div class="info_img" v-show="showBox">
+        <ul>
+          <li>学员编码:{{ userData.studentCode }}</li>
+          <li>学员姓名:{{ userData.realName }}</li>
+          <li>学员身份证号码:{{ userData.idCard }}</li>
+          <li>绑定手机号码:{{ userData.telPhone }}</li>
+        </ul>
+        <div class="img_by">
+          <div class="photoSty1">
+            <img
+              v-if="!userData.oneInchPhotos"
+              src="@/assets/images/peopleImg.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.oneInchPhotos)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.oneInchPhotos),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">一寸头像图</div>
+          </div>
+          <div class="photoSty2">
+            <img
+              v-if="!userData.idCardImg1"
+              src="@/assets/images/idcardF.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg1)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg1),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证头像照</div>
+          </div>
+          <div class="photoSty2" style="margin-right: 0px">
+            <img
+              v-if="!userData.idCardImg2"
+              src="@/assets/images/idcardZ.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg2)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg2),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证国徽照</div>
+          </div>
+        </div>
       </div>
     </div>
     <div style="margin-top: 12px; overflow: auto; height: 100%">
@@ -282,7 +283,7 @@ export default {
 
 <style lang="less" scoped>
 #hoursTimesRecord {
-  max-height: 710px;
+  max-height: 70vh;
   display: flex;
   flex-direction: column;
 }
@@ -431,4 +432,93 @@ export default {
     background-color: rgba(90, 90, 90, 0.7);
   }
 }
+.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;
+      }
+    }
+  }
+  & > .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;
+        }
+      }
+    }
+  }
+}
 </style>

+ 138 - 130
src/views/education/classManageMent/learningHoursRecordList/index.vue

@@ -37,54 +37,6 @@
       @handleSizeChange="handleSizeChange"
       @handleCurrentChange="handleCurrentChange"
     />
-    <el-dialog
-      :visible.sync="vidBoxHours"
-      v-if="vidBoxHours"
-      width="1360px"
-      :show-close="false"
-      :close-on-click-modal="false"
-    >
-      <div slot="title" class="hearders">
-        <div class="leftTitle">学习记录</div>
-        <div class="rightBoxs">
-          <img
-            src="@/assets/images/Close@2x.png"
-            alt=""
-            @click="vidBoxHours = false"
-          />
-        </div>
-      </div>
-      <div>
-        <hours-times-record :objs="objs" />
-      </div>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="vidBoxHours = false">取 消</el-button>
-      </span>
-    </el-dialog>
-    <el-dialog
-      :visible.sync="vidBox"
-      v-if="vidBox"
-      width="1360px"
-      :show-close="false"
-      :close-on-click-modal="false"
-    >
-      <div slot="title" class="hearders">
-        <div class="leftTitle">学时记录</div>
-        <div class="rightBoxs">
-          <img
-            src="@/assets/images/Close@2x.png"
-            alt=""
-            @click="vidBox = false"
-          />
-        </div>
-      </div>
-      <div>
-        <study-times-record :objs="objs" />
-      </div>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="vidBox = false">取 消</el-button>
-      </span>
-    </el-dialog>
     <el-dialog
       @closed="loadingClose"
       :visible.sync="dialogDR"
@@ -121,8 +73,6 @@ import * as baseUrls from "@/utils/request.js";
 import searchBoxNew from "@/components/searchBoxNew";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
-import studyTimesRecord from "./studyTimesRecord.vue";
-import hoursTimesRecord from "./hoursTimesRecord.vue";
 import exportTable from "./exportTable.vue";
 export default {
   name: "LearningHoursRecordList",
@@ -130,8 +80,6 @@ export default {
     searchBoxNew,
     tableList,
     pagination,
-    studyTimesRecord,
-    hoursTimesRecord,
     exportTable,
   },
   data() {
@@ -152,7 +100,6 @@ export default {
           title: "未定义",
         },
       },
-      objs: {},
       //搜索
       formList: [
         {
@@ -303,14 +250,14 @@ export default {
         //   Diszing: true,
         //   scope: "TimeLists",
         // },
-        {
-          label: "班级有效期",
-          prop1: "classStartTime",
-          prop2: "classEndTime",
-          scope: "TimeLists",
-          Diszing: false,
-          hidden: false,
-        },
+        // {
+        //   label: "班级有效期",
+        //   prop1: "classStartTime",
+        //   prop2: "classEndTime",
+        //   scope: "TimeLists",
+        //   Diszing: false,
+        //   hidden: false,
+        // },
         {
           label: "学习时间",
           prop1: "startTime",
@@ -318,30 +265,30 @@ export default {
           scope: "TimeLists",
           hidden: false,
         },
-        {
-          label: "学习状态",
-          prop: "periodStatus",
-          hidden: true,
-          scope: "isOptions",
-          options: [
-            {
-              label: "已完成",
-              value: 0,
-            },
-            {
-              label: "已完成",
-              value: 1,
-            },
-            {
-              label: "已完成",
-              value: 2,
-            },
-            {
-              label: "未完成",
-              value: -1,
-            },
-          ],
-        },
+        // {
+        //   label: "学习状态",
+        //   prop: "periodStatus",
+        //   hidden: true,
+        //   scope: "isOptions",
+        //   options: [
+        //     {
+        //       label: "已完成",
+        //       value: 0,
+        //     },
+        //     {
+        //       label: "已完成",
+        //       value: 1,
+        //     },
+        //     {
+        //       label: "已完成",
+        //       value: 2,
+        //     },
+        //     {
+        //       label: "未完成",
+        //       value: -1,
+        //     },
+        //   ],
+        // },
         {
           label: "学时审核状态",
           prop: "periodStatus",
@@ -370,31 +317,29 @@ export default {
             },
           ],
         },
-        {
-          label: "学时官方推送状态",
-          prop: "periodPlush",
-          hidden: true,
-          scope: "isOptions",
-          options: [
-            {
-              label: "否",
-              value: null,
-            },
-            {
-              label: "否",
-              value: 0,
-            },
-            {
-              label: "是",
-              value: 1,
-            },
-          ],
-        },
+        // {
+        //   label: "学时官方推送状态",
+        //   prop: "periodPlush",
+        //   hidden: true,
+        //   scope: "isOptions",
+        //   options: [
+        //     {
+        //       label: "否",
+        //       value: null,
+        //     },
+        //     {
+        //       label: "否",
+        //       value: 0,
+        //     },
+        //     {
+        //       label: "是",
+        //       value: 1,
+        //     },
+        //   ],
+        // },
       ],
       tableData: [], //表单数据
       total: 0, //一共多少条
-      vidBox: false,
-      vidBoxHours: false,
     };
   },
   mounted() {
@@ -498,48 +443,111 @@ export default {
      * @remard 学习记录
      */
     activeHoursRecord(options) {
-      this.objs = {
-        gradeId: options.gradeId,
-        userId: options.userId,
-        goodsId: options.goodsId,
-        className: options.className,
-        classHours: options.classHours,
-        studyStartTime: options.studyStartTime,
-        studyEndTime: options.studyEndTime,
+      const jump = () => {
+        //班级详情
+        this.$router.push({
+          path: "hoursTimesRecord",
+          query: {
+            gradeId: options.gradeId,
+            userId: options.userId,
+            goodsId: options.goodsId,
+            goodsName: options.goodsName,
+            className: options.className,
+            classHours: options.classHours,
+            studyStartTime: options.studyStartTime,
+            studyEndTime: options.studyEndTime,
+          },
+        });
       };
-      this.vidBoxHours = true;
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "HoursTimesRecord";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "HoursTimesRecord",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
     },
     /**
      *
      * @param {obj} int
      * @remard 学时记录
      */
-    activeStudyRecord(options) {
+    activeStudyRecord(v) {
       this.$api
         .inquireGradegradelockPeriodStatus({
-          gradeId: Number(options.gradeId),
-          userId: Number(options.userId),
-          goodsId: Number(options.goodsId),
+          gradeId: v.gradeId,
+          userId: v.userId,
+          goodsId: v.goodsId,
         })
         .then((res) => {
           if (res.msg) {
             this.$message.warning(res.msg + "正在操作");
             return;
           } else {
-            this.objs = {
-              id: options.gradeId,
-              gradeId: options.gradeId,
-              userId: options.userId,
-              goodsId: options.goodsId,
-              className: options.className,
-              classHours: options.classHours,
-              studyStartTime: options.studyStartTime,
-              studyEndTime: options.studyEndTime,
+            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.vidBox = true;
+            console.log(data, v);
+            this.checkSession(data)
+              .then(() => {
+                //学员详情
+                this.$router.push({
+                  path: "classHoursReview",
+                });
+              })
+              .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();
+        }
+      });
+    },
     /**
      * 搜索列表
      */

+ 344 - 270
src/views/education/classManageMent/learningHoursRecordList/studyTimesRecord.vue

@@ -1,139 +1,148 @@
 <template>
   <div id="classHoursReview">
-    <div style="margin-bottom: 10px">
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「1」</strong>所在班级:{{
-          objs.className
-        }}</span
-      >
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「2」</strong>学时:{{
-          objs.classHours
-        }}</span
-      >
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「3」</strong>完成{{
-          userData.stuAllNum + userData.recordNum
-        }}节的内容学习</span
-      >
-      <span style="margin-left: 10px"
-        ><strong style="color: red">「4」</strong>学习时间:{{
-          $methodsTools.onlyForma(userData.studyStartTime, false)
-        }}
-        - {{ $methodsTools.onlyForma(userData.studyEndTime, false) }}</span
-      >
-      <el-button
-        class="btn_styleShow"
-        type="primary"
-        size="mini"
-        @click="showBox = !showBox"
-        >{{ showBox ? "收起" : "展开" }}</el-button
-      >
-      <div style="clear:both;"></div>
-    </div>
-      <div class="dis_fs" :style="showBox ? '' : 'height:0px;'">
-        <ul class="ul_ls">
+    <div class="top_style">
+      <header>
+        <div class="left"><i></i><span>学员信息</span></div>
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「1」</strong>所在班级:{{
+            objs.className
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「2」</strong>学时:{{
+            objs.classHours
+          }}</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「3」</strong>完成{{
+            userData.stuAllNum + userData.recordNum
+          }}节的内容学习</span
+        >
+        <span style="margin-left: 10px"
+          ><strong style="color: red">「4」</strong>学习时间:{{
+            $methodsTools.onlyForma(userData.studyStartTime, false)
+          }}
+          - {{ $methodsTools.onlyForma(userData.studyEndTime, false) }}</span
+        >
+        <el-button type="primary" size="mini" @click="showBox = !showBox">{{
+          showBox ? "收起" : "展开"
+        }}</el-button>
+      </header>
+      <div class="info_img" v-show="showBox">
+        <ul>
           <li>学员编码:{{ userData.studentCode }}</li>
           <li>学员姓名:{{ userData.realName }}</li>
           <li>学员身份证号码:{{ userData.idCard }}</li>
           <li>绑定手机号码:{{ userData.telPhone }}</li>
         </ul>
-        <div class="photoSty1">
-          <img
-            style="width: 100%; height: 100%"
-            v-if="!userData.oneInchPhotos"
-            src="@/assets/404_images/wuyuxaog.png"
-            alt=""
-          />
-          <el-image
-            v-else
-            style="width: 100%; height: 100%"
-            :src="$methodsTools.splitImgHost(userData.oneInchPhotos)"
-            :preview-src-list="[
-              $methodsTools.splitImgHost(userData.oneInchPhotos),
-            ]"
-          >
-          </el-image>
-          <div class="pos_bottom">一寸头像图</div>
-        </div>
-        <div class="photoSty2">
-          <img
-            style="width: 100%; height: 100%"
-            v-if="!userData.idCardImg1"
-            src="@/assets/404_images/wuyuxaog.png"
-            alt=""
-          />
-          <el-image
-            v-else
-            style="width: 100%; height: 100%"
-            :src="$methodsTools.splitImgHost(userData.idCardImg1)"
-            :preview-src-list="[
-              $methodsTools.splitImgHost(userData.idCardImg1),
-            ]"
-          >
-          </el-image>
-          <div class="pos_bottom">身份证头像照</div>
+        <div class="img_by">
+          <div class="photoSty1">
+            <img
+              v-if="!userData.oneInchPhotos"
+              src="@/assets/images/peopleImg.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.oneInchPhotos)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.oneInchPhotos),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">一寸头像图</div>
+          </div>
+          <div class="photoSty2">
+            <img
+              v-if="!userData.idCardImg1"
+              src="@/assets/images/idcardF.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg1)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg1),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证头像照</div>
+          </div>
+          <div class="photoSty2" style="margin-right: 0px">
+            <img
+              v-if="!userData.idCardImg2"
+              src="@/assets/images/idcardZ.png"
+              alt=""
+            />
+            <el-image
+              v-else
+              style="width: 100%; height: 100%"
+              :src="$methodsTools.splitImgHost(userData.idCardImg2)"
+              :preview-src-list="[
+                $methodsTools.splitImgHost(userData.idCardImg2),
+              ]"
+            >
+            </el-image>
+            <div class="pos_bottom">身份证国徽照</div>
+          </div>
         </div>
-        <div class="photoSty2" style="margin-right: 0px">
-          <img
-            style="width: 100%; height: 100%"
-            v-if="!userData.idCardImg2"
-            src="@/assets/404_images/wuyuxaog.png"
-            alt=""
-          />
-          <el-image
-            v-else
-            style="width: 100%; height: 100%"
-            :src="$methodsTools.splitImgHost(userData.idCardImg2)"
-            :preview-src-list="[
-              $methodsTools.splitImgHost(userData.idCardImg2),
-            ]"
-          >
-          </el-image>
-          <div class="pos_bottom">身份证国徽照</div>
+      </div>
+    </div>
+    <div class="studyStyle">
+      <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="dis_fls">
-      <div class="s_sd">
-        <div class="dis_colu">
-          <div class="jdNumSty" style="margin-bottom: 4px">
-            视频学习进度:{{ userData.stuAllNum }}/{{ userData.secAllNum }}
-            {{
-              userData.stuAllNum == 0 && userData.secAllNum == 0
-                ? "0"
-                : ((userData.stuAllNum / userData.secAllNum) * 100).toFixed(2)
-            }}% 通过:{{ userData.pass }}节
-            <span style="color: #f56c6c">作弊:{{ userData.cheat }}节</span>
-            <span style="color: #409eff"> 待审:{{ userData.pending }}节</span>
+      <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="jdNumSty">
-            做题学习进度:{{ userData.recordNum }}/{{ userData.examNum }}
-            {{
-              userData.recordNum == 0 && userData.examNum == 0
-                ? "0"
-                : ((userData.recordNum / userData.examNum) * 100).toFixed(2)
-            }}% 通过:{{ userData.examPass }}节
-            <span style="color: #f56c6c">作弊:{{ userData.examCheat }}节</span>
-            <span style="color: #409eff">
-              待审:{{ userData.examPending }}节</span
-            >
+          <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 class="shbtns">
-          学时审批状态:{{
-            userData.periodStatus === 0
-              ? "未通过"
-              : userData.periodStatus === 2
-              ? "待审核"
-              : userData.periodStatus === -1
-              ? "不可审核"
-              : userData.periodStatus === 1
-              ? "通过审核"
-              : userData.periodStatus === 3
-              ? "审核中"
-              : "未知状态,请联系管理员"
-          }}
+      </div>
+      <div class="a_style" style="width: 280px">
+        <i></i>
+        <span>学时审批状态</span>
+        <div class="flex_style_study">
+          <div class="num_style" style="color: #0047d0">
+            {{
+              userData.periodStatus === 0
+                ? "未通过"
+                : userData.periodStatus === 2
+                ? "待审核"
+                : userData.periodStatus === -1
+                ? "不可审核"
+                : userData.periodStatus === 1
+                ? "通过审核"
+                : userData.periodStatus === 3
+                ? "审核中"
+                : "未知状态,请联系管理员"
+            }}
+          </div>
+          <div style="clear: both"></div>
         </div>
       </div>
       <div class="s_sd">
@@ -149,12 +158,14 @@
           <el-button
             style="margin-left: 10px"
             size="mini"
+            type="success"
             v-if="userData.periodStatus === 2"
             @click="getChangeStatus(1)"
             >勾选通过</el-button
           >
           <el-button
             size="mini"
+            type="danger"
             v-if="userData.periodStatus === 2"
             @click="getChangeStatus(2)"
             >勾选作弊</el-button
@@ -192,25 +203,29 @@
                 : ''
             ]
           "
-          style="width: 100%"
+          style="width: 100%; border-radius: 4px; overflow: hidden"
           :header-cell-style="
             asrt.value === 0
               ? {
-                  'background-color': 'skyblue',
+                  'background-color': '#CCDDF7',
                   padding: '8px',
-                  color: '#333',
+                  color: '#0047D0',
+                  'border-right-color': '#0047D0',
+                  'border-left-color': '#0047D0',
                 }
               : asrt.value === 1
               ? {
-                  'background-color': 'rgb(255,255,204)',
+                  'background-color': '#D9ECFA',
                   padding: '8px',
-                  color: '#333',
+                  color: '#1565C0',
+                  'border-right-color': '#1565C0',
+                  'border-left-color': '#1565C0',
                 }
               : asrt.value === 2
               ? {
-                  'background-color': '#eee',
+                  'background-color': '#F5F5F5',
                   padding: '8px',
-                  color: '#333',
+                  color: '#666',
                 }
               : ''
           "
@@ -267,8 +282,8 @@
                 <div
                   class="styFlex"
                   v-if="
-                    (userData.periodStatus === 2 ||
-                      userData.periodStatus === 0 ||
+                    (userData.periodStatus === 0 ||
+                      userData.periodStatus === 2 ||
                       userData.periodStatus === 3) &&
                     scope.row.periodStatus === 1
                   "
@@ -300,7 +315,7 @@
                     :disabled="scope.row.status !== 2"
                     class="btnstyles"
                     size="small"
-                    type="warning"
+                    type="danger"
                     @click="changeStatus(scope.row, 2, scope.$index)"
                     >作弊</el-button
                   >
@@ -318,20 +333,21 @@
                     ? scope.row.classPeriodSectionList
                     : ''
                 "
-                style="width: 98%; margin-left: 2%"
                 :default-expand-all="defaultExpand"
                 :header-cell-style="
                   scope.row.type === 1
                     ? {
-                        'background-color': 'rgb(255,255,204)',
+                        'background-color': '#D9ECFA',
                         padding: '8px',
-                        color: '#333',
+                        color: '#1565C0',
+                        'border-right-color': '#1565C0',
+                        'border-left-color': '#1565C0',
                       }
                     : scope.row.type === 2
                     ? {
-                        'background-color': '#eee',
+                        'background-color': '#f5f5f5',
                         padding: '8px',
-                        color: '#333',
+                        color: '#666',
                       }
                     : ''
                 "
@@ -433,7 +449,7 @@
                           :disabled="scope2.row.status !== 2"
                           class="btnstyles"
                           size="small"
-                          type="warning"
+                          type="danger"
                           @click="
                             changeStatusCharpter(
                               scope2.row,
@@ -456,14 +472,13 @@
                           ? scope2.row.classPeriodSectionList
                           : ''
                       "
-                      style="width: 98%; margin-left: 2%"
                       :default-expand-all="defaultExpand"
                       :header-cell-style="
                         scope2.row.type === 2
                           ? {
-                              'background-color': '#eee',
+                              'background-color': '#f5f5f5',
                               padding: '8px',
-                              color: '#333',
+                              color: '#666',
                             }
                           : ''
                       "
@@ -555,7 +570,7 @@
                                 :disabled="scope3.row.status !== 2"
                                 class="btnstyles"
                                 size="small"
-                                type="warning"
+                                type="danger"
                                 @click="
                                   changeStatusModule(
                                     scope3.row,
@@ -587,7 +602,13 @@
                               v-for="(k, ds) in item.options"
                               :key="ds"
                               :style="
-                                scope3.row[item.prop] === 0 ? 'color:red;' : ''
+                                scope3.row[item.prop] === 0
+                                  ? 'color:red;'
+                                  : scope3.row[item.prop] === 2
+                                  ? 'color:#0047D0;'
+                                  : scope3.row[item.prop] === 1
+                                  ? 'color:#67C23A;'
+                                  : ''
                               "
                             >
                               {{
@@ -680,7 +701,15 @@
                       <span
                         v-for="(k, ds) in item.options"
                         :key="ds"
-                        :style="scope2.row[item.prop] === 0 ? 'color:red;' : ''"
+                        :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>
@@ -765,7 +794,15 @@
                 <span
                   v-for="(k, ds) in item.options"
                   :key="ds"
-                  :style="scope.row[item.prop] === 0 ? 'color:red;' : ''"
+                  :style="
+                    scope.row[item.prop] === 0
+                      ? 'color:red;'
+                      : scope.row[item.prop] === 2
+                      ? 'color:#0047D0;'
+                      : scope.row[item.prop] === 1
+                      ? 'color:#67C23A;'
+                      : ''
+                  "
                 >
                   {{ k.value == scope.row[item.prop] ? k.label : "" }}
                 </span>
@@ -1069,10 +1106,6 @@ export default {
           label: "模块标题",
           prop: "typeName",
         },
-        {
-          label: "学时",
-          prop: "classHours",
-        },
       ],
       tableSet2: [
         {
@@ -1895,16 +1928,12 @@ export default {
   },
 };
 </script>
-
 <style lang="less" scoped>
 #classHoursReview {
-  max-height: 710px;
+  max-height: 70vh;
   display: flex;
   flex-direction: column;
 }
-.btn_styleShow {
-  float: right;
-}
 .li_sty {
   cursor: pointer;
   transition: all 0.3s;
@@ -1918,106 +1947,136 @@ export default {
     box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, 0.2);
   }
 }
-.styFlex {
-  width: 80px;
-  text-align: center;
-}
-.checkboxList {
-  margin-bottom: 6px;
-  &/deep/.el-checkbox__label {
-    display: none;
+.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;
+      }
+    }
+  }
+  & > .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;
+        }
+      }
+    }
   }
 }
-.btnstyles {
-  margin-left: 0px;
-  margin-bottom: 10px;
-}
-.dis_flexs {
-  display: flex;
-  align-items: center;
-}
-.dis_fs {
+.studyStyle {
+  margin: 16px 0px 0px;
   display: flex;
   align-items: center;
-  height: 211px;
-  background-color: #eee;
-  padding: 0px 30px;
-  overflow: auto;
-  flex-shrink: 0;
-  .ul_ls {
-    margin-right: 30px;
-    align-self: flex-start;
-    li {
+  & > .a_style {
+    display: flex;
+    align-items: center;
+    margin: 0px 16px 16px 0px;
+    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;
-      white-space: nowrap;
-      margin-bottom: 14px;
+      margin-left: 14px;
     }
   }
-  &::-webkit-scrollbar {
-    width: 14px;
-    height: 14px;
-  }
-
-  &::-webkit-scrollbar-track,
-  &::-webkit-scrollbar-thumb {
-    border-radius: 999px;
-    border: 5px solid transparent;
-  }
-
-  &::-webkit-scrollbar-track {
-    box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2) inset;
-  }
-
-  &::-webkit-scrollbar-thumb {
-    min-height: 20px;
-    background-clip: content-box;
-    box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.2) inset;
-  }
-
-  &::-webkit-scrollbar-corner {
-    background: transparent;
-  }
-}
-.photoSty1 {
-  flex-shrink: 0;
-  width: 150px;
-  height: 160px;
-  background-color: #fff;
-  margin-right: 60px;
-  position: relative;
-}
-.photoSty2 {
-  position: relative;
-  flex-shrink: 0;
-  width: 230px;
-  height: 160px;
-  margin-right: 60px;
-  background-color: #fff;
-}
-.pos_bottom {
-  position: absolute;
-  height: 20px;
-  bottom: 0px;
-  left: 0px;
-  right: 0px;
-  background-color: rgba(0, 0, 0, 0.8);
-  text-align: center;
-  line-height: 20px;
-  font-size: 14px;
-  color: #fff;
-}
-.dis_fls {
-  height: 65px;
-  margin: 16px 0px;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  flex-wrap: wrap;
   .s_sd {
+    flex: 1;
+    justify-content:flex-end;
     display: flex;
     align-items: center;
     flex-shrink: 0;
-    margin-bottom: 10px;
+    margin: 0px 16px 16px 0px;
     .dis_colu {
       height: 55px;
       margin-right: 14px;
@@ -2028,43 +2087,58 @@ export default {
     }
   }
 }
-.jdNumSty {
-  border: 1px solid #000;
-  border-radius: 6px;
-  padding: 6px;
+/deep/ .el-table__expanded-cell {
+  background: #f5f5f5;
 }
-.shbtns {
-  padding: 0px 10px;
-  height: 55px;
-  line-height: 55px;
-  background-color: #eee;
-  border-radius: 6px;
+/deep/ .el-table__expanded-cell {
+  padding: 0px !important;
 }
-.btnStys {
-  border: 1px solid #666;
-  padding: 0px 8px;
-  border-radius: 4px;
-  font-size: 15px;
-  margin-right: 8px;
-  cursor: pointer;
+#studyTimes {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - 190px);
+}
+.styFlex {
+  width: 80px;
+  text-align: center;
+}
+.checkboxList {
+  margin-bottom: 6px;
+  &/deep/.el-checkbox__label {
+    display: none;
+  }
+}
+.btnstyles {
+  margin-left: 0px;
+  margin-bottom: 10px;
+}
+.dis_flexs {
+  display: flex;
+  align-items: center;
+  padding: 10px 18px;
+  ul {
+    margin-bottom: 0px;
+  }
 }
 .liImgs {
   float: left;
-  width: 250px;
-  height: 250px;
-  margin-right: 20px;
-  margin-bottom: 20px;
+  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: 44px;
-    line-height: 44px;
-    font-size: 16px;
-    color: #000;
+    height: 32px;
+    line-height: 32px;
+    font-size: 14px;
+    color: #fff;
     text-align: center;
-    background-color: rgba(90, 90, 90, 0.7);
+    background-color: rgba(51, 51, 51, 0.7);
   }
 }
 /deep/.el-button {

+ 2 - 2
src/views/education/examManagement/applicationData/byTrainee.vue

@@ -385,7 +385,7 @@
                 : ""
             }}</span>
           </el-form-item>
-          <div v-if="activeInfoType === 1">
+          <div v-if="activeInfoType === 1 && infoData.userExamGoodsSupplement && infoData.userExamGoodsSupplement.length > 0">
             <el-button type="info" style="margin-bottom: 20px" size="mini"
               >补考商品自带考试次数</el-button
             >
@@ -418,7 +418,7 @@
               > -->
             </div>
           </div>
-          <div v-if="activeInfoType === 2">
+          <div v-if="activeInfoType === 2 && infoData.userExamGoodsSupplementVos && infoData.userExamGoodsSupplementVos.length > 0">
             <el-button type="info" style="margin-bottom: 20px" size="mini"
               >前培商品自带前培次数</el-button
             >

+ 52 - 4
src/views/education/studentManageMent/studentList/index.vue

@@ -59,6 +59,17 @@ export default {
       },
       //搜索
       formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
         {
           prop: "gradePoint",
           placeholder: "是否分班",
@@ -74,6 +85,22 @@ export default {
             },
           ],
         },
+        {
+          prop1: "startTime",
+          prop2: "endTime",
+          placeholder1: "创建开始时间",
+          placeholder2: "创建结束时间",
+          scope: "moreDataPicker",
+          Diszing: true,
+        },
+        {
+          prop: "goodsSearchKey",
+          placeholder: "请输入商品编码/商品名称",
+        },
+        {
+          prop: "companyName",
+          placeholder: "请输入公司名称",
+        },
         {
           prop: "realname",
           placeholder: "请输入学员名称",
@@ -98,6 +125,13 @@ export default {
           hidden: true,
           scope: "editInfo",
         },
+        {
+          label: "一寸头像",
+          prop: "oneInchPhotos",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
         {
           label: "学员身份证",
           prop: "idCard",
@@ -123,7 +157,7 @@ export default {
           label: "所购商品",
           prop1: "goodsCourseNum",
           prop2: "goodsBankNum",
-          prop3:"goodsLiveNum",
+          prop3: "goodsLiveNum",
           hidden: true,
           scope: "payGoodsList",
         },
@@ -133,7 +167,7 @@ export default {
           hidden: true,
           scope: "classNums",
           sort: true,
-          width:"120px"
+          width: "120px",
         },
       ],
       tableData: [], //表单数据
@@ -153,7 +187,21 @@ export default {
         this.$methodsTools.timestampConvert(this.$route.params.timeType)[1]
       );
     }
-    this.formData.businessId = this.$route.params.businessId || "";
+    if (this.$route.params.educationId) {
+      this.$set(
+        this.formData,
+        "educationTypeId",
+        this.$route.params.educationId
+      );
+      this.$refs.searchBox.changeEducationType(
+        this.$route.params.educationId,
+        true
+      );
+    }
+    if (this.$route.params.businessId) {
+      this.$set(this.formData, "businessId", this.$route.params.businessId);
+      this.$refs.searchBox.changeBusinessLevel(this.$route.params.businessId);
+    }
     this.search();
   },
   activated() {
@@ -176,7 +224,7 @@ export default {
           getOrderNum: 1,
         };
       }
-      var data = JSON.parse(JSON.stringify(this.formData))
+      var data = JSON.parse(JSON.stringify(this.formData));
       if (this.formData.startTime) {
         data.startTime = parseInt(data.startTime / 1000);
       }

+ 1 - 0
src/views/index.vue

@@ -822,6 +822,7 @@ export default {
           this.$router.push({
             name: "StudentList",
             params: {
+              educationId: this.activeEduId,
               businessId: this.activeBusId,
               timeType: timeType,
             },

+ 0 - 98
src/views/index_v1.vue

@@ -1,98 +0,0 @@
-<template>
-  <div class="dashboard-editor-container">
-
-    <panel-group @handleSetLineChartData="handleSetLineChartData" />
-
-    <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
-      <line-chart :chart-data="lineChartData" />
-    </el-row>
-
-    <el-row :gutter="32">
-      <el-col :xs="24" :sm="24" :lg="8">
-        <div class="chart-wrapper">
-          <raddar-chart />
-        </div>
-      </el-col>
-      <el-col :xs="24" :sm="24" :lg="8">
-        <div class="chart-wrapper">
-          <pie-chart />
-        </div>
-      </el-col>
-      <el-col :xs="24" :sm="24" :lg="8">
-        <div class="chart-wrapper">
-          <bar-chart />
-        </div>
-      </el-col>
-    </el-row>
-
-    
-  </div>
-</template>
-
-<script>
-import PanelGroup from './dashboard/PanelGroup'
-import LineChart from './dashboard/LineChart'
-import RaddarChart from './dashboard/RaddarChart'
-import PieChart from './dashboard/PieChart'
-import BarChart from './dashboard/BarChart'
-
-const lineChartData = {
-  newVisitis: {
-    expectedData: [100, 120, 161, 134, 105, 160, 165],
-    actualData: [120, 82, 91, 154, 162, 140, 145]
-  },
-  messages: {
-    expectedData: [200, 192, 120, 144, 160, 130, 140],
-    actualData: [180, 160, 151, 106, 145, 150, 130]
-  },
-  purchases: {
-    expectedData: [80, 100, 121, 104, 105, 90, 100],
-    actualData: [120, 90, 100, 138, 142, 130, 130]
-  },
-  shoppings: {
-    expectedData: [130, 140, 141, 142, 145, 150, 160],
-    actualData: [120, 82, 91, 154, 162, 140, 130]
-  }
-}
-
-export default {
-  name: 'Index',
-  components: {
-    PanelGroup,
-    LineChart,
-    RaddarChart,
-    PieChart,
-    BarChart
-  },
-  data() {
-    return {
-      lineChartData: lineChartData.newVisitis
-    }
-  },
-  methods: {
-    handleSetLineChartData(type) {
-      this.lineChartData = lineChartData[type]
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.dashboard-editor-container {
-  padding: 32px;
-  background-color: rgb(240, 242, 245);
-  position: relative;
-
-  .chart-wrapper {
-    background: #fff;
-    padding: 16px 16px 0;
-    margin-bottom: 32px;
-  }
-}
-
-@media (max-width:1024px) {
-  .chart-wrapper {
-    padding: 8px;
-  }
-}
-</style>

+ 0 - 215
src/views/loginCopy.vue

@@ -1,215 +0,0 @@
-<template>
-  <div class="login">
-    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
-      <h3 class="title">中正高校端后台管理系统</h3>
-      <el-form-item prop="username">
-        <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
-          <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="password">
-        <el-input
-          v-model="loginForm.password"
-          type="password"
-          auto-complete="off"
-          placeholder="密码"
-          @keyup.enter.native="handleLogin"
-        >
-          <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="code" v-if="captchaOnOff">
-        <el-input
-          v-model="loginForm.code"
-          auto-complete="off"
-          placeholder="验证码"
-          style="width: 63%"
-          @keyup.enter.native="handleLogin"
-        >
-          <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
-        </el-input>
-        <div class="login-code">
-          <img :src="codeUrl" @click="getCode" class="login-code-img"/>
-        </div>
-      </el-form-item>
-      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
-      <el-form-item style="width:100%;">
-        <el-button
-          :loading="loading"
-          size="medium"
-          type="primary"
-          style="width:100%;"
-          @click.native.prevent="handleLogin"
-        >
-          <span v-if="!loading">登 录</span>
-          <span v-else>登 录 中...</span>
-        </el-button>
-        <div style="float: right;" v-if="register">
-          <router-link class="link-type" :to="'/register'">立即注册</router-link>
-        </div>
-      </el-form-item>
-    </el-form>
-    <!--  底部  -->
-    <div class="el-login-footer">
-      <span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span>
-    </div>
-  </div>
-</template>
-
-<script>
-import { getCodeImg } from "@/api/login";
-import Cookies from "js-cookie";
-import { encrypt, decrypt } from '@/utils/jsencrypt'
-
-export default {
-  name: "Login",
-  data() {
-    return {
-      codeUrl: "",
-      cookiePassword: "",
-      loginForm: {
-        username: "",
-        password: "",
-        rememberMe: false,
-        code: "",
-        uuid: ""
-      },
-      loginRules: {
-        username: [
-          { required: true, trigger: "blur", message: "请输入您的账号" }
-        ],
-        password: [
-          { required: true, trigger: "blur", message: "请输入您的密码" }
-        ],
-        code: [{ required: true, trigger: "change", message: "请输入验证码" }]
-      },
-      loading: false,
-      // 验证码开关
-      captchaOnOff: true,
-      // 注册开关
-      register: false,
-      redirect: undefined
-    };
-  },
-  watch: {
-    $route: {
-      handler: function(route) {
-        this.redirect = route.query && route.query.redirect;
-      },
-      immediate: true
-    }
-  },
-  created() {
-    this.getCode();
-    this.getCookie();
-  },
-  methods: {
-    getCode() {
-      getCodeImg().then(res => {
-        // this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
-        // if (this.captchaOnOff) {
-          this.codeUrl = "data:image/gif;base64," + res.data.img;
-          this.loginForm.uuid = res.data.uuid;
-        // }
-      });
-    },
-    getCookie() {
-      const username = Cookies.get("username");
-      const password = Cookies.get("password");
-      const rememberMe = Cookies.get('rememberMe')
-      this.loginForm = {
-        username: username === undefined ? this.loginForm.username : username,
-        password: password === undefined ? this.loginForm.password : decrypt(password),
-        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
-      };
-    },
-    handleLogin() {
-      this.$refs.loginForm.validate(valid => {
-        if (valid) {
-          this.loading = true;
-          if (this.loginForm.rememberMe) {
-            Cookies.set("username", this.loginForm.username, { expires: 30 });
-            Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
-            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
-          } else {
-            Cookies.remove("username");
-            Cookies.remove("password");
-            Cookies.remove('rememberMe');
-          }
-          this.$store.dispatch("Login", this.loginForm).then(() => {
-            this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
-          }).catch(() => {
-            this.loading = false;
-            if (this.captchaOnOff) {
-              this.getCode();
-            }
-          });
-        }
-      });
-    }
-  }
-};
-</script>
-
-<style rel="stylesheet/scss" lang="scss">
-.login {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  height: 100%;
-  background-image: url("../assets/images/login-background.jpg");
-  background-size: cover;
-}
-.title {
-  margin: 0px auto 30px auto;
-  text-align: center;
-  color: #707070;
-}
-
-.login-form {
-  border-radius: 6px;
-  background: #ffffff;
-  width: 400px;
-  padding: 25px 25px 5px 25px;
-  .el-input {
-    height: 38px;
-    input {
-      height: 38px;
-    }
-  }
-  .input-icon {
-    height: 39px;
-    width: 14px;
-    margin-left: 2px;
-  }
-}
-.login-tip {
-  font-size: 13px;
-  text-align: center;
-  color: #bfbfbf;
-}
-.login-code {
-  width: 33%;
-  height: 38px;
-  float: right;
-  img {
-    cursor: pointer;
-    vertical-align: middle;
-  }
-}
-.el-login-footer {
-  height: 40px;
-  line-height: 40px;
-  position: fixed;
-  bottom: 0;
-  width: 100%;
-  text-align: center;
-  color: #fff;
-  font-family: Arial;
-  font-size: 12px;
-  letter-spacing: 1px;
-}
-.login-code-img {
-  height: 38px;
-}
-</style>

+ 0 - 208
src/views/register.vue

@@ -1,208 +0,0 @@
-<template>
-  <div class="register">
-    <el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
-      <h3 class="title">中正高校端后台管理系统</h3>
-      <el-form-item prop="username">
-        <el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
-          <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="password">
-        <el-input
-          v-model="registerForm.password"
-          type="password"
-          auto-complete="off"
-          placeholder="密码"
-          @keyup.enter.native="handleRegister"
-        >
-          <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="confirmPassword">
-        <el-input
-          v-model="registerForm.confirmPassword"
-          type="password"
-          auto-complete="off"
-          placeholder="确认密码"
-          @keyup.enter.native="handleRegister"
-        >
-          <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="code" v-if="captchaOnOff">
-        <el-input
-          v-model="registerForm.code"
-          auto-complete="off"
-          placeholder="验证码"
-          style="width: 63%"
-          @keyup.enter.native="handleRegister"
-        >
-          <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
-        </el-input>
-        <div class="register-code">
-          <img :src="codeUrl" @click="getCode" class="register-code-img"/>
-        </div>
-      </el-form-item>
-      <el-form-item style="width:100%;">
-        <el-button
-          :loading="loading"
-          size="medium"
-          type="primary"
-          style="width:100%;"
-          @click.native.prevent="handleRegister"
-        >
-          <span v-if="!loading">注 册</span>
-          <span v-else>注 册 中...</span>
-        </el-button>
-        <div style="float: right;">
-          <router-link class="link-type" :to="'/login'">使用已有账户登录</router-link>
-        </div>
-      </el-form-item>
-    </el-form>
-    <!--  底部  -->
-    <div class="el-register-footer">
-      <span>Copyright © 2018-2021 ruoyi.vip All Rights Reserved.</span>
-    </div>
-  </div>
-</template>
-
-<script>
-import { getCodeImg, register } from "@/api/login";
-
-export default {
-  name: "Register",
-  data() {
-    const equalToPassword = (rule, value, callback) => {
-      if (this.registerForm.password !== value) {
-        callback(new Error("两次输入的密码不一致"));
-      } else {
-        callback();
-      }
-    };
-    return {
-      codeUrl: "",
-      registerForm: {
-        username: "",
-        password: "",
-        confirmPassword: "",
-        code: "",
-        uuid: ""
-      },
-      registerRules: {
-        username: [
-          { required: true, trigger: "blur", message: "请输入您的账号" },
-          { min: 2, max: 20, message: '用户账号长度必须介于 2 和 20 之间', trigger: 'blur' }
-        ],
-        password: [
-          { required: true, trigger: "blur", message: "请输入您的密码" },
-          { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
-        ],
-        confirmPassword: [
-          { required: true, trigger: "blur", message: "请再次输入您的密码" },
-          { required: true, validator: equalToPassword, trigger: "blur" }
-        ],
-        code: [{ required: true, trigger: "change", message: "请输入验证码" }]
-      },
-      loading: false,
-      captchaOnOff: true
-    };
-  },
-  created() {
-    this.getCode();
-  },
-  methods: {
-    getCode() {
-      getCodeImg().then(res => {
-        this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
-        if (this.captchaOnOff) {
-          this.codeUrl = "data:image/gif;base64," + res.img;
-          this.registerForm.uuid = res.uuid;
-        }
-      });
-    },
-    handleRegister() {
-      this.$refs.registerForm.validate(valid => {
-        if (valid) {
-          this.loading = true;
-          register(this.registerForm).then(res => {
-            const username = this.registerForm.username;
-            this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
-              dangerouslyUseHTMLString: true
-            }).then(() => {
-              this.$router.push("/login");
-            }).catch(() => {});
-          }).catch(() => {
-            this.loading = false;
-            if (this.captchaOnOff) {
-              this.getCode();
-            }
-          })
-        }
-      });
-    }
-  }
-};
-</script>
-
-<style rel="stylesheet/scss" lang="scss">
-.register {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  height: 100%;
-  background-image: url("../assets/images/login-background.jpg");
-  background-size: cover;
-}
-.title {
-  margin: 0px auto 30px auto;
-  text-align: center;
-  color: #707070;
-}
-
-.register-form {
-  border-radius: 6px;
-  background: #ffffff;
-  width: 400px;
-  padding: 25px 25px 5px 25px;
-  .el-input {
-    height: 38px;
-    input {
-      height: 38px;
-    }
-  }
-  .input-icon {
-    height: 39px;
-    width: 14px;
-    margin-left: 2px;
-  }
-}
-.register-tip {
-  font-size: 13px;
-  text-align: center;
-  color: #bfbfbf;
-}
-.register-code {
-  width: 33%;
-  height: 38px;
-  float: right;
-  img {
-    cursor: pointer;
-    vertical-align: middle;
-  }
-}
-.el-register-footer {
-  height: 40px;
-  line-height: 40px;
-  position: fixed;
-  bottom: 0;
-  width: 100%;
-  text-align: center;
-  color: #fff;
-  font-family: Arial;
-  font-size: 12px;
-  letter-spacing: 1px;
-}
-.register-code-img {
-  height: 38px;
-}
-</style>

+ 49 - 5
src/views/resource/baseManageInfos/resource/businessLevel/index.vue

@@ -18,6 +18,7 @@
       @editInfo="editInfo"
       @emitData="openPZDowm"
       @sortFunc="sortFunc"
+      @editName="editName"
     >
       <!-- <template slot="customize">
         <el-button size="small" type="success" @click="setOptions"
@@ -324,17 +325,20 @@ export default {
         },
         {
           label: "业务层次名称",
-          prop: "businessName",
+          prop1: "projectName",
+          prop2: "businessName",
+          scope: "InfoMore",
           hidden: true,
         },
         {
-          label: "教育类型",
-          prop: "educationName",
+          label: "业务层次别名",
+          prop: "aliasName",
           hidden: true,
+          scope: "editName",
         },
         {
-          label: "项目类型",
-          prop: "projectName",
+          label: "教育类型",
+          prop: "educationName",
           hidden: true,
         },
         {
@@ -478,6 +482,46 @@ export default {
     this.initPlate();
   },
   methods: {
+    /**
+     * 修改别名
+     */
+    editName(item) {
+      this.$prompt("请输入新别名", "修改", {
+        inputErrorMessage: "请输入内容",
+        inputValidator: (value) => {
+          if (value == null || value == "" || value == undefined) {
+            return false;
+          } else {
+            if (value.trim().length == 0) {
+              return false;
+            } else {
+              return true;
+            }
+          }
+        },
+        inputValue:item.aliasName,
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        beforeClose: (action, instance, done) => {
+          if (action === "confirm") {
+            let apiData = JSON.parse(JSON.stringify(item));
+            apiData.aliasName = instance.inputValue;
+            this.$api.editCourseBusiness(apiData).then((res) => {
+              done();
+              this.$store.commit("BUSINESSLEVEL");
+              this.search();
+            })
+          } else {
+            done();
+          }
+        },
+      })
+        .then(({ value }) => {
+          this.$message.success("修改成功");
+        })
+        .catch(() => {});
+      console.log(item);
+    },
     sortFunc(row) {
       if (row.sort || row.sort == 0) {
         this.$api.editCourseBusiness(row).then((res) => {

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

@@ -1221,6 +1221,7 @@ export default {
       }
       this.tableData = this.tableData.concat(this.activeLists);
       this.dialogVisible = false;
+      this.activeLists = []
       if (!int) {
         this.$message({
           type: "success",

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

@@ -179,7 +179,7 @@
           <div>
             <el-button size="small" @click="openBoxs">调用已有数据</el-button>
             <el-button size="small" type="success" @click="dialogDRFunc"
-              >Excel批量新增</el-button
+              >Excel批量新增</el-button
             >
             <el-button size="small" @click="addSection">自定义添加节</el-button>
           </div>
@@ -625,7 +625,7 @@ export default {
     this.$modal.loading("正在导入数据,请稍后...");
     this.$api.gradecheckGoodsChange({ chapterId: this.pageId }).then((res) => {
       if (res.data > 0) {
-        this.noStudent = false;
+        // this.noStudent = false;
       }
     });
     await this.getDict();
@@ -662,7 +662,6 @@ export default {
      * 添加节-返回数据
      */
     backData(v) {
-      console.log(v)
       this.$api.inquireCourseSection({ sectionIds: v }).then((res) => {
         this.activeLists = res.rows;
         this.submitForm();
@@ -1312,6 +1311,7 @@ export default {
         });
       }
       this.tableData = this.tableData.concat(this.activeLists);
+      this.activeLists = []
       this.dialogVisible = false;
       if (!int) {
         this.$message({

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

@@ -299,7 +299,7 @@ export default {
       .gradecheckGoodsChange({ courseId: this.$route.query.id })
       .then((res) => {
         if (res.data > 0) {
-          this.noStudent = false;
+          // this.noStudent = false;
         }
       });
     this.getDict();

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

@@ -552,7 +552,7 @@ export default {
       .gradecheckGoodsChange({ courseId: this.$route.query.id })
       .then((res) => {
         if (res.data > 0) {
-          this.noStudent = false;
+          // this.noStudent = false;
         }
       });
     this.getDs();

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

@@ -537,7 +537,7 @@ export default {
     this.$modal.loading("正在导入数据,请稍后...");
     this.$api.gradecheckGoodsChange({ sectionId: this.pageId }).then((res) => {
       if (res.data > 0) {
-        this.noStudent = false;
+        // this.noStudent = false;
       }
     });
     this.getDict();

+ 221 - 2
src/views/resource/videoManagement/moduleManagement/add/index.vue

@@ -204,6 +204,9 @@
         <div class="dis_plays">
           <div>
             <el-button size="small" @click="openBoxs">调用已有数据</el-button>
+            <el-button size="small" type="success" @click="dialogDRFunc"
+              >Excel批量新增章</el-button
+            >
             <el-button size="small" @click="addChapter">自定义添加章</el-button>
           </div>
           <div style="color: #f56c6c">
@@ -391,11 +394,95 @@
         >
       </span>
     </el-dialog>
+    <el-dialog
+      :visible.sync="dialogDR"
+      width="660px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">导入</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogDR = false"
+          />
+        </div>
+      </div>
+      <div>
+        <div class="swq">
+          <img
+            style="width: 182px; height: 168px"
+            src="@/assets/images/dr.png"
+            alt=""
+          />
+        </div>
+        <div style="padding-left: 100px">
+          <p>第一步:下载导入模板</p>
+          <p style="padding-left: 50px">
+            <i class="el-icon-upload"></i
+            ><span class="dowmStys" @click="getDowm">下载模板</span>
+          </p>
+          <p>第二步:(批量新增):点击“上传Excel”完成导入</p>
+          <label
+            for="mobles"
+            class="el-button el-button--primary"
+            style="margin-left: 50px; padding: 10px 20px"
+            >上传Excel</label
+          ><input
+            style="display: none"
+            type="file"
+            id="mobles"
+            ref="input1"
+            @change="importMobleadd"
+          />
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogDR = false">取消</el-button>
+        <!-- <el-button type="primary" @click="submitChecksDR">确定</el-button> -->
+      </span>
+    </el-dialog>
+    <el-dialog
+      append-to-body
+      :visible.sync="dialogERROR"
+      width="660px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">提示</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogERROR = false"
+          />
+        </div>
+      </div>
+      <div>
+        <h4 style="margin-top: 0px; font-weight: bold; text-align: center">
+          导入失败原因
+        </h4>
+        <el-input
+          readonly
+          type="textarea"
+          :autosize="{ minRows: 6, maxRows: 24 }"
+          v-model="errorData"
+        >
+        </el-input>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogERROR = false">确定</el-button>
+      </span>
+    </el-dialog>
     <addChapter ref="addChapter" @backData="backData" />
   </div>
 </template>
 
 <script>
+import * as baseUrls from "@/utils/request.js";
 import addChapter from "../addChapter.vue";
 import searchBoxNew from "@/components/searchBoxNew";
 import pagination from "@/components/pagination";
@@ -508,6 +595,9 @@ export default {
       disCheckList: [], //已选转禁用复选列表
       activeLists: [],
       localData: [],
+      errorData: "",
+      dialogERROR: false,
+      dialogDR: false,
     };
   },
   watch: {
@@ -540,6 +630,115 @@ export default {
     }
   },
   methods: {
+    
+    /**
+     * 下载Excel模板
+     */
+    getDowm() {
+      let url =
+        baseUrls.BASE_IMG_URL + "/oss/images/file/20220617/1655453121157.xlsx";
+      let link = document.createElement("a");
+      let fileName = "导入模板" + ".xlsx";
+      document.body.appendChild(link);
+      link.href = url;
+      link.dowmload = fileName;
+      link.click();
+      link.remove();
+    },
+    dialogDRFunc() {
+      if (!this.newSujectApis.length) {
+        this.$message.error("请添加科目");
+        return;
+      }
+      this.dialogDR = true;
+    }
+    /**
+     *
+     * @param {Object} e
+     * @remards 导入逻辑
+     */,
+    importMobleadd(e) {
+      if (!this.newSujectApis.length) {
+        this.$message.error("请添加科目");
+        return;
+      }
+      var self = this;
+      var file = e.target.files[0];
+      let formData = new FormData();
+      formData.append("businessJson", JSON.stringify(this.newSujectApis));
+      formData.append("file", file);
+      this.$api
+        .CoursemoduleimportData(formData)
+        .then(async (res) => {
+          if (res.code === 200) {
+            if (!res.data.errorLog) {
+              await this.awaitGetFestivalList(res.data.importNo, 1)
+                .then((result) => {
+                  self.dialogDR = false;
+                })
+                .catch(() => {
+                  e.target.value = "";
+                });
+            } else {
+              await this.awaitGetFestivalList(res.data.importNo, 2)
+                .then((result) => {
+                  let ary = res.data.errorLog.split("\r\n");
+                  ary = ary
+                    .filter((item) => {
+                      return item.length > 0;
+                    })
+                    .reverse();
+                  self.$message({
+                    message: `${ary.length}条数据导入失败,请查看失败原因`,
+                    customClass: "myMessageClass",
+                  });
+                  ary = ary.join("\r\n");
+                  self.errorData = ary;
+                  self.dialogERROR = true;
+                })
+                .catch(() => {
+                  e.target.value = "";
+                });
+            }
+          }
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
+    },
+    /**
+     *
+     * @param {Strings} ids 查询编码
+     * @param {Number} type 1为成功2为失败
+     * @remards 失败时也需查询是否有成功的数据导入数据库,如存在 则加列队列同时提示
+     */
+    awaitGetFestivalList(ids, type) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .inquireCourseListchapter({ importNo: ids })
+          .then((res) => {
+            if (type === 2 && res.rows.length) {
+              this.$message({
+                type: "success",
+                message: `成功导入${res.rows.length}条数据,`,
+                customClass: "myMessageClass",
+              });
+            }
+            if (res.rows.length) {
+              this.activeLists = res.rows;
+              if (type === 1) {
+                this.submitForm();
+              } else {
+                this.submitForm(1);
+              }
+            }
+            resolve();
+          })
+          .catch(() => {
+            reject();
+          });
+      });
+    },
     jumpChapter(v) {
       const jump = () => {
         this.$store.dispatch("changemodulePage", {
@@ -973,7 +1172,12 @@ export default {
     getRowKeys(row) {
       return row.chapterId;
     },
-    submitForm() {
+    /**
+     *
+     * @param {Number} int 导入失败标识
+     * @remards 合并且排列节列表数据
+     */
+    submitForm(int) {
       if (this.activeLists.length === 0) {
         this.dialogVisible = false;
         return;
@@ -995,7 +1199,14 @@ export default {
       }
       this.tableData = this.tableData.concat(this.activeLists);
       this.dialogVisible = false;
-      this.$message.success("添加成功");
+      this.activeLists = []
+      if (!int) {
+        this.$message({
+          type: "success",
+          message: `添加成功`,
+          customClass: "myMessageClass",
+        });
+      }
     },
     delList(item) {
       this.tableData.map((items, indexs) => {
@@ -1013,6 +1224,14 @@ export default {
 </script>
 
 <style lang="less" scoped>
+.swq {
+  text-align: center;
+  border-bottom: 1px solid #eee;
+}
+.dowmStys {
+  color: blue;
+  cursor: pointer;
+}
 .boxWidth {
   width: 800px;
 }

+ 233 - 19
src/views/resource/videoManagement/moduleManagement/edit/index.vue

@@ -178,6 +178,9 @@
         <div class="dis_plays">
           <div>
             <el-button size="small" @click="openBoxs">调用已有数据</el-button>
+            <el-button size="small" type="success" @click="dialogDRFunc"
+              >Excel批量新增章</el-button
+            >
             <el-button size="small" @click="addChapter">自定义添加章</el-button>
           </div>
           <div style="color: #f56c6c">
@@ -366,11 +369,95 @@
         >
       </span>
     </el-dialog>
+    <el-dialog
+      :visible.sync="dialogDR"
+      width="660px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">导入</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogDR = false"
+          />
+        </div>
+      </div>
+      <div>
+        <div class="swq">
+          <img
+            style="width: 182px; height: 168px"
+            src="@/assets/images/dr.png"
+            alt=""
+          />
+        </div>
+        <div style="padding-left: 100px">
+          <p>第一步:下载导入模板</p>
+          <p style="padding-left: 50px">
+            <i class="el-icon-upload"></i
+            ><span class="dowmStys" @click="getDowm">下载模板</span>
+          </p>
+          <p>第二步:(批量新增):点击“上传Excel”完成导入</p>
+          <label
+            for="mobles"
+            class="el-button el-button--primary"
+            style="margin-left: 50px; padding: 10px 20px"
+            >上传Excel</label
+          ><input
+            style="display: none"
+            type="file"
+            id="mobles"
+            ref="input1"
+            @change="importMobleadd"
+          />
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogDR = false">取消</el-button>
+        <!-- <el-button type="primary" @click="submitChecksDR">确定</el-button> -->
+      </span>
+    </el-dialog>
+    <el-dialog
+      append-to-body
+      :visible.sync="dialogERROR"
+      width="660px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">提示</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogERROR = false"
+          />
+        </div>
+      </div>
+      <div>
+        <h4 style="margin-top: 0px; font-weight: bold; text-align: center">
+          导入失败原因
+        </h4>
+        <el-input
+          readonly
+          type="textarea"
+          :autosize="{ minRows: 6, maxRows: 24 }"
+          v-model="errorData"
+        >
+        </el-input>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogERROR = false">确定</el-button>
+      </span>
+    </el-dialog>
     <addChapter ref="addChapter" @backData="backData" />
   </div>
 </template>
 
 <script>
+import * as baseUrls from "@/utils/request.js";
 import searchBoxNew from "@/components/searchBoxNew";
 import pagination from "@/components/pagination";
 import addChapter from "../addChapter.vue";
@@ -424,7 +511,7 @@ export default {
         { label: "章编码", prop: "code", width: "120" },
         { label: "标题前缀", prop: "prefixName", width: "180" },
         { label: "章标题", prop: "name" },
-        { label: "节数量", prop: "sectionNum" , width: "120" },
+        { label: "节数量", prop: "sectionNum", width: "120" },
         {
           label: "发布状态",
           prop: "publishStatus",
@@ -483,7 +570,10 @@ export default {
       disCheckList: [], //已选转禁用复选列表
       activeLists: [],
       noStudent: true,
-      pageId:this.$route.query.id
+      pageId: this.$route.query.id,
+      errorData: "",
+      dialogERROR: false,
+      dialogDR: false,
     };
   },
   watch: {
@@ -496,13 +586,11 @@ export default {
   },
   async mounted() {
     this.$modal.loading("正在导入数据,请稍后...");
-    this.$api
-      .gradecheckGoodsChange({ moduleId: this.pageId })
-      .then((res) => {
-        if (res.data > 0) {
-          this.noStudent = false;
-        }
-      });
+    this.$api.gradecheckGoodsChange({ moduleId: this.pageId }).then((res) => {
+      if (res.data > 0) {
+        // this.noStudent = false;
+      }
+    });
     await this.getDict();
     this.search();
   },
@@ -523,6 +611,114 @@ export default {
     }
   },
   methods: {
+    /**
+     * 下载Excel模板
+     */
+    getDowm() {
+      let url =
+        baseUrls.BASE_IMG_URL + "/oss/images/file/20220617/1655453121157.xlsx";
+      let link = document.createElement("a");
+      let fileName = "导入模板" + ".xlsx";
+      document.body.appendChild(link);
+      link.href = url;
+      link.dowmload = fileName;
+      link.click();
+      link.remove();
+    },
+    dialogDRFunc() {
+      if (!this.newSujectApis.length) {
+        this.$message.error("请添加科目");
+        return;
+      }
+      this.dialogDR = true;
+    }
+    /**
+     *
+     * @param {Object} e
+     * @remards 导入逻辑
+     */,
+    importMobleadd(e) {
+      if (!this.newSujectApis.length) {
+        this.$message.error("请添加科目");
+        return;
+      }
+      var self = this;
+      var file = e.target.files[0];
+      let formData = new FormData();
+      formData.append("businessJson", JSON.stringify(this.newSujectApis));
+      formData.append("file", file);
+      this.$api
+        .CoursemoduleimportData(formData)
+        .then(async (res) => {
+          if (res.code === 200) {
+            if (!res.data.errorLog) {
+              await this.awaitGetFestivalList(res.data.importNo, 1)
+                .then((result) => {
+                  self.dialogDR = false;
+                })
+                .catch(() => {
+                  e.target.value = "";
+                });
+            } else {
+              await this.awaitGetFestivalList(res.data.importNo, 2)
+                .then((result) => {
+                  let ary = res.data.errorLog.split("\r\n");
+                  ary = ary
+                    .filter((item) => {
+                      return item.length > 0;
+                    })
+                    .reverse();
+                  self.$message({
+                    message: `${ary.length}条数据导入失败,请查看失败原因`,
+                    customClass: "myMessageClass",
+                  });
+                  ary = ary.join("\r\n");
+                  self.errorData = ary;
+                  self.dialogERROR = true;
+                })
+                .catch(() => {
+                  e.target.value = "";
+                });
+            }
+          }
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
+    },
+    /**
+     *
+     * @param {Strings} ids 查询编码
+     * @param {Number} type 1为成功2为失败
+     * @remards 失败时也需查询是否有成功的数据导入数据库,如存在 则加列队列同时提示
+     */
+    awaitGetFestivalList(ids, type) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .inquireCourseListchapter({ importNo: ids })
+          .then((res) => {
+            if (type === 2 && res.rows.length) {
+              this.$message({
+                type: "success",
+                message: `成功导入${res.rows.length}条数据,`,
+                customClass: "myMessageClass",
+              });
+            }
+            if (res.rows.length) {
+              this.activeLists = res.rows;
+              if (type === 1) {
+                this.submitForm();
+              } else {
+                this.submitForm(1);
+              }
+            }
+            resolve();
+          })
+          .catch(() => {
+            reject();
+          });
+      });
+    },
     jumpChapter(v) {
       const jump = () => {
         this.$store.dispatch("changemodulePage", {
@@ -640,13 +836,11 @@ export default {
         });
     },
     getInfosList() {
-      this.$api
-        .inquireCourseListmodulechapter(this.pageId)
-        .then((result) => {
-          // this.numberAll = result.total;
-          // this.minTimeAll = result.timeTotal;
-          this.tableData = result.data;
-        });
+      this.$api.inquireCourseListmodulechapter(this.pageId).then((result) => {
+        // this.numberAll = result.total;
+        // this.minTimeAll = result.timeTotal;
+        this.tableData = result.data;
+      });
     },
     init() {
       this.getInfos(2);
@@ -947,7 +1141,12 @@ export default {
     getRowKeys(row) {
       return row.chapterId;
     },
-    submitForm() {
+    /**
+     *
+     * @param {Number} int 导入失败标识
+     * @remards 合并且排列节列表数据
+     */
+    submitForm(int) {
       if (this.activeLists.length === 0) {
         this.dialogVisible = false;
         return;
@@ -969,7 +1168,14 @@ export default {
       }
       this.tableData = this.tableData.concat(this.activeLists);
       this.dialogVisible = false;
-      this.$message.success("添加成功");
+      this.activeLists = []
+      if (!int) {
+        this.$message({
+          type: "success",
+          message: `添加成功`,
+          customClass: "myMessageClass",
+        });
+      }
     },
     delList(item) {
       this.tableData.map((items, indexs) => {
@@ -979,7 +1185,7 @@ export default {
         }
       });
     },
-    closedFunc(){
+    closedFunc() {
       this.activeLists = [];
     },
   },
@@ -987,6 +1193,14 @@ export default {
 </script>
 
 <style lang="less" scoped>
+.swq {
+  text-align: center;
+  border-bottom: 1px solid #eee;
+}
+.dowmStys {
+  color: blue;
+  cursor: pointer;
+}
 .boxWidth {
   width: 800px;
 }

+ 1 - 1
src/views/system/menu/index.vue

@@ -424,7 +424,7 @@ export default {
       this.$refs["form"].validate(valid => {
         if (valid) {
           if (this.form.menuId != undefined) {
-            updateMenu(this.form).then(response => {
+            this.$api.editsystemmenu(this.form).then(response => {
               this.$modal.msgSuccess("修改成功");
               this.open = false;
               this.getList();