Explorar el Código

Merge branch 'newtang' into d_ls

谢杰标 hace 3 años
padre
commit
e14605b571
Se han modificado 97 ficheros con 12049 adiciones y 687 borrados
  1. 4 0
      package.json
  2. 1 1
      public/index.html
  3. 15 11
      src/App.vue
  4. 6 0
      src/api/api.js
  5. 22 2
      src/api/login.js
  6. BIN
      src/assets/images/left@2x.png
  7. BIN
      src/assets/images/left_slices/left@2x.png
  8. BIN
      src/assets/model_images/model1.png
  9. BIN
      src/assets/model_images/model2.png
  10. BIN
      src/assets/model_images/model3.png
  11. BIN
      src/assets/model_images/model4.png
  12. BIN
      src/assets/model_images/示例.png
  13. 30 6
      src/components/Editor/index.vue
  14. 18 7
      src/components/Study/StudentInfo.vue
  15. 13 0
      src/components/busIns.vue
  16. 353 0
      src/components/goodsList/index.vue
  17. 238 0
      src/components/modelView/index.vue
  18. 19 11
      src/components/questionBank.vue
  19. 8 0
      src/components/searchBoxNew.vue
  20. 8 0
      src/components/tableList.vue
  21. 42 0
      src/fxApi/poster.js
  22. 120 0
      src/fxApi/temp.js
  23. 6 1
      src/layout/components/Navbar.vue
  24. 3 3
      src/layout/components/Sidebar/Logo.vue
  25. 3 0
      src/main.js
  26. 9 0
      src/newApi/business.js
  27. 8 0
      src/newApi/classTab.js
  28. 9 0
      src/newApi/order.js
  29. 8 0
      src/newApi/paperquestion.js
  30. 8 0
      src/newApi/systemRemind.js
  31. 23 0
      src/newApi/userInformationManagement.js
  32. 33 10
      src/permission.js
  33. 1 1
      src/settings.js
  34. 1 0
      src/store/modules/permission.js
  35. 62 2
      src/store/modules/user.js
  36. 3 3
      src/utils/request.js
  37. 208 0
      src/views/2Cport/pageSettings/H5_small.vue
  38. 73 4
      src/views/2Cport/pageSettings/footer.vue
  39. 4 1
      src/views/2Cport/pageSettings/index.vue
  40. 124 0
      src/views/Marketing/activitySystem/activityList/activityInfo/first.vue
  41. 293 0
      src/views/Marketing/activitySystem/activityList/activityInfo/index.vue
  42. 226 0
      src/views/Marketing/activitySystem/activityList/activityInfo/second.vue
  43. 194 0
      src/views/Marketing/activitySystem/activityList/activityInfo/tenant.vue
  44. 120 0
      src/views/Marketing/activitySystem/activityList/activityInfo/three.vue
  45. 340 0
      src/views/Marketing/activitySystem/activityList/index.vue
  46. 292 0
      src/views/Marketing/activitySystem/posterList/index.vue
  47. 520 0
      src/views/Marketing/activitySystem/posterList/model.vue
  48. 309 0
      src/views/Marketing/distribution/commissionList/index.vue
  49. 326 0
      src/views/Marketing/distribution/distributionOrder/index.vue
  50. 282 0
      src/views/Marketing/distribution/rankingList/index.vue
  51. 250 0
      src/views/Marketing/distribution/salesmanList/formBox.vue
  52. 319 0
      src/views/Marketing/distribution/salesmanList/index.vue
  53. 258 0
      src/views/Marketing/distribution/salesmanList/salesCheckout.vue
  54. 1 0
      src/views/Marketing/goods/commodityManageMent/add/index.vue
  55. 24 1
      src/views/Marketing/goods/commodityManageMent/add/introduction.vue
  56. 4 2
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/courseCheck.vue
  57. 1 4
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue
  58. 1 0
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/moreListCheck.vue
  59. 2 1
      src/views/Marketing/goods/commodityManageMent/edit/index.vue
  60. 24 1
      src/views/Marketing/goods/commodityManageMent/edit/introduction.vue
  61. 0 1
      src/views/Marketing/goods/commodityManageMent/edit/productInformation.vue
  62. 4 4
      src/views/Marketing/goods/commodityManageMent/poppleSet.vue
  63. 4 4
      src/views/Marketing/goods/commodityManageMent/poppleSetTK.vue
  64. 267 15
      src/views/Marketing/order/pendingRefundOrder/index.vue
  65. 28 6
      src/views/Marketing/order/pendingRefundOrder/refundDia.vue
  66. 91 0
      src/views/classHoursReview/component/ChapterTable.vue
  67. 137 0
      src/views/classHoursReview/component/CheatDialog.vue
  68. 433 0
      src/views/classHoursReview/component/LessonTable.vue
  69. 58 0
      src/views/classHoursReview/component/ModulTable.vue
  70. 531 0
      src/views/classHoursReview/component/StudyTables.vue
  71. 89 0
      src/views/classHoursReview/index.vue
  72. 402 0
      src/views/classHoursReview/studyTimes.vue
  73. 2 0
      src/views/education/classManageMent/classHoursReview/component/LessonTable.vue
  74. 77 25
      src/views/education/notificationManageMent/stationLetter/index.vue
  75. 300 0
      src/views/finance/paymentList/index.vue
  76. 139 0
      src/views/finance/withdrawal/audit.vue
  77. 327 0
      src/views/finance/withdrawal/index.vue
  78. 561 538
      src/views/index.vue
  79. 106 2
      src/views/login.vue
  80. 11 0
      src/views/resource/bankManagement/testPaperManagement/BatchImportPop.vue
  81. 25 7
      src/views/resource/bankManagement/testPaperManagement/PaperSort.vue
  82. 31 3
      src/views/resource/bankManagement/testPaperManagement/addPaper/topicAddPaper/index.vue
  83. 30 2
      src/views/resource/bankManagement/testPaperManagement/editPaper/topicEditPaper/index.vue
  84. 20 0
      src/views/resource/bankManagement/topicManagement/index.vue
  85. 2 2
      src/views/resource/baseManageInfos/resource/businessLevel/index.vue
  86. 1 0
      src/views/resource/baseManageInfos/resource/papers/index.vue
  87. 1 1
      src/views/resource/videoManagement/chapter/add/index.vue
  88. 1 1
      src/views/resource/videoManagement/chapter/edit/index.vue
  89. 1 2
      src/views/resource/videoManagement/courseManagement/chapterContent/index.vue
  90. 1 1
      src/views/resource/videoManagement/festival/add/index.vue
  91. 1 1
      src/views/resource/videoManagement/festival/edit/index.vue
  92. 378 0
      src/views/secondJian/completionList/index.vue
  93. 814 0
      src/views/secondJian/courseList/index.vue
  94. 358 0
      src/views/secondJian/learningList/index.vue
  95. 378 0
      src/views/secondZao/completionList/index.vue
  96. 813 0
      src/views/secondZao/courseList/index.vue
  97. 358 0
      src/views/secondZao/learningList/index.vue

+ 4 - 0
package.json

@@ -46,7 +46,9 @@
     "element-ui": "2.15.6",
     "file-saver": "^2.0.5",
     "fuse.js": "6.4.3",
+    "gsap": "^3.11.4",
     "highlight.js": "9.18.5",
+    "html2canvas": "^1.4.1",
     "js-beautify": "1.13.0",
     "js-cookie": "2.2.1",
     "js-md5": "^0.7.3",
@@ -59,8 +61,10 @@
     "sortablejs": "1.10.2",
     "v-fit-columns": "^0.2.0",
     "vue": "2.6.12",
+    "vue-canvas-poster": "^1.2.1",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
+    "vue-draggable-resizable": "^2.3.0",
     "vue-meta": "^2.4.0",
     "vue-router": "3.4.9",
     "vuedraggable": "2.24.3",

+ 1 - 1
public/index.html

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

+ 15 - 11
src/App.vue

@@ -5,15 +5,19 @@
 </template>
 
 <script>
-export default  {
-  name:  'App',
-    metaInfo() {
-        return {
-            title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
-            titleTemplate: title => {
-                return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
-            }
-        }
-    }
-}
+export default {
+  name: "App",
+  metaInfo() {
+    return {
+      title:
+        this.$store.state.settings.dynamicTitle &&
+        this.$store.state.settings.title,
+      titleTemplate: (title) => {
+        return title
+          ? `${title} - ${this.$store.state.user.companyName}`
+          : this.$store.state.user.companyName;
+      },
+    };
+  },
+};
 </script>

+ 6 - 0
src/api/api.js

@@ -101,11 +101,17 @@ import studyAccountStatus from '../newApi/studyAccountStatus'//学习账号标
 import mock from '../newApi/mock'//模考管理
 import mockSub from '../newApi/mockSub'//预约模考管理
 import systemExam from '../newApi/systemExam'//模考活动列表
+//分销相关
+
+import poster from '../fxApi/poster'//海报列表
+import temp from '../fxApi/temp'//分销活动列表
 
 
 
 // 导入对应模块------------------------
 export default {
+    ...poster,
+    ...temp,
     ...courseEducationType,
     ...courseProjectType,
     ...applyAreas,

+ 22 - 2
src/api/login.js

@@ -1,12 +1,12 @@
 import request from '@/utils/request'
 
 // 登录方法
-export function login(username, password, code, uuid) {
+export function login(username, password, code, uuid, phonenumber, smsCode) {
   const data = {
     username,
     password,
     code,
-    uuid
+    uuid, phonenumber, smsCode
   }
   return request({
     url: '/login',
@@ -15,6 +15,26 @@ export function login(username, password, code, uuid) {
   })
 }
 
+
+// 双重等保
+export function commondual_auth() {
+  return request({
+    url: '/common/free/dual_auth',
+    method: 'get',
+    timeout: 20000
+  })
+}
+// 获取登入短信
+export function commonsms_login(data) {
+  return request({
+    url: '/app/common/sms/login',
+    method: 'post',
+    data: data,
+    headers: {
+      isToken: false
+    },
+  })
+}
 // 注册方法
 export function register(data) {
   return request({

BIN
src/assets/images/left@2x.png


BIN
src/assets/images/left_slices/left@2x.png


BIN
src/assets/model_images/model1.png


BIN
src/assets/model_images/model2.png


BIN
src/assets/model_images/model3.png


BIN
src/assets/model_images/model4.png


BIN
src/assets/model_images/示例.png


+ 30 - 6
src/components/Editor/index.vue

@@ -73,7 +73,7 @@ export default {
         modules: {
           clipboard: {
             // 粘贴版,处理粘贴时候带图片
-            matchers: [[Node.ELEMENT_NODE, this.handleCustomMatcher]],
+            // matchers: [[Node.ELEMENT_NODE, this.handleCustomMatcher]],
           },
           // 工具栏配置
           toolbar: [
@@ -138,20 +138,21 @@ export default {
       };
       this.$api.getPolicy(datats).then((res) => {
         this.datas = res.data.resultContent;
-        console.log(res.data.resultContent.host)
+        console.log(res.data.resultContent.host);
         this.uploadUrl = res.data.resultContent.host;
         resolve();
       });
     }).then(() => {
       this.init();
     });
+    this.paste();
   },
   beforeDestroy() {
     this.Quill = null;
   },
   methods: {
     handleCustomMatcher(node, Delta) {
-      console.log("handleCustomMatcher")
+      console.log("handleCustomMatcher", node);
       let ops = [];
       Delta.ops.forEach((op) => {
         if (op.insert && typeof op.insert === "string") {
@@ -187,7 +188,7 @@ export default {
       return Delta;
     },
     base64ToFile(base64, fileName) {
-      console.log("base64ToFile")
+      console.log("base64ToFile");
       return new Promise((resolve, reject) => {
         let arr = base64.split(",");
         let mime = arr[0].match(/:(.*?);/)[1];
@@ -204,7 +205,7 @@ export default {
       });
     },
     init() {
-      console.log("init")
+      console.log("init");
       const editor = this.$refs.editor;
       this.Quill = new Quill(editor, this.options);
       // 如果设置了上传地址则自定义图片上传事件
@@ -257,7 +258,7 @@ export default {
       };
     },
     imageChange(param, type) {
-      console.log("imageChange")
+      console.log("imageChange");
       this.$upload
         .upload(param.file, this.uploadStatus)
         .then((res) => {
@@ -280,6 +281,29 @@ export default {
     handleUploadError() {
       this.$message.error("图片插入失败");
     },
+    paste() {
+      window.addEventListener(
+        "paste",
+        (evt) => {
+          if (
+            evt.clipboardData &&
+            evt.clipboardData.files &&
+            evt.clipboardData.files.length
+          ) {
+            evt.preventDefault();
+            [].forEach.call(evt.clipboardData.files, (file) => {
+              if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
+                return;
+              }
+              this.imageChange({
+                file: file,
+              });
+            });
+          }
+        },
+        false
+      );
+    },
   },
 };
 </script>

+ 18 - 7
src/components/Study/StudentInfo.vue

@@ -4,15 +4,25 @@
       <div class="left"><i></i><span>学员信息</span></div>
       <div class="goods_info">
         <span v-for="(item, i) in headList" :key="i">
-          <strong style="color: red">「{{ i + 1 }}」</strong>
-          {{ item.lebel }}
-          <span v-if="item.key != 'num' && item.key != 'time'">{{
+          <strong>「{{ i + 1 }}」</strong>
+          <span style="padding-left: 0px">{{ item.lebel }}</span>
+          <!-- <span v-if="item.key != 'num' && item.key != 'time'">{{
+            userData[item.key]
+          }}</span> -->
+
+          <span v-if="item.key == 'goodsName'">{{ userData[item.key] }}</span>
+          <span v-else-if="item.key == 'className'">{{
             userData[item.key]
           }}</span>
+          <span
+            v-else-if="item.key == 'classHours'"
+            style="color: red; font-weight: bold"
+            >{{ parseInt(userData["finishSectionDuration"] / 60 / 45) }}</span
+          >
           <span v-else-if="item.key == 'num'"
             >完成{{ userData.stuAllNum + userData.recordNum }}节的内容学习</span
           >
-          <span v-else-if="item.key == 'time'"
+          <span v-else-if="item.key == 'time'" style="padding-right: 50px"
             >{{ $methodsTools.onlyForma(userData.studyStartTime, false) }} -
             {{ $methodsTools.onlyForma(userData.studyEndTime, false) }}</span
           >
@@ -118,7 +128,7 @@ export default {
       const list = [
         { lebel: "所在班级:", key: "className" },
         { lebel: "学时:", key: "classHours" },
-        { lebel: "", key: "num" },
+        // { lebel: "", key: "num" },
         { lebel: "学习时间:", key: "time" },
       ];
       if (this.all) {
@@ -165,7 +175,7 @@ export default {
       flex-wrap: wrap;
       span {
         font-size: 14px;
-        padding-left: 20px;
+        padding-left: 10px;
         white-space: nowrap;
       }
     }
@@ -237,4 +247,5 @@ export default {
     }
   }
 }
-</style>>
+</style>
+>

+ 13 - 0
src/components/busIns.vue

@@ -191,6 +191,19 @@ export default {
       // 立即处理 进入页面就触发
       immediate: true,
     },
+    newSujectApis: {
+      handler(newVal, oldVal) {
+        if (newVal && newVal.length > 0) {
+          const finds = newVal.findIndex((item) => {
+            return item.businessName === "安管三类";
+          });
+          this.$emit("disableType", finds);
+        }else{
+          this.$emit("disableType", -1);
+        }
+      },
+      immediate: true,
+    },
   },
   created() {
     this.localData = this.$methodsTools.getBusinessList();

+ 353 - 0
src/components/goodsList/index.vue

@@ -0,0 +1,353 @@
+<template>
+  <div id="">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="1088px"
+      :show-close="false"
+      :close-on-click-modal="false"
+      destroy-on-close
+      @closed="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>
+      <search-box-new
+        ref="searchBox"
+        :formData="formData"
+        :formList="formList"
+        @search="search"
+        @init="search(2)"
+        :topType="topType"
+      />
+      <el-table
+        ref="table"
+        row-key="goodsId"
+        :data="tableData"
+        v-loading="loading"
+        border
+        style="width: 100%"
+        @selection-change="selectionChange"
+      >
+        <el-table-column
+          type="selection"
+          width="55"
+          align="center"
+          reserve-selection
+          :selectable="dis_active"
+        >
+        </el-table-column>
+        <el-table-column
+          align="center"
+          type="index"
+          :disabled="true"
+        ></el-table-column>
+        <template v-for="(item, index) in tableSet">
+          <el-table-column
+            header-align="center"
+            :align="item.align ? item.align : 'center'"
+            :prop="item.prop"
+            :label="item.label"
+            :width="item.width || ''"
+            ><template slot-scope="scope"
+              ><div v-if="item.scope === 'options'">
+                <template v-for="(itemt, indext) in item.options">
+                  <span v-if="itemt.value === scope.row[item.prop]">{{
+                    itemt.label
+                  }}</span>
+                </template>
+              </div>
+              <span v-else-if="item.scope === 'leftCh'"
+                >{{ item.ch }}{{ scope.row[item.prop] }}</span
+              >
+              <span v-else>{{ scope.row[item.prop] }}</span></template
+            >
+          </el-table-column>
+        </template>
+      </el-table>
+      <div style="margin-top: 10px; text-align: center">
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+          :current-page="formData.pageNum"
+          :page-sizes="[10, 20, 50, 100]"
+          :page-size="formData.pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="total"
+        >
+        </el-pagination>
+      </div>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="submitTable" :loading="disbtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+export default {
+  components: { searchBoxNew },
+  data() {
+    return {
+      topType: true,
+      disbtn: false,
+      dialogVisible: false,
+      //搜索
+      formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "schoolId",
+          placeholder: "院校",
+          scope: "schoolList",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "majorId",
+          placeholder: "专业",
+          scope: "Professional",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "subjectId",
+          placeholder: "科目",
+          scope: "sujectType",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "status",
+          placeholder: "商品状态",
+          scope: "select",
+          noClear: false,
+          options: [
+            {
+              label: "全部状态",
+              value: "0,1",
+            },
+            {
+              label: "有效",
+              value: 1,
+            },
+            {
+              label: "无效",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop: "goodsStatus",
+          placeholder: "前台可售状态",
+          scope: "select",
+          options: [
+            {
+              label: "已上架",
+              value: 1,
+            },
+            {
+              label: "未上架",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop1: "validityStartTime",
+          prop2: "validityEndTime",
+          placeholder1: "商品有效期开始时间",
+          placeholder2: "商品有效期结束时间",
+          scope: "moreDataPicker",
+        },
+        // {
+        //   prop: "orderGoodsStatus",
+        //   placeholder: "退款状态",
+        //   scope: "select",
+        //   options: [
+        //     {
+        //       label: "已退款",
+        //       value: 1,
+        //     },
+        //     {
+        //       label: "退款中",
+        //       value: 2,
+        //     },
+        //     {
+        //       label: "拒绝退款",
+        //       value: 3,
+        //     },
+        //   ],
+        // },
+        {
+          prop: "goodsName",
+          placeholder: "请输入商品名称",
+        },
+      ],
+      formData: {
+        goodsType: "",
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "商品名称",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+          hidden: true,
+        },
+        {
+          label: "科目",
+          prop: "subjectNames",
+          hidden: true,
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+          hidden: true,
+        },
+        {
+          label: "商品价格",
+          prop: "standPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "商品划线价",
+          prop: "linePrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "可售状态",
+          prop: "goodsStatus",
+          hidden: true,
+          scope: "options",
+          options: [
+            {
+              label: "正常",
+              value: 1,
+            },
+            {
+              label: "关闭",
+              value: 0,
+            },
+          ],
+        },
+      ],
+      tableData: [],
+      loading: false,
+      total: 0,
+      outActive: [], //置灰列表
+      active: [], //当前选中
+    };
+  },
+  methods: {
+    selectionChange(e) {
+      this.active = e;
+    },
+    showBox(e) {
+      if (e && e.length > 0) {
+        this.outActive = e;
+      }
+      this.search(2);
+      this.dialogVisible = true;
+    },
+    dis_active(e) {
+      return this.outActive.includes(e.goodsId) ? false : true;
+    },
+    search(int) {
+      if (int === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+          goodsType: "",
+          status: "0,1",
+        };
+      }
+      if (int === 3) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.validityStartTime) {
+        data.validityStartTime = data.validityStartTime / 1000;
+      }
+      if (this.formData.validityEndTime) {
+        data.validityEndTime = data.validityEndTime / 1000;
+      }
+      this.loading = true;
+      this.$api
+        .inquireGoods(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    submitTable() {
+      if (this.active.length === 0) {
+        this.$message.warning("请勾选商品");
+        return;
+      }
+      this.disbtn = true;
+      const array = this.active.map((item) => {
+        return {
+          goodsId: item.goodsId,
+          goodsName: item.goodsName,
+          goodsPrice: item.standPrice,
+          profitMax: "",
+          profitType: 1,
+          profitOne: "",
+          profitTwo: "",
+          profitThree: "",
+        };
+      });
+      this.dialogVisible = false;
+      this.$emit("backGoodsList", array);
+    },
+    close() {
+      this.disbtn = false;
+      this.$refs.table.clearSelection();
+      this.outActive = [];
+      this.active = [];
+    },
+    handleSizeChange(e) {
+      this.formData.pageSize = e;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(e) {
+      this.formData.pageNum = e;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 238 - 0
src/components/modelView/index.vue

@@ -0,0 +1,238 @@
+<template>
+  <div
+    id="left"
+    class="left"
+    ref="modelView"
+    :style="IMGSHOW ? '' : 'border:none'"
+  >
+    <img
+      :style="modelData.background.css"
+      v-if="modelData.background.checked"
+      :src="$methodsTools.splitImgHost(modelData.background.name)"
+      alt=""
+      crossorigin="anonymous"
+    />
+    <!-- 标题 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop1"
+      @resizestop="onResizeStop1"
+      :w="modelData.title.width"
+      :h="modelData.title.height"
+      :x="modelData.title.left"
+      :y="modelData.title.top"
+      :parent="true"
+      v-if="modelData.title.checked"
+    >
+      <p :style="modelData.title.css">{{ modelData.title.name }}</p>
+    </vue-draggable-resizable>
+    <!-- 商品图 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop2"
+      @resizestop="onResizeStop2"
+      :w="modelData.goods.width"
+      :h="modelData.goods.height"
+      :x="modelData.goods.left"
+      :y="modelData.goods.top"
+      :parent="true"
+      v-if="modelData.goods.checked"
+      :style="
+        modelData.goods.name ? '' : 'border: 1px dotted rgba(225,225,225,.4)'
+      "
+    >
+      <img
+        crossorigin="anonymous"
+        v-if="modelData.goods.name"
+        :style="modelData.goods.css"
+        :src="$methodsTools.splitImgHost(modelData.goods.name)"
+        alt=""
+      />
+    </vue-draggable-resizable>
+    <!-- 分销码 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop3"
+      @resizestop="onResizeStop3"
+      :w="modelData.distribution.width"
+      :h="modelData.distribution.height"
+      :x="modelData.distribution.left"
+      :y="modelData.distribution.top"
+      :parent="true"
+      v-if="modelData.distribution.checked"
+      v-show="IMGSHOW"
+      style="border: 1px solid skyblue"
+      :lock-aspect-ratio="true"
+    >
+      <!-- <img
+        :style="modelData.distribution.css"
+        :src="modelData.distribution.name"
+        alt=""
+      /> -->
+    </vue-draggable-resizable>
+    <!-- 电子名片码 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop4"
+      @resizestop="onResizeStop4"
+      :w="modelData.cardCode.width"
+      :h="modelData.cardCode.height"
+      :x="modelData.cardCode.left"
+      :y="modelData.cardCode.top"
+      :parent="true"
+      v-if="modelData.cardCode.checked"
+      v-show="IMGSHOW"
+      style="border: 1px solid skyblue"
+      :lock-aspect-ratio="true"
+    >
+      <!-- <img
+        :style="modelData.cardCode.css"
+        :src="modelData.cardCode.name"
+        alt=""
+      /> -->
+    </vue-draggable-resizable>
+    <!-- 广告语 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop5"
+      @resizestop="onResizeStop5"
+      :w="modelData.advertise.width"
+      :h="modelData.advertise.height"
+      :x="modelData.advertise.left"
+      :y="modelData.advertise.top"
+      :parent="true"
+      v-if="modelData.advertise.checked"
+    >
+      <p style="white-space:pre-wrap;" :style="modelData.advertise.css">{{ modelData.advertise.name }}</p>
+    </vue-draggable-resizable>
+    <!-- 机构 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop6"
+      @resizestop="onResizeStop6"
+      :w="modelData.mechanism.width"
+      :h="modelData.mechanism.height"
+      :x="modelData.mechanism.left"
+      :y="modelData.mechanism.top"
+      :parent="true"
+      v-if="modelData.mechanism.checked"
+    >
+      <p :style="modelData.mechanism.css">{{ modelData.mechanism.name }}</p>
+    </vue-draggable-resizable>
+  </div>
+</template>
+
+<script>
+import html2Canvas from "html2canvas";
+import VueDraggableResizable from "vue-draggable-resizable";
+import "vue-draggable-resizable/dist/VueDraggableResizable.css";
+export default {
+  components: { VueDraggableResizable },
+  props: {
+    modelData: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      IMGSHOW: true, //截图过程先隐藏二维码窗口
+    };
+  },
+  methods: {
+    //标签转oss图片路径
+    changeFile() {
+      return new Promise((resolve, reject) => {
+        this.IMGSHOW = false;
+        this.$nextTick(() => {
+          html2Canvas(this.$refs.modelView, { useCORS: true, allowTaint: true })
+            .then((canvas) => {
+              const jpeg = canvas.toDataURL("image/jpeg", 1.0);
+              this.$upload
+                .upload(this.base64ToFile(jpeg), 0)
+                .then((res) => {
+                  resolve(res);
+                })
+                .catch(() => {
+                  reject();
+                });
+            })
+            .catch(() => {
+              reject();
+            })
+            .finally(() => {
+              this.IMGSHOW = true;
+            });
+        });
+      });
+    },
+    //格式转换
+    base64ToFile(urlData) {
+      const arr = urlData.split(",");
+      const mime = arr[0].match(/:(.*?);/)[1];
+      const bytes = atob(arr[1]);
+      let n = bytes.length;
+      const ia = new Uint8Array(n);
+      while (n--) {
+        ia[n] = bytes.charCodeAt(n);
+      }
+      return new File([ia], "jpeg", { type: mime });
+    },
+    onDragstop1(left, top) {
+      this.backData("title", left, top);
+    },
+    onResizeStop1(left, top, width, height) {
+      this.backData("title", left, top, width, height);
+    },
+    onDragstop2(left, top) {
+      this.backData("goods", left, top);
+    },
+    onResizeStop2(left, top, width, height) {
+      this.backData("goods", left, top, width, height);
+    },
+    onDragstop3(left, top) {
+      this.backData("distribution", left, top);
+    },
+    onResizeStop3(left, top, width, height) {
+      this.backData("distribution", left, top, width, height);
+    },
+    onDragstop4(left, top) {
+      this.backData("cardCode", left, top);
+    },
+    onResizeStop4(left, top, width, height) {
+      this.backData("cardCode", left, top, width, height);
+    },
+    onDragstop5(left, top) {
+      this.backData("advertise", left, top);
+    },
+    onResizeStop5(left, top, width, height) {
+      this.backData("advertise", left, top, width, height);
+    },
+    onDragstop6(left, top) {
+      this.backData("mechanism", left, top);
+    },
+    onResizeStop6(left, top, width, height) {
+      this.backData("mechanism", left, top, width, height);
+    },
+
+    backData(name, left, top, width, height) {
+      this.$emit("changeModelData", { name, left, top, width, height });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+#left {
+  position: relative;
+  width: 375px;
+  height: 667px;
+  border: 1px solid #333;
+  margin-right: 20px;
+  flex-shrink: 0;
+  box-sizing: content-box;
+  overflow: hidden;
+}
+.vdr {
+  border-color: transparent;
+}
+.active {
+  border: 1px dashed #000;
+}
+</style>

+ 19 - 11
src/components/questionBank.vue

@@ -25,9 +25,9 @@
           <span class="spans">题目类型:</span>
           <el-radio-group v-model="dingForm.type" @change="changeTypes">
             <el-radio
-              :disabled="statusPop === 2 || statusPop === 0"
               v-for="(item, index) in radioArrays"
               :key="index"
+              :disabled="computedDisabled(item)"
               :label="item.value"
               >{{ item.label }}</el-radio
             >
@@ -75,9 +75,7 @@
         </div> -->
         <div
           class="marg_play"
-          v-if="
-            dingForm.type === 1 || dingForm.type === 2
-          "
+          v-if="dingForm.type === 1 || dingForm.type === 2"
         >
           <span class="spans"
             ><span style="color: red" v-if="dingForm.type !== 5">* </span
@@ -199,7 +197,7 @@
                     v-for="(tng, nindex) in radioArray"
                     :key="nindex"
                     :label="tng.value"
-                    :disabled="statusPop === 2"
+                    :disabled="computedDisabled(tng)"
                     >{{ tng.label }}</el-radio
                   >
                 </el-radio-group>
@@ -245,10 +243,7 @@
                   </p>
                 </div>
               </div> -->
-              <div
-                class="marg_play"
-                v-if="ans.type === 1 || ans.type === 2"
-              >
+              <div class="marg_play" v-if="ans.type === 1 || ans.type === 2">
                 <span class="spans"
                   ><span style="color: red" v-if="ans.type !== 5">* </span
                   >选项:</span
@@ -487,7 +482,7 @@ import Editor from "@/components/Editor";
 export default {
   components: { Editor },
   name: "questionBank",
-  props: ["nums", "dingFormInfo"],
+  props: ["nums", "dingFormInfo", "disableTypeStatus"],
   data() {
     return {
       dingForm: {},
@@ -548,13 +543,26 @@ export default {
   watch: {
     dingFormInfo: {
       handler(newVal, oldVal) {
-        console.log(newVal)
+        console.log(newVal);
         this.dingForm = newVal;
       },
       // 立即处理 进入页面就触发
       immediate: true,
     },
   },
+  computed: {
+    computedDisabled: function () {
+      return function (item) {
+        if (this.statusPop === 2 || this.statusPop === 0) {
+          return true;
+        } else if (this.disableTypeStatus && item.value === 5) {
+          return true;
+        } else {
+          return false;
+        }
+      };
+    },
+  },
   methods: {
     changeTypes(int) {
       var data = {

+ 8 - 0
src/components/searchBoxNew.vue

@@ -556,6 +556,14 @@ export default {
           label: "复审",
           value: "1,2",
         },
+        {
+          label: "不通过",
+          value: "-1,-2",
+        },
+        {
+          label: "已通过",
+          value: 3,
+        },
       ],
       lists5: [
         {

+ 8 - 0
src/components/tableList.vue

@@ -262,6 +262,14 @@
             >
             <span v-else>{{ scope.row[item.prop] }}</span>
           </div>
+          <ul v-else-if="item.scope === 'baseInfo'">
+           <li>姓名:{{ scope.row[item.prop1] }}</li>
+           <li>身份证:{{ scope.row[item.prop2] }}</li>
+           <li>公司:{{ scope.row[item.prop3] }}</li>
+          </ul>
+          <span v-else-if="item.scope === 'recordEndTime'">
+            {{ scope.row[item.prop] ? '完成':'未完成' }}
+          </span>
           <span
             v-else-if="
               item.scope === 'treeWatch' &&

+ 42 - 0
src/fxApi/poster.js

@@ -0,0 +1,42 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增海报模板
+    distributionpostersave(data) {
+        return request({
+            url: '/distribution/poster/save', 
+            method: 'post',
+            data
+        })
+    },
+    //修改海报模板
+    editdistributionposter(data) {
+        return request({
+            url: '/distribution/poster/edit',
+            method: 'post',
+            data
+        })
+    },
+    //查询海报模板列表
+    inquiredistributionposterlist(data) {
+        return request({
+            url: '/distribution/poster/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取海报模板详细信息
+    obtaindistributionposter(data) {
+        return request({
+            url: `/distribution/poster/` + data,
+            method: 'get',
+        })
+    },
+    //查询海报模板列表
+    inquiredistributionposterimagelist(data) {
+        return request({
+            url: '/distribution/poster/image/list',
+            method: 'get',
+            params: data
+        })
+    },
+}

+ 120 - 0
src/fxApi/temp.js

@@ -0,0 +1,120 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增分销活动模板
+    distributiontempsave(data) {
+        return request({
+            url: '/distribution/activity/save', 
+            method: 'post',
+            data
+        })
+    },
+    //修改分销活动模板
+    editdistributiontemp(data) {
+        return request({
+            url: '/distribution/activity/edit',
+            method: 'post',
+            data
+        })
+    },
+    //启用-禁用
+    editdistributiontempupdatestatus(data) {
+        return request({
+            url: '/distribution/activity/update/status',
+            method: 'post',
+            data
+        })
+    },
+    //拉取商品
+    distributionactivitypullgoods(data) {
+        return request({
+            url: `/distribution/activity/pull/goods/` + data,
+            method: 'get',
+        })
+    },
+    //启用-禁用分销活动
+    editdistributionactivityeditstatus(data) {
+        return request({
+            url: '/distribution/activity/edit/status',
+            method: 'post',
+            data
+        })
+    },
+    //导出【请填写功能名称】列表
+    distributiontempexport(data) {
+        return request({
+            url: '/distribution/activity/export',
+            method: 'get',
+            params: data
+        })
+    },
+    //查询分销活动模板列表
+    distributiontemplist(data) {
+        return request({
+            url: '/distribution/activity/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //活动模板发布
+    distributiontemppublishdata(data) {
+        return request({
+            url: `/distribution/activity/publish/` + data,
+            method: 'get',
+        })
+    },
+    //获取分销活动模板详细信息
+    distributiontempdata(data) {
+        return request({
+            url: `/distribution/activity/` + data,
+            method: 'get',
+        })
+    },
+    //查询系统商户列表
+    systemtenantlist(data) {
+        return request({
+            url: '/system/tenant/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //查询分销业务员列表
+    distributionsellerlist(data) {
+        return request({
+            url: '/distribution/seller/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取分销业务员详细信息
+    distributionseller(data) {
+        return request({
+            url: '/distribution/seller/' + data,
+            method: 'get',
+        })
+    },
+    //新增分销业务员
+    addDistributionseller(data) {
+        return request({
+            url: '/distribution/seller',
+            method: 'post',
+            data
+        })
+    },
+    //批量新增关联分销业务员
+    distributionsellerbatchAdd(data) {
+        return request({
+            url: '/distribution/seller/batchAdd',
+            method: 'post',
+            data
+        })
+    },
+    //修改分销业务员
+    editDistributionseller(data) {
+        return request({
+            url: '/distribution/seller/edit',
+            method: 'post',
+            data
+        })
+    },
+    
+}

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

@@ -373,7 +373,11 @@ export default {
       })
         .then(() => {
           this.$store.dispatch("LogOut").then(() => {
-            location.href = "/index";
+            if (this.$route.query.TenantId) {
+              location.href = "/index?TenantId=" + this.$route.query.TenantId;
+            } else {
+              location.href = "/index";
+            }
           });
         })
         .catch(() => {
@@ -678,6 +682,7 @@ export default {
   width: 400px !important;
   padding: 0px !important;
   & > .el-notification__group {
+    width: 100%;
     margin: 0px;
     & > .el-notification__title {
       text-align: center;

+ 3 - 3
src/layout/components/Sidebar/Logo.vue

@@ -3,11 +3,11 @@
     <transition name="sidebarLogoFade">
       <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
         <img v-if="logo" :src="sideTheme === 'theme-dark'? logo : logoYT" class="sidebar-logo" />
-        <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
+        <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ $store.state.user.companyName }} </h1>
       </router-link>
       <router-link v-else key="expand" class="sidebar-logo-link" to="/">
         <img v-if="logo" :src="sideTheme === 'theme-dark'? logo : logoYT" class="sidebar-logo" />
-        <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
+        <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ $store.state.user.companyName }} </h1>
       </router-link>
     </transition>
   </div>
@@ -36,7 +36,7 @@ export default {
   },
   data() {
     return {
-      title: '中正云教育',
+      title: '',
       logo: logoImg,
       logoYT:logoYTImg,
     }

+ 3 - 0
src/main.js

@@ -12,6 +12,7 @@ import '@/assets/styles/ruoyi.scss' // ruoyi css
 import App from './App'
 import store from './store'
 import api from '@/api/api'
+import gsap from 'gsap'
 import upload from '@/utils/uploadFile'
 import router from './router'
 import directive from './directive' //directive
@@ -56,6 +57,8 @@ Vue.prototype.$api = api
 Vue.prototype.$upload = upload
 Vue.prototype.$methodsTools = methodsTools
 Vue.prototype.$bus = bus
+Vue.prototype.gsap = gsap
+
 // 全局组件挂载
 Vue.component('DictTag', DictTag)
 Vue.component('Pagination', Pagination)

+ 9 - 0
src/newApi/business.js

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

+ 8 - 0
src/newApi/classTab.js

@@ -288,6 +288,14 @@ export default {
             params: data
         })
     },
+    //查询学员视频学习记录列表
+    inquireGradegradelistUserVideoRecord(data) {
+        return request({
+            url: '/grade/grade/listUserVideoRecord',
+            method: 'get',
+            params: data
+        })
+    },
     
     
 }

+ 9 - 0
src/newApi/order.js

@@ -39,6 +39,15 @@ export default {
             method: 'get',
         })
     },
+    //获取退款订单详细子列表
+    obtainOrderRefundlistAll(data) {
+        return request({
+            url: `/order/refund/listAll/goods`,
+            method: 'get',
+            params: data
+        })
+    },
+    
     //修改订单商品
     editordergoods(data) {
         return request({

+ 8 - 0
src/newApi/paperquestion.js

@@ -71,4 +71,12 @@ export default {
             data
         })
     },
+    //导入题目模板EXCEL(旧系统)
+    importDataBackFromOldList(data) {
+        return request({
+            url: '/bank/question/importDataBackFromOldList',
+            method: 'post',
+            data
+        })
+    },
 }

+ 8 - 0
src/newApi/systemRemind.js

@@ -39,5 +39,13 @@ export default {
             params: data
         })
     },
+    //检查密码修改时间
+    inquireusercheckPwdTime(data) {
+        return request({
+            url: '/system/user/checkPwdTime',
+            method: 'get',
+            params: data
+        })
+    },
     
 }

+ 23 - 0
src/newApi/userInformationManagement.js

@@ -31,4 +31,27 @@ export default {
             method: 'get',
         })
     },
+    //获取企业ID
+    commonfreefindTenantId(data) {
+        return request({
+            url: '/common/free/findTenantId',
+            method: 'get',
+            params: data,
+            headers: {
+                isToken: false
+              },
+        })
+    },
+    //获取系统配置
+    commonfreeconfig(data) {
+        return request({
+            url: '/common/free/config',
+            method: 'get',
+            params: data,
+            headers: {
+                isToken: false
+              },
+        })
+    },
+
 }

+ 33 - 10
src/permission.js

@@ -1,27 +1,30 @@
 import router from './router'
 import store from './store'
-import { Message } from 'element-ui'
+import { MessageBox, Message } from 'element-ui'
 import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
 import methods from '@/utils/methodsTool';
 import { getToken } from '@/utils/auth'
+import $api from "@/api/api"
 
 NProgress.configure({ showSpinner: false })
 
 const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
 
-router.beforeEach((to, from, next) => {
+router.beforeEach(async (to, from, next) => {
   if (to.path !== from.path) {
     NProgress.start();
   }
-  if (methods.getQueryVariable('TenantId') && !sessionStorage.TenantId) {
-    sessionStorage.TenantId = methods.getQueryVariable('TenantId')
+  if (store.state.user.TENANT_NANE === null) {
+    await store.dispatch('findTenantId')
   }
-  if (methods.getQueryVariable('TenantId') && sessionStorage.TenantId == undefined) {
+  if (store.state.user.TENANT_NANE === '' && methods.getQueryVariable('TenantId')) {
     sessionStorage.TenantId = methods.getQueryVariable('TenantId')
   }
-  if (methods.getQueryVariable('TenantId') && sessionStorage.TenantId != methods.getQueryVariable('TenantId')) {
-    sessionStorage.TenantId = methods.getQueryVariable('TenantId')
+  if (store.state.user.TENANT_NANE || sessionStorage.TenantId) {
+    if (!store.state.user.companyName) {
+      store.dispatch('footerData')
+    }
   }
   if (getToken()) {
     to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
@@ -45,10 +48,14 @@ router.beforeEach((to, from, next) => {
           })
         })
       } else {
-        if (!to.query.TenantId) {
+        if (!store.state.user.TENANT_NANE && !to.query.TenantId) {
           to.query.TenantId = sessionStorage.TenantId
           next(to)
         } else {
+          if (!to.path.includes('/user/profile')) {
+            checkFunc()
+          }
+          console.log("to:", to)
           next()
         }
       }
@@ -59,7 +66,7 @@ router.beforeEach((to, from, next) => {
       // 在免登录白名单,直接进入
       next()
     } else {
-      if (sessionStorage.TenantId == undefined) {
+      if (store.state.user.TENANT_NANE || sessionStorage.TenantId == undefined) {
         next(`/login`) // 否则全部重定向到登录页
       } else {
         next(`/login?redirect=${to.fullPath}&TenantId=${sessionStorage.TenantId}`) // 否则全部重定向到登录页
@@ -68,7 +75,23 @@ router.beforeEach((to, from, next) => {
     }
   }
 })
-
+function checkFunc() {
+  $api.inquireusercheckPwdTime().then(res => {
+    if (res.data) {
+      MessageBox.confirm('您已90天为修改密码,请前往修改密码', '系统提示', {
+        confirmButtonText: '前往修改',
+        showCancelButton: false,
+        closeOnClickModal: false,
+        closeOnPressEscape: false,
+        showClose: false,
+        type: 'warning'
+      }
+      ).then(() => {
+        location.href = '/user/profile';
+      }).catch(() => { });
+    }
+  })
+}
 router.afterEach(() => {
   NProgress.done()
 })

+ 1 - 1
src/settings.js

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

+ 1 - 0
src/store/modules/permission.js

@@ -63,6 +63,7 @@ const permission = {
           const rdata = JSON.parse(JSON.stringify(res.data))
           const sidebarRoutes = filterAsyncRouter(sdata)
           const rewriteRoutes = filterAsyncRouter(rdata, false, true)
+          console.log("rewriteRoutes:",rewriteRoutes)
           rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
           commit('SET_ROUTES', rewriteRoutes)
           commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))

+ 62 - 2
src/store/modules/user.js

@@ -2,6 +2,7 @@ import { login, logout, getInfo } from '@/api/login'
 import { getToken, setToken, removeToken } from '@/utils/auth'
 import methods from "@/utils/methodsTool";
 import { encrypt } from '@/utils/jsencrypt'
+import api from '@/api/api'
 
 const user = {
   state: {
@@ -10,7 +11,9 @@ const user = {
     avatar: '',
     roles: [],
     permissions: [],
-    userId: ''
+    userId: '',
+    TENANT_NANE: null,
+    companyName: ''
   },
 
   mutations: {
@@ -32,9 +35,63 @@ const user = {
     SET_USERID: (state, userId) => {
       state.userId = userId
     },
+    setTENANT_NANE(state, id) {
+      state.TENANT_NANE = id
+    },
+    outLogin(state) {
+      if (state.TENANT_NANE) {
+        sessionStorage.removeItem('TenantId')
+      }
+    },
+    set_companyName(state, data) {
+      state.companyName = data || ''
+      document.title = data || ''
+    }
   },
 
   actions: {
+    findTenantId({
+      commit
+    }) {
+      return new Promise(resolve => {
+        var urlReg = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/;
+        var urls = location.origin.includes("localhost") ? '' : urlReg.exec(location.origin)[0];
+        if (location.origin.includes("192.168.1") || location.origin.includes("localhost") || location.origin.includes("120.79.166.78")) {
+          urls = "120.79.166.78:19012"
+        }
+        api.commonfreefindTenantId({ hostAdmin: urls })
+          .then(function (res) {
+            if (res.code === 200) {
+              commit('setTENANT_NANE', res.data)
+            } else {
+              commit('setTENANT_NANE', '')
+              sessionStorage.removeItem('TenantId')
+            }
+            resolve()
+          })
+          .catch(function (error) {
+            commit('setTENANT_NANE', '')
+              sessionStorage.removeItem('TenantId')
+            resolve()
+            console.log("TenantIDerror:", error);
+          });
+      })
+    },
+    footerData({
+      commit
+    }) {
+      return new Promise(resolve => {
+        api.commonfreeconfig()
+          .then(function (response) {
+            commit('set_companyName', response.data.companyName)
+            resolve()
+          })
+          .catch(function (error) {
+            commit('set_companyName', '')
+            resolve()
+          });
+      })
+    },
     // 登录
     Login({ commit }, userInfo) {
       const username = userInfo.username.trim()
@@ -42,8 +99,10 @@ const user = {
       // const password = userInfo.password
       const code = userInfo.code
       const uuid = userInfo.uuid
+      const phonenumber = userInfo.phonenumber
+      const smsCode = userInfo.smsCode
       return new Promise((resolve, reject) => {
-        login(username, password, code, uuid).then(res => {
+        login(username, password, code, uuid, phonenumber, smsCode).then(res => {
           setToken(res.token)
           commit('SET_TOKEN', res.token)
           resolve()
@@ -83,6 +142,7 @@ const user = {
           commit('SET_TOKEN', '')
           commit('SET_ROLES', [])
           commit('SET_PERMISSIONS', [])
+          commit('outLogin')
           removeToken()
           resolve()
         }).catch(error => {

+ 3 - 3
src/utils/request.js

@@ -7,8 +7,8 @@ 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.7:5030/'
+// export const baseURL = process.env.VUE_APP_BASE_API
+export const baseURL = 'http://192.168.1.24:5030/'
 export const BASE_IMG_URL = process.env.VUE_APP_IMG_API
 const service = axios.create({
   // axios中请求配置有baseURL选项,表示请求URL公共部分
@@ -23,7 +23,7 @@ service.interceptors.request.use(config => {
   if (getToken() && !isToken) {
     config.headers['AuthorizationToken'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
   }
-  config.headers.TenantId = sessionStorage.TenantId || methods.getQueryVariable('TenantId')
+  config.headers.TenantId = store.state.user.TENANT_NANE || sessionStorage.TenantId || methods.getQueryVariable('TenantId')
   // get请求映射params参数
   if (config.method === 'get' && config.params) {
     let url = config.url + '?';

+ 208 - 0
src/views/2Cport/pageSettings/H5_small.vue

@@ -0,0 +1,208 @@
+<template>
+  <div id="">
+    <el-form
+      :model="moveInfo"
+      status-icon
+      :rules="rulesMove"
+      ref="moveInfo"
+      label-width="100px"
+      class="demo-ruleForm"
+    >
+      <el-form-item label="H5-logo" prop="h5Logo">
+        <div class="imageStyBox" v-if="!moveInfo.h5Logo">
+          <label for="uplose1"><i class="btn_upload">上传图片</i></label>
+          <input
+            type="file"
+            style="display: none"
+            id="uplose1"
+            @change="getImgFile($event, 'h5Logo')"
+          />
+        </div>
+        <div v-else>
+          <el-image
+            class="imageStyBoxShow"
+            :src="$methodsTools.splitImgHost(moveInfo.h5Logo)"
+            :preview-src-list="[$methodsTools.splitImgHost(moveInfo.h5Logo)]"
+          >
+          </el-image>
+          <el-button
+            style="margin-left: 20px"
+            type="danger"
+            size="mini"
+            @click="moveInfo.h5Logo = ''"
+            >删除</el-button
+          >
+        </div>
+      </el-form-item>
+      <el-form-item label="Small-logo" prop="smallLogo">
+        <div class="imageStyBox" v-if="!moveInfo.smallLogo">
+          <label for="uplose2"><i class="btn_upload">上传图片</i></label>
+          <input
+            type="file"
+            style="display: none"
+            id="uplose2"
+            @change="getImgFile($event, 'smallLogo')"
+          />
+        </div>
+        <div v-else>
+          <el-image
+            class="imageStyBoxShow"
+            :src="$methodsTools.splitImgHost(moveInfo.smallLogo)"
+            :preview-src-list="[$methodsTools.splitImgHost(moveInfo.smallLogo)]"
+          >
+          </el-image>
+          <el-button
+            style="margin-left: 20px"
+            type="danger"
+            size="mini"
+            @click="moveInfo.smallLogo = ''"
+            >删除</el-button
+          >
+        </div>
+      </el-form-item>
+      <el-form-item label="H5域名" prop="hostH5">
+        <el-input v-model="moveInfo.hostH5" disabled></el-input>
+      </el-form-item>
+      <el-form-item label="Live域名" prop="hostLive">
+        <el-input v-model="moveInfo.hostLive" disabled></el-input>
+      </el-form-item>
+      <el-form-item label="Pc域名" prop="hostPc">
+        <el-input v-model="moveInfo.hostPc" disabled></el-input>
+      </el-form-item>
+      <el-form-item label="PC小程序" prop="smallQrCodeShow">
+        <el-switch
+          v-model="moveInfo.smallQrCodeShow"
+          active-color="#13ce66"
+          inactive-color="#ff4949"
+        >
+        </el-switch>
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          size="small"
+          type="primary"
+          @click="submitFormRight('moveInfo')"
+          >保存</el-button
+        >
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { listConfig, updateConfig } from "@/api/system/config";
+export default {
+  data() {
+    return {
+      moveDuan: {},
+      moveInfo: {},
+      rulesMove: {
+        h5Logo: [
+          {
+            required: true,
+            message: "请上传h5Logo",
+            trigger: ["blur", "change"],
+          },
+        ],
+        smallLogo: [
+          {
+            required: true,
+            message: "请上传smallLogo",
+            trigger: ["blur", "change"],
+          },
+        ],
+        hostH5: [{ required: false, message: "请输入hostH5", trigger: "blur" }],
+        hostLive: [
+          { required: false, message: "请输入hostLive", trigger: "blur" },
+        ],
+        hostPc: [{ required: false, message: "请输入hostPc", trigger: "blur" }],
+      },
+    };
+  },
+  created() {
+    listConfig({ configKey: "home.mobile" }).then((res) => {
+      if (res.rows.length) {
+        this.moveDuan = res.rows[0];
+        this.moveInfo = JSON.parse(res.rows[0].configValue);
+        console.log(this.moveInfo);
+      }
+    });
+  },
+  methods: {
+    submitFormRight(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          if (!this.moveInfo.h5Logo || !this.moveInfo.smallLogo) {
+            this.$message.error("请上传Logo图片");
+            return;
+          }
+          let data = JSON.parse(JSON.stringify(this.moveInfo));
+          let copySubmitData = JSON.parse(JSON.stringify(this.moveDuan));
+          copySubmitData.configValue = JSON.stringify(data);
+          updateConfig(copySubmitData).then((res) => {
+            this.$message.success("保存成功");
+          });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+
+    /**
+     * 上传图片
+     */
+    getImgFile(e, name) {
+      var self = this;
+      var file = e.target.files[0];
+      if (file === undefined) {
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = e.target.value.toLowerCase().split(".").splice(-1);
+      if (type[0] != "jpg" && type[0] != "png" && type[0] != "jpeg") {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg");
+        e.target.value = "";
+        return;
+      }
+      this.$upload
+        .upload(file, 0)
+        .then((res) => {
+          self.moveInfo[name] = res;
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.btn_upload {
+  font-style: normal;
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
+  cursor: pointer;
+  background: #ffffff;
+  border: 1px solid #dcdfe6;
+  border-color: #dcdfe6;
+  color: #606266;
+  text-align: center;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  outline: none;
+  margin: 0;
+  -webkit-transition: 0.1s;
+  transition: 0.1s;
+  font-weight: 400;
+  user-select: none;
+  padding: 12px 20px;
+  font-size: 14px;
+  border-radius: 4px;
+}
+</style>

+ 73 - 4
src/views/2Cport/pageSettings/footer.vue

@@ -38,6 +38,36 @@
         <el-button :size="size" type="primary" @click="submit">保 存</el-button>
       </div>
     </div>
+    <div class="right_box">
+      <el-form
+        :model="ruleForm"
+        status-icon
+        :rules="rulesRight"
+        ref="ruleForm"
+        label-width="100px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="备案号" prop="footerTip">
+          <el-input
+            :autosize="{ minRows: 4, maxRows: 15 }"
+            type="textarea"
+            v-model="ruleForm.footerTip"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="其他说明" prop="footerRecordNo">
+          <el-input
+            :autosize="{ minRows: 4, maxRows: 15 }"
+            type="textarea"
+            v-model="ruleForm.footerRecordNo"
+          ></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="submitFormRight('ruleForm')"
+            >保存</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </div>
     <el-dialog
       @closed="loadingClose"
       :visible.sync="dialogVisible"
@@ -77,7 +107,7 @@
 </template>
 
 <script>
-import { listConfig,updateConfig } from "@/api/system/config";
+import { listConfig, updateConfig } from "@/api/system/config";
 export default {
   data() {
     return {
@@ -110,9 +140,20 @@ export default {
         name: [{ required: true, message: "请填写文本内容", trigger: "blur" }],
       },
       newIndex: "",
+
+      BData: {},
+      ruleForm: {},
+      rulesRight: {
+        footerTip: [
+          { required: true, message: "请输入备案号", trigger: "blur" },
+        ],
+        footerRecordNo: [
+          { required: false, message: "请输入其他说明", trigger: "blur" },
+        ],
+      },
     };
   },
-  mounted() {
+  created() {
     this.init();
   },
   methods: {
@@ -181,11 +222,34 @@ export default {
         }
       });
     },
+    submitFormRight(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          let data = JSON.parse(JSON.stringify(this.ruleForm));
+          let copySubmitData = JSON.parse(JSON.stringify(this.BData));
+          copySubmitData.configValue = JSON.stringify(data);
+          updateConfig(copySubmitData).then((res) => {
+            this.$message.success("保存成功");
+          });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
     init() {
       listConfig({ configKey: "home.footer" }).then((res) => {
         if (res.rows.length) {
-          this.initData = res.rows[0];
-          this.listData = JSON.parse(res.rows[0].configValue);
+          res.rows.forEach((item) => {
+            if (item.configKey === "home.footer") {
+              this.initData = item;
+              this.listData = JSON.parse(item.configValue);
+            }
+            if (item.configKey === "home.footer.record") {
+              this.BData = item;
+              this.ruleForm = JSON.parse(item.configValue);
+            }
+          });
         }
       });
     },
@@ -203,8 +267,13 @@ export default {
 
 <style lang="less" scoped>
 .smallBox {
+  float: left;
   width: 700px;
 }
+.right_box {
+  width: 500px;
+  float: left;
+}
 
 /deep/.el-button {
   border-radius: 8px;

+ 4 - 1
src/views/2Cport/pageSettings/index.vue

@@ -4,11 +4,13 @@
       <el-tab-pane label="页头设置" name="headerPage"></el-tab-pane>
       <el-tab-pane label="页尾设置" name="footerPage"></el-tab-pane>
       <el-tab-pane label="友情链接" name="linksPage"></el-tab-pane>
+      <el-tab-pane label="移动端配置" name="h5small"></el-tab-pane>
     </el-tabs>
     <div class="allSy">
       <header-page ref="headerPage" v-if="activeName === 'headerPage'" />
       <footer-page ref="footerPage" v-if="activeName === 'footerPage'" />
       <links-page ref="linksPage" v-if="activeName === 'linksPage'" />
+      <h5-small ref="h5small" v-if="activeName === 'h5small'" />
     </div>
   </div>
 </template>
@@ -17,8 +19,9 @@
 import headerPage from "./header.vue";
 import footerPage from "./footer.vue";
 import linksPage from "./links.vue";
+import H5Small from "./H5_small.vue";
 export default {
-  components: { headerPage, footerPage, linksPage },
+  components: { headerPage, footerPage, linksPage,H5Small },
   data() {
     return {
       activeName: "headerPage",

+ 124 - 0
src/views/Marketing/activitySystem/activityList/activityInfo/first.vue

@@ -0,0 +1,124 @@
+<template>
+  <div id="">
+    <el-row>
+      <el-col :span="14">
+        <el-form-item label="活动名称" prop="name">
+          <el-input v-model="ruleForm.name"></el-input>
+        </el-form-item>
+        <el-form-item label="选择模板" prop="posterId">
+          <el-select v-model="ruleForm.posterId" placeholder="请选择模板">
+            <el-option
+              v-for="item in modelList"
+              :label="item.name"
+              :value="item.posterId"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="活动时间" prop="timeList">
+          <el-date-picker
+            v-model="ruleForm.timeList"
+            type="datetimerange"
+            :picker-options="pickerOptions"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            align="right"
+            value-format="timestamp"
+          >
+          </el-date-picker>
+        </el-form-item>
+        </el-col
+      >
+      <el-col :span="6" :offset="4" v-show="ruleForm.posterId">
+        <div style="text-align: center">
+          <el-image
+            style="width: 187.5px; height: 333.5px"
+            :src="ModelUrl(ruleForm.posterId)"
+            :preview-src-list="[ModelUrl(ruleForm.posterId)]"
+          >
+          </el-image>
+          <h2>模板预览</h2>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    ruleForm: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modelList: [],
+      pickerOptions: {
+        shortcuts: [
+          {
+            text: "最近一周",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "最近一个月",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+          {
+            text: "最近三个月",
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+              picker.$emit("pick", [start, end]);
+            },
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.getModelList();
+  },
+  computed: {
+    ModelUrl: function () {
+      return function (k) {
+        if (k) {
+          for (let i = 0; i < this.modelList.length; i++) {
+            if (this.modelList[i].posterId === k) {
+              return this.$methodsTools.splitImgHost(
+                this.modelList[i].url
+              );
+            }
+          }
+        } else {
+          return "";
+        }
+      };
+    },
+  },
+  methods: {
+    //获取模板列表
+    getModelList() {
+      this.$api.inquiredistributionposterlist({ status: 1 }).then((res) => {
+        this.modelList = res.rows;
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 293 - 0
src/views/Marketing/activitySystem/activityList/activityInfo/index.vue

@@ -0,0 +1,293 @@
+<template>
+  <div id="">
+    <el-form
+      :model="ruleForm"
+      :rules="rules"
+      ref="ruleForm"
+      label-width="120px"
+      class="demo-ruleForm"
+      :disabled="status === 'info'"
+    >
+      <First :ruleForm="ruleForm"></First>
+      <Second :ruleForm="ruleForm" @backGoodsList="backGoodsList"></Second>
+      <Three :ruleForm="ruleForm" @backTenantList="backTenantList"></Three
+    ></el-form>
+    <div style="text-align: center">
+      <el-button @click="close">取消</el-button>
+      <el-button
+        type="primary"
+        @click="submitForm('ruleForm')"
+        v-if="status !== 'info'"
+        >保存</el-button
+      >
+      <el-button
+        type="primary"
+        @click="submitForm('ruleForm', true)"
+        v-if="status !== 'info'"
+        >启用</el-button
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import First from "./first.vue";
+import Second from "./second.vue";
+import Three from "./three.vue";
+export default {
+  components: { First, Second, Three },
+  data() {
+    return {
+      ruleForm: {
+        status: 0,
+        goodsList: [], //商品列表
+        tenantList: [], //机构列表
+      },
+      rules: {
+        name: [{ required: true, message: "请输入活动名称", trigger: "blur" }],
+        posterId: [
+          { required: true, message: "请选择模板", trigger: "change" },
+        ],
+        timeList: [
+          { required: true, message: "请选择活动时间", trigger: "change" },
+        ],
+        freezingPeriod: [
+          { required: true, message: "请输入佣金冻结天数", trigger: "blur" },
+        ],
+      },
+      id: "",
+    };
+  },
+  created() {
+    this.id = this.$route.query.id;
+    this.status = this.$route.query.status;
+    if (this.id) {
+      this.getInit();
+    }
+  },
+  methods: {
+    close() {
+      this.$store.dispatch("tagsView/exitView", this.$route).then((res) => {
+        this.$router.push({
+          path: "activityList",
+        });
+      });
+    },
+    getInit() {
+      this.$api.distributiontempdata(this.id).then((res) => {
+        res.data.timeList = [
+          parseInt(res.data.startTime * 1000),
+          parseInt(res.data.endTime * 1000),
+        ];
+        res.data.goodsList = res.data.goodsList || []
+        this.$nextTick(() => {
+          this.ruleForm = res.data;
+        });
+      });
+    },
+    //提交
+    submitForm(formName, status) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.checkGoodsFunc()
+            .then(() => {
+              var data = JSON.parse(JSON.stringify(this.ruleForm));
+              data.startTime = data.timeList[0] / 1000;
+              data.endTime = data.timeList[1] / 1000;
+              if (status) {
+                data.status = 1;
+              }
+              this.$api[
+                data.distributionId
+                  ? "editdistributiontemp"
+                  : "distributiontempsave"
+              ](data).then((res) => {
+                this.$message.success("成功");
+                setTimeout(() => {
+                  this.$store
+                    .dispatch("tagsView/exitView", this.$route)
+                    .then((res) => {
+                      this.$router.push({
+                        path: "activityList",
+                      });
+                    });
+                }, 300);
+              });
+            })
+            .catch((err) => {
+              this.$message.error(err);
+            });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    //处理商品佣金逻辑
+    checkGoodsFunc() {
+      return new Promise((resolve, reject) => {
+        for (let i = 0; i < this.ruleForm.goodsList.length; i++) {
+          if (this.ruleForm.goodsList[i].profitType === 1) {
+            //百分比处理
+            if (this.ruleForm.goodsList[i].profitMax > 100) {
+              return reject(`请检查第${i + 1}个商品的数组设置`);
+            } else {
+              let countNum =
+                parseFloat(this.ruleForm.goodsList[i].profitOne) +
+                parseFloat(this.ruleForm.goodsList[i].profitTwo) +
+                parseFloat(this.ruleForm.goodsList[i].profitThree);
+              if (countNum > this.ruleForm.goodsList[i].profitMax) {
+                return reject(
+                  `请检查第${
+                    i + 1
+                  }个商品的佣金设置,三个级别佣金相加不能大于数值`
+                );
+              }
+            }
+          }
+          if (this.ruleForm.goodsList[i].profitType === 2) {
+            //固定金额处理
+            if (
+              this.ruleForm.goodsList[i].profitMax >
+              this.ruleForm.goodsList[i].goodsPrice
+            ) {
+              return reject(`请检查第${i + 1}个商品的数组设置`);
+            } else {
+              let countNum =
+                parseFloat(this.ruleForm.goodsList[i].profitOne) +
+                parseFloat(this.ruleForm.goodsList[i].profitTwo) +
+                parseFloat(this.ruleForm.goodsList[i].profitThree);
+              if (countNum > this.ruleForm.goodsList[i].profitMax) {
+                return reject(
+                  `请检查第${
+                    i + 1
+                  }个商品的佣金设置,三个级别佣金相加不能大于数值`
+                );
+              }
+            }
+          }
+        }
+        resolve();
+      });
+    },
+    //商品列表选中返回
+    backGoodsList(e) {
+      this.$nextTick(() => {
+        this.ruleForm.goodsList.push(...e);
+      });
+    },
+    //机构列表选中返回
+    backTenantList(e) {
+      this.$nextTick(() => {
+        this.ruleForm.tenantList.push(...e);
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" 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>

+ 226 - 0
src/views/Marketing/activitySystem/activityList/activityInfo/second.vue

@@ -0,0 +1,226 @@
+<template>
+  <div id="">
+    <el-row>
+      <el-col :span="24">
+        <el-form-item label="设置商品及佣金" prop="goodsList">
+          <p>
+            <el-button type="primary" @click="activeGoods">新增</el-button>
+            <el-form style="float:left;margin-right: 10px;">
+              <!-- 详情出现 --><el-button
+                v-if="ruleForm.tempId"
+                type="primary"
+                @click="pull"
+                :disabled="false"
+                >拉取商品</el-button
+              >
+            </el-form>
+          </p>
+          <el-table :data="ruleForm.goodsList" border style="width: 100%">
+            <el-table-column
+              align="center"
+              v-for="(item, index) in goodsSet"
+              :key="index"
+              :prop="item.prop"
+              :label="item.label"
+              :width="item.width"
+              show-overflow-tooltip
+            >
+              <template slot-scope="scope">
+                <el-input-number
+                  v-if="item.scope === 'price'"
+                  style="width: 100px"
+                  v-model="scope.row[item.prop]"
+                  :precision="scope.row['profitType'] === 1 ? 0 : 2"
+                  :min="0"
+                  :controls="false"
+                ></el-input-number>
+                <el-input-number
+                  v-else-if="item.scope === 'goodsPrice'"
+                  style="width: 100px"
+                  v-model="scope.row[item.prop]"
+                  :precision="2"
+                  :min="0"
+                  :controls="false"
+                  @change="
+                    {
+                      (scope.row['profitMax'] = ''),
+                        (scope.row['profitOne'] = ''),
+                        (scope.row['profitTwo'] = ''),
+                        (scope.row['profitThree'] = '');
+                    }
+                  "
+                ></el-input-number>
+                <el-input-number
+                  v-else-if="item.scope === 'priceChan'"
+                  style="width: 100px"
+                  v-model="scope.row[item.prop]"
+                  :precision="scope.row['profitType'] === 1 ? 0 : 2"
+                  :min="0"
+                  :max="
+                    scope.row['profitType'] === 1
+                      ? 100
+                      : scope.row['profitType'] === 2
+                      ? scope.row['goodsPrice']
+                      : ''
+                  "
+                  :controls="false"
+                ></el-input-number>
+                <el-select
+                  v-else-if="item.scope === 'select'"
+                  v-model="scope.row[item.prop]"
+                  placeholder="请选择分佣方式"
+                  @change="
+                    {
+                      (scope.row['profitMax'] = ''),
+                        (scope.row['profitOne'] = ''),
+                        (scope.row['profitTwo'] = ''),
+                        (scope.row['profitThree'] = '');
+                    }
+                  "
+                >
+                  <el-option
+                    v-for="item in profitTypeList"
+                    :label="item.label"
+                    :value="item.value"
+                  ></el-option>
+                </el-select>
+                <span v-else>{{ scope.row[item.prop] }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              fixed="right"
+              label="操作"
+              width="100"
+              align="center"
+            >
+              <template slot-scope="scope">
+                <el-button
+                  type="text"
+                  size="small"
+                  @click="ruleForm.goodsList.splice(scope.$index, 1)"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column></el-table
+          >
+        </el-form-item>
+        <p
+          style="
+            color: rgba(134, 144, 156, 1);
+            font-size: 16px;
+            margin-left: 120px;
+          "
+        >
+          分佣方式设置为百分比时,数值不能超过100%,3个等级的佣金总和不能超过100%;<br />分佣方式设置为固定金额时,数值不能超过该固定金额,3个等级的佣金总和不能超过该数值。
+        </p>
+        <el-form-item label="佣金冻结期" prop="freezingPeriod">
+          <el-input-number
+            style="width: 70px"
+            v-model="ruleForm.freezingPeriod"
+            :precision="0"
+            :max="9999"
+            :min="0"
+            :controls="false"
+          ></el-input-number>
+          <span style="margin-left: 8px; font-weight: bold">天</span>
+        </el-form-item>
+        <p
+          style="
+            color: rgba(134, 144, 156, 1);
+            font-size: 16px;
+            margin-left: 120px;
+          "
+        >
+          冻结期的设置要考虑到退款的可能并设置安全合理的天数,建议最少为3天;
+        </p>
+      </el-col>
+    </el-row>
+    <goodsList ref="goodsList" v-on="$listeners"></goodsList>
+  </div>
+</template>
+
+<script>
+import goodsList from "@/components/goodsList";
+export default {
+  components: { goodsList },
+  props: {
+    ruleForm: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      goodsSet: [
+        {
+          label: "商品名称",
+          prop: "goodsName",
+        },
+        {
+          label: "价格",
+          prop: "goodsPrice",
+          scope: "goodsPrice",
+          width: "130",
+        },
+        {
+          label: "分佣方式",
+          prop: "profitType",
+          scope: "select",
+          width: "170",
+        },
+        {
+          label: "数值",
+          prop: "profitMax",
+          scope: "priceChan",
+          width: "130",
+        },
+        {
+          label: "一级佣金",
+          prop: "profitOne",
+          scope: "price",
+          width: "130",
+        },
+        {
+          label: "二级佣金",
+          prop: "profitTwo",
+          scope: "price",
+          width: "130",
+        },
+        {
+          label: "三级佣金",
+          prop: "profitThree",
+          scope: "price",
+          width: "130",
+        },
+      ],
+      profitTypeList: [
+        {
+          label: "百分比(%)",
+          value: 1,
+        },
+        {
+          label: "固定金额(元)",
+          value: 2,
+        },
+      ],
+    };
+  },
+  methods: {
+    activeGoods() {
+      const array = this.ruleForm.goodsList.map((item) => item.goodsId);
+      this.$refs.goodsList.showBox(array);
+    },
+    pull() {
+      this.$api
+        .distributionactivitypullgoods(this.ruleForm.distributionId)
+        .then((res) => {
+          this.$message.success("操作成功");
+        });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 194 - 0
src/views/Marketing/activitySystem/activityList/activityInfo/tenant.vue

@@ -0,0 +1,194 @@
+<template>
+  <div id="">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="1088px"
+      :show-close="false"
+      :close-on-click-modal="false"
+      destroy-on-close
+      @closed="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-table
+        ref="table"
+        row-key="tenantId"
+        :data="tableData"
+        v-loading="loading"
+        border
+        style="width: 100%"
+        @selection-change="selectionChange"
+      >
+        <el-table-column
+          type="selection"
+          width="55"
+          align="center"
+          reserve-selection
+          :selectable="dis_active"
+        >
+        </el-table-column>
+        <el-table-column
+          align="center"
+          type="index"
+          :disabled="true"
+        ></el-table-column>
+        <template v-for="(item, index) in tableSet">
+          <el-table-column
+            header-align="center"
+            :align="item.align ? item.align : 'center'"
+            :prop="item.prop"
+            :label="item.label"
+            :width="item.width || ''"
+            ><template slot-scope="scope"
+              ><div v-if="item.scope === 'options'">
+                <template v-for="(itemt, indext) in item.options">
+                  <span v-if="itemt.value === scope.row[item.prop]">{{
+                    itemt.label
+                  }}</span>
+                </template>
+              </div>
+              <span v-else>{{ scope.row[item.prop] }}</span></template
+            >
+          </el-table-column>
+        </template>
+      </el-table>
+      <div style="margin-top: 10px; text-align: center">
+        <el-pagination
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+          :current-page="formData.pageNum"
+          :page-sizes="[10, 20, 50, 100]"
+          :page-size="formData.pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="total"
+        >
+        </el-pagination>
+      </div>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="submitTable" :loading="disbtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      disbtn: false,
+      dialogVisible: false,
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "租户ID",
+          prop: "tenantId",
+          hidden: true,
+        },
+        {
+          label: "租户名称",
+          prop: "tenantName",
+          hidden: true,
+        },
+        {
+          label: "地址",
+          prop: "address",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "options",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "失效",
+              value: 0,
+            },
+          ],
+        },
+      ],
+      tableData: [],
+      loading: false,
+      total: 0,
+      outActive: [], //置灰列表
+      active: [], //当前选中
+    };
+  },
+  methods: {
+    selectionChange(e) {
+      this.active = e;
+    },
+    showBox(e) {
+      if (e && e.length > 0) {
+        this.outActive = e;
+      }
+      this.getList(true);
+      this.dialogVisible = true;
+    },
+    dis_active(e) {
+      return this.outActive.includes(e.tenantId) ? false : true;
+    },
+    getList(int) {
+      if (int) {
+        this.formData = { pageSize: 10, pageNum: 1 };
+      }
+      this.loading = true;
+      this.$api
+        .systemtenantlist(this.formData)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    submitTable() {
+      if (this.active.length === 0) {
+        this.$message.warning("请勾选机构");
+        return;
+      }
+      this.disbtn = true;
+      this.dialogVisible = false;
+      this.$emit("backTenantList", this.active);
+    },
+    close() {
+      this.disbtn = false;
+      this.$refs.table.clearSelection();
+      this.outActive = [];
+      this.active = [];
+    },
+    handleSizeChange(e) {
+      this.formData.pageSize = e;
+      this.formData.pageNum = 1;
+      this.getList();
+    },
+    handleCurrentChange(e) {
+      this.formData.pageNum = e;
+      this.getList();
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 120 - 0
src/views/Marketing/activitySystem/activityList/activityInfo/three.vue

@@ -0,0 +1,120 @@
+<template>
+  <div id="">
+    <el-row>
+      <el-col :span="24">
+        <el-form-item  v-if="false" label="选择推送机构" prop="tenantList">
+          <p>
+            <el-button type="primary" @click="activeTenant">新增</el-button>
+          </p>
+          <el-table :data="ruleForm.tenantList" border style="width: 100%">
+            <el-table-column
+              align="center"
+              v-for="(item, index) in mechanismSet"
+              :key="index"
+              :prop="item.prop"
+              :label="item.label"
+              :width="item.width"
+              show-overflow-tooltip
+            >
+              <template slot-scope="scope">
+                <div v-if="item.scope === 'options'">
+                  <template v-for="(itemt, indext) in item.options">
+                    <span v-if="itemt.value === scope.row[item.prop]">{{
+                      itemt.label
+                    }}</span>
+                  </template>
+                </div>
+                <span v-else>{{ scope.row[item.prop] }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              fixed="right"
+              label="操作"
+              width="100"
+              align="center"
+            >
+              <template slot-scope="scope">
+                <el-button
+                  type="text"
+                  size="small"
+                  @click="ruleForm.tenantList.splice(scope.$index, 1)"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column></el-table
+          >
+        </el-form-item>
+        <el-form-item label="描述" prop="remark">
+          <el-input
+            type="textarea"
+            :rows="6"
+            v-model="ruleForm.remark"
+          ></el-input>
+          <p style="color: rgba(134, 144, 156, 1); font-size: 14px">
+            说明:<br />1.
+            当订单完成以后,该链路上所有推广者根据其相应等级进行分佣,每个推广者的分佣金额或比例不会超过商品的最大限额<br />2.
+            考虑到商品退款情况,商品金额需要完全入账方可解冻对应佣金,具体时间需与业务部门沟通<br />3.
+            选择固定数值时请注意商品成本
+          </p>
+        </el-form-item>
+      </el-col>
+    </el-row>
+    <tenant ref="tenant" v-on="$listeners"></tenant>
+  </div>
+</template>
+
+<script>
+import tenant from "./tenant";
+export default {
+  components: { tenant },
+  props: {
+    ruleForm: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      mechanismSet: [
+        {
+          label: "租户ID",
+          prop: "tenantId",
+        },
+        {
+          label: "租户名称",
+          prop: "tenantName",
+        },
+        {
+          label: "地址",
+          prop: "address",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "options",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "失效",
+              value: 0,
+            },
+          ],
+        },
+      ],
+    };
+  },
+  methods: {
+    activeTenant() {
+      const array = this.ruleForm.tenantList.map((item) => item.tenantId);
+      this.$refs.tenant.showBox(array);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 340 - 0
src/views/Marketing/activitySystem/activityList/index.vue

@@ -0,0 +1,340 @@
+<template>
+  <div id="ActivityList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+      @addClick="addClick"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="editClick(props.scope.row)"
+          >详情</el-button
+        ><el-button
+          v-if="props.scope.row.tempId"
+          type="text"
+          @click="pull(props.scope.row)"
+          >拉取商品</el-button
+        ><el-button
+          v-if="!props.scope.row.tempId && props.scope.row.status !== -1"
+          type="text"
+          @click="sendUpload(props.scope.row)"
+          >{{ props.scope.row.status === 1 ? "禁用" : "启用" }}</el-button
+        ><el-button
+          v-if="props.scope.row.status === 0 && !props.scope.row.tempId"
+          type="text"
+          @click="editClick(props.scope.row, true)"
+          >修改</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: "ActivityList",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "活动管理",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: false,
+        openCheckMore: true,
+        changeWidth: "160px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          lable: "活动名称",
+          prop: "name",
+          placeholder: "请输入活动名称",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "活动名称",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "活动类型",
+          prop: "type",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "分销活动",
+              value: 1,
+            },
+          ],
+        },
+        {
+          label: "模板",
+          prop: "posterTempName",
+          hidden: true,
+        },
+        {
+          label: "活动开始时间",
+          prop: "startTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "活动结束时间",
+          prop: "endTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "启用",
+              value: 1,
+            },
+            {
+              label: "禁用",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    addClick() {
+      this.$router.push({
+        path: "activityInfo",
+        status: "add",
+      });
+      // this.$refs.model.showBox();
+    },
+    editClick(e, status) {
+      this.$router.push({
+        path: "activityInfo",
+        query: {
+          id: e.distributionId,
+          status: status ? "edit" : "info",
+        },
+      });
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      // if (this.formData.classStartTime) {
+      //   data.classStartTime = parseInt(data.classStartTime / 1000);
+      // }
+      // if (this.formData.classEndTime) {
+      //   data.classEndTime = parseInt(data.classEndTime / 1000);
+      // }
+      this.$api
+        .distributiontemplist(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    sendUpload(v) {
+      this.$alert(`是否${v.status === 1 ? "禁用" : "启用"}`, "提示", {
+        dangerouslyUseHTMLString: true,
+      })
+        .then(() => {
+          this.$api
+            .editdistributionactivityeditstatus({
+              distributionId: v.distributionId,
+              status: v.status === 1 ? 0 : 1,
+            })
+            .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();
+    },
+    pull(item) {
+      this.$api
+        .distributionactivitypullgoods(item.distributionId)
+        .then((res) => {
+          this.$message.success("操作成功");
+        });
+    },
+  },
+};
+</script>
+
+<style lang="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

+ 292 - 0
src/views/Marketing/activitySystem/posterList/index.vue

@@ -0,0 +1,292 @@
+<template>
+  <div id="posterList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+      @addClick="addClick"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="editClick(props.scope.row)"
+          >编辑</el-button
+        >
+        <el-button type="text" @click="Status(props.scope.row)">{{
+          props.scope.row.status === 1 ? "关闭" : "开启"
+        }}</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <model ref="model"></model>
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import model from "./model.vue";
+export default {
+  // name: "PosterList",
+  components: { searchBoxNew, tableList, pagination, model },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "模板管理",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: false,
+        openCheckMore: true,
+        changeWidth: "100px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          lable: "模板名称",
+          prop: "name",
+          placeholder: "请输入模板名称",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "模板名称",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "创建时间",
+          prop: "createTime",
+          hidden: true,
+          scope:"aTimeList"
+        },
+        {
+          label: "使用状态",
+          prop: "status",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "开启",
+              value: 1,
+            },
+            {
+              label: "关闭",
+              value: 0,
+            },
+          ],
+        },
+        {
+          label: "备注",
+          prop: "remark",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    Status(e) {
+      this.$api
+        .editdistributionposter({
+          posterId: e.posterId,
+          status: e.status === 1 ? 0 : 1,
+        })
+        .then((res) => {
+          this.$message.success("操作成功");
+          this.search();
+        });
+    },
+    addClick() {
+      this.$refs.model.showBox();
+    },
+    editClick(e) {
+      this.$refs.model.showBox(JSON.parse(JSON.stringify(e)))
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.classStartTime) {
+        data.classStartTime = parseInt(data.classStartTime / 1000);
+      }
+      if (this.formData.classEndTime) {
+        data.classEndTime = parseInt(data.classEndTime / 1000);
+      }
+      this.$api
+        .inquiredistributionposterlist(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(() => {
+          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="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

+ 520 - 0
src/views/Marketing/activitySystem/posterList/model.vue

@@ -0,0 +1,520 @@
+<template>
+  <div id="">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="1160px"
+      :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>
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="100px"
+        class="demo-ruleForm"
+        ><el-form-item label="模板名称" prop="name">
+          <el-input v-model="ruleForm.name"></el-input>
+        </el-form-item>
+        <el-form-item label="模板配置">
+          <div id="content">
+            <modelView
+              ref="modelView"
+              :modelData="modelData"
+              @changeModelData="changeModelData"
+            ></modelView>
+            <div class="right">
+              <div class="lis">
+                <el-checkbox v-model="modelData.title.checked"
+                  >标题:</el-checkbox
+                ><el-input v-model="modelData.title.name"></el-input
+                ><el-color-picker
+                  v-model="modelData.title.css.color"
+                  show-alpha
+                ></el-color-picker>
+                <el-input
+                  placeholder="请输入字体大小"
+                  v-model="modelData.title.css.fontSize"
+                >
+                  <template slot="prepend">字体大小</template></el-input
+                >
+              </div>
+              <div class="lis">
+                <el-checkbox v-model="modelData.background.checked"
+                  >背景图:</el-checkbox
+                ><el-select
+                  v-model="modelData.background.name"
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="(item, index) in backImgList"
+                    :key="index"
+                    :label="item.name"
+                    :value="item.url"
+                  >
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="lis">
+                <el-checkbox v-model="modelData.goods.checked"
+                  >商品图:</el-checkbox
+                ><label for="goods"
+                  ><i class="btn">{{
+                    modelData.goods.name ? "更换商品图" : "上传商品图"
+                  }}</i></label
+                ><input
+                  style="display: none"
+                  id="goods"
+                  type="file"
+                  @change="uploadImg"
+                />
+              </div>
+              <div class="lis">
+                <el-checkbox v-model="modelData.distribution.checked"
+                  >分销码</el-checkbox
+                >
+                <el-checkbox v-model="modelData.cardCode.checked"
+                  >电子名片码</el-checkbox
+                >
+              </div>
+              <div class="lis">
+                <el-checkbox v-model="modelData.advertise.checked"
+                  >广告语:</el-checkbox
+                ><el-input
+                  type="textarea"
+                  :rows="4"
+                  v-model="modelData.advertise.name"
+                ></el-input
+                ><el-color-picker
+                  v-model="modelData.advertise.css.color"
+                  show-alpha
+                ></el-color-picker>
+                <el-input
+                  placeholder="请输入字体大小"
+                  v-model="modelData.advertise.css.fontSize"
+                >
+                  <template slot="prepend">字体大小</template></el-input
+                >
+              </div>
+              <div class="lis">
+                <el-checkbox v-model="modelData.mechanism.checked"
+                  >机构:</el-checkbox
+                ><el-input v-model="modelData.mechanism.name"></el-input
+                ><el-color-picker
+                  v-model="modelData.mechanism.css.color"
+                  show-alpha
+                ></el-color-picker>
+                <el-input
+                  placeholder="请输入字体大小"
+                  v-model="modelData.mechanism.css.fontSize"
+                >
+                  <template slot="prepend">字体大小</template></el-input
+                >
+              </div>
+            </div>
+          </div> </el-form-item
+        ><el-form-item label="状态" prop="status">
+          <el-radio-group v-model="ruleForm.status">
+            <el-radio :label="1">开启</el-radio>
+            <el-radio :label="0">关闭</el-radio>
+          </el-radio-group> </el-form-item
+        ><el-form-item label="备注" prop="remark">
+          <el-input
+            type="textarea"
+            v-model="ruleForm.remark"
+            :rows="4"
+          ></el-input> </el-form-item
+      ></el-form>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button
+          type="primary"
+          :loading="disabledBtn"
+          @click="submit('ruleForm')"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import modelView from "@/components/modelView";
+export default {
+  components: { modelView },
+  data() {
+    return {
+      dialogVisible: false,
+      disabledBtn: false,
+      //   弹窗数据
+      ruleForm: {},
+      rules: {
+        name: [{ required: true, message: "请输入模板名称", trigger: "blur" }],
+        status: [{ required: true, message: "请选择状态", trigger: "change" }],
+        remark: [{ required: false, message: "请输入备注", trigger: "blur" }],
+      },
+      backImgList: [],
+      modelData: {
+        background: {
+          name: "",
+          type: 0,
+          css: {
+            top: "0px",
+            left: "0px",
+            width: "375px",
+            height: "667px",
+            position: "absolute",
+          },
+        },
+        title: {
+          name: "",
+          type: 1,
+          top: 38,
+          left: 0,
+          width: 375,
+          height: 50,
+          css: {
+            textAlign: "center",
+            fontSize: "30px",
+            margin: "0px",
+          },
+        },
+        goods: {
+          // name: require("@/assets/model_images/model1.png"),
+          name: "",
+          type: 2,
+          top: 126,
+          left: 28,
+          width: 330,
+          height: 330,
+          css: {
+            width: "100%",
+            height: "100%",
+          },
+        },
+        distribution: {
+          name: "",
+          type: 3,
+          top: 476,
+          left: 114,
+          width: 121,
+          height: 121,
+          css: {
+            width: "100%",
+            height: "100%",
+          },
+        },
+        cardCode: {
+          name: "",
+          type: 3,
+          top: 476,
+          left: 244,
+          width: 121,
+          height: 121,
+          css: {
+            width: "100%",
+            height: "100%",
+          },
+        },
+        advertise: {
+          name: "",
+          type: 1,
+          top: 490,
+          left: 0,
+          width: 102,
+          height: 96,
+          css: {
+            fontSize: "20px",
+            margin: "0px",
+          },
+        },
+        mechanism: {
+          name: "",
+          type: 1,
+          top: 623,
+          left: 0,
+          width: 375,
+          height: 44,
+          css: {
+            fontSize: "16px",
+            textAlign: "center",
+            margin: "0px",
+          },
+        },
+      },
+    };
+  },
+  created() {
+    this.getPosterBackgroundImgList();
+  },
+  methods: {
+    //获取模板底图
+    getPosterBackgroundImgList() {
+      this.$api.inquiredistributionposterimagelist().then((res) => {
+        this.backImgList = res.data;
+      });
+    },
+    showBox(e) {
+      if (e) {
+        this.$nextTick(() => {
+          this.ruleForm = {
+            name: e.name,
+            posterId: e.posterId,
+            url: e.url,
+            remark: e.remark,
+            status: e.status,
+          };
+          this.modelData = JSON.parse(e.posterConfig);
+        });
+      } else {
+        this.$nextTick(() => {
+          this.modelData = {
+            background: {
+              name: "",
+              type: 0,
+              css: {
+                top: "0px",
+                left: "0px",
+                width: "375px",
+                height: "667px",
+                position: "absolute",
+              },
+            },
+            title: {
+              name: "",
+              type: 1,
+              top: 38,
+              left: 0,
+              width: 375,
+              height: 50,
+              css: {
+                textAlign: "center",
+                fontSize: "30px",
+                margin: "0px",
+                lineHeight: "36px",
+              },
+            },
+            goods: {
+              // name: require("@/assets/model_images/model1.png"),
+              name: "",
+              type: 2,
+              top: 126,
+              left: 28,
+              width: 330,
+              height: 330,
+              css: {
+                width: "100%",
+                height: "100%",
+              },
+            },
+            distribution: {
+              name: "",
+              type: 3,
+              top: 476,
+              left: 114,
+              width: 121,
+              height: 121,
+              css: {
+                width: "100%",
+                height: "100%",
+              },
+            },
+            cardCode: {
+              name: "",
+              type: 3,
+              top: 476,
+              left: 244,
+              width: 121,
+              height: 121,
+              css: {
+                width: "100%",
+                height: "100%",
+              },
+            },
+            advertise: {
+              name: "",
+              type: 1,
+              top: 490,
+              left: 0,
+              width: 102,
+              height: 96,
+              css: {
+                fontSize: "20px",
+                margin: "0px",
+                lineHeight: "36px",
+              },
+            },
+            mechanism: {
+              name: "",
+              type: 1,
+              top: 623,
+              left: 0,
+              width: 375,
+              height: 44,
+              css: {
+                fontSize: "16px",
+                textAlign: "center",
+                margin: "0px",
+                lineHeight: "36px",
+              },
+            },
+          };
+          this.ruleForm = {};
+        });
+      }
+      this.dialogVisible = true;
+    },
+    close() {
+      this.$refs["ruleForm"].clearValidate();
+      this.dialogVisible = false;
+    },
+    submit(formName) {
+      this.$refs[formName].validate(async (valid) => {
+        if (valid) {
+          this.disabledBtn = true;
+          this.ruleForm.url = await this.$refs.modelView.changeFile();
+          this.ruleForm.posterConfig = JSON.stringify(this.modelData);
+          this.$api[
+            this.ruleForm.posterId
+              ? "editdistributionposter"
+              : "distributionpostersave"
+          ](this.ruleForm)
+            .then((res) => {
+              this.dialogVisible = false;
+              console.log(this.$parent);
+              this.$parent.search();
+            })
+            .finally(() => {
+              this.disabledBtn = false;
+            });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    changeModelData(data) {
+      const { name, left, top, width, height } = data;
+      for (let k in this.modelData) {
+        if (k === name) {
+          this.$set(this.modelData[name], "left", left);
+          this.$set(this.modelData[name], "top", top);
+          if (width >= 0) {
+            this.$set(this.modelData[name], "width", width);
+          }
+          if (height >= 0) {
+            this.$set(this.modelData[name], "height", height);
+          }
+        }
+      }
+    },
+    uploadImg(e) {
+      var self = this;
+      var file = e.target.files[0];
+      if (file === undefined) {
+        self.$set(self.modelData.goods, "name", "");
+        e.target.value = "";
+        return;
+      }
+      if (file.size > 0.8 * 1024 * 1024) {
+        self.$message.error("图片不得大于800kb");
+        e.target.value = "";
+        return;
+      }
+      var type = e.target.value.toLowerCase().split(".").splice(-1);
+      if (
+        type[0] != "jpg" &&
+        type[0] != "png" &&
+        type[0] != "jpeg" &&
+        type[0] != "gif"
+      ) {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
+        e.target.value = "";
+        return;
+      }
+      this.$upload
+        .upload(file, 0)
+        .then((res) => {
+          this.$set(self.modelData.goods, "name", res);
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.btn {
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
+  cursor: pointer;
+  background: #ffffff;
+  border: 1px solid #dcdfe6;
+  -webkit-appearance: none;
+  text-align: center;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  outline: none;
+  margin: 0;
+  -webkit-transition: 0.1s;
+  transition: 0.1s;
+  font-weight: 400;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  border-radius: 8px;
+  color: #ffffff;
+  background-color: #1890ff;
+  border-color: #1890ff;
+  padding: 10px 20px;
+  font-size: 14px;
+  font-style: normal;
+}
+.header_img {
+  & > .imageStyBoxShow {
+    border-radius: 50%;
+    overflow: hidden;
+    width: 60px;
+    height: 60px;
+    margin-right: 10px;
+    border: 1px solid #999;
+  }
+  .btns {
+    border: 1px solid #333;
+    color: #333;
+    padding: 4px 6px;
+    font-style: normal;
+    border-radius: 8px;
+    cursor: pointer;
+    user-select: none;
+  }
+}
+.title_i {
+  text-align: center;
+  font-size: 12px;
+  color: rgba(134, 144, 156, 1);
+}
+
+#content {
+  display: flex;
+  & > .right {
+    & > .lis {
+      display: flex;
+      align-items: center;
+      margin-bottom: 10px;
+      & > .el-input {
+        // width: 200px;
+      }
+    }
+  }
+}
+</style>

+ 309 - 0
src/views/Marketing/distribution/commissionList/index.vue

@@ -0,0 +1,309 @@
+<template>
+  <div id="commissionList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="editClick(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: "CommissionList",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "佣金列表",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: true,
+        openCheckMore: true,
+        changeWidth: "100px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          placeholder1: "开始时间",
+          placeholder2: "结束时间",
+          scope: "moreDataPicker",
+        },
+        {
+          lable: "邀请人",
+          prop: "name",
+          placeholder: "请输入邀请人",
+        },
+        {
+          lable: "订单",
+          prop: "name",
+          placeholder: "请输入订单",
+        },
+        {
+          lable: "业务员姓名",
+          prop: "name",
+          placeholder: "请输入业务员姓名",
+        },
+      ],
+      formData: {
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "业务员ID",
+          prop: "id",
+          hidden: true,
+        },
+        {
+          label: "业务员名称",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "联系方式",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "邀请人ID",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "邀请人姓名",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "累计客户数",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "累计推广员数",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "加入时间",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "所属机构",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "佣金总金额",
+          prop: "name",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    editClick(e) {
+      console.log("详情", e);
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.classStartTime) {
+        data.classStartTime = parseInt(data.classStartTime / 1000);
+      }
+      if (this.formData.classEndTime) {
+        data.classEndTime = parseInt(data.classEndTime / 1000);
+      }
+      this.$api
+        .inquirebusinessList(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(() => {
+          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="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

+ 326 - 0
src/views/Marketing/distribution/distributionOrder/index.vue

@@ -0,0 +1,326 @@
+<template>
+  <div id="distributionOrder">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="editClick(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: "DistributionOrder",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "分销订单列表",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: true,
+        openCheckMore: true,
+        changeWidth: "100px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          lable: "机构",
+          prop: "name",
+          placeholder: "请输入机构",
+        },
+        {
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          placeholder1: "开始时间",
+          placeholder2: "结束时间",
+          scope: "moreDataPicker",
+        },
+        {
+          lable: "姓名",
+          prop: "name",
+          placeholder: "请输入姓名",
+        },
+        {
+          lable: "订单号",
+          prop: "name",
+          placeholder: "请输入订单号",
+        },
+        {
+          prop: "status",
+          placeholder: "状态",
+          scope: "select",
+          noClear: false,
+          options: [
+            { label: "全部", value: "1,2,3" },
+            { label: "已支付", value: 1 },
+            { label: "未支付", value: 2 },
+            { label: "已退款", value: 3 },
+          ],
+        },
+      ],
+      formData: {
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "编号",
+          prop: "id",
+          hidden: true,
+        },
+        {
+          label: "订单号",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "订单价格",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "所属活动",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "课程",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "学员",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "手机号",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "业务员",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "所属机构",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "交易时间",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "支付状态",
+          prop: "name",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    editClick(e) {
+      console.log("详情", e);
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.classStartTime) {
+        data.classStartTime = parseInt(data.classStartTime / 1000);
+      }
+      if (this.formData.classEndTime) {
+        data.classEndTime = parseInt(data.classEndTime / 1000);
+      }
+      this.$api
+        .inquirebusinessList(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(() => {
+          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="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

+ 282 - 0
src/views/Marketing/distribution/rankingList/index.vue

@@ -0,0 +1,282 @@
+<template>
+  <div id="rankingList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+    </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: "RankingList",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        tableHide:true,
+        title: "排行榜",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: true,
+        openCheckMore: true,
+        changeWidth: "100px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          placeholder1: "开始时间",
+          placeholder2: "结束时间",
+          scope: "moreDataPicker",
+        },
+        {
+          prop: "status1",
+          placeholder: "范围",
+          scope: "select",
+          noClear: false,
+          options: [
+            { label: "是", value: 1 },
+            { label: "否", value: 0 },
+          ],
+        },
+        {
+          prop: "status2",
+          placeholder: "活动",
+          scope: "select",
+          noClear: false,
+          options: [
+            { label: "是", value: 1 },
+            { label: "否", value: 0 },
+          ],
+        },
+      ],
+      formData: {
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          hidden: true,
+        },
+        {
+          label: "名称",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "佣金总额",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "时间",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "所属活动",
+          prop: "name",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.classStartTime) {
+        data.classStartTime = parseInt(data.classStartTime / 1000);
+      }
+      if (this.formData.classEndTime) {
+        data.classEndTime = parseInt(data.classEndTime / 1000);
+      }
+      this.$api
+        .inquirebusinessList(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(() => {
+          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="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

+ 250 - 0
src/views/Marketing/distribution/salesmanList/formBox.vue

@@ -0,0 +1,250 @@
+<template>
+  <div id="">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :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="110px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item
+            v-for="(items, indexs) in listitem"
+            :key="indexs"
+            :label="items.label"
+            :prop="items.prop"
+          >
+            <div v-if="items.scope === 'header_img'" class="header_img">
+              <el-image
+                v-if="listData[items.prop]"
+                class="imageStyBoxShow"
+                :src="$methodsTools.splitImgHost(listData[items.prop])"
+                :preview-src-list="[
+                  $methodsTools.splitImgHost(listData[items.prop]),
+                ]"
+              >
+              </el-image>
+              <label for="imgs"
+                ><i class="btns">{{
+                  listData[items.prop] ? "更换头像" : "上传头像"
+                }}</i></label
+              >
+              <input
+                id="imgs"
+                type="file"
+                style="display: none"
+                @change="uploadImg"
+              />
+            </div>
+            <el-input v-else v-model="listData[items.prop]"></el-input>
+          </el-form-item>
+        </el-form>
+        <p class="title_i">创建新账户时,默认密码为身份证号末6位</p>
+      </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() {
+    var validatorphone = (rule, value, callback) => {
+      var reg = /^1(3|4|5|6|7|8|9)\d{9}$/;
+      if (!value) {
+        return callback(new Error("请输入手机号码"));
+      } else if (!reg.test(value)) {
+        return callback(new Error("请输入正确手机号码"));
+      } else {
+        callback();
+      }
+    };
+    var validatorIdCode = (rule, value, callback) => {
+      var reg =
+        /^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
+
+      if (!value) {
+        return callback(new Error("请输入身份证号码"));
+      } else if (!reg.test(value)) {
+        return callback(new Error("请输入正确身份证号码"));
+      } else {
+        callback();
+      }
+    };
+    return {
+      // 弹窗字段
+      listitem: [
+        {
+          label: "头像",
+          prop: "avatar",
+          scope: "header_img",
+        },
+        {
+          label: "姓名",
+          prop: "realname",
+        },
+        {
+          label: "手机号码",
+          prop: "telphone",
+        },
+        {
+          label: "身份证号",
+          prop: "idCard",
+        },
+      ],
+      dialogVisible: false,
+      disabledBtn: false,
+      //   弹窗数据
+      listData: {
+        realname: "",
+        telphone: "",
+        idCard: "",
+        status: 1,
+      },
+      //表单验证
+      rules: {
+        avatar: [
+          {
+            required: true,
+            message: "请上传头像",
+            trigger: ["blur", "change"],
+          },
+        ],
+        realname: [
+          {
+            required: true,
+            message: "请输入姓名",
+            trigger: "blur",
+          },
+        ],
+        telphone: [
+          { required: true, validator: validatorphone, trigger: "blur" },
+        ],
+        idCard: [
+          { required: true, validator: validatorIdCode, trigger: "blur" },
+        ],
+      },
+    };
+  },
+  methods: {
+    uploadImg(e) {
+      var file = e.target.files[0];
+      if (file === undefined) {
+        e.target.value = "";
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        this.$message.warning("图片不得大于300kb");
+        e.target.value = "";
+        return;
+      }
+      var type = e.target.value.toLowerCase().split(".").splice(-1);
+      if (type[0] != "jpg" && type[0] != "png" && type[0] != "jpeg") {
+        this.$message.warning("上传格式需为:.jpg/.png/.jpeg");
+        e.target.value = "";
+        return;
+      }
+      this.$upload
+        .upload(file, 0)
+        .then((res) => {
+          this.$set(this.listData, "avatar", res);
+          this.$refs["listData"].validateField("avatar");
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
+    },
+    showBox(id) {
+      if (id) {
+        this.$api.distributionseller(id).then((res) => {
+          this.listData = res.data;
+        });
+      } else {
+        this.listData = {
+          realname: "",
+          telphone: "",
+          idCard: "",
+          status: 1,
+        };
+      }
+      this.dialogVisible = true;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      this.disabledBtn = true;
+      this.$api[
+        this.listData.sellerId
+          ? "editDistributionseller"
+          : "addDistributionseller"
+      ](this.listData)
+        .then((res) => {
+          this.$message.success("操作成功");
+          this.dialogVisible = false;
+          this.$parent.search();
+        })
+        .finally(() => {
+          this.disabledBtn = false;
+        });
+    },
+    close() {
+      this.$refs.listData.clearValidate();
+      this.dialogVisible = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.header_img {
+  & > .imageStyBoxShow {
+    border-radius: 50%;
+    overflow: hidden;
+    width: 60px;
+    height: 60px;
+    margin-right: 10px;
+    border: 1px solid #999;
+  }
+  .btns {
+    border: 1px solid #333;
+    color: #333;
+    padding: 4px 6px;
+    font-style: normal;
+    border-radius: 8px;
+    cursor: pointer;
+    user-select: none;
+  }
+}
+.title_i {
+  text-align: center;
+  font-size: 12px;
+  color: rgba(134, 144, 156, 1);
+}
+</style>

+ 319 - 0
src/views/Marketing/distribution/salesmanList/index.vue

@@ -0,0 +1,319 @@
+<template>
+  <div id="salesmanList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="sellerId"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      @addClick="addClick"
+      :loading="loading"
+    >
+      <template slot="customize">
+        <el-button @click="sales" type="success" size="medium"
+          >关联现有业务员</el-button
+        >
+      </template>
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="statusChange(props.scope.row)">{{
+          props.scope.row.status === 1 ? "禁用" : "启用"
+        }}</el-button>
+        <el-button type="text" @click="editClick(props.scope.row)"
+          >修改</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <form-box ref="formBox"></form-box>
+    <sales-checkout ref="salesCheckout"> </sales-checkout>
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import FormBox from "./formBox.vue";
+import salesCheckout from "./salesCheckout.vue";
+export default {
+  name: "SalesmanList",
+  components: { searchBoxNew, tableList, pagination, FormBox, salesCheckout },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "业务员列表",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: false,
+        openCheckMore: false,
+        tableHide: false,
+        changeWidth: "180px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          lable: "邀请人",
+          prop: "parentName",
+          placeholder: "请输入邀请人",
+        },
+        {
+          lable: "姓名",
+          prop: "realname",
+          placeholder: "请输入姓名",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "业务员编码",
+          prop: "userAccount",
+          hidden: true,
+        },
+        {
+          label: "姓名",
+          prop: "realname",
+          hidden: true,
+        },
+        {
+          label: "手机号",
+          prop: "telphone",
+          hidden: true,
+        },
+        {
+          label: "身份证号",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "所属机构",
+          prop: "tenantName",
+          hidden: true,
+        },
+        {
+          label: "是否完成提现授权",
+          prop: "gzhOpenId",
+          hidden: true,
+          scope: "isgzhOpenId",
+        },
+        {
+          label: "邀请人ID",
+          prop: "parentAccount",
+          hidden: true,
+        },
+        {
+          label: "邀请人姓名",
+          prop: "parentName",
+          hidden: true,
+        },
+        {
+          label: "成交订单客户数",
+          prop: "orderPeopleNum",
+          hidden: true,
+        },
+        {
+          label: "累计推广员数",
+          prop: "promotionNum",
+          hidden: true,
+        },
+        {
+          label: "账号状态",
+          prop: "status",
+          scope: "isOptions",
+          hidden: true,
+          options: [
+            {
+              label: "有效",
+              value: 1,
+            },
+            {
+              label: "禁止",
+              value: 0,
+            },
+          ],
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    statusChange(row) {
+      this.$api
+        .editDistributionseller({
+          sellerId: row.sellerId,
+          status: row.status === 1 ? 0 : 1,
+        })
+        .then((res) => {
+          this.$message.success("操作成功");
+          this.search();
+        });
+    },
+    //关联业务员
+    sales() {
+      this.$refs.salesCheckout.showBox();
+    },
+    //添加
+    addClick() {
+      this.$refs.formBox.showBox();
+    },
+    editClick(e) {
+      this.$refs.formBox.showBox(e.sellerId);
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .distributionsellerlist(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="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

+ 258 - 0
src/views/Marketing/distribution/salesmanList/salesCheckout.vue

@@ -0,0 +1,258 @@
+<template>
+  <div id="">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="960px"
+      :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>
+      <search-box-new
+        ref="searchBox"
+        :formData="formData"
+        :formList="formList"
+        @search="search"
+        @init="search(1)"
+      />
+      <table-list
+        rowKey="userId"
+        ref="tableList"
+        :tableSets="tableSet"
+        :tableData="tableData"
+        :navText="navText"
+        :loading="loading"
+      >
+        <template slot="btn" slot-scope="props">
+          <el-button type="text" @click="statusChange(props.scope.row)">{{
+            props.scope.row.status === 1 ? "禁用" : "启用"
+          }}</el-button>
+          <el-button type="text" @click="editClick(props.scope.row)"
+            >修改</el-button
+          >
+        </template>
+      </table-list>
+      <pagination
+        :total="total"
+        :pageSize="formData.pageSize"
+        :currentPage="formData.pageNum"
+        @handleSizeChange="handleSizeChange"
+        @handleCurrentChange="handleCurrentChange"
+      />
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" :loading="disabledBtn" @click="submit"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+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: true,
+        choice: true,
+        addHide: true,
+        openCheckMore: true,
+        tableHide: true,
+        changeWidth: "180px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      dialogVisible: false,
+      disabledBtn: false,
+      //   弹窗数据
+      formData: {
+        realname:"",
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      formList: [
+        {
+          lable: "用户昵称",
+          prop: "nickname",
+          placeholder: "请输入用户昵称",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+      // 表单
+      tableSet: [
+        {
+          label: "用户编码",
+          prop: "studentCode",
+          hidden: true,
+        },
+        {
+          label: "头像",
+          prop: "avatar",
+          hidden: true,
+          scope: "img",
+        },
+        {
+          label: "昵称",
+          prop: "nickname",
+          hidden: true,
+        },
+        {
+          label: "性别",
+          prop: "sex",
+          hidden: true,
+          scope: "sex",
+        },
+        {
+          label: "姓名",
+          prop: "realname",
+          hidden: true,
+        },
+        {
+          label: "身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "手机号码",
+          prop: "telphone",
+          hidden: true,
+        },
+        {
+          label: "所在城市",
+          prop1: "province",
+          prop2: "city",
+          prop3: "district",
+          hidden: true,
+          scope: "address",
+        },
+        {
+          label: "注册时间",
+          prop: "createTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "归属来源",
+          prop: "registerPlat",
+          hidden: true,
+          scope: "ptai",
+        },
+        {
+          label: "最后一次登录时间",
+          prop: "lastLoginTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+      ],
+    };
+  },
+  methods: {
+    showBox() {
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.search(1);
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData = {
+        realname:"",
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+        this.$refs.tableList.clearMoreActive();
+      }
+      console.log(this.formData)
+      this.$api
+        .inquireappuserlists(this.formData)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+
+    submit() {
+      if (this.$refs.tableList.allCheckData.length === 0) {
+        this.$message.error("请勾选数据");
+        return;
+      }
+      const Array = this.$refs.tableList.allCheckData.map(
+        (item) => item.userId
+      );
+      this.disabledBtn = true;
+      this.$api
+        .distributionsellerbatchAdd({ userIds: Array })
+        .then((res) => {
+          this.$message.success("操作成功");
+          this.dialogVisible = false;
+          this.$parent.search();
+        })
+        .finally(() => {
+          this.disabledBtn = false;
+        });
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.header_img {
+  & > .imageStyBoxShow {
+    border-radius: 50%;
+    overflow: hidden;
+    width: 60px;
+    height: 60px;
+    margin-right: 10px;
+    border: 1px solid #999;
+  }
+  .btns {
+    border: 1px solid #333;
+    color: #333;
+    padding: 4px 6px;
+    font-style: normal;
+    border-radius: 8px;
+    cursor: pointer;
+    user-select: none;
+  }
+}
+.title_i {
+  text-align: center;
+  font-size: 12px;
+  color: rgba(134, 144, 156, 1);
+}
+</style>

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

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

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

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

+ 4 - 2
src/views/Marketing/goods/commodityManageMent/edit/courseContent/courseCheck.vue

@@ -168,6 +168,9 @@ export default {
     submitTab() {
       this.$message.success("添加成功");
       this.dialogVisibleTableBoxs = false;
+      this.activeLists.forEach((item) => {
+        item.newActive = true;
+      });
       this.$emit("backData", this.activeLists);
     },
     selectCheck(value) {
@@ -196,5 +199,4 @@ export default {
 };
 </script>
 
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

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

@@ -2,14 +2,12 @@
   <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="
@@ -130,13 +128,12 @@
         align="center"
         fixed="right"
         width="100px"
-        v-if="!submitStatusInfo"
       >
         <template slot-scope="scope">
           <el-button
             type="text"
             @click="delCourse(scope.row)"
-            v-if="scope.row.index"
+            v-if="scope.row.index && scope.row.newActive"
             >删除</el-button
           >
           <el-button

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

@@ -289,6 +289,7 @@ export default {
         let ary = this.activeLists.map((item) => {
           const splitStr = item.keyId.split("-").map(Number);
           return {
+            newActive:true,
             type: splitStr[0],
             menuId: splitStr[1],
             menuName: item.name,

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

@@ -237,6 +237,7 @@ export default {
         coverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
         goodsType: "",
         certificateTypeId: "",
+        commitPeriodStatus:0
       },
       rules: {
         year: [
@@ -816,7 +817,7 @@ export default {
     checkSubmitInfo() {
       this.$api.gradecheckGoodsChange({ goodsId: this.goodsId }).then((res) => {
         if (res.data > 0) {
-          // this.submitStatusInfo = true;
+          this.submitStatusInfo = true;
         }
       });
     },

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

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

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

@@ -103,7 +103,6 @@
             placeholder="请选择科目"
             multiple
             collapse-tags
-            :disabled="submitStatusInfo"
             @change="clearList"
           >
             <el-option

+ 4 - 4
src/views/Marketing/goods/commodityManageMent/poppleSet.vue

@@ -240,10 +240,10 @@ export default {
       }
     },
     submitTable() {
-      if (!this.auditionListCope.length) {
-        this.$message.warning("请勾选至少一节的试听时间");
-        return;
-      }
+      // if (!this.auditionListCope.length) {
+      //   this.$message.warning("请勾选至少一节的试听时间");
+      //   return;
+      // }
       for (let i = 0; i < this.auditionListCope.length; i++) {
         if (
           !this.auditionListCope[i].auditionMinute ||

+ 4 - 4
src/views/Marketing/goods/commodityManageMent/poppleSetTK.vue

@@ -137,10 +137,10 @@ export default {
       }
     },
     submitTable() {
-      if (!this.examConfigListCope.length) {
-        this.$message.warning("请勾选至少一张试卷的试做内容");
-        return;
-      }
+      // if (!this.examConfigListCope.length) {
+      //   this.$message.warning("请勾选至少一张试卷的试做内容");
+      //   return;
+      // }
       var arrays = this.$refs.trees.getCheckedNodes();
       for (let i = 0; i < arrays.length; i++) {
         for (let j = 0; j < this.examConfigListCope.length; j++) {

+ 267 - 15
src/views/Marketing/order/pendingRefundOrder/index.vue

@@ -9,7 +9,7 @@
       :topType="topType"
       :pendingType="pendingType"
     />
-    <table-list
+    <!-- <table-list
       rowKey="refundId"
       :tableSets="tableSet"
       :tableData="tableData"
@@ -25,7 +25,109 @@
       <template slot="btn" slot-scope="props">
         <el-button type="text" @click="audit(props.scope.row)">审核</el-button>
       </template>
-    </table-list>
+    </table-list> -->
+    <div
+      style="
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-bottom: 12px;
+      "
+    >
+      <span
+        >退款订单:<span style="color: red">{{ total || 0 }}</span
+        >条</span
+      >
+      <el-button
+        size="small"
+        type="primary"
+        @click="setGoodsOptions"
+        v-if="formData.periodStatus === '1,2' || formData.periodStatus === 0"
+        >批量审核</el-button
+      >
+    </div>
+    <el-table
+      v-if="!loading"
+      ref="tableList"
+      :data="tableData"
+      style="width: 100%"
+      row-key="refundId"
+      border
+      lazy
+      :load="load"
+      :tree-props="prop"
+      :row-class-name="tableRowClassName"
+      @selection-change="handleSelectionChange"
+      @select-all="selectAll"
+      @select="selectRow"
+    >
+      <el-table-column align="center" type="selection" width="55">
+      </el-table-column>
+      <el-table-column
+        v-for="(item, index) in tableSet"
+        header-align="center"
+        :prop="item.prop"
+        sort-by="sort"
+        :key="index"
+        :width="item.width"
+        :label="item.label"
+        :align="index === 0 ? 'left' : 'center'"
+      >
+        <template slot-scope="scope">
+          <span v-if="item.scope === 'aTimeList'">{{
+            scope.row[item.prop] === null
+              ? "--"
+              : $methodsTools.onlyForma(scope.row[item.prop], !item.isDiszing)
+          }}</span>
+          <span v-else-if="item.scope === 'eduTypes'">
+            {{
+              scope.row[item.prop1] +
+              "-" +
+              scope.row[item.prop2] +
+              "-" +
+              scope.row[item.prop3]
+            }}{{ scope.row[item.prop4] ? "-" + scope.row[item.prop4] : "" }}
+          </span>
+          <span v-else-if="item.scope === 'leftCh'">
+            {{ item.ch }}{{ scope.row[item.prop] }}
+          </span>
+          <div v-else-if="item.scope === 'isOptions'">
+            <template v-for="(itemt, indext) in item.options">
+              <span
+                :key="indext"
+                v-if="itemt.value === scope.row[item.prop]"
+                :style="itemt.style ? itemt.style : ''"
+                >{{ itemt.label }}</span
+              >
+            </template>
+          </div>
+          <span v-else-if="item.scope === 'outStandingAmount'">
+            ¥{{ (scope.row[item.prop1] - scope.row[item.prop2]).toFixed(2) }}
+          </span>
+          <div v-else-if="item.scope === 'periodStatusShow'">
+            {{
+              scope.row[item.prop] === 2
+                ? "同意,待退款"
+                : scope.row[item.prop] === 3
+                ? "同意,已退款"
+                : "待审核"
+            }}
+          </div>
+          <span v-else>{{ item.ch }}{{ scope.row[item.prop] }}</span></template
+        >
+      </el-table-column>
+      <el-table-column
+        fixed="right"
+        label="操作"
+        width="120"
+        align="center"
+        v-if="formData.periodStatus === '1,2' || formData.periodStatus === 0"
+      >
+        <template slot-scope="props">
+          <el-button type="text" @click="audit(props.row)">审核</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
     <pagination
       :total="total"
       :pageSize="formData.pageSize"
@@ -39,12 +141,12 @@
 
 <script>
 import searchBoxNew from "@/components/searchBoxNew";
-import tableList from "@/components/tableList";
+// import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
 import refundDia from "./refundDia.vue";
 export default {
   name: "PendingRefundOrder",
-  components: { searchBoxNew, tableList, pagination, refundDia },
+  components: { searchBoxNew, pagination, refundDia },
   data() {
     return {
       loading: false, //当前表单加载是否加载动画
@@ -92,6 +194,7 @@ export default {
         },
       ],
       formData: {
+        searchKey: "",
         goodsType: "",
         periodStatus: 0,
         pageSize: 10,
@@ -100,6 +203,12 @@ export default {
       },
       // 表单
       tableSet: [
+        {
+          label: "订单编码",
+          prop: "orderSn",
+          hidden: true,
+          width: "240px",
+        },
         {
           label: "订单时间",
           prop: "createTime",
@@ -107,12 +216,6 @@ export default {
           scope: "aTimeList",
           width: "180px",
         },
-        {
-          label: "订单编码",
-          prop: "orderSn",
-          hidden: true,
-          width: "210px",
-        },
         {
           label: "手机号码",
           prop: "telphone",
@@ -208,8 +311,15 @@ export default {
       ],
       tableData: [], //表单数据
       total: 0, //一共多少条
+      isCheckedAll: false,
+      allCheckData: [],
+      prop: { hasChildren: "hasChildren", children: "children" },
     };
   },
+  created() {
+    this.formData.searchKey = this.$route.params.orderSn || "";
+    this.formData.periodStatus = this.$route.params.type === "1,2" ? "1,2" : 0;
+  },
   mounted() {
     this.search();
   },
@@ -217,16 +327,119 @@ export default {
     this.search();
   },
   methods: {
+    tableRowClassName({ row, rowIndex }) {
+      if (row.backGround) {
+        return "backGround";
+      } else if (row.childrenGround) {
+        return "childrenGround";
+      } else {
+        return "";
+      }
+    },
+    load(tree, treeNode, resolve) {
+      const table = this.$refs["tableList"];
+      this.$api
+        .obtainOrderRefundlistAll({
+          orderSn: tree.orderSn,
+          periodStatus: this.formData.periodStatus,
+        })
+        .then((res) => {
+          const NewArray = res.data.filter((item) => {
+            item.childrenGround = true;
+            return item.refundId != tree.refundId;
+          });
+          tree.children = NewArray;
+          resolve(NewArray);
+          this.$set(
+            //更新table内部的数据  不这样的话勾选父节点以后子节点还是不能勾选 就很奇怪
+            table.store.states.lazyTreeNodeMap,
+            tree.refundId, //父节点id
+            tree.children //新数组
+          );
+          // 这里判断当前父节点是否有被勾选
+          let dt = this.allCheckData.find((m) => {
+            return m.refundId == tree.refundId;
+          });
+          this.setChildren(tree.children, dt ? true : false);
+        }, 1000)
+        .catch(() => {
+          resolve([]);
+        });
+    },
+    setChildren(children, type) {
+      // 编辑多个子层级
+      children.map((j) => {
+        this.toggleSelection(j, type);
+        if (j.children) {
+          this.setChildren(j.children, type);
+        }
+      });
+    },
+    // 选中父节点时,子节点一起选中取消
+    async selectRow(selection, row) {
+      const hasSelect = selection.some((el) => {
+        return row.refundId === el.refundId;
+      });
+      if (hasSelect) {
+        if (row.children) {
+          // 解决子组件没有被勾选到
+          this.setChildren(row.children, true);
+        }
+      } else {
+        if (row.children) {
+          this.setChildren(row.children, false);
+        }
+      }
+    },
+    // 选择全部
+    selectAll(selection) {
+      // tabledata第一层只要有在selection里面就是全选
+      const isSelect = selection.some((el) => {
+        const tableDataIds = this.tableData.map((j) => j.refundId);
+        return tableDataIds.includes(el.refundId);
+      });
+      // tableDate第一层只要有不在selection里面就是全不选
+      const isCancel = !this.tableData.every((el) => {
+        const selectIds = selection.map((j) => j.refundId);
+        return selectIds.includes(el.refundId);
+      });
+      if (isSelect) {
+        selection.map((el) => {
+          if (el.children) {
+            // 解决子组件没有被勾选到
+            this.setChildren(el.children, true);
+          }
+        });
+      }
+      if (isCancel) {
+        this.tableData.map((el) => {
+          if (el.children) {
+            // 解决子组件没有被勾选到
+            this.setChildren(el.children, false);
+          }
+        });
+      }
+    },
+    toggleSelection(row, select) {
+      if (row) {
+        this.$nextTick(() => {
+          this.$refs.tableList.toggleRowSelection(row, select);
+        });
+      }
+    },
+    handleSelectionChange(selection) {
+      this.allCheckData = selection;
+    },
     /**
      * 批量审核
      */
     setGoodsOptions() {
-      if (!this.$refs.tableList.allCheckData.length) {
+      if (!this.allCheckData.length) {
         this.$message.warning("请选择订单");
         return;
       }
       this.$refs.refundDia.openBox(
-        this.$refs.tableList.allCheckData,
+        this.allCheckData,
         this.formData.periodStatus === "1,2"
           ? 1
           : this.formData.periodStatus === 0
@@ -242,6 +455,7 @@ export default {
       if (int === 2) {
         this.formData = {
           // type: 2,
+          searchKey: "",
           goodsType: "",
           periodStatus: this.formData.periodStatus,
           pageSize: 10,
@@ -253,7 +467,6 @@ export default {
       }
       if (int === 4) {
         this.formData.pageNum = 1;
-        this.$refs.tableList.clearMoreActive();
       }
       var data = JSON.parse(JSON.stringify(this.formData));
       data.inputOrderSn = this.$route.query.inputOrderSn;
@@ -266,14 +479,32 @@ export default {
       this.$api
         .inquireorderrefundlist(data)
         .then((res) => {
-          this.tableData = res.rows;
+          this.tableData = res.rows.map((e) => {
+            if (e.goodsNum > 1) {
+              e.hasChildren = true;
+            }
+            e.backGround = true;
+            return e;
+          });
           this.total = res.total;
           this.navText.index = res.total;
         })
         .finally(() => {
           this.loading = false;
+          this.$nextTick(() => {
+            this.allCheckData = [];
+            this.$refs.tableList.clearSelection();
+            this.expandAll();
+          });
         });
     },
+    expandAll() {
+      // 获取点击的箭头元素
+      let els = document.getElementsByClassName("el-table__expand-icon");
+      for (let i = 0; i < els.length; i++) {
+        els[i].click();
+      }
+    },
     init() {
       this.search(2);
     },
@@ -301,6 +532,28 @@ export default {
 </script>
 
 <style lang="less" scoped>
+// ::v-deep .el-table .backGround {
+//   td {
+//     background-color: rgb(252, 248, 229);
+//   }
+// }
+// ::v-deep .el-table .childrenGround {
+//   td {
+//     background-color: rgb(252, 238, 238);
+//     &:nth-of-type(2) {
+//       background: rgb(237, 246, 245);
+//     }
+//   }
+// }
+// el-table表格对齐
+::v-deep .el-table__row:not([class*="el-table__row--level-"]) {
+  td:nth-of-type(2) {
+    padding-left: 24px !important; //一级数据无Child缩进
+  }
+}
+::v-deep .el-table__placeholder {
+  margin-left: 20px; //子节点无Child缩进
+}
 /deep/.el-button {
   border-radius: 8px;
 }
@@ -394,4 +647,3 @@ export default {
   }
 }
 </style>
-

+ 28 - 6
src/views/Marketing/order/pendingRefundOrder/refundDia.vue

@@ -72,6 +72,8 @@
               <span class="spanSty">审核意见:</span>
               <el-input
                 type="textarea"
+                maxlength="800"
+                show-word-limit
                 v-model="item.periodReason"
                 :size="size"
               ></el-input>
@@ -84,9 +86,16 @@
               <el-radio-group
                 v-model="item.periodStatus"
                 :size="size"
-                @change="item.type === 1 && item.periodStatus === 2 ? (item.periodStatusLine = 3,item.realRefundFee?'':item.realRefundFee = item.refundFee) : item.periodStatusLine = ''"
+                @change="
+                  item.type === 1 && item.periodStatus === 2
+                    ? ((item.periodStatusLine = 3),
+                      item.realRefundFee
+                        ? ''
+                        : (item.realRefundFee = item.refundFee))
+                    : (item.periodStatusLine = '')
+                "
               >
-                <el-radio :label="2" >同意</el-radio>
+                <el-radio :label="2">同意</el-radio>
                 <el-radio :label="-2">拒绝</el-radio>
               </el-radio-group>
             </div>
@@ -100,7 +109,10 @@
                 <el-radio :label="3">已退款</el-radio>
               </el-radio-group>
             </div>
-            <div class="disflex_sty" v-if="item.type === 1 && item.periodStatus === 2">
+            <div
+              class="disflex_sty"
+              v-if="item.type === 1 && item.periodStatus === 2"
+            >
               <span class="spanSty">退款金额:</span><span>¥</span>
               <el-input-number
                 v-model="item.realRefundFee"
@@ -108,13 +120,19 @@
                 :min="0.01"
                 :max="item.refundFee"
                 :controls="false"
-                @blur="item.realRefundFee ? '':item.realRefundFee = item.refundFee"
+                @blur="
+                  item.realRefundFee
+                    ? ''
+                    : (item.realRefundFee = item.refundFee)
+                "
               ></el-input-number>
             </div>
             <div class="disflex_sty">
               <span class="spanSty">审核意见:</span>
               <el-input
                 type="textarea"
+                maxlength="800"
+                show-word-limit
                 v-model="item.periodReviewReason"
                 :size="size"
               ></el-input>
@@ -216,7 +234,9 @@ export default {
           .editorderrefundfirstPeriod(data)
           .then((res) => {
             this.dialogVisible = false;
-            this.$parent.$refs.tableList.clearMoreActive();
+            this.$parent.allCheckData = [];
+            this.$parent.$refs.tableList.clearSelection();
+            this.$parent.formData.searchKey = "";
             this.$parent.search();
           })
           .catch((err) => {
@@ -228,7 +248,9 @@ export default {
           .editorderrefundconfirmPeriod(data)
           .then((res) => {
             this.dialogVisible = false;
-            this.$parent.$refs.tableList.clearMoreActive();
+            this.$parent.allCheckData = [];
+            this.$parent.$refs.tableList.clearSelection();
+            this.$parent.formData.searchKey = "";
             this.$parent.search();
           })
           .catch((err) => {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 2 - 0
src/views/education/classManageMent/classHoursReview/component/LessonTable.vue

@@ -377,6 +377,8 @@ export default {
   padding: 10px 18px;
   ul {
     margin-bottom: 0px;
+    max-height: 588px;
+    overflow: auto;
   }
 }
 .styFlex {

+ 77 - 25
src/views/education/notificationManageMent/stationLetter/index.vue

@@ -8,7 +8,12 @@
       <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
+          v-if="false"
+          size="mini"
+          type="primary"
+          plain
+          @click="notHaveRead"
           >标记为未读</el-button
         ><span style="font-size: 14px; margin-left: 10px">状态:</span
         ><el-select
@@ -121,7 +126,19 @@
       <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>
+        <el-button
+          type="primary"
+          @click="
+            submitChecks(
+              newData.type === 2 || newData.type === 3 ? 2 : 1
+            )
+          "
+          >{{
+            newData.type === 2 || newData.type === 3
+              ? "查看订单"
+              : "查看学员"
+          }}</el-button
+        >
       </span>
     </el-dialog>
   </div>
@@ -134,7 +151,7 @@ export default {
   components: { pagination },
   data() {
     return {
-      newData: {}, //当前数据
+      newData: { remind: "" }, //当前数据
       options: [
         {
           label: "全部",
@@ -245,32 +262,67 @@ export default {
     /**
      * 查看学员
      */
-    submitChecks() {
+    submitChecks(int) {
       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 (int === 2) {
+        const jump = () => {
+          //退款订单列表
+          this.$router.push({
+            name: "PendingRefundOrder",
+            params: {
+              orderSn: this.newData.orderSn,
+              type:
+                this.newData.type === 3
+                  ? "1,2"
+                  : this.newData.type === 2
+                  ? "0"
+                  : "",
+            },
+          });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "PendingRefundOrder";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "PendingRefundOrder",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
         }
-      );
-      if (statusPage) {
-        this.$store
-          .dispatch("tagsView/delCachedView", {
+      }
+      if (int === 1) {
+        const jump = () => {
+          //学员详情
+          this.$router.push({
             name: "StudentXQ",
-          })
-          .then((res) => {
-            jump();
+            query: {
+              id: this.newData.studentUserId,
+            },
           });
-      } else {
-        jump();
+        };
+        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();
+        }
       }
     },
     /**

+ 300 - 0
src/views/finance/paymentList/index.vue

@@ -0,0 +1,300 @@
+<template>
+  <div id="paymentList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="customize">
+        <el-button size="medium" @click="batch" type="warning"
+          >批量支付</el-button
+        > </template
+      ><template slot="btn" slot-scope="props">
+        <el-button type="text" @click="editClick(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: "PaymentList",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "提现支付列表",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: true,
+        addHide: true,
+        openCheckMore: true,
+        changeWidth: "100px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          placeholder1: "开始时间",
+          placeholder2: "结束时间",
+          scope: "moreDataPicker",
+        },
+        {
+          lable: "提现单号",
+          prop: "name",
+          placeholder: "请输入提现单号",
+        },
+        {
+          lable: "姓名",
+          prop: "name",
+          placeholder: "请输入姓名",
+        },
+        {
+          prop: "status1",
+          placeholder: "状态",
+          scope: "select",
+          noClear: false,
+          options: [
+            { label: "待处理", value: 2 },
+            { label: "已处理", value: 1 },
+            { label: "全部", value: 0 },
+          ],
+        },
+      ],
+      formData: {
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          hidden: true,
+        },
+        {
+          label: "名称",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "佣金总额",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "时间",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "所属活动",
+          prop: "name",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    batch() {
+      if (!this.$refs.tableList.allCheckData.length) {
+        this.$message.warning("请勾选需要批量支付的数量");
+        return;
+      }
+    },
+    editClick(e) {
+      console.log("支付", e);
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.classStartTime) {
+        data.classStartTime = parseInt(data.classStartTime / 1000);
+      }
+      if (this.formData.classEndTime) {
+        data.classEndTime = parseInt(data.classEndTime / 1000);
+      }
+      this.$api
+        .inquirebusinessList(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(() => {
+          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="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

+ 139 - 0
src/views/finance/withdrawal/audit.vue

@@ -0,0 +1,139 @@
+<template>
+  <div id="">
+    <el-dialog
+      :visible.sync="dialogVisible"
+      width="560px"
+      :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="110px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item label="申请详情">
+            <div><span>tang</span><span>发起了提现申请</span></div>
+            <div>本次提现金额:¥1500.00</div>
+          </el-form-item>
+
+          <el-form-item label="审核结果" prop="jg">
+            <el-radio-group v-model="listData.jg">
+              <el-radio :label="1">同意</el-radio>
+              <el-radio :label="0">拒绝</el-radio>
+            </el-radio-group>
+          </el-form-item>
+
+          <el-form-item label="审核意见" prop="yj">
+            <el-input
+              type="textarea"
+              :rows="2"
+              v-model="listData.yj"
+            ></el-input>
+          </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 {
+      dialogVisible: false,
+      disabledBtn: false,
+      //   弹窗数据
+      listData: {},
+      //表单验证
+      rules: {
+        jg: [
+          {
+            required: true,
+            message: "请选择审核结果",
+            trigger: "change",
+          },
+        ],
+        yj: [
+          {
+            required: true,
+            message: "请输入审核意见",
+            trigger: "blur",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    showBox(e) {
+      this.dialogVisible = true;
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    rulesTableSumbit() {
+      this.disabledBtn = true;
+      setTimeout(() => {
+        this.$message.success("提交成功");
+        this.disabledBtn = false;
+        this.dialogVisible = false;
+        this.search();
+      }, 500);
+    },
+    close() {
+      this.$refs.listData.clearValidate();
+      this.dialogVisible = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.header_img {
+  & > .imageStyBoxShow {
+    border-radius: 50%;
+    overflow: hidden;
+    width: 60px;
+    height: 60px;
+    margin-right: 10px;
+    border: 1px solid #999;
+  }
+  .btns {
+    border: 1px solid #333;
+    color: #333;
+    padding: 4px 6px;
+    font-style: normal;
+    border-radius: 8px;
+    cursor: pointer;
+    user-select: none;
+  }
+}
+.title_i {
+  text-align: center;
+  font-size: 12px;
+  color: rgba(134, 144, 156, 1);
+}
+</style>

+ 327 - 0
src/views/finance/withdrawal/index.vue

@@ -0,0 +1,327 @@
+<template>
+  <div id="withdrawal">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
+    <table-list
+      rowKey="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+      ><template slot="btn" slot-scope="props"
+        ><el-button type="text" @click="audit(props.scope.row)"
+          >审核</el-button
+        >
+        <el-button type="text" @click="editClick(props.scope.row)"
+          >详情</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <audit ref="audit"></audit>
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import audit from "./audit.vue"
+export default {
+  name: "Withdrawal",
+  components: { searchBoxNew, tableList, pagination,audit },
+  data() {
+    return {
+      disabledBtn: false,
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "提现申请列表",
+        index: 0,
+        ch: "条",
+        num: true,
+        choice: false,
+        addHide: true,
+        openCheckMore: true,
+        changeWidth: "100px",
+        backFatherBtn: {
+          status: false,
+          title: "配置下单填选模板",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop1: "classStartTime",
+          prop2: "classEndTime",
+          placeholder1: "开始时间",
+          placeholder2: "结束时间",
+          scope: "moreDataPicker",
+        },
+        {
+          lable: "提现单号",
+          prop: "name",
+          placeholder: "请输入提现单号",
+        },
+        {
+          lable: "姓名",
+          prop: "name",
+          placeholder: "请输入姓名",
+        },
+        {
+          prop: "status1",
+          placeholder: "状态",
+          scope: "select",
+          noClear: false,
+          options: [
+            { label: "待处理", value: 2 },
+            { label: "已处理", value: 1 },
+            { label: "全部", value: 0 },
+          ],
+        },
+      ],
+      formData: {
+        status: "0,1",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "提现单号",
+          prop: "sort",
+          hidden: true,
+        },
+        {
+          label: "申请时间",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "业务员ID",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "业务员姓名",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "所属机构",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "手机号",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "对应活动",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "提现方式",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "账号",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "金额(元)",
+          prop: "name",
+          hidden: true,
+        },
+        {
+          label: "状态",
+          prop: "name",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    audit(e){
+      this.$refs.audit.showBox(e)
+    },
+    editClick(e) {
+      console.log("支付", e);
+    },
+    search(v) {
+      this.loading = true;
+      if (v === 2) {
+        this.formData = {
+          status: "0,1",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.classStartTime) {
+        data.classStartTime = parseInt(data.classStartTime / 1000);
+      }
+      if (this.formData.classEndTime) {
+        data.classEndTime = parseInt(data.classEndTime / 1000);
+      }
+      this.$api
+        .inquirebusinessList(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(() => {
+          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="scss" 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;
+  }
+}
+.numInputs {
+  width: 150px;
+}
+</style>

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


+ 106 - 2
src/views/login.vue

@@ -1,6 +1,10 @@
 <template>
   <div class="login">
     <div class="login_Left">
+      <h2 class="topName">
+        <img src="@/assets/images/logo@2xSYT.png" alt="" />
+        {{ $store.state.user.companyName }}
+      </h2>
       <div class="anima1"></div>
       <div class="anima2"></div>
       <div class="anima3"></div>
@@ -57,6 +61,27 @@
             <img :src="codeUrl" @click="getCode" class="login-code-img" />
           </div>
         </el-form-item>
+        <div class="mar_stys textStys" v-if="commondual">手机号码</div>
+        <el-form-item prop="phonenumber" v-if="commondual">
+          <el-input
+            v-model="loginForm.phonenumber"
+            type="text"
+            placeholder="请输入手机号码"
+          >
+          </el-input>
+        </el-form-item>
+        <div class="mar_stys textStys" v-if="commondual">手机验证码</div>
+        <el-form-item prop="smsCode" v-if="commondual">
+          <el-input placeholder="获取验证码" v-model="loginForm.smsCode">
+            <span class="btn" slot="suffix" @click="getRegisterSms">
+              {{
+                registerCountDown == 0
+                  ? "获取验证码"
+                  : `${registerCountDown}秒重新获取`
+              }}
+            </span>
+          </el-input>
+        </el-form-item>
         <div class="rightStsyt">
           <el-checkbox v-model="loginForm.rememberMe" class="checkStyles"
             >记住密码</el-checkbox
@@ -85,7 +110,7 @@
 </template>
 
 <script>
-import { getCodeImg } from "@/api/login";
+import { getCodeImg, commondual_auth, commonsms_login } from "@/api/login";
 import Cookies from "js-cookie";
 import { encrypt, decrypt } from "@/utils/jsencrypt";
 
@@ -93,6 +118,7 @@ export default {
   name: "Login",
   data() {
     return {
+      registerCountDown: 0,
       codeUrl: "",
       cookiePassword: "",
       loginForm: {
@@ -101,6 +127,8 @@ export default {
         rememberMe: false,
         code: "",
         uuid: "",
+        phonenumber: "",
+        smsCode: "",
       },
       loginRules: {
         username: [
@@ -110,6 +138,12 @@ export default {
           { required: true, trigger: "blur", message: "请输入您的密码" },
         ],
         code: [{ required: true, trigger: "change", message: "请输入验证码" }],
+        phonenumber: [
+          { required: true, trigger: "blur", message: "请输入手机号码" },
+        ],
+        smsCode: [
+          { required: true, trigger: "blur", message: "请输入手机验证码" },
+        ],
       },
       loading: false,
       // 验证码开关
@@ -117,6 +151,8 @@ export default {
       // 注册开关
       register: false,
       redirect: undefined,
+      commondual: false,
+      getRegisterCodeLock: false,
     };
   },
   watch: {
@@ -128,11 +164,55 @@ export default {
     },
   },
   created() {
-    console.log("---Systems:中正科技")
+    commondual_auth().then((res) => {
+      if (res.data === "1") {
+        this.commondual = true;
+      } else {
+        this.commondual = false;
+      }
+    });
     this.getCode();
     this.getCookie();
   },
   methods: {
+    /**
+     * 获取注册验证码
+     */
+    getRegisterSms() {
+      var self = this;
+      this.$refs.loginForm.validateField("phonenumber", (valid) => {
+        if (!valid) {
+          if (this.registerCountDown == 0) {
+            if (this.getRegisterCodeLock) {
+              return;
+            }
+            this.getRegisterCodeLock = true;
+            commonsms_login({ tel: this.loginForm.phonenumber })
+              .then((res) => {
+                this.getRegisterCodeLock = false;
+                this.$message({
+                  message: `验证码已发送`,
+                  type: "success",
+                });
+                this.registerCountDown = 60;
+                this.registerCountDownTimer = setInterval(() => {
+                  self.registerCountDown--;
+                  if (self.registerCountDown == 0) {
+                    clearInterval(self.registerCountDownTimer);
+                  }
+                }, 1000);
+              })
+              .catch((err) => {
+                this.$message({
+                  message: err.msg,
+                  type: "error",
+                });
+                this.getRegisterCodeLock = false;
+              });
+          }
+        }
+      });
+    },
     getCode() {
       getCodeImg().then((res) => {
         // this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
@@ -199,6 +279,21 @@ export default {
     background: url("../assets/images/left@2x.png") no-repeat center;
     background-size: contain;
     overflow: hidden;
+    .topName {
+      user-select: none;
+      cursor: unset;
+      img {
+        width: 54.4px;
+        height: 38.4px;
+        vertical-align: bottom;
+      }
+      text-shadow: 0px 0px 3px rgba(41, 115, 255, 0.7);
+      position: absolute;
+      color: rgb(41, 115, 255);
+      top: 50px;
+      left: 150px;
+      font-size: 32px;
+    }
     .anima1 {
       position: fixed;
       top: 343px;
@@ -334,4 +429,13 @@ export default {
   display: flex;
   align-items: center;
 }
+
+.btn {
+  font-size: 14px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #3f8dfd;
+  white-space: nowrap;
+  cursor: pointer;
+}
 </style>

+ 11 - 0
src/views/resource/bankManagement/testPaperManagement/BatchImportPop.vue

@@ -8,6 +8,15 @@
     :isShowTip="false"
     @success="ExcelSuccess"
   ></batch-import-dialoga>
+  <batch-import-dialoga
+    v-else-if="type == 3"
+    :dialogVisible.sync="dialogVisible"
+    temUrl="/oss/images/file/20230316/1678948767057.xls"
+    apiKey="importDataBackFromOldList"
+    :isCheck="false"
+    :isShowTip="false"
+    @success="ExcelSuccess"
+  ></batch-import-dialoga>
   <batch-import-dialoga
     v-else
     :dialogVisible.sync="dialogVisible"
@@ -23,6 +32,7 @@
 </template>
 
 <script>
+import * as baseUrls from "@/utils/request.js";
 import batchImportDialoga from "@/components/Comon/batchImportDialog.vue";
 export default {
   data() {
@@ -84,6 +94,7 @@ export default {
       this.$emit("backData", list);
     },
     ExcelSuccess(data) {
+      console.log(data,"data")
       if (data.fullStatus == "全部成功") {
         this.backDataX(data.questionList);
         this.$message.success("全部导入成功");

+ 25 - 7
src/views/resource/bankManagement/testPaperManagement/PaperSort.vue

@@ -29,7 +29,7 @@
           controls-position="right"
           @blur="blur(form[item.key], 'orderNum')"
           :min="1"
-          :max="3"
+          :max="4"
           size="mini"
         ></el-input-number>
         <el-radio
@@ -121,9 +121,10 @@ export default {
     return {
       isShow: false,
       list: [
-        { name: "单选题", key: "caseQuestion" },
+        { name: "单选题", key: "singleChoice" },
         { name: "多选题", key: "multipleChoice" },
-        { name: "案例题", key: "singleChoice" },
+        { name: "判断题", key: "trueFalseQuestion" },
+        { name: "案例题", key: "caseQuestion" },
       ],
       tableData: [{ name: 1 }],
       selectList: [],
@@ -184,7 +185,7 @@ export default {
     },
     initform() {
       this.form = {
-        caseQuestion: {
+        singleChoice: {
           knowledIds: [],
           knum: 0,
           orderNum: 1,
@@ -198,13 +199,20 @@ export default {
           qnum: 0,
           randomNum: 1,
         },
-        singleChoice: {
+        trueFalseQuestion: {
           knowledIds: [],
           knum: 0,
           orderNum: 3,
           qnum: 0,
           randomNum: 1,
         },
+        caseQuestion: {
+          knowledIds: [],
+          knum: 0,
+          orderNum: 4,
+          qnum: 0,
+          randomNum: 1,
+        },
         type: 1,
       };
     },
@@ -213,7 +221,7 @@ export default {
     },
   },
   watch: {
-    "form.caseQuestion.randomNum": {
+    "form.singleChoice.randomNum": {
       handler(val) {
         this.list.forEach((ele) => {
           this.form[ele.key].randomNum = val;
@@ -225,7 +233,17 @@ export default {
         if (!val) {
           this.init();
         } else {
+          var objs = Object.keys(JSON.parse(val));
           this.form = JSON.parse(val);
+          if (!objs.includes("trueFalseQuestion")) {
+            this.form.trueFalseQuestion = {
+              knowledIds: [],
+              knum: 0,
+              orderNum: 3,
+              qnum: 0,
+              randomNum: 1,
+            };
+          }
         }
       },
       deep: true,
@@ -257,4 +275,4 @@ export default {
     }
   }
 }
-</style>
+</style>

+ 31 - 3
src/views/resource/bankManagement/testPaperManagement/addPaper/topicAddPaper/index.vue

@@ -20,7 +20,13 @@
             placeholder="请输入题目内容"
             v-model="keyValue"
             style="margin-right: 10px"
-          ></el-input>
+          ></el-input
+          ><el-button
+            size="medium"
+            @click="$refs.batchPop.openBoxs(tableData, businObj, 3)"
+            type="success"
+            >(旧系统)Excel批量导入</el-button
+          >
           <el-button
             size="medium"
             @click="$refs.batchPop.openBoxs(tableData, businObj, 2)"
@@ -145,7 +151,12 @@
                 v-else
               ></el-input> </el-form-item
           ></el-form>
-          <questionBank :dingFormInfo="listNums" :nums="1" ref="child" />
+          <questionBank
+            :dingFormInfo="listNums"
+            :nums="1"
+            ref="child"
+            :disableTypeStatus="disableTypeStatus"
+          />
         </div>
         <span slot="footer" class="dialog-footer">
           <el-button @click="closeBefore">关 闭</el-button>
@@ -969,6 +980,7 @@ export default {
       uploadStatus: false, //是否同步预览
       simulateConfigJson: "", //随机抽题目分组排序
       simulateStatus: 1,
+      disableTypeStatus: false, //安管禁用简答题
     };
   },
   computed: {
@@ -1110,7 +1122,8 @@ export default {
     },
     getInfos() {
       this.$api.obtainbankexam(this.$route.query.id).then((res) => {
-        console.log(res, "res");
+        this.disableTypeStatus =
+          res.data.businessName === "安管三类" ? true : false;
         this.businObj = {
           businessId: res.data.businessId,
           businessName: res.data.businessName,
@@ -1522,6 +1535,14 @@ export default {
           //   return;
           // }
           var data = this.$refs.child.getInfosPage();
+
+          if (self.disableTypeStatus && data.type == 5) {
+            //安管三类禁止简答题录入
+            self.$message.error(
+              "当前业务层次存在安管三类,禁止录入简答题,请手动修改"
+            );
+            return;
+          }
           if (!data.content || data.content == "<p><br></p>") {
             self.$message.error("请填写题目内容");
             return;
@@ -1551,6 +1572,13 @@ export default {
           }
           if (data.type == 4 && data.optionsList.length) {
             for (let i = 0; i < data.optionsList.length; i++) {
+              if (self.disableTypeStatus && data.optionsList[i].type == 5) {
+                //安管三类禁止简答题录入
+                self.$message.error(
+                  "当前业务层次存在安管三类,禁止录入简答题,请手动修改"
+                );
+                return;
+              }
               if (
                 !data.optionsList[i].content ||
                 data.optionsList[i].content == "<p><br></p>"

+ 30 - 2
src/views/resource/bankManagement/testPaperManagement/editPaper/topicEditPaper/index.vue

@@ -15,7 +15,12 @@
             placeholder="请输入题目内容"
             v-model="keyValue"
             style="margin-right: 10px"
-          ></el-input>
+          ></el-input><el-button
+            size="medium"
+            @click="$refs.batchPop.openBoxs(tableData, businObj, 3)"
+            type="success"
+            >(旧系统)Excel批量导入</el-button
+          >
           <el-button
             size="medium"
             @click="$refs.batchPop.openBoxs(tableData, businObj, 2)"
@@ -149,7 +154,12 @@
                 v-else
               ></el-input> </el-form-item
           ></el-form>
-          <questionBank :dingFormInfo="listNums" :nums="1" ref="child" />
+          <questionBank
+            :dingFormInfo="listNums"
+            :nums="1"
+            ref="child"
+            :disableTypeStatus="disableTypeStatus"
+          />
         </div>
         <span slot="footer" class="dialog-footer">
           <el-button @click="closeBefore">关 闭</el-button>
@@ -981,6 +991,7 @@ export default {
       uploadStatus: false, //是否同步预览
       simulateConfigJson: "",
       simulateStatus: 1,
+      disableTypeStatus:false,//安管三类 禁用简答题
     };
   },
   computed: {
@@ -1123,6 +1134,8 @@ export default {
     },
     getInfos() {
       this.$api.obtainbankexam(this.$route.query.id).then((res) => {
+        this.disableTypeStatus =
+          res.data.businessName === "安管三类" ? true : false;
         this.businObj = {
           businessId: res.data.businessId,
           businessName: res.data.businessName,
@@ -1568,6 +1581,14 @@ export default {
           //   return;
           // }
           var data = this.$refs.child.getInfosPage();
+          
+          if (self.disableTypeStatus && data.type == 5) {
+            //安管三类禁止简答题录入
+            self.$message.error(
+              "当前业务层次存在安管三类,禁止录入简答题,请手动修改"
+            );
+            return;
+          }
           if (!data.content || data.content == "<p><br></p>") {
             self.$message.error("请填写题目内容");
             return;
@@ -1597,6 +1618,13 @@ export default {
           }
           if (data.type == 4 && data.optionsList.length) {
             for (let i = 0; i < data.optionsList.length; i++) {
+              if (self.disableTypeStatus && data.optionsList[i].type == 5) {
+                //安管三类禁止简答题录入
+                self.$message.error(
+                  "当前业务层次存在安管三类,禁止录入简答题,请手动修改"
+                );
+                return;
+              }
               if (
                 !data.optionsList[i].content ||
                 data.optionsList[i].content == "<p><br></p>"

+ 20 - 0
src/views/resource/bankManagement/topicManagement/index.vue

@@ -103,6 +103,7 @@
           :sujectApisTable="sujectApis"
           :newSujectApisTable="newSujectApis"
           :typeBus="typeBus"
+          @disableType="disableType"
         />
         <el-form
           label-position="right"
@@ -168,6 +169,7 @@
           :dingFormInfo="item"
           :nums="index"
           ref="child"
+          :disableTypeStatus="disableTypeStatus"
         />
       </div>
       <span slot="footer" class="dialog-footer">
@@ -452,6 +454,7 @@ export default {
           { required: true, message: "请选择发布状态", trigger: "change" },
         ],
       },
+      disableTypeStatus: false, //是否安管三类 如果是 禁用简答题目
     };
   },
   mounted() {
@@ -463,6 +466,9 @@ export default {
     this.search();
   },
   methods: {
+    disableType(e) {
+      this.disableTypeStatus = e !== -1 ? true : false;
+    },
     batchDel() {
       if (!this.$refs.tableList.allCheckData.length) {
         this.$message.warning("请勾选需要删除的题目");
@@ -815,6 +821,13 @@ export default {
             return;
           }
           var data = this.$refs.child[0].getInfosPage();
+          if (self.disableTypeStatus && data.type == 5) {
+            //安管三类禁止简答题录入
+            self.$message.error(
+              "当前业务层次存在安管三类,禁止录入简答题,请手动修改"
+            );
+            return;
+          }
           if (!data.content || data.content == "<p><br></p>") {
             self.$message.error("请填写题目内容");
             return;
@@ -844,6 +857,13 @@ export default {
           }
           if (data.type == 4 && data.optionsList.length) {
             for (let i = 0; i < data.optionsList.length; i++) {
+              if (self.disableTypeStatus && data.optionsList[i].type == 5) {
+                //安管三类禁止简答题录入
+                self.$message.error(
+                  "当前业务层次存在安管三类,禁止录入简答题,请手动修改"
+                );
+                return;
+              }
               if (
                 !data.optionsList[i].content ||
                 data.optionsList[i].content == "<p><br></p>"

+ 2 - 2
src/views/resource/baseManageInfos/resource/businessLevel/index.vue

@@ -219,7 +219,7 @@
         <el-radio-group v-model="learningOrder">
           <el-radio :label="0">不限制顺序</el-radio>
           <!-- <el-radio :label="1">限制顺序1</el-radio> -->
-          <el-radio :label="2">限制顺序2</el-radio>
+          <el-radio :label="2">限制顺序</el-radio>
         </el-radio-group>
         <p v-if="learningOrder === 1 || learningOrder === 2" style="color: red">
           {{
@@ -361,7 +361,7 @@ export default {
               value: 1,
             },
             {
-              label: "限制顺序2",
+              label: "限制顺序",
               value: 2,
             },
           ],

+ 1 - 0
src/views/resource/baseManageInfos/resource/papers/index.vue

@@ -44,6 +44,7 @@
           :model="listData"
           :rules="rules"
           ref="listData"
+              @submit.native.prevent
         >
           <el-form-item
             v-for="(items, indexs) in listitem"

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

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

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

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

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

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

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

@@ -519,7 +519,7 @@ export default {
           },
         ],
         durationTime: [
-          { required: true, message: "请选择节时长", trigger: "change" },
+          { required: false, message: "请选择节时长", trigger: "change" },
         ],
         liveUrl: [
           {

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

@@ -494,7 +494,7 @@ export default {
           },
         ],
         durationTime: [
-          { required: true, message: "请选择节时长", trigger: "change" },
+          { required: false, message: "请选择节时长", trigger: "change" },
         ],
         liveUrl: [
           {

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

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

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

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

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

@@ -0,0 +1,358 @@
+<template>
+  <div id="">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="search(2)"
+    />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="jumpPage(props.scope.row)"
+          >学习记录</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { searchBoxNew,tableList, pagination },
+  data() {
+    return {
+      size: "small",
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "学习列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        tableHide:true,
+        choice: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formList: [
+        {
+          placeholder: "学员姓名",
+          prop: "realname",
+        },
+        {
+          placeholder: "身份证",
+          prop: "idCard",
+        },
+        {
+          placeholder: "公司名称",
+          prop: "companyName",
+        },
+        {
+          placeholder: "手机号码",
+          prop: "telphone",
+        },
+      ],
+      formData: {
+        realname: "",
+        idcard: "",
+        companyName: "",
+        telphone: "",
+        profileStatus: "",
+        periodStatus: "",
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "基本信息",
+          prop1: "realName",
+          prop2: "idCard",
+          prop3: "companyName",
+          hidden: true,
+          scope: "baseInfo",
+        },
+        {
+          label: "头像",
+          prop: "oneInchPhotos",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
+        {
+          label: "最新拍照",
+          prop: "idCardImg1",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
+        {
+          label: "学习班名称",
+          prop: "className",
+          hidden: true,
+        },
+        {
+          label: "视频名称",
+          prop: "sectionName",
+          hidden: true,
+        },
+        {
+          label: "在线时间",
+          prop: "recordEndTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习时间",
+          prop1: "recordStartTime",
+          prop2: "recordEndTime",
+          scope: "TimeLists",
+          hidden: true,
+        },
+        {
+          label: "时长",
+          prop: "durationTime",
+          hidden: true,
+          scope: "convert",
+        },
+        {
+          label: "是否完成",
+          prop: "recordEndTime",
+          hidden: true,
+          scope: "recordEndTime",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "建造师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    jumpPage(options) {
+      const jump = () => {
+        //班级详情
+        this.$router.push({
+          name: "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,
+          },
+        });
+      };
+      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();
+      }
+    },
+    checkSession(row) {
+      return new Promise((resolve, reject) => {
+        const SESSION = sessionStorage.getItem("hoursAudit");
+        try {
+          if (SESSION) {
+            let parseSession = JSON.parse(SESSION);
+            const STATUS = parseSession.options.some((item) => {
+              return (
+                item.userId == row.userId &&
+                item.goodsId == row.goodsId &&
+                item.id == row.id
+              );
+            });
+            if (!STATUS) {
+              parseSession.options.push(row);
+            }
+            parseSession.activeData = `${row.userId}-${row.goodsId}-${row.id}`;
+            sessionStorage.setItem("hoursAudit", JSON.stringify(parseSession));
+          } else {
+            let data = {
+              activeData: `${row.userId}-${row.goodsId}-${row.id}`,
+              options: [row],
+            };
+            sessionStorage.setItem("hoursAudit", JSON.stringify(data));
+          }
+
+          resolve();
+        } catch (error) {
+          reject();
+        }
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData.pageNum = 1;
+        this.formData.realname = "";
+        this.formData.idCard = "";
+        this.formData.companyName = "";
+        this.formData.telphone = "";
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGradegradelistUserVideoRecord(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

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

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

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

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

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

@@ -0,0 +1,358 @@
+<template>
+  <div id="">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="search(2)"
+    />
+    <table-list
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="jumpPage(props.scope.row)"
+          >学习记录</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      size: "small",
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "学习列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        tableHide:true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      formList: [
+        {
+          placeholder: "学员姓名",
+          prop: "realname",
+        },
+        {
+          placeholder: "身份证",
+          prop: "idCard",
+        },
+        {
+          placeholder: "公司名称",
+          prop: "companyName",
+        },
+        {
+          placeholder: "手机号码",
+          prop: "telphone",
+        },
+      ],
+      formData: {
+        realname: "",
+        idcard: "",
+        companyName: "",
+        telphone: "",
+        profileStatus: "",
+        periodStatus: "",
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "基本信息",
+          prop1: "realName",
+          prop2: "idCard",
+          prop3: "companyName",
+          hidden: true,
+          scope: "baseInfo",
+        },
+        {
+          label: "头像",
+          prop: "oneInchPhotos",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
+        {
+          label: "最新拍照",
+          prop: "idCardImg1",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
+        {
+          label: "学习班名称",
+          prop: "className",
+          hidden: true,
+        },
+        {
+          label: "视频名称",
+          prop: "sectionName",
+          hidden: true,
+        },
+        {
+          label: "在线时间",
+          prop: "recordEndTime",
+          hidden: true,
+          scope: "aTimeList",
+        },
+        {
+          label: "学习时间",
+          prop1: "recordStartTime",
+          prop2: "recordEndTime",
+          scope: "TimeLists",
+          hidden: true,
+        },
+        {
+          label: "时长",
+          prop: "durationTime",
+          hidden: true,
+          scope: "convert",
+        },
+        {
+          label: "是否完成",
+          prop: "recordEndTime",
+          hidden: true,
+          scope: "recordEndTime",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.$api
+      .coursebusinessqueryFullId({
+        educationName: "继续教育",
+        projectName: "造价师",
+        businessName: "二级",
+      })
+      .then((res) => {
+        this.formData.educationId = res.data.educationId;
+        this.formData.projectId = res.data.projectId;
+        this.formData.businessId = res.data.businessId;
+        this.search();
+      });
+  },
+  methods: {
+    jumpPage(options) {
+      const jump = () => {
+        //班级详情
+        this.$router.push({
+          name: "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,
+          },
+        });
+      };
+      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();
+      }
+    },
+    checkSession(row) {
+      return new Promise((resolve, reject) => {
+        const SESSION = sessionStorage.getItem("hoursAudit");
+        try {
+          if (SESSION) {
+            let parseSession = JSON.parse(SESSION);
+            const STATUS = parseSession.options.some((item) => {
+              return (
+                item.userId == row.userId &&
+                item.goodsId == row.goodsId &&
+                item.id == row.id
+              );
+            });
+            if (!STATUS) {
+              parseSession.options.push(row);
+            }
+            parseSession.activeData = `${row.userId}-${row.goodsId}-${row.id}`;
+            sessionStorage.setItem("hoursAudit", JSON.stringify(parseSession));
+          } else {
+            let data = {
+              activeData: `${row.userId}-${row.goodsId}-${row.id}`,
+              options: [row],
+            };
+            sessionStorage.setItem("hoursAudit", JSON.stringify(data));
+          }
+
+          resolve();
+        } catch (error) {
+          reject();
+        }
+      });
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData.pageNum = 1;
+        this.formData.realname = "";
+        this.formData.idCard = "";
+        this.formData.companyName = "";
+        this.formData.telphone = "";
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      this.$api
+        .inquireGradegradelistUserVideoRecord(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

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