Sfoglia il codice sorgente

Merge branch 'seven' into dev

yangdamao 3 anni fa
parent
commit
13d780b369
100 ha cambiato i file con 9405 aggiunte e 2135 eliminazioni
  1. 1 0
      .env.development
  2. 3 0
      .env.production
  3. 7 0
      .env.staging
  4. 1 0
      .gitignore
  5. 1 2
      public/index.html
  6. 3 1
      src/api/api.js
  7. BIN
      src/assets/images/idcardF.png
  8. BIN
      src/assets/images/idcardZ.png
  9. BIN
      src/assets/images/peopleImg.png
  10. 5 0
      src/components/Editor/index.vue
  11. 119 9
      src/components/tableList.vue
  12. 348 1
      src/layout/components/Navbar.vue
  13. 24 0
      src/newApi/applicationData.js
  14. 60 0
      src/newApi/appuser.js
  15. 16 1
      src/newApi/business.js
  16. 8 0
      src/newApi/classTab.js
  17. 16 0
      src/newApi/colleges.js
  18. 64 0
      src/newApi/course.js
  19. 7 0
      src/newApi/examapply.js
  20. 16 0
      src/newApi/festival.js
  21. 8 0
      src/newApi/goods.js
  22. 8 0
      src/newApi/modules.js
  23. 31 0
      src/newApi/notificationFL.js
  24. 8 0
      src/newApi/studentList.js
  25. 55 0
      src/newApi/systemExam.js
  26. 0 5
      src/router/index.js
  27. 1 1
      src/store/modules/tagsView.js
  28. 1 1
      src/store/modules/user.js
  29. 1 1
      src/utils/request.js
  30. 258 0
      src/views/2Cport/filterItemSettings/index.vue
  31. 81 6
      src/views/2Cport/referralManageMent/tab1/addGL.vue
  32. 81 6
      src/views/2Cport/referralManageMent/tab2/addGL.vue
  33. 2 3
      src/views/Marketing/goods/commodityManageMent/add/courseContent/index.vue
  34. 7 0
      src/views/Marketing/goods/commodityManageMent/add/pricePeriod.vue
  35. 432 0
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/index copy.vue
  36. 170 20
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue
  37. 181 0
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/share.vue
  38. 3 1
      src/views/Marketing/goods/commodityManageMent/edit/index.vue
  39. 9 0
      src/views/Marketing/goods/commodityManageMent/edit/pricePeriod.vue
  40. 44 4
      src/views/Marketing/goods/commodityManageMent/index.vue
  41. 50 43
      src/views/Marketing/goods/commodityManageMent/poppleSet.vue
  42. 383 0
      src/views/Marketing/goods/commodityManageMent/teacher/index.vue
  43. 203 0
      src/views/Marketing/goods/commodityManageMent/teacher/selectCourse.vue
  44. 277 0
      src/views/Marketing/goods/goodTopic/index.vue
  45. 28 5
      src/views/Marketing/order/offlineOrder/batchRecord/firstStep/index.vue
  46. 4 0
      src/views/Marketing/order/offlineOrder/batchRecord/firstStep/uploadStudent.vue
  47. 18 5
      src/views/Marketing/order/offlineOrder/batchRecord/secondStep/index.vue
  48. 62 43
      src/views/Marketing/order/offlineOrder/batchRecord/secondStep/setGoodsList.vue
  49. 64 4
      src/views/Marketing/order/offlineOrder/index.vue
  50. 10 1
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/costPrice.vue
  51. 18 5
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/goodsInfos.vue
  52. 33 3
      src/views/Marketing/order/offlineOrder/orderChargeInfo/topBox.vue
  53. 4 4
      src/views/Marketing/order/offlineOrder/orderDetailsT/index.vue
  54. 0 102
      src/views/dashboard/BarChart.vue
  55. 0 135
      src/views/dashboard/LineChart.vue
  56. 0 181
      src/views/dashboard/PanelGroup.vue
  57. 0 79
      src/views/dashboard/PieChart.vue
  58. 0 116
      src/views/dashboard/RaddarChart.vue
  59. 3 0
      src/views/education/classManageMent/classHoursReview/index.vue
  60. 353 254
      src/views/education/classManageMent/classHoursReview/studyTimes.vue
  61. 1 1
      src/views/education/classManageMent/classList/index.vue
  62. 689 0
      src/views/education/classManageMent/hoursTimesRecord/index.vue
  63. 1 0
      src/views/education/classManageMent/learningAccoutTags/index.vue
  64. 175 85
      src/views/education/classManageMent/learningHoursRecordList/hoursTimesRecord.vue
  65. 138 130
      src/views/education/classManageMent/learningHoursRecordList/index.vue
  66. 344 270
      src/views/education/classManageMent/learningHoursRecordList/studyTimesRecord.vue
  67. 33 18
      src/views/education/classManageMent/listOfhoursToBeReviewed/index.vue
  68. 168 14
      src/views/education/classManageMent/studentMenu/index.vue
  69. 32 1
      src/views/education/examManagement/applicationData/asPlanned.vue
  70. 5 4
      src/views/education/examManagement/applicationData/bulkImportPlan/newRegister.vue
  71. 2 2
      src/views/education/examManagement/applicationData/byTrainee.vue
  72. 18 1
      src/views/education/examManagement/applicationData/cancelAppointMent/index.vue
  73. 18 1
      src/views/education/examManagement/applicationData/examRegistration/index.vue
  74. 25 8
      src/views/education/examManagement/applicationData/formerAccount/index.vue
  75. 273 0
      src/views/education/examManagement/examArrangement/applicableProducts/beforePage.vue
  76. 267 0
      src/views/education/examManagement/examArrangement/applicableProducts/downMaterial.vue
  77. 188 17
      src/views/education/examManagement/examArrangement/index.vue
  78. 37 2
      src/views/education/examManagement/examConfiguration/examPlace/index.vue
  79. 238 0
      src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/curriculumDimension.vue
  80. 266 0
      src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/curriculumDimensionData/index.vue
  81. 219 0
      src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/curriculumDimensionData/infoBox.vue
  82. 12 193
      src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/index.vue
  83. 211 0
      src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/studentDimension.vue
  84. 527 0
      src/views/education/marketingCampaignManageMent/marketingActivitiesList/index.vue
  85. 139 0
      src/views/education/marketingCampaignManageMent/marketingActivitiesList/userBoxs.vue
  86. 75 35
      src/views/education/mockTestManagement/mockExamArrangement/addMockExam/index.vue
  87. 107 82
      src/views/education/mockTestManagement/mockExamArrangement/addMockExam/infoPage.vue
  88. 90 41
      src/views/education/mockTestManagement/mockExamArrangement/editMockExam/index.vue
  89. 102 69
      src/views/education/mockTestManagement/mockExamArrangement/editMockExam/infoPage.vue
  90. 29 8
      src/views/education/notificationManageMent/notificationModel/index.vue
  91. 427 0
      src/views/education/notificationManageMent/stationLetter/index.vue
  92. 303 5
      src/views/education/studentManageMent/studentList/index.vue
  93. 239 0
      src/views/education/studentManageMent/studentStatistics/index.vue
  94. 189 0
      src/views/education/studentManageMent/studentXQ/accesslog.vue
  95. 4 3
      src/views/education/studentManageMent/studentXQ/classRecord.vue
  96. 10 0
      src/views/education/studentManageMent/studentXQ/index.vue
  97. 6 5
      src/views/education/studentManageMent/studentXQ/studentBaseManage.vue
  98. 207 0
      src/views/education/studentManageMent/studentXQ/studylog.vue
  99. 1 0
      src/views/index.vue
  100. 0 98
      src/views/index_v1.vue

+ 1 - 0
.env.development

@@ -6,6 +6,7 @@ ENV = 'development'
 
 # 中正云教育管理后台/开发环境
 VUE_APP_BASE_API = 'http://192.168.1.222:5030/'
+# VUE_APP_BASE_API = 'http://localhost:5030/'
 VUE_APP_IMG_API = 'https://file-dev.xyyxt.net'
 
 # 路由懒加载

+ 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

+ 7 - 0
.env.staging

@@ -7,5 +7,12 @@ NODE_ENV = production
 ENV = 'staging'
 
 # 中正云教育管理后台/预发布环境
+# 测试
+VUE_APP_BASE_API1 = 'http://120.79.166.78:19013/'
+# 预发布
 VUE_APP_BASE_API = 'http://120.79.166.78:19007/'
+#图片
 VUE_APP_IMG_API = 'https://file-dev.xyyxt.net'
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 1 - 0
.gitignore

@@ -1,4 +1,5 @@
 .DS_Store
+.history
 node_modules/
 dist/
 npm-debug.log*

+ 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,

+ 3 - 1
src/api/api.js

@@ -100,6 +100,7 @@ import homeApi from '../newApi/homeApi'//控制台学员数据
 import studyAccountStatus from '../newApi/studyAccountStatus'//学习账号标记
 import mock from '../newApi/mock'//模考管理
 import mockSub from '../newApi/mockSub'//预约模考管理
+import systemExam from '../newApi/systemExam'//模考活动列表
 
 
 
@@ -179,7 +180,8 @@ export default {
     ...homeApi,
     ...studyAccountStatus,
     ...mock,
-    ...mockSub
+    ...mockSub,
+    ...systemExam,
 
     // ...login,
     // ...profession,

BIN
src/assets/images/idcardF.png


BIN
src/assets/images/idcardZ.png


BIN
src/assets/images/peopleImg.png


+ 5 - 0
src/components/Editor/index.vue

@@ -138,6 +138,7 @@ export default {
       };
       this.$api.getPolicy(datats).then((res) => {
         this.datas = res.data.resultContent;
+        console.log(res.data.resultContent.host)
         this.uploadUrl = res.data.resultContent.host;
         resolve();
       });
@@ -150,6 +151,7 @@ export default {
   },
   methods: {
     handleCustomMatcher(node, Delta) {
+      console.log("handleCustomMatcher")
       let ops = [];
       Delta.ops.forEach((op) => {
         if (op.insert && typeof op.insert === "string") {
@@ -185,6 +187,7 @@ export default {
       return Delta;
     },
     base64ToFile(base64, fileName) {
+      console.log("base64ToFile")
       return new Promise((resolve, reject) => {
         let arr = base64.split(",");
         let mime = arr[0].match(/:(.*?);/)[1];
@@ -201,6 +204,7 @@ export default {
       });
     },
     init() {
+      console.log("init")
       const editor = this.$refs.editor;
       this.Quill = new Quill(editor, this.options);
       // 如果设置了上传地址则自定义图片上传事件
@@ -253,6 +257,7 @@ export default {
       };
     },
     imageChange(param, type) {
+      console.log("imageChange")
       this.$upload
         .upload(param.file, this.uploadStatus)
         .then((res) => {

+ 119 - 9
src/components/tableList.vue

@@ -668,10 +668,38 @@
                 : scope.row[item.prop2] + "~" + scope.row[item.prop3]
             }}
           </span>
+          <template v-else-if="item.scope === 'courseAbout'">
+            <div v-for="(item, index) in scope.row[item.prop]" :key="index">
+            {{ item.courseName }}  ({{ item.aliasName }})
+          </div>
+          </template>
           <div v-else-if="item.scope === 'changAdress'">
-            <div>{{ scope.row[item.prop1] }}</div>
+            <div>地点:{{ scope.row[item.prop1] }}</div>
             <div>
-              {{ $methodsTools.onlyForma(scope.row[item.prop2], false) }}
+              时间:{{ $methodsTools.onlyForma(scope.row[item.prop2], false) }}
+              <span
+                >{{ scope.row[item.prop3] }}-{{ scope.row[item.prop4] }}</span
+              >
+            </div>
+            <div v-if="scope.row['fromPlat'] === 2">准考证号:{{ scope.row[item.prop5] }}</div>
+            <div v-if="scope.row['fromPlat'] === 2">座位号:{{ scope.row[item.prop6] }}</div>
+            <div v-if="scope.row['fromPlat'] === 2">
+              同步到考场状态:{{
+                scope.row[item.prop7] === 0
+                  ? "未同步"
+                  : scope.row[item.prop7] === 1
+                  ? "成功"
+                  : scope.row[item.prop7] === 2
+                  ? "失败"
+                  : ""
+              }} 
+              <!-- <el-button v-if="scope.row[item.prop7] === 2" type="text">原因</el-button> -->
+            </div>
+          </div>
+          <div v-else-if="item.scope === 'changAdressKP'">
+            <div>地点:{{ scope.row[item.prop1] }}</div>
+            <div>
+              时间:{{ $methodsTools.onlyForma(scope.row[item.prop2], false) }}
               <span
                 >{{ scope.row[item.prop3] }}-{{ scope.row[item.prop4] }}</span
               >
@@ -907,7 +935,7 @@
           <span v-else-if="item.scope === 'aTimeList'">{{
             scope.row[item.prop] === null
               ? "--"
-              : $methodsTools.onlyForma(scope.row[item.prop])
+              : $methodsTools.onlyForma(scope.row[item.prop], !item.isDiszing)
           }}</span>
           <div v-else-if="item.scope === 'inputs'">
             <el-input-number
@@ -974,6 +1002,27 @@
                 : ""
             }}
           </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>
+          <ul style="margin: 0" v-else-if="item.scope === 'chance'">
+            <li>总共:{{ scope.row[item.prop1] }}</li>
+            <li>消耗:{{ scope.row[item.prop2] }}</li>
+            <li>剩余:{{ scope.row[item.prop1] - scope.row[item.prop2] }}</li>
+          </ul>
+          <ul style="margin: 0" v-else-if="item.scope === 'studyCount'">
+            <li>总共:{{ scope.row[item.prop1] + scope.row[item.prop2] }}</li>
+            <li>消耗:{{ scope.row[item.prop1] }}</li>
+            <li>剩余:{{ scope.row[item.prop2] }}</li>
+          </ul>
           <span
             v-else-if="item.scope === 'statusPeriod'"
             :style="scope.row[item.prop] === 2 ? 'color:red' : ''"
@@ -1204,6 +1253,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 +1456,39 @@
               >
             </template>
           </div>
+          <div v-else-if="item.scope === 'isOptionsDY'">
+            <template v-for="(itemt, indext) in item.options">
+              <div
+                :key="indext"
+                v-if="itemt.value === scope.row[item.prop]"
+                :style="
+                  scope.row[item.prop] == 5 ? 'color:rgb(132, 0, 255);' : ''
+                "
+              >
+                <el-popover
+                  :key="indext"
+                  trigger="hover"
+                  v-if="itemt.popover === true"
+                >
+                  <span
+                    >订单编号(业务系统):{{ scope.row[item.oldOrder] }}</span
+                  >
+                  <el-button type="text" slot="reference">{{
+                    itemt.label
+                  }}</el-button>
+                </el-popover>
+                <span v-else
+                  >{{ itemt.label }}
+                  <el-button
+                    type="text"
+                    v-if="itemt.click"
+                    @click="backFunc(scope.row)"
+                    >查看</el-button
+                  ></span
+                >
+              </div>
+            </template>
+          </div>
           <div v-else-if="item.scope === 'orderGoodsStatus'">
             {{
               scope.row[item.prop] === -1
@@ -1433,14 +1524,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>
 
@@ -1760,7 +1851,14 @@
 import bankMsg from "./bankMsg";
 export default {
   components: { bankMsg },
-  props: ["tableSets", "tableData", "navText", "rowKey", "loading"],
+  props: [
+    "tableSets",
+    "tableData",
+    "navText",
+    "rowKey",
+    "loading",
+    "studentTable",
+  ],
   data: function () {
     return {
       diaviosOpen: false,
@@ -1844,6 +1942,12 @@ export default {
     },
   },
   created() {
+    if (this.studentTable) {
+      let data = sessionStorage.getItem("studentTableList");
+      if (data && data !== "") {
+        this.tableSet = JSON.parse(data);
+      }
+    }
     this.inittableSet = JSON.stringify(this.tableSet);
     this.initTR();
   },
@@ -2375,6 +2479,7 @@ export default {
     },
     //自定义列全选按钮触发
     handleCheckAllChange(val) {
+      console.log(val, "val");
       this.checkedCities = val ? this.cities : [];
       this.isIndeterminate = false;
       if (val) {
@@ -2411,6 +2516,9 @@ export default {
       this.tableSet = [];
       this.$nextTick(() => {
         this.tableSet = copyTable;
+        if (this.studentTable) {
+          sessionStorage.setItem("studentTableList", JSON.stringify(copyTable));
+        }
       });
     },
     //自定义列重置
@@ -2591,7 +2699,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);

+ 348 - 1
src/layout/components/Navbar.vue

@@ -86,6 +86,48 @@
         </el-dropdown-menu>
       </el-dropdown>
     </div>
+    <el-dialog
+      append-to-body
+      :visible.sync="dialog_haveRead"
+      width="440px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">{{ total }}条未读消息</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialog_haveRead = false"
+          />
+        </div>
+      </div>
+      <div class="haveRead_style">
+        <div
+          v-for="(item, index) in tableData"
+          :key="index"
+          class="haveRead_list"
+        >
+          <strong>{{ item.remind }}</strong>
+          <p>
+            {{ item.text }}
+          </p>
+          <p style="time_style">{{ $methodsTools.onlyForma(item.sendTime) }}</p>
+          <div>
+            <el-button type="primary" size="small" @click="newSee(item.id)"
+              >立即查看</el-button
+            >
+            <el-button size="small" @click="changeReadStatus(item.id)"
+              >标记为已读</el-button
+            >
+          </div>
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="seeAllRead">查看所有</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
@@ -116,6 +158,9 @@ export default {
   data() {
     return {
       dialogVisible: false,
+      dialog_haveRead: false,
+      tableData: [], //未读列表
+      total: 0, //未读数量
     };
   },
   computed: {
@@ -137,7 +182,183 @@ export default {
       },
     },
   },
+  mounted() {
+    if (this.$route.name !== "StationLetter") {
+      this.$api.inquireinformsys_userinformUnReadSum().then((res) => {
+        if (res.data > 0) {
+          this.getDontReadList();
+        }
+      });
+    }
+  },
   methods: {
+    /**
+     * 立即查看
+     */
+    newSee(id) {
+      this.$router.push({
+        name: "StationLetter",
+        params: {
+          id: id,
+        },
+      });
+      // this.dialog_haveRead = false;
+    },
+    /**
+     * 获取未读数据列表
+     */
+    getDontReadList() {
+      var self = this;
+      let val = {
+        receiptStatus: 0,
+        systemStatus: 1,
+      };
+      this.$api.inquireinformsys_userlist(val).then((result) => {
+        this.tableData = result.rows;
+        this.total = result.total;
+        if (this.total > 0) {
+          const h = this.$createElement;
+          let arrays = result.rows.map((item, index) => {
+            return h(
+              "div",
+              {
+                style: {
+                  borderBottom:
+                    result.total === index + 1 ? "none" : "1px solid #D9D9D9",
+                  marginTop: "26px",
+                  paddingBottom: "26px",
+                },
+              },
+              [
+                h(
+                  "strong",
+                  {
+                    style: {
+                      fontSize: "16px",
+                      fontWeight: "bold",
+                      color: "#222222",
+                      marginBottom: "12px",
+                    },
+                  },
+                  item.remind
+                ),
+                h(
+                  "p",
+                  {
+                    style: {
+                      fontSize: "14px",
+                      color: "#606266",
+                      marginBottom: "12px",
+                    },
+                  },
+                  item.text
+                ),
+                h(
+                  "p",
+                  {
+                    style: {
+                      fontSize: "12px",
+                      color: "#999999",
+                      marginBottom: "12px",
+                    },
+                  },
+                  this.$methodsTools.onlyForma(item.sendTime)
+                ),
+                h(
+                  "el-button",
+                  {
+                    attrs: {
+                      size: "small",
+                      type: "primary",
+                    },
+                    on: {
+                      click: function () {
+                        self.newSee(item.id);
+                        self.$notify.closeAll();
+                      },
+                    },
+                  },
+                  "立即查看"
+                ),
+                h(
+                  "el-button",
+                  {
+                    attrs: {
+                      size: "small",
+                    },
+                    on: {
+                      click: async function () {
+                        await self.changeReadStatus(item.id);
+                        self.$notify.closeAll();
+                        self.$nextTick(() => {
+                          self.getDontReadList();
+                        });
+                      },
+                    },
+                  },
+                  "标记为已读"
+                ),
+              ]
+            );
+          });
+          this.$notify({
+            title: `${result.total}条未读信息`,
+            position: "bottom-right",
+            dangerouslyUseHTMLString: true,
+            duration: 0,
+            customClass: "notiSty",
+            message: h("div", [
+              h(
+                "div",
+                {
+                  class: "znxStyle",
+                },
+                arrays
+              ),
+              h(
+                "div",
+                {
+                  class: "btn_bottom_style",
+                  on: {
+                    click: function () {
+                      self.seeAllRead();
+                      self.$notify.closeAll();
+                    },
+                  },
+                },
+                "查看所有"
+              ),
+            ]),
+          });
+          // this.dialog_haveRead = true;
+        } else {
+          // this.dialog_haveRead = false;
+        }
+      });
+    },
+    /**
+     * 更新已读状态
+     */
+    changeReadStatus(id) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .editupdateReadStatusBatch({ ids: [id], receiptStatus: 1 })
+          .then((res) => {
+            this.$message.success("已读成功");
+            resolve();
+            // this.getDontReadList();
+          });
+      });
+    },
+    /**
+     * 查看所有消息
+     */
+    seeAllRead() {
+      this.$router.push({
+        name: "StationLetter",
+      });
+      // this.dialog_haveRead = false;
+    },
     openMsg() {
       this.dialogVisible = true;
     },
@@ -155,13 +376,79 @@ export default {
             location.href = "/index";
           });
         })
-        .catch(() => {});
+        .catch(() => {
+          // var message: h("div", [
+          //       h("strong", null, item.text),
+          //       h("p", null, this.$methodsTools.onlyForma(item.sendTime)),
+          //       h(
+          //         "el-button",
+          //         {
+          //           attrs: {
+          //             size: "small",
+          //             type: "primary",
+          //           },
+          //           on: {
+          //             click: function () {
+          //               self.newSee(item.id);
+          //               self.$notify.closeAll();
+          //             },
+          //           },
+          //         },
+          //         "立即查看"
+          //       ),
+          //       h(
+          //         "el-button",
+          //         {
+          //           attrs: {
+          //             size: "small",
+          //           },
+          //           on: {
+          //             click: function () {
+          //               self.changeReadStatus(item.id);
+          //               instance[index].close();
+          //             },
+          //           },
+          //         },
+          //         "标记已读"
+          //       ),
+          //       h(
+          //         "el-button",
+          //         {
+          //           attrs: {
+          //             size: "small",
+          //             type: "success",
+          //           },
+          //           on: {
+          //             click: function () {
+          //               self.seeAllRead()
+          //               self.$notify.closeAll();
+          //             },
+          //           },
+          //         },
+          //         "查看全部"
+          //       ),
+          //     ]),
+        });
     },
   },
 };
 </script>
 
 <style lang="scss" scoped>
+.haveRead_list {
+  margin-top: 24px;
+  padding-bottom: 28px;
+  border-bottom: 1px solid #d9d9d9;
+  & > strong {
+    color: #000;
+  }
+  & > .time_style {
+    color: #999999;
+  }
+  &:last-child {
+    border-bottom: none;
+  }
+}
 /deep/.el-button {
   border-radius: 8px;
 }
@@ -349,4 +636,64 @@ export default {
     }
   }
 }
+.znxStyle {
+  max-height: 460px;
+  overflow-y: auto;
+  padding: 0px 28px;
+  &::-webkit-scrollbar {
+    width: 4px;
+  }
+  &::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    -webkit-box-shadow: inset 0 0 5px rgba(165, 165, 165, 0.2);
+    background: rgba(165, 165, 165, 0.2);
+  }
+  &::-webkit-scrollbar-track {
+    -webkit-box-shadow: inset 0 0 5px rgba(165, 165, 165, 0.2);
+    border-radius: 0;
+    background: rgba(226, 225, 225, 0.2);
+  }
+}
+.btn_bottom_style {
+  height: 50px;
+  border-top: 1px solid #d9d9d9;
+  line-height: 50px;
+  text-align: center;
+  color: #222;
+  font-size: 16px;
+  cursor: pointer;
+  transition: all 0.2s;
+  &:hover {
+    background-color: #eee;
+  }
+}
+.btnStyle_s {
+  margin-top: 6px;
+  background-color: skyblue;
+  color: #fff;
+}
+</style>
+<style lang="less">
+.notiSty {
+  width: 400px !important;
+  padding: 0px !important;
+  & > .el-notification__group {
+    margin: 0px;
+    & > .el-notification__title {
+      text-align: center;
+      height: 60px;
+      line-height: 60px;
+      color: #fff;
+      font-size: 18px;
+      font-weight: bold;
+      background-color: #409eff;
+      font-family: OPPOSans-Bold, OPPOSans;
+    }
+    & > .el-notification__closeBtn {
+      color: #fff;
+      font-size: 18px;
+      top: 24px;
+    }
+  }
+}
 </style>

+ 24 - 0
src/newApi/applicationData.js

@@ -145,5 +145,29 @@ export default {
             data
         })
     },
+    //导出学员信息表
+    inquiresystemsubscribelistUserExport(data) {
+        return request({
+            url: '/system/subscribe/listUserExport',
+            method: 'get',
+            params: data
+        })
+    },
+    //导出学员签到表
+    inquiresystemsubscribelistSignExport(data) {
+        return request({
+            url: '/system/subscribe/listSignExport',
+            method: 'get',
+            params: data
+        })
+    },
+    //导出疫情防控承诺书
+    inquiresystemsubscribelistLetterExport(data) {
+        return request({
+            url: '/system/subscribe/listLetterExport',
+            method: 'get',
+            params: data
+        })
+    },
     
 }

+ 60 - 0
src/newApi/appuser.js

@@ -63,4 +63,64 @@ export default {
             method: 'get',
         })
     },
+    //统计查询客户端用户列表
+    inquirestudystats_list(data) {
+        return request({
+            url: '/app/user/stats_list',
+            method: 'get',
+            params: data
+        })
+    },
+    //导出统计查询客户端用户列表
+    exportstudystats_list(data) {
+        return request({
+            url: '/app/user/stats_list_export',
+            method: 'get',
+            params: data
+        })
+    },
+    //同步智慧考场
+    appcommonsyncExamSite(data) {
+        return request({
+            url: '/app/common/syncExamSite',
+            method: 'get',
+            params: data,
+            headers: {
+              isToken: false
+            },
+        })
+    },
+    //同步考生考试状态信息
+    appcommonwisdomSyncExamStatus(data) {
+        return request({
+            url: '/app/common/wisdomSyncExamStatus',
+            method: 'get',
+            params: data,
+            headers: {
+              isToken: false
+            },
+        })
+    },
+    //同步考试视频信息
+    appcommonwisdomSyncExamVideo(data) {
+        return request({
+            url: '/app/common/wisdomSyncExamVideo',
+            method: 'get',
+            params: data,
+            headers: {
+              isToken: false
+            },
+        })
+    },
+    //批量同步考试计划用户
+    appcommonwsyncApplyUserInfo(data) {
+        return request({
+            url: '/app/common/syncApplyUserInfo',
+            method: 'get',
+            params: data,
+            headers: {
+              isToken: false
+            },
+        })
+    },
 }

+ 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/classTab.js

@@ -72,6 +72,14 @@ export default {
             params: data
         })
     },
+    //导出班级学员列表
+    inquireGradegradeexportGrade(data) {
+        return request({
+            url: '/grade/grade/exportListGrade',
+            method: 'get',
+            params: data
+        })
+    },
     //查询学员学时列表
     inquireGradegradelistUserPeriod(data) {
         return request({

+ 16 - 0
src/newApi/colleges.js

@@ -31,4 +31,20 @@ export default {
             method: 'get',
         })
     },
+    //查询用户视频学习日志列表
+    inquireUserStudyloglist(data) {
+        return request({
+            url: '/user/study/log/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //查询用户访问日志列表
+    inquireUserVisitloglist(data) {
+        return request({
+            url: '/user/visit/log/list',
+            method: 'get',
+            params: data
+        })
+    },
 }

+ 64 - 0
src/newApi/course.js

@@ -46,4 +46,68 @@ export default {
             method: 'get',
         })
     },
+    //查询商品双师资模板列表
+    inquireCourseTeacherList(data) {
+        return request({
+            url: `/goods/course/teacher/list`,
+            method: 'get',
+            params: data
+        })
+    },
+    //新增商品双师资模板
+    addCourseTeacherList(data) {
+        return request({
+            url: `/goods/course/teacher`,
+            method: 'post',
+            data
+        })
+    },
+    //修改商品双师资模板
+    editCourseTeacherList(data) {
+        return request({
+            url: `/goods/course/teacher/edit`,
+            method: 'post',
+            data
+        })
+    },
+    //课程统计报表
+    inquireCoursestatement(data) {
+        return request({
+            url: '/course/statement',
+            method: 'get',
+            params: data
+        })
+    },
+    //课程详情统计
+    inquireCoursedetailstatistics(data) {
+        return request({
+            url: '/course/detail/statistics',
+            method: 'get',
+            params: data
+        })
+    },
+    //学员观看记录
+    inquireCourseuserwatch(data) {
+        return request({
+            url: '/course/user/watch',
+            method: 'get',
+            params: data
+        })
+    },
+    //课程维度导出
+    inquireCoursestatementexport(data) {
+        return request({
+            url: '/course/statement/export',
+            method: 'get',
+            params: data
+        })
+    },
+    //课程学员详情导出
+    inquireCoursestatementstatisticsexport(data) {
+        return request({
+            url: '/course/detail/statistics/export',
+            method: 'get',
+            params: data
+        })
+    },
 }

+ 7 - 0
src/newApi/examapply.js

@@ -95,4 +95,11 @@ export default {
             params: data
         })
     },
+    //获取考试安排的前培计划详细信息
+    obtainsystemapplygetBefore(data) {
+        return request({
+            url: `/system/apply/getBefore/` + data,
+            method: 'get',
+        })
+    },
 }

+ 16 - 0
src/newApi/festival.js

@@ -63,4 +63,20 @@ export default {
             data
         })
     },
+    //保存课程小节观看权限
+    coursesectionaddwatchper(data) {
+        return request({
+            url: '/course/section/add/watch/per',
+            method: 'post',
+            data
+        })
+    },
+    //获取课程小节观看权限
+    coursesectionwatchper(data) {
+        return request({
+            url: '/course/section/watch/per',
+            method: 'get',
+            params: data
+        })
+    },
 }

+ 8 - 0
src/newApi/goods.js

@@ -127,4 +127,12 @@ export default {
             params: data
         })
     },
+    //商品专题页查询
+    inquirecoursetopiclist(data) {
+        return request({
+            url: '/course/topic/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
+        })
+    },
 }

+ 31 - 0
src/newApi/notificationFL.js

@@ -31,4 +31,35 @@ export default {
             method: 'get',
         })
     },
+    //查询通知绑定系统用户列表
+    inquireinformsys_userlist(data) {
+        return request({
+            url: '/inform/sys_user/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取通知绑定教务用户未读消息数量
+    inquireinformsys_userinformUnReadSum(data) {
+        return request({
+            url: '/inform/sys_user/informUnReadSum',
+            method: 'get',
+            params: data
+        })
+    },
+    //批量修改通知绑定系统用户状态
+    editupdateReadStatusBatch(data) {
+        return request({
+            url: '/inform/sys_user/updateReadStatusBatch',
+            method: 'post',
+            data
+        })
+    },
+    //获取通知绑定系统用户详细信息
+    informsys_user(data) {
+        return request({
+            url: `/inform/sys_user/` + data,
+            method: 'get',
+        })
+    },
 }

+ 8 - 0
src/newApi/studentList.js

@@ -88,6 +88,14 @@ export default {
             params: data
         })
     },
+    // 导出學員用户列表
+    inquiregradestudentlistStudentExport(data) {
+        return request({
+            url: '/grade/student/listStudentExport',
+            method: 'get',
+            params: data
+        })
+    },
     
 
 }

+ 55 - 0
src/newApi/systemExam.js

@@ -0,0 +1,55 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增新增活动
+    addSystemexamactivity(data) {
+        return request({
+            url: '/system/exam/activity/add',
+            method: 'post',
+            data
+        })
+    },
+    //修改活动
+    editSystemexamactivity(data) {
+        return request({
+            url: '/system/exam/activity/update',
+            method: 'post',
+            data
+        })
+    },
+    //获取活动列表
+    inquireSystemexamactivitylist(data) {
+        return request({
+            url: '/system/exam/activity/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取活动信息
+    inquireSystemexamactivitydetail(data) {
+        return request({
+            url: '/system/exam/activity/detail/' + data,
+            method: 'get',
+        })
+    },
+    //获取活动用户列表
+    inquireSystemexamactivityuserlist(data) {
+        return request({
+            url: '/system/exam/activity/user/list/' + data,
+            method: 'get',
+        })
+    },
+    //导出活动用户
+    exportsystemexamactivity(data) {
+        return request({
+            url: '/system/exam/activity/export/' + data,
+            method: 'get',
+        })
+    },
+    //获取活动报名二维码
+    exportsystemexamactivitycode(data) {
+        return request({
+            url: '/system/exam/activity/apply/code/' + data,
+            method: 'get',
+        })
+    },
+}

+ 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),

+ 1 - 1
src/store/modules/tagsView.js

@@ -2,7 +2,7 @@ import { MessageBox } from 'element-ui';
 const state = {
   visitedViews: [],
   cachedViews: [],
-  alertPage: ["CommodityManageMentAdd", "CommodityManageMentEdit", "FestivalAdd", "FestivalEdit", "ChapterAdd", "ChapterEdit", "ModuleManagementAdd", "ModuleManagementEdit", "BasicInfoEdit", "BasicInfoAdd", "ChapterContent", "EditCourse", "OrderDetail", "OrderPrice", "AddOrder", "EditPaper", "AddPaper", "TopicAddPaper", "ChapterVolumeManagementEdit", "ChapterVolumeManagementAdd", "VolumeManagementAdd", "VolumeManagementEdit", "HandoutListEdit", "HandoutListAdd", "StudentXQ", "AddClass", "ManageClass", "NotificationInfo", "NotificationListAdd", "NotificationEdit", "BulkImportPlan", "MatchInfoData", "BatchRecord", "OrderChargeInfo", "RefundDocument", "BillingBillCharges", "AddMockExam", "EditMockExam","RecordQusetion"],
+  alertPage: ["CommodityManageMentAdd", "CommodityManageMentEdit", "FestivalAdd", "FestivalEdit", "ChapterAdd", "ChapterEdit", "ModuleManagementAdd", "ModuleManagementEdit", "BasicInfoEdit", "BasicInfoAdd", "ChapterContent", "EditCourse", "OrderDetail", "OrderPrice", "AddOrder", "EditPaper", "AddPaper", "TopicAddPaper", "ChapterVolumeManagementEdit", "ChapterVolumeManagementAdd", "VolumeManagementAdd", "VolumeManagementEdit", "HandoutListEdit", "HandoutListAdd", "StudentXQ", "AddClass", "ManageClass", "NotificationInfo", "NotificationListAdd", "NotificationEdit", "BulkImportPlan", "MatchInfoData", "BatchRecord", "OrderChargeInfo", "RefundDocument", "BillingBillCharges", "AddMockExam", "EditMockExam","RecordQusetion","CommoditySetTeacher"],
 }
 
 const mutations = {

+ 1 - 1
src/store/modules/user.js

@@ -31,7 +31,7 @@ const user = {
     },
     SET_USERID: (state, userId) => {
       state.userId = userId
-    }
+    },
   },
 
   actions: {

+ 1 - 1
src/utils/request.js

@@ -8,7 +8,7 @@ import methods from '@/utils/methodsTool';
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 // 创建axios实例
 export const baseURL = process.env.VUE_APP_BASE_API
-// export const baseURL = 'http://192.168.1.24:5030/'
+// export const baseURL = 'http://192.168.1.7:5030/'
 export const BASE_IMG_URL = process.env.VUE_APP_IMG_API
 const service = axios.create({
   // axios中请求配置有baseURL选项,表示请求URL公共部分

+ 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>

+ 81 - 6
src/views/2Cport/referralManageMent/tab1/addGL.vue

@@ -62,9 +62,49 @@
               </el-option>
             </el-select>
           </el-form-item>
+          <el-form-item
+          label=""
+          prop="majorId"
+          v-if="listData.businessId"
+        >
+          <el-select 
+            v-model="listData.majorId"
+            :disabled="listData.goodsList.length > 0"
+            placeholder="请选择专业">
+            <el-option
+              v-for="(item, index) in newMajorOption"
+              :key="index"
+              :label="item.categoryName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label=""
+          prop="subjectIds"
+          v-if="listData.businessId"
+        >
+          <el-select
+            v-model="listData.subjectIds"
+            :disabled="listData.goodsList.length > 0"
+            placeholder="请选择科目"
+            multiple
+            collapse-tags
+          @change="subjectChanges"
+          >
+            <el-option
+              v-for="(item, index) in newSubjectOption"
+              :key="index"
+              :label="item.subjectName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
           <div v-if="listData.businessId" style="margin-bottom: 10px">
             <p class="p_sty">
-              <span style="color: red">注:推荐位最多显示15个商品</span>
+              <!-- <span style="color: red">注:推荐位最多显示15个商品</span> -->
               <el-button :size="size" @click="addList">添加</el-button>
             </p>
             <el-table
@@ -198,6 +238,8 @@ export default {
       disabledBtn: false,
       listData: {
         businessId: "",
+        majorId:"",
+        subjectIds:"",
         goodsList: [],
       },
       rules: {
@@ -244,6 +286,8 @@ export default {
         },
       ],
       newBusinessLevel: [],
+      newMajorOption: [],
+      newSubjectOption: [],
       activeNum: [], //已选商品ID
       newActiveNum: [],
       goodsList: [], //商品列表
@@ -261,6 +305,7 @@ export default {
             break;
           }
         }
+        this.getInitBabelList(val);
       }
     },
   },
@@ -295,6 +340,32 @@ export default {
         .then((res) => {
           this.newBusinessLevel = res.rows;
         });
+    },
+     /**
+     * 根据条件获取院校、专业列表
+     */
+    getInitBabelList(val) {
+      /**
+       * 专业
+       */
+      this.$api
+        .inquireCourseMajor({ status: 1, businessId: val })
+        .then((res) => {
+          this.newMajorOption = res.rows;
+        });
+      /**
+       * 科目
+       */
+      this.$api
+        .inquireCourseSubject({ status: 1, businessId: val })
+        .then((res) => {
+          this.newSubjectOption = res.rows;
+        });
+    },
+    subjectChanges() {
+      console.log(123)
+      this.$bus.$emit("sendBybus");
+      this.$bus.$emit("sendBybusBank");
     },
     loadingClose() {
       this.disabledBtn = false;
@@ -322,10 +393,10 @@ export default {
     },
     submit() {
       if (this.listData.goodsList.length) {
-        if (this.listData.goodsList.length > 16) {
-          this.$message.warning("推荐位最多显示15个商品");
-          return;
-        }
+        // if (this.listData.goodsList.length > 16) {
+        //   this.$message.warning("推荐位最多显示15个商品");
+        //   return;
+        // }
         var indexNum = this.listData.goodsList.map((item) => {
           return item.sort;
         });
@@ -341,6 +412,7 @@ export default {
         data.type = this.$parent.activeName === "first" ? 1 : 2;
         this.$api
           .appactivityrecommend(data)
+
           .then((res) => {
             this.$message.success("新增成功");
             this.$parent.search();
@@ -380,9 +452,12 @@ export default {
       });
       this.$api
         .inquireGoods({
+          educationTypeId: this.listData.educationTypeId,
           businessId: this.listData.businessId,
+          majorId: this.listData.majorId,
+          subjectIdList: this.listData.subjectIds,
           status: 1,
-          goodsType: this.$parent.activeName === "first" ? 1 : 2,
+          goodsTypes: this.$parent.activeName === "first" ? [1,6] : [2],
         })
         .then((res) => {
           this.goodsList = res.rows;

+ 81 - 6
src/views/2Cport/referralManageMent/tab2/addGL.vue

@@ -62,9 +62,49 @@
               </el-option>
             </el-select>
           </el-form-item>
+                    <el-form-item
+          label=""
+          prop="majorId"
+          v-if="listData.businessId"
+        >
+          <el-select 
+            v-model="listData.majorId"
+            :disabled="listData.goodsList.length > 0"
+            placeholder="请选择专业">
+            <el-option
+              v-for="(item, index) in newMajorOption"
+              :key="index"
+              :label="item.categoryName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          label=""
+          prop="subjectIds"
+          v-if="listData.businessId"
+        >
+          <el-select
+            v-model="listData.subjectIds"
+            :disabled="listData.goodsList.length > 0"
+            placeholder="请选择科目"
+            multiple
+            collapse-tags
+          @change="subjectChanges"
+          >
+            <el-option
+              v-for="(item, index) in newSubjectOption"
+              :key="index"
+              :label="item.subjectName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
           <div v-if="listData.businessId" style="margin-bottom: 10px">
             <p class="p_sty">
-              <span style="color: red">注:推荐位最多显示15个商品</span>
+              <!-- <span style="color: red">注:推荐位最多显示15个商品</span> -->
               <el-button :size="size" @click="addList">添加</el-button>
             </p>
             <el-table
@@ -198,6 +238,8 @@ export default {
       disabledBtn: false,
       listData: {
         businessId: "",
+        majorId:"",
+        subjectIds:"",
         goodsList: [],
       },
       rules: {
@@ -244,6 +286,8 @@ export default {
         },
       ],
       newBusinessLevel: [],
+      newMajorOption: [],
+      newSubjectOption: [],
       activeNum: [], //已选商品ID
       newActiveNum: [],
       goodsList: [], //商品列表
@@ -261,6 +305,7 @@ export default {
             break;
           }
         }
+        this.getInitBabelList(val);
       }
     },
   },
@@ -298,6 +343,27 @@ export default {
     },
     loadingClose() {
       this.disabledBtn = false;
+    },
+      /**
+     * 根据条件获取院校、专业列表
+     */
+    getInitBabelList(val) {
+      /**
+       * 专业
+       */
+      this.$api
+        .inquireCourseMajor({ status: 1, businessId: val })
+        .then((res) => {
+          this.newMajorOption = res.rows;
+        });
+      /**
+       * 科目
+       */
+      this.$api
+        .inquireCourseSubject({ status: 1, businessId: val })
+        .then((res) => {
+          this.newSubjectOption = res.rows;
+        });
     },
     submitForm(formName) {
       this.$refs[formName].validate((valid) => {
@@ -320,12 +386,17 @@ export default {
       }
       return true;
     },
+    subjectChanges() {
+      console.log(123)
+      this.$bus.$emit("sendBybus");
+      this.$bus.$emit("sendBybusBank");
+    },
     submit() {
       if (this.listData.goodsList.length) {
-        if (this.listData.goodsList.length > 15) {
-          this.$message.warning("推荐位最多显示15个商品");
-          return;
-        }
+        // if (this.listData.goodsList.length > 15) {
+        //   this.$message.warning("推荐位最多显示15个商品");
+        //   return;
+        // }
         var indexNum = this.listData.goodsList.map((item) => {
           return item.sort;
         });
@@ -352,6 +423,7 @@ export default {
       }
       if (this.statusPop === 0) {
         let data = JSON.parse(JSON.stringify(this.listData));
+        console.log(this.listData,'this.listData');
         this.$api
           .editactivityrecommend(data)
           .then((res) => {
@@ -380,9 +452,12 @@ export default {
       });
       this.$api
         .inquireGoods({
+          educationTypeId: this.listData.educationTypeId,
           businessId: this.listData.businessId,
+          majorId: this.listData.majorId,
+          subjectIdList: this.listData.subjectIds,
           status: 1,
-          goodsType: this.$parent.activeName === "first" ? 1 : 2,
+          goodsTypes: this.$parent.activeName === "first" ? [1,6]: [2],
         })
         .then((res) => {
           this.goodsList = res.rows;

+ 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)
     },
     /**
      * 试听回调数据

+ 7 - 0
src/views/Marketing/goods/commodityManageMent/add/pricePeriod.vue

@@ -16,6 +16,13 @@
             ></el-input
           >
         </el-form-item>
+        <el-form-item label="商品划线价(元)" prop="linePrice">
+          <el-input
+            :style="`max-width:${inputWidth}px;`"
+            v-model="listData.linePrice"
+            ></el-input
+          >
+        </el-form-item>
         <el-form-item label="状态" prop="status">
           <el-radio-group v-model="listData.status">
             <el-radio :label="1">有效</el-radio>

+ 432 - 0
src/views/Marketing/goods/commodityManageMent/edit/courseContent/index copy.vue

@@ -0,0 +1,432 @@
+<template>
+  <div id="courseContent">
+    <div style="margin-bottom: 20px">
+      <el-button
+        v-if="!submitStatusInfo"
+        @click="addCourse"
+        size="small"
+        :disabled="tableData.length > 0 && tableData[0].type > 0"
+        >添加课程</el-button
+      >
+      <el-button
+        v-if="!submitStatusInfo"
+        @click="addMoreList"
+        size="small"
+        :disabled="
+          tableData.length > 0 && tableData[0].courseName ? true : false
+        "
+        >添加模块/章/节</el-button
+      >
+      <el-button
+        @click="openAudition"
+        type="success"
+        size="small"
+        v-if="tableData.length > 0"
+        >试听设置</el-button
+      >
+      <el-button type="primary" @click="openPlayPhotoSet" size="small"
+        >播放和拍照设置</el-button
+      >
+      <el-button type="primary" @click="openStyleNumSet" size="small"
+        >每天学习限制</el-button
+      >
+      <el-button type="primary" @click="openHandoutSet" size="small"
+        >关联讲义</el-button
+      >
+    </div>
+    <el-table
+      :data="tableData"
+      border
+      :header-cell-style="{
+        'background-color': '#eee',
+        padding: '8px',
+        color: '#333',
+      }"
+      :default-sort="{ prop: 'sort', order: 'ascending' }"
+    >
+      <el-table-column
+        v-for="(item, index) in compayTypes(tableSetVideo)"
+        :width="item.width"
+        :key="index"
+        :label="item.label"
+        align="center"
+        :show-overflow-tooltip="true"
+        header-align="center"
+        :sortable="item.prop === 'sort'"
+        sort-by="sort"
+        :prop="item.prop"
+      >
+        <template slot-scope="scope">
+          <span v-if="item.scope === 'types'">{{
+            scope.row[item.prop] === 1
+              ? "录播"
+              : scope.row[item.prop] === 2
+              ? "直播"
+              : scope.row[item.prop] === 3
+              ? "回放"
+              : "未知"
+          }}</span>
+          <span v-else-if="item.scope === 'type'">{{
+            scope.row[item.prop] === 1
+              ? "模块"
+              : scope.row[item.prop] === 2
+              ? "章"
+              : scope.row[item.prop] === 3
+              ? "节"
+              : "未知"
+          }}</span>
+          <span v-else-if="item.scope === 'busin'">
+            {{ scope.row[item.prop1] + " - " + scope.row[item.prop2] }}
+          </span>
+          <span v-else-if="item.scope === 'Status'">
+            {{
+              scope.row[item.prop] === 1
+                ? "发布"
+                : scope.row[item.prop] === 0
+                ? "未发布"
+                : "未知"
+            }}
+          </span>
+          <div v-else-if="item.scope === 'inputs'">
+            <el-input-number
+              style="width: 50px"
+              size="small"
+              :controls="false"
+              v-model="scope.row[item.prop]"
+              controls-position="right"
+              :min="0"
+            ></el-input-number>
+          </div>
+          <span v-else>{{ scope.row[item.prop] }}</span></template
+        >
+      </el-table-column>
+      <el-table-column
+        label="操作"
+        align="center"
+        fixed="right"
+        width="100px"
+        v-if="!submitStatusInfo"
+      >
+        <template slot-scope="scope">
+          <el-button type="text" @click="delCourse(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <popple-set
+      :key="Math.random()"
+      ref="poppleSet"
+      @uploadArrays="uploadArrays"
+    />
+    <course-check ref="courseCheck" @backData="backVideoData" />
+    <more-list-check
+      ref="moreListCheck"
+      @backData="backMoreListData"
+      :bfCourseId="bfCourseId"
+    />
+    <play-photo ref="playPhoto" @backData="backPlayPhotoData" />
+    <every-day-study-num ref="everyDayStudyNum" @backData="backEveryDaySet" />
+    <handout-view ref="handoutView" @backData="backHandoutView" />
+  </div>
+</template>
+
+<script>
+import poppleSet from "../../poppleSet.vue";
+import courseCheck from "./courseCheck.vue";
+import moreListCheck from "./moreListCheck.vue";
+import playPhoto from "./playPhoto.vue";
+import everyDayStudyNum from "./everyDayStudyNum.vue";
+import handoutView from "./handoutView.vue";
+
+export default {
+  components: {
+    poppleSet,
+    courseCheck,
+    moreListCheck,
+    playPhoto,
+    everyDayStudyNum,
+    handoutView,
+  },
+  props: ["listData", "submitStatusInfo"],
+  data() {
+    return {
+      tableSetVideo: [
+        { label: "排序", prop: "sort", scope: "inputs", width: "100" },
+        { label: "编码", prop: "code", width: "140" },
+        { label: "课程名称", prop: "courseName", width: "300", type: 1 },
+        { label: "类型", prop: "type", width: "190", type: 2, scope: "type" },
+        { label: "名称", prop: "menuName", width: "300", type: 2 },
+        { label: "科目", prop: "subjectName", width: "150", type: 1 },
+        { label: "专业", prop: "categoryName", type: 1 },
+        { label: "院校", prop: "schoolName", width: "150", type: 1 },
+        // {
+        //   label: "业务层次",
+        //   prop1: "projectName",
+        //   prop2: "businessName",
+        //   scope: "busin",
+        //   width: "350px",
+        //   type: 1,
+        // },
+        // { label: "教育类型", prop: "educationName", width: "160", type: 1 },
+        {
+          label: "发布状态",
+          prop: "publishStatus",
+          scope: "Status",
+        },
+      ],
+      tableData: [],
+      auditionList: [], //试听数据
+      bfCourseId: 0,
+    };
+  },
+  watch: {
+    tableData(val) {
+      if (val.length === 0) {
+        this.auditionList = [];
+      }
+    },
+  },
+  computed: {
+    compayTypes: function () {
+      return function (array) {
+        let ary = [];
+        ary = array.filter((item) => {
+          if (this.tableData.length > 0) {
+            if (this.tableData[0].type) {
+              return item.type !== 1;
+            } else {
+              return item.type !== 2;
+            }
+          } else {
+            return item;
+          }
+        });
+        return ary;
+      };
+    },
+  },
+  mounted() {
+    this.$bus.$on("sendBybus", () => {
+      this.tableData = [];
+    });
+  },
+  methods: {
+    /**
+     * 获取初始课程列表
+     */
+    getBybusCoursetableData(id) {
+      this.$api.obtainCourseSgoodsId(id).then((res) => {
+        if (res.rows.length === 1 && res.rows[0].courseShow === 0) {
+          this.bfCourseId = res.rows[0].courseId;
+          this.getMoreList(res.rows[0].courseId);
+          this.auditionList.forEach((item) => {
+            item.courseId = res.rows[0].courseId;
+          });
+          return;
+        }
+        this.tableData = res.rows;
+      });
+    },
+    /**
+     * 获取商品模块/章/节列表
+     */
+    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;
+      });
+    },
+    /**
+     * 获取初始课程试听列表
+     */
+    getBybusCourseAudition(audition) {
+      this.auditionList = audition;
+      console.log(audition);
+    },
+    /**
+     * 点击添加函数
+     */
+    addCourse() {
+      //搜索条件
+      var data = {
+        businessId: this.listData.businessId,
+        subjectIds: this.listData.subjectIds.toString(),
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+        publishStatus: 1,
+      };
+      //已选课程
+      var aList = this.tableData.map((item) => {
+        return item.courseId;
+      });
+      //打开选择课程组件
+      this.$refs.courseCheck.openBox(
+        data,
+        aList,
+        this.listData.educationTypeId
+      );
+    },
+    /**
+     * 选择课程回调数据
+     */
+    backVideoData(array) {
+      let copyData = JSON.parse(JSON.stringify(array));
+      if (this.tableData.length) {
+        let maxIndex = 0;
+        this.tableData.forEach((item) => {
+          if (item.sort > maxIndex) {
+            maxIndex = item.sort;
+          }
+        });
+        copyData.forEach((item, index) => {
+          item.sort = maxIndex + index + 1;
+        });
+      } else {
+        copyData.forEach((item, index) => {
+          item.sort = index + 1;
+        });
+      }
+      this.tableData = this.tableData.concat(copyData);
+    },
+    /**
+     * 删除课程
+     */
+    delCourse(item) {
+      if (this.tableData[0].type) {
+        const FINDINDEX = this.tableData.findIndex((items) => {
+          return items.type === item.type && item.menuId === item.menuId;
+        });
+        this.tableData.splice(FINDINDEX, 1);
+        this.auditionList = this.auditionList.filter((items) => {
+          return items.TypeId !== item.TypeId;
+        });
+        this.$message.success("删除成功");
+      } else {
+        const FINDINDEX = this.tableData.findIndex((items) => {
+          return items.courseId === item.courseId;
+        });
+        this.tableData.splice(FINDINDEX, 1);
+        this.auditionList = this.auditionList.filter((items) => {
+          return items.courseId !== item.courseId;
+        });
+        this.$message.success("删除成功");
+      }
+    },
+    /**
+     * 点击添加函数
+     */
+    addMoreList() {
+      //搜索条件
+      var data = {
+        businessId: this.listData.businessId,
+        subjectIds: this.listData.subjectIds.toString(),
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+        publishStatus: 1,
+      };
+      //已选模块/章/节
+      var aList = this.tableData.map((item) => {
+        return `${item.type}-${item.menuId}`;
+      });
+      //打开选择模块/章/节组件
+      this.$refs.moreListCheck.openBox(
+        data,
+        aList,
+        this.listData.educationTypeId
+      );
+    },
+    /**
+     * 选择模块/章/节回调数据
+     */
+    backMoreListData(array) {
+      let copyData = JSON.parse(JSON.stringify(array));
+      if (this.tableData.length) {
+        let maxIndex = 0;
+        this.tableData.forEach((item) => {
+          if (item.sort > maxIndex) {
+            maxIndex = item.sort;
+          }
+        });
+        copyData.forEach((item, index) => {
+          item.sort = maxIndex + index + 1;
+        });
+      } else {
+        copyData.forEach((item, index) => {
+          item.sort = index + 1;
+        });
+      }
+      this.tableData = this.tableData.concat(copyData);
+    },
+    /**
+     * 点击试听函数
+     */
+    openAudition() {
+      console.log(this.tableData, this.auditionList);
+      this.$refs.poppleSet.openExpand(this.tableData, this.auditionList);
+    },
+    /**
+     * 试听回调数据
+     */
+    uploadArrays(arrays) {
+      this.auditionList = arrays;
+    },
+    /**
+     * 点击播放和拍照设置函数
+     */
+    openPlayPhotoSet() {
+      this.$refs.playPhoto.openBox(this.listData);
+    },
+    /**
+     * 播放和拍照设置回调数据
+     */
+    backPlayPhotoData(obj) {
+      this.$set(this.listData, "playConfig", obj.playConfig);
+      this.$set(this.listData, "photographConfig", obj.photographConfig);
+      this.$set(
+        this.listData,
+        "goodsPhotographExamConfig",
+        obj.goodsPhotographExamConfig
+      );
+    },
+    /**
+     * 点击学习限制函数
+     */
+    openStyleNumSet() {
+      this.$refs.everyDayStudyNum.openBox(this.listData.sectionMaxNum);
+    },
+    /**
+     * 学习限制回调数据
+     */
+    backEveryDaySet(num) {
+      this.$set(this.listData, "sectionMaxNum", num);
+    },
+    /**
+     * 点击选择讲义函数
+     */
+    openHandoutSet() {
+      if (!this.listData.businessId) {
+        this.$message.warning("请选择业务层次");
+        return;
+      }
+      console.log(this.listData);
+      this.$refs.handoutView.openBox(this.listData.handoutsId);
+    },
+    /**
+     * 讲义回调数据
+     */
+    backHandoutView(id) {
+      this.$set(this.listData, "handoutsId", id);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 170 - 20
src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue

@@ -43,13 +43,17 @@
         color: '#333',
       }"
       :default-sort="{ prop: 'sort', order: 'ascending' }"
+      lazy
+      :load="load"
+      row-key="keyId"
+      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
     >
       <el-table-column
         v-for="(item, index) in compayTypes(tableSetVideo)"
         :width="item.width"
         :key="index"
         :label="item.label"
-        align="center"
+        :align="item.scope === 'typeNames' ? 'left' : 'center'"
         :show-overflow-tooltip="true"
         header-align="center"
         :sortable="item.prop === 'sort'"
@@ -73,6 +77,8 @@
               ? "章"
               : scope.row[item.prop] === 3
               ? "节"
+              : scope.row[item.prop] === 0
+              ? "课程"
               : "未知"
           }}</span>
           <span v-else-if="item.scope === 'busin'">
@@ -87,16 +93,35 @@
                 : "未知"
             }}
           </span>
-          <div v-else-if="item.scope === 'inputs'">
-            <el-input-number
-              style="width: 50px"
-              size="small"
-              :controls="false"
-              v-model="scope.row[item.prop]"
-              controls-position="right"
-              :min="0"
-            ></el-input-number>
-          </div>
+          <span v-else-if="item.scope === 'typeNames'">
+            <span
+              v-if="scope.row['sectionType']"
+              style="color: green; margin-right: 10px"
+              >{{
+                scope.row["sectionType"] === 1
+                  ? "[录播]"
+                  : scope.row["sectionType"] === 2
+                  ? "[直播]"
+                  : scope.row["sectionType"] === 3
+                  ? "[回放]"
+                  : ""
+              }}</span
+            >
+
+            {{ scope.row[item.prop] }}
+          </span>
+          <span v-else-if="item.scope === 'inputs'">
+            <span v-if="item.scope === 'inputs' && scope.row['index']">
+              <el-input-number
+                style="width: 50px"
+                size="small"
+                :controls="false"
+                v-model="scope.row[item.prop]"
+                controls-position="right"
+                :min="0"
+              ></el-input-number>
+            </span>
+          </span>
           <span v-else>{{ scope.row[item.prop] }}</span></template
         >
       </el-table-column>
@@ -108,15 +133,24 @@
         v-if="!submitStatusInfo"
       >
         <template slot-scope="scope">
-          <el-button type="text" @click="delCourse(scope.row)">删除</el-button>
+          <el-button
+            type="text"
+            @click="delCourse(scope.row)"
+            v-if="scope.row.index"
+            >删除</el-button
+          >
+          <el-button
+            type="text"
+            v-if="scope.row.type === 3 && scope.row.sectionType !== 1"
+            @click="openShare(scope.row)"
+            >分享</el-button
+          >
         </template>
       </el-table-column>
     </el-table>
     <popple-set
       :key="Math.random()"
       ref="poppleSet"
-      :tableData="tableData"
-      :auditionList="auditionList"
       @uploadArrays="uploadArrays"
     />
     <course-check ref="courseCheck" @backData="backVideoData" />
@@ -126,6 +160,7 @@
       :bfCourseId="bfCourseId"
     />
     <play-photo ref="playPhoto" @backData="backPlayPhotoData" />
+    <share ref="share" />
     <every-day-study-num ref="everyDayStudyNum" @backData="backEveryDaySet" />
     <handout-view ref="handoutView" @backData="backHandoutView" />
   </div>
@@ -136,6 +171,7 @@ import poppleSet from "../../poppleSet.vue";
 import courseCheck from "./courseCheck.vue";
 import moreListCheck from "./moreListCheck.vue";
 import playPhoto from "./playPhoto.vue";
+import share from "./share.vue";
 import everyDayStudyNum from "./everyDayStudyNum.vue";
 import handoutView from "./handoutView.vue";
 
@@ -145,6 +181,7 @@ export default {
     courseCheck,
     moreListCheck,
     playPhoto,
+    share,
     everyDayStudyNum,
     handoutView,
   },
@@ -154,9 +191,15 @@ export default {
       tableSetVideo: [
         { label: "排序", prop: "sort", scope: "inputs", width: "100" },
         { label: "编码", prop: "code", width: "140" },
-        { label: "课程名称", prop: "courseName", width: "300", type: 1 },
-        { label: "类型", prop: "type", width: "190", type: 2, scope: "type" },
-        { label: "名称", prop: "menuName", width: "300", type: 2 },
+        // { label: "课程名称", prop: "courseName", width: "300", type: 1 },
+        {
+          label: "名称",
+          prop: "menuName",
+          width: "300",
+          scope: "typeNames",
+        },
+        { label: "类型", prop: "type", width: "190", scope: "type" },
+        // { label: "名称", prop: "menuName", width: "300", type: 2 },
         { label: "科目", prop: "subjectName", width: "150", type: 1 },
         { label: "专业", prop: "categoryName", type: 1 },
         { label: "院校", prop: "schoolName", width: "150", type: 1 },
@@ -178,6 +221,7 @@ export default {
       tableData: [],
       auditionList: [], //试听数据
       bfCourseId: 0,
+      dialogVisible: false, //分享窗口
     };
   },
   watch: {
@@ -212,6 +256,71 @@ export default {
     });
   },
   methods: {
+    /**
+     * 打开分享窗口
+     */
+    openShare(rows) {
+      let goodsId = this.$route.query.id;
+      this.$refs.share.openBox(rows, goodsId);
+      // this.$api.coursesectionwatchper().then((res) => {});
+    },
+    /**
+     * 异步加载table数据
+     */
+    load(tree, treeNode, resolve) {
+      console.log(tree, "tree");
+      if (tree.type === 0) {
+        this.$api
+          .inquireCoursemenuListS({ courseId: tree.courseId })
+          .then((res) => {
+            res.rows.forEach((item) => {
+              if (item.type === 1) {
+                item.moduleId = item.menuId;
+                item.keyId = `${tree.courseId}-${item.menuId}`;
+              }
+              if (item.type === 2) {
+                item.chapterId = item.menuId;
+                item.keyId = `${tree.courseId}-0-${item.menuId}`;
+              }
+              if (item.type === 3) {
+                item.sectionId = item.menuId;
+                item.keyId = `${tree.courseId}-0-0-${item.menuId}`;
+              }
+              item.children = [];
+              item.courseId = tree.courseId;
+              item.hasChildren = item.type === 3 ? false : true;
+            });
+            return resolve(res.rows);
+          });
+      } else if (tree.type === 1) {
+        this.$api.inquireCourseListmodulechapter(tree.menuId).then((res) => {
+          res.data.forEach((item) => {
+            item.keyId = `${tree.courseId}-${tree.menuId}-${item.chapterId}`;
+            item.children = [];
+            item.type = 2;
+            item.menuName = item.name;
+            item.courseId = tree.courseId;
+            item.hasChildren = item.type === 3 ? false : true;
+          });
+          return resolve(res.data);
+        });
+      } else if (tree.type === 2) {
+        this.$api
+          .inquireCoursechaptersectionlist(tree.chapterId)
+          .then((res) => {
+            res.data.forEach((item) => {
+              item.keyId = `${tree.courseId}-${tree.moduleId}-${tree.chapterId}-${item.sectionId}`;
+              item.children = [];
+              item.type = 3;
+              item.menuName = item.name;
+              item.hasChildren = false;
+            });
+            return resolve(res.data);
+          });
+      } else {
+        return resolve([]);
+      }
+    },
     /**
      * 获取初始课程列表
      */
@@ -225,6 +334,14 @@ export default {
           });
           return;
         }
+        res.rows.forEach((item, index) => {
+          item.keyId = item.courseId + "";
+          item.children = [];
+          item.hasChildren = true;
+          item.type = 0;
+          item.menuName = item.courseName;
+          item.index = true;
+        });
         this.tableData = res.rows;
       });
     },
@@ -234,7 +351,20 @@ export default {
     getMoreList(id) {
       this.$api.inquireCoursemenuListS({ courseId: id }).then((res) => {
         res.rows.forEach((item) => {
+          item.auditionMinute = this.$methodsTools.secondToDate(
+            item.durationTime,
+            false
+          );
+          item.children = [];
+          item.hasChildren = item.type === 1 || item.type === 2 ? true : false;
           item.name = item.menuName;
+          item.index = true;
+          item.keyId = `${id}-${item.type === 1 ? item.menuId : 0}-${
+            item.type === 2 ? item.menuId : 0
+          }-${item.type === 3 ? item.menuId : 0}`;
+          item.moduleId = item.type === 1 ? item.menuId : 0;
+          item.chapterId = item.type === 2 ? item.menuId : 0;
+          item.sectionId = item.type === 3 ? item.menuId : 0;
         });
         this.tableData = res.rows;
       });
@@ -244,7 +374,6 @@ export default {
      */
     getBybusCourseAudition(audition) {
       this.auditionList = audition;
-      console.log(audition);
     },
     /**
      * 点击添加函数
@@ -275,6 +404,14 @@ export default {
      */
     backVideoData(array) {
       let copyData = JSON.parse(JSON.stringify(array));
+      copyData.forEach((item) => {
+        item.keyId = item.courseId + "";
+        item.children = [];
+        item.hasChildren = true;
+        item.type = 0;
+        item.menuName = item.courseName;
+        item.index = true;
+      });
       if (this.tableData.length) {
         let maxIndex = 0;
         this.tableData.forEach((item) => {
@@ -298,7 +435,7 @@ export default {
     delCourse(item) {
       if (this.tableData[0].type) {
         const FINDINDEX = this.tableData.findIndex((items) => {
-          return items.type === item.type && item.menuId === item.menuId;
+          return items.type === item.type && items.menuId === item.menuId;
         });
         this.tableData.splice(FINDINDEX, 1);
         this.auditionList = this.auditionList.filter((items) => {
@@ -345,6 +482,18 @@ export default {
      */
     backMoreListData(array) {
       let copyData = JSON.parse(JSON.stringify(array));
+      copyData.forEach((item) => {
+        item.keyId = `${this.bfCourseId}-${item.type === 1 ? item.menuId : 0}-${
+          item.type === 2 ? item.menuId : 0
+        }-${item.type === 3 ? item.menuId : 0}`;
+        (item.courseId = this.bfCourseId),
+          (item.moduleId = item.type === 1 ? item.menuId : 0);
+        item.chapterId = item.type === 2 ? item.menuId : 0;
+        item.sectionId = item.type === 3 ? item.menuId : 0;
+        item.children = [];
+        item.hasChildren = item.type === 3 ? false : true;
+        item.index = true;
+      });
       if (this.tableData.length) {
         let maxIndex = 0;
         this.tableData.forEach((item) => {
@@ -366,7 +515,8 @@ export default {
      * 点击试听函数
      */
     openAudition() {
-      this.$refs.poppleSet.dialogVisible = true;
+      console.log(this.tableData, this.auditionList);
+      this.$refs.poppleSet.openExpand(this.tableData, this.auditionList);
     },
     /**
      * 试听回调数据

+ 181 - 0
src/views/Marketing/goods/commodityManageMent/edit/courseContent/share.vue

@@ -0,0 +1,181 @@
+<template>
+  <div id="share">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="520px"
+      :show-close="false"
+      :close-on-click-modal="false"
+      destroy-on-close
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">分享</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogVisible = false"
+          />
+        </div>
+      </div>
+      <el-form label-width="180px" :model="formLabelAlign">
+        <el-form-item label="观看权限:">
+          <el-radio-group v-model="formLabelAlign.watchPer" @change="submitTable">
+            <el-radio :label="1">已开通课程的学员</el-radio>
+            <el-radio :label="2">所有学员</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="观看链接(PC端):">
+          <span id="copycode">{{ formLabelAlign.enCodePC }}</span
+          ><el-button
+            v-if="formLabelAlign.enCodePC"
+            type="text"
+            style="margin-left: 10px"
+            @click="copyUrl"
+            >复制</el-button
+          >
+        </el-form-item>
+        <el-form-item label="观看二维码:">
+          <img
+            style="width: 100px; height: 100px"
+            :src="formLabelAlign.enCode"
+            alt=""
+          />
+          <el-button
+            type="text"
+            @click="downloadFileByBase64(formLabelAlign.enCode, '小程序二维码')"
+            >下载</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">关 闭</el-button>
+        <!-- <el-button type="primary" @click="submitTable">保 存</el-button> -->
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      dialogVisible: false, //分享窗口
+      formLabelAlign: {
+        watchPer: 1,
+        enCode: "",
+      },
+      keyIdArray: [],
+      sectionType: "",
+      goodsId: "",
+    };
+  },
+  methods: {
+    /**
+     * 复制地址
+     */
+    copyUrl() {
+      const range = document.createRange();//创建range对象;
+      range.selectNode(document.getElementById("copycode")); //获取复制内容的 id 选择器
+      const selection = window.getSelection(); //创建 selection对象
+      if (selection.rangeCount > 0) selection.removeAllRanges(); //如果页面已经有选取了的话,会自动删除这个选区,没有选区的话,会把这个选取加入选区
+      selection.addRange(range); //将range对象添加到selection选区当中,会高亮文本块
+      document.execCommand("copy"); //复制选中的文字到剪贴板
+      this.$message.success("复制成功");
+      selection.removeRange(range); // 移除选中的元素
+    },
+    //将base64转换为blob
+    dataURLtoBlob(dataurl) {
+      if (!dataurl) {
+        this.$message.error("下载失败");
+        return;
+      }
+      var arr = dataurl.split(","),
+        mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]),
+        n = bstr.length,
+        u8arr = new Uint8Array(n);
+      while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new Blob([u8arr], { type: mime });
+    },
+    //下载方法
+    downloadFile(url, name = "下载图") {
+      var a = document.createElement("a");
+      a.setAttribute("href", url);
+      a.setAttribute("download", name);
+      a.setAttribute("target", "_blank");
+      let clickEvent = document.createEvent("MouseEvents");
+      clickEvent.initEvent("click", true, true);
+      a.dispatchEvent(clickEvent);
+    },
+
+    downloadFileByBase64(base64, name) {
+      var myBlob = this.dataURLtoBlob(base64);
+      var myUrl = URL.createObjectURL(myBlob);
+      this.downloadFile(myUrl, name);
+    },
+    /**
+     * 打开分享窗口
+     */
+    openBox(rows, goodsId) {
+      this.keyIdArray = rows.keyId.split("-").map(Number);
+      this.goodsId = goodsId;
+      this.sectionType = rows.sectionType;
+      this.$api
+        .coursesectionwatchper({
+          goodsId: this.goodsId,
+          courseId: this.keyIdArray[0] || "",
+          moduleId: this.keyIdArray[1] || "",
+          chapterId: this.keyIdArray[2] || "",
+          sectionId: this.keyIdArray[3] || "",
+          sectionType: this.sectionType,
+        })
+        .then((res) => {
+          if (res.data) {
+            if (!res.data.watchPer) {
+              res.data.watchPer = 1;
+            }
+            this.formLabelAlign = res.data;
+          } else {
+            this.formLabelAlign = {
+              goodsId: this.goodsId,
+              courseId: this.keyIdArray[0] || "",
+              moduleId: this.keyIdArray[1] || "",
+              chapterId: this.keyIdArray[2] || "",
+              sectionId: this.keyIdArray[3] || "",
+              sectionType: this.sectionType,
+              watchPer: 1,
+            };
+          }
+          this.dialogVisible = true;
+        });
+    },
+    /**
+     * 保存分享
+     */
+    submitTable() {
+      let data;
+      if (this.formLabelAlign.id) {
+        data = this.formLabelAlign;
+      } else {
+        data = {
+          goodsId: this.goodsId,
+          courseId: this.keyIdArray[0] || "",
+          moduleId: this.keyIdArray[1] || "",
+          chapterId: this.keyIdArray[2] || "",
+          sectionId: this.keyIdArray[3] || "",
+          sectionType: this.sectionType,
+          watchPer: this.formLabelAlign.watchPer,
+        };
+      }
+      this.$api.coursesectionaddwatchper(data).then((res) => {
+        this.$message.success("保存成功");
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 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 = [];

+ 9 - 0
src/views/Marketing/goods/commodityManageMent/edit/pricePeriod.vue

@@ -19,6 +19,15 @@
             v-model="listData.lowestPrice"
             ></el-input-number
           >
+        </el-form-item>
+         <el-form-item label="商品划线价(元)" prop="linePrice">
+          <el-input-number
+            :controls="false"
+            :min="0"
+            :style="`max-width:${inputWidth}px;`"
+            v-model="listData.linePrice"
+            ></el-input-number
+          >
         </el-form-item>
         <el-form-item label="状态" prop="status">
           <el-radio-group v-model="listData.status">

+ 44 - 4
src/views/Marketing/goods/commodityManageMent/index.vue

@@ -17,6 +17,12 @@
       @editInfo="editInfo"
     >
       <template slot="btn" slot-scope="props">
+        <el-button
+          v-if="props.scope.row.goodsType == 1 && props.scope.row.courseNum && props.scope.row.courseNum > 0"
+          type="text"
+          @click="setTeacher(props.scope.row)"
+          >双师制设置</el-button
+        >
         <el-button type="text" @click="addClick(props.scope.row, 0)"
           >修改</el-button
         >
@@ -54,7 +60,7 @@ export default {
         border: true,
         choice: true,
         addHide: false,
-        changeWidth:"180px",
+        changeWidth: "180px",
         backFatherBtn: {
           status: false,
           title: "未定义",
@@ -188,9 +194,9 @@ export default {
           hidden: false,
         },
         {
-          label:"科目",
-          prop:"subjectNames",
-          hidden:true
+          label: "科目",
+          prop: "subjectNames",
+          hidden: true,
         },
         {
           label: "业务层次",
@@ -221,6 +227,13 @@ export default {
           scope: "leftCh",
           ch: "¥",
         },
+        {
+          label: "商品划线价",
+          prop: "linePrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
         {
           label: "商品状态",
           prop: "status",
@@ -351,6 +364,33 @@ export default {
         }
       });
     },
+    //双师制设置
+    setTeacher(data) {
+      const jump = () => {
+        this.$router.push({
+          path: "commoditySetTeacher",
+          query: {
+            id: data.goodsId,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "CommoditySetTeacher";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "CommoditySetTeacher",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
     addClick(v, int) {
       if (v === undefined) {
         this.$router.push({

+ 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);

+ 383 - 0
src/views/Marketing/goods/commodityManageMent/teacher/index.vue

@@ -0,0 +1,383 @@
+<template>
+  <div id="commoditySetTeacher">
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      @addClick="addClick"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="edit(props.scope.row)">编辑</el-button>
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+      </template>
+    </table-list>
+    <!-- <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    /> -->
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="1200px"
+      :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="closeBZ" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="150px"
+          :model="resultData"
+          ref="resultData"
+        >
+          <el-form-item label="模板名称" prop="name">
+            <el-input v-model="resultData.name" placeholder="请输入别名"></el-input>
+          </el-form-item>
+          <el-form-item label="关联课程" prop="majors">
+            <el-button type="primary" size="small" @click="link"
+              >关联课程</el-button
+            >
+            <el-table
+              v-if="resultData.courseList && resultData.courseList.length > 0"
+              border
+              :data="resultData.courseList"
+              style="width: 100%"
+              max-height="250"
+              :header-cell-style="{ 'text-align': 'center' }"
+            >
+              <el-table-column prop="code" label="编码" width="200">
+              </el-table-column>
+              <el-table-column prop="courseName" label="名称" width="300">
+              </el-table-column>
+              <el-table-column prop="subjectName" label="科目" width="200">
+              </el-table-column>
+              <el-table-column prop="aliasName" label="别名(必填)" width="200">
+                <template slot-scope="scope">
+                  <el-input v-model="scope.row['aliasName']"></el-input>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="108">
+                <template slot-scope="scope">
+                  <el-button
+                    @click="delCourse(scope.row.courseId)"
+                    type="text"
+                    size="small"
+                  >
+                    删除
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeBZ">取 消</el-button>
+        <el-button @click="submits">确 定</el-button>
+      </span>
+    </el-dialog>
+    <select-course ref="selectCourse" @backData="backData" />
+  </div>
+</template>
+
+<script>
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import selectCourse from "./selectCourse.vue";
+export default {
+  name: "CommoditySetTeacher",
+  components: { tableList, pagination, selectCourse },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      goodsId: "", //商品ID
+      dialogVisible: false,
+      bieName: "",
+      navText: {
+        title: "双师资模板设置",
+        num: false,
+        border: true,
+        choice: false,
+        addHide: false,
+        changeWidth: "180px",
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      resultData: {
+        name: "",
+        courseList: [],
+      },
+      topType: true,
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "模板名称",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "关联课程",
+          prop: "courseList",
+          scope: "courseAbout",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.goodsId = this.$route.query.id;
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    edit(v) {
+      this.resultData.id = v.id;
+      this.resultData.name = v.name;
+      this.resultData.courseList = v.courseList;
+      console.log(this.resultData);
+      this.dialogVisible = true;
+    },
+    addClick() {
+      this.resultData.id = "";
+      this.resultData.name = "";
+      this.resultData.courseList = [];
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs["listData"];
+      });
+    },
+    closeBZ() {
+      this.dialogVisible = false;
+      this.search()
+    },
+    link() {
+      //打开关联课程组件
+      this.$refs.selectCourse.openBox(this.goodsId, this.resultData.courseList);
+    },
+    //弹窗回调
+    backData(array) {
+      let size = this.resultData.courseList.length + array.length;
+      if (size > 3) {
+        this.$message.warning("最多关联3条数据,请重新选择!");
+      } else {
+        if (array && array.length > 0) {
+          array.forEach((item) => {
+            let data = {
+              courseId: item.courseId,
+              code: item.code,
+              courseName: item.courseName,
+              subjectId: item.subjectId,
+              subjectName: item.subjectName,
+              aliasName: "",
+            };
+            this.resultData.courseList.push(data);
+          });
+        }
+      }
+    },
+    search() {
+      let param = {
+        goodsId: this.goodsId,
+      };
+      this.$api.inquireCourseTeacherList(param).then((res) => {
+        console.log(res, "res");
+        if (res.code == 200) {
+          this.tableData = res.data;
+        }
+      });
+    },
+    init() {
+      this.search();
+    },
+    delCourse(courseId) {
+      this.resultData.courseList = this.resultData.courseList.filter(
+        (x) => x.courseId !== courseId
+      );
+    },
+    del(v) {
+      console.log(v, "v");
+      //删除
+      let param = {
+        id: v.id,
+        status: -1,
+      };
+      this.$api.editCourseTeacherList(param).then((res) => {
+        this.$message.success("删除成功");
+        this.dialogVisible = false;
+        this.search();
+      });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    submits() {
+      if (
+        this.resultData.courseList &&
+        this.resultData.courseList.length > 1 &&
+        this.resultData.courseList.length < 4
+      ) {
+        let data = this.resultData.courseList.filter((x) => x.aliasName == "");
+        if (data && data.length > 0) {
+          this.$message.warning("请先填写别名");
+        } else {
+          let subjectId = this.resultData.courseList[0].subjectId;
+          let flag = this.resultData.courseList.every((items) => {
+            return items.subjectId === subjectId;
+          });
+          if (flag) {
+            if (this.resultData.id && this.resultData.id != "") {
+              //修改
+              let param = {
+                id: this.resultData.id,
+                goodsId: this.goodsId,
+                name: this.resultData.name,
+                courseList: this.resultData.courseList,
+              };
+              this.$api.editCourseTeacherList(param).then((res) => {
+                this.$message.success("修改成功");
+                this.dialogVisible = false;
+                this.search();
+              });
+            } else {
+              //新增
+              let param = {
+                goodsId: this.goodsId,
+                name: this.resultData.name,
+                courseList: this.resultData.courseList,
+              };
+              this.$api.addCourseTeacherList(param).then((res) => {
+                this.$message.success("添加成功");
+                this.dialogVisible = false;
+                this.search();
+              });
+            }
+          } else {
+            this.$message.warning(
+              "只能选择相同科目的课程进行关联,请重新选择!"
+            );
+          }
+        }
+      } else {
+        this.$message.warning("最多关联3条/最少关联2条数据,请重新选择!");
+      }
+      console.log(this.resultData, "resultData");
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 203 - 0
src/views/Marketing/goods/commodityManageMent/teacher/selectCourse.vue

@@ -0,0 +1,203 @@
+<template>
+  <div id="selectCourse">
+    <el-dialog
+      @opened="prepareEnd"
+      :visible.sync="dialogVisibleTableBoxs"
+      width="1100px"
+      :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="dialogVisibleTableBoxs = false"
+          />
+        </div>
+      </div>
+      <!-- <div style="margin-bottom: 10px">
+        <el-input
+          style="width: 230px; margin: 0px 10px"
+          :size="size"
+          v-model="formData['key']"
+          placeholder="课程标题/课程编码"
+        ></el-input>
+        <el-button :size="size" type="primary" @click="getInfos(1)"
+          >查询</el-button
+        >
+        <el-button :size="size" @click="getInfos(0)">重置</el-button>
+      </div> -->
+      <span style="color: red">注:最多选择3条数据进行关联</span>
+      <el-table
+        ref="multipleTable"
+        :data="tableData"
+        border
+        @selection-change="selectCheck"
+        :row-key="getRowKeys"
+        :header-cell-style="{
+          'background-color': '#eee',
+          padding: '8px',
+          color: '#333',
+        }"
+      >
+        <el-table-column
+          align="center"
+          type="selection"
+          width="55"
+          header-align="center"
+          :selectable="checkboxT"
+          :reserve-selection="true"
+        >
+        </el-table-column>
+        <template v-for="(item, index) in tableSet">
+          <el-table-column
+            v-if="item.scope !== 'inputs'"
+            :width="item.width"
+            :key="index"
+            :label="item.label"
+            align="center"
+            :show-overflow-tooltip="true"
+            header-align="center"
+            ><template slot-scope="scope">
+              <span>{{ scope.row[item.prop] }}</span></template
+            >
+          </el-table-column></template
+        >
+      </el-table>
+      <pagination
+        :total="total"
+        :pageSize="formData.pageSize"
+        :currentPage="formData.pageNum"
+        @handleSizeChange="handleSizeChange"
+        @handleCurrentChange="handleCurrentChange"
+      />
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisibleTableBoxs = false">取 消</el-button>
+        <el-button
+          type="primary"
+          :disabled="activeLists.length === 0"
+          @click="submitTab"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import pagination from "@/components/pagination";
+export default {
+  components: { pagination },
+  data() {
+    return {
+      size: "small",
+      dialogVisibleTableBoxs: false,
+      tableData: [],
+      goodsId: "",
+      tableSet: [
+        { label: "课程编码", prop: "code", width: "140px" },
+        { label: "课程科目", prop: "subjectName"},
+        { label: "课程标题", prop: "courseName" },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      activeLists: [],
+      courseIds:[],
+      total: 0,
+    };
+  },
+  methods: {
+    /**
+     * 初始
+     */
+    openBox(goodsId,courseList) {
+      this.goodsId = goodsId;
+      console.log(courseList,'courseList');
+      if(courseList && courseList.length > 0){
+        this.courseIds = courseList.map(item => item.courseId)
+        console.log(this.courseIds,'courseIds');
+      }else{
+        this.courseIds = []
+      }
+      //获取商品课程
+      this.$api.obtainCourseSgoodsId(goodsId).then((res) => {
+        console.log(res, "res");
+        if (res.code == 200) {
+          this.tableData = res.rows;
+          this.total = res.total;
+        }
+        console.log(this.tableData, "this.tableData");
+      });
+      this.dialogVisibleTableBoxs = true;
+      this.$nextTick(() => {
+        this.$refs.multipleTable.clearSelection();
+      });
+    },
+    /**
+     * 搜索数据
+     */
+    getInfos(int) {
+      //重置0
+      if (int === 0) {
+        this.formData.pageSize = 10;
+        this.formData.pageNum = 1;
+      }
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      this.$api.obtainCourseSgoodsId(this.goodsId).then((res) => {
+        this.tableData = res.rows;
+        this.total = res.total;
+      });
+    },
+    /**
+     * 开启动画结束执行
+     */
+    prepareEnd() {
+      this.activeLists = []; //初始清空勾选数据
+    },
+    /**
+     * 提交回调数据
+     */
+    submitTab() {
+      if(this.activeLists && this.activeLists.length > 3){
+        this.$message.warning("最多选择3条数据进行关联,进行关联,请重新选择!");
+        return;
+      }
+      this.$message.success("添加成功");
+      this.dialogVisibleTableBoxs = false;
+      this.$emit("backData", this.activeLists);
+    },
+    selectCheck(value) {
+      this.activeLists = value;
+    },
+    checkboxT(row, index) {
+      // || row.bindStatus != 0
+      if((this.courseIds.length > 0 && this.courseIds.includes(row.courseId)) ||  (row.bindStatus && row.bindStatus > 0)){
+        return false;
+      }else{
+        return true;
+      }
+    },
+    getRowKeys(row) {
+      return row.courseId;
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.getInfos();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.getInfos();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 277 - 0
src/views/Marketing/goods/goodTopic/index.vue

@@ -0,0 +1,277 @@
+<template>
+  <div id="goodTopic">
+    <!-- <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+      :topType="topType"
+    /> -->
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="share(props.scope.row)">分享</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "GoodTopic",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "商品专题页",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        changeWidth: "180px",
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      topType: true,
+      //搜索
+      formList: [],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "教育类型",
+          prop: "educationName",
+          hidden: true,
+        },
+        {
+          label: "业务层次",
+          prop1: "projectName",
+          prop2: "businessName",
+          hidden: true,
+          scope: "InfoMore",
+        },
+        {
+          label: "业务层次别名",
+          prop: "aliasName",
+          hidden: true,
+        },
+        {
+          label: "专题页状态",
+          prop: "status",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "关闭",
+              value: 0,
+            },
+          ],
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    share(v) {
+      console.log(v);
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      if (int === 3) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquirecoursetopiclist(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    del(v) {
+      this.$api.gradecheckGoodsChange({ goodsId: v.goodsId }).then((res) => {
+        if (res.data > 0) {
+          this.$message.error("已有学员正在学习该商品,无法删除");
+          return;
+        } else {
+          this.$alert(
+            "确定删除此内容?<br />内容删除后将无法恢复,请慎重考虑",
+            "提示",
+            {
+              dangerouslyUseHTMLString: true,
+            }
+          )
+            .then(() => {
+              var data = {
+                goodsId: v.goodsId,
+                status: -1,
+              };
+              this.$api.editGoods(data).then((res) => {
+                this.$message.success("删除成功");
+                this.search();
+              });
+            })
+            .catch(() => {
+              this.$message({
+                type: "info",
+                message: "已取消删除",
+              });
+            });
+        }
+      });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

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

@@ -145,6 +145,7 @@ export default {
         { label: "题库商品", value: 2 },
         { label: "补考商品", value: 3 },
         { label: "前培商品", value: 4 },
+        { label: "直播商品", value: 6 },
       ],
       topData: {
         type: [],
@@ -174,6 +175,10 @@ export default {
           label: "学员身份证",
           prop: "idCard",
         },
+        {
+          label: "所在公司",
+          prop: "companyName",
+        },
         {
           label: "科目",
           prop: "subjectIds",
@@ -257,10 +262,30 @@ 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");
+      if(this.tableData && this.tableData.length > 0){
+        const data = new Set()
+        this.tableData.forEach((item) => {
+          ays.forEach((as) => {
+            if(item.telphone == as.telphone && as.companyName && as.companyName != ''){
+              item.companyName = as.companyName
+            }else{
+              data.add(as)
+            }
+          })
+        })
+        if(data && data.size > 0){
+          let newObjs = this.tableData.concat(Array.from(data));
+          this.tableData = this.$methodsTools.uniqueFunc(newObjs, "userId");
+        }
+      }else{
+        this.tableData = ays
+      }
     },
     /**
      * 导入
@@ -413,8 +438,6 @@ export default {
 }
 .rowSty {
   display: flex;
-  .ulSty {
-  }
   .spanSty {
     width: 50px;
     flex-shrink: 0;

+ 4 - 0
src/views/Marketing/order/offlineOrder/batchRecord/firstStep/uploadStudent.vue

@@ -173,6 +173,10 @@ export default {
           label: "学员身份证",
           prop: "idCard",
         },
+        {
+          label: "所在公司",
+          prop: "companyName",
+        },
         {
           label: "绑定手机号码",
           prop: "telphone",

+ 18 - 5
src/views/Marketing/order/offlineOrder/batchRecord/secondStep/index.vue

@@ -4,12 +4,13 @@
       已选择
       <strong style="color: red">{{ objCopy.length }}</strong> 人;共<strong
         style="color: red"
-        >{{ compay(tableData, 6) }}</strong
+        >{{ compay(tableData, 7) }}</strong
       >个商品(<strong style="color: red">{{ compay(tableData, 1) }}</strong
       >视频、<strong style="color: red">{{ compay(tableData, 2) }}</strong
       >题库、<strong style="color: red">{{ compay(tableData, 3) }}</strong
       >补考、<strong style="color: red">{{ compay(tableData, 4) }}</strong
-      >前培);总价<strong style="color: red"
+      >前培、<strong style="color: red">{{ compay(tableData, 6) }}</strong
+      >直播);总价<strong style="color: red"
         >¥{{ compay(tableData, 5).toFixed(2) }}</strong
       >
     </div>
@@ -255,6 +256,13 @@ export default {
             });
             break;
           case 6:
+            data.forEach((item) => {
+              if (item.goodsType === int && item.checked) {
+                num++;
+              }
+            });
+            break;
+          case 7:       
             data.forEach((item) => {
               if (
                 item.goodsType &&
@@ -266,7 +274,6 @@ export default {
               }
             });
             break;
-
           default:
             break;
         }
@@ -766,6 +773,12 @@ export default {
           return item.checked;
         }
       });
+      if (!submitTable || submitTable.length == 0) {
+        this.$message.error("请选择需要购买的商品");
+        this.disabledBtn = false;
+        this.loading = false;
+        return;
+      }
       if (!submitTable.length && int === 2) {
         this.tableData.forEach((items, indexs) => {
           if (items.userId === row.userId) {
@@ -781,7 +794,7 @@ export default {
         if (!arr.length) {
           arr.push({
             inputOrderSn: this.SN,
-            orderFrom: 1,
+            orderFrom: 5,
             userId: item.userId,
             goodsList: [
               {
@@ -812,7 +825,7 @@ export default {
           } else {
             arr.push({
               inputOrderSn: this.SN,
-              orderFrom: 1,
+              orderFrom: 5,
               userId: item.userId,
               goodsList: [
                 {

+ 62 - 43
src/views/Marketing/order/offlineOrder/batchRecord/secondStep/setGoodsList.vue

@@ -66,9 +66,12 @@
               >
               <el-button :size="size" @click="init">重置</el-button>
             </div>
+            <div v-if="stop" style="text-align: center">
+              加载中<i class="el-icon-loading"></i>
+            </div>
             <div
               style="margin-top: 14px; text-align: center"
-              v-if="!goodsList.length"
+              v-else-if="goodsList.length <= 0 && !stop"
             >
               暂无符合条件商品
             </div>
@@ -79,6 +82,7 @@
                 background: #eee;
                 margin-top: 10px;
               "
+              v-else-if="goodsList.length && !stop"
             >
               <li
                 v-for="(item, index) in goodsList"
@@ -116,6 +120,7 @@
 export default {
   data() {
     return {
+      stop: false,
       disabledBtn: false,
       size: "mini",
       dialogCG: false,
@@ -200,55 +205,65 @@ export default {
         }
       }
     },
-    init() {
+    async init() {
       this.goodsName = "";
       this.goodsPrice = "";
-      this.searchData();
+      await this.searchData();
     },
     /**
      * 科目ID,商品类型
      */
-    activeLi(subjectId, type) {
+    async activeLi(subjectId, type) {
       if (this.active == `${subjectId}-${type}`) return;
-      this.active = `${subjectId}-${type}`;
+      if (this.stop) return;
       this.goodsName = "";
       this.goodsPrice = "";
-      this.searchData();
+      this.active = `${subjectId}-${type}`
+      await this.searchData()
     },
     searchData() {
-      var subjectId = this.active.split("-")[0];
-      var type = this.active.split("-")[1];
-      var priceReg = /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/;
-      if (this.goodsPrice && !priceReg.test(this.goodsPrice)) {
-        this.$message.warning("请输入正确价格");
-        return;
-      }
-      var data = {
-        goodsType: type,
-        goodsName: this.goodsName || "",
-        standPrice: this.goodsPrice || "",
-        goodsStatus: 1,
-        status: 1,
-        businessIds: this.oldObj.businessId,
-        subjectId : subjectId
-      };
-      // if (type == 1 || type == 2) {
-      //   data.subjectId = subjectId;
-      // }
-      this.$api.inquiregoodslistToInputList(data).then((res) => {
-        res.rows.forEach((item) => {
-          item.subjectId = subjectId;
-          item.checked = false;
-          this.newDatas.forEach((items) => {
-            if (
-              items.subjectId == item.subjectId &&
-              items.goodsId == item.goodsId
-            ) {
-              item.checked = true;
-            }
+      return new Promise((resolve, reject) => {
+        var subjectId = this.active.split("-")[0];
+        var type = this.active.split("-")[1];
+        var priceReg = /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/;
+        if (this.goodsPrice && !priceReg.test(this.goodsPrice)) {
+          this.$message.warning("请输入正确价格");
+          return reject();
+        }
+        var data = {
+          goodsType: type,
+          goodsName: this.goodsName || "",
+          standPrice: this.goodsPrice || "",
+          // goodsStatus: 1,
+          status: 1,
+          businessIds: this.oldObj.businessId,
+          subjectId: subjectId,
+        };
+        // if (type == 1 || type == 2) {
+        //   data.subjectId = subjectId;
+        // }
+        this.stop = true;
+        this.$api
+          .inquiregoodslistToInputList(data)
+          .then((res) => {
+            res.rows.forEach((item) => {
+              item.subjectId = subjectId;
+              item.checked = false;
+              this.newDatas.forEach((items) => {
+                if (
+                  items.subjectId == item.subjectId &&
+                  items.goodsId == item.goodsId
+                ) {
+                  item.checked = true;
+                }
+              });
+            });
+            this.goodsList = res.rows;
+            resolve();
+          })
+          .finally(() => {
+            this.stop = false;
           });
-        });
-        this.goodsList = res.rows;
       });
     },
     submitCG() {
@@ -283,17 +298,17 @@ export default {
       this.disabledBtn = false;
       this.dialogCG = false;
     },
-    openBox(oldObj, datas) {
+    async openBox(oldObj, datas) {
       this.newDatas = JSON.parse(JSON.stringify(datas));
       this.copynewDatas = JSON.parse(JSON.stringify(datas));
       this.oldObj = JSON.parse(JSON.stringify(oldObj));
       if (this.active) {
-        this.searchData();
+        await this.searchData();
       }
       // this.active = "";
-      this.goodsName = "";
-      this.goodsPrice = "";
-      this.goodsList = [];
+      // this.goodsName = "";
+      // this.goodsPrice = "";
+      // this.goodsList = [];
       this.$api
         .inquireCourseSubject({
           businessId: Number(oldObj.businessId),
@@ -313,6 +328,9 @@ export default {
           if (oldObj.type.indexOf(4) !== -1) {
             options.push({ label: "前培商品", value: 4 });
           }
+          if (oldObj.type.indexOf(6) !== -1) {
+            options.push({ label: "直播商品", value: 6 });
+          }
           this.dataList = res.rows.map((item) => {
             return {
               id: item.id,
@@ -335,6 +353,7 @@ export default {
   padding: 10px;
 }
 .liStyLI {
+  user-select: none;
   cursor: pointer;
   text-align: center;
   margin-bottom: 10px;

+ 64 - 4
src/views/Marketing/order/offlineOrder/index.vue

@@ -24,7 +24,12 @@
         <el-button type="text" @click="theOrderJump(props.scope.row, 1)"
           >订单详情</el-button
         >
-        <el-button type="text" @click="theOrderJump(props.scope.row, 2)"
+        <el-button
+          type="text"
+          @click="theOrderJump(props.scope.row, 2)"
+          :disabled="
+            props.scope.row.orderFrom == 6
+          "
           >计费单收费</el-button
         >
         <el-button type="text" @click="theOrderJump(props.scope.row, 3)"
@@ -90,6 +95,25 @@ export default {
           prop: "searchKey",
           placeholder: "请输入订单编码/录单人姓名",
         },
+        {
+          prop: "orderFrom",
+          placeholder: "订单来源",
+          scope: "select",
+          options: [
+            {
+              label: "系统录单",
+              value: "5",
+            },
+            {
+              label: "业务系统",
+              value: "6",
+            },
+          ],
+        },
+        {
+          prop: "oldOrderSn",
+          placeholder: "订单编号(业务系统)",
+        },
       ],
       formData: {
         status: 1,
@@ -142,10 +166,10 @@ export default {
         },
         {
           label: "已收总金额",
-          prop: "goodsReceived",
+          prop1: "goodsReceived",
+          prop2: "goodsRealPrice",
           hidden: true,
-          scope: "leftCh",
-          ch: "¥",
+          scope: "RealPrice",
         },
         {
           label: "已退总金额",
@@ -161,6 +185,41 @@ export default {
           hidden: true,
           scope: "outStandingAmount",
         },
+        {
+          label: "订单来源",
+          prop: "orderFrom",
+          oldOrder:"oldOrderSn",
+          hidden: true,
+          scope: "isOptionsDY",
+          width: "130px",
+          options: [
+            {
+              label: "业务员普通单",
+              value: "1",
+            },
+            {
+              label: "祥粤云学堂小程序",
+              value: "2",
+            },
+            {
+              label: "祥粤云学堂网站",
+              value: "3",
+            },
+            {
+              label: "祥粤e管证小程序",
+              value: "4",
+            },
+            {
+              label: "系统录单",
+              value: "5",
+            },
+            {
+              label: "业务系统",
+              value: "6",
+              popover: true,
+            },
+          ],
+        },
         {
           label: "录单人",
           prop: "createUsername",
@@ -284,6 +343,7 @@ export default {
             path: "orderDetailsT",
             query: {
               inputOrderSn: row.inputOrderSn,
+              orderFrom: row.orderFrom,
             },
           });
         };

+ 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>

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

@@ -18,7 +18,7 @@
       @backFunc="jumpRefund"
     >
       <template slot="customize">
-        <el-button size="medium" type="warning" @click="setGoodsOptions(1)"
+        <el-button size="medium" type="warning" @click="setGoodsOptions(1)" :disabled="$route.query.orderFrom == 6"
           >计费单收费</el-button
         ><el-button size="medium" type="success" @click="setGoodsOptions(2)"
           >退款申请</el-button
@@ -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 {

+ 1 - 1
src/views/education/classManageMent/classList/index.vue

@@ -254,7 +254,7 @@ export default {
         this.formData.hasInterface = this.$route.params.hasInterface;
       }
     } else {
-      await this.moRenBus();
+      // await this.moRenBus();
     }
     if (this.$route.params.timeType >= 0) {
       this.$set(

+ 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>

+ 1 - 0
src/views/education/classManageMent/learningAccoutTags/index.vue

@@ -30,6 +30,7 @@
           >有接口数据标记</el-button
         >
         <el-button
+        style="margin-left:0px;"
           type="text"
           v-if="props.scope.row.noInterfaceNum > 0"
           @click="getInter(2, props.scope.row)"

+ 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 {

+ 33 - 18
src/views/education/classManageMent/listOfhoursToBeReviewed/index.vue

@@ -6,8 +6,8 @@
         :type="formData.periodStatus === 2 ? 'primary' : ''"
         :size="size"
         @click="changeBTN(2)"
-        >待审核
-        <i
+        >初审({{ reviewListNums }})
+        <!-- <i
           class="el-icon-warning-outline"
           :style="
             reviewListNums >= 200
@@ -19,13 +19,13 @@
               : ''
           "
           style="font-weight: bold"
-        ></i></el-button
+        ></i> --> </el-button
       ><el-button
         :type="formData.periodStatus === 3 ? 'primary' : ''"
         :size="size"
         @click="changeBTN(3)"
-        >审核中
-        <i
+        >复审({{ underReiviewNums }})
+        <!-- <i
           class="el-icon-warning-outline"
           :style="
             underReiviewNums >= 200
@@ -37,12 +37,12 @@
               : ''
           "
           style="font-weight: bold"
-        ></i></el-button
+        ></i> --> </el-button
       ><el-button
         :type="formData.periodStatus === 0 ? 'primary' : ''"
         :size="size"
         @click="changeBTN(0)"
-        >不通过</el-button
+        >不通过({{ failNums }})</el-button
       ><el-button
         :type="formData.periodStatus === 1 ? 'primary' : ''"
         :size="size"
@@ -96,6 +96,7 @@ export default {
       size: "small",
       reviewListNums: 0,
       underReiviewNums: 0,
+      failNums: 0,
       loading: false, //当前表单加载是否加载动画
       navText: {
         title: "学时审核管理",
@@ -309,8 +310,12 @@ export default {
       );
       this.$refs.searchBox.changeBusinessLevel(this.$route.params.businessId);
     }
-    console.log(this.$methodsTools.timestampConvert(this.$route.params.timeType)[0])
-    console.log(this.$methodsTools.timestampConvert(this.$route.params.timeType)[1])
+    console.log(
+      this.$methodsTools.timestampConvert(this.$route.params.timeType)[0]
+    );
+    console.log(
+      this.$methodsTools.timestampConvert(this.$route.params.timeType)[1]
+    );
     if (this.$route.params.timeType >= 0) {
       this.$set(
         this.formData,
@@ -326,11 +331,13 @@ export default {
     this.search();
     this.getInitList();
     this.getInitUnderList();
+    this.getFailList();
   },
   activated() {
     this.search();
     this.getInitList();
     this.getInitUnderList();
+    this.getFailList();
   },
   methods: {
     changeBTN(int) {
@@ -363,6 +370,19 @@ export default {
           this.underReiviewNums = res.rows.length;
         });
     },
+    /**
+     * 不通过数量
+     */
+    getFailList() {
+      this.$api
+        .inquireGradegradelistUserPeriod({
+          periodStatus: 0,
+          status: 1,
+        })
+        .then((res) => {
+          this.failNums = res.rows.length;
+        });
+    },
     jumpPage(v) {
       this.$api
         .inquireGradegradelockPeriodStatus({
@@ -444,20 +464,15 @@ export default {
         };
       }
       if (int === 6) {
-        this.formData = {
-          profileStatus: "",
-          periodStatus: this.formData.periodStatus,
-          status: 1,
-          pageSize: 10,
-          pageNum: 1,
-        };
+        this.formData.pageSize = 10;
+        this.formData.pageNum = 10;
       }
       var data = JSON.parse(JSON.stringify(this.formData));
       if (this.formData.classStartTime) {
-        data.classStartTime = parseInt(data.classStartTime / 1000)
+        data.classStartTime = parseInt(data.classStartTime / 1000);
       }
       if (this.formData.classEndTime) {
-        data.classEndTime = parseInt(data.classEndTime / 1000)
+        data.classEndTime = parseInt(data.classEndTime / 1000);
       }
       this.$api
         .inquireGradegradelistUserPeriods(data)

+ 168 - 14
src/views/education/classManageMent/studentMenu/index.vue

@@ -50,6 +50,7 @@
       :tableSets="tableSet"
       :tableData="tableData"
       :navText="navText"
+      :studentTable="true"
       @addClick="addClick"
       :loading="loading"
       @editInfo="editInfo"
@@ -83,6 +84,40 @@
           @click="moreActive(2)"
           >选班</el-button
         >
+        <el-input
+          clearable
+          style="width: 230px"
+          v-model="formData.companyName"
+          placeholder="所在公司"
+          @clear="search(3)"
+        ><el-button @click="search(3)" slot="append" icon="el-icon-search"></el-button></el-input>
+        <el-select
+          clearable
+          @change="search(3)"
+          v-model="formData.hasBindWx"
+          placeholder="是否绑定微信"
+          style="margin: 0px 10px"
+          size="medium"
+        >
+          <el-option label="是" :value="1"> </el-option>
+          <el-option label="否" :value="0"> </el-option>
+        </el-select>
+        <el-select
+          clearable
+          @change="search(3)"
+          v-model="formData.hasFollowWx"
+          placeholder="是否关注公众号"
+          style="margin: 0px 10px"
+          size="medium"
+        >
+          <el-option label="是" :value="1"> </el-option>
+          <el-option label="否" :value="0"> </el-option>
+        </el-select>
+         <el-button
+          size="medium"
+          @click="exportGrade"
+          :loading="exportLoading"
+          >导出学员数据</el-button>
       </template>
       <template slot="btn" slot-scope="props">
         <el-button type="text" @click="addClick(props.scope.row, 2)"
@@ -554,6 +589,7 @@ import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
 import accountTag from "@/components/AccountTag";
 import quickLogin from "@/components/quickLogin";
+import * as baseUrls from "@/utils/request.js";
 
 export default {
   components: { tableList, pagination, accountTag, quickLogin },
@@ -581,6 +617,7 @@ export default {
       size: "medium",
       active: 1,
       loading: false, //当前表单加载是否加载动画
+      exportLoading: false,//导出按钮
       navText: {
         title: "班级人数:",
         index: 0,
@@ -589,6 +626,7 @@ export default {
         choice: true,
         border: true,
         addHide: true,
+        rowKey:"id",
         gftsStatus: false,
         gfUserStatus: false,
         backFatherBtn: {
@@ -637,39 +675,77 @@ export default {
         {
           label: "资料变更状态",
           prop: "userStatus",
-          hidden: true,
+          hidden: false,
           scope: "changeCLS",
         },
         {
-          label: "学时",
+          label: "是否绑定小程序账号",
+          prop: "userBindWx",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "是否关注公众号",
+          prop: "userFollowWx",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "课程学时",
           prop: "classHours",
-          hidden: false,
+          hidden: true,
+        },
+        {
+          label: "用户学习时长(秒)",
+          prop: "userStudyDuration",
+          hidden: true,
+          scope: "convert",
         },
         {
           label: "视频学习进度(节)",
           prop1: "stuAllNum",
           prop2: "secAllNum",
-          hidden: false,
+          hidden: true,
           scope: "computer",
         },
         {
           label: "做题进度(章卷)",
           prop1: "recordNum",
           prop2: "examNum",
-          hidden: false,
+          hidden: true,
           scope: "computer",
         },
         {
           label: "学时审批状态",
           prop: "periodStatus",
-          hidden: true,
+          hidden: false,
           scope: "statusPeriods",
         },
         {
           label: "学习服务期",
           prop1: "serviceStartTime",
           prop2: "serviceEndTime",
-          hidden: false,
+          hidden: true,
           Diszing: true,
           scope: "TimeLists",
         },
@@ -677,20 +753,41 @@ export default {
           label: "班级有效期",
           prop1: "classStartTime",
           prop2: "classEndTime",
-          hidden: true,
+          hidden: false,
           Diszing: false,
           scope: "TimeLists",
         },
         {
           label: "学完状态",
           prop: "finishStatus",
-          hidden: true,
+          hidden: false,
           scope: "finishStatus",
         },
         {
           label: "剩余学习机会",
           prop: "studyCount",
+          hidden: false,
+        },
+        {
+          label: "学习机会",
+          prop1: "useStudyCount",
+          prop2: "studyCount",
+          hidden: true,
+          scope:"studyCount"
+        },
+        {
+          label: "考试机会",
+          prop1: "examNumber",
+          prop2: "expendNumber",
           hidden: true,
+          scope:"chance"
+        },
+        {
+          label: "前培机会",
+          prop1: "doNumber",
+          prop2: "expendBefore",
+          hidden: true,
+          scope:"chance"
         },
         {
           label: "复购-学时冲突",
@@ -983,12 +1080,37 @@ export default {
       } else {
         if (int === 2) {
           //学员详情
-          this.$api
-            .inquiregradestudentlistStudent({ userId: v.userId })
-            .then((res) => {
-              this.listData = res.rows[0];
-              this.dialogVisibleStudent = true;
+          // this.$api
+          //   .inquiregradestudentlistStudent({ userId: v.userId })
+          //   .then((res) => {
+          //     this.listData = res.rows[0];
+          //     this.dialogVisibleStudent = true;
+          //   });
+          const jump = () => {
+            //学员详情
+            this.$router.push({
+              name: "StudentXQ",
+              query: {
+                id: v.userId,
+              },
             });
+          };
+          const statusPage = this.$store.state.tagsView.visitedViews.some(
+            (item) => {
+              return item.name == "StudentXQ";
+            }
+          );
+          if (statusPage) {
+            this.$store
+              .dispatch("tagsView/delCachedView", {
+                name: "StudentXQ",
+              })
+              .then((res) => {
+                jump();
+              });
+          } else {
+            jump();
+          }
         }
         if (int === 3) {
           // 学员管理
@@ -1049,6 +1171,38 @@ export default {
         }
       }
     },
+    //导出学员数据
+    exportGrade(){
+      this.exportLoading = true
+      let data = this.$refs.tableList.allCheckData
+      if(data && data.length > 0){
+       let idCards = data.map(x => x.idCard)
+       this.formData.idCards = idCards
+       console.log(idCards,'idCards');
+       console.log(this.formData,'this.formData');
+      }
+      this.formData.gradeId = this.$route.query.id,
+      this.formData.status = '0,1',
+      this.$api
+        .inquireGradegradeexportGrade(this.formData)
+        .then((res) => {
+            if (res.msg) {
+              let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
+              let link = document.createElement("a");
+              let fileName = "班级学员数据" + ".xlsx";
+              document.body.appendChild(link);
+              link.href = url;
+              link.dowmload = fileName;
+              link.click();
+              link.remove();
+              this.$message.success("导出成功");
+            } else {
+              this.$message.error("导出失败");
+            }
+        }).finally(() => {
+          this.exportLoading = false
+        })
+    },
     search(int) {
       this.loading = true;
       if (int === 1) {

+ 32 - 1
src/views/education/examManagement/applicationData/asPlanned.vue

@@ -386,6 +386,16 @@ export default {
           placeholder: "前培标题",
           scope: "beforeList",
         },
+        {
+          prop: "syncStatus",
+          placeholder: "同步状态",
+          scope: "select",
+          options: [
+            { label: "未同步", value: 0 },
+            { label: "成功", value: 1 },
+            { label: "失败", value: 2 },
+          ],
+        },
         {
           prop: "studentType",
           placeholder: "学员报名类型",
@@ -425,6 +435,20 @@ export default {
       },
       // 表单
       tableSet: [
+        {
+          label: "考试机会",
+          prop1: "examNumber",
+          prop2: "expendNumber",
+          hidden: true,
+          scope: "chance",
+        },
+        {
+          label: "前培机会",
+          prop1: "doNumber",
+          prop2: "expendBefore",
+          hidden: true,
+          scope: "chance",
+        },
         {
           label: "预约状态",
           prop: "subscribeStatus",
@@ -548,6 +572,9 @@ export default {
           prop2: "applySiteExamTime",
           prop3: "applySiteStartTime",
           prop4: "applySiteEndTime",
+          prop5: "examineeCode",
+          prop6: "seatNumber",
+          prop7: "syncStatus",
           hidden: true,
           scope: "changAdress",
         },
@@ -563,7 +590,7 @@ export default {
           prop3: "applySiteStartTrainTime",
           prop4: "applySiteEndTrainTime",
           hidden: true,
-          scope: "changAdress",
+          scope: "changAdressKP",
         },
         {
           label: "前培次数消耗",
@@ -616,6 +643,10 @@ export default {
     if (this.$route.query.type == 2) {
       this.formData.beforeId = Number(this.$route.query.id);
     }
+    if (this.$route.params.type == 3) {
+      this.formData.applyId = Number(this.$route.params.id);
+      this.formData.syncStatus = 2
+    }
     this.search();
     this.getQP();
   },

+ 5 - 4
src/views/education/examManagement/applicationData/bulkImportPlan/newRegister.vue

@@ -464,10 +464,11 @@ export default {
       var data = JSON.parse(JSON.stringify(this.formData));
       if (this.formData.idCards) {
         data.idCards = this.formData.idCards.split("\n");
-      } else {
-        this.$message.warning("请选择学员");
-        return;
-      }
+      } 
+      // else {
+      //   this.$message.warning("请选择学员");
+      //   return;
+      // }
       const indexs = this.examLists.findIndex((item) => {
         return item.applyId == data.applyId;
       });

+ 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
             >

+ 18 - 1
src/views/education/examManagement/applicationData/cancelAppointMent/index.vue

@@ -182,6 +182,20 @@ export default {
       },
       // 表单
       tableSet: [
+        {
+          label: "考试机会",
+          prop1: "examNumber",
+          prop2: "expendNumber",
+          hidden: true,
+          scope: "chance",
+        },
+        {
+          label: "前培机会",
+          prop1: "doNumber",
+          prop2: "expendBefore",
+          hidden: true,
+          scope: "chance",
+        },
         {
           label: "预约状态",
           prop: "subscribeStatus",
@@ -305,6 +319,9 @@ export default {
           prop2: "applySiteExamTime",
           prop3: "applySiteStartTime",
           prop4: "applySiteEndTime",
+          prop5: "examineeCode",
+          prop6: "seatNumber",
+          prop7: "syncStatus",
           hidden: true,
           scope: "changAdress",
         },
@@ -320,7 +337,7 @@ export default {
           prop3: "applySiteStartTrainTime",
           prop4: "applySiteEndTrainTime",
           hidden: true,
-          scope: "changAdress",
+          scope: "changAdressKP",
         },
         {
           label: "前培次数消耗",

+ 18 - 1
src/views/education/examManagement/applicationData/examRegistration/index.vue

@@ -228,6 +228,20 @@ export default {
       },
       // 表单
       tableSet: [
+        {
+          label: "考试机会",
+          prop1: "examNumber",
+          prop2: "expendNumber",
+          hidden: true,
+          scope: "chance",
+        },
+        {
+          label: "前培机会",
+          prop1: "doNumber",
+          prop2: "expendBefore",
+          hidden: true,
+          scope: "chance",
+        },
         {
           label: "预约状态",
           prop: "subscribeStatus",
@@ -351,6 +365,9 @@ export default {
           prop2: "applySiteExamTime",
           prop3: "applySiteStartTime",
           prop4: "applySiteEndTime",
+          prop5: "examineeCode",
+          prop6: "seatNumber",
+          prop7: "syncStatus",
           hidden: true,
           scope: "changAdress",
         },
@@ -366,7 +383,7 @@ export default {
           prop3: "applySiteStartTrainTime",
           prop4: "applySiteEndTrainTime",
           hidden: true,
-          scope: "changAdress",
+          scope: "changAdressKP",
         },
         {
           label: "前培次数消耗",

+ 25 - 8
src/views/education/examManagement/applicationData/formerAccount/index.vue

@@ -156,11 +156,11 @@ export default {
       },
       //搜索
       formList: [
-        {
-          prop: "beforeId",
-          placeholder: "前培计划",
-          scope: "beforeLists",
-        },
+        // {
+        //   prop: "beforeId",
+        //   placeholder: "前培计划",
+        //   scope: "beforeLists",
+        // },
         {
           prop: "applyId",
           placeholder: "考试计划",
@@ -202,6 +202,20 @@ export default {
       },
       // 表单
       tableSet: [
+        {
+          label: "考试机会",
+          prop1: "examNumber",
+          prop2: "expendNumber",
+          hidden: true,
+          scope: "chance",
+        },
+        {
+          label: "前培机会",
+          prop1: "doNumber",
+          prop2: "expendBefore",
+          hidden: true,
+          scope: "chance",
+        },
         {
           label: "预约状态",
           prop: "subscribeStatus",
@@ -325,6 +339,9 @@ export default {
           prop2: "applySiteExamTime",
           prop3: "applySiteStartTime",
           prop4: "applySiteEndTime",
+          prop5: "examineeCode",
+          prop6: "seatNumber",
+          prop7: "syncStatus",
           hidden: true,
           scope: "changAdress",
         },
@@ -340,7 +357,7 @@ export default {
           prop3: "applySiteStartTrainTime",
           prop4: "applySiteEndTrainTime",
           hidden: true,
-          scope: "changAdress",
+          scope: "changAdressKP",
         },
         {
           label: "前培次数消耗",
@@ -363,8 +380,8 @@ export default {
       peopleList: [],
     };
   },
-  async mounted() {
-    await this.getFirstOptions();
+  mounted() {
+    // await this.getFirstOptions();
     this.search();
   },
   activated() {

+ 273 - 0
src/views/education/examManagement/examArrangement/applicableProducts/beforePage.vue

@@ -0,0 +1,273 @@
+<template>
+  <div id="beforePage">
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="610px"
+      :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="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="150px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item label="前培标题" prop="beforeName">
+            <el-input v-model="listData.beforeName"></el-input>
+          </el-form-item>
+          <el-form-item label="关联题卷" required prop="beforeStatus">
+            <el-select v-model="listData.beforeStatus" placeholder="请选择">
+              <el-option
+                v-for="item in optionsApis"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="" prop="beforeUrl" v-if="listData.beforeStatus">
+            <el-radio-group v-model="listData.beforeUrl">
+              <el-radio
+                style="margin-bottom: 10px"
+                v-for="(item, index) in radioApi"
+                :key="index"
+                :label="item.beforeUrlId"
+                >{{ item.urlName }} - {{ item.url }}</el-radio
+              >
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="学习开放时间" required>
+            <el-col :span="11">
+              <el-form-item prop="beforeStartTime">
+                <el-date-picker
+                  type="datetime"
+                  placeholder="开始日期"
+                  @change="changeEndTime(1)"
+                  v-model="listData.beforeStartTime"
+                  style="width: 100%"
+                  value-format="timestamp"
+                ></el-date-picker>
+              </el-form-item>
+            </el-col>
+            <el-col class="line" style="text-align: center" :span="2">-</el-col>
+            <el-col :span="11">
+              <el-form-item prop="beforeEndTime">
+                <el-date-picker
+                  type="datetime"
+                  placeholder="结束日期"
+                  @change="changeEndTime(2)"
+                  v-model="listData.beforeEndTime"
+                  style="width: 100%"
+                  value-format="timestamp"
+                ></el-date-picker>
+              </el-form-item>
+            </el-col>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          :loading="disabledBtn"
+          @click="submit('listData')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      listData: {
+        beforeName: "",
+        beforeStatus: "",
+        beforeUrl: "",
+        beforeStartTime: "",
+        beforeEndTime: "",
+      },
+      radioApi: [],
+      dialogVisible: false,
+      disabledBtn: false,
+      optionsApis: [
+        // {
+        //   label: "内部接口",
+        //   value: 1,
+        // },
+        {
+          label: "外部接口",
+          value: 2,
+        },
+        // {
+        //   label: "关联题库资源",
+        //   value: 3,
+        // },
+      ],
+      //表单验证
+      rules: {
+        beforeName: [
+          { required: true, message: "请输入前培标题", trigger: "blur" },
+        ],
+        beforeStatus: [
+          { required: true, message: "请选中关联题卷", trigger: "change" },
+        ],
+        beforeUrl: [
+          { required: true, message: "请选择接口地址", trigger: "change" },
+        ],
+        beforeStartTime: [
+          {
+            type: "date",
+            required: true,
+            message: "请选择学习开放开始时间",
+            trigger: "change",
+          },
+        ],
+        beforeEndTime: [
+          {
+            type: "date",
+            required: true,
+            message: "请选择学习开放结束时间",
+            trigger: "change",
+          },
+        ],
+      },
+      applyId: null, //考试ID
+    };
+  },
+  watch: {
+    "listData.beforeStatus"(value) {
+      this.$api.inquiresystembeforelistUrl({ urlStatus: value }).then((res) => {
+        this.radioApi = res.rows;
+      });
+    },
+  },
+  methods: {
+    openBox(row) {
+      this.$api
+        .obtainsystemapplygetBefore(row.applyId)
+        .then((res) => {
+          if (res.data.beforeId) {
+            res.data.beforeStartTime = res.data.beforeStartTime * 1000;
+            res.data.beforeEndTime = res.data.beforeEndTime * 1000;
+            this.listData = res.data;
+          } else {
+            this.listData = {
+              beforeName: "",
+              beforeStatus: "",
+              beforeUrl: "",
+              beforeStartTime: "",
+              beforeEndTime: "",
+            };
+          }
+        })
+        .finally(() => {
+          this.dialogVisible = true;
+          this.$nextTick(() => {
+            this.$refs["listData"].clearValidate();
+          });
+        });
+      this.applyId = row.applyId;
+    },
+    // 判断选择时间逻辑
+    changeEndTime(int) {
+      if (this.listData.beforeStartTime === this.listData.beforeEndTime) {
+        this.$message.warning("开始时间与结束时间不允许相同");
+        if (int === 1) {
+          this.listData.beforeStartTime = "";
+        }
+        if (int === 2) {
+          this.listData.beforeEndTime = "";
+        }
+        return;
+      }
+      if (
+        int === 1 &&
+        this.listData.beforeEndTime &&
+        this.listData.beforeStartTime > this.listData.beforeEndTime
+      ) {
+        this.$message.warning(
+          "当前选择的开始时间大于结束时间,请重新选择开始时间!"
+        );
+        this.listData.beforeStartTime = "";
+        return;
+      }
+      if (
+        int === 2 &&
+        this.listData.beforeStartTime &&
+        this.listData.beforeEndTime < this.listData.beforeStartTime
+      ) {
+        this.$message.warning(
+          "当前选择的结束时间小于开始时间,请重新选择结束时间!"
+        );
+        this.listData.beforeEndTime = "";
+        return;
+      }
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      this.disabledBtn = true;
+      var data = JSON.parse(JSON.stringify(this.listData));
+      data.beforeStartTime = this.$methodsTools.time10to13(
+        data.beforeStartTime,
+        1
+      );
+      data.beforeEndTime = this.$methodsTools.time10to13(data.beforeEndTime, 1);
+      data.status = 0;
+      data.applyId = this.applyId;
+      if (data.beforeId) {
+        this.$api
+          .editsystembefore(data)
+          .then((res) => {
+            this.$message.success("修改成功");
+            this.dialogVisible = false;
+            this.$store.commit("BEFORELIST");
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      } else {
+        this.$api
+          .appsystembefore(data)
+          .then((res) => {
+            this.$message.success("设置成功");
+            this.dialogVisible = false;
+            this.$store.commit("BEFORELIST");
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 267 - 0
src/views/education/examManagement/examArrangement/applicableProducts/downMaterial.vue

@@ -0,0 +1,267 @@
+<template>
+  <div id="downMaterial">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="610px"
+      :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="dialogVisible = false"
+          />
+        </div>
+      </div>
+      <div>
+        <p>
+          考试地点:<el-select
+            v-model="listData.siteId"
+            placeholder="请选择考试地点"
+            @change="getOptionsTime"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.siteId"
+              :label="item.siteAddress"
+              :value="item.siteId"
+            >
+            </el-option>
+          </el-select>
+        </p>
+        <p v-if="listData.siteId && optionsTime.length > 0">
+          考试日期:<el-select
+            v-model="listData.applySiteExamTime"
+            placeholder="请选择考试日期"
+            @change="getOptionsChildrenTime"
+          >
+            <el-option
+              v-for="item in optionsTime"
+              :key="item.examTime"
+              :label="$methodsTools.onlyForma(item.examTime, false)"
+              :value="item.examTime"
+            >
+            </el-option>
+          </el-select>
+          <el-select
+            style="margin-left: 14px"
+            v-if="
+              listData.siteId &&
+              optionsTime.length > 0 &&
+              optionsTimeChildren.length > 0
+            "
+            v-model="listData.index"
+            placeholder="请选择考试时间段"
+            @change="getSizeTime"
+          >
+            <el-option
+              v-for="(item, index) in optionsTimeChildren"
+              :key="index"
+              :label="item.startTime + ' - ' + item.endTime"
+              :value="item.index"
+            >
+            </el-option>
+          </el-select>
+        </p>
+        <p>
+          学员信息表 <el-button type="text" @click="userDowm">下载</el-button>
+        </p>
+        <p>
+          疫情防控承诺书
+          <el-button type="text" @click="yqbookDown">下载</el-button>
+        </p>
+        <p>
+          学员签到表 <el-button type="text" @click="userSign">下载</el-button>
+        </p>
+        <p>考场视频 <el-button type="text">下载</el-button></p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import * as baseUrls from "@/utils/request.js";
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      listData: {
+        applyId: "",
+        siteId: "",
+        applySiteExamTime: "",
+        applySiteStartTime: "",
+        applySiteEndTime: "",
+        index: "",
+      },
+      options: [],
+      optionsTime: [],
+      optionsTimeChildren: [],
+    };
+  },
+  methods: {
+    //地点
+    getOptionsTime(v) {
+      this.listData.applySiteExamTime = "";
+      this.listData.applySiteStartTime = "";
+      this.listData.applySiteEndTime = "";
+      this.listData.index = "";
+      for (let i = 0; i < this.options.length; i++) {
+        if ((this.options[i].applyId = v)) {
+          this.optionsTime = this.options[i].examApplySiteTime;
+          break;
+        }
+      }
+    },
+    //日期
+    getOptionsChildrenTime(v) {
+      this.listData.applySiteStartTime = "";
+      this.listData.applySiteEndTime = "";
+      this.listData.index = "";
+      for (let i = 0; i < this.optionsTime.length; i++) {
+        if ((this.optionsTime[i].applySiteExamTime = v)) {
+          let time = JSON.parse(this.optionsTime[i].siteTime);
+          for (let j = 0; j < time.length; j++) {
+            time[j].index = j + 1;
+          }
+          this.optionsTimeChildren = time;
+          break;
+        }
+      }
+    },
+    //时间段
+    getSizeTime(v) {
+      for (let i = 0; i < this.optionsTimeChildren.length; i++) {
+        if (this.optionsTimeChildren[i].index === v) {
+          this.listData.applySiteStartTime =
+            this.optionsTimeChildren[i].startTime;
+          this.listData.applySiteEndTime = this.optionsTimeChildren[i].endTime;
+          break;
+        }
+      }
+    },
+    //学员信息表
+    userDowm() {
+      var data = JSON.parse(JSON.stringify(this.listData));
+      delete data.index;
+      this.$api
+        .inquiresystemsubscribelistUserExport(data)
+        .then(async (res) => {
+          for (let k in res.data) {
+            if (res.data[k].code === 200) {
+              await this.dowmFunc(res, k);
+            } else {
+              this.$message.error("code值错误:", res.data[k].code);
+            }
+          }
+        })
+        .catch((err) => {
+          let { message } = err;
+          if (message.includes("timeout")) {
+            this.$message.error(
+              "数据体量过大,无法正常导出,请调整导出的日期范围,缩小数据体量"
+            );
+          }
+        });
+    },
+    dowmFunc(res, k) {
+      return new Promise((resolve, reject) => {
+        let url =
+          baseUrls.baseURL + "common/download?fileName=" + res.data[k].msg;
+        let link = document.createElement("a");
+        let fileName = "导入模板" + ".xlsx";
+        document.body.appendChild(link);
+        link.href = url;
+        link.dowmload = fileName;
+        link.click();
+        link.remove();
+        setTimeout(() => {
+          resolve();
+        }, 200);
+      });
+    },
+    //学员签到表
+    userSign() {
+      var data = JSON.parse(JSON.stringify(this.listData));
+      delete data.index;
+      this.$api
+        .inquiresystemsubscribelistSignExport(data)
+        .then(async (res) => {
+          for (let k in res.data) {
+            if (res.data[k].code === 200) {
+              await this.dowmFunc(res, k);
+            } else {
+              this.$message.error("code值错误:", res.data[k].code);
+            }
+          }
+        })
+        .catch((err) => {
+          let { message } = err;
+          if (message.includes("timeout")) {
+            this.$message.error(
+              "数据体量过大,无法正常导出,请调整导出的日期范围,缩小数据体量"
+            );
+          }
+        });
+    },
+    //疫情防控承诺书
+    yqbookDown() {
+      var data = JSON.parse(JSON.stringify(this.listData));
+      delete data.index;
+      this.$api
+        .inquiresystemsubscribelistLetterExport(data)
+        .then(async (res) => {
+          for (let k in res.data) {
+            if (res.data[k].code === 200) {
+              await this.dowmFunc(res, k);
+            } else {
+              this.$message.error("code值错误:", res.data[k].code);
+            }
+          }
+        })
+        .catch((err) => {
+          let { message } = err;
+          if (message.includes("timeout")) {
+            this.$message.error(
+              "数据体量过大,无法正常导出,请调整导出的日期范围,缩小数据体量"
+            );
+          }
+        });
+    },
+    openBox(row) {
+      this.listData = {
+        applyId: row.applyId,
+        siteId: "",
+        applySiteExamTime: "",
+        applySiteStartTime: "",
+        applySiteEndTime: "",
+        index: "",
+      };
+      this.getAddress();
+      this.dialogVisible = true;
+    },
+    getAddress() {
+      this.$api
+        .inquirepayservesiteInfo({
+          addressStatus: 1,
+          applyId: this.listData.applyId,
+        })
+        .then((res) => {
+          res.rows.forEach((item) => {
+            item.examApplySiteTime.forEach((items) => {
+              // items.examTime = this.$methodsTools.time10to13(items.examTime, 2);
+              items.examApplySiteTimeTwo = JSON.parse(items.siteTime);
+            });
+          });
+          this.options = res.rows;
+          console.log(res.rows, "res.rows");
+        });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 188 - 17
src/views/education/examManagement/examArrangement/index.vue

@@ -14,6 +14,9 @@
         >
       </template>
       <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="beforeFunc(props.scope.row)"
+          >前培设置</el-button
+        >
         <el-button
           type="text"
           @click="addClick(props.scope.row, 0)"
@@ -39,6 +42,23 @@
           >适用商品</el-button
         >
         <el-button type="text" @click="watchs(props.scope.row)">预览</el-button>
+        <el-button type="text" @click="downMaterial(props.scope.row)"
+          >下载资料</el-button
+        >
+        <el-button
+          type="text"
+          @click="syncUser(props.scope.row)"
+          v-if="props.scope.row.wisdomNum > 0"
+          :disabled="sysTime < props.scope.row.applyEndTime"
+          >同步考场信息</el-button
+        >
+        <el-button
+          type="text"
+          @click="syncExam(props.scope.row)"
+          v-if="props.scope.row.wisdomNum > 0"
+          :disabled="sysTime < props.scope.row.applyEndTime"
+          >同步信息到考场</el-button
+        >
         <el-button
           type="text"
           @click="del(props.scope.row, 1)"
@@ -79,7 +99,7 @@
       <div>
         <el-form
           label-position="right"
-          label-width="150px"
+          label-width="180px"
           :model="listData"
           :rules="rules"
           ref="listData"
@@ -163,6 +183,12 @@
               </el-form-item>
             </el-col>
           </el-form-item>
+          <el-form-item label="线上签署疫情防控承诺书" prop="reportStatus">
+            <el-radio-group v-model="listData.reportStatus">
+              <el-radio :label="1">是</el-radio>
+              <el-radio :label="0">否</el-radio>
+            </el-radio-group>
+          </el-form-item>
         </el-form>
       </div>
       <span slot="footer" class="dialog-footer">
@@ -202,13 +228,25 @@
         </div>
       </div>
       <div>
-        <el-button type="text" @click="openExamPlace">{{
-          intStatus === 1
-            ? "添加考试地点"
-            : intStatus === 2
-            ? "添加考前培训地点"
-            : "未知"
-        }}</el-button>
+        <div>
+          <span>考试地点来源:</span
+          ><el-radio-group v-model="radioAddress" @change="clearPlaceData">
+            <el-radio :label="2">智慧考场</el-radio>
+            <el-radio :label="1">云学堂</el-radio>
+          </el-radio-group>
+        </div>
+        <el-button
+          type="text"
+          @click="openExamPlace"
+          :disabled="radioAddress > 0 ? false : true"
+          >{{
+            intStatus === 1
+              ? "添加考试地点"
+              : intStatus === 2
+              ? "添加考前培训地点"
+              : "未知"
+          }}</el-button
+        >
         <div
           v-for="(item, index) in examPlaces"
           :key="index"
@@ -429,7 +467,6 @@
         >
       </span>
     </el-dialog>
-
     <el-dialog
       :visible.sync="dialoginfoWatch"
       width="900px"
@@ -546,9 +583,13 @@
                 >适用商品</el-button
               >
               <el-form-item label="商品类型:">
-                <span v-for="(item, index) in $methodsTools.getGoodsType()" :key="index">{{
-                  item.value === infoData.goodsType ? item.label : ""
-                }}</span>
+                <span
+                  v-for="(item, index) in $methodsTools.getGoodsType()"
+                  :key="index"
+                  >{{
+                    item.value === infoData.goodsType ? item.label : ""
+                  }}</span
+                >
               </el-form-item>
               <el-form-item label="业务层级:">
                 <span
@@ -576,7 +617,37 @@
         <el-button @click="dialoginfoWatch = false">取 消</el-button>
       </span>
     </el-dialog>
+    <el-dialog
+      :visible.sync="dialogExamSync"
+      width="460px"
+      :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="dialogExamSync = false"
+          />
+        </div>
+      </div>
+      <div>
+        <p>总共:{{ syncData.total }}条数据</p>
+        <p>成功:{{ syncData.success }}条数据</p>
+        <p>
+          失败:{{ syncData.fail }}条数据
+          <el-button type="text" @click="watchSyncPeople">查看</el-button>
+        </p>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogExamSync = false">取 消</el-button>
+      </span>
+    </el-dialog>
+    <before-page ref="beforePage" />
     <applicable-products ref="applicableProducts" />
+    <downMaterial ref="downMaterial" />
   </div>
 </template>
 
@@ -585,11 +656,27 @@ import searchBox from "@/components/searchBox";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
 import applicableProducts from "./applicableProducts/index.vue";
+import beforePage from "./applicableProducts/beforePage.vue";
+import downMaterial from "./applicableProducts/downMaterial.vue";
 export default {
   name: "ExamArrangement",
-  components: { searchBox, tableList, pagination, applicableProducts },
+  components: {
+    searchBox,
+    tableList,
+    pagination,
+    applicableProducts,
+    beforePage,
+    downMaterial,
+  },
   data() {
     return {
+      dialogExamSync: false, //同步信息到考场
+      syncData: {
+        total: 0,
+        success: 0,
+        fail: 0,
+      }, //同步信息到考场
+      radioAddress: "", //考试地点来源
       disabledBtn: false,
       total2: 0,
       pageSize2: 10,
@@ -652,6 +739,7 @@ export default {
       //   弹窗数据
       listData: {
         applyStatus: [],
+        reportStatus: 1,
       },
       statusPop: -1,
       dialogVisible: false,
@@ -691,6 +779,13 @@ export default {
             trigger: "change",
           },
         ],
+        reportStatus: [
+          {
+            required: true,
+            message: "请选择线上签署疫情防控承诺书",
+            trigger: "change",
+          },
+        ],
       },
       dialogExamBoxs: false, //考点
       dialogExamPlace: false, //考试地点列表
@@ -745,17 +840,79 @@ export default {
       infoData: {
         applyStatus: [],
       },
+      sysTime: 0,
     };
   },
   mounted() {
+    this.sysTime = new Date().getTime() / 1000;
     this.search();
-    this.getExamPlace();
   },
   activated() {
+    this.sysTime = new Date().getTime() / 1000;
     this.search();
-    this.getExamPlace();
   },
   methods: {
+    //下载资料
+    downMaterial(row) {
+      this.$refs.downMaterial.openBox(row);
+    },
+    //同步考场信息
+    syncUser(row) {
+      this.$api
+        .appcommonwisdomSyncExamStatus({ applyId: row.applyId })
+        .then((res) => {
+          this.$message.success("同步成功");
+        });
+    },
+    //同步信息到考场
+    syncExam(row) {
+      this.$api
+        .appcommonwsyncApplyUserInfo({ applyId: row.applyId })
+        .then((res) => {
+          if (res.data && res.data.total) {
+            res.data.applyId = row.applyId;
+            this.syncData = res.data;
+            this.dialogExamSync = true;
+          } else {
+            this.$message.error("没有学员推送");
+          }
+        });
+    },
+    //查看失败学员-跳转
+    watchSyncPeople() {
+      const jump = () => {
+        this.dialogExamSync = false;
+        this.$router.push({
+          name: "ApplicationData",
+          params: {
+            id: this.syncData.applyId,
+            type: 3,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "ApplicationData";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "ApplicationData",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    /**
+     * 前培设置
+     */
+    beforeFunc(row) {
+      this.$refs.beforePage.openBox(row);
+    },
     setExamAdress() {
       this.$router.push({
         path: "examPlace",
@@ -918,8 +1075,15 @@ export default {
       this.examPlaces = this.examPlaces.concat(array);
       this.dialogExamPlace = false;
     },
+    /**
+     * 清空考场信息
+     */
+    clearPlaceData() {
+      this.examPlaces = [];
+    },
     getExamPlace() {
       var data = {
+        fromPlat: this.radioAddress,
         status: 1,
         pageSize: this.pageSize2,
         pageNum: this.currentPage2,
@@ -934,6 +1098,7 @@ export default {
       this.examPlaces.forEach((item) => {
         this.activeListExamPlace.push(item.siteId);
       });
+      this.getExamPlace();
       this.dialogExamPlace = true;
       this.$nextTick(function () {
         this.activeLists = [];
@@ -953,6 +1118,11 @@ export default {
               items.examApplySiteTimeTwo = JSON.parse(items.siteTime);
             });
           });
+          if (res.rows.length) {
+            this.radioAddress = res.rows[0].fromPlat;
+          } else {
+            this.radioAddress = 2;
+          }
           this.examPlaces = res.rows;
           this.dialogExamBoxs = true;
         });
@@ -1137,6 +1307,7 @@ export default {
         this.statusPop = 1;
         this.listData = {
           applyStatus: [],
+          reportStatus: 1,
           applyUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
         };
         this.$nextTick(() => {
@@ -1148,8 +1319,8 @@ export default {
         this.$api.obtainsystemapply(v.applyId).then((res) => {
           if (res.data.applyStatus) {
             res.data.applyStatus = res.data.applyStatus.split(",").map(Number);
-          }else{
-            res.data.applyStatus = []
+          } else {
+            res.data.applyStatus = [];
           }
           if (res.data.applyStartTime) {
             res.data.applyStartTime = this.$methodsTools.time10to13(

+ 37 - 2
src/views/education/examManagement/examConfiguration/examPlace/index.vue

@@ -8,11 +8,24 @@
       :loading="loading"
       @editInfo="editInfo"
     >
+      <template slot="customize">
+        <el-button size="medium" type="warning" @click="Synchronize"
+          >同步智慧考场</el-button
+        >
+      </template>
       <template slot="btn" slot-scope="props">
-        <el-button type="text" @click="addClick(props.scope.row, 0)"
+        <el-button
+          type="text"
+          @click="addClick(props.scope.row, 0)"
+          v-if="props.scope.row.fromPlat === 1"
           >修改</el-button
         >
-        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+        <el-button
+          type="text"
+          @click="del(props.scope.row)"
+          v-if="props.scope.row.fromPlat === 1"
+          >删除</el-button
+        >
       </template>
     </table-list>
     <pagination
@@ -124,6 +137,22 @@ export default {
           prop: "code",
           hidden: true,
         },
+        {
+          label: "来源",
+          prop: "fromPlat",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "云学堂",
+              value: 1,
+            },
+            {
+              label: "智慧考场",
+              value: 2,
+            },
+          ],
+        },
         {
           label: "考试地点",
           prop: "siteAddress",
@@ -199,6 +228,12 @@ export default {
     this.search();
   },
   methods: {
+    Synchronize() {
+      this.$api.appcommonsyncExamSite().then((res) => {
+        this.$message.success("同步成功");
+        this.search()
+      });
+    },
     loadingClose() {
       this.disabledBtn = false;
     },

+ 238 - 0
src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/curriculumDimension.vue

@@ -0,0 +1,238 @@
+<template>
+  <div id="curriculumDimension">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+      ><template slot="customize">
+        <el-button size="small" type="success" @click="moreActive"
+          >批量导出</el-button
+        >
+      </template></search-box-new
+    >
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="doList(props.scope.row)">详情</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import * as baseUrls from "@/utils/request.js";
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "课程维度列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop: "sectionName",
+          placeholder: "课程名称",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "课程名称",
+          prop: "sectionName",
+          hidden: true,
+        },
+        {
+          label: "课程状态",
+          prop: "watchStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "直播中",
+              value: "live",
+            },
+            {
+              label: "直播结束",
+              value: "end",
+            },
+            {
+              label: "回放中",
+              value: "playback",
+            },
+            {
+              label: "等待直播",
+              value: "waiting",
+            },
+          ],
+        },
+        {
+          label: "直播开始时间",
+          prop: "liveStartTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "直播结束时间",
+          prop: "liveEndTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "观看人数",
+          prop: "watchNumber",
+          hidden: true,
+        },
+        {
+          label: "开通课程人数",
+          prop: "buyCourseNumber",
+          hidden: true,
+        },
+        {
+          label: "未开通课程人数",
+          prop: "unBuyCourseNumber",
+          hidden: true,
+        },
+        {
+          label: "小程序观看人数",
+          prop: "appWatchNumber",
+          hidden: true,
+        },
+        {
+          label: "PC观看人数",
+          prop: "adminWatchNumber",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      id: "",
+    };
+  },
+  mounted() {
+    this.id = this.$route.query.id;
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    moreActive() {
+      let arr = JSON.parse(JSON.stringify(this.formData));
+      arr.goodsId = this.id;
+      this.$api.inquireCoursestatementexport(arr).then((res) => {
+        if (res.msg) {
+          let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
+          let link = document.createElement("a");
+          let fileName = "导出直播数据" + ".xlsx";
+          document.body.appendChild(link);
+          link.href = url;
+          link.dowmload = fileName;
+          link.click();
+          link.remove();
+          this.$message.success("导出成功");
+        } else {
+          this.$message.error("导出失败");
+        }
+      });
+    },
+    doList(row) {
+      const jump = () => {
+        this.$router.push({
+          path: "curriculumDimensionData",
+          query: {
+            goodsId: row.goodsId,
+            sectionId: row.sectionId,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "CurriculumDimensionData";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "CurriculumDimensionData",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      data.goodsId = this.id;
+      this.$api
+        .inquireCoursestatement(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 266 - 0
src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/curriculumDimensionData/index.vue

@@ -0,0 +1,266 @@
+<template>
+  <div id="curriculumDimensionData">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    ><template slot="customize">
+        <el-button size="small" type="success" @click="moreActive"
+          >批量导出</el-button
+        >
+      </template></search-box-new>
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="doList(props.scope.row)"
+          >观看记录</el-button
+        >
+        <el-button type="text" @click="studentInfoPage(props.scope.row)"
+          >会员详情</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <infoBox ref="infoBox" />
+  </div>
+</template>
+
+<script>
+import * as baseUrls from "@/utils/request.js";
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import infoBox from "./infoBox.vue";
+export default {
+  components: { searchBoxNew, tableList, pagination, infoBox },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: `观看直播学员数`,
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop: "userName",
+          placeholder: "学员姓名",
+        },
+        {
+          prop: "idCard",
+          placeholder: "学员身份证",
+        },
+        {
+          prop: "phone",
+          placeholder: "学员电话",
+        },
+        {
+          prop: "purchaseStatus",
+          placeholder: "开课状态",
+          scope: "select",
+          options: [
+            {
+              label: "已开课",
+              value: "1",
+            },
+            {
+              label: "未开课",
+              value: "0",
+            },
+          ],
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "学员姓名",
+          prop: "userName",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "学员电话",
+          prop: "phone",
+          hidden: true,
+        },
+        {
+          label: "开课状态",
+          prop: "purchaseStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "已开课",
+              value: 1,
+            },
+            {
+              label: "未开课",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "直播累计时长",
+          prop: "liveDuration",
+          hidden: true,
+          scope: "convert",
+        },
+        {
+          label: "观看直播累计时长",
+          prop: "watchLiveDuration",
+          hidden: true,
+          scope: "convert",
+        },
+        {
+          label: "观看次数",
+          prop: "watchNumber",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      goodsId: "",
+      sectionId: "",
+    };
+  },
+  mounted() {
+    this.goodsId = this.$route.query.goodsId;
+    this.sectionId = this.$route.query.sectionId;
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    moreActive() {
+      let arr = JSON.parse(JSON.stringify(this.formData));
+      arr.goodsId = this.goodsId;
+      arr.sectionId = this.sectionId;
+      this.$api.inquireCoursestatementstatisticsexport(arr).then((res) => {
+        if (res.msg) {
+          let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
+          let link = document.createElement("a");
+          let fileName = "导出直播数据" + ".xlsx";
+          document.body.appendChild(link);
+          link.href = url;
+          link.dowmload = fileName;
+          link.click();
+          link.remove();
+          this.$message.success("导出成功");
+        } else {
+          this.$message.error("导出失败");
+        }
+      });
+    },
+    /**
+     * 会员详情页
+     */
+    studentInfoPage(v) {
+      const jump = () => {
+        //学员详情
+        this.$router.push({
+          name: "StudentXQ",
+          query: {
+            id: v.userId,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "StudentXQ";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "StudentXQ",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    /**
+     * 查看详情
+     */
+    doList(row) {
+      this.$refs.infoBox.openBox({
+        goodsId: this.goodsId,
+        sectionId: this.sectionId,
+        userId: row.userId,
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      data.goodsId = this.goodsId;
+      data.sectionId = this.sectionId;
+      this.$api
+        .inquireCoursedetailstatistics(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 219 - 0
src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/curriculumDimensionData/infoBox.vue

@@ -0,0 +1,219 @@
+<template>
+  <div id="infoBox">
+    <el-dialog
+      :visible.sync="dialogVisibleTableBoxs"
+      width="1100px"
+      :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="dialogVisibleTableBoxs = false"
+          />
+        </div>
+      </div>
+      <el-table
+        ref="multipleTable"
+        :data="tableData"
+        border
+        :header-cell-style="{
+          'background-color': '#eee',
+          padding: '8px',
+          color: '#333',
+        }"
+        max-height="600"
+      >
+        <el-table-column
+          label="序号"
+          type="index"
+          width="80"
+          align="center"
+          header-align="center"
+        >
+        </el-table-column>
+        <template v-for="(item, index) in tableSet">
+          <el-table-column
+            v-if="item.scope !== 'inputs'"
+            :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 === 'Date'">
+                {{ $methodsTools.onlyForma(scope.row[item.prop]) }}
+              </span>
+              <span v-else-if="item.scope === 'time'">
+                {{ $methodsTools.secondToDate(scope.row[item.prop], false) }}
+              </span>
+              <span v-else-if="item.scope === 'Type'">
+                {{
+                  scope.row[item.prop] === 1
+                    ? "录播"
+                    : scope.row[item.prop] === 2
+                    ? "直播"
+                    : scope.row[item.prop] === 3
+                    ? "回放"
+                    : ""
+                }}
+              </span>
+              <span v-else-if="item.scope === 'Plat'">
+                {{
+                  scope.row[item.prop] === "1"
+                    ? "小程序"
+                    : scope.row[item.prop] === "2"
+                    ? "PC端"
+                    : ""
+                }}
+              </span>
+              <span v-else>{{ scope.row[item.prop] }}</span></template
+            >
+          </el-table-column></template
+        >
+      </el-table>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisibleTableBoxs = false">取 消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      size: "small",
+      dialogVisibleTableBoxs: false,
+      tableData: [],
+      tableSet: [
+        { label: "进入时间", prop: "startTime", scope: "Date" },
+        {
+          label: "离开时间",
+          prop: "endTime",
+          scope: "Date",
+        },
+        { label: "观看时长", prop: "watchLiveDuration", scope: "time" },
+        { label: "观看类型", prop: "sectionType", scope: "Type" },
+        { label: "观看终端", prop: "fromPlat", scope: "Plat" },
+      ],
+      formData: {},
+    };
+  },
+  methods: {
+    /**
+     * 初始
+     */
+    openBox(obj) {
+      this.formData = JSON.parse(JSON.stringify(obj));
+      this.getInfos();
+      this.dialogVisibleTableBoxs = true;
+    },
+    /**
+     * 搜索数据
+     */
+    getInfos(int) {
+      this.$api.inquireCourseuserwatch(this.formData).then((res) => {
+        this.tableData = res.data;
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 12 - 193
src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/index.vue

@@ -1,208 +1,27 @@
 <template>
   <div id="liveLearningRecord">
-    <search-box-new
-      ref="searchBox"
-      :formData="formData"
-      :formList="formList"
-      @search="search"
-      @init="init"
-      ><template slot="customize">
-        <el-button size="small" type="success" @click="moreActive"
-          >批量导出</el-button
-        >
-      </template></search-box-new
-    >
-    <table-list
-      :tableSets="tableSet"
-      :tableData="tableData"
-      :navText="navText"
-      :loading="loading"
-    >
-      <template slot="btn" slot-scope="props">
-        <el-button type="text" @click="doList(props.scope.row)"
-          >学员观看直播数据</el-button
-        >
-      </template>
-    </table-list>
-    <pagination
-      :total="total"
-      :pageSize="formData.pageSize"
-      :currentPage="formData.pageNum"
-      @handleSizeChange="handleSizeChange"
-      @handleCurrentChange="handleCurrentChange"
-    />
+    <el-tabs v-model="activeName" type="card">
+      <el-tab-pane lazy label="课程维度" name="first">
+        <curriculumDimension />
+      </el-tab-pane>
+      <el-tab-pane lazy label="学员维度" name="second">
+        <studentDimension />
+      </el-tab-pane>
+    </el-tabs>
   </div>
 </template>
 
 <script>
-import * as baseUrls from "@/utils/request.js";
-import searchBoxNew from "@/components/searchBoxNew";
-import tableList from "@/components/tableList";
-import pagination from "@/components/pagination";
+import curriculumDimension from "./curriculumDimension.vue";
+import studentDimension from "./studentDimension.vue";
 export default {
-  components: { searchBoxNew, tableList, pagination },
+  components: { curriculumDimension, studentDimension },
   data() {
     return {
-      loading: false, //当前表单加载是否加载动画
-      navText: {
-        title: "学员学习列表",
-        index: 0,
-        ch: "条",
-        num: false,
-        border: true,
-        choice: true,
-        addHide: true,
-        backFatherBtn: {
-          status: false,
-          title: "未定义",
-        },
-      },
-      //搜索
-      formList: [
-        {
-          prop: "searchKey",
-          placeholder: "请输入学员姓名/学员身份证",
-        },
-      ],
-      formData: {
-        pageSize: 10,
-        pageNum: 1,
-      },
-      // 表单
-      tableSet: [
-        {
-          label: "学员姓名",
-          prop: "realname",
-          hidden: true,
-        },
-        {
-          label: "学员身份证",
-          prop: "idCard",
-          hidden: true,
-        },
-        {
-          label: "直播累计时长",
-          prop: "liveTime",
-          hidden: true,
-          scope: "convert",
-        },
-        {
-          label: "观看直播累计时长",
-          prop: "seeTime",
-          hidden: true,
-          scope: "convert",
-        },
-        {
-          label: "课程总直播次数",
-          prop: "totalLiveNum",
-          hidden: true,
-        },
-        {
-          label: "课程已直播次数",
-          prop: "overLiveNum",
-          hidden: true,
-        },
-        {
-          label: "已参加直播次数",
-          prop: "joinLiveNum",
-          hidden: true,
-        },
-      ],
-      tableData: [], //表单数据
-      total: 0, //一共多少条
-      id: "",
+      activeName: "first",
     };
   },
-  mounted() {
-    this.id = this.$route.query.id;
-    this.search();
-  },
-  activated() {
-    this.search();
-  },
   methods: {
-    moreActive() {
-      let arr = JSON.parse(JSON.stringify(this.formData));
-      arr.goodsId = this.id;
-      this.$api.inquireOrderGoodsexport_listLiveGoodsList(arr).then((res) => {
-        if (res.msg) {
-          let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
-          let link = document.createElement("a");
-          let fileName = "导出直播数据" + ".xlsx";
-          document.body.appendChild(link);
-          link.href = url;
-          link.dowmload = fileName;
-          link.click();
-          link.remove();
-          this.$message.success("导出成功");
-        } else {
-          this.$message.error("导出失败");
-        }
-      });
-    },
-    doList(row) {
-      const jump = () => {
-        this.$router.push({
-          path: "watchLiveData",
-          query: {
-            orderGoodsId: row.orderGoodsId,
-            realname: row.realname,
-          },
-        });
-      };
-      const statusPage = this.$store.state.tagsView.visitedViews.some(
-        (item) => {
-          return item.name == "WatchLiveData";
-        }
-      );
-      if (statusPage) {
-        this.$store
-          .dispatch("tagsView/delCachedView", {
-            name: "WatchLiveData",
-          })
-          .then((res) => {
-            jump();
-          });
-      } else {
-        jump();
-      }
-    },
-    search(int) {
-      this.loading = true;
-      if (int === 1) {
-        this.formData.pageNum = 1;
-      }
-      if (int === 2) {
-        this.formData = {
-          pageSize: 10,
-          pageNum: 1,
-        };
-      }
-      var data = JSON.parse(JSON.stringify(this.formData));
-      data.goodsId = this.id;
-      this.$api
-        .inquireOrderGoodsBuyLiveGoodsList(data)
-        .then((res) => {
-          this.tableData = res.rows;
-          this.total = res.total;
-          this.navText.index = res.total;
-        })
-        .finally(() => {
-          this.loading = false;
-        });
-    },
-    init() {
-      this.search(2);
-    },
-    handleSizeChange(v) {
-      this.formData.pageSize = v;
-      this.formData.pageNum = 1;
-      this.search();
-    },
-    handleCurrentChange(v) {
-      this.formData.pageNum = v;
-      this.search();
-    },
   },
 };
 </script>

+ 211 - 0
src/views/education/liveLearningManagement/liveLearningRecord/studentStyleList/studentDimension.vue

@@ -0,0 +1,211 @@
+<template>
+  <div id="studentDimension">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+      ><template slot="customize">
+        <el-button size="small" type="success" @click="moreActive"
+          >批量导出</el-button
+        >
+      </template></search-box-new
+    >
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="doList(props.scope.row)"
+          >学员观看直播数据</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import * as baseUrls from "@/utils/request.js";
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+    components:{ searchBoxNew, tableList, pagination },
+  data() {
+    return {
+        loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "学员维度列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop: "searchKey",
+          placeholder: "请输入学员姓名/学员身份证",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "学员姓名",
+          prop: "realname",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "直播累计时长",
+          prop: "liveTime",
+          hidden: true,
+          scope: "convert",
+        },
+        {
+          label: "观看直播累计时长",
+          prop: "seeTime",
+          hidden: true,
+          scope: "convert",
+        },
+        {
+          label: "课程总直播次数",
+          prop: "totalLiveNum",
+          hidden: true,
+        },
+        {
+          label: "课程已直播次数",
+          prop: "overLiveNum",
+          hidden: true,
+        },
+        {
+          label: "已参加直播次数",
+          prop: "joinLiveNum",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      id: "",
+    };
+  },
+  mounted() {
+    this.id = this.$route.query.id;
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    moreActive() {
+      let arr = JSON.parse(JSON.stringify(this.formData));
+      arr.goodsId = this.id;
+      this.$api.inquireOrderGoodsexport_listLiveGoodsList(arr).then((res) => {
+        if (res.msg) {
+          let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
+          let link = document.createElement("a");
+          let fileName = "导出直播数据" + ".xlsx";
+          document.body.appendChild(link);
+          link.href = url;
+          link.dowmload = fileName;
+          link.click();
+          link.remove();
+          this.$message.success("导出成功");
+        } else {
+          this.$message.error("导出失败");
+        }
+      });
+    },
+    doList(row) {
+      const jump = () => {
+        this.$router.push({
+          path: "watchLiveData",
+          query: {
+            orderGoodsId: row.orderGoodsId,
+            realname: row.realname,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "WatchLiveData";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "WatchLiveData",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      data.goodsId = this.id;
+      this.$api
+        .inquireOrderGoodsBuyLiveGoodsList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 527 - 0
src/views/education/marketingCampaignManageMent/marketingActivitiesList/index.vue

@@ -0,0 +1,527 @@
+<template>
+  <div id="marketingActivitiesList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="customize">
+        <el-button size="medium" type="success" @click="allClick"
+          >新增活动</el-button
+        >
+      </template>
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="reply(props.scope.row)">修改</el-button>
+        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+        <el-button type="text" @click="openCode(props.scope.row)"
+          >二维码</el-button
+        >
+        <el-button type="text" @click="userBoxsOpen(props.scope.row)"
+          >报名情况</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="610px"
+      :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="closeBZ" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="150px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item label="活动名称" prop="name">
+            <el-input v-model="listData.name"></el-input>
+          </el-form-item>
+          <el-form-item label="活动科目(多个科目使用逗号','隔开)" prop="majors">
+            <el-input v-model="listData.majors"></el-input>
+          </el-form-item>
+          <el-form-item label="活动开始时间" prop="startTime"
+            ><el-date-picker
+              type="datetime"
+              placeholder="开始日期"
+              @change="changeEndTime(1)"
+              v-model="listData.startTime"
+              style="width: 100%"
+              value-format="timestamp"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item label="活动结束时间" prop="endTime">
+            <el-date-picker
+              type="datetime"
+              placeholder="开始日期"
+              @change="changeEndTime(2)"
+              v-model="listData.endTime"
+              style="width: 100%"
+              value-format="timestamp"
+            ></el-date-picker>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="closeBZ">取 消</el-button>
+        <el-button @click="submitForm('listData')">确 定</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="dialogVisibleCode"
+      width="610px"
+      :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="dialogVisibleCode = false"
+          />
+        </div>
+      </div>
+      <div style="text-align: center">
+        <img style="max-width: 420px" :src="baseImgCode" alt="" />
+        <div style="margin-top: 16px">
+          <el-button size="small" type="success" @click="downCode"
+            >下载二维码</el-button
+          >
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisibleCode = false">取 消</el-button>
+      </span>
+    </el-dialog>
+    <userBoxs ref="userBoxs" />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import userBoxs from "./userBoxs.vue";
+export default {
+  name: "MarketingActivitiesList",
+  components: { searchBoxNew, tableList, pagination, userBoxs },
+  data() {
+    return {
+      baseImgCode: "",
+      dialogVisibleCode: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "营销活动",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        changeWidth: "240px",
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop: "name",
+          placeholder: "请输入活动名称",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+        status: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "活动名称",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "科目",
+          prop: "majors",
+          hidden: true,
+        },
+        {
+          label: "活动开始时间",
+          prop: "startTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "活动结束时间",
+          prop: "endTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "创建人",
+          prop: "creatorName",
+          hidden: true,
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      listData: {
+        name: "",
+        majors: "",
+        startTime: "",
+        endTime: "",
+      },
+      rules: {
+        name: [{ required: true, message: "请输入活动名称", trigger: "blur" }],
+        majors: [{ required: true, message: "请输入科目", trigger: "blur" }],
+        startTime: [
+          {
+            type: "date",
+            required: true,
+            message: "请选择活动开始时间",
+            trigger: "change",
+          },
+        ],
+        endTime: [
+          {
+            type: "date",
+            required: true,
+            message: "请选择活动结束时间",
+            trigger: "change",
+          },
+        ],
+      },
+      listPop: 1, //1新增2修改
+      dialogVisible: false,
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    //将base64转换为blob
+    dataURLtoBlob(dataurl) {
+      if (!dataurl) {
+        this.$message.error("下载失败");
+        return;
+      }
+      var arr = dataurl.split(","),
+        mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]),
+        n = bstr.length,
+        u8arr = new Uint8Array(n);
+      while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new Blob([u8arr], { type: mime });
+    },
+    //下载方法
+    downloadFile(url, name = "下载图") {
+      var a = document.createElement("a");
+      a.setAttribute("href", url);
+      a.setAttribute("download", name);
+      a.setAttribute("target", "_blank");
+      let clickEvent = document.createEvent("MouseEvents");
+      clickEvent.initEvent("click", true, true);
+      a.dispatchEvent(clickEvent);
+    },
+    //下载二维码
+    downCode() {
+      var base64 = this.baseImgCode;
+      var name = "营销活动小程序二维码";
+      var myBlob = this.dataURLtoBlob(base64);
+      var myUrl = URL.createObjectURL(myBlob);
+      this.downloadFile(myUrl, name);
+    },
+    //打开二维码
+    openCode(row) {
+      this.$api.exportsystemexamactivitycode(row.activityId).then((res) => {
+        console.log(res);
+        this.baseImgCode = res.data;
+        this.dialogVisibleCode = true;
+      });
+    },
+    userBoxsOpen(row) {
+      this.$refs.userBoxs.openBox(row);
+    },
+    changeEndTime(int) {
+      if (this.listData.startTime === this.listData.endTime) {
+        this.$message.warning("开始时间与结束时间不允许相同");
+        if (int === 1) {
+          this.listData.startTime = "";
+        }
+        if (int === 2) {
+          this.listData.endTime = "";
+        }
+        return;
+      }
+      if (
+        int === 1 &&
+        this.listData.endTime &&
+        this.listData.startTime > this.listData.endTime
+      ) {
+        this.$message.warning(
+          "当前选择的开始时间大于结束时间,请重新选择开始时间!"
+        );
+        this.listData.startTime = "";
+        return;
+      }
+      if (
+        int === 2 &&
+        this.listData.startTime &&
+        this.listData.endTime < this.listData.startTime
+      ) {
+        this.$message.warning(
+          "当前选择的结束时间小于开始时间,请重新选择结束时间!"
+        );
+        this.listData.endTime = "";
+        return;
+      }
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+          status: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireSystemexamactivitylist(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    del(v) {
+      this.$alert(
+        "确定删除此内容?<br />内容删除后将无法恢复,请慎重考虑",
+        "提示",
+        {
+          dangerouslyUseHTMLString: true,
+        }
+      )
+        .then(() => {
+          var data = {
+            activityId: v.activityId,
+            status: -1,
+          };
+          this.$api.editSystemexamactivity(data).then((res) => {
+            this.$message.success("删除成功");
+            this.search();
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    reply(item) {
+      this.listPop = 2;
+      this.listData = JSON.parse(JSON.stringify(item));
+      this.listData.startTime = this.listData.startTime * 1000;
+      this.listData.endTime = this.listData.endTime * 1000;
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs["listData"].clearValidate();
+      });
+    },
+    allClick() {
+      this.listPop = 1;
+      this.listData = {
+        name: "",
+        majors: "",
+        startTime: "",
+        endTime: "",
+      };
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs["listData"].clearValidate();
+      });
+    },
+    closeBZ() {
+      this.dialogVisible = false;
+    },
+    /**
+     * 提交-表单验证
+     */
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.submit();
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    submit() {
+      var data = JSON.parse(JSON.stringify(this.listData));
+      data.startTime = data.startTime / 1000;
+      data.endTime = data.endTime / 1000;
+      if (this.listPop === 1) {
+        this.$api.addSystemexamactivity(data).then((res) => {
+          this.$message.success("新增成功");
+          this.search();
+          this.dialogVisible = false;
+        });
+      }
+      if (this.listPop === 2) {
+        this.$api.editSystemexamactivity(data).then((res) => {
+          this.$message.success("修改成功");
+          this.search();
+          this.dialogVisible = false;
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 139 - 0
src/views/education/marketingCampaignManageMent/marketingActivitiesList/userBoxs.vue

@@ -0,0 +1,139 @@
+<template>
+  <div id="userBoxs">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="910px"
+      :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="close" />
+        </div>
+      </div>
+      <div>
+        <div>
+          <el-button type="success" size="small" @click="exportUserList"
+            >导出数据</el-button
+          >
+        </div>
+        <el-table
+          v-loading="loading"
+          border
+          :data="tableData"
+          style="width: 100%; margin-top: 16px"
+          ref="tableList"
+          max-height="800px"
+          ><el-table-column type="index" width="55" label="序号" align="center">
+          </el-table-column>
+          <el-table-column
+            align="center"
+            v-for="(item, index) in tableSet"
+            :key="index"
+            :prop="item.prop"
+            :label="item.label"
+            :width="item.width"
+          >
+            <template slot-scope="scope">
+              <span v-if="item.scope === 'sex'">
+                {{
+                  scope.row[item.prop] === 1
+                    ? "男"
+                    : scope.row[item.prop] === 2
+                    ? "女"
+                    : ""
+                }}
+              </span>
+              <span v-else>{{ scope.row[item.prop] }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import * as baseUrls from "@/utils/request.js";
+export default {
+  data() {
+    return {
+      loading: false,
+      dialogVisible: false,
+      activityId: null, //考试ID
+      tableData: [],
+      tableSet: [
+        {
+          label: "用户名称",
+          prop: "userName",
+        },
+        {
+          label: "用户性别",
+          prop: "userSex",
+          scope: "sex",
+          width: "100px",
+        },
+        {
+          label: "企业名称",
+          prop: "companyName",
+        },
+        {
+          label: "用户身份证号码",
+          prop: "userIdCard",
+        },
+        {
+          label: "用户手机号码",
+          prop: "userPhone",
+        },
+        {
+          label: "报考科目",
+          prop: "userMajors",
+        },
+      ],
+      total: 0,
+    };
+  },
+  methods: {
+    openBox(row) {
+      this.activityId = row.activityId;
+      this.search();
+      this.dialogVisible = true;
+    },
+    search() {
+      this.loading = true;
+      this.$api
+        .inquireSystemexamactivityuserlist(this.activityId)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    exportUserList() {
+      this.$api.exportsystemexamactivity(this.activityId).then((res) => {
+        let url =
+          baseUrls.baseURL + "common/download?fileName=" + res.msg;
+        let link = document.createElement("a");
+        let fileName = "导入模板" + ".xlsx";
+        document.body.appendChild(link);
+        link.href = url;
+        link.dowmload = fileName;
+        link.click();
+        link.remove();
+      });
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 75 - 35
src/views/education/mockTestManagement/mockExamArrangement/addMockExam/index.vue

@@ -51,6 +51,21 @@
           placeholder="请输入模考简介"
         ></el-input>
       </el-form-item>
+      <el-form-item label="是否活动模考" prop="mockActivity">
+        <el-radio-group
+          v-model="listData.mockActivity"
+          :disabled="
+            $refs.infoPage
+              ? $refs.infoPage.infoData.length > 0
+                ? true
+                : false
+              : false
+          "
+        >
+          <el-radio :label="1">是</el-radio>
+          <el-radio :label="0">否</el-radio>
+        </el-radio-group>
+      </el-form-item>
       <el-form-item label="业务层级" prop="educationTypeId">
         <el-select
           v-model="listData.educationTypeId"
@@ -108,7 +123,10 @@
           :newsubjectOption="newsubjectOption"
         />
       </el-form-item>
-      <el-form-item label="预约时间" prop="timeArray">
+      <el-form-item
+        :label="listData.mockActivity === 0 ? '预约时间' : '活动时间'"
+        prop="timeArray"
+      >
         <el-date-picker
           v-model="listData.timeArray"
           type="datetimerange"
@@ -165,6 +183,7 @@ export default {
       listData: {
         applyUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
         status: 1,
+        mockActivity: 0,
       },
       rules: {
         applyName: [
@@ -179,7 +198,7 @@ export default {
         timeArray: [
           {
             required: true,
-            message: "请选择预约时间",
+            message: "请选择时间",
             trigger: ["blur", "change"],
           },
         ],
@@ -256,17 +275,24 @@ export default {
             try {
               this.$refs.infoPage.infoData.forEach((item) => {
                 item.mockMajorSubjectList.forEach((items) => {
-                  const checkSubjectTime = items.mockMajorSubjectTimeList.every(
-                    (time) => {
-                      return time.examTime && time.startTime && time.endTime;
+                  if (this.listData.mockActivity === 0) {
+                    const checkSubjectTime =
+                      items.mockMajorSubjectTimeList.every((time) => {
+                        return time.examTime && time.startTime && time.endTime;
+                      });
+                    if (checkSubjectTime) {
+                      if (!items.examId) {
+                        throw new Error("请检查关联试卷是否关联");
+                      }
+                    } else {
+                      throw new Error("请检查考试日期是否填写");
                     }
-                  );
-                  if (checkSubjectTime) {
-                    if (!items.examId) {
+                  } else if (this.listData.mockActivity === 1) {
+                    if (!items.duration) {
+                      throw new Error("请检查考试时长是否正确");
+                    } else if (!items.examId) {
                       throw new Error("请检查关联试卷是否关联");
                     }
-                  } else {
-                    throw new Error("请检查考试日期是否填写");
                   }
                 });
               });
@@ -290,24 +316,26 @@ export default {
           data.mockMajorList = JSON.parse(
             JSON.stringify(this.$refs.infoPage.infoData)
           );
-          var array = [];
-          data.mockMajorList.forEach((item) => {
-            item.mockMajorSubjectList.forEach((items) => {
-              items.mockMajorSubjectTimeList.forEach((itemTime) => {
-                itemTime.examTime = parseInt(itemTime.examTime / 1000);
-                array.push(
-                  new Date(
-                    this.$methodsTools.onlyForma(itemTime.examTime, false) +
-                      " " +
-                      itemTime.startTime
-                  ).getTime()
-                );
+          if (this.listData.mockActivity === 0) {
+            var array = [];
+            data.mockMajorList.forEach((item) => {
+              item.mockMajorSubjectList.forEach((items) => {
+                items.mockMajorSubjectTimeList.forEach((itemTime) => {
+                  itemTime.examTime = parseInt(itemTime.examTime / 1000);
+                  array.push(
+                    new Date(
+                      this.$methodsTools.onlyForma(itemTime.examTime, false) +
+                        " " +
+                        itemTime.startTime
+                    ).getTime()
+                  );
+                });
               });
             });
-          });
-          array.sort((a, b) => {
-            return a - b;
-          });
+            array.sort((a, b) => {
+              return a - b;
+            });
+          }
           // if (data.timeArray[1] >= array[0]) {
           //   this.$message.error("预约时间需要不得超过考试时间,请重新设置");
           //   this.disabledBtn = false;
@@ -319,15 +347,27 @@ export default {
               break;
             }
           }
-          data.applyStartTime = this.$methodsTools.time10to13(
-            data.timeArray[0],
-            1
-          );
-          data.applyEndTime = this.$methodsTools.time10to13(
-            data.timeArray[1],
-            1
-          );
-          delete data.timeArray;
+          if (data.mockActivity === 0) {
+            data.applyStartTime = this.$methodsTools.time10to13(
+              data.timeArray[0],
+              1
+            );
+            data.applyEndTime = this.$methodsTools.time10to13(
+              data.timeArray[1],
+              1
+            );
+            delete data.timeArray;
+          } else if (data.mockActivity === 1) {
+            data.activityStartTime = this.$methodsTools.time10to13(
+              data.timeArray[0],
+              1
+            );
+            data.activityEndTime = this.$methodsTools.time10to13(
+              data.timeArray[1],
+              1
+            );
+            delete data.timeArray;
+          }
           this.$api
             .appmockapply(data)
             .then((res) => {

+ 107 - 82
src/views/education/mockTestManagement/mockExamArrangement/addMockExam/infoPage.vue

@@ -58,6 +58,7 @@
               >{{ getsubjectName(items.subjectId) }}
             </span>
             <el-button
+              v-if="listData.mockActivity === 0"
               type="text"
               style="margin-left: 10px"
               @click="addTime(index, indexs)"
@@ -70,64 +71,74 @@
               >删除</el-button
             >
             <div style="padding-left: 20px">
-              <div
-                v-for="(
-                  timeItem, indexItem
-                ) in items.mockMajorSubjectTimeList"
-                :key="indexItem"
-                style="padding-bottom: 6px"
-              >
-                <el-date-picker
-                  style="max-width: 180px"
-                  size="small"
-                  v-model="timeItem.examTime"
-                  type="date"
-                  format="yyyy 年 MM 月 dd 日"
-                  value-format="timestamp"
-                  placeholder="考试日期"
-                >
-                </el-date-picker>
-                <el-time-picker
-                  style="max-width: 140px; margin-left: 10px"
-                  size="small"
-                  format="HH:mm:ss"
-                  placeholder="开始时间"
-                  v-model="timeItem.startTime"
-                  value-format="HH:mm:ss"
-                  :picker-options="{
-                    selectableRange: `00:00:00-${
-                      timeItem.endTime ? timeItem.endTime : '23:59:59'
-                    }`,
-                  }"
-                >
-                </el-time-picker>
-                <span> - </span>
-                <el-time-picker
-                  style="max-width: 140px"
-                  size="small"
-                  format="HH:mm:ss"
-                  placeholder="结束时间"
-                  v-model="timeItem.endTime"
-                  value-format="HH:mm:ss"
-                  :picker-options="{
-                    selectableRange: `${
-                      timeItem.startTime ? timeItem.startTime : '00:00:00'
-                    }-23:59:59`,
-                  }"
+              <template v-if="listData.mockActivity === 0">
+                <div
+                  v-for="(
+                    timeItem, indexItem
+                  ) in items.mockMajorSubjectTimeList"
+                  :key="indexItem"
+                  style="padding-bottom: 6px"
                 >
-                </el-time-picker>
-                <el-button
-                  v-if="items.mockMajorSubjectTimeList.length > 1"
-                  size="mini"
-                  style="margin-left: 6px"
-                  type="danger"
-                  icon="el-icon-delete"
-                  circle
-                  @click="
-                    items.mockMajorSubjectTimeList.splice(indexItem, 1)
-                  "
-                ></el-button>
-              </div>
+                  <el-date-picker
+                    style="max-width: 180px"
+                    size="small"
+                    v-model="timeItem.examTime"
+                    type="date"
+                    format="yyyy 年 MM 月 dd 日"
+                    value-format="timestamp"
+                    placeholder="考试日期"
+                  >
+                  </el-date-picker>
+                  <el-time-picker
+                    style="max-width: 140px; margin-left: 10px"
+                    size="small"
+                    format="HH:mm:ss"
+                    placeholder="开始时间"
+                    v-model="timeItem.startTime"
+                    value-format="HH:mm:ss"
+                    :picker-options="{
+                      selectableRange: `00:00:00-${
+                        timeItem.endTime ? timeItem.endTime : '23:59:59'
+                      }`,
+                    }"
+                  >
+                  </el-time-picker>
+                  <span> - </span>
+                  <el-time-picker
+                    style="max-width: 140px"
+                    size="small"
+                    format="HH:mm:ss"
+                    placeholder="结束时间"
+                    v-model="timeItem.endTime"
+                    value-format="HH:mm:ss"
+                    :picker-options="{
+                      selectableRange: `${
+                        timeItem.startTime ? timeItem.startTime : '00:00:00'
+                      }-23:59:59`,
+                    }"
+                  >
+                  </el-time-picker>
+                  <el-button
+                    v-if="items.mockMajorSubjectTimeList.length > 1"
+                    size="mini"
+                    style="margin-left: 6px"
+                    type="danger"
+                    icon="el-icon-delete"
+                    circle
+                    @click="items.mockMajorSubjectTimeList.splice(indexItem, 1)"
+                  ></el-button>
+                </div>
+              </template>
+              <template v-if="listData.mockActivity === 1">
+                考试时长(分钟):<el-input-number
+                  :controls="false"
+                  :precision="0"
+                  v-model="items.duration"
+                  controls-position="right"
+                  :min="1"
+                  :size="size"
+                ></el-input-number>
+              </template>
               <div style="margin-bottom: 10px">
                 <el-button
                   type="primary"
@@ -162,9 +173,7 @@
               </div>
               <ul class="goodslist_style">
                 <li
-                  v-for="(
-                    ititem, itindex
-                  ) in items.mockMajorSubjectGoodsList"
+                  v-for="(ititem, itindex) in items.mockMajorSubjectGoodsList"
                   :key="itindex"
                 >
                   {{ ititem.goodsCode }}-{{ ititem.goodsName }}-<span
@@ -173,9 +182,7 @@
                   ><i
                     class="deleteStyle"
                     style="margin-left: 10px"
-                    @click="
-                      items.mockMajorSubjectGoodsList.splice(itindex, 1)
-                    "
+                    @click="items.mockMajorSubjectGoodsList.splice(itindex, 1)"
                     >删除</i
                   >
                 </li>
@@ -228,9 +235,7 @@ export default {
             i < this.infoData[index].mockMajorSubjectList.length;
             i++
           ) {
-            if (
-              this.infoData[index].mockMajorSubjectList[i].subjectId === id
-            ) {
+            if (this.infoData[index].mockMajorSubjectList[i].subjectId === id) {
               status = true;
               break;
             }
@@ -287,23 +292,45 @@ export default {
      */
     handleSubjedt(item, index) {
       if (this.infoData[index].mockMajorSubjectList) {
-        this.infoData[index].mockMajorSubjectList.push({
-          subjectId: item.id,
-          mockMajorSubjectTimeList: [
-            { examTime: "", startTime: "", endTime: "" },
-          ],
-          mockMajorSubjectGoodsList: [],
-        });
-      } else {
-        this.$set(this.infoData[index], "mockMajorSubjectList", [
-          {
+        var ary = {};
+        if (this.listData.mockActivity === 0) {
+          ary = {
             subjectId: item.id,
             mockMajorSubjectTimeList: [
               { examTime: "", startTime: "", endTime: "" },
             ],
             mockMajorSubjectGoodsList: [],
-          },
-        ]);
+          };
+        }
+        if (this.listData.mockActivity === 1) {
+          ary = {
+            subjectId: item.id,
+            duration: "",
+            mockMajorSubjectGoodsList: [],
+          };
+        }
+        this.infoData[index].mockMajorSubjectList.push(ary);
+      } else {
+        if (this.listData.mockActivity === 0) {
+          this.$set(this.infoData[index], "mockMajorSubjectList", [
+            {
+              subjectId: item.id,
+              mockMajorSubjectTimeList: [
+                { examTime: "", startTime: "", endTime: "" },
+              ],
+              mockMajorSubjectGoodsList: [],
+            },
+          ]);
+        }
+        if (this.listData.mockActivity === 1) {
+          this.$set(this.infoData[index], "mockMajorSubjectList", [
+            {
+              subjectId: item.id,
+              duration: "",
+              mockMajorSubjectGoodsList: [],
+            },
+          ]);
+        }
       }
     },
     /**
@@ -380,8 +407,7 @@ export default {
         educationTypeId: this.listData.educationTypeId,
         businessId: this.listData.businessId,
         examId: this.infoData[index].mockMajorSubjectList[indexs].examId,
-        examName:
-          this.infoData[index].mockMajorSubjectList[indexs].examName,
+        examName: this.infoData[index].mockMajorSubjectList[indexs].examName,
       });
     },
     /**
@@ -406,8 +432,7 @@ export default {
       this.$refs.activeSection.openBoxGoods(index, indexs, {
         educationTypeId: this.listData.educationTypeId,
         businessId: this.listData.businessId,
-        sectionId:
-          this.infoData[index].mockMajorSubjectList[indexs].sectionId,
+        sectionId: this.infoData[index].mockMajorSubjectList[indexs].sectionId,
         sectionName:
           this.infoData[index].mockMajorSubjectList[indexs].sectionName,
       });

+ 90 - 41
src/views/education/mockTestManagement/mockExamArrangement/editMockExam/index.vue

@@ -51,6 +51,21 @@
           placeholder="请输入模考简介"
         ></el-input>
       </el-form-item>
+      <el-form-item label="是否活动模考" prop="mockActivity">
+        <el-radio-group
+          v-model="listData.mockActivity"
+          :disabled="
+            $refs.infoPage
+              ? $refs.infoPage.infoData.length > 0
+                ? true
+                : false
+              : false
+          "
+        >
+          <el-radio :label="1">是</el-radio>
+          <el-radio :label="0">否</el-radio>
+        </el-radio-group>
+      </el-form-item>
       <el-form-item label="业务层级" prop="educationTypeId">
         <el-select
           v-model="listData.educationTypeId"
@@ -108,7 +123,10 @@
           :newsubjectOption="newsubjectOption"
         />
       </el-form-item>
-      <el-form-item label="预约时间" prop="timeArray">
+      <el-form-item
+        :label="listData.mockActivity === 0 ? '预约时间' : '活动时间'"
+        prop="timeArray"
+      >
         <el-date-picker
           v-model="listData.timeArray"
           type="datetimerange"
@@ -165,6 +183,7 @@ export default {
       listData: {
         applyUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
         status: 1,
+        mockActivity: 0,
       },
       rules: {
         applyName: [
@@ -179,7 +198,7 @@ export default {
         timeArray: [
           {
             required: true,
-            message: "请选择预约时间",
+            message: "请选择时间",
             trigger: ["blur", "change"],
           },
         ],
@@ -248,12 +267,21 @@ export default {
         });
         delete res.data.mockMajorList;
         //预约时间处理逻辑
-        res.data.timeArray = [
-          this.$methodsTools.time10to13(res.data.applyStartTime, 0),
-          this.$methodsTools.time10to13(res.data.applyEndTime, 0),
-        ];
-        delete res.data.applyStartTime;
-        delete res.data.applyEndTime;
+        if (res.data.mockActivity === 0) {
+          res.data.timeArray = [
+            this.$methodsTools.time10to13(res.data.applyStartTime, 0),
+            this.$methodsTools.time10to13(res.data.applyEndTime, 0),
+          ];
+          delete res.data.applyStartTime;
+          delete res.data.applyEndTime;
+        } else if (res.data.mockActivity === 1) {
+          res.data.timeArray = [
+            this.$methodsTools.time10to13(res.data.activityStartTime, 0),
+            this.$methodsTools.time10to13(res.data.activityEndTime, 0),
+          ];
+          delete res.data.activityStartTime;
+          delete res.data.activityEndTime;
+        }
         this.listData = res.data;
         this.$nextTick(() => {
           //模考专业
@@ -294,17 +322,24 @@ export default {
             try {
               this.$refs.infoPage.infoData.forEach((item) => {
                 item.mockMajorSubjectList.forEach((items) => {
-                  const checkSubjectTime = items.mockMajorSubjectTimeList.every(
-                    (time) => {
-                      return time.examTime && time.startTime && time.endTime;
+                  if (this.listData.mockActivity === 0) {
+                    const checkSubjectTime =
+                      items.mockMajorSubjectTimeList.every((time) => {
+                        return time.examTime && time.startTime && time.endTime;
+                      });
+                    if (checkSubjectTime) {
+                      if (!items.examId) {
+                        throw new Error("请检查关联试卷是否关联");
+                      }
+                    } else {
+                      throw new Error("请检查考试日期是否填写");
                     }
-                  );
-                  if (checkSubjectTime) {
-                    if (!items.examId) {
+                  } else if (this.listData.mockActivity === 1) {
+                    if (!items.duration) {
+                      throw new Error("请检查考试时长是否正确");
+                    } else if (!items.examId) {
                       throw new Error("请检查关联试卷是否关联");
                     }
-                  } else {
-                    throw new Error("请检查考试日期是否填写");
                   }
                 });
               });
@@ -328,24 +363,26 @@ export default {
           data.mockMajorList = JSON.parse(
             JSON.stringify(this.$refs.infoPage.infoData)
           );
-          var array = [];
-          data.mockMajorList.forEach((item) => {
-            item.mockMajorSubjectList.forEach((items) => {
-              items.mockMajorSubjectTimeList.forEach((itemTime) => {
-                itemTime.examTime = parseInt(itemTime.examTime / 1000);
-                array.push(
-                  new Date(
-                    this.$methodsTools.onlyForma(itemTime.examTime, false) +
-                      " " +
-                      itemTime.startTime
-                  ).getTime()
-                );
+          if (this.listData.mockActivity === 0) {
+            var array = [];
+            data.mockMajorList.forEach((item) => {
+              item.mockMajorSubjectList.forEach((items) => {
+                items.mockMajorSubjectTimeList.forEach((itemTime) => {
+                  itemTime.examTime = parseInt(itemTime.examTime / 1000);
+                  array.push(
+                    new Date(
+                      this.$methodsTools.onlyForma(itemTime.examTime, false) +
+                        " " +
+                        itemTime.startTime
+                    ).getTime()
+                  );
+                });
               });
             });
-          });
-          array.sort((a, b) => {
-            return a - b;
-          });
+            array.sort((a, b) => {
+              return a - b;
+            });
+          }
           // if (data.timeArray[1] >= array[0]) {
           //   this.$message.error("预约时间需要不得超过考试时间,请重新设置");
           //   this.disabledBtn = false;
@@ -357,15 +394,27 @@ export default {
               break;
             }
           }
-          data.applyStartTime = this.$methodsTools.time10to13(
-            data.timeArray[0],
-            1
-          );
-          data.applyEndTime = this.$methodsTools.time10to13(
-            data.timeArray[1],
-            1
-          );
-          delete data.timeArray;
+          if (data.mockActivity === 0) {
+            data.applyStartTime = this.$methodsTools.time10to13(
+              data.timeArray[0],
+              1
+            );
+            data.applyEndTime = this.$methodsTools.time10to13(
+              data.timeArray[1],
+              1
+            );
+            delete data.timeArray;
+          } else if (data.mockActivity === 1) {
+            data.activityStartTime = this.$methodsTools.time10to13(
+              data.timeArray[0],
+              1
+            );
+            data.activityEndTime = this.$methodsTools.time10to13(
+              data.timeArray[1],
+              1
+            );
+            delete data.timeArray;
+          }
           this.$api
             .editmockapply(data)
             .then((res) => {

+ 102 - 69
src/views/education/mockTestManagement/mockExamArrangement/editMockExam/infoPage.vue

@@ -58,6 +58,7 @@
               >{{ getsubjectName(items.subjectId) }}
             </span>
             <el-button
+              v-if="listData.mockActivity === 0"
               type="text"
               style="margin-left: 10px"
               @click="addTime(index, indexs)"
@@ -70,64 +71,74 @@
               >删除</el-button
             >
             <div style="padding-left: 20px">
-              <div
-                v-for="(
-                  timeItem, indexItem
-                ) in items.mockMajorSubjectTimeList"
-                :key="indexItem"
-                style="padding-bottom: 6px"
-              >
-                <el-date-picker
-                  style="max-width: 180px"
-                  size="small"
-                  v-model="timeItem.examTime"
-                  type="date"
-                  format="yyyy 年 MM 月 dd 日"
-                  value-format="timestamp"
-                  placeholder="考试日期"
-                >
-                </el-date-picker>
-                <el-time-picker
-                  style="max-width: 140px; margin-left: 10px"
-                  size="small"
-                  format="HH:mm:ss"
-                  placeholder="开始时间"
-                  v-model="timeItem.startTime"
-                  value-format="HH:mm:ss"
-                  :picker-options="{
-                    selectableRange: `00:00:00-${
-                      timeItem.endTime ? timeItem.endTime : '23:59:59'
-                    }`,
-                  }"
-                >
-                </el-time-picker>
-                <span> - </span>
-                <el-time-picker
-                  style="max-width: 140px"
-                  size="small"
-                  format="HH:mm:ss"
-                  placeholder="结束时间"
-                  v-model="timeItem.endTime"
-                  value-format="HH:mm:ss"
-                  :picker-options="{
-                    selectableRange: `${
-                      timeItem.startTime ? timeItem.startTime : '00:00:00'
-                    }-23:59:59`,
-                  }"
+              <template v-if="listData.mockActivity === 0">
+                <div
+                  v-for="(
+                    timeItem, indexItem
+                  ) in items.mockMajorSubjectTimeList"
+                  :key="indexItem"
+                  style="padding-bottom: 6px"
                 >
-                </el-time-picker>
-                <el-button
-                  v-if="items.mockMajorSubjectTimeList.length > 1"
-                  size="mini"
-                  style="margin-left: 6px"
-                  type="danger"
-                  icon="el-icon-delete"
-                  circle
-                  @click="
-                    items.mockMajorSubjectTimeList.splice(indexItem, 1)
-                  "
-                ></el-button>
-              </div>
+                  <el-date-picker
+                    style="max-width: 180px"
+                    size="small"
+                    v-model="timeItem.examTime"
+                    type="date"
+                    format="yyyy 年 MM 月 dd 日"
+                    value-format="timestamp"
+                    placeholder="考试日期"
+                  >
+                  </el-date-picker>
+                  <el-time-picker
+                    style="max-width: 140px; margin-left: 10px"
+                    size="small"
+                    format="HH:mm:ss"
+                    placeholder="开始时间"
+                    v-model="timeItem.startTime"
+                    value-format="HH:mm:ss"
+                    :picker-options="{
+                      selectableRange: `00:00:00-${
+                        timeItem.endTime ? timeItem.endTime : '23:59:59'
+                      }`,
+                    }"
+                  >
+                  </el-time-picker>
+                  <span> - </span>
+                  <el-time-picker
+                    style="max-width: 140px"
+                    size="small"
+                    format="HH:mm:ss"
+                    placeholder="结束时间"
+                    v-model="timeItem.endTime"
+                    value-format="HH:mm:ss"
+                    :picker-options="{
+                      selectableRange: `${
+                        timeItem.startTime ? timeItem.startTime : '00:00:00'
+                      }-23:59:59`,
+                    }"
+                  >
+                  </el-time-picker>
+                  <el-button
+                    v-if="items.mockMajorSubjectTimeList.length > 1"
+                    size="mini"
+                    style="margin-left: 6px"
+                    type="danger"
+                    icon="el-icon-delete"
+                    circle
+                    @click="items.mockMajorSubjectTimeList.splice(indexItem, 1)"
+                  ></el-button>
+                </div>
+              </template>
+              <template v-if="listData.mockActivity === 1">
+                考试时长(分钟):<el-input-number
+                  :controls="false"
+                  :precision="0"
+                  v-model="items.duration"
+                  controls-position="right"
+                  :min="1"
+                  :size="size"
+                ></el-input-number>
+              </template>
               <div style="margin-bottom: 10px">
                 <el-button
                   type="primary"
@@ -294,23 +305,45 @@ export default {
      */
     handleSubjedt(item, index) {
       if (this.infoData[index].mockMajorSubjectList) {
-        this.infoData[index].mockMajorSubjectList.push({
-          subjectId: item.id,
-          mockMajorSubjectTimeList: [
-            { examTime: "", startTime: "", endTime: "" },
-          ],
-          mockMajorSubjectGoodsList: [],
-        });
-      } else {
-        this.$set(this.infoData[index], "mockMajorSubjectList", [
-          {
+        var ary = {};
+        if (this.listData.mockActivity === 0) {
+          ary = {
             subjectId: item.id,
             mockMajorSubjectTimeList: [
               { examTime: "", startTime: "", endTime: "" },
             ],
             mockMajorSubjectGoodsList: [],
-          },
-        ]);
+          };
+        }
+        if (this.listData.mockActivity === 1) {
+          ary = {
+            subjectId: item.id,
+            duration: "",
+            mockMajorSubjectGoodsList: [],
+          };
+        }
+        this.infoData[index].mockMajorSubjectList.push(ary);
+      } else {
+        if (this.listData.mockActivity === 0) {
+          this.$set(this.infoData[index], "mockMajorSubjectList", [
+            {
+              subjectId: item.id,
+              mockMajorSubjectTimeList: [
+                { examTime: "", startTime: "", endTime: "" },
+              ],
+              mockMajorSubjectGoodsList: [],
+            },
+          ]);
+        }
+        if (this.listData.mockActivity === 1) {
+          this.$set(this.infoData[index], "mockMajorSubjectList", [
+            {
+              subjectId: item.id,
+              duration: "",
+              mockMajorSubjectGoodsList: [],
+            },
+          ]);
+        }
       }
     },
     /**

+ 29 - 8
src/views/education/notificationManageMent/notificationModel/index.vue

@@ -21,6 +21,9 @@
               v-model="scope.row[item.prop]"
               @change="changeCheck(scope.row, item.prop)"
             ></el-checkbox>
+            <span v-else-if="item.scope === 'isOptions'">
+              {{scope.row[item.prop] == 1 ? '学员':scope.row[item.prop] == 2 ? '教务':''}}
+            </span>
             <span v-else-if="item.scope === 'busins'">
               <span v-if="scope.row[item.prop] === 1">全部</span
               ><el-button v-else type="text" @click="openBox(scope.row)"
@@ -83,7 +86,7 @@
 <script>
 import pagination from "@/components/pagination";
 export default {
-  name:"NotificationModel",
+  name: "NotificationModel",
   components: { pagination },
   data() {
     return {
@@ -99,7 +102,13 @@ export default {
           width: "80px",
         },
         {
-          label: "提醒项(学员)",
+          label: "通知用户",
+          width: "100px",
+          prop: "userType",
+          scope: "isOptions",
+        },
+        {
+          label: "提醒项",
           prop: "remind",
         },
         {
@@ -124,6 +133,12 @@ export default {
           scope: "checked",
           width: "80px",
         },
+        {
+          label: "公众号模板消息",
+          prop: "gzhTpStatus",
+          scope: "checked",
+          width: "120px",
+        },
       ],
       tableData: [],
       loading: false,
@@ -151,11 +166,17 @@ export default {
       if (value === "wayStatus") {
         data.wayStatus = item.wayStatus;
       }
-      this.$api.editsystemremind(data).then((res) => {
-        this.$message.success("更新成功");
-      }).finally(()=>{
-        this.search()
-      })
+      if (value === "gzhTpStatus") {
+        data.gzhTpStatus = item.gzhTpStatus;
+      }
+      this.$api
+        .editsystemremind(data)
+        .then((res) => {
+          this.$message.success("更新成功");
+        })
+        .finally(() => {
+          this.search();
+        });
     },
     submitChecks() {
       var data = {
@@ -272,7 +293,7 @@ export default {
       }
     }
   }
-  .el-dialog__body{
+  .el-dialog__body {
     max-height: 500px;
     overflow: auto;
   }

+ 427 - 0
src/views/education/notificationManageMent/stationLetter/index.vue

@@ -0,0 +1,427 @@
+<template>
+  <div id="stationLetter">
+    <div style="margin-bottom: 10px">
+      <p>
+        共{{ total }}封,其中<span style="color: red">{{ dontRead }}</span>
+        个消息未读
+      </p>
+      <div>
+        <el-button size="mini" type="primary" plain @click="haveRead"
+          >标记为已读</el-button
+        ><el-button v-if="false" size="mini" type="primary" plain @click="notHaveRead"
+          >标记为未读</el-button
+        ><span style="font-size: 14px; margin-left: 10px">状态:</span
+        ><el-select
+          size="mini"
+          v-model="formData.receiptStatus"
+          placeholder="请选择状态"
+          @change="changeStatus"
+        >
+          <el-option
+            v-for="item in options"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </div>
+    </div>
+    <el-table
+      :data="tableData"
+      style="width: 100%"
+      border
+      row-key="id"
+      ref="tableData"
+    >
+      <el-table-column
+        type="selection"
+        width="55"
+        align="center"
+        reserve-selection
+        :selectable="canSelect"
+      >
+      </el-table-column>
+
+      <template v-for="(item, index) in tableSet">
+        <el-table-column
+          :width="item.width"
+          :key="index"
+          :label="item.label"
+          align="center"
+          :sortable="item.prop === 'sort'"
+          :show-overflow-tooltip="true"
+          header-align="center"
+          :prop="item.prop"
+          sort-by="sort"
+        >
+          <template slot-scope="scope">
+            <i
+              v-if="item.scope === 'icon'"
+              :style="
+                scope.row[item.prop] === 0
+                  ? 'color:#409EFF;'
+                  : scope.row[item.prop] === 1
+                  ? 'color:#eee;'
+                  : ''
+              "
+              style="font-size: 18px"
+              class="el-icon-s-comment"
+            ></i>
+            <span v-else-if="item.scope === 'theme'">
+              <strong style="margin-left: 10px">{{
+                scope.row[item.prop1]
+              }}</strong
+              ><span>{{ scope.row[item.prop2] }}</span>
+            </span>
+            <span v-else-if="item.scope === 'aTimeList'">{{
+              $methodsTools.onlyForma(scope.row[item.prop])
+            }}</span>
+            <span v-else>{{ scope.row[item.prop] }}</span></template
+          ></el-table-column
+        ></template
+      ><el-table-column label="操作" align="center" fixed="right" width="180px">
+        <template slot-scope="scope">
+          <el-button size="mini" @click="newSee(scope.row)" type="text"
+            >立即查看</el-button
+          ><el-button
+            size="mini"
+            :disabled="scope.row.receiptStatus === 1"
+            @click="haveReadID(scope.row.id)"
+            type="text"
+            >标记为已读</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <el-dialog
+      :visible.sync="dialogCG"
+      width="760px"
+      :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="dialogCG = false"
+          />
+        </div>
+      </div>
+      <h3 style="color: #333; font-weight: bold">{{ newData.remind }}</h3>
+      <p>{{ newData.text }}</p>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogCG = false">关闭</el-button>
+        <el-button type="primary" @click="submitChecks">查看学员</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import pagination from "@/components/pagination";
+export default {
+  name: "StationLetter",
+  components: { pagination },
+  data() {
+    return {
+      newData: {}, //当前数据
+      options: [
+        {
+          label: "全部",
+          value: "",
+        },
+        {
+          label: "已读",
+          value: 1,
+        },
+        {
+          label: "未读",
+          value: 0,
+        },
+      ],
+      total: 0,
+      dontRead: 0, //未读
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+        receiptStatus: "",
+        systemStatus: 1,
+      },
+      tableSet: [
+        {
+          label: "状态",
+          prop: "receiptStatus",
+          scope: "icon",
+          width: "80px",
+        },
+        {
+          label: "主题",
+          prop1: "remind",
+          prop2: "text",
+          scope: "theme",
+        },
+        {
+          label: "发送时间",
+          prop: "sendTime",
+          scope: "aTimeList",
+          width: "220px",
+        },
+      ],
+      tableData: [],
+      loading: false,
+      dialogCG: false,
+    };
+  },
+  mounted() {
+    this.search();
+    if (this.$route.params.id) {
+      this.$api.informsys_user(this.$route.params.id).then((res) => {
+        if (res.data) {
+          this.newSee(res.data);
+        }
+      });
+    }
+  },
+  methods: {
+    /**
+     * 查看消息
+     */
+    newSee(data) {
+      this.newData = JSON.parse(JSON.stringify(data));
+      this.dialogCG = true;
+      if (data.receiptStatus !== 1) {
+        this.haveReadID(data.id, false);
+      }
+    },
+    /**
+     * 单个标记已读
+     */
+    haveReadID(id, status = true) {
+      this.$api
+        .editupdateReadStatusBatch({ ids: [id], receiptStatus: 1 })
+        .then((res) => {
+          if (status) {
+            this.$message.success("已读成功");
+            this.$refs.tableData.clearSelection();
+          }
+          this.search();
+        });
+    },
+    /**
+     * 切换消息状态
+     */
+    changeStatus(val) {
+      this.formData.pageSize = 10;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    search() {
+      this.loading = true;
+      this.$api
+        .inquireinformsys_userlist(this.formData)
+        .then((res) => {
+          this.total = res.total;
+          this.tableData = res.rows;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+      this.$api
+        .inquireinformsys_userinformUnReadSum({ systemStatus: 1 })
+        .then((res) => {
+          this.dontRead = res.data;
+        });
+    },
+    /**
+     * 查看学员
+     */
+    submitChecks() {
+      this.dialogCG = false;
+      const jump = () => {
+        //学员详情
+        this.$router.push({
+          name: "StudentXQ",
+          query: {
+            id: this.newData.studentUserId,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "StudentXQ";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "StudentXQ",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    /**
+     * 已读
+     */
+    haveRead() {
+      const idList = this.$refs.tableData.selection.map((item) => {
+        return item.id;
+      });
+      if (idList.length == 0) {
+        this.$message.warning("请选择需要标记已读的数据");
+        return;
+      }
+      this.$api
+        .editupdateReadStatusBatch({ ids: idList, receiptStatus: 1 })
+        .then((res) => {
+          this.$message.success("已读成功");
+          this.$refs.tableData.clearSelection();
+          this.search();
+        });
+      console.log(idList);
+    },
+    notHaveRead() {
+      const idList = this.$refs.tableData.selection.map((item) => {
+        return item.id;
+      });
+      if (idList.length == 0) {
+        this.$message.warning("请选择需要标记已读的数据");
+        return;
+      }
+      this.$api
+        .editupdateReadStatusBatch({ ids: idList, receiptStatus: 0 })
+        .then((res) => {
+          this.$message.success("未读成功");
+          this.$refs.tableData.clearSelection();
+          this.search();
+        });
+      console.log(idList);
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    canSelect(row, index) {
+      if (row.receiptStatus === 0) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__body {
+    max-height: 500px;
+    overflow: auto;
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 303 - 5
src/views/education/studentManageMent/studentList/index.vue

@@ -6,7 +6,12 @@
       :formList="formList"
       @search="search"
       @init="init"
-    />
+      ><template slot="customize">
+        <el-button size="small" type="success" @click="exportUserList"
+          >导出</el-button
+        >
+      </template></search-box-new
+    >
     <table-list
       :tableSets="tableSet"
       :tableData="tableData"
@@ -35,6 +40,7 @@
 </template>
 
 <script>
+import * as baseUrls from "@/utils/request.js";
 import searchBoxNew from "@/components/searchBoxNew";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
@@ -59,6 +65,17 @@ export default {
       },
       //搜索
       formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
         {
           prop: "gradePoint",
           placeholder: "是否分班",
@@ -74,10 +91,106 @@ export default {
             },
           ],
         },
+        {
+          prop: "hasBindWx",
+          placeholder: "是否绑定微信",
+          scope: "select",
+          options: [
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop: "hasFollowWx",
+          placeholder: "是否关注公众号",
+          scope: "select",
+          options: [
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop1: "startTime",
+          prop2: "endTime",
+          placeholder1: "创建开始时间",
+          placeholder2: "创建结束时间",
+          scope: "moreDataPicker",
+          Diszing: true,
+        },
+        {
+          prop: "goodsSearchKey",
+          placeholder: "请输入商品编码/商品名称",
+        },
+        {
+          prop: "companyName",
+          placeholder: "请输入公司名称",
+        },
         {
           prop: "realname",
           placeholder: "请输入学员名称",
         },
+        {
+          prop: "gradeName",
+          placeholder: "请输入所属班级",
+        },
+        {
+          prop: "lastVisitPlat",
+          placeholder: "最近访问终端",
+          scope: "select",
+          options: [
+            {
+              label: "小程序",
+              value: 1,
+            },
+            {
+              label: "PC网站",
+              value: 2,
+            },
+          ],
+        },
+        {
+          prop1: "visitStartTime",
+          prop2: "visitEndTime",
+          placeholder1: "访问开始时间",
+          placeholder2: "访问结束时间",
+          scope: "moreDataPicker",
+          Diszing: true,
+        },
+        {
+          prop: "lastStudyPlat",
+          placeholder: "最近学习终端",
+          scope: "select",
+          options: [
+            {
+              label: "小程序",
+              value: 1,
+            },
+            {
+              label: "PC网站",
+              value: 2,
+            },
+          ],
+        },
+        {
+          prop1: "studyStartTime",
+          prop2: "studyEndTime",
+          placeholder1: "学习开始时间",
+          placeholder2: "学习结束时间",
+          scope: "moreDataPicker",
+          Diszing: true,
+        },
       ],
       formData: {
         status: "0,1",
@@ -98,6 +211,13 @@ export default {
           hidden: true,
           scope: "editInfo",
         },
+        {
+          label: "一寸头像",
+          prop: "oneInchPhotos",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
         {
           label: "学员身份证",
           prop: "idCard",
@@ -108,6 +228,84 @@ export default {
           prop: "telphone",
           hidden: true,
         },
+        {
+          label: "是否绑定小程序账号",
+          prop: "userBindWx",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "是否关注公众号",
+          prop: "userFollowWx",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "最近访问终端",
+          prop: "visitFromPlat",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "小程序",
+              value: 1,
+            },
+            {
+              label: "PC网站",
+              value: 2,
+            },
+          ],
+        },
+        {
+          label: "最近访问时间",
+          prop: "lastVisitTime",
+          hidden: true,
+          scope: "aTimeList",
+          isDiszing:true
+        },
+        {
+          label: "最近学习终端",
+          prop: "studyFromPlat",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "小程序",
+              value: 1,
+            },
+            {
+              label: "PC网站",
+              value: 2,
+            },
+          ],
+        },
+        {
+          label: "最近学习时间",
+          prop: "lastStudyTime",
+          hidden: true,
+          scope: "aTimeList",
+          isDiszing:true
+        },
         {
           label: "所在公司",
           prop: "companyName",
@@ -123,7 +321,7 @@ export default {
           label: "所购商品",
           prop1: "goodsCourseNum",
           prop2: "goodsBankNum",
-          prop3:"goodsLiveNum",
+          prop3: "goodsLiveNum",
           hidden: true,
           scope: "payGoodsList",
         },
@@ -133,7 +331,7 @@ export default {
           hidden: true,
           scope: "classNums",
           sort: true,
-          width:"120px"
+          width: "120px",
         },
       ],
       tableData: [], //表单数据
@@ -153,13 +351,101 @@ 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);
+    }
+    //学员统计页跳转带参初始化
+    if (this.$route.params.row) {
+      console.log(this.$route.params);
+      let data = JSON.parse(this.$route.params.row);
+      switch (this.$route.params.type) {
+        case 1:
+          //新增学员数
+          let data1 = new Date(`${data.date} 00:00:00`).getTime();
+          this.formData.startTime = data1;
+          this.formData.endTime = data1 + 86399999;
+          break;
+        case 2:
+          //访问学员总数
+          let data2 = new Date(`${data.date} 00:00:00`).getTime();
+          this.formData.visitStartTime = data2;
+          this.formData.visitEndTime = data2 + 86399999;
+          break;
+        case 3:
+          //访问小程序学员数
+          let data3 = new Date(`${data.date} 00:00:00`).getTime();
+          this.formData.visitStartTime = data3;
+          this.formData.visitEndTime = data3 + 86399999;
+          this.formData.lastVisitPlat = 1;
+          break;
+        case 4:
+          //访问PC学员数
+          let data4 = new Date(`${data.date} 00:00:00`).getTime();
+          this.formData.visitStartTime = data4;
+          this.formData.visitEndTime = data4 + 86399999;
+          this.formData.lastVisitPlat = 2;
+          break;
+        case 5:
+          //学习学员数
+          let data5 = new Date(`${data.date} 00:00:00`).getTime();
+          this.formData.studyStartTime = data5;
+          this.formData.studyEndTime = data5 + 86399999;
+          break;
+        case 6:
+          //小程序学习学员数
+          let data6 = new Date(`${data.date} 00:00:00`).getTime();
+          this.formData.studyStartTime = data6;
+          this.formData.studyEndTime = data6 + 86399999;
+          this.formData.lastStudyPlat = 1;
+          break;
+        case 7:
+          //PC学习学员数
+          let data7 = new Date(`${data.date} 00:00:00`).getTime();
+          this.formData.studyStartTime = data7;
+          this.formData.studyEndTime = data7 + 86399999;
+          this.formData.lastStudyPlat = 2;
+          break;
+
+        default:
+          break;
+      }
+    }
     this.search();
   },
   activated() {
     this.search();
   },
   methods: {
+    /**
+     * 导出学员列表
+     */
+    exportUserList() {
+      var data = JSON.parse(JSON.stringify(this.formData));
+      delete data.pageSize;
+      delete data.pageNum;
+      this.$api.inquiregradestudentlistStudentExport(data).then((res) => {
+        let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
+        let link = document.createElement("a");
+        let fileName = "导入模板" + ".xlsx";
+        document.body.appendChild(link);
+        link.href = url;
+        link.dowmload = fileName;
+        link.click();
+        link.remove();
+      });
+    },
     editInfo(v) {
       this.addClick(v, 2);
     },
@@ -176,13 +462,25 @@ 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);
       }
       if (this.formData.endTime) {
         data.endTime = parseInt(data.endTime / 1000);
       }
+      if (this.formData.visitStartTime) {
+        data.visitStartTime = parseInt(data.visitStartTime / 1000);
+      }
+      if (this.formData.visitEndTime) {
+        data.visitEndTime = parseInt(data.visitEndTime / 1000);
+      }
+      if (this.formData.studyStartTime) {
+        data.studyStartTime = parseInt(data.studyStartTime / 1000);
+      }
+      if (this.formData.studyEndTime) {
+        data.studyEndTime = parseInt(data.studyEndTime / 1000);
+      }
       this.$api
         .inquiregradestudentlistStudent(data)
         .then((res) => {

+ 239 - 0
src/views/education/studentManageMent/studentStatistics/index.vue

@@ -0,0 +1,239 @@
+<template>
+  <div id="studentStatistics">
+    <el-form :model="formData" ref="ruleForm" label-width="0px" :inline="true">
+      <el-form-item label="">
+        <el-date-picker
+          v-model="formData.statsStartTime"
+          type="date"
+          value-format="timestamp"
+          :size="size"
+          placeholder="开始时间"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="">
+        <el-date-picker
+          v-model="formData.statsEndTime"
+          type="date"
+          value-format="timestamp"
+          :size="size"
+          placeholder="结束时间"
+        >
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button :size="size" type="primary" @click="search">查询</el-button
+        ><el-button size="small" type="success" @click="exportUserList"
+          >导出</el-button
+        >
+      </el-form-item> </el-form
+    ><el-table
+      v-loading="loading"
+      ref="multipleTable"
+      :data="tableData"
+      border
+      :header-cell-style="{
+        'background-color': '#eee',
+        padding: '8px',
+        color: '#333',
+      }"
+    >
+      <template v-for="(item, index) in tableList">
+        <el-table-column
+          v-if="item.scope !== 'inputs'"
+          :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 === 'time'">{{
+              $methodsTools.onlyForma(scope.row[item.prop], false)
+            }}</span
+            ><span
+              class="click_style"
+              v-else-if="item.scope === 'click'"
+              @click="jumpPage(scope.row, item.type)"
+              >{{ scope.row[item.prop] }}</span
+            >
+            <span v-else>{{ scope.row[item.prop] }}</span></template
+          >
+        </el-table-column></template
+      >
+    </el-table>
+  </div>
+</template>
+
+<script>
+import * as baseUrls from "@/utils/request.js";
+import pagination from "@/components/pagination";
+export default {
+  name: "StudentStatistics",
+  components: {
+    pagination,
+  },
+  data() {
+    return {
+      loading: false,
+      size: "small",
+      tableData: [],
+      tableList: [
+        {
+          label: "日期",
+          prop: "date",
+          width: "180px",
+        },
+        {
+          label: "学员总数",
+          prop: "allNum",
+        },
+        {
+          label: "新增学员数",
+          prop: "addNum",
+          scope: "click",
+          type: 1,
+        },
+        {
+          label: "访问学员总数",
+          prop: "visitAllNum",
+          scope: "click",
+          type: 2,
+        },
+        {
+          label: "访问小程序学员数",
+          prop: "visitSmallNum",
+          scope: "click",
+          type: 3,
+        },
+        {
+          label: "访问PC学员数",
+          prop: "visitPcNum",
+          scope: "click",
+          type: 4,
+        },
+        {
+          label: "学习学员数",
+          prop: "studyAllNum",
+          scope: "click",
+          type: 5,
+        },
+        {
+          label: "小程序学习学员数",
+          prop: "studySmallNum",
+          scope: "click",
+          type: 6,
+        },
+        {
+          label: "PC学习学员数",
+          prop: "studyPcNum",
+          scope: "click",
+          type: 7,
+        },
+      ],
+      formData: {
+        userId: this.$route.query.id,
+      },
+    };
+  },
+  mounted() {
+    //默认7天时间范围
+    this.formData = {
+      statsStartTime:
+        new Date(new Date().toLocaleDateString()).getTime() - 604800000,
+      statsEndTime: new Date(new Date().toLocaleDateString()).getTime(),
+    };
+    this.search();
+  },
+  methods: {
+    /**
+     * 导出学员列表
+     */
+    exportUserList() {
+      if (!this.formData.statsStartTime || !this.formData.statsEndTime) {
+        this.$message.error("请选择开始时间与结束时间");
+        return;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.statsStartTime) {
+        data.statsStartTime = parseInt(data.statsStartTime / 1000);
+      }
+      if (this.formData.statsEndTime) {
+        data.statsEndTime = parseInt(data.statsEndTime / 1000);
+      }
+      this.$api.exportstudystats_list(data).then((res) => {
+        let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
+        let link = document.createElement("a");
+        let fileName = "导入模板" + ".xlsx";
+        document.body.appendChild(link);
+        link.href = url;
+        link.dowmload = fileName;
+        link.click();
+        link.remove();
+      });
+    },
+    /**
+     * 跳转页面
+     */
+    jumpPage(row, type) {
+      const jump = () => {
+        //学员详情
+        this.$router.push({
+          name: "StudentList",
+          params: {
+            row: JSON.stringify(row),
+            type: type,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "StudentList";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "StudentList",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    search() {
+      if (!this.formData.statsStartTime || !this.formData.statsEndTime) {
+        this.$message.error("请选择开始时间与结束时间");
+        return;
+      }
+      this.loading = true;
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.statsStartTime) {
+        data.statsStartTime = parseInt(data.statsStartTime / 1000);
+      }
+      if (this.formData.statsEndTime) {
+        data.statsEndTime = parseInt(data.statsEndTime / 1000);
+      }
+      this.$api
+        .inquirestudystats_list(data)
+        .then((res) => {
+          this.tableData = res.data;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.click_style {
+  cursor: pointer;
+  user-select: none;
+  text-decoration: underline;
+}
+</style>

+ 189 - 0
src/views/education/studentManageMent/studentXQ/accesslog.vue

@@ -0,0 +1,189 @@
+<template>
+  <div id="accesslog">
+    <div class="studentSty">
+      <el-form
+        :model="formData"
+        ref="ruleForm"
+        label-width="0px"
+        :inline="true"
+      >
+        <el-form-item label="">
+          <el-select v-model="formData.fromPlat" clearable placeholder="请选择访问终端" :size="size">
+            <el-option label="小程序端" :value="1"> </el-option>
+            <el-option label="PC端" :value="2"> </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="">
+          <el-date-picker
+            v-model="formData.startTime"
+            type="datetime"
+            value-format="timestamp"
+            :size="size"
+            placeholder="最近访问时间(开始时间)"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="">
+          <el-date-picker
+            v-model="formData.endTime"
+            type="datetime"
+            value-format="timestamp"
+            :size="size"
+            placeholder="最近访问时间(结束时间)"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-button :size="size" type="primary" @click="search"
+            >查询</el-button
+          >
+          <el-button :size="size" @click="clearFunc">重置</el-button>
+        </el-form-item>
+      </el-form>
+      <el-table
+        ref="multipleTable"
+        :data="tableData"
+        border
+        :header-cell-style="{
+          'background-color': '#eee',
+          padding: '8px',
+          color: '#333',
+        }"
+      >
+        <el-table-column type="index" width="80" label="序号" align="center">
+        </el-table-column>
+        <template v-for="(item, index) in tableList">
+          <el-table-column
+            v-if="item.scope !== 'inputs'"
+            :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 === 'fromPlatType'">
+                {{
+                  scope.row[item.prop] == 1
+                    ? "小程序"
+                    : scope.row[item.prop] == 2
+                    ? "PC网站"
+                    : "未知"
+                }}
+              </span>
+              <span v-else-if="item.scope === 'time'">{{
+                $methodsTools.onlyForma(scope.row[item.prop])
+              }}</span>
+              <span v-else>{{ scope.row[item.prop] }}</span></template
+            >
+          </el-table-column></template
+        >
+      </el-table>
+      <pagination
+        :total="total"
+        :pageSize="formData.pageSize"
+        :currentPage="formData.pageNum"
+        @handleSizeChange="handleSizeChange"
+        @handleCurrentChange="handleCurrentChange"
+      />
+      <div class="align_center">
+        <el-button @click="backPage">返回</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import pagination from "@/components/pagination";
+export default {
+  components: { pagination },
+  data() {
+    return {
+      size: "small",
+      tableData: [],
+      tableList: [
+        {
+          label: "访问终端",
+          prop: "fromPlat",
+          scope: "fromPlatType",
+        },
+        {
+          label: "访问时间",
+          prop: "createTime",
+          scope: "time",
+          width: "180px",
+        },
+      ],
+      total: 0,
+      formData: {
+        userId: this.$route.query.id,
+        pageSize: 10,
+        pageNum: 1,
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    clearFunc() {
+      this.formData = {
+        userId: this.$route.query.id,
+        pageSize: 10,
+        pageNum: 1,
+      };
+      this.search();
+    },
+    search() {
+      this.loading = true;
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.startTime) {
+        data.startTime = parseInt(data.startTime / 1000);
+      }
+      if (this.formData.endTime) {
+        data.endTime = parseInt(data.endTime / 1000);
+      }
+      this.$api
+        .inquireUserVisitloglist(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    //返回
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        // this.$router.push({
+        //   path: "StudentList",
+        // });
+        this.$router.go(-1);
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.studentSty {
+  // background-color: #eee;
+  padding: 20px 10px;
+  margin-top: 16px;
+}
+.align_center {
+  margin-top: 20px;
+  text-align: center;
+}
+</style>

+ 4 - 3
src/views/education/studentManageMent/studentXQ/classRecord.vue

@@ -164,9 +164,10 @@ export default {
     //返回
     backPage() {
       this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
-        this.$router.push({
-          path: "StudentList",
-        });
+        // this.$router.push({
+        //   path: "StudentList",
+        // });
+        this.$router.go(-1);
       });
     },
   },

+ 10 - 0
src/views/education/studentManageMent/studentXQ/index.vue

@@ -16,6 +16,12 @@
       <el-tab-pane label="直播-学习记录" name="liveRecode"
         ><live-list
       /></el-tab-pane>
+      <el-tab-pane label="访问日志" name="accesslog"
+        ><access-log
+      /></el-tab-pane>
+      <el-tab-pane label="学习日志" name="studylog"
+        ><study-log
+      /></el-tab-pane>
     </el-tabs>
   </div>
 </template>
@@ -26,6 +32,8 @@ import classRecord from "./classRecord.vue";
 import studentBaseManage from "./studentBaseManage.vue";
 import studyRecord from "./studyRecord.vue";
 import liveList from "./liveList.vue";
+import accessLog from "./accesslog.vue";
+import studyLog from "./studylog.vue";
 export default {
   name: "StudentXQ",
   components: {
@@ -34,6 +42,8 @@ export default {
     studentBaseManage,
     studyRecord,
     liveList,
+    accessLog,
+    studyLog
   },
   data() {
     return {

+ 6 - 5
src/views/education/studentManageMent/studentXQ/studentBaseManage.vue

@@ -303,8 +303,8 @@ export default {
         }
         return;
       }
-      if (file.size > 0.3 * 1024 * 1024) {
-        self.$message.error("图片不得大于300kb");
+      if (file.size > 2 * 1024 * 1024) {
+        self.$message.error("图片不得大于2MB");
         return;
       }
       if (int === 1) {
@@ -356,9 +356,10 @@ export default {
     },
     backPage() {
       this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
-        this.$router.push({
-          path: "StudentList",
-        });
+        // this.$router.push({
+        //   path: "StudentList",
+        // });
+        this.$router.go(-1);
       });
     },
     submit() {

+ 207 - 0
src/views/education/studentManageMent/studentXQ/studylog.vue

@@ -0,0 +1,207 @@
+<template>
+  <div id="studylog">
+    <div class="studentSty">
+      <el-form
+        :model="formData"
+        ref="ruleForm"
+        label-width="0px"
+        :inline="true"
+      >
+        <el-form-item label="">
+          <el-select v-model="formData.fromPlat" clearable placeholder="请选择学习终端" :size="size">
+            <el-option label="小程序端" :value="1"> </el-option>
+            <el-option label="PC端" :value="2"> </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="">
+          <el-date-picker
+            v-model="formData.startTime"
+            type="datetime"
+            value-format="timestamp"
+            :size="size"
+            placeholder="最近学习时间(开始时间)"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="">
+          <el-date-picker
+            v-model="formData.endTime"
+            type="datetime"
+            value-format="timestamp"
+            :size="size"
+            placeholder="最近学习时间(结束时间)"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-button :size="size" type="primary" @click="search"
+            >查询</el-button
+          >
+          <el-button :size="size" @click="clearFunc">重置</el-button>
+        </el-form-item>
+      </el-form>
+      <el-table
+        ref="multipleTable"
+        :data="tableData"
+        border
+        :header-cell-style="{
+          'background-color': '#eee',
+          padding: '8px',
+          color: '#333',
+        }"
+      >
+        <el-table-column type="index" width="80" label="序号" align="center">
+        </el-table-column>
+        <template v-for="(item, index) in tableList">
+          <el-table-column
+            v-if="item.scope !== 'inputs'"
+            :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 === 'fromPlatType'">
+                {{
+                  scope.row[item.prop] == 1
+                    ? "小程序"
+                    : scope.row[item.prop] == 2
+                    ? "PC网站"
+                    : "未知"
+                }}
+              </span>
+              <span v-else-if="item.scope === 'goodsType'">
+                <span v-for="(itemt, indext) in $methodsTools.getGoodsType()"
+                    :key="indext">
+                  <span
+                    v-if="itemt.value === scope.row[item.prop]"
+                    >{{ itemt.label }}</span
+                  >
+                </span>
+              </span>
+              <span v-else-if="item.scope === 'time'">{{
+                $methodsTools.onlyForma(scope.row[item.prop])
+              }}</span>
+              <span v-else>{{ scope.row[item.prop] }}</span></template
+            >
+          </el-table-column></template
+        >
+      </el-table>
+      <pagination
+        :total="total"
+        :pageSize="formData.pageSize"
+        :currentPage="formData.pageNum"
+        @handleSizeChange="handleSizeChange"
+        @handleCurrentChange="handleCurrentChange"
+      />
+      <div class="align_center">
+        <el-button @click="backPage">返回</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import pagination from "@/components/pagination";
+export default {
+  components: { pagination },
+  data() {
+    return {
+      size: "small",
+      tableData: [],
+      tableList: [
+        {
+          label: "商品课程名称",
+          prop: "goodsName",
+        },
+        {
+          label: "商品课程类型",
+          prop: "goodsType",
+          scope: "goodsType",
+        },
+        {
+          label: "学习终端",
+          prop: "fromPlat",
+          scope: "fromPlatType",
+        },
+        {
+          label: "学习时间",
+          prop: "createTime",
+          scope: "time",
+          width: "180px",
+        },
+      ],
+      total: 0,
+      formData: {
+        userId: this.$route.query.id,
+        pageSize: 10,
+        pageNum: 1,
+      },
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    clearFunc() {
+      this.formData = {
+        userId: this.$route.query.id,
+        pageSize: 10,
+        pageNum: 1,
+      };
+      this.search();
+    },
+    search() {
+      this.loading = true;
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.startTime) {
+        data.startTime = parseInt(data.startTime / 1000);
+      }
+      if (this.formData.endTime) {
+        data.endTime = parseInt(data.endTime / 1000);
+      }
+      this.$api
+        .inquireUserStudyloglist(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    //返回
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        // this.$router.push({
+        //   path: "StudentList",
+        // });
+        this.$router.go(-1);
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.studentSty {
+  // background-color: #eee;
+  padding: 20px 10px;
+  margin-top: 16px;
+}
+.align_center {
+  margin-top: 20px;
+  text-align: center;
+}
+</style>

+ 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>

Some files were not shown because too many files changed in this diff