Prechádzať zdrojové kódy

需求优化及监管抽查功能

Tang 2 rokov pred
rodič
commit
59acec1c5e
52 zmenil súbory, kde vykonal 2146 pridanie a 171 odobranie
  1. 1 1
      package.json
  2. 1 1
      src/assets/styles/variables.scss
  3. 20 11
      src/components/Study/StudentInfo.vue
  4. 48 34
      src/components/searchBoxNew.vue
  5. 18 11
      src/components/tableList.vue
  6. 9 4
      src/layout/components/Navbar.vue
  7. 1 0
      src/layout/components/Sidebar/Item.vue
  8. 3 0
      src/newApi/business.js
  9. 39 2
      src/newApi/classTab.js
  10. 24 0
      src/newApi/examapply.js
  11. 14 2
      src/newApi/goods.js
  12. 8 0
      src/newApi/mockSub.js
  13. 8 0
      src/newApi/paperquestion.js
  14. 9 0
      src/newApi/systemRemind.js
  15. 49 8
      src/permission.js
  16. 1 1
      src/store/modules/permission.js
  17. 2 0
      src/store/modules/user.js
  18. 10 0
      src/utils/index.js
  19. 85 0
      src/utils/methodsTool.js
  20. 1 1
      src/utils/request.js
  21. 221 0
      src/utils/spotCheck.js
  22. 7 5
      src/views/Marketing/goods/commodityManageMent/add/courseContent/index.vue
  23. 18 1
      src/views/Marketing/goods/commodityManageMent/add/courseContent/playPhoto.vue
  24. 44 4
      src/views/Marketing/goods/commodityManageMent/add/productInformation.vue
  25. 1 1
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue
  26. 19 1
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/playPhoto.vue
  27. 16 3
      src/views/classHoursReview/studyTimes.vue
  28. 77 7
      src/views/education/classManageMent/hoursTimesRecord/index.vue
  29. 1 16
      src/views/education/classManageMent/learningHoursRecordList/index.vue
  30. 607 0
      src/views/education/classManageMent/learningHoursRecordListMonth/index.vue
  31. 2 2
      src/views/education/examManagement/applicationData/asPlanned.vue
  32. 1 1
      src/views/education/examManagement/applicationData/byTrainee.vue
  33. 1 1
      src/views/education/examManagement/applicationData/cancelAppointMent/index.vue
  34. 1 1
      src/views/education/examManagement/applicationData/examRegistration/index.vue
  35. 1 1
      src/views/education/examManagement/applicationData/formerAccount/index.vue
  36. 1 1
      src/views/education/examManagement/examArrangement/applicableProducts/downMaterial.vue
  37. 6 8
      src/views/education/examManagement/examArrangement/applicableProducts/index.vue
  38. 129 18
      src/views/education/examManagement/examArrangement/index.vue
  39. 277 0
      src/views/education/examManagement/listOfTestRooms/index.vue
  40. 177 0
      src/views/education/examManagement/listOfTestRooms/sendEmail.vue
  41. 1 1
      src/views/education/examManagement/qianpeiArrange/allAssociatedExamPlans.vue
  42. 1 1
      src/views/education/examManagement/qianpeiArrange/assExamPlan.vue
  43. 1 1
      src/views/education/examManagement/qianpeiArrange/index.vue
  44. 28 6
      src/views/education/mockTestManagement/mockTestData/index.vue
  45. 12 6
      src/views/index.vue
  46. 13 1
      src/views/resource/bankManagement/testPaperManagement/BatchImportPop.vue
  47. 5 0
      src/views/resource/bankManagement/testPaperManagement/addPaper/topicAddPaper/index.vue
  48. 6 0
      src/views/resource/bankManagement/testPaperManagement/editPaper/topicEditPaper/index.vue
  49. 1 1
      src/views/secondJian/courseList/index.vue
  50. 1 1
      src/views/secondZao/courseList/index.vue
  51. 95 0
      src/views/system/user/profile/email.vue
  52. 24 6
      src/views/system/user/profile/index.vue

+ 1 - 1
package.json

@@ -43,7 +43,7 @@
     "clipboard": "2.0.6",
     "core-js": "3.8.1",
     "echarts": "4.9.0",
-    "element-ui": "2.15.6",
+    "element-ui": "^2.15.13",
     "file-saver": "^2.0.5",
     "fuse.js": "6.4.3",
     "gsap": "^3.11.4",

+ 1 - 1
src/assets/styles/variables.scss

@@ -36,7 +36,7 @@ $base-sub-menu-background:#000c17;
 $base-sub-menu-hover:#001528;
 */
 
-$base-sidebar-width: 200px;
+$base-sidebar-width: 220px;
 
 // the :export directive is the magic sauce for webpack
 // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass

+ 20 - 11
src/components/Study/StudentInfo.vue

@@ -5,7 +5,7 @@
       <div class="goods_info">
         <span v-for="(item, i) in headList" :key="i">
           <strong>「{{ i + 1 }}」</strong>
-          <span style="padding-left: 0px">{{ item.lebel }}</span>
+          <span style="padding-left: 0px">{{ item.label }}</span>
           <!-- <span v-if="item.key != 'num' && item.key != 'time'">{{
             userData[item.key]
           }}</span> -->
@@ -16,11 +16,13 @@
           <span
             v-else-if="item.key == 'classHours'"
             style="color: red; font-weight: bold; font-size: 18px"
-            >{{ (userData["finishSectionDuration"] / 60 / 45).toFixed(0) }}</span
+            >{{
+              (userData["finishSectionDuration"] / 60 / 45).toFixed(0)
+            }}</span
           ><span
             v-else-if="item.key == 'secTotalTime'"
             style="color: red; font-weight: bold; font-size: 18px"
-            >{{(secTotalTime / 60 / 45).toFixed(0) }}</span
+            >{{ (secTotalTime / 60 / 45).toFixed(0) }}</span
           >
           <span v-else-if="item.key == 'num'"
             >完成{{ userData.stuAllNum + userData.recordNum }}节的内容学习</span
@@ -144,16 +146,23 @@ export default {
   },
   computed: {
     headList() {
-      const list = [
-        { lebel: "所在班级:", key: "className" },
-        { lebel: "课程总学时:", key: "secTotalTime" },
-        { lebel: "完成学时:", key: "classHours" },
-        // { lebel: "", key: "num" },
-        { lebel: "学习时间:", key: "time" },
-        { lebel: "班级有效期:", key: "classTimes" },
+      let list = [
+        { label: "所在班级:", key: "className" },
+        { label: "课程总学时:", key: "secTotalTime" },
+        { label: "完成学时:", key: "classHours" },
+        // { label: "", key: "num" },
+        { label: "学习时间:", key: "time" },
       ];
+      if (
+        !(
+          this.userData.supervise &&
+          this.userData.fullName === "考前培训施工现场专业人员七大员"
+        )
+      ) {
+        list.push({ label: "班级有效期:", key: "classTimes" });
+      }
       if (this.all) {
-        list.unshift({ lebel: "所购商品:", key: "goodsName" });
+        list.unshift({ label: "所购商品:", key: "goodsName" });
       }
       return list;
     },

+ 48 - 34
src/components/searchBoxNew.vue

@@ -376,29 +376,39 @@
             ></el-option>
           </el-select>
           <div v-else-if="item.scope === 'numList'">
-            <el-input-number
-              :controls="false"
+            <el-select
+              clearable
+              filterable
+              style="width: 120px"
               v-model="formData[item.prop1]"
-              controls-position="right"
-              :min="0"
-              :max="100"
-              :size="size"
-              @change="
-                handleChanges(formData[item.prop1], formData[item.prop2])
-              "
-            ></el-input-number
-            >~
-            <el-input-number
-              :controls="false"
+              :placeholder="item.placeholder1"
+            >
+              <el-option
+                v-for="(items, index) in 101"
+                :key="index"
+                :label="index"
+                :value="index"
+                :disabled="comNum(index, formData[item.prop2], true)"
+              >
+              </el-option>
+            </el-select>
+            -
+            <el-select
+              clearable
+              filterable
+              style="width: 120px"
               v-model="formData[item.prop2]"
-              controls-position="right"
-              :min="0"
-              :max="100"
-              :size="size"
-              @change="
-                handleChanges(formData[item.prop1], formData[item.prop2])
-              "
-            ></el-input-number>
+              :placeholder="item.placeholder2"
+            >
+              <el-option
+                v-for="(items, index) in 101"
+                :key="index"
+                :label="index"
+                :value="index"
+                :disabled="comNum(index, formData[item.prop1])"
+              >
+              </el-option>
+            </el-select>
           </div>
           <el-input-number
             v-else-if="item.scope === 'inputNumber'"
@@ -719,6 +729,23 @@ export default {
       "certificate",
       "distributionList",
     ]),
+    comNum: function () {
+      return function (index, num, status) {
+        if (status) {
+          if (index > num) {
+            return true;
+          } else {
+            return false;
+          }
+        } else {
+          if (index < num) {
+            return true;
+          } else {
+            return false;
+          }
+        }
+      };
+    },
     /**
      * @remarks 过滤选择器列表
      */
@@ -922,19 +949,6 @@ export default {
     init() {
       this.$emit("init");
     },
-    /**
-     *
-     * @param {int} int1
-     * @param {int} int2
-     * @remark 数值取值范围选择器
-     */
-    handleChanges(int1, int2) {
-      if (int1 !== undefined && int2 !== undefined) {
-        if (int1 > int2) {
-          this.$message.error("请规范输入取值范围");
-        }
-      }
-    },
     /**
      *
      * @param {int} id

+ 18 - 11
src/components/tableList.vue

@@ -2,7 +2,7 @@
   <div id="tableList">
     <div class="headerNavTool" v-if="navText.headShow !== false">
       <div class="leftIndexText">
-        {{ navText.title }} <strong>{{ navText.index }}</strong>
+        {{ navText.title }} <strong>{{ navIndex || navText.index }}</strong>
         {{ navText.ch }}
       </div>
       <div class="rightBtnBox">
@@ -121,6 +121,9 @@
         width="55"
         header-align="center"
         fixed="left"
+        :selectable="
+          navText.selectableStatus ? navText.selectableFunc : null
+        "
       >
       </el-table-column>
       <!-- v-if="navText.num" ↓ -->
@@ -216,6 +219,9 @@
               ? "已删除"
               : "未知"
           }}</span>
+          <div v-else-if="item.scope === 'solt'">
+            <slot :name="item.soltName" :scope="scope"></slot>
+          </div>
           <span v-else-if="item.scope === 'reStatus'">{{
             Number(scope.row[item.prop]) === 1
               ? "定时发布"
@@ -263,12 +269,12 @@
             <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>
+            <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] ? '完成':'未完成' }}
+            {{ scope.row[item.prop] ? "完成" : "未完成" }}
           </span>
           <span
             v-else-if="
@@ -731,13 +737,13 @@
                 >{{ scope.row[item.prop3] }}-{{ scope.row[item.prop4] }}</span
               >
             </div>
-            <div v-if="scope.row['fromPlat'] === 2">
+            <div>
               准考证号:{{ scope.row[item.prop5] }}
             </div>
-            <div v-if="scope.row['fromPlat'] === 2">
+            <div>
               座位号:{{ scope.row[item.prop6] }}
             </div>
-            <div v-if="scope.row['fromPlat'] === 2">
+            <div>
               同步到考场状态:{{
                 scope.row[item.prop7] === 0
                   ? "未同步"
@@ -1187,7 +1193,7 @@
               </div>
             </template>
           </div>
-          
+
           <span v-else-if="item.scope === 'isgzhOpenId'">{{
             scope.row[item.prop] ? "是" : "否"
           }}</span>
@@ -1473,7 +1479,7 @@
                   .map(Number)"
                 :key="idm"
               >
-                {{ itm === 1 ? "非补考学员" : itm === 2 ? "补考学员" : "" }}
+                {{ itm === 1 ? "考学员" : itm === 2 ? "补考学员" : "" }}
               </span>
             </template>
           </div>
@@ -1942,6 +1948,7 @@ export default {
     "tableSets",
     "tableData",
     "navText",
+    "navIndex",
     "rowKey",
     "loading",
     "studentTable",
@@ -2504,7 +2511,7 @@ export default {
     openBoxData(row) {
       this.$emit("openBoxFun", row);
     },
-    openDialog(row){
+    openDialog(row) {
       this.$emit("openDialog", row);
     },
     diaviosTK(ids) {

+ 9 - 4
src/layout/components/Navbar.vue

@@ -64,8 +64,8 @@
           <size-select id="size-select" class="right-menu-item hover-effect" />
         </el-tooltip>
       </template>
-
       <el-dropdown
+        v-if="!spotDataStatus"
         class="avatar-container right-menu-item hover-effect"
         trigger="click"
       >
@@ -161,6 +161,7 @@ export default {
       dialog_haveRead: false,
       tableData: [], //未读列表
       total: 0, //未读数量
+      spotDataStatus: false,
     };
   },
   computed: {
@@ -183,7 +184,11 @@ export default {
     },
   },
   mounted() {
-    if (this.$route.name !== "StationLetter") {
+    this.spotDataStatus = sessionStorage.getItem("spotData") ? true : false;
+    if (
+      this.$route.name !== "StationLetter" &&
+      !sessionStorage.getItem("spotData")
+    ) {
       this.$api.inquireinformsys_userinformUnReadSum().then((res) => {
         if (res.data > 0) {
           this.getDontReadList();
@@ -372,9 +377,9 @@ export default {
         type: "warning",
       })
         .then(() => {
-          const tid = sessionStorage.TenantId
+          const tid = sessionStorage.TenantId;
           this.$store.dispatch("LogOut").then(() => {
-            location.href = "/index?TenantId=" + tid
+            location.href = "/index?TenantId=" + tid;
           });
         })
         .catch(() => {

+ 1 - 0
src/layout/components/Sidebar/Item.vue

@@ -39,6 +39,7 @@ export default {
     //     );
     //   }
     // }
+    
     if (title) {
       vnodes.push(<span slot="title">{title}</span>);
     }

+ 3 - 0
src/newApi/business.js

@@ -84,6 +84,9 @@ export default {
         return request({
             url: '/course/business/queryFullId',
             method: 'get',
+            headers:{
+                isToken:false,
+            },
             params: data
         })
     },

+ 39 - 2
src/newApi/classTab.js

@@ -101,6 +101,9 @@ export default {
         return request({
             url: '/grade/grade/listUserPeriod',
             method: 'get',
+            headers: {
+                isToken: false
+            },
             params: data
         })
     },
@@ -140,6 +143,9 @@ export default {
         return request({
             url: '/grade/grade/listPeriod',
             method: 'get',
+            headers: {
+                isToken: false
+            },
             params: data
         })
     },
@@ -156,6 +162,9 @@ export default {
         return request({
             url: '/grade/grade/listPeriodAudit',
             method: 'get',
+            headers: {
+                isToken: false,
+            },
             params: data
         })
     },
@@ -180,6 +189,9 @@ export default {
         return request({
             url: '/grade/grade/listPeriodAuditStatus',
             method: 'get',
+            headers: {
+                isToken: false,
+            },
             params: data
         })
     },
@@ -309,9 +321,34 @@ export default {
         return request({
             url: '/grade/grade/listUserVideoRecord',
             method: 'get',
+            headers: {
+                isToken: false
+            },
             params: data
         })
     },
-    
-    
+    //按周查询学员学时学习记录列表
+    inquireGradegradelistUserPeriodWeekRecord(data) {
+        return request({
+            url: '/grade/grade/listUserPeriodWeekRecord',
+            method: 'get',
+            params: data
+        })
+    },
+    //周查询学员学习记录列表
+    inquireGradegradelistUserStudyRecordV2Week(data) {
+        return request({
+            url: '/grade/grade/listUserStudyRecordV2Week',
+            method: 'get',
+            params: data
+        })
+    },
+    //周导出学员学时列表
+    gradegradeexportWeek(data) {
+        return request({
+            url: '/grade/grade/exportWeek',
+            method: 'post',
+            data
+        })
+    },
 }

+ 24 - 0
src/newApi/examapply.js

@@ -102,4 +102,28 @@ export default {
             method: 'get',
         })
     },
+    //查询考场列表
+    inquireexamapplyplaceList(data) {
+        return request({
+            url: '/system/apply/place',
+            method: 'get',
+            params: data
+        })
+    },
+    //考场邮件地址
+    examapplysendmail(data) {
+        return request({
+            url: '/system/apply/sendmail',
+            method: 'get',
+            params: data
+        })
+    },
+    //考场邮件发送
+    systemapplysend(data) {
+        return request({
+            url: '/system/apply/send',
+            method: 'post',
+            data
+        })
+    },
 }

+ 14 - 2
src/newApi/goods.js

@@ -43,11 +43,11 @@ export default {
     // 获取题库商品每日一练试卷列表
     getBankGoodsExamList(id) {
         return request({
-            url: '/goods/getBankGoodsExamList/'+id,
+            url: '/goods/getBankGoodsExamList/' + id,
             method: 'get',
         })
     },
-    
+
     //查询前培或补考商品列表
     inquireGoodslistGoods(data) {
         return request({
@@ -64,6 +64,18 @@ export default {
             params: data
         })
     },
+    //查询商品列表监管
+    commonfreegoodslist(data) {
+        return request({
+            url: '/common/free/goods/list',
+            method: 'get',
+            headers: {
+                isToken: false
+            },
+            params: data
+        })
+    },
+
     //获取商品详细信息
     obtainGoods(data) {
         return request({

+ 8 - 0
src/newApi/mockSub.js

@@ -31,4 +31,12 @@ export default {
             method: 'get',
         })
     },
+    //模考导出
+    exportMockrecordData(data) {
+        return request({
+            url: '/user/subscribe/listSubscribe/export',
+            method: 'get',
+            params: data
+        })
+    },
 }

+ 8 - 0
src/newApi/paperquestion.js

@@ -63,6 +63,14 @@ export default {
             data
         })
     },
+    //导入建匠题目Word模板列表
+    bankquestionimportJJWordQuestionList(data) {
+        return request({
+            url: '/bank/question/importJJWordQuestionList',
+            method: 'post',
+            data
+        })
+    },
     //导入题目模板EXCEL
     importDatabankimportDataBackList(data) {
         return request({

+ 9 - 0
src/newApi/systemRemind.js

@@ -47,5 +47,14 @@ export default {
             params: data
         })
     },
+    //学时抽查
+    commonfreedecryptOfficialInfo(data) {
+        return request({
+            url: '/common/free/decryptOfficialInfo',
+            method: 'post',
+            data
+        })
+    },
+    
     
 }

+ 49 - 8
src/permission.js

@@ -5,12 +5,12 @@ import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
 import methods from '@/utils/methodsTool';
 import { getToken } from '@/utils/auth'
+import { checkSession, spotCheckFunc } from '@/utils/spotCheck'
 import $api from "@/api/api"
 
 NProgress.configure({ showSpinner: false })
 
 const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
-
 router.beforeEach(async (to, from, next) => {
   if (to.path !== from.path) {
     NProgress.start();
@@ -18,20 +18,47 @@ router.beforeEach(async (to, from, next) => {
   if (to.path === '/login' && to.query.account) {
     await store.dispatch('oldLogin', to.query)
   } else {
-    if(to.path === '/login' &&!methods.getQueryVariable('TenantId')){
+    if (to.path === '/login' && !methods.getQueryVariable('TenantId')) {
       sessionStorage.removeItem('TenantId')
     }
     if (!sessionStorage.TenantId) {
       await store.dispatch('findTenantId')
     } else {
-      if(methods.getQueryVariable('TenantId')){
+      if (methods.getQueryVariable('TenantId')) {
         sessionStorage.TenantId = methods.getQueryVariable('TenantId')
       }
     }
   }
+  //监管人员抽查处理
+  if (to.path.includes('/spotCheck')) {
+    let array = to.path.split('/').filter(i => !!i)
+    sessionStorage.TenantId = array[1]
+    if (to.query.data) {
+      store.dispatch('FedLogOut')
+      await new Promise((resolve) => {
+        $api.commonfreedecryptOfficialInfo({ data: to.query.data }).then(res => {
+          console.log(res, 'res')
+          let data = {
+            type: res.data.gradeType,
+            userId: res.data.userId,
+            realName: res.data.realName,
+            id: res.data.gradeId,
+            className: res.data.className,
+            goodsId: res.data.goodsId,
+            goodsName: res.data.goodsName,
+            fullName:res.data.fullName,
+            keyId: `${res.data.userId}-${res.data.goodsId}-${res.data.gradeId}`,
+          };
+          sessionStorage.spotData = JSON.stringify(data)
+          resolve()
+        })
+      })
+    }
+  }
   if (sessionStorage.TenantId && !store.state.user.companyName) {
     store.dispatch('footerData')
   }
+
   if (getToken()) {
     to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
     /* has token*/
@@ -54,15 +81,10 @@ router.beforeEach(async (to, from, next) => {
           })
         })
       } else {
-        // if (!store.state.user.TENANT_NANE && !to.query.TenantId) {
-        //   to.query.TenantId = sessionStorage.TenantId
-        //   next(to)
-        // } else {
         if (!to.path.includes('/user/profile')) {
           checkFunc()
         }
         next()
-        // }
       }
     }
   } else {
@@ -70,6 +92,25 @@ router.beforeEach(async (to, from, next) => {
     if (whiteList.indexOf(to.path) !== -1) {
       // 在免登录白名单,直接进入
       next()
+    } else if (sessionStorage.getItem('spotData')) {
+      if (store.state.permission.addRoutes.length === 0) {
+        let li = JSON.parse(sessionStorage.getItem('spotData'))
+        spotCheckFunc(li)
+        if (to.path.includes('/spotCheck') && sessionStorage.getItem('TenantId')) {
+          checkSession(li)
+            .then(() => {
+              //学时审核
+              next({ path: '/classHoursReviews', replace: true })
+            })
+            .catch(() => {
+              this.$message.error("存在异常,请联系开发人员");
+            });
+        } else {
+          next({ ...to, replace: true })
+        }
+      } else {
+        next() // hack方法 确保addRoutes已完成
+      }
     } else {
       if (sessionStorage.TenantId == undefined) {
         next(`/login`) // 否则全部重定向到登录页

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

@@ -63,7 +63,6 @@ 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))
@@ -130,6 +129,7 @@ function filterChildren(childrenMap, lastRouter = false) {
 }
 
 export const loadView = (view) => {
+  console.log(view,"view")
   if (process.env.NODE_ENV === 'development') {
     return (resolve) => require([`@/views/${view}`], resolve)
   } else {

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

@@ -116,6 +116,7 @@ const user = {
         login(username, password, code, uuid, phonenumber, smsCode).then(res => {
           setToken(res.token)
           commit('SET_TOKEN', res.token)
+          sessionStorage.removeItem('spotData')
           resolve()
         }).catch(error => {
           reject(error)
@@ -154,6 +155,7 @@ const user = {
           commit('SET_ROLES', [])
           commit('SET_PERMISSIONS', [])
           sessionStorage.removeItem('TenantId')
+          sessionStorage.removeItem('spotData')
           removeToken()
           resolve()
         }).catch(error => {

+ 10 - 0
src/utils/index.js

@@ -107,6 +107,16 @@ export function cleanArray(actual) {
   return newArray
 }
 
+export function exportFn(str, name) {
+  let url = process.env.VUE_APP_BASE_API + "common/download?fileName=" + str;
+  let link = document.createElement("a");
+  let fileName = name + ".xlsx";
+  document.body.appendChild(link);
+  link.href = url;
+  link.dowmload = fileName;
+  link.click();
+  link.remove();
+}
 /**
  * @param {Object} json
  * @returns {Array}

+ 85 - 0
src/utils/methodsTool.js

@@ -549,4 +549,89 @@ export default {
 			});
 		})
 	},
+	getWeekData(year, month) { //传入  年  月  获取当月有几周 以及日期 
+		var new_year = year;    //取当前的年份
+		var new_month = month++;//取下一个月的第一天,方便计算(最后一天不固定)
+		if (new_month < 10) { new_month = '0' + new_month }
+		var weekDay = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"];
+		if (new_month > 12) {
+			new_month -= 12;        //月份减
+			new_year++;            //年份增
+		}
+		var first_date = new Date(new_year, new_month, 1);                //取当年当月中的第一天-时间格式
+		var last_Data = (new Date(first_date.getTime() - 1000 * 60 * 60 * 24)).getDate() //获取当月最后一天日期
+		//当月第一天是周几
+		var firstzhouji = new Date(new_year + '/' + new_month + '/' + 1).getDay() == 0 ? '星期天' : weekDay[new Date(new_year + '/' + new_month + '/' + 1).getDay() - 1]
+		//当月最后一天是周几
+		var lastzhouji = new Date(new_year + '/' + new_month + '/' + last_Data).getDay() == 0 ? '星期天' : weekDay[new Date(new_year + '/' + new_month + '/' + last_Data).getDay() - 1]
+		var firsttime = '' //第一周有几天
+		if (firstzhouji == '星期一') { firsttime = 7 }
+		if (firstzhouji == '星期二') { firsttime = 6 }
+		if (firstzhouji == '星期三') { firsttime = 5 }
+		if (firstzhouji == '星期四') { firsttime = 4 }
+		if (firstzhouji == '星期五') { firsttime = 3 }
+		if (firstzhouji == '星期六') { firsttime = 2 }
+		if (firstzhouji == '星期天') { firsttime = 1 }
+
+		var lasttime = '' //最后一周有几天
+		if (lastzhouji == '星期一') { lasttime = 1 }
+		if (lastzhouji == '星期二') { lasttime = 2 }
+		if (lastzhouji == '星期三') { lasttime = 3 }
+		if (lastzhouji == '星期四') { lasttime = 4 }
+		if (lastzhouji == '星期五') { lasttime = 5 }
+		if (lastzhouji == '星期六') { lasttime = 6 }
+		if (lastzhouji == '星期天') { lasttime = 7 }
+
+		// 前后两周  加上 剩余周数  得出总周数
+		var contime = 2 + (last_Data - lasttime - firsttime) / 7
+
+		//得出每周对应的日期
+		var zhouArry = []
+
+		for (var i = 1; i <= contime; i++) {
+			var strTime = ''
+			var lastTime = ''
+			if (i == 1) {
+				strTime = year + '-' + new_month + '-' + '01'
+				let aa = 1 + firsttime - 1
+				if (aa < 10) {
+					aa = '0' + aa
+				}
+				lastTime = year + '-' + new_month + '-' + aa
+			} else if (i == contime) {
+				let bb = last_Data - lasttime + 1
+				if (bb < 10) {
+					bb = '0' + bb
+				}
+				strTime = year + '-' + new_month + '-' + bb
+				lastTime = year + '-' + new_month + '-' + (last_Data < 10 ? ('0' + last_Data) : last_Data)
+			} else {
+				strTime = addDate(zhouArry[zhouArry.length - 1].endTime, 1)
+				lastTime = addDate(zhouArry[zhouArry.length - 1].endTime, 7)
+			}
+
+			zhouArry.push({
+				weeknum: i,
+				beginTime: strTime,
+				endTime: lastTime,
+				beginTimeCode: new Date(strTime + ' 00:00:00').getTime() / 1000,
+				endTimeCode: new Date(lastTime + ' 23:59:59').getTime() / 1000,
+			})
+
+			//日期增加 接受两个参数, 传入的时间,传入时间增加的天数
+			function addDate(date, days) {
+				if (days == undefined || days == '') {
+					days = 1;
+				}
+				var date = new Date(date);
+				date.setDate(date.getDate() + days);
+				var month = date.getMonth() + 1;
+				if (month < 10) { month = '0' + month; }
+				var day = date.getDate();
+				if (day < 10) { day = '0' + day; }
+				return date.getFullYear() + '-' + month + '-' + day;
+			}
+		}
+		return zhouArry
+	}
 }

+ 1 - 1
src/utils/request.js

@@ -8,7 +8,7 @@ import methods from '@/utils/methodsTool';
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 // 创建axios实例
 export const baseURL = process.env.VUE_APP_BASE_API
-// export const baseURL = 'http://192.168.1.7:5030/'
+// 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公共部分

+ 221 - 0
src/utils/spotCheck.js

@@ -0,0 +1,221 @@
+
+import Layout from '@/layout/index'
+import ParentView from '@/components/ParentView';
+import InnerLink from '@/layout/components/InnerLink'
+import router from '@/router'
+import store from '@/store'
+import { constantRoutes } from '@/router'
+export var loadView = (view) => {
+    return (resolve) => require([`@/views/${view}`], resolve)
+}
+let spotRouter = [{
+    "menuId": 11220,
+    "name": "SecondJian",
+    "path": "/secondJian",
+    "hidden": false,
+    "redirect": "noRedirect",
+    "component": "Layout",
+    "alwaysShow": true,
+    "meta": {
+        "title": "二建监管平台",
+        "icon": "date-range",
+        "noCache": false
+    },
+    "children": [
+    //     {
+    //     "menuId": 11219,
+    //     "name": "CourseListJian",
+    //     "path": "courseListJian",
+    //     "hidden": false,
+    //     "component": "secondJian/courseList",
+    //     "meta": {
+    //         "title": "课程列表",
+    //         "icon": "#",
+    //         "noCache": false
+    //     }
+    // }, 
+    {
+        "menuId": 11222,
+        "name": "CompletionListJian",
+        "path": "completionListJian",
+        "hidden": false,
+        "component": "secondJian/completionList",
+        "meta": {
+            "title": "完成列表",
+            "icon": "#",
+            "noCache": false
+        }
+    }, {
+        "menuId": 11223,
+        "name": "LearningListJian",
+        "path": "learningListJian",
+        "hidden": false,
+        "component": "secondJian/learningList",
+        "meta": {
+            "title": "学习列表",
+            "icon": "#",
+            "noCache": false
+        }
+    }]
+}, {
+    "menuId": 11221,
+    "name": "SecondZao",
+    "path": "/secondZao",
+    "hidden": false,
+    "redirect": "noRedirect",
+    "component": "Layout",
+    "alwaysShow": true,
+    "meta": {
+        "title": "二造监管平台",
+        "icon": "druid",
+        "noCache": false
+    },
+    "children": [
+    //     {
+    //     "menuId": 11224,
+    //     "name": "CourseListZao",
+    //     "path": "courseListZao",
+    //     "hidden": false,
+    //     "component": "secondZao/courseList",
+    //     "meta": {
+    //         "title": "课程列表",
+    //         "icon": "#",
+    //         "noCache": false
+    //     }
+    // },
+     {
+        "menuId": 11225,
+        "name": "CompletionListZao",
+        "path": "completionListZao",
+        "hidden": false,
+        "component": "secondZao/completionList",
+        "meta": {
+            "title": "完成列表",
+            "icon": "#",
+            "noCache": false
+        }
+    }, {
+        "menuId": 11226,
+        "name": "LearningListZao",
+        "path": "learningListZao",
+        "hidden": false,
+        "component": "secondZao/learningList",
+        "meta": {
+            "title": "学习列表",
+            "icon": "#",
+            "noCache": false
+        }
+    }]
+}, {
+    "menuId": 11227,
+    "path": "/",
+    "hidden": true,
+    "component": "Layout",
+    "children": [{
+        "name": "ClassHoursReviews",
+        "path": "classHoursReviews",
+        "hidden": false,
+        "component": "classHoursReview",
+        "meta": {
+            "title": "学时审核",
+            "icon": "#",
+            "noCache": false
+        }
+    }]
+}]
+export function spotCheckFunc(li) {
+    ///根据缓存数据筛选分类二建二造菜单
+    const path = li.type == 1 ? '/secondJian' : li.type == 2 ? '/secondZao' : null
+    const mapSpotRouter = spotRouter.filter(i => i.path === path || i.path === '/')
+    const sidebarRoutes = filterAsyncRouter(JSON.parse(JSON.stringify(mapSpotRouter)))
+    const rewriteRoutes = filterAsyncRouter(JSON.parse(JSON.stringify(mapSpotRouter)), false, true)
+    rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
+    store.commit('SET_ROUTES', rewriteRoutes)
+    store.commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
+    store.commit('SET_DEFAULT_ROUTES', sidebarRoutes)
+    store.commit('SET_TOPBAR_ROUTES', sidebarRoutes)
+    router.addRoutes(rewriteRoutes) // 动态添加可访问路由表
+}
+
+export function 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();
+        }
+    });
+}
+
+// 遍历后台传来的路由字符串,转换为组件对象
+function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
+    return asyncRouterMap.filter(route => {
+        if (type && route.children) {
+            route.children = filterChildren(route.children)
+        }
+        if (route.component) {
+            // Layout ParentView 组件特殊处理
+            if (route.component === 'Layout') {
+                route.component = Layout
+            } else if (route.component === 'ParentView') {
+                route.component = ParentView
+            } else if (route.component === 'InnerLink') {
+                route.component = InnerLink
+            } else {
+                route.component = loadView(route.component)
+            }
+        }
+        if (route.children != null && route.children && route.children.length) {
+            route.children = filterAsyncRouter(route.children, route, type)
+        } else {
+            delete route['children']
+            delete route['redirect']
+        }
+        return true
+    })
+}
+function filterChildren(childrenMap, lastRouter = false) {
+    var children = []
+    childrenMap.forEach((el, index) => {
+        if (el.children && el.children.length) {
+            if (el.component === 'ParentView' && !lastRouter) {
+                el.children.forEach(c => {
+                    c.path = el.path + '/' + c.path
+                    if (c.children && c.children.length) {
+                        children = children.concat(filterChildren(c.children, c))
+                        return
+                    }
+                    children.push(c)
+                })
+                return
+            }
+        }
+        if (lastRouter) {
+            el.path = lastRouter.path + '/' + el.path
+        }
+        children = children.concat(el)
+    })
+    return children
+}

+ 7 - 5
src/views/Marketing/goods/commodityManageMent/add/courseContent/index.vue

@@ -4,7 +4,10 @@
       <el-button
         @click="addCourse"
         size="small"
-        :disabled="tableData.length > 0 && tableData[0].type > 0"
+        :disabled="
+          (tableData.length > 0 && tableData[0].type > 0) ||
+          tableData.length > 0
+        "
         >添加课程</el-button
       >
       <el-button
@@ -312,8 +315,8 @@ export default {
      * 点击试听函数
      */
     openAudition() {
-      console.log(this.tableData,this.auditionList)
-      this.$refs.poppleSet.openExpand(this.tableData,this.auditionList)
+      console.log(this.tableData, this.auditionList);
+      this.$refs.poppleSet.openExpand(this.tableData, this.auditionList);
     },
     /**
      * 试听回调数据
@@ -372,5 +375,4 @@ export default {
 };
 </script>
 
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 18 - 1
src/views/Marketing/goods/commodityManageMent/add/courseContent/playPhoto.vue

@@ -47,6 +47,7 @@
           <h4>课程节-点播拍照</h4>
           <div>
             <el-radio-group
+              :disabled="disabledFunc()"
               v-model="photoVideoList.photographConfig.photograph"
             >
               <el-radio :label="1">是</el-radio>
@@ -62,7 +63,10 @@
             style="margin-top: 14px"
           >
             拍照数量:
-            <el-radio-group v-model="photoVideoList.photographConfig.photoNum">
+            <el-radio-group
+              :disabled="disabledFunc()"
+              v-model="photoVideoList.photographConfig.photoNum"
+            >
               <el-radio :label="1">1张</el-radio>
               <el-radio :label="3">3张</el-radio>
             </el-radio-group>
@@ -133,13 +137,26 @@ export default {
           photograph: 0,
         },
       }, //播放和拍照设置---暂存
+      listDataCopy: {},
     };
   },
   methods: {
+    disabledFunc() {
+      if (
+        this.listDataCopy.educationName === "考前培训" &&
+        this.listDataCopy.projectName === "施工现场专业人员" &&
+        this.listDataCopy.businessName === "七大员"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
     /**
      * 初始进入
      */
     openBox(obj) {
+      this.listDataCopy = obj
       if (obj.playConfig) {
         this.photoVideoList.playConfig = JSON.parse(
           JSON.stringify(obj.playConfig)

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

@@ -125,7 +125,10 @@
           ></el-input>
         </el-form-item>
         <el-form-item label="是否外链商品" prop="externalLinkStatus">
-          <el-radio-group v-model="listData.externalLinkStatus" @change="activeExternalLinkStatus">
+          <el-radio-group
+            v-model="listData.externalLinkStatus"
+            @change="activeExternalLinkStatus"
+          >
             <el-radio :label="1">是</el-radio>
             <el-radio :label="0">否</el-radio>
           </el-radio-group>
@@ -256,13 +259,50 @@ export default {
           this.$bus.$emit("getCheckQuitRequired", val);
         }
       }
+      this.setListDataBusinessName(val);
     },
   },
   computed: { ...mapGetters(["paysupply", "educationType"]) },
   methods: {
+    //根据业务层级提前设置拍照配置
+    setListDataBusinessName(val) {
+      new Promise((resolve, reject) => {
+        this.listData.photographConfig = {};
+        if (!val) {
+          reject();
+          return;
+        }
+        let data = this.newCourTypeOptions.find((i) => i.id == val);
+        if (
+          data.educationName === "考前培训" &&
+          data.projectName === "施工现场专业人员" &&
+          data.businessName === "七大员"
+        ) {
+          resolve(data);
+        } else {
+          reject();
+        }
+      })
+        .then((res) => {
+          this.$set(this.listData, "educationName", res.educationName);
+          this.$set(this.listData, "projectName", res.projectName);
+          this.$set(this.listData, "businessName", res.businessName);
+          this.$set(this.listData.photographConfig, "photograph", 1);
+          this.$set(this.listData.photographConfig, "photoNum", 3);
+          this.$set(this.listData.photographConfig, "livephotograph", 0);
+        })
+        .catch((err) => {
+          this.$set(this.listData, "educationName", "");
+          this.$set(this.listData, "projectName", "");
+          this.$set(this.listData, "businessName", "");
+          this.$set(this.listData.photographConfig, "photograph", 0);
+          this.$set(this.listData.photographConfig, "photoNum", "");
+        });
+    },
     //校验外链格式
     judgeUrl(val) {
-      var regUrl = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/;
+      var regUrl =
+        /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/;
       let flag = new RegExp(regUrl).test(val);
       if (!flag) {
         this.$message({
@@ -275,8 +315,8 @@ export default {
       }
       return 1;
     },
-    activeExternalLinkStatus(e){
-      this.$emit('activeExternalLinkStatus',e)
+    activeExternalLinkStatus(e) {
+      this.$emit("activeExternalLinkStatus", e);
     },
     subjectChanges() {
       this.$bus.$emit("sendBybus");

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

@@ -4,7 +4,7 @@
       <el-button
         @click="addCourse"
         size="small"
-        :disabled="tableData.length > 0 && tableData[0].type > 0"
+        :disabled="tableData.length > 0 && tableData[0].type > 0 || tableData.length > 0 "
         >添加课程</el-button
       >
       <el-button

+ 19 - 1
src/views/Marketing/goods/commodityManageMent/edit/courseContent/playPhoto.vue

@@ -48,6 +48,7 @@
           <div>
             <el-radio-group
               v-model="photoVideoList.photographConfig.photograph"
+              :disabled="disabledFunc()"
             >
               <el-radio :label="1">是</el-radio>
               <el-radio
@@ -62,7 +63,10 @@
             style="margin-top: 14px"
           >
             拍照数量:
-            <el-radio-group v-model="photoVideoList.photographConfig.photoNum">
+            <el-radio-group
+              :disabled="disabledFunc()"
+              v-model="photoVideoList.photographConfig.photoNum"
+            >
               <el-radio :label="1">1张</el-radio>
               <el-radio :label="3">3张</el-radio>
             </el-radio-group>
@@ -133,13 +137,27 @@ export default {
           photograph: 0,
         },
       }, //播放和拍照设置---暂存
+      listDataCopy: {},
     };
   },
   methods: {
+    disabledFunc() {
+      if (
+        this.listDataCopy.educationName === "考前培训" &&
+        this.listDataCopy.projectName === "施工现场专业人员" &&
+        this.listDataCopy.businessName === "七大员"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
     /**
      * 初始进入
      */
     openBox(obj) {
+      console.log(obj)
+      this.listDataCopy = obj;
       if (obj.playConfig) {
         this.photoVideoList.playConfig = JSON.parse(
           JSON.stringify(obj.playConfig)

+ 16 - 3
src/views/classHoursReview/studyTimes.vue

@@ -188,8 +188,21 @@ export default {
           userId: this.setData.userId,
           goodsId: this.setData.goodsId,
         })
-        .then((res) => {
-          this.userData = res.rows[0];
+        .then(async (res) => {
+          let data = res.rows[0];
+          if (sessionStorage.getItem("spotData")) {
+            var result = JSON.parse(sessionStorage.getItem("spotData"));
+            console.log("fullName",result)
+            data["fullName"] = result.fullName;
+          } else {
+            var result = await this.$api.obtainGoods(this.setData.goodsId);
+            data["fullName"] =
+              result.data.educationName +
+              result.data.projectName +
+              result.data.businessName;
+          }
+          data["supervise"] = true;
+          this.userData = data;
           isS && this.search();
         });
     },
@@ -236,7 +249,7 @@ export default {
               res.rows[0].startTotalTime,
               res.rows[0].endTotalTime,
             ];
-            this.numTotal = res.rows[0].secTotalTime
+            this.numTotal = res.rows[0].secTotalTime;
           }
         })
         .finally(() => {

+ 77 - 7
src/views/education/classManageMent/hoursTimesRecord/index.vue

@@ -1,6 +1,29 @@
 <template>
   <div id="hoursTimesRecord">
     <StudentInfo :userData="userData"></StudentInfo>
+    <div class="datePicker" v-if="objs.time">
+      <span>筛选:</span>
+      <el-date-picker
+        type="month"
+        v-model="objs.time"
+        placeholder="选择月份"
+        @change="changeMonth"
+        value-format="timestamp"
+        style="width: 160px"
+        :clearable="false"
+      >
+      </el-date-picker>
+      <span style="display: inline-block; width: 70px; text-align: end"
+        >周期:</span
+      >
+      <el-button
+        v-for="(item, index) in monthData"
+        :key="index"
+        :type="objs.activeMonth == index ? 'primary' : ''"
+        @click="activeMonthFunc(index)"
+        >第{{ index + 1 }}周</el-button
+      >
+    </div>
     <el-tabs
       style="margin-top: 14px"
       v-if="show"
@@ -69,9 +92,7 @@
             </div>
             <span v-else-if="item.scope === 'durationTime'">
               {{
-                scope.row[item.prop]
-                  ? $methodsTools.secondToDate(scope.row[item.prop], false)
-                  : ""
+                scope.row[item.prop]?(scope.row[item.prop] / 45 / 60).toFixed(1):0
               }}
             </span>
             <span v-else-if="item.scope === 'score'">
@@ -91,6 +112,7 @@ export default {
   name: "HoursTimesRecord",
   data() {
     return {
+      monthData: [],
       size: "medium",
       loading: false,
       userData: {},
@@ -113,7 +135,7 @@ export default {
           scope: "sectionType",
         },
         {
-          label: "节时长",
+          label: "学时",
           prop: "durationTime",
           scope: "durationTime",
         },
@@ -150,7 +172,9 @@ export default {
       total: 0,
       showBox: true,
       //路由参数
-      objs: {},
+      objs: {
+        time: "",
+      },
       //课程列表
       courseList: [],
       //选中课程Id
@@ -167,6 +191,10 @@ export default {
   },
   created() {
     this.objs = this.$route.query;
+    if (this.objs.time) {
+      var a = this.onlyForma(parseInt(this.objs.time));
+      this.monthData = this.$methodsTools.getWeekData(a.year, a.month);
+    }
   },
   mounted() {
     //获取用户信息
@@ -182,6 +210,35 @@ export default {
     },
   },
   methods: {
+    changeMonth() {
+      var a = this.onlyForma(this.objs.time);
+      this.monthData = this.$methodsTools.getWeekData(a.year, a.month);
+      this.activeMonthFunc(0, true);
+    },
+    activeMonthFunc(index, status) {
+      if (this.objs.activeMonth == index && !status) {
+        return;
+      }
+      this.objs.activeMonth = index;
+      this.changeActiveCourseIdFunc(this.activeCourseId);
+    },
+    onlyForma(timeStamp) {
+      if (!timeStamp) {
+        return;
+      }
+      var date = new Date(timeStamp); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
+      var Y = date.getFullYear();
+      var M =
+        date.getMonth() + 1 < 10
+          ? "0" + (date.getMonth() + 1)
+          : date.getMonth() + 1;
+      return {
+        time: timeStamp,
+        date: Y + "-" + M,
+        year: Y,
+        month: M,
+      };
+    },
     //获取商品课程列表
     getGoodsCourseList(id) {
       return new Promise((resolve, reject) => {
@@ -214,14 +271,20 @@ export default {
     changeActiveCourseIdFunc(newName, oldName) {
       return new Promise((resolve, reject) => {
         this.loading = true;
-        const data = {
+        let data = {
           gradeId: this.objs.gradeId,
           userId: this.objs.userId,
           goodsId: this.objs.goodsId,
           courseId: newName,
         };
+        if (this.objs.activeMonth || this.objs.activeMonth == 0) {
+          data.searchWeekStartTime =
+            this.monthData[parseInt(this.objs.activeMonth)].beginTimeCode;
+          data.searchWeekEndTime =
+            this.monthData[parseInt(this.objs.activeMonth)].endTimeCode;
+        }
         this.$api
-          .gradegradelistUserStudyRecord(data)
+          .inquireGradegradelistUserStudyRecordV2Week(data)
           .then((res) => {
             if (res.code === 200) {
               let COURSELISTMX = [];
@@ -351,6 +414,13 @@ export default {
   flex-direction: column;
   height: calc(100vh - 145px);
 }
+.datePicker {
+  margin-top: 14px;
+  font-size: 14px;
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
 .footerTableStyle {
   flex: 1;
   overflow: auto;

+ 1 - 16
src/views/education/classManageMent/learningHoursRecordList/index.vue

@@ -362,22 +362,6 @@ export default {
      * @remards 导出条件
      */
     exputs(data) {
-      // var data = this.$refs.exportTable.formData;
-      // if (!data.businessId) {
-      //   this.$message.warning("请选择业务层次");
-      //   return;
-      // }
-      /**
-       * @remards 学习状态为2的话 需要勾选学时官方推送状态
-       */
-      // if (
-      //   data.studyStatus === 2 &&
-      //   data.officialStatus !== 0 &&
-      //   data.officialStatus !== 1
-      // ) {
-      //   this.$message.warning("请选择学时官方推送状态");
-      //   return;
-      // }
       this.disabledBtn = true;
       this.$modal.loading("正在导出数据,请稍后...");
       this.$api
@@ -434,6 +418,7 @@ export default {
         searchStartTime: this.formData.searchStartTime / 1000 || "",
         searchEndTime: this.formData.searchEndTime / 1000 || "",
         periodStatus: this.formData.periodStatus || "",
+        idCard: this.formData.idCard || "",
         officialStatus:
           this.formData.studyStatus === 2 && this.formData.periodStatus === 1
             ? this.formData.periodPlush

+ 607 - 0
src/views/education/classManageMent/learningHoursRecordListMonth/index.vue

@@ -0,0 +1,607 @@
+<template>
+  <div id="learningHoursRecordListMonth">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="getData(1)"
+      @init="getData(2)"
+      ><template slot="customize">
+        <el-button size="small" type="success" @click="moreActive"
+          >批量导出</el-button
+        >
+      </template></search-box-new
+    >
+    <div style="margin-bottom: 20px">
+      <span
+        style="
+          display: inline-block;
+          width: 70px;
+          text-align: end;
+          font-size: 14px;
+          color: #6b6b6b;
+        "
+        >月份:</span
+      >
+      <el-date-picker
+        style="width: 90%"
+        type="months"
+        v-model="dates"
+        placeholder="选择月份"
+        @change="search"
+        value-format="timestamp"
+      >
+      </el-date-picker>
+    </div>
+    <el-table
+      :row-class-name="tableRowClassName"
+      :default-expand-all="expandAll"
+      border
+      :data="tableData"
+      style="width: 100%"
+      :header-cell-style="{
+        color: '#333',
+        fontSize: '16px',
+      }"
+    >
+      <el-table-column type="expand">
+        <template slot-scope="props">
+          <div style="margin-bottom: 14px">
+            <span style="display: inline-block; width: 70px; text-align: end"
+              >周期:</span
+            >
+            <el-button
+              v-for="(item, index) in props.row.monthData"
+              :key="index"
+              :type="props.row.activeMonth == index ? 'primary' : ''"
+              @click="changeBtn(props.row, index)"
+              >第{{ index + 1 }}周</el-button
+            >
+          </div>
+          <table-list
+            :tableSets="studyTableSet"
+            :tableData="props.row.children"
+            :navText="navText"
+            :navIndex="props.row.total"
+            :loading="props.row.loading"
+          >
+            <template slot="studyTime" slot-scope="propsChild">
+              <span>{{
+                (propsChild.scope.row.studyTime / 45 / 60).toFixed(2) || 0
+              }}</span>
+            </template>
+            <template slot="btn" slot-scope="propsChild">
+              <el-button
+                type="text"
+                @click="activeHoursRecord(propsChild.scope.row, props.row)"
+                >学习记录</el-button
+              >
+              <el-button
+                type="text"
+                @click="activeStudyRecord(propsChild.scope.row, props.row)"
+                :disabled="
+                  [-1, 2, 3].includes(propsChild.scope.row.periodStatus)
+                "
+                >学时记录</el-button
+              >
+            </template>
+          </table-list>
+          <div style="text-align: center">
+            <pagination
+              :total="props.row.total"
+              :pageSize="props.row.params.pageSize"
+              :currentPage="props.row.params.pageNum"
+              @handleSizeChange="handleSizeChange($event, props.row)"
+              @handleCurrentChange="handleCurrentChange($event, props.row)"
+            />
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        header-align="center"
+        label="日期"
+        prop="date"
+      >
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import * as baseUrls from "@/utils/request.js";
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "LearningHoursRecordListMonth",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      expandAll: true,
+      navText: {
+        title: "学习学时记录",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: false,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
+        {
+          prop: "className",
+          placeholder: "请输入班级名称",
+        },
+        {
+          prop: "studyStatus",
+          placeholder: "学习状态",
+          scope: "select",
+          options: [
+            {
+              label: "完成学习",
+              value: 2,
+            },
+            {
+              label: "未完成学习",
+              value: 1,
+            },
+          ],
+        },
+        {
+          prop: "periodStatus",
+          placeholder: "学时审核状态",
+          scope: "select",
+          options: [
+            {
+              label: "不可审核",
+              value: -1,
+            },
+            {
+              label: "待审核",
+              value: 2,
+            },
+            {
+              label: "审核不通过",
+              value: 0,
+            },
+            {
+              label: "审核通过",
+              value: 1,
+            },
+            {
+              label: "审核中",
+              value: 3,
+            },
+          ],
+        },
+        {
+          prop: "periodPlush",
+          placeholder: "请选择学时官方推送状态",
+          scope: "select",
+          noClear: false,
+          diff: "gfxs",
+          options: [
+            {
+              label: "学时官方推送状态",
+              value: "",
+              disable: true,
+            },
+            {
+              label: "是",
+              value: 1,
+            },
+            {
+              label: "否",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop: "idCard",
+          placeholder: "身份证",
+        },
+        {
+          prop: "searchKey",
+          placeholder: "班级名称/商品名称/学员姓名",
+        },
+      ],
+      dates: [],
+      formData: {
+        status: 1,
+        changeGrade: 0,
+        pageSize: 10,
+        pageNum: 1,
+        userPhoto: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "日期",
+          prop: "date",
+          hidden: true,
+        },
+      ],
+      tableData: [], //表单数据
+      // 表单
+      studyTableSet: [
+        {
+          label: "学员姓名",
+          prop: "realName",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+        },
+        {
+          label: "一寸头像照",
+          prop: "oneInchPhotos",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
+        {
+          label: "最近人脸照",
+          prop: "idCardImg1",
+          hidden: true,
+          scope: "img",
+          width: "120px",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+          hidden: true,
+        },
+        {
+          label: "学习学时",
+          prop: "studyTime",
+          hidden: true,
+          scope: "solt",
+          soltName: "studyTime",
+        },
+        {
+          label: "所在班级",
+          prop: "className",
+          hidden: true,
+        },
+        {
+          label: "学习时间",
+          prop1: "startTime",
+          prop2: "endTime",
+          scope: "TimeLists",
+          hidden: false,
+        },
+        {
+          label: "学时审核状态",
+          prop: "periodStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "不可审核",
+              value: -1,
+            },
+            {
+              label: "待审核",
+              value: 2,
+            },
+            {
+              label: "审核不通过",
+              value: 0,
+            },
+            {
+              label: "审核通过",
+              value: 1,
+            },
+            {
+              label: "审核中",
+              value: 3,
+            },
+          ],
+        },
+      ],
+      studyArray: {},
+      studyTableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.getNewMonth();
+  },
+  methods: {
+    tableRowClassName({ row, rowIndex }) {
+      return "success-row";
+    },
+    moreActive() {
+      var ary = ["第一周", "第二周", "第三周", "第四周", "第五周", "第六周"];
+      var array = [];
+      this.dates.forEach((item) => {
+        var alis = this.onlyForma(item);
+        var monthData = this.$methodsTools.getWeekData(alis.year, alis.month);
+        var s = monthData.map((i) => {
+          return {
+            searchWeekStartTime: i.beginTimeCode,
+            searchWeekEndTime: i.endTimeCode,
+            weekCxt: alis.date + " " + ary[parseInt(i.weeknum) - 1],
+          };
+        });
+        array = array.concat(s);
+      });
+      var data = JSON.parse(JSON.stringify(this.formData));
+      delete data.pageNum;
+      delete data.pageSize;
+      data.status = [data.status];
+      data.weekList = array;
+      this.exputs(data)
+    },
+    /**
+     *
+     * @param {Object} data
+     * @remards 导出条件
+     */
+     exputs(data) {
+      this.$modal.loading("正在导出数据,请稍后...");
+      this.$api
+        .gradegradeexportWeek(data)
+        .then(async (res) => {
+          for (let k in res.data) {
+            if (res.data[k].code === 200) {
+              await this.dowmFunc(res, k);
+            } else {
+              this.$message.error("code值错误:", res.data[k].code);
+            }
+          }
+        })
+        .catch((err) => {
+          /**
+           * @remards 请求超时处理
+           */
+          let { message } = err;
+          if (message.includes("timeout")) {
+            this.$message.error(
+              "数据体量过大,无法正常导出,请调整导出的日期范围,缩小数据体量"
+            );
+          }
+        })
+        .finally(() => {
+          this.$modal.closeLoading();
+        });
+    },
+    dowmFunc(res, k) {
+      return new Promise((resolve, reject) => {
+        let url =
+          baseUrls.baseURL + "common/download?fileName=" + res.data[k].msg;
+        let link = document.createElement("a");
+        let fileName = "导入模板" + ".xlsx";
+        document.body.appendChild(link);
+        link.href = url;
+        link.dowmload = fileName;
+        link.click();
+        link.remove();
+        setTimeout(() => {
+          resolve();
+        }, 200);
+      });
+    },
+    getNewMonth() {
+      var date = new Date();
+      date.setDate(1);
+      var cTime = new Date(new Date(date).toLocaleDateString()).getTime();
+      this.dates = [cTime];
+      this.search();
+    },
+    /**
+     * 搜索列表
+     */
+    search() {
+      this.tableData = this.dates?.length
+        ? this.dates
+            .map((i) => {
+              var a = this.onlyForma(i);
+              return {
+                ...a,
+                children: [],
+                loading: false,
+                monthData: this.$methodsTools.getWeekData(a.year, a.month),
+                activeMonth: 0,
+                total: 0,
+                params: {
+                  pageSize: 10,
+                  pageNum: 1,
+                },
+              };
+            })
+            .sort((a, b) => {
+              return a.time - b.time;
+            })
+        : [];
+      this.getData();
+    },
+    getData(int) {
+      this.tableData.forEach(async (i) => {
+        this.getChildrenData(i, int);
+      });
+    },
+    getChildrenData(info, int) {
+      info.loading = true;
+      if (int === 1) {
+        info.params.pageNum = 1;
+      }
+      if (int === 2) {
+        info.params = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+        this.formData = {
+          changeGrade: 0,
+          status: 1,
+          userPhoto: 1,
+        };
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      data.searchWeekStartTime = info.monthData[info.activeMonth].beginTimeCode;
+      data.searchWeekEndTime = info.monthData[info.activeMonth].endTimeCode;
+      let arr = Object.assign(data, info.params);
+      this.$api
+        .inquireGradegradelistUserPeriodWeekRecord(arr)
+        .then((res) => {
+          info.total = res.total;
+          info.children = res.rows;
+        })
+        .finally(() => {
+          info.loading = false;
+        });
+    },
+    changeBtn(item, index) {
+      if (item.activeMonth == index) {
+        return;
+      }
+      item.activeMonth = index;
+      this.getChildrenData(item, 1);
+    },
+    onlyForma(timeStamp) {
+      if (!timeStamp) {
+        return;
+      }
+      var date = new Date(timeStamp); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
+      var Y = date.getFullYear();
+      var M =
+        date.getMonth() + 1 < 10
+          ? "0" + (date.getMonth() + 1)
+          : date.getMonth() + 1;
+      return {
+        time: timeStamp,
+        date: Y + "-" + M,
+        year: Y,
+        month: M,
+      };
+    },
+
+    /**
+     *
+     * @param {Number} v
+     * @remards 每页数量
+     */
+    handleSizeChange(v, item) {
+      item.params.pageSize = v;
+      item.params.pageNum = 1;
+      this.getChildrenData(item);
+    },
+    /**
+     *
+     * @param {Number} v
+     * @remards 切换页码
+     */
+    handleCurrentChange(v, item) {
+      item.params.pageNum = v;
+      this.getChildrenData(item);
+    },
+    /**
+     *
+     * @param {obj} int
+     * @remard 学习记录
+     */
+    activeHoursRecord(options, parentItem) {
+      this.isShow = false;
+      const jump = () => {
+        //班级详情
+        this.$router.push({
+          path: "hoursTimesRecord",
+          query: {
+            gradeId: options.gradeId,
+            userId: options.userId,
+            goodsId: options.goodsId,
+            goodsName: options.goodsName,
+            className: options.className,
+            classHours: options.classHours,
+            studyStartTime: options.studyStartTime,
+            studyEndTime: options.studyEndTime,
+            time: parentItem.time,
+            activeMonth: parentItem.activeMonth,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "HoursTimesRecord";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "HoursTimesRecord",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    /**
+     *
+     * @param {obj} int
+     * @remard 学时记录
+     */
+    activeStudyRecord(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.isShow = false;
+                //学员详情
+                this.$router.push({
+                  path: "classHoursReview",
+                });
+              })
+              .catch(() => {
+                this.$message.error("存在异常,请联系开发人员");
+              });
+          }
+        });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/ .el-table .success-row {
+  background: rgb(204, 221, 247);
+}
+</style>

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

@@ -401,7 +401,7 @@ export default {
           placeholder: "学员报名类型",
           scope: "select",
           options: [
-            { label: "非补考学员", value: 1 },
+            { label: "考学员", value: 1 },
             { label: "补考学员", value: 2 },
           ],
         },
@@ -552,7 +552,7 @@ export default {
           scope: "isOptions",
           options: [
             {
-              label: "非补考学员",
+              label: "考学员",
               value: 1,
             },
             {

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

@@ -666,7 +666,7 @@ export default {
           scope: "isOptions",
           options: [
             {
-              label: "非补考学员",
+              label: "考学员",
               value: 1,
             },
             {

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

@@ -299,7 +299,7 @@ export default {
           scope: "isOptions",
           options: [
             {
-              label: "非补考学员",
+              label: "考学员",
               value: 1,
             },
             {

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

@@ -345,7 +345,7 @@ export default {
           scope: "isOptions",
           options: [
             {
-              label: "非补考学员",
+              label: "考学员",
               value: 1,
             },
             {

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

@@ -319,7 +319,7 @@ export default {
           scope: "isOptions",
           options: [
             {
-              label: "非补考学员",
+              label: "考学员",
               value: 1,
             },
             {

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

@@ -69,7 +69,7 @@
         <p>
           学员信息表 <el-button type="text" @click="userDowm">下载</el-button>
         </p>
-        <p>
+        <p v-if="false">
           疫情防控承诺书
           <el-button type="text" @click="yqbookDown">下载</el-button>
         </p>

+ 6 - 8
src/views/education/examManagement/examArrangement/applicableProducts/index.vue

@@ -49,8 +49,7 @@
                   @change="listDataGoods.businessId = ''"
                   :disabled="
                     statusPop === 0 ||
-                    listDataGoods.goodsId.length > 0 ||
-                    listDataGoods.userId.length > 0
+                    listDataGoods.goodsId.length > 0
                   "
                 >
                   <el-option
@@ -73,8 +72,7 @@
                   v-model="listDataGoods.businessId"
                   :disabled="
                     statusPop === 0 ||
-                    listDataGoods.goodsId.length > 0 ||
-                    listDataGoods.userId.length > 0
+                    listDataGoods.goodsId.length > 0
                   "
                   placeholder="选择业务层次"
                 >
@@ -87,21 +85,21 @@
                   </el-option>
                 </el-select> </el-form-item
             ></el-col>
-            <el-col :span="12" v-if="listDataGoods.businessId"
+            <el-col :span="24" v-if="listDataGoods.businessId"
               ><el-form-item label="适用商品" prop="goodsId">
                 <el-button size="small" type="info" @click="checkgoods"
                   >选择商品</el-button
                 >
               </el-form-item></el-col
             >
-            <el-col :span="12" v-if="listDataGoods.businessId"
+            <el-col :span="12" v-if="listDataGoods.businessId" v-show="false"
               ><el-form-item label="指定学员">
                 <el-button size="small" type="info" @click="checkStudent"
                   >选择学员</el-button
                 ></el-form-item
               ></el-col
             >
-            <el-col :span="12" v-if="listDataGoods.businessId"
+            <el-col :span="24" v-if="listDataGoods.businessId"
               ><el-form-item label="" label-width="78px">
                 <ul class="ul_style_gy" v-if="listDataGoods.goodsId.length">
                   <li
@@ -121,7 +119,7 @@
                 <div v-else style="text-align: center">暂无选择适用商品</div>
               </el-form-item></el-col
             >
-            <el-col :span="12" v-if="listDataGoods.businessId"
+            <el-col :span="12" v-if="listDataGoods.businessId" v-show="false"
               ><el-form-item label="" label-width="78px"
                 ><ul class="ul_style_gy" v-if="listDataGoods.userId.length">
                   <li

+ 129 - 18
src/views/education/examManagement/examArrangement/index.vue

@@ -151,7 +151,7 @@
               v-model="listData.applyStatus"
               style="width: 60%; display: inline-block"
             >
-              <el-checkbox :label="1">非补考学员</el-checkbox>
+              <el-checkbox :label="1">考学员</el-checkbox>
               <el-checkbox :label="2">补考学员</el-checkbox>
             </el-checkbox-group>
             <span style="font-size: 12px; color: #999">注:可多选</span>
@@ -183,11 +183,45 @@
               </el-form-item>
             </el-col>
           </el-form-item>
-          <el-form-item label="线上签署疫情防控承诺书" prop="reportStatus">
-            <el-radio-group v-model="listData.reportStatus">
-              <el-radio :label="1"></el-radio>
-              <el-radio :label="0">否</el-radio>
+          <el-form-item label="场次性质" prop="applyNature">
+            <el-radio-group v-model="listData.applyNature">
+              <el-radio :label="1">普通</el-radio>
+              <el-radio :label="2">专场</el-radio>
             </el-radio-group>
+            <div v-if="listData.applyNature === 2">
+              <div v-if="listData.natureUrl">
+                <img
+                  class="excel"
+                  src="@/assets/images/xlsx.png"
+                  alt="加载失败"
+                />
+                <el-button
+                  size="mini"
+                  @click="listData.natureUrl = ''"
+                  type="danger"
+                  >删除</el-button
+                >
+                <el-button
+                  size="mini"
+                  @click="getDowm('/' + listData.natureUrl)"
+                  >下载</el-button
+                >
+              </div>
+              <label v-else>
+                <span class="upload_style"
+                  >上传文件<i class="el-icon-upload el-icon--right"></i
+                ></span>
+                <input
+                  ref="fileExcel"
+                  type="file"
+                  style="display: none"
+                  @change="editExcel"
+                />
+              </label>
+              <span type="text" class="upload_style pt" @click="getDowm()"
+                >下载模板 <i class="el-icon-download el-icon--right"></i>
+              </span>
+            </div>
           </el-form-item>
         </el-form>
       </div>
@@ -231,8 +265,8 @@
         <div>
           <span>考试地点来源:</span
           ><el-radio-group v-model="radioAddress" @change="clearPlaceData">
-            <el-radio :label="2">智慧考场</el-radio>
             <el-radio :label="1">云学堂</el-radio>
+            <el-radio :label="2" disabled>智慧考场</el-radio>
           </el-radio-group>
         </div>
         <el-button
@@ -380,6 +414,7 @@
       <span slot="footer" class="dialog-footer">
         <el-button @click="dialogExamBoxs = false">取 消</el-button>
         <el-button
+          :disabled="editStatus"
           type="primary"
           v-if="statusPop !== 2"
           :loading="disabledBtn"
@@ -506,7 +541,7 @@
               </el-form-item>
               <el-form-item label="报考学员:">
                 <span v-for="(item, index) in infoData.applyStatus" :key="index"
-                  >{{ item === 1 ? "非补考学员" : item === 2 ? "补考学员" : ""
+                  >{{ item === 1 ? "考学员" : item === 2 ? "补考学员" : ""
                   }}{{
                     index === infoData.applyStatus.length - 1 ? "" : "、"
                   }}</span
@@ -652,6 +687,7 @@
 </template>
 
 <script>
+import * as baseUrls from "@/utils/request.js";
 import searchBox from "@/components/searchBox";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
@@ -739,7 +775,7 @@ export default {
       //   弹窗数据
       listData: {
         applyStatus: [],
-        reportStatus: 1,
+        applyNature: 1,
       },
       statusPop: -1,
       dialogVisible: false,
@@ -779,10 +815,10 @@ export default {
             trigger: "change",
           },
         ],
-        reportStatus: [
+        applyNature: [
           {
             required: true,
-            message: "请选择线上签署疫情防控承诺书",
+            message: "请选择场次性质",
             trigger: "change",
           },
         ],
@@ -841,6 +877,7 @@ export default {
         applyStatus: [],
       },
       sysTime: 0,
+      editStatus: false, //是否禁止修改
     };
   },
   mounted() {
@@ -852,6 +889,19 @@ export default {
     this.search();
   },
   methods: {
+    getDowm(urls = "/oss/images/file/20230616/1686905522334.xls") {
+      let url =
+        baseUrls.BASE_IMG_URL +
+        urls +
+        `?time=${this.$methodsTools.getNewTime()}`;
+      let link = document.createElement("a");
+      let fileName = "导入模板" + ".xlsx";
+      document.body.appendChild(link);
+      link.href = url;
+      link.dowmload = fileName;
+      link.click();
+      link.remove();
+    },
     //下载资料
     downMaterial(row) {
       this.$refs.downMaterial.openBox(row);
@@ -1121,10 +1171,11 @@ export default {
           if (res.rows.length) {
             this.radioAddress = res.rows[0].fromPlat;
           } else {
-            this.radioAddress = 2;
+            this.radioAddress = 1;
           }
           this.examPlaces = res.rows;
           this.dialogExamBoxs = true;
+          this.editStatus = row.people > 0 ? true : false;
         });
     },
     // 判断选择时间逻辑
@@ -1174,7 +1225,7 @@ export default {
         this.$message.warning("图片不得大于300kb");
         return;
       }
-      var type = this.$refs.file.value.toLowerCase().split(".").splice(-1);
+      var type = e.target.value.toLowerCase().split(".").splice(-1);
       if (
         type[0] != "jpg" &&
         type[0] != "png" &&
@@ -1182,12 +1233,41 @@ export default {
         type[0] != "gif"
       ) {
         this.$message.warning("上传格式需为:.jpg/.png/.jpeg/gif");
-        this.$refs.file.value = "";
+        e.target.value = "";
         return;
       }
-      this.$upload.upload(file, 0).then((res) => {
-        this.listData.applyUrl = res;
-      });
+      this.$upload
+        .upload(file, 0)
+        .then((res) => {
+          this.listData.applyUrl = res;
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
+    },
+    editExcel(e) {
+      var file = e.target.files[0];
+      if (file === undefined) {
+        return;
+      }
+      if (file.size > 10 * 1024 * 1024) {
+        this.$message.warning("文件不得大于10MB");
+        return;
+      }
+      var type = e.target.value.toLowerCase().split(".").splice(-1);
+      if (type[0] != "xls" && type[0] != "xlsx") {
+        this.$message.warning("上传格式需为:.xls/.xlsx");
+        e.target.value = "";
+        return;
+      }
+      this.$upload
+        .upload(file, 0)
+        .then((res) => {
+          this.$set(this.listData, "natureUrl", res);
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
     },
     search(v) {
       this.loading = true;
@@ -1307,7 +1387,7 @@ export default {
         this.statusPop = 1;
         this.listData = {
           applyStatus: [],
-          reportStatus: 1,
+          applyNature: 1,
           applyUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
         };
         this.$nextTick(() => {
@@ -1431,6 +1511,38 @@ export default {
 </script>
 
 <style lang="less" scoped>
+.pt {
+  color: #606266 !important;
+  background: #fff !important;
+  border-color: #dcdfe6 !important;
+}
+.upload_style {
+  margin-right: 10px;
+  color: #fff;
+  background-color: #409eff;
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
+  cursor: pointer;
+  border: 1px solid #409eff;
+  -webkit-appearance: none;
+  text-align: center;
+  box-sizing: border-box;
+  outline: none;
+  transition: 0.1s;
+  font-weight: 500;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  padding: 6px 10px;
+  font-size: 12px;
+  border-radius: 4px;
+}
+.excel {
+  width: 38px;
+  margin-right: 14px;
+  vertical-align: bottom;
+}
 .imgBoxWatch {
   width: 200px;
   height: 110px;
@@ -1566,4 +1678,3 @@ export default {
   background-color: #eee;
 }
 </style>
-

+ 277 - 0
src/views/education/examManagement/listOfTestRooms/index.vue

@@ -0,0 +1,277 @@
+<template>
+  <div id="learningHoursRecordList">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+      ><template slot="customize">
+        <el-button size="small" type="success" @click="moreActive"
+          >发送邮件</el-button
+        >
+      </template></search-box-new
+    >
+    <table-list
+      row-key="id"
+      ref="tableList"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+    >
+      <template slot="num" slot-scope="props">
+        <div>
+          <span style="color: rgb(78, 175, 255)">{{
+            props.scope.row["people"] || 0
+          }}</span>
+          {{ " / " + props.scope.row["mayNum"] || 0 }}
+        </div>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <sendEmail ref="sendEmail" />
+  </div>
+</template>
+
+<script>
+import sendEmail from "./sendEmail.vue";
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "ListOfTestRooms",
+  components: {
+    searchBoxNew,
+    tableList,
+    pagination,
+    sendEmail,
+  },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "考场列表",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        tableHide: true,
+        openCheckMore: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+        selectableStatus: true,
+        selectableFunc: (row, rowIndex) => {
+          if (row.people) {
+            return true;
+          } else {
+            return false;
+          }
+        },
+      },
+      //搜索
+      formList: [
+        {
+          prop1: "startTime",
+          prop2: "endTime",
+          placeholder1: "开始时间",
+          placeholder2: "结束时间",
+          scope: "moreDataPicker",
+        },
+      ],
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "考试日期",
+          prop: "applyDate",
+          hidden: true,
+          scope: "aTimeList",
+          isDiszing: true,
+        },
+        {
+          label: "考试时间段",
+          prop: "applyTime",
+          hidden: true,
+        },
+        {
+          label: "报名时间",
+          prop1: "applyStartTime",
+          prop2: "applyEndTime",
+          hidden: true,
+          Diszing: true,
+          scope: "TimeLists",
+        },
+        {
+          label: "已报考人数/可报考人数",
+          hidden: true,
+          soltName: "num",
+          scope: "solt",
+        },
+        {
+          label: "考试性质",
+          prop: "applyNature",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "普通场",
+              value: 1,
+            },
+            {
+              label: "专场",
+              value: 2,
+            },
+          ],
+        },
+        {
+          label: "学员限制",
+          prop: "applyStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "新考学员",
+              value: "1",
+            },
+            {
+              label: "补考学员",
+              value: "2",
+            },
+            {
+              label: "新考学员,补考学员",
+              value: "1,2",
+            },
+          ],
+        },
+        {
+          label: "是否发送",
+          prop: "sendmail",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "未发送",
+              value: 0,
+            },
+            {
+              label: "已发送",
+              value: 1,
+            },
+          ],
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    moreActive() {
+      if (this.$refs.tableList.allCheckData.length === 0) {
+        this.$message.error("请勾选数据");
+        return;
+      }
+      let ids = [];
+      let timeList = [];
+      this.$refs.tableList.allCheckData.forEach((i) => {
+        ids.push(i.id);
+        timeList.push(i.applyDate);
+      });
+      timeList.sort((a, b) => {
+        return a - b;
+      });
+      let time = [timeList[0], timeList[timeList.length - 1]];
+      let info = {
+        ids: ids,
+        time: time,
+      };
+      this.$refs.sendEmail.init(info);
+    },
+    /**
+     * 搜索列表
+     */
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      if (int === 3) {
+        this.$refs.tableList.clearMoreActive();
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.startTime) {
+        data.startTime = parseInt(data.startTime / 1000);
+      }
+      if (this.formData.endTime) {
+        data.endTime = parseInt(data.endTime / 1000);
+      }
+      this.$api
+        .inquireexamapplyplaceList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    /**
+     * 重置列表
+     */
+    init() {
+      this.search(2);
+    },
+    /**
+     *
+     * @param {Number} v
+     * @remards 每页数量
+     */
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    /**
+     *
+     * @param {Number} v
+     * @remards 切换页码
+     */
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+</style>

+ 177 - 0
src/views/education/examManagement/listOfTestRooms/sendEmail.vue

@@ -0,0 +1,177 @@
+<template>
+  <div>
+    <BaseDialog
+      width="700px"
+      :isShow.sync="emailDialog"
+      title="发送邮件"
+      @close="close"
+      @submit="submitForm"
+      :appendToBody="true"
+      :confirmStatus="false"
+    >
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="140px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="邮件主题:" prop="mailName">
+          <el-input v-model="ruleForm.mailName"></el-input> </el-form-item
+        ><el-form-item label="收件人邮箱地址:" prop="mailAttrList">
+          <el-select
+            style="width: 100%"
+            v-model="ruleForm.mailAttrList"
+            multiple
+            filterable
+            allow-create
+            default-first-option
+            placeholder="请输入邮箱地址"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select> </el-form-item
+        ><el-form-item label="邮件附件:">
+          <span v-if="info.time && info.time.length">{{
+            dowmloadEmailName
+          }}</span>
+          <el-button
+            size="mini"
+            type="primary"
+            @click="getDowm"
+            style="margin-left: 10px"
+            >下载</el-button
+          > </el-form-item
+        ><el-form-item label="邮件内容:" prop="mailText">
+          <editor
+            v-model="ruleForm.mailText"
+            :min-height="300"
+            :max-height="500"
+            :uploadStatus="2"
+          /> </el-form-item
+      ></el-form>
+    </BaseDialog>
+  </div>
+</template>
+
+<script>
+import Editor from "@/components/Editor";
+import * as baseUrls from "@/utils/request.js";
+export default {
+  components: { Editor },
+  data() {
+    var checkEmails = (rule, value, callback) => {
+      var reg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
+      if (value.every((i) => reg.test(i) === true)) {
+        callback();
+      } else {
+        callback(new Error("邮箱地址格式错误,请检查邮箱地址格式"));
+      }
+    };
+    return {
+      rules: {
+        mailName: [
+          { required: true, message: "请输入邮件主题", trigger: "blur" },
+        ],
+        mailAttrList: [
+          {
+            required: true,
+            message: "请创建收件人邮箱地址",
+            trigger: "change",
+          },
+          { validator: checkEmails, trigger: "change" },
+        ],
+        mailText: [
+          { required: true, message: "请输入邮件内容", trigger: "blur" },
+        ],
+      },
+      ruleForm: {},
+      options: [],
+      dowmloadEmail: "",
+      dowmloadEmailName: "",
+      emailDialog: false,
+      info: {},
+    };
+  },
+
+  mounted() {},
+
+  methods: {
+    init(data) {
+      this.info = data;
+      this.emailDialog = true;
+      console.log(this.info, "info");
+      if (this.info.time?.length) {
+        var times =
+          this.$methodsTools.onlyForma(this.info.time[0], false) +
+          " 至 " +
+          this.$methodsTools.onlyForma(this.info.time[1], false);
+        this.ruleForm.mailName = times + "测试计划学习记录";
+        this.ruleForm.mailText =
+          "<p>您好,周老师!</p><p>		附件是" +
+          times +
+          "参考学员学习记录,请查收!</p><p>致礼!</p><p>																			云学堂 " +
+          this.$methodsTools.onlyForma(new Date().getTime() / 1000, false) +
+          "</p>";
+      }
+      this.$api.examapplysendmail({ ids: this.info.ids }).then((res) => {
+        this.dowmloadEmail = res.msg;
+        this.dowmloadEmailName =
+          this.$methodsTools.onlyForma(this.info.time[0], false) +
+          " - " +
+          this.$methodsTools.onlyForma(this.info.time[1], false) +
+          "测试计划学习记录.zip";
+      });
+      this.$nextTick(() => {
+        this.$refs["ruleForm"].clearValidate();
+      });
+    },
+    getDowm() {
+      let url =
+        baseUrls.BASE_IMG_URL +
+        "/" +
+        this.dowmloadEmail +
+        `?time=${this.$methodsTools.getNewTime()}`;
+      let link = document.createElement("a");
+      let fileName = "导入模板" + ".xlsx";
+      document.body.appendChild(link);
+      link.href = url;
+      link.dowmload = fileName;
+      link.click();
+      link.remove();
+    },
+    close() {},
+    submitForm() {
+      this.$refs["ruleForm"].validate((valid) => {
+        if (valid) {
+          var data = JSON.parse(JSON.stringify(this.ruleForm));
+          data.mailUrl = this.dowmloadEmail;
+          data.mailUrlName = this.dowmloadEmailName;
+          data.ids = this.info.ids;
+          this.$api.systemapplysend(data).then((res) => {
+            this.$message.success("发送成功");
+            this.emailDialog = false;
+            this.$parent.search(3);
+          });
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.el-timeline {
+  padding: 0px 6px;
+  max-height: 600px;
+  overflow: auto;
+}
+</style>

+ 1 - 1
src/views/education/examManagement/qianpeiArrange/allAssociatedExamPlans.vue

@@ -42,7 +42,7 @@
                     .map(Number)"
                   :key="idm"
                 >
-                  {{ itm === 1 ? "非补考学员" : itm === 2 ? "补考学员" : "" }}
+                  {{ itm === 1 ? "考学员" : itm === 2 ? "补考学员" : "" }}
                 </span>
               </div>
               <el-button

+ 1 - 1
src/views/education/examManagement/qianpeiArrange/assExamPlan.vue

@@ -66,7 +66,7 @@
                       .map(Number)"
                     :key="idm"
                   >
-                    {{ itm === 1 ? "非补考学员" : itm === 2 ? "补考学员" : "" }}
+                    {{ itm === 1 ? "考学员" : itm === 2 ? "补考学员" : "" }}
                   </span>
                 </template>
                 <span v-else></span>

+ 1 - 1
src/views/education/examManagement/qianpeiArrange/index.vue

@@ -303,7 +303,7 @@
             <div v-for="(item, index) in infoData.list" :key="index">
               {{ index + 1 }}.{{ item.applyName }} (<span
                 v-if="item.applyStatus.includes('1')"
-                >非补考学员、</span
+                >考学员、</span
               ><span v-if="item.applyStatus.includes('2')">补考学员、</span
               >{{ $methodsTools.onlyForma(item.applyStartTime) }} - {{
                 $methodsTools.onlyForma(item.applyEndTime)

+ 28 - 6
src/views/education/mockTestManagement/mockTestData/index.vue

@@ -6,7 +6,12 @@
       :formList="formList"
       @search="search"
       @init="init"
-    />
+      ><template slot="customize">
+        <el-button size="small" type="success" @click="moreActive"
+          >批量导出</el-button
+        >
+      </template></search-box-new
+    >
     <table-list
       :tableSets="tableSet"
       :tableData="tableData"
@@ -31,6 +36,7 @@
 </template>
 
 <script>
+import { exportFn } from "@/utils/index.js";
 import searchBoxNew from "@/components/searchBoxNew";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
@@ -59,7 +65,6 @@ export default {
           prop: "subscribeStatus",
           placeholder: "预约状态",
           scope: "select",
-          noClear: false,
           options: [
             {
               label: "正常",
@@ -94,11 +99,17 @@ export default {
           scope: "subjectType",
           edu: "educationTypeId",
         },
+        {
+          prop1: "startScore",
+          placeholder1: "开始分数",
+          prop2: "endScore",
+          placeholder2: "结束分数",
+          scope: "numList",
+        },
         {
           prop: "firstSubjectiveScore",
           placeholder: "主观题待评分",
           scope: "select",
-          noClear: false,
           options: [
             {
               label: "是",
@@ -219,7 +230,7 @@ export default {
       );
       this.$refs.searchBox.changeBusinessLevel(this.$route.params.businessId);
     }
-    if(this.$route.params.applyName){
+    if (this.$route.params.applyName) {
       this.$set(this.formData, "applyName", this.$route.params.applyName);
     }
     this.search();
@@ -228,6 +239,18 @@ export default {
     this.search();
   },
   methods: {
+    moreActive() {
+      var data = JSON.parse(JSON.stringify(this.formData));
+      delete data.pageNum;
+      delete data.pageSize;
+      this.$api.exportMockrecordData(data).then((res) => {
+        if (res.msg) {
+          exportFn(res.msg, `导出数据`);
+        } else {
+          this.$message.error("导出失败");
+        }
+      });
+    },
     /**
      * 预约/取消点击触发
      */
@@ -304,5 +327,4 @@ export default {
 };
 </script>
 
-<style lang="less" scoped>
-</style>
+<style lang="less" scoped></style>

+ 12 - 6
src/views/index.vue

@@ -809,7 +809,9 @@ export default {
     },
   },
   computed: {
-    ...mapGetters(["educationType"]),
+    educationType(){
+      return sessionStorage.getItem('spotData')?[]: this.$store.getters['educationType']
+    },
     changeDateTime: function () {
       return function (date) {
         if (date) {
@@ -824,13 +826,17 @@ export default {
     },
   },
   created() {
-    getInfo().then((res) => {
-      this.user = res.data.user;
-    });
+    if (!sessionStorage.getItem("spotData")) {
+      getInfo().then((res) => {
+        this.user = res.data.user;
+      });
+    }
   },
   mounted() {
-    console.log(this.$store.state.user.roles,this.$store.state.user.roles.includes("supervisory"))
-    if (this.$store.state.user.roles.includes("supervisory")) {
+    if (
+      this.$store.state.user.roles.includes("supervisory") ||
+      sessionStorage.getItem("spotData")
+    ) {
       this.ShowStatus = false;
     }
     /**

+ 13 - 1
src/views/resource/bankManagement/testPaperManagement/BatchImportPop.vue

@@ -17,6 +17,18 @@
     :isShowTip="false"
     @success="ExcelSuccess"
   ></batch-import-dialoga>
+  <batch-import-dialoga
+  v-else-if="type == 4"
+    :dialogVisible.sync="dialogVisible"
+    temUrl="/oss/images/file/20220324/1648102107588.docx"
+    apiKey="bankquestionimportJJWordQuestionList"
+    :isCheck="false"
+    :isShowTip="false"
+    :isSuccessBack="true"
+    @success="wordSuccess"
+    type="Word"
+    :param="formData"
+  ></batch-import-dialoga>
   <batch-import-dialoga
     v-else
     :dialogVisible.sync="dialogVisible"
@@ -46,7 +58,7 @@ export default {
         subjectId: "",
         projectId: "",
       },
-      type: 1, //1是execl 2 word
+      type: 1, //1是execl 2 word 4建匠题目Word
     };
   },
   methods: {

+ 5 - 0
src/views/resource/bankManagement/testPaperManagement/addPaper/topicAddPaper/index.vue

@@ -26,6 +26,11 @@
             @click="$refs.batchPop.openBoxs(tableData, businObj, 3)"
             type="success"
             >(旧系统)Excel批量导入</el-button
+          ><el-button
+            size="medium"
+            @click="$refs.batchPop.openBoxs(tableData, businObj, 4)"
+            type="success"
+            >建匠题目Word批量导入</el-button
           >
           <el-button
             size="medium"

+ 6 - 0
src/views/resource/bankManagement/testPaperManagement/editPaper/topicEditPaper/index.vue

@@ -22,6 +22,12 @@
             type="success"
             :disabled="!noStudent"
             >(旧系统)Excel批量导入</el-button
+          ><el-button
+            size="medium"
+            @click="$refs.batchPop.openBoxs(tableData, businObj, 4)"
+            type="success"
+            :disabled="!noStudent"
+            >建匠题目Word批量导入</el-button
           >
           <el-button
             size="medium"

+ 1 - 1
src/views/secondJian/courseList/index.vue

@@ -305,7 +305,7 @@ export default {
       var data = JSON.parse(JSON.stringify(this.formData));
       data.chapterNum = 1
       this.$api
-        .inquireGoods(data)
+        .commonfreegoodslist(data)
         .then((res) => {
           this.tableData = res.rows;
           this.total = res.total;

+ 1 - 1
src/views/secondZao/courseList/index.vue

@@ -305,7 +305,7 @@ export default {
       var data = JSON.parse(JSON.stringify(this.formData));
       data.chapterNum = 1
       this.$api
-        .inquireGoods(data)
+        .commonfreegoodslist(data)
         .then((res) => {
           this.tableData = res.rows;
           this.total = res.total;

+ 95 - 0
src/views/system/user/profile/email.vue

@@ -0,0 +1,95 @@
+<template>
+  <el-form ref="form" :model="configValue" :rules="rules" label-width="140px">
+    <el-form-item label="邮箱账号" prop="postAccount">
+      <el-input
+        v-model="configValue.postAccount"
+        placeholder="请输入邮箱账号"
+      />
+    </el-form-item>
+    <el-form-item label="授权密码" prop="postPassword">
+      <el-input
+        v-model="configValue.postPassword"
+        placeholder="请输入授权密码"
+      />
+    </el-form-item>
+    <el-form-item label="STMP服务期地址" prop="STMPserver">
+      <el-input
+        v-model="configValue.STMPserver"
+        placeholder="请输入STMP服务期地址"
+      />
+    </el-form-item>
+    <el-form-item label="端口号" prop="post">
+      <el-input v-model="configValue.post" placeholder="请确认端口号" />
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" size="mini" @click="submit">保存</el-button>
+      <el-button type="danger" size="mini" @click="close">关闭</el-button>
+    </el-form-item>
+  </el-form>
+</template>
+
+<script>
+import { updateConfig } from "@/api/system/config";
+
+export default {
+  props: {
+    info: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+    configValue: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  data() {
+    const emailValidator = (rule, value, callback) => {
+      var reg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
+      if (reg.test(value)) {
+        callback();
+      } else {
+        callback(new Error("邮箱账号格式错误,请检查邮箱账号格式"));
+      }
+    };
+    return {
+      test: "1test",
+      // 表单校验
+      rules: {
+        postAccount: [
+          { required: true, message: "请输入邮箱账号", trigger: "blur" },
+          { validator: emailValidator, trigger: "blur" },
+        ],
+        postPassword: [
+          { required: true, message: "请输入授权密码", trigger: "blur" },
+        ],
+        STMPserver: [
+          { required: true, message: "请输入STMP服务器地址", trigger: "blur" },
+        ],
+        post: [{ required: true, message: "请输入端口", trigger: "blur" }],
+      },
+    };
+  },
+  methods: {
+    submit() {
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          let data = JSON.parse(JSON.stringify(this.configValue));
+          let copySubmitData = JSON.parse(JSON.stringify(this.info));
+          copySubmitData.configValue = JSON.stringify(data);
+          updateConfig(copySubmitData).then(() => {
+            this.$message.success("保存成功");
+          });
+        }
+      });
+    },
+    close() {
+      this.$store.dispatch("tagsView/delView", this.$route);
+      this.$router.push({ path: "/index" });
+    },
+  },
+};
+</script>

+ 24 - 6
src/views/system/user/profile/index.vue

@@ -25,7 +25,9 @@
               </li>
               <li class="list-group-item">
                 <svg-icon icon-class="tree" />所属部门
-                <div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div>
+                <div class="pull-right" v-if="user.dept">
+                  {{ user.dept.deptName }} / {{ postGroup }}
+                </div>
               </li>
               <li class="list-group-item">
                 <svg-icon icon-class="peoples" />所属角色
@@ -51,6 +53,9 @@
             <el-tab-pane label="修改密码" name="resetPwd">
               <resetPwd :user="user" />
             </el-tab-pane>
+            <el-tab-pane label="邮箱配置" name="postEmail">
+              <email :info="info" :configValue="configValue" />
+            </el-tab-pane>
           </el-tabs>
         </el-card>
       </el-col>
@@ -59,20 +64,24 @@
 </template>
 
 <script>
+import { listConfig } from "@/api/system/config";
 import userAvatar from "./userAvatar";
 import userInfo from "./userInfo";
 import resetPwd from "./resetPwd";
+import email from "./email";
 import { getUserProfile } from "@/api/system/user";
 
 export default {
   name: "Profile",
-  components: { userAvatar, userInfo, resetPwd },
+  components: { userAvatar, userInfo, resetPwd, email },
   data() {
     return {
       user: {},
+      info: {},
+      configValue:{},
       roleGroup: {},
       postGroup: {},
-      activeTab: "userinfo"
+      activeTab: "userinfo",
     };
   },
   created() {
@@ -80,12 +89,21 @@ export default {
   },
   methods: {
     getUser() {
-      getUserProfile().then(response => {
+      getUserProfile().then((response) => {
         this.user = response.data;
         this.roleGroup = response.roleGroup;
         this.postGroup = response.postGroup;
       });
-    }
-  }
+      this.getUserPostEmail();
+    },
+    getUserPostEmail() {
+      listConfig({ configKey: "home.mail" }).then((res) => {
+        if (res.rows.length) {
+          this.info = res.rows[0];
+          this.configValue = JSON.parse(res.rows[0].configValue);
+        }
+      });
+    },
+  },
 };
 </script>