Browse Source

Merge remote-tracking branch 'origin/master'

wangchangsheng 2 years ago
parent
commit
2134c222fd

+ 1 - 1
exam-06173-uni - reg/pages/course/detail.vue

@@ -82,7 +82,7 @@
 					</view>
 					
 					<view v-if="current === 1">
-						<rich-text :nodes="courseData.content | formatRichText"></rich-text>
+						<!-- <rich-text :nodes="courseData.content | formatRichText"></rich-text> -->
 						<u-parse :content="courseData.content | formatRichText" @preview="preview" @navigate="navigate" ></u-parse>
 					</view>
 				</view>

+ 1 - 1
exam-06173-uni/pages/course/detail.vue

@@ -82,7 +82,7 @@
 					</view>
 					
 					<view v-if="current === 1">
-						<rich-text :nodes="courseData.content | formatRichText"></rich-text>
+						<!-- <rich-text :nodes="courseData.content | formatRichText"></rich-text> -->
 						<u-parse :content="courseData.content | formatRichText" @preview="preview" @navigate="navigate" ></u-parse>
 					</view>
 				</view>

BIN
exam-06173-vue/public/introduce/智能多媒体考试培训系统功能讲解.mp4


+ 14 - 1
exam-06173-vue/src/components/DataTable/index.vue

@@ -46,7 +46,7 @@
 
       <el-table-column
         v-if="options.multi"
-        :reserve-selection="false"
+        :reserve-selection="true"
         align="center"
         type="selection"
         width="55"
@@ -145,9 +145,20 @@ export default {
         this.getList()
       },
       deep: true
+    }, // 检测判定弹框类嵌套组件时, 激活时清空表格选择项
+    '$parent.$parent.dialogVisible': {
+      handler(val) {
+        if (val) {
+          this.clearSelection()
+        }
+      },
+      deep: true
     }
   },
   created() {
+    // 创建时 清空选中的所有项
+    this.selectedIds = []
+    this.selectedObjs = []
     this.getList()
   },
   methods: {
@@ -385,6 +396,8 @@ export default {
 
     // 清理选择的
     clearSelection() {
+      this.selectedIds = []
+      this.selectedObjs = []
       this.$refs.table.clearSelection()
     }
 

+ 3 - 0
exam-06173-vue/src/components/Tinymce/index.vue

@@ -151,6 +151,9 @@ export default {
     getContent() {
       window.tinymce.get(this.tinymceId).getContent()
     },
+    getTextContent() {
+      return window.tinymce.get(this.tinymceId).getContent( { format : 'text' } );
+    },
     imageSuccessCBK(arr) {
       const that = this
       arr.forEach(v => {

+ 5 - 1
exam-06173-vue/src/layout/components/Navbar.vue

@@ -43,6 +43,9 @@
           <router-link to="/">
             <el-dropdown-item>学员首页</el-dropdown-item>
           </router-link>
+          <router-link to="/introduce/index" v-if="isDemo">
+            <el-dropdown-item>视频介绍</el-dropdown-item>
+          </router-link>
           <el-dropdown-item divided>
             <span style="display:block;" @click="logout">退出登录</span>
           </el-dropdown-item>
@@ -70,7 +73,8 @@ export default {
   },
   data() {
     return {
-      downloadShow: false
+      downloadShow: false,
+      isDemo: process.env.NODE_ENV === 'demo'
     }
   },
   computed: {

+ 14 - 0
exam-06173-vue/src/router/index.js

@@ -117,6 +117,20 @@ export const constantRoutes = [
       }
     ]
   },
+  {
+    path: '/introduce',
+    component: Layout,
+    redirect: '/introduce/index',
+    hidden: true,
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/introduce/index'),
+        name: 'Introduce',
+        meta: { title: '视频介绍', icon: 'user', noCache: true }
+      }
+    ]
+  },
 
   {
     path: '/',

+ 36 - 0
exam-06173-vue/src/utils/export-word.js

@@ -0,0 +1,36 @@
+const Export2Word = (elementStr, filename = '') => {
+  var preHtml = "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'><head><meta charset='utf-8'><title>Export HTML To Doc</title></head><body>";
+  var postHtml = "</body></html>";
+  var html = preHtml + elementStr + postHtml;
+
+  var blob = new Blob(['\ufeff', html], {
+    type: 'application/msword'
+  });
+
+  // Specify link url
+  var url = 'data:application/vnd.ms-word;charset=utf-8,' + encodeURIComponent(html);
+
+  // Specify file name
+  filename = filename ? filename + '.doc' : 'document.doc';
+
+  // Create download link element
+  var downloadLink = document.createElement("a");
+
+  document.body.appendChild(downloadLink);
+
+  if (navigator.msSaveOrOpenBlob) {
+    navigator.msSaveOrOpenBlob(blob, filename);
+  } else {
+    // Create a link to the file
+    downloadLink.href = url;
+
+    // Setting the file name
+    downloadLink.download = filename;
+
+    //triggering the function
+    downloadLink.click();
+  }
+
+  document.body.removeChild(downloadLink);
+}
+export default Export2Word

+ 4 - 4
exam-06173-vue/src/views/admin/exam/exam/form.vue

@@ -224,12 +224,12 @@
                     </el-radio-group>
 
                     <div style="padding-top: 20px">
-                      <div v-if="postForm.openType == 1">
+                      <!-- <div v-if="postForm.openType == 1">
                         <el-alert
                           title="开放的,任何人都可以进行考试!"
                           type="warning"
                         />
-                      </div>
+                      </div> -->
 
                       <div v-if="postForm.openType == 2">
                         <depart-refs
@@ -471,7 +471,7 @@ export default {
         endTime: timeEnd.formatDate("yyyy-MM-dd hh:mm:ss"),
         capture: 0,
         // 开放权限
-        openType: 1,
+        openType: 2,
         // 积分数量
         points: 0,
         // 是否截屏
@@ -523,7 +523,7 @@ export default {
     if (id !== undefined) {
       this.fetchData(id);
     } else {
-      this.postForm.openType = 1;
+      this.postForm.openType = 2;
       this.postForm.joinType = 1;
     }
 

+ 27 - 44
exam-06173-vue/src/views/admin/repo/qu/components/QuSelectDialog.vue

@@ -1,21 +1,10 @@
 <template>
 
-  <el-dialog
-    :visible.sync="dialogVisible"
-    :close-on-click-modal="false"
-    title="选择试题"
-    width="60%"
-    @close="handleClose"
-  >
+  <el-dialog :visible.sync="dialogVisible" :close-on-click-modal="false" title="选择试题" width="60%" @close="handleClose">
 
     <div class="app-container">
 
-      <data-table
-        ref="pagingTable"
-        :options="options"
-        :list-query="listQuery"
-        @select-changed="handleSelected"
-      >
+      <data-table ref="pagingTable" :options="options" :list-query="listQuery" @select-changed="handleSelected">
         <template slot="filter-content">
 
           <el-row>
@@ -23,9 +12,11 @@
 
               <repo-select v-model="listQuery.params.repoId" :is-exam="true" />
 
-              <el-input v-model="listQuery.params.content" placeholder="试题内容" style="width: 200px;" class="filter-item" />
+              <el-input v-model="listQuery.params.content" placeholder="试题内容" style="width: 200px;"
+                class="filter-item" />
 
-              <el-button type="primary" class="filter-item" style="float:  right" @click="handleConfirm">{{ selectedLabel }}</el-button>
+              <el-button type="primary" class="filter-item" style="float:  right" @click="handleConfirm">{{
+              selectedLabel }}</el-button>
 
             </el-col>
           </el-row>
@@ -34,35 +25,20 @@
 
         <template slot="data-columns">
 
-          <el-table-column
-            label="试题类型"
-            align="center"
-            width="100px"
-            prop="quType_dictText"
-          />
-
-          <el-table-column
-            label="试题内容"
-            show-overflow-tooltip
-          >
+          <el-table-column label="试题类型" align="center" width="100px" prop="quType_dictText" />
+
+          <el-table-column label="试题内容" show-overflow-tooltip>
             <template slot-scope="scope">
-              <router-link :to="{ name: 'UpdateQu', params:{ id: scope.row.id}}">
-                {{ scope.row.contentText }}
-              </router-link>
+              <a href="javascript:;" @click="funPush('UpdateQu', {id: scope.row.id})">{{ scope.row.contentText }}</a>
+              <!-- <router-link :to="{ name: 'UpdateQu', params:{ id: scope.row.id}}"> -->
+
+              <!-- </router-link> -->
             </template>
           </el-table-column>
 
-          <el-table-column
-            label="所属题库"
-            align="center"
-            prop="repoId_dictText"
-          />
+          <el-table-column label="所属题库" align="center" prop="repoId_dictText" />
 
-          <el-table-column
-            label="级别"
-            align="center"
-            prop="level_dictText"
-          />
+          <el-table-column label="级别" align="center" prop="level_dictText" />
 
         </template>
 
@@ -168,6 +144,15 @@ export default {
       this.$emit('update:dialogShow', false)
       this.$emit('select', this.selectedList)
       this.$refs.pagingTable.clearSelection()
+    },
+    funPush(name, params) {
+      this.$emit('update:dialogShow', false)
+      this.$emit('select', this.selectedList)
+      this.$refs.pagingTable.clearSelection()
+      this.$router.push({
+        name,
+        params
+      })
     }
 
   }
@@ -175,9 +160,7 @@ export default {
 </script>
 
 <style scoped>
-
-  ::v-deep
-  .el-dialog__body{
-    padding: 0px;
-  }
+::v-deep .el-dialog__body {
+  padding: 0px;
+}
 </style>

+ 31 - 7
exam-06173-vue/src/views/admin/stat/total/archives.vue

@@ -44,7 +44,7 @@
           ref="archivesTableRef-bm"
           :data="bmTableData"
           border
-          height="250"
+          :height="tableHeight"
           style="width: 100%"
         >
           <el-table-column fixed="left" label="名称" align="center">
@@ -70,11 +70,11 @@
             <template slot-scope="scope">{{scope.row.pxl}}%</template>
           </el-table-column>
           <el-table-column prop="rjxs" label="人均学时" sortable align="center" >
-            <template slot-scope="scope">{{scope.row.rjxs}}%</template>
+            <template slot-scope="scope">{{scope.row.rjxs}}</template>
           </el-table-column>
           <el-table-column prop="ecTotalMin" sortable label="累计学时" align="center" />
           <el-table-column
-            prop="ecTotalUser"
+            prop="eeTotalUser"
             label="应考试人数"
             align="center"
             sortable
@@ -193,11 +193,17 @@ export default {
       zgTableData: [],
       selectDeptCode: "",
       selectDeptName: "",
+      myChart: null,
+      tableHeight: (window.innerHeight - 657) <= 280 ? 280 : window.innerHeight - 657
     };
   },
 
   mounted() {
     this.resetDate(this.radio);
+    window.addEventListener('resize', () => {
+      this.myChart.resize()
+      this.tableHeight = (window.innerHeight - 657) <= 280 ? 280 : window.innerHeight - 657
+    })
   },
 
   methods: {
@@ -274,14 +280,22 @@ export default {
     // 初始化图表
     initChart(xAxisData, seriesData) {
       let myChart = echarts.init(document.getElementById("chartDom"));
+      this.myChart = myChart
       let option;
 
       option = {
+        title: {
+          showTitle: true,
+          subtext: "可滚轮缩放、左右拖动查看",
+          x: "center",
+          y: "20",
+        },
         xAxis: {
           type: "category",
           data: xAxisData,
         },
         yAxis: {
+          name: '单位 (%)',
           type: "value",
         },
         legend: {
@@ -311,10 +325,20 @@ export default {
         grid: {
           show: true,
           left: "35",
-          top: "23",
+          // top: "23",
           right: "30",
           bottom: "23",
         },
+        dataZoom: [
+          {
+            id: "dataZoomX",
+            type: "inside",
+            xAxisIndex: [0],
+            filterMode: "none",
+            start: 0,
+            end: 50,
+          },
+        ],
         series: [
           {
             name: "部门培训率",
@@ -378,7 +402,7 @@ export default {
         nowDate.setDate(0)
         const day = nowDate.getDate()
         this.date = [
-          nowDate.formatDate("yyyy")+ `-${(minMonth < 10 ? "0" + minMonth : maxMonth)}-01`,
+          nowDate.formatDate("yyyy")+ `-${(minMonth < 10 ? "0" + minMonth : minMonth)}-01`,
             nowDate.formatDate("yyyy") +
             `-${(maxMonth < 10 ? "0" + maxMonth : maxMonth)}-${day}`,
         ];
@@ -444,9 +468,9 @@ export default {
             ele['应培训人数'] = ele.ecTotalUser
             ele['实培训人数'] = ele.ecActualUser
             ele['培训率'] = this.renderNumber(ele.ecActualUser, ele.ecTotalUser)
-            ele['人均学时'] = this.renderNumber(ele.ecActualUser, ele.ecTotalMin);
+            ele['人均学时'] = this.renderNumber(ele.ecActualUser, ele.ecTotalMin, true);
             ele['累积学时'] = ele.ecTotalMin
-            ele['应考试人数'] = ele.ecTotalUser
+            ele['应考试人数'] = ele.eeTotalUser
             ele['实考试人数'] = ele.eeActualUser
             ele['考试率'] = this.renderNumber(ele.eeActualUser, ele.eeTotalUser);
             ele['考试合格率'] = this.renderNumber(ele.eePassUser, ele.eeActualUser);

+ 8 - 4
exam-06173-vue/src/views/admin/tmpl/components/Join1Form.vue

@@ -254,6 +254,7 @@ export default {
 
     // 创建新的大题
     createGroup(command) {
+      let index = 0
       const data = {
         anchor: new Date().getTime(),
         title: command.title,
@@ -267,10 +268,13 @@ export default {
         quList: [],
         pathScore: false
       }
-      this.postForm.groupList.push(data)
-
-      const index = this.postForm.groupList.length - 1
-      console.log('index', index)
+      const findIndex = this.postForm.groupList.findIndex(o => o.title === data.title)
+      if (findIndex === -1) {
+        this.postForm.groupList.push(data)
+        index = this.postForm.groupList.length - 1
+      } else {
+        index = findIndex
+      }
       // 默认打开选择
       this.$refs.joinQuList.openSelectQu(index)
     },

+ 1 - 1
exam-06173-vue/src/views/admin/tmpl/components/components/JoinQuList.vue

@@ -251,7 +251,7 @@ export default {
           quType: qu.quType,
           content: qu.content,
           analysis: qu.analysis,
-          score: 0,
+          score: this.postForm.groupList[this.index].perScore || 0,
           answerList: fixedAnswers,
           leftList: qu.leftList,
           rightList: qu.rightList,

+ 1 - 1
exam-06173-vue/src/views/admin/tmpl/form.vue

@@ -14,8 +14,8 @@
 <script>
 import Join1Form from '@/views/admin/tmpl/components/Join1Form'
 import { apiFindTmpl } from '@/api/tmpl/tmpl'
-
 export default {
+  name: 'ExamTmplAdd',
   components: {
     Join1Form
   },

+ 145 - 11
exam-06173-vue/src/views/dashboard/index.vue

@@ -34,7 +34,7 @@
           <img src="@/assets/dash/stzs.png" />
         </div>
         <div class="r">
-          <span class="statisticsTitle">课总数</span>
+          <span class="statisticsTitle">课总数</span>
           <span class="statisticsNum">{{ coursenum }}</span>
         </div>
       </el-card>
@@ -141,12 +141,12 @@
 
       <el-tabs v-model="tabActive" @tab-click="reLayoutTable">
         <el-tab-pane class="chartItem" label="部门" name="bm">
-          <div id="bmPxChartDom" style="width: 48%; height: 280px"></div>
-          <div id="bmKsChartDom" style="width: 48%; height: 280px"></div>
+          <div id="bmPxChartDom" style="width: 48%; height: 30vh"></div>
+          <div id="bmKsChartDom" style="width: 48%; height: 30vh"></div>
         </el-tab-pane>
         <el-tab-pane class="chartItem" label="职工" name="zg">
-          <div id="zgPxChartDom" style="width: 48%; height: 280px"></div>
-          <div id="zgKsChartDom" style="width: 48%; height: 280px"></div>
+          <div id="zgPxChartDom" style="width: 48%; height: 30vh"></div>
+          <div id="zgKsChartDom" style="width: 48%; height: 30vh"></div>
         </el-tab-pane>
       </el-tabs>
     </div>
@@ -155,6 +155,7 @@
 
 <script>
 import * as echarts from "echarts";
+import exportWord from '@/utils/export-word'
 import {
   getCttTotal,
   getCurrentExam,
@@ -178,12 +179,131 @@ export default {
       getPassedRate,
       getUserRank,
       getUserRate,
+      chart1: null,
+      chart2: null,
+      chart3: null,
+      chart4: null
     };
   },
   mounted() {
     this.initChart();
     this.getCttTotal();
     this.getCurrentExam();
+    setTimeout(() => {
+      window.addEventListener('resize', () => {
+        if (this.chart1 && this.chart3) {
+          this.chart1.getDom().style.height = (window.innerHeight - 650)> 281 ? (window.innerHeight - 650) + 'px' : '281px'
+          this.chart1.resize()
+          this.chart3.getDom().style.height = (window.innerHeight - 650)> 281 ? (window.innerHeight - 650) + 'px' : '281px'
+          this.chart3.resize()
+        }
+        if (this.chart2 && this.chart4) {
+          this.chart2.getDom().style.height = (window.innerHeight - 650)> 281 ? (window.innerHeight - 650) + 'px' : '281px'
+          this.chart2.resize()
+          this.chart4.getDom().style.height = (window.innerHeight - 650)> 281 ? (window.innerHeight - 650) + 'px' : '281px'
+          this.chart4.resize()
+        }
+      })
+    }, 1000)
+    const htmlStr = `<style>table {border: none;width: 100%; text-align: center;border-collapse: collapse;} tr {height: 30px;} td {border: 1px solid black;}</style><div>档案编号:</div>
+	<table>
+		<tr>
+			<td width="10%">姓名</td>
+			<td width="20%">${this.$store.state.user.realName}</td>
+			<td width="20%">性别</td>
+			<td width="20%"></td>
+			<td width="20%">年龄</td>
+			<td width="10%"></td>
+		</tr>
+		<tr>
+			<td>参加工作时间</td>
+			<td colspan="2"></td>
+			<td>进入公司时间</td>
+			<td colspan="2"></td>
+		</tr>
+		<tr>
+			<td>工种</td>
+			<td colspan="2"></td>
+			<td>从业资格证书</td>
+			<td colspan="2"></td>
+		</tr>
+		<tr>
+			<td colspan="6">三级安全培训记录</td>
+		</tr>
+		<tr>
+			<td>序号</td>
+			<td>培训时间</td>
+			<td>培训内容</td>
+			<td>培训级别</td>
+			<td>培训评价</td>
+			<td>备注</td>
+		</tr>
+		<tr>
+			<td>1</td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+		<tr>
+			<td>2</td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+		<tr>
+			<td>3</td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+		<tr>
+			<td>4</td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+		<tr>
+			<td>5</td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+		<tr>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+		<tr>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+		<tr>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+			<td></td>
+		</tr>
+	</table>`
+    // exportWord(htmlStr, 'app')
   },
   methods: {
     // 获取统计数值
@@ -251,7 +371,11 @@ export default {
         statDateR: endDate
       }).then((res) => {
         let myChart = echarts.init(pxChartDom);
-
+        if (tabActive === 'bm') {
+          this.chart1 = myChart
+        } else {
+          this.chart2 = myChart
+        }
         let option;
 
         let xAxisData = [];
@@ -281,6 +405,7 @@ export default {
           },
           yAxis: {
             type: "value",
+            name: tabActive === 'bm' ? '单位 (个)' : '单位 (分钟)',
             minInterval: 1,
           },
           tooltip: {
@@ -325,7 +450,11 @@ export default {
         statDateR: endDate,
       }).then((res) => {
         let myChart = echarts.init(ksChartDom);
-
+        if (tabActive === 'bm') {
+          this.chart3 = myChart
+        } else {
+          this.chart4 = myChart
+        }
         let option;
 
         let xAxisData = [];
@@ -333,7 +462,7 @@ export default {
 
         res.data.forEach((ele) => {
           xAxisData.push(tabActive === "bm" ? ele.deptName : ele.realName);
-          pxSeriesData.push(ele.total > 0 ? (ele.passed / ele.total) * 100 : 0);
+          pxSeriesData.push(ele.total > 0 ? ((ele.passed / ele.total) * 100).toFixed(0) : 0);
         });
 
         option = {
@@ -351,8 +480,12 @@ export default {
           xAxis: {
             type: "category",
             data: xAxisData,
+            axisLabel: {
+              rotate: -40,
+            },
           },
           yAxis: {
+            name: '单位 (%)',
             type: "value",
           },
           tooltip: {
@@ -418,7 +551,7 @@ export default {
   flex-wrap: wrap;
 
   .statisticsItem {
-    margin-left: 20px;
+    margin-right: 20px;
     background: #1890ff;
     padding: 5px;
     cursor: pointer;
@@ -483,7 +616,7 @@ export default {
       .el-scrollbar__view {
         display: flex;
         justify-content: space-between;
-        align-items: center;
+        // align-items: center;
         flex-wrap: wrap;
       }
 
@@ -506,6 +639,7 @@ export default {
             width: 50px;
             height: 50px;
             margin-right: 20px;
+            min-width: 50px;
 
             img {
               width: 100%;
@@ -532,7 +666,7 @@ export default {
               color: #666;
               overflow: hidden;
               text-overflow: ellipsis;
-              white-space: nowrap;
+              // white-space: nowrap;
             }
           }
         }

+ 19 - 0
exam-06173-vue/src/views/introduce/index.vue

@@ -0,0 +1,19 @@
+<template>
+	<div>
+		<video-player :value="videoSrc" :drag="false" ref-id="introduceVideo">
+		</video-player>
+	</div>
+</template>
+<script>
+import VideoPlayer from '@/components/VideoPlayer'
+export default {
+	components: {
+		VideoPlayer
+	},
+	data(){
+		return {
+			videoSrc: '/introduce/智能多媒体考试培训系统功能讲解.mp4'
+		}
+	}
+}
+</script>